1use ffmpeg_next::ffi::AVERROR;
2use ffmpeg_sys_next::*;
3use std::ffi::NulError;
4use std::{io, result};
5
6#[cfg(feature = "opengl")]
11#[allow(deprecated)]
12use crate::opengl::OpenGLFilterError;
13
14pub type Result<T, E = Error> = result::Result<T, E>;
16
17#[derive(thiserror::Error, Debug)]
18#[non_exhaustive]
19pub enum Error {
20 #[error("Scheduler is not started")]
21 NotStarted,
22
23 #[error("URL error: {0}")]
24 Url(#[from] UrlError),
25
26 #[error("Open input stream error: {0}")]
27 OpenInputStream(#[from] OpenInputError),
28
29 #[error("Find stream info error: {0}")]
30 FindStream(#[from] FindStreamError),
31
32 #[error("Decoder error: {0}")]
33 Decoder(#[from] DecoderError),
34
35 #[error("Filter graph parse error: {0}")]
36 FilterGraphParse(#[from] FilterGraphParseError),
37
38 #[error("Filter description converted to utf8 string error")]
39 FilterDescUtf8,
40
41 #[error("Filter name converted to utf8 string error")]
42 FilterNameUtf8,
43
44 #[error("A filtergraph has zero outputs, this is not supported")]
45 FilterZeroOutputs,
46
47 #[error("A filtergraph has zero inputs, this is not supported")]
48 FilterZeroInputs,
49
50 #[error("Input is not a valid number")]
51 ParseInteger,
52
53 #[error("Alloc output context error: {0}")]
54 AllocOutputContext(#[from] AllocOutputContextError),
55
56 #[error("Open output error: {0}")]
57 OpenOutput(#[from] OpenOutputError),
58
59 #[error("Output file '{0}' is the same as an input file")]
60 FileSameAsInput(String),
61
62 #[error("Find devices error: {0}")]
63 FindDevices(#[from] FindDevicesError),
64
65 #[error("Alloc frame error: {0}")]
66 AllocFrame(#[from] AllocFrameError),
67
68 #[error("Alloc packet error: {0}")]
69 AllocPacket(#[from] AllocPacketError),
70
71 #[error("Frame writable error: {0}")]
72 FrameWritable(#[from] FrameWritableError),
73
74 #[error("Muxing operation failed {0}")]
76 Muxing(#[from] MuxingOperationError),
77
78 #[error("Open encoder operation failed {0}")]
80 OpenEncoder(#[from] OpenEncoderOperationError),
81
82 #[error("Encoding operation failed {0}")]
84 Encoding(#[from] EncodingOperationError),
85
86 #[error("Filter graph operation failed {0}")]
88 FilterGraph(#[from] FilterGraphOperationError),
89
90 #[error("Open decoder operation failed {0}")]
92 OpenDecoder(#[from] OpenDecoderOperationError),
93
94 #[error("Decoding operation failed {0}")]
96 Decoding(#[from] DecodingOperationError),
97
98 #[error("Demuxing operation failed {0}")]
100 Demuxing(#[from] DemuxingOperationError),
101
102 #[error("Packet scanner error: {0}")]
104 PacketScanner(#[from] PacketScannerError),
105
106 #[error("Frame filter init failed: {0}")]
108 FrameFilterInit(Box<dyn std::error::Error + Send + Sync>),
109
110 #[error("Frame filter process failed: {0}")]
111 FrameFilterProcess(Box<dyn std::error::Error + Send + Sync>),
112
113 #[error("Frame filter request failed: {0}")]
114 FrameFilterRequest(Box<dyn std::error::Error + Send + Sync>),
115
116 #[error("No {0} stream of the type:{1} were found while build frame pipeline")]
117 FrameFilterTypeNoMatched(String, String),
118
119 #[error("{0} stream:{1} of the type:{2} were mismatched while build frame pipeline")]
120 FrameFilterStreamTypeNoMatched(String, usize, String),
121
122 #[error("Frame filter pipeline destination already finished")]
123 FrameFilterDstFinished,
124
125 #[error("Frame filter pipeline failed to duplicate a frame for an additional destination")]
126 FrameFilterFrameDuplicateFailed,
127
128 #[error("Frame filter pipeline thread exited")]
129 FrameFilterThreadExited,
130
131 #[error("Worker thread '{0}' panicked; output may be incomplete")]
132 WorkerPanicked(String),
133
134 #[cfg(feature = "rtmp")]
135 #[error("Rtmp stream already exists with key: {0}")]
136 RtmpStreamAlreadyExists(String),
137
138 #[cfg(feature = "rtmp")]
139 #[error("Rtmp create stream failed. Check whether the server is stopped.")]
140 RtmpCreateStream,
141
142 #[cfg(feature = "rtmp")]
143 #[error("Rtmp server thread exited")]
144 RtmpThreadExited,
145
146 #[cfg(feature = "rtmp")]
147 #[error("Rtmp stream closed: the server is no longer consuming this stream")]
148 RtmpStreamClosed,
149
150 #[cfg(feature = "subtitle")]
151 #[error("Subtitle error: {0}")]
152 Subtitle(#[from] crate::subtitle::SubtitleError),
153
154 #[cfg(feature = "wgpu")]
155 #[error("Wgpu filter error: {0}")]
156 WgpuFilter(#[from] crate::wgpu_filter::WgpuFilterError),
157
158 #[cfg(feature = "opengl")]
163 #[allow(deprecated)]
164 #[error("OpenGL filter error: {0}")]
165 OpenGLFilter(#[source] OpenGLFilterError),
166
167 #[error("IO error:{0}")]
168 IO(#[from] io::Error),
169
170 #[error("EOF")]
171 EOF,
172 #[error("Exit")]
173 Exit,
174 #[error("Bug")]
175 Bug,
176
177 #[error("Invalid recipe argument: {0}")]
178 InvalidRecipeArg(String),
179
180 #[error("Container info error: {0}")]
181 ContainerInfo(#[from] ContainerInfoError),
182
183 #[error("Frame export error: {0}")]
184 FrameExport(#[from] crate::core::frame_export::FrameExportError),
185
186 #[error("Video writer error: {0}")]
187 Writer(#[from] crate::core::writer::WriterError),
188
189 #[error("Video writer push error: {0}")]
190 Push(#[from] crate::core::writer::PushError),
191
192 #[error("Frame source thread failed to start")]
193 FrameSourceThreadExited,
194}
195
196pub use crate::core::writer::WriterError;
201
202#[cfg(feature = "opengl")]
206#[allow(deprecated)]
207impl From<OpenGLFilterError> for Error {
208 fn from(err: OpenGLFilterError) -> Self {
209 Error::OpenGLFilter(err)
210 }
211}
212
213#[derive(thiserror::Error, Debug)]
221#[non_exhaustive]
222pub enum ContainerInfoError {
223 #[error("chapter index {index} out of range: the container has {count} chapter(s)")]
224 ChapterIndexOutOfRange { index: usize, count: usize },
225
226 #[error("stream index {index} out of range: the container has {count} stream(s)")]
227 StreamIndexOutOfRange { index: usize, count: usize },
228}
229
230#[cfg(feature = "rtmp")]
232#[derive(thiserror::Error, Debug)]
233#[non_exhaustive]
234pub enum StreamError {
235 #[error("missing required parameter: {0}")]
236 MissingParameter(&'static str),
237
238 #[error("input path is not a valid file: {path}")]
239 InputNotFound { path: std::path::PathBuf },
240
241 #[error("ffmpeg error: {0}")]
242 Ffmpeg(#[from] crate::error::Error),
243}
244
245impl PartialEq for Error {
246 fn eq(&self, other: &Self) -> bool {
250 use Error::*;
251 match (self, other) {
252 (NotStarted, NotStarted)
253 | (FilterDescUtf8, FilterDescUtf8)
254 | (FilterNameUtf8, FilterNameUtf8)
255 | (FilterZeroOutputs, FilterZeroOutputs)
256 | (FilterZeroInputs, FilterZeroInputs)
257 | (ParseInteger, ParseInteger)
258 | (FrameFilterDstFinished, FrameFilterDstFinished)
259 | (FrameFilterFrameDuplicateFailed, FrameFilterFrameDuplicateFailed)
260 | (FrameFilterThreadExited, FrameFilterThreadExited)
261 | (FrameSourceThreadExited, FrameSourceThreadExited)
262 | (EOF, EOF)
263 | (Exit, Exit)
264 | (Bug, Bug) => true,
265 #[cfg(feature = "rtmp")]
266 (RtmpCreateStream, RtmpCreateStream)
267 | (RtmpThreadExited, RtmpThreadExited)
268 | (RtmpStreamClosed, RtmpStreamClosed) => true,
269 _ => false,
270 }
271 }
272}
273
274#[derive(thiserror::Error, Debug)]
278#[non_exhaustive]
279pub enum DemuxingOperationError {
280 #[error("while reading frame: {0}")]
281 ReadFrameError(DemuxingError),
282
283 #[error("while referencing packet: {0}")]
284 PacketRefError(DemuxingError),
285
286 #[error("while seeking file: {0}")]
287 SeekFileError(DemuxingError),
288
289 #[error("Thread exited")]
290 ThreadExited,
291}
292
293#[derive(thiserror::Error, Debug)]
294#[non_exhaustive]
295pub enum DecodingOperationError {
296 #[error("during frame reference creation: {0}")]
297 FrameRefError(DecodingError),
298
299 #[error("during frame properties copy: {0}")]
300 FrameCopyPropsError(DecodingError),
301
302 #[error("during subtitle decoding: {0}")]
303 DecodeSubtitleError(DecodingError),
304
305 #[error("during subtitle copy: {0}")]
306 CopySubtitleError(DecodingError),
307
308 #[error("during packet submission to decoder: {0}")]
309 SendPacketError(DecodingError),
310
311 #[error("during frame reception from decoder: {0}")]
312 ReceiveFrameError(DecodingError),
313
314 #[error("during frame allocation: {0}")]
315 FrameAllocationError(DecodingError),
316
317 #[error("during packet allocation: {0}")]
318 PacketAllocationError(DecodingError),
319
320 #[error("during AVSubtitle allocation: {0}")]
321 SubtitleAllocationError(DecodingError),
322
323 #[error("corrupt decoded frame")]
324 CorruptFrame,
325
326 #[error("decode error rate exceeded the maximum allowed")]
327 ErrorRateExceeded,
328
329 #[error("during retrieve data on hw: {0}")]
330 HWRetrieveDataError(DecodingError),
331
332 #[error("during cropping: {0}")]
333 CroppingError(DecodingError),
334}
335
336#[derive(thiserror::Error, Debug)]
337#[non_exhaustive]
338pub enum OpenDecoderOperationError {
339 #[error("during context allocation: {0}")]
340 ContextAllocationError(OpenDecoderError),
341
342 #[error("while applying parameters to context: {0}")]
343 ParameterApplicationError(OpenDecoderError),
344
345 #[error("while opening decoder: {0}")]
346 DecoderOpenError(OpenDecoderError),
347
348 #[error("while copying channel layout: {0}")]
349 ChannelLayoutCopyError(OpenDecoderError),
350
351 #[error("while Hw setup: {0}")]
352 HwSetupError(OpenDecoderError),
353
354 #[error("Invalid decoder name")]
355 InvalidName,
356
357 #[error("Thread exited")]
358 ThreadExited,
359}
360
361#[derive(thiserror::Error, Debug)]
362#[non_exhaustive]
363pub enum FilterGraphOperationError {
364 #[error("during requesting oldest frame: {0}")]
365 RequestOldestError(FilterGraphError),
366
367 #[error("during process frames: {0}")]
368 ProcessFramesError(FilterGraphError),
369
370 #[error("during send frames: {0}")]
371 SendFramesError(FilterGraphError),
372
373 #[error("during copying channel layout: {0}")]
374 ChannelLayoutCopyError(FilterGraphError),
375
376 #[error("during buffer source add frame: {0}")]
377 BufferSourceAddFrameError(FilterGraphError),
378
379 #[error("during closing buffer source: {0}")]
380 BufferSourceCloseError(FilterGraphError),
381
382 #[error("during replace buffer: {0}")]
383 BufferReplaceoseError(FilterGraphError),
384
385 #[error("during cloning frame side data: {0}")]
386 FrameSideDataCloneError(FilterGraphError),
387
388 #[error("during parse: {0}")]
389 ParseError(FilterGraphParseError),
390
391 #[error("The data in the frame is invalid or corrupted")]
392 InvalidData,
393
394 #[error(
395 "graph input '{0}' already holds {1} buffered frames and admitting the next \
396 one would raise the best-effort retained-memory estimate to ~{2} bytes, \
397 while another input has not yet delivered its first frame, so the filter \
398 graph cannot be configured; check that every graph input actually produces \
399 data (or produces it within the buffering window)"
400 )]
401 PreConfigQueueOverflow(String, usize, usize),
402
403 #[cfg_attr(not(ffmpeg_8_0), allow(dead_code))]
405 #[error(
406 "graph input '{0}' would deep-copy an estimated {1} bytes of side-data \
407 metadata into the buffersrc parameters, exceeding the side-data clone \
408 estimate threshold; the frame's combined side-data metadata (across its \
409 global and downmix entries) is pathologically large"
410 )]
411 OversizedSideDataClone(String, usize),
412
413 #[error("Thread exited")]
414 ThreadExited,
415}
416
417#[derive(thiserror::Error, Debug)]
418#[non_exhaustive]
419pub enum EncodingOperationError {
420 #[error("during frame submission: {0}")]
421 SendFrameError(EncodingError),
422
423 #[error("during packet retrieval: {0}")]
424 ReceivePacketError(EncodingError),
425
426 #[error("during audio frame receive: {0}")]
427 ReceiveAudioError(EncodingError),
428
429 #[error(": Subtitle packets must have a pts")]
430 SubtitleNotPts,
431
432 #[error(": Muxer already finished")]
433 MuxerFinished,
434
435 #[error(": too many packets buffered for an output stream before the muxer started; raise Output::set_max_muxing_queue_size / Output::set_muxing_queue_data_threshold, or check that every mapped output stream receives data")]
441 MuxQueueFull,
442
443 #[error("Encode subtitle error: {0}")]
444 EncodeSubtitle(#[from] EncodeSubtitleError),
445
446 #[error(": {0}")]
447 AllocPacket(AllocPacketError),
448}
449
450#[derive(thiserror::Error, Debug)]
451#[non_exhaustive]
452pub enum MuxingOperationError {
453 #[error("during write header: {0}")]
454 WriteHeader(WriteHeaderError),
455
456 #[error("while initializing bitstream filter chain '{0}': {1}")]
457 BitstreamFilterInit(String, MuxingError),
458
459 #[error("during interleaved write: {0}")]
460 InterleavedWriteError(MuxingError),
461
462 #[error("during trailer write: {0}")]
463 TrailerWriteError(MuxingError),
464
465 #[error("during closing IO: {0}")]
466 IOCloseError(MuxingError),
467
468 #[error("Thread exited")]
469 ThreadExited,
470}
471
472#[derive(thiserror::Error, Debug)]
473#[non_exhaustive]
474pub enum OpenEncoderOperationError {
475 #[error("during frame side data cloning: {0}")]
476 FrameSideDataCloneError(OpenEncoderError),
477
478 #[error("during channel layout copying: {0}")]
479 ChannelLayoutCopyError(OpenEncoderError),
480
481 #[error("during codec opening: {0}")]
482 CodecOpenError(OpenEncoderError),
483
484 #[error("while setting codec parameters: {0}")]
485 CodecParametersError(OpenEncoderError),
486
487 #[error(": unknown format of the frame")]
488 UnknownFrameFormat,
489
490 #[error("while setting subtitle: {0}")]
491 SettingSubtitleError(OpenEncoderError),
492
493 #[error("while Hw setup: {0}")]
494 HwSetupError(OpenEncoderError),
495
496 #[error("during context allocation: {0}")]
497 ContextAllocationError(OpenEncoderError),
498
499 #[error(": no frames were received before EOF; encoder never opened")]
500 NoFramesReceived,
501
502 #[error(": unsupported media type for encoding")]
503 UnsupportedMediaType,
504
505 #[error("Thread exited")]
506 ThreadExited,
507}
508
509#[derive(thiserror::Error, Debug)]
510#[non_exhaustive]
511pub enum UrlError {
512 #[error("Null byte found in string at position {0}")]
513 NullByteError(usize),
514}
515
516impl From<NulError> for Error {
517 fn from(err: NulError) -> Self {
518 Error::Url(UrlError::NullByteError(err.nul_position()))
519 }
520}
521
522#[derive(thiserror::Error, Debug)]
523#[non_exhaustive]
524pub enum OpenInputError {
525 #[error("Memory allocation error")]
526 OutOfMemory,
527
528 #[error("Invalid argument provided")]
529 InvalidArgument,
530
531 #[error("File or stream not found")]
532 NotFound,
533
534 #[error("I/O error occurred while opening the file or stream")]
535 IOError,
536
537 #[error("Pipe error, possibly the stream or data connection was broken")]
538 PipeError,
539
540 #[error("Invalid file descriptor")]
541 BadFileDescriptor,
542
543 #[error("Functionality not implemented or unsupported input format")]
544 NotImplemented,
545
546 #[error("Operation not permitted to access the file or stream")]
547 OperationNotPermitted,
548
549 #[error("The data in the file or stream is invalid or corrupted")]
550 InvalidData,
551
552 #[error("The connection timed out while trying to open the stream")]
553 Timeout,
554
555 #[error("Invalid input option: {0}")]
561 InvalidOption(String),
562
563 #[error("{}. ret:{0}", crate::util::ffmpeg_utils::av_err2str(*.0))]
564 UnknownError(i32),
565
566 #[error("Invalid source provided")]
567 InvalidSource,
568
569 #[error("Invalid source format:{0}")]
570 InvalidFormat(String),
571
572 #[error("No seek callback is provided")]
573 SeekFunctionMissing,
574}
575
576impl From<i32> for OpenInputError {
577 fn from(err_code: i32) -> Self {
578 match err_code {
579 AVERROR_OUT_OF_MEMORY => OpenInputError::OutOfMemory,
580 AVERROR_INVALID_ARGUMENT => OpenInputError::InvalidArgument,
581 AVERROR_NOT_FOUND => OpenInputError::NotFound,
582 AVERROR_IO_ERROR => OpenInputError::IOError,
583 AVERROR_PIPE_ERROR => OpenInputError::PipeError,
584 AVERROR_BAD_FILE_DESCRIPTOR => OpenInputError::BadFileDescriptor,
585 AVERROR_NOT_IMPLEMENTED => OpenInputError::NotImplemented,
586 AVERROR_OPERATION_NOT_PERMITTED => OpenInputError::OperationNotPermitted,
587 AVERROR_INVALIDDATA => OpenInputError::InvalidData,
588 AVERROR_TIMEOUT => OpenInputError::Timeout,
589 _ => OpenInputError::UnknownError(err_code),
590 }
591 }
592}
593
594const AVERROR_OUT_OF_MEMORY: i32 = AVERROR(ENOMEM);
595const AVERROR_INVALID_ARGUMENT: i32 = AVERROR(EINVAL);
596const AVERROR_NOT_FOUND: i32 = AVERROR(ENOENT);
597const AVERROR_IO_ERROR: i32 = AVERROR(EIO);
598const AVERROR_PIPE_ERROR: i32 = AVERROR(EPIPE);
599const AVERROR_BAD_FILE_DESCRIPTOR: i32 = AVERROR(EBADF);
600const AVERROR_NOT_IMPLEMENTED: i32 = AVERROR(ENOSYS);
601const AVERROR_OPERATION_NOT_PERMITTED: i32 = AVERROR(EPERM);
602const AVERROR_PERMISSION_DENIED: i32 = AVERROR(EACCES);
603const AVERROR_TIMEOUT: i32 = AVERROR(ETIMEDOUT);
604const AVERROR_NOT_SOCKET: i32 = AVERROR(ENOTSOCK);
605const AVERROR_AGAIN: i32 = AVERROR(EAGAIN);
606
607#[derive(thiserror::Error, Debug)]
608#[non_exhaustive]
609pub enum FindStreamError {
610 #[error("Memory allocation error")]
611 OutOfMemory,
612
613 #[error("Invalid argument provided")]
614 InvalidArgument,
615
616 #[error("Reached end of file while looking for stream info")]
617 EndOfFile,
618
619 #[error("Timeout occurred while reading stream info")]
620 Timeout,
621
622 #[error("I/O error occurred while reading stream info")]
623 IOError,
624
625 #[error("The data in the stream is invalid or corrupted")]
626 InvalidData,
627
628 #[error("Functionality not implemented or unsupported stream format")]
629 NotImplemented,
630
631 #[error("Operation not permitted to access the file or stream")]
632 OperationNotPermitted,
633
634 #[error("No Stream found")]
635 NoStreamFound,
636
637 #[error("{}. ret:{0}", crate::util::ffmpeg_utils::av_err2str(*.0))]
638 UnknownError(i32),
639}
640
641impl From<i32> for FindStreamError {
642 fn from(err_code: i32) -> Self {
643 match err_code {
644 AVERROR_OUT_OF_MEMORY => FindStreamError::OutOfMemory,
645 AVERROR_INVALID_ARGUMENT => FindStreamError::InvalidArgument,
646 AVERROR_EOF => FindStreamError::EndOfFile,
647 AVERROR_TIMEOUT => FindStreamError::Timeout,
648 AVERROR_IO_ERROR => FindStreamError::IOError,
649 AVERROR_INVALIDDATA => FindStreamError::InvalidData,
650 AVERROR_NOT_IMPLEMENTED => FindStreamError::NotImplemented,
651 AVERROR_OPERATION_NOT_PERMITTED => FindStreamError::OperationNotPermitted,
652 _ => FindStreamError::UnknownError(err_code),
653 }
654 }
655}
656
657#[derive(thiserror::Error, Debug)]
658#[non_exhaustive]
659pub enum FilterGraphParseError {
660 #[error("Memory allocation error")]
661 OutOfMemory,
662
663 #[error("Invalid argument provided")]
664 InvalidArgument,
665
666 #[error("End of file reached during parsing")]
667 EndOfFile,
668
669 #[error("I/O error occurred during parsing")]
670 IOError,
671
672 #[error("Invalid data encountered during parsing")]
673 InvalidData,
674
675 #[error("Functionality not implemented or unsupported filter format")]
676 NotImplemented,
677
678 #[error("Permission denied during filter graph parsing")]
679 PermissionDenied,
680
681 #[error("Socket operation on non-socket during filter graph parsing")]
682 NotSocket,
683
684 #[error("Option not found during filter graph configuration")]
685 OptionNotFound,
686
687 #[error("Invalid file index {0} in filtergraph description {1}")]
688 InvalidFileIndexInFg(usize, String),
689
690 #[error("Invalid file index {0} in output url: {1}")]
691 InvalidFileIndexInOutput(usize, String),
692
693 #[error("Invalid filter specifier {0}")]
694 InvalidFilterSpecifier(String),
695
696 #[error("Filter '{0}' has output {1} ({2}) unconnected")]
697 OutputUnconnected(String, usize, String),
698
699 #[error("An unknown error occurred. ret: {0}")]
700 UnknownError(i32),
701}
702
703impl From<i32> for FilterGraphParseError {
704 fn from(err_code: i32) -> Self {
705 match err_code {
706 AVERROR_OUT_OF_MEMORY => FilterGraphParseError::OutOfMemory,
707 AVERROR_INVALID_ARGUMENT => FilterGraphParseError::InvalidArgument,
708 AVERROR_EOF => FilterGraphParseError::EndOfFile,
709 AVERROR_IO_ERROR => FilterGraphParseError::IOError,
710 AVERROR_INVALIDDATA => FilterGraphParseError::InvalidData,
711 AVERROR_NOT_IMPLEMENTED => FilterGraphParseError::NotImplemented,
712 AVERROR_OPTION_NOT_FOUND => FilterGraphParseError::OptionNotFound,
713 AVERROR_PERMISSION_DENIED => FilterGraphParseError::PermissionDenied,
717 AVERROR_NOT_SOCKET => FilterGraphParseError::NotSocket,
718 _ => FilterGraphParseError::UnknownError(err_code),
719 }
720 }
721}
722
723#[derive(thiserror::Error, Debug)]
724#[non_exhaustive]
725pub enum AllocOutputContextError {
726 #[error("Memory allocation error")]
727 OutOfMemory,
728
729 #[error("Invalid argument provided")]
730 InvalidArgument,
731
732 #[error("File or stream not found")]
733 NotFound,
734
735 #[error("I/O error occurred while allocating the output context")]
736 IOError,
737
738 #[error("Pipe error, possibly the stream or data connection was broken")]
739 PipeError,
740
741 #[error("Invalid file descriptor")]
742 BadFileDescriptor,
743
744 #[error("Functionality not implemented or unsupported output format")]
745 NotImplemented,
746
747 #[error("Operation not permitted to allocate the output context")]
748 OperationNotPermitted,
749
750 #[error("Permission denied while allocating the output context")]
751 PermissionDenied,
752
753 #[error("The connection timed out while trying to allocate the output context")]
754 Timeout,
755
756 #[error("{}. ret:{0}", crate::util::ffmpeg_utils::av_err2str(*.0))]
757 UnknownError(i32),
758}
759
760impl From<i32> for AllocOutputContextError {
761 fn from(err_code: i32) -> Self {
762 match err_code {
763 AVERROR_OUT_OF_MEMORY => AllocOutputContextError::OutOfMemory,
764 AVERROR_INVALID_ARGUMENT => AllocOutputContextError::InvalidArgument,
765 AVERROR_NOT_FOUND => AllocOutputContextError::NotFound,
766 AVERROR_IO_ERROR => AllocOutputContextError::IOError,
767 AVERROR_PIPE_ERROR => AllocOutputContextError::PipeError,
768 AVERROR_BAD_FILE_DESCRIPTOR => AllocOutputContextError::BadFileDescriptor,
769 AVERROR_NOT_IMPLEMENTED => AllocOutputContextError::NotImplemented,
770 AVERROR_OPERATION_NOT_PERMITTED => AllocOutputContextError::OperationNotPermitted,
771 AVERROR_PERMISSION_DENIED => AllocOutputContextError::PermissionDenied,
772 AVERROR_TIMEOUT => AllocOutputContextError::Timeout,
773 _ => AllocOutputContextError::UnknownError(err_code),
774 }
775 }
776}
777
778#[derive(thiserror::Error, Debug)]
779#[non_exhaustive]
780pub enum OpenOutputError {
781 #[error("Memory allocation error")]
782 OutOfMemory,
783
784 #[error("Invalid argument provided")]
785 InvalidArgument,
786
787 #[error("File or stream not found")]
788 NotFound,
789
790 #[error("I/O error occurred while opening the file or stream")]
791 IOError,
792
793 #[error("Pipe error, possibly the stream or data connection was broken")]
794 PipeError,
795
796 #[error("Invalid file descriptor")]
797 BadFileDescriptor,
798
799 #[error("Functionality not implemented or unsupported output format")]
800 NotImplemented,
801
802 #[error("Operation not permitted to open the file or stream")]
803 OperationNotPermitted,
804
805 #[error("Permission denied while opening the file or stream")]
806 PermissionDenied,
807
808 #[error("The connection timed out while trying to open the file or stream")]
809 Timeout,
810
811 #[error("encoder not found")]
812 EncoderNotFound,
813
814 #[error(
822 "encoder '{name}' is not available in the linked FFmpeg build — link \
823 an FFmpeg build that provides it (for example one configured with \
824 --enable-libx264 for libx264), or select a different encoder via \
825 Output::set_video_codec / set_audio_codec / set_subtitle_codec \
826 (list what the build provides with codec::get_encoders)"
827 )]
828 EncoderUnavailable { name: String },
829
830 #[error("Stream map '{0}' matches no streams;")]
831 MatchesNoStreams(String),
832
833 #[error("Invalid label {0}")]
834 InvalidLabel(String),
835
836 #[error("not contain any stream")]
837 NotContainStream,
838
839 #[error("unknown format of the frame")]
840 UnknownFrameFormat,
841
842 #[error("Invalid file index {0} in input url: {1}")]
843 InvalidFileIndexInIntput(usize, String),
844
845 #[error("{}. ret:{0}", crate::util::ffmpeg_utils::av_err2str(*.0))]
846 UnknownError(i32),
847
848 #[error("Invalid sink provided")]
849 InvalidSink,
850
851 #[error("No seek callback is provided")]
852 SeekFunctionMissing,
853
854 #[error("Format '{0}' is unsupported")]
855 FormatUnsupported(String),
856
857 #[error("Unknown pixel format: '{0}'")]
858 UnknownPixelFormat(String),
859
860 #[error("Unknown sample format: '{0}'")]
861 UnknownSampleFormat(String),
862
863 #[error("Invalid output option: {0}")]
869 InvalidOption(String),
870
871 #[error("Failed to read attachment file '{0}'")]
872 AttachmentRead(String, #[source] io::Error),
873
874 #[error("Attachment file '{0}' is empty")]
875 AttachmentEmpty(String),
876
877 #[error("Attachment file '{0}' is too large ({1} bytes, limit {2} bytes)")]
878 AttachmentTooLarge(String, u64, u64),
879
880 #[error("Attachment mimetype must not be empty (file '{0}')")]
881 AttachmentEmptyMimetype(String),
882}
883
884impl From<i32> for OpenOutputError {
885 fn from(err_code: i32) -> Self {
886 match err_code {
887 AVERROR_OUT_OF_MEMORY => OpenOutputError::OutOfMemory,
888 AVERROR_INVALID_ARGUMENT => OpenOutputError::InvalidArgument,
889 AVERROR_NOT_FOUND => OpenOutputError::NotFound,
890 AVERROR_IO_ERROR => OpenOutputError::IOError,
891 AVERROR_PIPE_ERROR => OpenOutputError::PipeError,
892 AVERROR_BAD_FILE_DESCRIPTOR => OpenOutputError::BadFileDescriptor,
893 AVERROR_NOT_IMPLEMENTED => OpenOutputError::NotImplemented,
894 AVERROR_OPERATION_NOT_PERMITTED => OpenOutputError::OperationNotPermitted,
895 AVERROR_PERMISSION_DENIED => OpenOutputError::PermissionDenied,
896 AVERROR_TIMEOUT => OpenOutputError::Timeout,
897 AVERROR_ENCODER_NOT_FOUND => OpenOutputError::EncoderNotFound,
898 _ => OpenOutputError::UnknownError(err_code),
899 }
900 }
901}
902
903#[derive(thiserror::Error, Debug)]
904#[non_exhaustive]
905pub enum FindDevicesError {
906 #[error("AVCaptureDevice class not found in macOS")]
907 AVCaptureDeviceNotFound,
908
909 #[error("current media_type({0}) is not supported")]
910 MediaTypeSupported(i32),
911 #[error("current OS is not supported")]
912 OsNotSupported,
913 #[error("device_description can not to string")]
914 UTF8Error,
915
916 #[error("Memory allocation error")]
917 OutOfMemory,
918 #[error("Invalid argument provided")]
919 InvalidArgument,
920 #[error("Device or stream not found")]
921 NotFound,
922 #[error("I/O error occurred while accessing the device or stream")]
923 IOError,
924 #[error("Operation not permitted for this device or stream")]
925 OperationNotPermitted,
926 #[error("Permission denied while accessing the device or stream")]
927 PermissionDenied,
928 #[error("This functionality is not implemented")]
929 NotImplemented,
930 #[error("Bad file descriptor")]
931 BadFileDescriptor,
932 #[error("{}. ret:{0}", crate::util::ffmpeg_utils::av_err2str(*.0))]
933 UnknownError(i32),
934}
935
936impl From<i32> for FindDevicesError {
937 fn from(err_code: i32) -> Self {
938 match err_code {
939 AVERROR_OUT_OF_MEMORY => FindDevicesError::OutOfMemory,
940 AVERROR_INVALID_ARGUMENT => FindDevicesError::InvalidArgument,
941 AVERROR_NOT_FOUND => FindDevicesError::NotFound,
942 AVERROR_IO_ERROR => FindDevicesError::IOError,
943 AVERROR_OPERATION_NOT_PERMITTED => FindDevicesError::OperationNotPermitted,
944 AVERROR_PERMISSION_DENIED => FindDevicesError::PermissionDenied,
945 AVERROR_NOT_IMPLEMENTED => FindDevicesError::NotImplemented,
946 AVERROR_BAD_FILE_DESCRIPTOR => FindDevicesError::BadFileDescriptor,
947 _ => FindDevicesError::UnknownError(err_code),
948 }
949 }
950}
951
952#[derive(thiserror::Error, Debug)]
953#[non_exhaustive]
954pub enum WriteHeaderError {
955 #[error("Memory allocation error")]
956 OutOfMemory,
957
958 #[error("Invalid argument provided")]
959 InvalidArgument,
960
961 #[error("File or stream not found")]
962 NotFound,
963
964 #[error("I/O error occurred while writing the header")]
965 IOError,
966
967 #[error("Pipe error, possibly the stream or data connection was broken")]
968 PipeError,
969
970 #[error("Invalid file descriptor")]
971 BadFileDescriptor,
972
973 #[error("Functionality not implemented or unsupported output format")]
974 NotImplemented,
975
976 #[error("Operation not permitted to write the header")]
977 OperationNotPermitted,
978
979 #[error("Permission denied while writing the header")]
980 PermissionDenied,
981
982 #[error("The connection timed out while trying to write the header")]
983 Timeout,
984
985 #[error("{}. ret:{0}", crate::util::ffmpeg_utils::av_err2str(*.0))]
986 UnknownError(i32),
987}
988
989impl From<i32> for WriteHeaderError {
990 fn from(err_code: i32) -> Self {
991 match err_code {
992 AVERROR_OUT_OF_MEMORY => WriteHeaderError::OutOfMemory,
993 AVERROR_INVALID_ARGUMENT => WriteHeaderError::InvalidArgument,
994 AVERROR_NOT_FOUND => WriteHeaderError::NotFound,
995 AVERROR_IO_ERROR => WriteHeaderError::IOError,
996 AVERROR_PIPE_ERROR => WriteHeaderError::PipeError,
997 AVERROR_BAD_FILE_DESCRIPTOR => WriteHeaderError::BadFileDescriptor,
998 AVERROR_NOT_IMPLEMENTED => WriteHeaderError::NotImplemented,
999 AVERROR_OPERATION_NOT_PERMITTED => WriteHeaderError::OperationNotPermitted,
1000 AVERROR_PERMISSION_DENIED => WriteHeaderError::PermissionDenied,
1001 AVERROR_TIMEOUT => WriteHeaderError::Timeout,
1002 _ => WriteHeaderError::UnknownError(err_code),
1003 }
1004 }
1005}
1006
1007#[derive(thiserror::Error, Debug)]
1008#[non_exhaustive]
1009pub enum EncodeSubtitleError {
1010 #[error("Memory allocation error while encoding subtitle")]
1011 OutOfMemory,
1012
1013 #[error("Invalid argument provided for subtitle encoding")]
1014 InvalidArgument,
1015
1016 #[error("Operation not permitted while encoding subtitle")]
1017 OperationNotPermitted,
1018
1019 #[error("The encoding functionality is not implemented or unsupported")]
1020 NotImplemented,
1021
1022 #[error("Encoder temporarily unable to process, please retry")]
1023 TryAgain,
1024
1025 #[error("Subtitle encoding failed with unknown error. ret: {0}")]
1026 UnknownError(i32),
1027}
1028
1029impl From<i32> for EncodeSubtitleError {
1030 fn from(err_code: i32) -> Self {
1031 match err_code {
1032 AVERROR_OUT_OF_MEMORY => EncodeSubtitleError::OutOfMemory,
1033 AVERROR_INVALID_ARGUMENT => EncodeSubtitleError::InvalidArgument,
1034 AVERROR_OPERATION_NOT_PERMITTED => EncodeSubtitleError::OperationNotPermitted,
1035 AVERROR_NOT_IMPLEMENTED => EncodeSubtitleError::NotImplemented,
1036 AVERROR_AGAIN => EncodeSubtitleError::TryAgain,
1037 _ => EncodeSubtitleError::UnknownError(err_code),
1038 }
1039 }
1040}
1041
1042#[derive(thiserror::Error, Debug)]
1043#[non_exhaustive]
1044pub enum AllocPacketError {
1045 #[error("Memory allocation error while alloc packet")]
1046 OutOfMemory,
1047}
1048
1049#[derive(thiserror::Error, Debug)]
1050#[non_exhaustive]
1051pub enum AllocFrameError {
1052 #[error("Memory allocation error while alloc frame")]
1053 OutOfMemory,
1054}
1055
1056#[derive(thiserror::Error, Debug)]
1064#[non_exhaustive]
1065pub enum FrameWritableError {
1066 #[error("Memory allocation error while copying frame data")]
1067 OutOfMemory,
1068
1069 #[error("Invalid argument provided")]
1070 InvalidArgument,
1071
1072 #[error("{}. ret:{0}", crate::util::ffmpeg_utils::av_err2str(*.0))]
1073 UnknownError(i32),
1074}
1075
1076impl From<i32> for FrameWritableError {
1077 fn from(err_code: i32) -> Self {
1078 match err_code {
1079 AVERROR_OUT_OF_MEMORY => FrameWritableError::OutOfMemory,
1080 AVERROR_INVALID_ARGUMENT => FrameWritableError::InvalidArgument,
1081 _ => FrameWritableError::UnknownError(err_code),
1082 }
1083 }
1084}
1085
1086#[derive(thiserror::Error, Debug)]
1087#[non_exhaustive]
1088pub enum MuxingError {
1089 #[error("Memory allocation error")]
1090 OutOfMemory,
1091
1092 #[error("Invalid argument provided")]
1093 InvalidArgument,
1094
1095 #[error("I/O error occurred during muxing")]
1096 IOError,
1097
1098 #[error("Broken pipe during muxing")]
1099 PipeError,
1100
1101 #[error("Bad file descriptor encountered")]
1102 BadFileDescriptor,
1103
1104 #[error("Functionality not implemented or unsupported")]
1105 NotImplemented,
1106
1107 #[error("Operation not permitted")]
1108 OperationNotPermitted,
1109
1110 #[error("Resource temporarily unavailable")]
1111 TryAgain,
1112
1113 #[error("{}. ret:{0}", crate::util::ffmpeg_utils::av_err2str(*.0))]
1114 UnknownError(i32),
1115}
1116
1117impl From<i32> for MuxingError {
1118 fn from(err_code: i32) -> Self {
1119 match err_code {
1120 AVERROR_OUT_OF_MEMORY => MuxingError::OutOfMemory,
1121 AVERROR_INVALID_ARGUMENT => MuxingError::InvalidArgument,
1122 AVERROR_IO_ERROR => MuxingError::IOError,
1123 AVERROR_PIPE_ERROR => MuxingError::PipeError,
1124 AVERROR_BAD_FILE_DESCRIPTOR => MuxingError::BadFileDescriptor,
1125 AVERROR_NOT_IMPLEMENTED => MuxingError::NotImplemented,
1126 AVERROR_OPERATION_NOT_PERMITTED => MuxingError::OperationNotPermitted,
1127 AVERROR_AGAIN => MuxingError::TryAgain,
1128 _ => MuxingError::UnknownError(err_code),
1129 }
1130 }
1131}
1132
1133#[derive(thiserror::Error, Debug)]
1134#[non_exhaustive]
1135pub enum OpenEncoderError {
1136 #[error("Memory allocation error occurred during encoder initialization")]
1137 OutOfMemory,
1138
1139 #[error("Invalid argument provided to encoder")]
1140 InvalidArgument,
1141
1142 #[error("I/O error occurred while opening encoder")]
1143 IOError,
1144
1145 #[error("Broken pipe encountered during encoder initialization")]
1146 PipeError,
1147
1148 #[error("Bad file descriptor used in encoder")]
1149 BadFileDescriptor,
1150
1151 #[error("Encoder functionality not implemented or unsupported")]
1152 NotImplemented,
1153
1154 #[error("Operation not permitted while configuring encoder")]
1155 OperationNotPermitted,
1156
1157 #[error("Resource temporarily unavailable during encoder setup")]
1158 TryAgain,
1159
1160 #[error("An unknown error occurred in encoder setup. ret:{0}")]
1161 UnknownError(i32),
1162}
1163
1164impl From<i32> for OpenEncoderError {
1165 fn from(err_code: i32) -> Self {
1166 match err_code {
1167 AVERROR_OUT_OF_MEMORY => OpenEncoderError::OutOfMemory,
1168 AVERROR_INVALID_ARGUMENT => OpenEncoderError::InvalidArgument,
1169 AVERROR_IO_ERROR => OpenEncoderError::IOError,
1170 AVERROR_PIPE_ERROR => OpenEncoderError::PipeError,
1171 AVERROR_BAD_FILE_DESCRIPTOR => OpenEncoderError::BadFileDescriptor,
1172 AVERROR_NOT_IMPLEMENTED => OpenEncoderError::NotImplemented,
1173 AVERROR_OPERATION_NOT_PERMITTED => OpenEncoderError::OperationNotPermitted,
1174 AVERROR_AGAIN => OpenEncoderError::TryAgain,
1175 _ => OpenEncoderError::UnknownError(err_code),
1176 }
1177 }
1178}
1179
1180#[derive(thiserror::Error, Debug)]
1181#[non_exhaustive]
1182pub enum EncodingError {
1183 #[error("Memory allocation error during encoding")]
1184 OutOfMemory,
1185
1186 #[error("Invalid argument provided to encoder")]
1187 InvalidArgument,
1188
1189 #[error("I/O error occurred during encoding")]
1190 IOError,
1191
1192 #[error("Broken pipe encountered during encoding")]
1193 PipeError,
1194
1195 #[error("Bad file descriptor encountered during encoding")]
1196 BadFileDescriptor,
1197
1198 #[error("Functionality not implemented or unsupported encoding feature")]
1199 NotImplemented,
1200
1201 #[error("Operation not permitted for encoder")]
1202 OperationNotPermitted,
1203
1204 #[error("Resource temporarily unavailable, try again later")]
1205 TryAgain,
1206
1207 #[error("End of stream reached or no more frames to encode")]
1208 EndOfStream,
1209
1210 #[error("An unknown error occurred during encoding. ret: {0}")]
1211 UnknownError(i32),
1212}
1213
1214impl From<i32> for EncodingError {
1215 fn from(err_code: i32) -> Self {
1216 match err_code {
1217 AVERROR_OUT_OF_MEMORY => EncodingError::OutOfMemory,
1218 AVERROR_INVALID_ARGUMENT => EncodingError::InvalidArgument,
1219 AVERROR_IO_ERROR => EncodingError::IOError,
1220 AVERROR_PIPE_ERROR => EncodingError::PipeError,
1221 AVERROR_BAD_FILE_DESCRIPTOR => EncodingError::BadFileDescriptor,
1222 AVERROR_NOT_IMPLEMENTED => EncodingError::NotImplemented,
1223 AVERROR_OPERATION_NOT_PERMITTED => EncodingError::OperationNotPermitted,
1224 AVERROR_AGAIN => EncodingError::TryAgain,
1225 AVERROR_EOF => EncodingError::EndOfStream,
1226 _ => EncodingError::UnknownError(err_code),
1227 }
1228 }
1229}
1230
1231#[derive(thiserror::Error, Debug)]
1232#[non_exhaustive]
1233pub enum FilterGraphError {
1234 #[error("Memory allocation error during filter graph processing")]
1235 OutOfMemory,
1236
1237 #[error("Invalid argument provided to filter graph processing")]
1238 InvalidArgument,
1239
1240 #[error("I/O error occurred during filter graph processing")]
1241 IOError,
1242
1243 #[error("Broken pipe during filter graph processing")]
1244 PipeError,
1245
1246 #[error("Bad file descriptor encountered during filter graph processing")]
1247 BadFileDescriptor,
1248
1249 #[error("Functionality not implemented or unsupported during filter graph processing")]
1250 NotImplemented,
1251
1252 #[error("Operation not permitted during filter graph processing")]
1253 OperationNotPermitted,
1254
1255 #[error("Resource temporarily unavailable during filter graph processing")]
1256 TryAgain,
1257
1258 #[error("EOF")]
1259 EOF,
1260
1261 #[error("An unknown error occurred during filter graph processing. ret:{0}")]
1262 UnknownError(i32),
1263}
1264
1265impl From<i32> for FilterGraphError {
1266 fn from(err_code: i32) -> Self {
1267 match err_code {
1268 AVERROR_OUT_OF_MEMORY => FilterGraphError::OutOfMemory,
1269 AVERROR_INVALID_ARGUMENT => FilterGraphError::InvalidArgument,
1270 AVERROR_IO_ERROR => FilterGraphError::IOError,
1271 AVERROR_PIPE_ERROR => FilterGraphError::PipeError,
1272 AVERROR_BAD_FILE_DESCRIPTOR => FilterGraphError::BadFileDescriptor,
1273 AVERROR_NOT_IMPLEMENTED => FilterGraphError::NotImplemented,
1274 AVERROR_OPERATION_NOT_PERMITTED => FilterGraphError::OperationNotPermitted,
1275 AVERROR_AGAIN => FilterGraphError::TryAgain,
1276 AVERROR_EOF => FilterGraphError::EOF,
1277 _ => FilterGraphError::UnknownError(err_code),
1278 }
1279 }
1280}
1281
1282#[derive(thiserror::Error, Debug)]
1283#[non_exhaustive]
1284pub enum OpenDecoderError {
1285 #[error("Memory allocation error during decoder initialization")]
1286 OutOfMemory,
1287
1288 #[error("Invalid argument provided during decoder initialization")]
1289 InvalidArgument,
1290
1291 #[error("Functionality not implemented or unsupported during decoder initialization")]
1292 NotImplemented,
1293
1294 #[error("Resource temporarily unavailable during decoder initialization")]
1295 TryAgain,
1296
1297 #[error("I/O error occurred during decoder initialization")]
1298 IOError,
1299
1300 #[error("An unknown error occurred during decoder initialization: {0}")]
1301 UnknownError(i32),
1302}
1303
1304impl From<i32> for OpenDecoderError {
1305 fn from(err_code: i32) -> Self {
1306 match err_code {
1307 AVERROR_OUT_OF_MEMORY => OpenDecoderError::OutOfMemory,
1308 AVERROR_INVALID_ARGUMENT => OpenDecoderError::InvalidArgument,
1309 AVERROR_NOT_IMPLEMENTED => OpenDecoderError::NotImplemented,
1310 AVERROR_AGAIN => OpenDecoderError::TryAgain,
1311 AVERROR_IO_ERROR => OpenDecoderError::IOError,
1312 _ => OpenDecoderError::UnknownError(err_code),
1313 }
1314 }
1315}
1316
1317#[derive(thiserror::Error, Debug)]
1318#[non_exhaustive]
1319pub enum DecodingError {
1320 #[error("Memory allocation error")]
1321 OutOfMemory,
1322
1323 #[error("Invalid argument provided")]
1324 InvalidArgument,
1325
1326 #[error("I/O error occurred during decoding")]
1327 IOError,
1328
1329 #[error("Timeout occurred during decoding")]
1330 Timeout,
1331
1332 #[error("Broken pipe encountered during decoding")]
1333 PipeError,
1334
1335 #[error("Bad file descriptor encountered during decoding")]
1336 BadFileDescriptor,
1337
1338 #[error("Unsupported functionality or format encountered")]
1339 NotImplemented,
1340
1341 #[error("Operation not permitted")]
1342 OperationNotPermitted,
1343
1344 #[error("Resource temporarily unavailable")]
1345 TryAgain,
1346
1347 #[error("An unknown decoding error occurred. ret:{0}")]
1348 UnknownError(i32),
1349}
1350
1351impl From<i32> for DecodingError {
1352 fn from(err_code: i32) -> Self {
1353 match err_code {
1354 AVERROR_OUT_OF_MEMORY => DecodingError::OutOfMemory,
1355 AVERROR_INVALID_ARGUMENT => DecodingError::InvalidArgument,
1356 AVERROR_IO_ERROR => DecodingError::IOError,
1357 AVERROR_TIMEOUT => DecodingError::Timeout,
1358 AVERROR_PIPE_ERROR => DecodingError::PipeError,
1359 AVERROR_BAD_FILE_DESCRIPTOR => DecodingError::BadFileDescriptor,
1360 AVERROR_NOT_IMPLEMENTED => DecodingError::NotImplemented,
1361 AVERROR_OPERATION_NOT_PERMITTED => DecodingError::OperationNotPermitted,
1362 AVERROR_AGAIN => DecodingError::TryAgain,
1363 _ => DecodingError::UnknownError(err_code),
1364 }
1365 }
1366}
1367
1368#[derive(thiserror::Error, Debug)]
1369#[non_exhaustive]
1370pub enum DecoderError {
1371 #[error("decoder '{0}' not found")]
1372 NotFound(String),
1373}
1374
1375#[derive(thiserror::Error, Debug)]
1376#[non_exhaustive]
1377pub enum DemuxingError {
1378 #[error("Memory allocation error")]
1379 OutOfMemory,
1380
1381 #[error("Invalid argument provided")]
1382 InvalidArgument,
1383
1384 #[error("I/O error occurred during demuxing")]
1385 IOError,
1386
1387 #[error("End of file reached during demuxing")]
1388 EndOfFile,
1389
1390 #[error("Resource temporarily unavailable")]
1391 TryAgain,
1392
1393 #[error("Functionality not implemented or unsupported")]
1394 NotImplemented,
1395
1396 #[error("Operation not permitted")]
1397 OperationNotPermitted,
1398
1399 #[error("Bad file descriptor encountered")]
1400 BadFileDescriptor,
1401
1402 #[error("Invalid data found when processing input")]
1403 InvalidData,
1404
1405 #[error("{}. ret:{0}", crate::util::ffmpeg_utils::av_err2str(*.0))]
1406 UnknownError(i32),
1407}
1408
1409impl From<i32> for DemuxingError {
1410 fn from(err_code: i32) -> Self {
1411 match err_code {
1412 AVERROR_OUT_OF_MEMORY => DemuxingError::OutOfMemory,
1413 AVERROR_INVALID_ARGUMENT => DemuxingError::InvalidArgument,
1414 AVERROR_IO_ERROR => DemuxingError::IOError,
1415 AVERROR_EOF => DemuxingError::EndOfFile,
1416 AVERROR_AGAIN => DemuxingError::TryAgain,
1417 AVERROR_NOT_IMPLEMENTED => DemuxingError::NotImplemented,
1418 AVERROR_OPERATION_NOT_PERMITTED => DemuxingError::OperationNotPermitted,
1419 AVERROR_BAD_FILE_DESCRIPTOR => DemuxingError::BadFileDescriptor,
1420 AVERROR_INVALIDDATA => DemuxingError::InvalidData,
1421 _ => DemuxingError::UnknownError(err_code),
1422 }
1423 }
1424}
1425
1426#[derive(thiserror::Error, Debug)]
1428#[non_exhaustive]
1429pub enum PacketScannerError {
1430 #[error("while seeking: {0}")]
1432 SeekError(DemuxingError),
1433
1434 #[error("while reading packet: {0}")]
1436 ReadError(DemuxingError),
1437}
1438
1439#[cfg(test)]
1440mod tests {
1441 #[test]
1446 fn frame_source_thread_exited_equals_itself() {
1447 use super::Error;
1448 assert_eq!(Error::FrameSourceThreadExited, Error::FrameSourceThreadExited);
1449 assert_ne!(Error::FrameSourceThreadExited, Error::NotStarted);
1450 }
1451
1452 #[test]
1457 fn filter_graph_parse_error_maps_permission_and_socket_codes() {
1458 use super::{FilterGraphParseError, AVERROR_NOT_SOCKET, AVERROR_PERMISSION_DENIED};
1459 assert!(matches!(
1460 FilterGraphParseError::from(AVERROR_PERMISSION_DENIED),
1461 FilterGraphParseError::PermissionDenied
1462 ));
1463 assert!(matches!(
1464 FilterGraphParseError::from(AVERROR_NOT_SOCKET),
1465 FilterGraphParseError::NotSocket
1466 ));
1467 }
1468
1469 #[test]
1473 fn frame_writable_error_maps_codes_and_pins_display() {
1474 use super::{Error, FrameWritableError, AVERROR_INVALID_ARGUMENT, AVERROR_OUT_OF_MEMORY};
1475 assert!(matches!(
1476 FrameWritableError::from(AVERROR_OUT_OF_MEMORY),
1477 FrameWritableError::OutOfMemory
1478 ));
1479 assert!(matches!(
1480 FrameWritableError::from(AVERROR_INVALID_ARGUMENT),
1481 FrameWritableError::InvalidArgument
1482 ));
1483 assert!(matches!(
1484 FrameWritableError::from(-99),
1485 FrameWritableError::UnknownError(-99)
1486 ));
1487 let err = Error::from(FrameWritableError::from(AVERROR_OUT_OF_MEMORY));
1488 assert_eq!(
1489 err.to_string(),
1490 "Frame writable error: Memory allocation error while copying frame data"
1491 );
1492 }
1493
1494 #[cfg(feature = "opengl")]
1498 #[test]
1499 fn opengl_filter_error_pins_display() {
1500 use super::{Error, OpenGLFilterError};
1501 let err = Error::from(OpenGLFilterError::InvalidOption(
1502 "fragment shader must declare 'in vec2 TexCoord;'".to_string(),
1503 ));
1504 assert_eq!(
1505 err.to_string(),
1506 "OpenGL filter error: invalid OpenGL filter option: \
1507 fragment shader must declare 'in vec2 TexCoord;'"
1508 );
1509 let err = Error::from(OpenGLFilterError::ContextCreation(
1510 "Failed to create Surfman connection".to_string(),
1511 ));
1512 assert_eq!(
1513 err.to_string(),
1514 "OpenGL filter error: OpenGL context creation failed: \
1515 Failed to create Surfman connection"
1516 );
1517 }
1518}