Skip to main content

ez_ffmpeg/
error.rs

1use ffmpeg_next::ffi::AVERROR;
2use ffmpeg_sys_next::*;
3use std::ffi::NulError;
4use std::{io, result};
5
6/// Result type of all ez-ffmpeg library calls.
7pub type Result<T, E = Error> = result::Result<T, E>;
8
9#[derive(thiserror::Error, Debug)]
10pub enum Error {
11    #[error("Scheduler is not started")]
12    NotStarted,
13
14    #[error("URL error: {0}")]
15    Url(#[from] UrlError),
16
17    #[error("Open input stream error: {0}")]
18    OpenInputStream(#[from] OpenInputError),
19
20    #[error("Find stream info error: {0}")]
21    FindStream(#[from] FindStreamError),
22
23    #[error("Decoder error: {0}")]
24    Decoder(#[from] DecoderError),
25
26    #[error("Filter graph parse error: {0}")]
27    FilterGraphParse(#[from] FilterGraphParseError),
28
29    #[error("Filter description converted to utf8 string error")]
30    FilterDescUtf8,
31
32    #[error("Filter name converted to utf8 string error")]
33    FilterNameUtf8,
34
35    #[error("A filtergraph has zero outputs, this is not supported")]
36    FilterZeroOutputs,
37
38    #[error("Input is not a valid number")]
39    ParseInteger,
40
41    #[error("Alloc output context error: {0}")]
42    AllocOutputContext(#[from] AllocOutputContextError),
43
44    #[error("Open output error: {0}")]
45    OpenOutput(#[from] OpenOutputError),
46
47    #[error("Output file '{0}' is the same as an input file")]
48    FileSameAsInput(String),
49
50    #[error("Find devices error: {0}")]
51    FindDevices(#[from] FindDevicesError),
52
53    #[error("Alloc frame error: {0}")]
54    AllocFrame(#[from] AllocFrameError),
55
56    #[error("Alloc packet error: {0}")]
57    AllocPacket(#[from] AllocPacketError),
58
59    // ---- Muxing ----
60    #[error("Muxing operation failed {0}")]
61    Muxing(#[from] MuxingOperationError),
62
63    // ---- Open Encoder ----
64    #[error("Open encoder operation failed {0}")]
65    OpenEncoder(#[from] OpenEncoderOperationError),
66
67    // ---- Encoding ----
68    #[error("Encoding operation failed {0}")]
69    Encoding(#[from] EncodingOperationError),
70
71    // ---- FilterGraph ----
72    #[error("Filter graph operation failed {0}")]
73    FilterGraph(#[from] FilterGraphOperationError),
74
75    // ---- Open Decoder ----
76    #[error("Open decoder operation failed {0}")]
77    OpenDecoder(#[from] OpenDecoderOperationError),
78
79    // ---- Decoding ----
80    #[error("Decoding operation failed {0}")]
81    Decoding(#[from] DecodingOperationError),
82
83    // ---- Demuxing ----
84    #[error("Demuxing operation failed {0}")]
85    Demuxing(#[from] DemuxingOperationError),
86
87    // ---- Packet Scanner ----
88    #[error("Packet scanner error: {0}")]
89    PacketScanner(#[from] PacketScannerError),
90
91    // ---- Frame Filter ----
92    #[error("Frame filter init failed: {0}")]
93    FrameFilterInit(String),
94
95    #[error("Frame filter process failed: {0}")]
96    FrameFilterProcess(String),
97
98    #[error("Frame filter request failed: {0}")]
99    FrameFilterRequest(String),
100
101    #[error("No {0} stream of the type:{1} were found while build frame pipeline")]
102    FrameFilterTypeNoMatched(String, String),
103
104    #[error("{0} stream:{1} of the type:{2} were mismatched while build frame pipeline")]
105    FrameFilterStreamTypeNoMatched(String, usize, String),
106
107    #[error("Frame filter pipeline destination already finished")]
108    FrameFilterDstFinished,
109
110    #[error("Frame filter pipeline send frame failed, out of memory")]
111    FrameFilterSendOOM,
112
113    #[error("Frame filter pipeline thread exited")]
114    FrameFilterThreadExited,
115
116    #[cfg(feature = "rtmp")]
117    #[error("Rtmp stream already exists with key: {0}")]
118    RtmpStreamAlreadyExists(String),
119
120    #[cfg(feature = "rtmp")]
121    #[error("Rtmp create stream failed. Check whether the server is stopped.")]
122    RtmpCreateStream,
123
124    #[cfg(feature = "rtmp")]
125    #[error("Rtmp server session error: {0}")]
126    RtmpServerSession(#[from] rml_rtmp::sessions::ServerSessionError),
127
128    #[cfg(feature = "rtmp")]
129    #[error("Rtmp server thread exited")]
130    RtmpThreadExited,
131
132    #[cfg(feature = "subtitle")]
133    #[error("Subtitle error: {0}")]
134    Subtitle(#[from] crate::subtitle::SubtitleError),
135
136    #[error("IO error:{0}")]
137    IO(#[from] io::Error),
138
139    #[error("EOF")]
140    EOF,
141    #[error("Exit")]
142    Exit,
143    #[error("Bug")]
144    Bug,
145
146    #[error("Invalid recipe argument: {0}")]
147    InvalidRecipeArg(String),
148}
149
150/// Error type for RTMP streaming operations using StreamBuilder
151#[cfg(feature = "rtmp")]
152#[derive(thiserror::Error, Debug)]
153pub enum StreamError {
154    #[error("missing required parameter: {0}")]
155    MissingParameter(&'static str),
156
157    #[error("input path is not a valid file: {path}")]
158    InputNotFound { path: std::path::PathBuf },
159
160    #[error("ffmpeg error: {0}")]
161    Ffmpeg(#[from] crate::error::Error),
162}
163
164impl PartialEq for Error {
165    /// Structural equality for payload-less variants only. Variants carrying
166    /// an inner error compare unequal even to themselves — use matches! on
167    /// the variant when that is what you mean.
168    fn eq(&self, other: &Self) -> bool {
169        use Error::*;
170        match (self, other) {
171            (NotStarted, NotStarted)
172            | (FilterDescUtf8, FilterDescUtf8)
173            | (FilterNameUtf8, FilterNameUtf8)
174            | (FilterZeroOutputs, FilterZeroOutputs)
175            | (ParseInteger, ParseInteger)
176            | (FrameFilterDstFinished, FrameFilterDstFinished)
177            | (FrameFilterSendOOM, FrameFilterSendOOM)
178            | (FrameFilterThreadExited, FrameFilterThreadExited)
179            | (EOF, EOF)
180            | (Exit, Exit)
181            | (Bug, Bug) => true,
182            #[cfg(feature = "rtmp")]
183            (RtmpCreateStream, RtmpCreateStream) | (RtmpThreadExited, RtmpThreadExited) => true,
184            _ => false,
185        }
186    }
187}
188
189// No Eq impl: variants carrying payloads are not equal to themselves, so
190// the relation is not reflexive and claiming Eq would be a lie.
191
192#[derive(thiserror::Error, Debug)]
193pub enum DemuxingOperationError {
194    #[error("while reading frame: {0}")]
195    ReadFrameError(DemuxingError),
196
197    #[error("while referencing packet: {0}")]
198    PacketRefError(DemuxingError),
199
200    #[error("while seeking file: {0}")]
201    SeekFileError(DemuxingError),
202
203    #[error("Thread exited")]
204    ThreadExited,
205}
206
207#[derive(thiserror::Error, Debug)]
208pub enum DecodingOperationError {
209    #[error("during frame reference creation: {0}")]
210    FrameRefError(DecodingError),
211
212    #[error("during frame properties copy: {0}")]
213    FrameCopyPropsError(DecodingError),
214
215    #[error("during subtitle decoding: {0}")]
216    DecodeSubtitleError(DecodingError),
217
218    #[error("during subtitle copy: {0}")]
219    CopySubtitleError(DecodingError),
220
221    #[error("during packet submission to decoder: {0}")]
222    SendPacketError(DecodingError),
223
224    #[error("during frame reception from decoder: {0}")]
225    ReceiveFrameError(DecodingError),
226
227    #[error("during frame allocation: {0}")]
228    FrameAllocationError(DecodingError),
229
230    #[error("during packet allocation: {0}")]
231    PacketAllocationError(DecodingError),
232
233    #[error("during AVSubtitle allocation: {0}")]
234    SubtitleAllocationError(DecodingError),
235
236    #[error("corrupt decoded frame")]
237    CorruptFrame,
238
239    #[error("decode error rate exceeded the maximum allowed")]
240    ErrorRateExceeded,
241
242    #[error("during retrieve data on hw: {0}")]
243    HWRetrieveDataError(DecodingError),
244
245    #[error("during cropping: {0}")]
246    CroppingError(DecodingError),
247}
248
249#[derive(thiserror::Error, Debug)]
250pub enum OpenDecoderOperationError {
251    #[error("during context allocation: {0}")]
252    ContextAllocationError(OpenDecoderError),
253
254    #[error("while applying parameters to context: {0}")]
255    ParameterApplicationError(OpenDecoderError),
256
257    #[error("while opening decoder: {0}")]
258    DecoderOpenError(OpenDecoderError),
259
260    #[error("while copying channel layout: {0}")]
261    ChannelLayoutCopyError(OpenDecoderError),
262
263    #[error("while Hw setup: {0}")]
264    HwSetupError(OpenDecoderError),
265
266    #[error("Invalid decoder name")]
267    InvalidName,
268
269    #[error("Thread exited")]
270    ThreadExited,
271}
272
273#[derive(thiserror::Error, Debug)]
274pub enum FilterGraphOperationError {
275    #[error("during requesting oldest frame: {0}")]
276    RequestOldestError(FilterGraphError),
277
278    #[error("during process frames: {0}")]
279    ProcessFramesError(FilterGraphError),
280
281    #[error("during send frames: {0}")]
282    SendFramesError(FilterGraphError),
283
284    #[error("during copying channel layout: {0}")]
285    ChannelLayoutCopyError(FilterGraphError),
286
287    #[error("during buffer source add frame: {0}")]
288    BufferSourceAddFrameError(FilterGraphError),
289
290    #[error("during closing buffer source: {0}")]
291    BufferSourceCloseError(FilterGraphError),
292
293    #[error("during replace buffer: {0}")]
294    BufferReplaceoseError(FilterGraphError),
295
296    #[error("during cloning frame side data: {0}")]
297    FrameSideDataCloneError(FilterGraphError),
298
299    #[error("during parse: {0}")]
300    ParseError(FilterGraphParseError),
301
302    #[error("The data in the frame is invalid or corrupted")]
303    InvalidData,
304
305    #[error("Thread exited")]
306    ThreadExited,
307}
308
309#[derive(thiserror::Error, Debug)]
310pub enum EncodingOperationError {
311    #[error("during frame submission: {0}")]
312    SendFrameError(EncodingError),
313
314    #[error("during packet retrieval: {0}")]
315    ReceivePacketError(EncodingError),
316
317    #[error("during audio frame receive: {0}")]
318    ReceiveAudioError(EncodingError),
319
320    #[error(": Subtitle packets must have a pts")]
321    SubtitleNotPts,
322
323    #[error(": Muxer already finished")]
324    MuxerFinished,
325
326    #[error("Encode subtitle error: {0}")]
327    EncodeSubtitle(#[from] EncodeSubtitleError),
328
329    #[error(": {0}")]
330    AllocPacket(AllocPacketError),
331}
332
333#[derive(thiserror::Error, Debug)]
334pub enum MuxingOperationError {
335    #[error("during write header: {0}")]
336    WriteHeader(WriteHeaderError),
337
338    #[error("during interleaved write: {0}")]
339    InterleavedWriteError(MuxingError),
340
341    #[error("during trailer write: {0}")]
342    TrailerWriteError(MuxingError),
343
344    #[error("during closing IO: {0}")]
345    IOCloseError(MuxingError),
346
347    #[error("Thread exited")]
348    ThreadExited,
349}
350
351#[derive(thiserror::Error, Debug)]
352pub enum OpenEncoderOperationError {
353    #[error("during frame side data cloning: {0}")]
354    FrameSideDataCloneError(OpenEncoderError),
355
356    #[error("during channel layout copying: {0}")]
357    ChannelLayoutCopyError(OpenEncoderError),
358
359    #[error("during codec opening: {0}")]
360    CodecOpenError(OpenEncoderError),
361
362    #[error("while setting codec parameters: {0}")]
363    CodecParametersError(OpenEncoderError),
364
365    #[error(": unknown format of the frame")]
366    UnknownFrameFormat,
367
368    #[error("while setting subtitle: {0}")]
369    SettingSubtitleError(OpenEncoderError),
370
371    #[error("while Hw setup: {0}")]
372    HwSetupError(OpenEncoderError),
373
374    #[error("during context allocation: {0}")]
375    ContextAllocationError(OpenEncoderError),
376
377    #[error(": no frames were received before EOF; encoder never opened")]
378    NoFramesReceived,
379
380    #[error(": unsupported media type for encoding")]
381    UnsupportedMediaType,
382
383    #[error("Thread exited")]
384    ThreadExited,
385}
386
387#[derive(thiserror::Error, Debug)]
388pub enum UrlError {
389    #[error("Null byte found in string at position {0}")]
390    NullByteError(usize),
391}
392
393impl From<NulError> for Error {
394    fn from(err: NulError) -> Self {
395        Error::Url(UrlError::NullByteError(err.nul_position()))
396    }
397}
398
399#[derive(thiserror::Error, Debug)]
400pub enum OpenInputError {
401    #[error("Memory allocation error")]
402    OutOfMemory,
403
404    #[error("Invalid argument provided")]
405    InvalidArgument,
406
407    #[error("File or stream not found")]
408    NotFound,
409
410    #[error("I/O error occurred while opening the file or stream")]
411    IOError,
412
413    #[error("Pipe error, possibly the stream or data connection was broken")]
414    PipeError,
415
416    #[error("Invalid file descriptor")]
417    BadFileDescriptor,
418
419    #[error("Functionality not implemented or unsupported input format")]
420    NotImplemented,
421
422    #[error("Operation not permitted to access the file or stream")]
423    OperationNotPermitted,
424
425    #[error("The data in the file or stream is invalid or corrupted")]
426    InvalidData,
427
428    #[error("The connection timed out while trying to open the stream")]
429    Timeout,
430
431    #[error("{}. ret:{0}", crate::util::ffmpeg_utils::av_err2str(*.0))]
432    UnknownError(i32),
433
434    #[error("Invalid source provided")]
435    InvalidSource,
436
437    #[error("Invalid source format:{0}")]
438    InvalidFormat(String),
439
440    #[error("No seek callback is provided")]
441    SeekFunctionMissing,
442}
443
444impl From<i32> for OpenInputError {
445    fn from(err_code: i32) -> Self {
446        match err_code {
447            AVERROR_OUT_OF_MEMORY => OpenInputError::OutOfMemory,
448            AVERROR_INVALID_ARGUMENT => OpenInputError::InvalidArgument,
449            AVERROR_NOT_FOUND => OpenInputError::NotFound,
450            AVERROR_IO_ERROR => OpenInputError::IOError,
451            AVERROR_PIPE_ERROR => OpenInputError::PipeError,
452            AVERROR_BAD_FILE_DESCRIPTOR => OpenInputError::BadFileDescriptor,
453            AVERROR_NOT_IMPLEMENTED => OpenInputError::NotImplemented,
454            AVERROR_OPERATION_NOT_PERMITTED => OpenInputError::OperationNotPermitted,
455            AVERROR_INVALIDDATA => OpenInputError::InvalidData,
456            AVERROR_TIMEOUT => OpenInputError::Timeout,
457            _ => OpenInputError::UnknownError(err_code),
458        }
459    }
460}
461
462const AVERROR_OUT_OF_MEMORY: i32 = AVERROR(ENOMEM);
463const AVERROR_INVALID_ARGUMENT: i32 = AVERROR(EINVAL);
464const AVERROR_NOT_FOUND: i32 = AVERROR(ENOENT);
465const AVERROR_IO_ERROR: i32 = AVERROR(EIO);
466const AVERROR_PIPE_ERROR: i32 = AVERROR(EPIPE);
467const AVERROR_BAD_FILE_DESCRIPTOR: i32 = AVERROR(EBADF);
468const AVERROR_NOT_IMPLEMENTED: i32 = AVERROR(ENOSYS);
469const AVERROR_OPERATION_NOT_PERMITTED: i32 = AVERROR(EPERM);
470const AVERROR_PERMISSION_DENIED: i32 = AVERROR(EACCES);
471const AVERROR_TIMEOUT: i32 = AVERROR(ETIMEDOUT);
472const AVERROR_NOT_SOCKET: i32 = AVERROR(ENOTSOCK);
473const AVERROR_AGAIN: i32 = AVERROR(EAGAIN);
474
475#[derive(thiserror::Error, Debug)]
476pub enum FindStreamError {
477    #[error("Memory allocation error")]
478    OutOfMemory,
479
480    #[error("Invalid argument provided")]
481    InvalidArgument,
482
483    #[error("Reached end of file while looking for stream info")]
484    EndOfFile,
485
486    #[error("Timeout occurred while reading stream info")]
487    Timeout,
488
489    #[error("I/O error occurred while reading stream info")]
490    IOError,
491
492    #[error("The data in the stream is invalid or corrupted")]
493    InvalidData,
494
495    #[error("Functionality not implemented or unsupported stream format")]
496    NotImplemented,
497
498    #[error("Operation not permitted to access the file or stream")]
499    OperationNotPermitted,
500
501    #[error("No Stream found")]
502    NoStreamFound,
503
504    #[error("{}. ret:{0}", crate::util::ffmpeg_utils::av_err2str(*.0))]
505    UnknownError(i32),
506}
507
508impl From<i32> for FindStreamError {
509    fn from(err_code: i32) -> Self {
510        match err_code {
511            AVERROR_OUT_OF_MEMORY => FindStreamError::OutOfMemory,
512            AVERROR_INVALID_ARGUMENT => FindStreamError::InvalidArgument,
513            AVERROR_EOF => FindStreamError::EndOfFile,
514            AVERROR_TIMEOUT => FindStreamError::Timeout,
515            AVERROR_IO_ERROR => FindStreamError::IOError,
516            AVERROR_INVALIDDATA => FindStreamError::InvalidData,
517            AVERROR_NOT_IMPLEMENTED => FindStreamError::NotImplemented,
518            AVERROR_OPERATION_NOT_PERMITTED => FindStreamError::OperationNotPermitted,
519            _ => FindStreamError::UnknownError(err_code),
520        }
521    }
522}
523
524#[derive(thiserror::Error, Debug)]
525pub enum FilterGraphParseError {
526    #[error("Memory allocation error")]
527    OutOfMemory,
528
529    #[error("Invalid argument provided")]
530    InvalidArgument,
531
532    #[error("End of file reached during parsing")]
533    EndOfFile,
534
535    #[error("I/O error occurred during parsing")]
536    IOError,
537
538    #[error("Invalid data encountered during parsing")]
539    InvalidData,
540
541    #[error("Functionality not implemented or unsupported filter format")]
542    NotImplemented,
543
544    #[error("Permission denied during filter graph parsing")]
545    PermissionDenied,
546
547    #[error("Socket operation on non-socket during filter graph parsing")]
548    NotSocket,
549
550    #[error("Option not found during filter graph configuration")]
551    OptionNotFound,
552
553    #[error("Invalid file index {0} in filtergraph description {1}")]
554    InvalidFileIndexInFg(usize, String),
555
556    #[error("Invalid file index {0} in output url: {1}")]
557    InvalidFileIndexInOutput(usize, String),
558
559    #[error("Invalid filter specifier {0}")]
560    InvalidFilterSpecifier(String),
561
562    #[error("Filter '{0}' has output {1} ({2}) unconnected")]
563    OutputUnconnected(String, usize, String),
564
565    #[error("An unknown error occurred. ret: {0}")]
566    UnknownError(i32),
567}
568
569impl From<i32> for FilterGraphParseError {
570    fn from(err_code: i32) -> Self {
571        match err_code {
572            AVERROR_OUT_OF_MEMORY => FilterGraphParseError::OutOfMemory,
573            AVERROR_INVALID_ARGUMENT => FilterGraphParseError::InvalidArgument,
574            AVERROR_EOF => FilterGraphParseError::EndOfFile,
575            AVERROR_IO_ERROR => FilterGraphParseError::IOError,
576            AVERROR_INVALIDDATA => FilterGraphParseError::InvalidData,
577            AVERROR_NOT_IMPLEMENTED => FilterGraphParseError::NotImplemented,
578            AVERROR_OPTION_NOT_FOUND => FilterGraphParseError::OptionNotFound,
579            _ => FilterGraphParseError::UnknownError(err_code),
580        }
581    }
582}
583
584#[derive(thiserror::Error, Debug)]
585pub enum AllocOutputContextError {
586    #[error("Memory allocation error")]
587    OutOfMemory,
588
589    #[error("Invalid argument provided")]
590    InvalidArgument,
591
592    #[error("File or stream not found")]
593    NotFound,
594
595    #[error("I/O error occurred while allocating the output context")]
596    IOError,
597
598    #[error("Pipe error, possibly the stream or data connection was broken")]
599    PipeError,
600
601    #[error("Invalid file descriptor")]
602    BadFileDescriptor,
603
604    #[error("Functionality not implemented or unsupported output format")]
605    NotImplemented,
606
607    #[error("Operation not permitted to allocate the output context")]
608    OperationNotPermitted,
609
610    #[error("Permission denied while allocating the output context")]
611    PermissionDenied,
612
613    #[error("The connection timed out while trying to allocate the output context")]
614    Timeout,
615
616    #[error("{}. ret:{0}", crate::util::ffmpeg_utils::av_err2str(*.0))]
617    UnknownError(i32),
618}
619
620impl From<i32> for AllocOutputContextError {
621    fn from(err_code: i32) -> Self {
622        match err_code {
623            AVERROR_OUT_OF_MEMORY => AllocOutputContextError::OutOfMemory,
624            AVERROR_INVALID_ARGUMENT => AllocOutputContextError::InvalidArgument,
625            AVERROR_NOT_FOUND => AllocOutputContextError::NotFound,
626            AVERROR_IO_ERROR => AllocOutputContextError::IOError,
627            AVERROR_PIPE_ERROR => AllocOutputContextError::PipeError,
628            AVERROR_BAD_FILE_DESCRIPTOR => AllocOutputContextError::BadFileDescriptor,
629            AVERROR_NOT_IMPLEMENTED => AllocOutputContextError::NotImplemented,
630            AVERROR_OPERATION_NOT_PERMITTED => AllocOutputContextError::OperationNotPermitted,
631            AVERROR_PERMISSION_DENIED => AllocOutputContextError::PermissionDenied,
632            AVERROR_TIMEOUT => AllocOutputContextError::Timeout,
633            _ => AllocOutputContextError::UnknownError(err_code),
634        }
635    }
636}
637
638#[derive(thiserror::Error, Debug)]
639pub enum OpenOutputError {
640    #[error("Memory allocation error")]
641    OutOfMemory,
642
643    #[error("Invalid argument provided")]
644    InvalidArgument,
645
646    #[error("File or stream not found")]
647    NotFound,
648
649    #[error("I/O error occurred while opening the file or stream")]
650    IOError,
651
652    #[error("Pipe error, possibly the stream or data connection was broken")]
653    PipeError,
654
655    #[error("Invalid file descriptor")]
656    BadFileDescriptor,
657
658    #[error("Functionality not implemented or unsupported output format")]
659    NotImplemented,
660
661    #[error("Operation not permitted to open the file or stream")]
662    OperationNotPermitted,
663
664    #[error("Permission denied while opening the file or stream")]
665    PermissionDenied,
666
667    #[error("The connection timed out while trying to open the file or stream")]
668    Timeout,
669
670    #[error("encoder not found")]
671    EncoderNotFound,
672
673    #[error("Stream map '{0}' matches no streams;")]
674    MatchesNoStreams(String),
675
676    #[error("Invalid label {0}")]
677    InvalidLabel(String),
678
679    #[error("not contain any stream")]
680    NotContainStream,
681
682    #[error("unknown format of the frame")]
683    UnknownFrameFormat,
684
685    #[error("Invalid file index {0} in input url: {1}")]
686    InvalidFileIndexInIntput(usize, String),
687
688    #[error("{}. ret:{0}", crate::util::ffmpeg_utils::av_err2str(*.0))]
689    UnknownError(i32),
690
691    #[error("Invalid sink provided")]
692    InvalidSink,
693
694    #[error("No seek callback is provided")]
695    SeekFunctionMissing,
696
697    #[error("Format '{0}' is unsupported")]
698    FormatUnsupported(String),
699
700    #[error("Unknown pixel format: '{0}'")]
701    UnknownPixelFormat(String),
702}
703
704impl From<i32> for OpenOutputError {
705    fn from(err_code: i32) -> Self {
706        match err_code {
707            AVERROR_OUT_OF_MEMORY => OpenOutputError::OutOfMemory,
708            AVERROR_INVALID_ARGUMENT => OpenOutputError::InvalidArgument,
709            AVERROR_NOT_FOUND => OpenOutputError::NotFound,
710            AVERROR_IO_ERROR => OpenOutputError::IOError,
711            AVERROR_PIPE_ERROR => OpenOutputError::PipeError,
712            AVERROR_BAD_FILE_DESCRIPTOR => OpenOutputError::BadFileDescriptor,
713            AVERROR_NOT_IMPLEMENTED => OpenOutputError::NotImplemented,
714            AVERROR_OPERATION_NOT_PERMITTED => OpenOutputError::OperationNotPermitted,
715            AVERROR_PERMISSION_DENIED => OpenOutputError::PermissionDenied,
716            AVERROR_TIMEOUT => OpenOutputError::Timeout,
717            AVERROR_ENCODER_NOT_FOUND => OpenOutputError::EncoderNotFound,
718            _ => OpenOutputError::UnknownError(err_code),
719        }
720    }
721}
722
723#[derive(thiserror::Error, Debug)]
724pub enum FindDevicesError {
725    #[error("AVCaptureDevice class not found in macOS")]
726    AVCaptureDeviceNotFound,
727
728    #[error("current media_type({0}) is not supported")]
729    MediaTypeSupported(i32),
730    #[error("current OS is not supported")]
731    OsNotSupported,
732    #[error("device_description can not to string")]
733    UTF8Error,
734
735    #[error("Memory allocation error")]
736    OutOfMemory,
737    #[error("Invalid argument provided")]
738    InvalidArgument,
739    #[error("Device or stream not found")]
740    NotFound,
741    #[error("I/O error occurred while accessing the device or stream")]
742    IOError,
743    #[error("Operation not permitted for this device or stream")]
744    OperationNotPermitted,
745    #[error("Permission denied while accessing the device or stream")]
746    PermissionDenied,
747    #[error("This functionality is not implemented")]
748    NotImplemented,
749    #[error("Bad file descriptor")]
750    BadFileDescriptor,
751    #[error("{}. ret:{0}", crate::util::ffmpeg_utils::av_err2str(*.0))]
752    UnknownError(i32),
753}
754
755impl From<i32> for FindDevicesError {
756    fn from(err_code: i32) -> Self {
757        match err_code {
758            AVERROR_OUT_OF_MEMORY => FindDevicesError::OutOfMemory,
759            AVERROR_INVALID_ARGUMENT => FindDevicesError::InvalidArgument,
760            AVERROR_NOT_FOUND => FindDevicesError::NotFound,
761            AVERROR_IO_ERROR => FindDevicesError::IOError,
762            AVERROR_OPERATION_NOT_PERMITTED => FindDevicesError::OperationNotPermitted,
763            AVERROR_PERMISSION_DENIED => FindDevicesError::PermissionDenied,
764            AVERROR_NOT_IMPLEMENTED => FindDevicesError::NotImplemented,
765            AVERROR_BAD_FILE_DESCRIPTOR => FindDevicesError::BadFileDescriptor,
766            _ => FindDevicesError::UnknownError(err_code),
767        }
768    }
769}
770
771#[derive(thiserror::Error, Debug)]
772pub enum WriteHeaderError {
773    #[error("Memory allocation error")]
774    OutOfMemory,
775
776    #[error("Invalid argument provided")]
777    InvalidArgument,
778
779    #[error("File or stream not found")]
780    NotFound,
781
782    #[error("I/O error occurred while writing the header")]
783    IOError,
784
785    #[error("Pipe error, possibly the stream or data connection was broken")]
786    PipeError,
787
788    #[error("Invalid file descriptor")]
789    BadFileDescriptor,
790
791    #[error("Functionality not implemented or unsupported output format")]
792    NotImplemented,
793
794    #[error("Operation not permitted to write the header")]
795    OperationNotPermitted,
796
797    #[error("Permission denied while writing the header")]
798    PermissionDenied,
799
800    #[error("The connection timed out while trying to write the header")]
801    Timeout,
802
803    #[error("{}. ret:{0}", crate::util::ffmpeg_utils::av_err2str(*.0))]
804    UnknownError(i32),
805}
806
807impl From<i32> for WriteHeaderError {
808    fn from(err_code: i32) -> Self {
809        match err_code {
810            AVERROR_OUT_OF_MEMORY => WriteHeaderError::OutOfMemory,
811            AVERROR_INVALID_ARGUMENT => WriteHeaderError::InvalidArgument,
812            AVERROR_NOT_FOUND => WriteHeaderError::NotFound,
813            AVERROR_IO_ERROR => WriteHeaderError::IOError,
814            AVERROR_PIPE_ERROR => WriteHeaderError::PipeError,
815            AVERROR_BAD_FILE_DESCRIPTOR => WriteHeaderError::BadFileDescriptor,
816            AVERROR_NOT_IMPLEMENTED => WriteHeaderError::NotImplemented,
817            AVERROR_OPERATION_NOT_PERMITTED => WriteHeaderError::OperationNotPermitted,
818            AVERROR_PERMISSION_DENIED => WriteHeaderError::PermissionDenied,
819            AVERROR_TIMEOUT => WriteHeaderError::Timeout,
820            _ => WriteHeaderError::UnknownError(err_code),
821        }
822    }
823}
824
825#[derive(thiserror::Error, Debug)]
826pub enum WriteFrameError {
827    #[error("Memory allocation error")]
828    OutOfMemory,
829
830    #[error("Invalid argument provided")]
831    InvalidArgument,
832
833    #[error("Reached end of file while writing data")]
834    EndOfFile,
835
836    #[error("Timeout occurred while writing data")]
837    Timeout,
838
839    #[error("I/O error occurred while writing data")]
840    IOError,
841
842    #[error("Bad file descriptor")]
843    BadFileDescriptor,
844
845    #[error("Pipe error occurred")]
846    PipeError,
847
848    #[error("Functionality not implemented or unsupported operation")]
849    NotImplemented,
850
851    #[error("Operation not permitted")]
852    OperationNotPermitted,
853
854    #[error("Permission denied")]
855    PermissionDenied,
856
857    #[error("Not a valid socket")]
858    NotSocket,
859
860    #[error("An unknown error occurred. ret: {0}")]
861    UnknownError(i32),
862}
863
864impl From<i32> for WriteFrameError {
865    fn from(err_code: i32) -> Self {
866        match err_code {
867            AVERROR_OUT_OF_MEMORY => WriteFrameError::OutOfMemory,
868            AVERROR_INVALID_ARGUMENT => WriteFrameError::InvalidArgument,
869            AVERROR_EOF => WriteFrameError::EndOfFile,
870            AVERROR_TIMEOUT => WriteFrameError::Timeout,
871            AVERROR_IO_ERROR => WriteFrameError::IOError,
872            AVERROR_BAD_FILE_DESCRIPTOR => WriteFrameError::BadFileDescriptor,
873            AVERROR_PIPE_ERROR => WriteFrameError::PipeError,
874            AVERROR_NOT_IMPLEMENTED => WriteFrameError::NotImplemented,
875            AVERROR_OPERATION_NOT_PERMITTED => WriteFrameError::OperationNotPermitted,
876            AVERROR_PERMISSION_DENIED => WriteFrameError::PermissionDenied,
877            AVERROR_NOT_SOCKET => WriteFrameError::NotSocket,
878            _ => WriteFrameError::UnknownError(err_code),
879        }
880    }
881}
882
883#[derive(thiserror::Error, Debug)]
884pub enum EncodeSubtitleError {
885    #[error("Memory allocation error while encoding subtitle")]
886    OutOfMemory,
887
888    #[error("Invalid argument provided for subtitle encoding")]
889    InvalidArgument,
890
891    #[error("Operation not permitted while encoding subtitle")]
892    OperationNotPermitted,
893
894    #[error("The encoding functionality is not implemented or unsupported")]
895    NotImplemented,
896
897    #[error("Encoder temporarily unable to process, please retry")]
898    TryAgain,
899
900    #[error("Subtitle encoding failed with unknown error. ret: {0}")]
901    UnknownError(i32),
902}
903
904impl From<i32> for EncodeSubtitleError {
905    fn from(err_code: i32) -> Self {
906        match err_code {
907            AVERROR_OUT_OF_MEMORY => EncodeSubtitleError::OutOfMemory,
908            AVERROR_INVALID_ARGUMENT => EncodeSubtitleError::InvalidArgument,
909            AVERROR_OPERATION_NOT_PERMITTED => EncodeSubtitleError::OperationNotPermitted,
910            AVERROR_NOT_IMPLEMENTED => EncodeSubtitleError::NotImplemented,
911            AVERROR_AGAIN => EncodeSubtitleError::TryAgain,
912            _ => EncodeSubtitleError::UnknownError(err_code),
913        }
914    }
915}
916
917#[derive(thiserror::Error, Debug)]
918pub enum AllocPacketError {
919    #[error("Memory allocation error while alloc packet")]
920    OutOfMemory,
921}
922
923#[derive(thiserror::Error, Debug)]
924pub enum AllocFrameError {
925    #[error("Memory allocation error while alloc frame")]
926    OutOfMemory,
927}
928
929#[derive(thiserror::Error, Debug)]
930pub enum MuxingError {
931    #[error("Memory allocation error")]
932    OutOfMemory,
933
934    #[error("Invalid argument provided")]
935    InvalidArgument,
936
937    #[error("I/O error occurred during muxing")]
938    IOError,
939
940    #[error("Broken pipe during muxing")]
941    PipeError,
942
943    #[error("Bad file descriptor encountered")]
944    BadFileDescriptor,
945
946    #[error("Functionality not implemented or unsupported")]
947    NotImplemented,
948
949    #[error("Operation not permitted")]
950    OperationNotPermitted,
951
952    #[error("Resource temporarily unavailable")]
953    TryAgain,
954
955    #[error("{}. ret:{0}", crate::util::ffmpeg_utils::av_err2str(*.0))]
956    UnknownError(i32),
957}
958
959impl From<i32> for MuxingError {
960    fn from(err_code: i32) -> Self {
961        match err_code {
962            AVERROR_OUT_OF_MEMORY => MuxingError::OutOfMemory,
963            AVERROR_INVALID_ARGUMENT => MuxingError::InvalidArgument,
964            AVERROR_IO_ERROR => MuxingError::IOError,
965            AVERROR_PIPE_ERROR => MuxingError::PipeError,
966            AVERROR_BAD_FILE_DESCRIPTOR => MuxingError::BadFileDescriptor,
967            AVERROR_NOT_IMPLEMENTED => MuxingError::NotImplemented,
968            AVERROR_OPERATION_NOT_PERMITTED => MuxingError::OperationNotPermitted,
969            AVERROR_AGAIN => MuxingError::TryAgain,
970            _ => MuxingError::UnknownError(err_code),
971        }
972    }
973}
974
975#[derive(thiserror::Error, Debug)]
976pub enum OpenEncoderError {
977    #[error("Memory allocation error occurred during encoder initialization")]
978    OutOfMemory,
979
980    #[error("Invalid argument provided to encoder")]
981    InvalidArgument,
982
983    #[error("I/O error occurred while opening encoder")]
984    IOError,
985
986    #[error("Broken pipe encountered during encoder initialization")]
987    PipeError,
988
989    #[error("Bad file descriptor used in encoder")]
990    BadFileDescriptor,
991
992    #[error("Encoder functionality not implemented or unsupported")]
993    NotImplemented,
994
995    #[error("Operation not permitted while configuring encoder")]
996    OperationNotPermitted,
997
998    #[error("Resource temporarily unavailable during encoder setup")]
999    TryAgain,
1000
1001    #[error("An unknown error occurred in encoder setup. ret:{0}")]
1002    UnknownError(i32),
1003}
1004
1005impl From<i32> for OpenEncoderError {
1006    fn from(err_code: i32) -> Self {
1007        match err_code {
1008            AVERROR_OUT_OF_MEMORY => OpenEncoderError::OutOfMemory,
1009            AVERROR_INVALID_ARGUMENT => OpenEncoderError::InvalidArgument,
1010            AVERROR_IO_ERROR => OpenEncoderError::IOError,
1011            AVERROR_PIPE_ERROR => OpenEncoderError::PipeError,
1012            AVERROR_BAD_FILE_DESCRIPTOR => OpenEncoderError::BadFileDescriptor,
1013            AVERROR_NOT_IMPLEMENTED => OpenEncoderError::NotImplemented,
1014            AVERROR_OPERATION_NOT_PERMITTED => OpenEncoderError::OperationNotPermitted,
1015            AVERROR_AGAIN => OpenEncoderError::TryAgain,
1016            _ => OpenEncoderError::UnknownError(err_code),
1017        }
1018    }
1019}
1020
1021#[derive(thiserror::Error, Debug)]
1022pub enum EncodingError {
1023    #[error("Memory allocation error during encoding")]
1024    OutOfMemory,
1025
1026    #[error("Invalid argument provided to encoder")]
1027    InvalidArgument,
1028
1029    #[error("I/O error occurred during encoding")]
1030    IOError,
1031
1032    #[error("Broken pipe encountered during encoding")]
1033    PipeError,
1034
1035    #[error("Bad file descriptor encountered during encoding")]
1036    BadFileDescriptor,
1037
1038    #[error("Functionality not implemented or unsupported encoding feature")]
1039    NotImplemented,
1040
1041    #[error("Operation not permitted for encoder")]
1042    OperationNotPermitted,
1043
1044    #[error("Resource temporarily unavailable, try again later")]
1045    TryAgain,
1046
1047    #[error("End of stream reached or no more frames to encode")]
1048    EndOfStream,
1049
1050    #[error("An unknown error occurred during encoding. ret: {0}")]
1051    UnknownError(i32),
1052}
1053
1054impl From<i32> for EncodingError {
1055    fn from(err_code: i32) -> Self {
1056        match err_code {
1057            AVERROR_OUT_OF_MEMORY => EncodingError::OutOfMemory,
1058            AVERROR_INVALID_ARGUMENT => EncodingError::InvalidArgument,
1059            AVERROR_IO_ERROR => EncodingError::IOError,
1060            AVERROR_PIPE_ERROR => EncodingError::PipeError,
1061            AVERROR_BAD_FILE_DESCRIPTOR => EncodingError::BadFileDescriptor,
1062            AVERROR_NOT_IMPLEMENTED => EncodingError::NotImplemented,
1063            AVERROR_OPERATION_NOT_PERMITTED => EncodingError::OperationNotPermitted,
1064            AVERROR_AGAIN => EncodingError::TryAgain,
1065            AVERROR_EOF => EncodingError::EndOfStream,
1066            _ => EncodingError::UnknownError(err_code),
1067        }
1068    }
1069}
1070
1071#[derive(thiserror::Error, Debug)]
1072pub enum FilterGraphError {
1073    #[error("Memory allocation error during filter graph processing")]
1074    OutOfMemory,
1075
1076    #[error("Invalid argument provided to filter graph processing")]
1077    InvalidArgument,
1078
1079    #[error("I/O error occurred during filter graph processing")]
1080    IOError,
1081
1082    #[error("Broken pipe during filter graph processing")]
1083    PipeError,
1084
1085    #[error("Bad file descriptor encountered during filter graph processing")]
1086    BadFileDescriptor,
1087
1088    #[error("Functionality not implemented or unsupported during filter graph processing")]
1089    NotImplemented,
1090
1091    #[error("Operation not permitted during filter graph processing")]
1092    OperationNotPermitted,
1093
1094    #[error("Resource temporarily unavailable during filter graph processing")]
1095    TryAgain,
1096
1097    #[error("EOF")]
1098    EOF,
1099
1100    #[error("An unknown error occurred during filter graph processing. ret:{0}")]
1101    UnknownError(i32),
1102}
1103
1104impl From<i32> for FilterGraphError {
1105    fn from(err_code: i32) -> Self {
1106        match err_code {
1107            AVERROR_OUT_OF_MEMORY => FilterGraphError::OutOfMemory,
1108            AVERROR_INVALID_ARGUMENT => FilterGraphError::InvalidArgument,
1109            AVERROR_IO_ERROR => FilterGraphError::IOError,
1110            AVERROR_PIPE_ERROR => FilterGraphError::PipeError,
1111            AVERROR_BAD_FILE_DESCRIPTOR => FilterGraphError::BadFileDescriptor,
1112            AVERROR_NOT_IMPLEMENTED => FilterGraphError::NotImplemented,
1113            AVERROR_OPERATION_NOT_PERMITTED => FilterGraphError::OperationNotPermitted,
1114            AVERROR_AGAIN => FilterGraphError::TryAgain,
1115            AVERROR_EOF => FilterGraphError::EOF,
1116            _ => FilterGraphError::UnknownError(err_code),
1117        }
1118    }
1119}
1120
1121#[derive(thiserror::Error, Debug)]
1122pub enum OpenDecoderError {
1123    #[error("Memory allocation error during decoder initialization")]
1124    OutOfMemory,
1125
1126    #[error("Invalid argument provided during decoder initialization")]
1127    InvalidArgument,
1128
1129    #[error("Functionality not implemented or unsupported during decoder initialization")]
1130    NotImplemented,
1131
1132    #[error("Resource temporarily unavailable during decoder initialization")]
1133    TryAgain,
1134
1135    #[error("I/O error occurred during decoder initialization")]
1136    IOError,
1137
1138    #[error("An unknown error occurred during decoder initialization: {0}")]
1139    UnknownError(i32),
1140}
1141
1142impl From<i32> for OpenDecoderError {
1143    fn from(err_code: i32) -> Self {
1144        match err_code {
1145            AVERROR_OUT_OF_MEMORY => OpenDecoderError::OutOfMemory,
1146            AVERROR_INVALID_ARGUMENT => OpenDecoderError::InvalidArgument,
1147            AVERROR_NOT_IMPLEMENTED => OpenDecoderError::NotImplemented,
1148            AVERROR_AGAIN => OpenDecoderError::TryAgain,
1149            AVERROR_IO_ERROR => OpenDecoderError::IOError,
1150            _ => OpenDecoderError::UnknownError(err_code),
1151        }
1152    }
1153}
1154
1155#[derive(thiserror::Error, Debug)]
1156pub enum DecodingError {
1157    #[error("Memory allocation error")]
1158    OutOfMemory,
1159
1160    #[error("Invalid argument provided")]
1161    InvalidArgument,
1162
1163    #[error("I/O error occurred during decoding")]
1164    IOError,
1165
1166    #[error("Timeout occurred during decoding")]
1167    Timeout,
1168
1169    #[error("Broken pipe encountered during decoding")]
1170    PipeError,
1171
1172    #[error("Bad file descriptor encountered during decoding")]
1173    BadFileDescriptor,
1174
1175    #[error("Unsupported functionality or format encountered")]
1176    NotImplemented,
1177
1178    #[error("Operation not permitted")]
1179    OperationNotPermitted,
1180
1181    #[error("Resource temporarily unavailable")]
1182    TryAgain,
1183
1184    #[error("An unknown decoding error occurred. ret:{0}")]
1185    UnknownError(i32),
1186}
1187
1188impl From<i32> for DecodingError {
1189    fn from(err_code: i32) -> Self {
1190        match err_code {
1191            AVERROR_OUT_OF_MEMORY => DecodingError::OutOfMemory,
1192            AVERROR_INVALID_ARGUMENT => DecodingError::InvalidArgument,
1193            AVERROR_IO_ERROR => DecodingError::IOError,
1194            AVERROR_TIMEOUT => DecodingError::Timeout,
1195            AVERROR_PIPE_ERROR => DecodingError::PipeError,
1196            AVERROR_BAD_FILE_DESCRIPTOR => DecodingError::BadFileDescriptor,
1197            AVERROR_NOT_IMPLEMENTED => DecodingError::NotImplemented,
1198            AVERROR_OPERATION_NOT_PERMITTED => DecodingError::OperationNotPermitted,
1199            AVERROR_AGAIN => DecodingError::TryAgain,
1200            _ => DecodingError::UnknownError(err_code),
1201        }
1202    }
1203}
1204
1205#[derive(thiserror::Error, Debug)]
1206pub enum DecoderError {
1207    #[error("decoder '{0}' not found")]
1208    NotFound(String),
1209}
1210
1211#[derive(thiserror::Error, Debug)]
1212pub enum DemuxingError {
1213    #[error("Memory allocation error")]
1214    OutOfMemory,
1215
1216    #[error("Invalid argument provided")]
1217    InvalidArgument,
1218
1219    #[error("I/O error occurred during demuxing")]
1220    IOError,
1221
1222    #[error("End of file reached during demuxing")]
1223    EndOfFile,
1224
1225    #[error("Resource temporarily unavailable")]
1226    TryAgain,
1227
1228    #[error("Functionality not implemented or unsupported")]
1229    NotImplemented,
1230
1231    #[error("Operation not permitted")]
1232    OperationNotPermitted,
1233
1234    #[error("Bad file descriptor encountered")]
1235    BadFileDescriptor,
1236
1237    #[error("Invalid data found when processing input")]
1238    InvalidData,
1239
1240    #[error("{}. ret:{0}", crate::util::ffmpeg_utils::av_err2str(*.0))]
1241    UnknownError(i32),
1242}
1243
1244impl From<i32> for DemuxingError {
1245    fn from(err_code: i32) -> Self {
1246        match err_code {
1247            AVERROR_OUT_OF_MEMORY => DemuxingError::OutOfMemory,
1248            AVERROR_INVALID_ARGUMENT => DemuxingError::InvalidArgument,
1249            AVERROR_IO_ERROR => DemuxingError::IOError,
1250            AVERROR_EOF => DemuxingError::EndOfFile,
1251            AVERROR_AGAIN => DemuxingError::TryAgain,
1252            AVERROR_NOT_IMPLEMENTED => DemuxingError::NotImplemented,
1253            AVERROR_OPERATION_NOT_PERMITTED => DemuxingError::OperationNotPermitted,
1254            AVERROR_BAD_FILE_DESCRIPTOR => DemuxingError::BadFileDescriptor,
1255            AVERROR_INVALIDDATA => DemuxingError::InvalidData,
1256            _ => DemuxingError::UnknownError(err_code),
1257        }
1258    }
1259}
1260
1261/// Errors that can occur during packet scanning operations.
1262#[derive(thiserror::Error, Debug)]
1263pub enum PacketScannerError {
1264    /// Failed to seek to the requested timestamp.
1265    #[error("while seeking: {0}")]
1266    SeekError(DemuxingError),
1267
1268    /// Failed to read the next packet from the demuxer.
1269    #[error("while reading packet: {0}")]
1270    ReadError(DemuxingError),
1271}