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 #[error("Scheduler start failed; the job was torn down during startup")]
140 StartFailed,
141
142 #[cfg(feature = "rtmp")]
143 #[error("Rtmp stream already exists with key: {0}")]
144 RtmpStreamAlreadyExists(String),
145
146 #[cfg(feature = "rtmp")]
147 #[error("Rtmp create stream failed. Check whether the server is stopped.")]
148 RtmpCreateStream,
149
150 #[cfg(feature = "rtmp")]
151 #[error("Rtmp registration queue is full: too many streams are waiting to be registered")]
152 RtmpRegistrationQueueFull,
153
154 #[cfg(feature = "rtmp")]
155 #[error("Rtmp server thread exited")]
156 RtmpThreadExited,
157
158 #[cfg(feature = "rtmp")]
159 #[error("Rtmp stream closed: the server is no longer consuming this stream")]
160 RtmpStreamClosed,
161
162 #[cfg(feature = "rtmp")]
163 #[error("Rtmp server already started: clones of one server share a single lifecycle, which can be started only once")]
164 RtmpServerAlreadyStarted,
165
166 #[cfg(feature = "subtitle")]
167 #[error("Subtitle error: {0}")]
168 Subtitle(#[from] crate::subtitle::SubtitleError),
169
170 #[cfg(feature = "wgpu")]
171 #[error("Wgpu filter error: {0}")]
172 WgpuFilter(#[from] crate::wgpu_filter::WgpuFilterError),
173
174 #[cfg(feature = "opengl")]
179 #[allow(deprecated)]
180 #[error("OpenGL filter error: {0}")]
181 OpenGLFilter(#[source] OpenGLFilterError),
182
183 #[error("IO error:{0}")]
184 IO(#[from] io::Error),
185
186 #[error("EOF")]
187 EOF,
188 #[error("Exit")]
189 Exit,
190 #[error("Bug")]
191 Bug,
192
193 #[error("Invalid recipe argument: {0}")]
194 InvalidRecipeArg(String),
195
196 #[error("Container info error: {0}")]
197 ContainerInfo(#[from] ContainerInfoError),
198
199 #[error("Frame export error: {0}")]
200 FrameExport(#[from] crate::core::frame_export::FrameExportError),
201
202 #[error("Video writer error: {0}")]
203 Writer(#[from] crate::core::writer::WriterError),
204
205 #[error("Video writer push error: {0}")]
206 Push(#[from] crate::core::writer::PushError),
207
208 #[error("Frame source thread failed to start")]
209 FrameSourceThreadExited,
210
211 #[error("Packet sink error: {0}")]
212 PacketSink(#[from] PacketSinkError),
213
214 #[cfg(feature = "cli")]
220 #[error("the per-output video filter requires exactly one video stream in the input; the opened input has {video_streams}")]
221 AmbiguousVideoSource { video_streams: usize },
222
223 #[cfg(feature = "cli")]
230 #[error("option '{option}' was not consumed by {site}; CLI-compat strict mode treats leftover AVOptions as errors")]
231 UnconsumedCliOption { site: String, option: String },
232}
233
234const _: () = assert!(
244 std::mem::size_of::<Error>() <= 64,
245 "Error grew past its 64-byte layout: shrink the new payload (static labels) or box the variant"
246);
247
248pub use crate::core::writer::WriterError;
253
254#[cfg(feature = "opengl")]
258#[allow(deprecated)]
259impl From<OpenGLFilterError> for Error {
260 fn from(err: OpenGLFilterError) -> Self {
261 Error::OpenGLFilter(err)
262 }
263}
264
265#[derive(thiserror::Error, Debug)]
273#[non_exhaustive]
274pub enum ContainerInfoError {
275 #[error("chapter index {index} out of range: the container has {count} chapter(s)")]
276 ChapterIndexOutOfRange { index: usize, count: usize },
277
278 #[error("stream index {index} out of range: the container has {count} stream(s)")]
279 StreamIndexOutOfRange { index: usize, count: usize },
280}
281
282#[cfg(feature = "rtmp")]
284#[derive(thiserror::Error, Debug)]
285#[non_exhaustive]
286pub enum StreamError {
287 #[error("missing required parameter: {0}")]
288 MissingParameter(&'static str),
289
290 #[error("input path is not a valid file: {path}")]
291 InputNotFound { path: std::path::PathBuf },
292
293 #[error("ffmpeg error: {0}")]
294 Ffmpeg(#[from] crate::error::Error),
295}
296
297impl PartialEq for Error {
298 fn eq(&self, other: &Self) -> bool {
302 use Error::*;
303 match (self, other) {
304 (NotStarted, NotStarted)
305 | (FilterDescUtf8, FilterDescUtf8)
306 | (FilterNameUtf8, FilterNameUtf8)
307 | (FilterZeroOutputs, FilterZeroOutputs)
308 | (FilterZeroInputs, FilterZeroInputs)
309 | (ParseInteger, ParseInteger)
310 | (FrameFilterDstFinished, FrameFilterDstFinished)
311 | (FrameFilterFrameDuplicateFailed, FrameFilterFrameDuplicateFailed)
312 | (FrameFilterThreadExited, FrameFilterThreadExited)
313 | (FrameSourceThreadExited, FrameSourceThreadExited)
314 | (EOF, EOF)
315 | (Exit, Exit)
316 | (Bug, Bug) => true,
317 #[cfg(feature = "rtmp")]
318 (RtmpCreateStream, RtmpCreateStream)
319 | (RtmpRegistrationQueueFull, RtmpRegistrationQueueFull)
320 | (RtmpThreadExited, RtmpThreadExited)
321 | (RtmpStreamClosed, RtmpStreamClosed)
322 | (RtmpServerAlreadyStarted, RtmpServerAlreadyStarted) => true,
323 _ => false,
324 }
325 }
326}
327
328#[derive(thiserror::Error, Debug)]
332#[non_exhaustive]
333pub enum DemuxingOperationError {
334 #[error("while reading frame: {0}")]
335 ReadFrameError(DemuxingError),
336
337 #[error("while referencing packet: {0}")]
338 PacketRefError(DemuxingError),
339
340 #[error("while seeking file: {0}")]
341 SeekFileError(DemuxingError),
342
343 #[error("Thread exited")]
344 ThreadExited,
345}
346
347#[derive(thiserror::Error, Debug)]
348#[non_exhaustive]
349pub enum DecodingOperationError {
350 #[error("during frame reference creation: {0}")]
351 FrameRefError(DecodingError),
352
353 #[error("during frame properties copy: {0}")]
354 FrameCopyPropsError(DecodingError),
355
356 #[error("during subtitle decoding: {0}")]
357 DecodeSubtitleError(DecodingError),
358
359 #[error("during subtitle copy: {0}")]
360 CopySubtitleError(DecodingError),
361
362 #[error("during packet submission to decoder: {0}")]
363 SendPacketError(DecodingError),
364
365 #[error("during frame reception from decoder: {0}")]
366 ReceiveFrameError(DecodingError),
367
368 #[error("during frame allocation: {0}")]
369 FrameAllocationError(DecodingError),
370
371 #[error("during packet allocation: {0}")]
372 PacketAllocationError(DecodingError),
373
374 #[error("during AVSubtitle allocation: {0}")]
375 SubtitleAllocationError(DecodingError),
376
377 #[error("corrupt decoded frame")]
378 CorruptFrame,
379
380 #[error("decode error rate exceeded the maximum allowed")]
381 ErrorRateExceeded,
382
383 #[error("during retrieve data on hw: {0}")]
384 HWRetrieveDataError(DecodingError),
385
386 #[error("during cropping: {0}")]
387 CroppingError(DecodingError),
388}
389
390#[derive(thiserror::Error, Debug)]
391#[non_exhaustive]
392pub enum OpenDecoderOperationError {
393 #[error("during context allocation: {0}")]
394 ContextAllocationError(OpenDecoderError),
395
396 #[error("while applying parameters to context: {0}")]
397 ParameterApplicationError(OpenDecoderError),
398
399 #[error("while opening decoder: {0}")]
400 DecoderOpenError(OpenDecoderError),
401
402 #[error("while copying channel layout: {0}")]
403 ChannelLayoutCopyError(OpenDecoderError),
404
405 #[error("while Hw setup: {0}")]
406 HwSetupError(OpenDecoderError),
407
408 #[error("Invalid decoder name")]
409 InvalidName,
410
411 #[error("Thread exited")]
412 ThreadExited,
413}
414
415#[derive(thiserror::Error, Debug)]
416#[non_exhaustive]
417pub enum FilterGraphOperationError {
418 #[error("during requesting oldest frame: {0}")]
419 RequestOldestError(FilterGraphError),
420
421 #[error("during process frames: {0}")]
422 ProcessFramesError(FilterGraphError),
423
424 #[error("during send frames: {0}")]
425 SendFramesError(FilterGraphError),
426
427 #[error("during copying channel layout: {0}")]
428 ChannelLayoutCopyError(FilterGraphError),
429
430 #[error("during buffer source add frame: {0}")]
431 BufferSourceAddFrameError(FilterGraphError),
432
433 #[error("during closing buffer source: {0}")]
434 BufferSourceCloseError(FilterGraphError),
435
436 #[error("during replace buffer: {0}")]
437 BufferReplaceoseError(FilterGraphError),
438
439 #[error("during cloning frame side data: {0}")]
440 FrameSideDataCloneError(FilterGraphError),
441
442 #[error("during parse: {0}")]
443 ParseError(FilterGraphParseError),
444
445 #[error("The data in the frame is invalid or corrupted")]
446 InvalidData,
447
448 #[error(
449 "graph input '{0}' already holds {1} buffered frames and admitting the next \
450 one would raise the best-effort retained-memory estimate to ~{2} bytes, \
451 while another input has not yet delivered its first frame, so the filter \
452 graph cannot be configured; check that every graph input actually produces \
453 data (or produces it within the buffering window)"
454 )]
455 PreConfigQueueOverflow(String, usize, usize),
456
457 #[cfg_attr(not(ffmpeg_8_0), allow(dead_code))]
459 #[error(
460 "graph input '{0}' would deep-copy an estimated {1} bytes of side-data \
461 metadata into the buffersrc parameters, exceeding the side-data clone \
462 estimate threshold; the frame's combined side-data metadata (across its \
463 global and downmix entries) is pathologically large"
464 )]
465 OversizedSideDataClone(String, usize),
466
467 #[error("Thread exited")]
468 ThreadExited,
469}
470
471#[derive(thiserror::Error, Debug)]
472#[non_exhaustive]
473pub enum EncodingOperationError {
474 #[error("during frame submission: {0}")]
475 SendFrameError(EncodingError),
476
477 #[error("during packet retrieval: {0}")]
478 ReceivePacketError(EncodingError),
479
480 #[error("during audio frame receive: {0}")]
481 ReceiveAudioError(EncodingError),
482
483 #[error(": Subtitle packets must have a pts")]
484 SubtitleNotPts,
485
486 #[error(": Muxer already finished")]
487 MuxerFinished,
488
489 #[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")]
495 MuxQueueFull,
496
497 #[error("Encode subtitle error: {0}")]
498 EncodeSubtitle(#[from] EncodeSubtitleError),
499
500 #[error(": {0}")]
501 AllocPacket(AllocPacketError),
502}
503
504#[derive(thiserror::Error, Debug)]
505#[non_exhaustive]
506pub enum MuxingOperationError {
507 #[error("during write header: {0}")]
508 WriteHeader(WriteHeaderError),
509
510 #[error("while initializing bitstream filter chain '{0}': {1}")]
511 BitstreamFilterInit(String, MuxingError),
512
513 #[error("during interleaved write: {0}")]
514 InterleavedWriteError(MuxingError),
515
516 #[error("during trailer write: {0}")]
517 TrailerWriteError(MuxingError),
518
519 #[error("during closing IO: {0}")]
520 IOCloseError(MuxingError),
521
522 #[error("Thread exited")]
523 ThreadExited,
524}
525
526#[derive(thiserror::Error, Debug, Clone)]
537#[non_exhaustive]
538pub enum PacketSinkError {
539 #[error("{0} is not supported on packet-sink outputs")]
545 UnsupportedOption(&'static str),
546
547 #[error("stream copy is not supported on packet-sink outputs (strict tier requires encoded streams)")]
550 StreamCopyUnsupported,
551
552 #[error("{kind} streams are not supported on packet-sink outputs (strict tier)")]
555 UnsupportedStream { kind: &'static str },
556
557 #[error("encoder '{encoder}' is not on the strict-tier whitelist for {kind} (v1 accepts: {allowed})")]
559 EncoderNotWhitelisted {
560 kind: &'static str,
561 encoder: String,
562 allowed: &'static str,
563 },
564
565 #[error("packet-sink output has no streams")]
567 NoStreams,
568
569 #[error("output stream {stream_index}: encoder produced no extradata; the strict tier requires codec configuration (avcC / AudioSpecificConfig) before the first callback")]
572 MissingExtradata { stream_index: usize },
573
574 #[error("output stream {stream_index}: invalid codec configuration: {reason}")]
576 InvalidExtradata { stream_index: usize, reason: String },
577
578 #[error("output stream {stream_index}: invalid time base {num}/{den} (positive numerator and denominator required)")]
580 InvalidTimeBase {
581 stream_index: usize,
582 num: i32,
583 den: i32,
584 },
585
586 #[error("output stream {stream_index}: packet time base {packet_num}/{packet_den} differs from the stream time base {stream_num}/{stream_den}")]
588 PacketTimeBaseMismatch {
589 stream_index: usize,
590 packet_num: i32,
591 packet_den: i32,
592 stream_num: i32,
593 stream_den: i32,
594 },
595
596 #[error("output stream {stream_index}: packet carries no {which} (strict tier rejects AV_NOPTS_VALUE)")]
598 MissingTimestamp {
599 stream_index: usize,
600 which: &'static str,
601 },
602
603 #[error("output stream {stream_index}: non-monotonic dts (previous {prev}, current {current})")]
605 NonMonotonicDts {
606 stream_index: usize,
607 prev: i64,
608 current: i64,
609 },
610
611 #[error("output stream {stream_index}: duplicate pts {pts}")]
613 DuplicatePts { stream_index: usize, pts: i64 },
614
615 #[error("output stream {stream_index}: pts {pts} is earlier than dts {dts}")]
617 PtsBeforeDts {
618 stream_index: usize,
619 pts: i64,
620 dts: i64,
621 },
622
623 #[error("output stream {stream_index}: timestamp overflow while applying the shared time origin")]
625 TimestampOverflow { stream_index: usize },
626
627 #[error("output stream {stream_index}: packet duration is absent and cannot be derived (strict tier requires a positive duration)")]
630 MissingDuration { stream_index: usize },
631
632 #[error("output stream {stream_index}: malformed packet payload: {reason}")]
634 MalformedPacket {
635 stream_index: usize,
636 reason: String,
637 },
638
639 #[error("output stream {stream_index}: packet processed outside the delivery phase (internal sequencing violation)")]
642 PhaseViolation { stream_index: usize },
643
644 #[error("output stream {stream_index}: mid-stream configuration change ({what}); the strict tier requires an immutable stream configuration")]
646 ConfigChange {
647 stream_index: usize,
648 what: String,
649 },
650
651 #[error("output stream {stream_index}: in-band SPS/PPS parameter sets are not supported in the strict tier (WebCodecs avc requires out-of-band configuration)")]
653 InBandParameterSets { stream_index: usize },
654
655 #[error("on_stream_info callback rejected the stream configuration: {error}")]
657 StreamInfoCallbackFailed {
658 #[source]
659 error: crate::core::packet_sink::PacketCallbackError,
660 },
661
662 #[error("on_packet callback failed on output stream {stream_index}: {error}")]
664 PacketCallbackFailed {
665 stream_index: usize,
666 #[source]
667 error: crate::core::packet_sink::PacketCallbackError,
668 },
669
670 #[error("the packet-sink channel receiver was dropped; delivery cancelled")]
673 ChannelDisconnected,
674
675 #[error("the job failed outside this packet sink; delivery may have been truncated: {message}")]
678 JobFailed { message: String },
679}
680
681#[derive(thiserror::Error, Debug)]
682#[non_exhaustive]
683pub enum OpenEncoderOperationError {
684 #[error("during frame side data cloning: {0}")]
685 FrameSideDataCloneError(OpenEncoderError),
686
687 #[error("during channel layout copying: {0}")]
688 ChannelLayoutCopyError(OpenEncoderError),
689
690 #[error("during codec opening: {0}")]
691 CodecOpenError(OpenEncoderError),
692
693 #[error("while setting codec parameters: {0}")]
694 CodecParametersError(OpenEncoderError),
695
696 #[error(": unknown format of the frame")]
697 UnknownFrameFormat,
698
699 #[error("while setting subtitle: {0}")]
700 SettingSubtitleError(OpenEncoderError),
701
702 #[error("while Hw setup: {0}")]
703 HwSetupError(OpenEncoderError),
704
705 #[error("during context allocation: {0}")]
706 ContextAllocationError(OpenEncoderError),
707
708 #[error(": no frames were received before EOF; encoder never opened")]
709 NoFramesReceived,
710
711 #[error(": unsupported media type for encoding")]
712 UnsupportedMediaType,
713
714 #[error("Thread exited")]
715 ThreadExited,
716}
717
718#[derive(thiserror::Error, Debug)]
719#[non_exhaustive]
720pub enum UrlError {
721 #[error("Null byte found in string at position {0}")]
722 NullByteError(usize),
723}
724
725impl From<NulError> for Error {
726 fn from(err: NulError) -> Self {
727 Error::Url(UrlError::NullByteError(err.nul_position()))
728 }
729}
730
731#[derive(thiserror::Error, Debug)]
732#[non_exhaustive]
733pub enum OpenInputError {
734 #[error("Memory allocation error")]
735 OutOfMemory,
736
737 #[error("Invalid argument provided")]
738 InvalidArgument,
739
740 #[error("File or stream not found")]
741 NotFound,
742
743 #[error("I/O error occurred while opening the file or stream")]
744 IOError,
745
746 #[error("Pipe error, possibly the stream or data connection was broken")]
747 PipeError,
748
749 #[error("Invalid file descriptor")]
750 BadFileDescriptor,
751
752 #[error("Functionality not implemented or unsupported input format")]
753 NotImplemented,
754
755 #[error("Operation not permitted to access the file or stream")]
756 OperationNotPermitted,
757
758 #[error("The data in the file or stream is invalid or corrupted")]
759 InvalidData,
760
761 #[error("The connection timed out while trying to open the stream")]
762 Timeout,
763
764 #[error("Invalid input option: {0}")]
770 InvalidOption(String),
771
772 #[error("{}. ret:{0}", crate::util::ffmpeg_utils::av_err2str(*.0))]
773 UnknownError(i32),
774
775 #[error("Invalid source provided")]
776 InvalidSource,
777
778 #[error("Invalid source format:{0}")]
779 InvalidFormat(String),
780
781 #[error("No seek callback is provided")]
782 SeekFunctionMissing,
783}
784
785impl From<i32> for OpenInputError {
786 fn from(err_code: i32) -> Self {
787 match err_code {
788 AVERROR_OUT_OF_MEMORY => OpenInputError::OutOfMemory,
789 AVERROR_INVALID_ARGUMENT => OpenInputError::InvalidArgument,
790 AVERROR_NOT_FOUND => OpenInputError::NotFound,
791 AVERROR_IO_ERROR => OpenInputError::IOError,
792 AVERROR_PIPE_ERROR => OpenInputError::PipeError,
793 AVERROR_BAD_FILE_DESCRIPTOR => OpenInputError::BadFileDescriptor,
794 AVERROR_NOT_IMPLEMENTED => OpenInputError::NotImplemented,
795 AVERROR_OPERATION_NOT_PERMITTED => OpenInputError::OperationNotPermitted,
796 AVERROR_INVALIDDATA => OpenInputError::InvalidData,
797 AVERROR_TIMEOUT => OpenInputError::Timeout,
798 _ => OpenInputError::UnknownError(err_code),
799 }
800 }
801}
802
803const AVERROR_OUT_OF_MEMORY: i32 = AVERROR(ENOMEM);
804const AVERROR_INVALID_ARGUMENT: i32 = AVERROR(EINVAL);
805const AVERROR_NOT_FOUND: i32 = AVERROR(ENOENT);
806const AVERROR_IO_ERROR: i32 = AVERROR(EIO);
807const AVERROR_PIPE_ERROR: i32 = AVERROR(EPIPE);
808const AVERROR_BAD_FILE_DESCRIPTOR: i32 = AVERROR(EBADF);
809const AVERROR_NOT_IMPLEMENTED: i32 = AVERROR(ENOSYS);
810const AVERROR_OPERATION_NOT_PERMITTED: i32 = AVERROR(EPERM);
811const AVERROR_PERMISSION_DENIED: i32 = AVERROR(EACCES);
812const AVERROR_TIMEOUT: i32 = AVERROR(ETIMEDOUT);
813const AVERROR_NOT_SOCKET: i32 = AVERROR(ENOTSOCK);
814const AVERROR_AGAIN: i32 = AVERROR(EAGAIN);
815
816#[derive(thiserror::Error, Debug)]
817#[non_exhaustive]
818pub enum FindStreamError {
819 #[error("Memory allocation error")]
820 OutOfMemory,
821
822 #[error("Invalid argument provided")]
823 InvalidArgument,
824
825 #[error("Reached end of file while looking for stream info")]
826 EndOfFile,
827
828 #[error("Timeout occurred while reading stream info")]
829 Timeout,
830
831 #[error("I/O error occurred while reading stream info")]
832 IOError,
833
834 #[error("The data in the stream is invalid or corrupted")]
835 InvalidData,
836
837 #[error("Functionality not implemented or unsupported stream format")]
838 NotImplemented,
839
840 #[error("Operation not permitted to access the file or stream")]
841 OperationNotPermitted,
842
843 #[error("No Stream found")]
844 NoStreamFound,
845
846 #[error("{}. ret:{0}", crate::util::ffmpeg_utils::av_err2str(*.0))]
847 UnknownError(i32),
848}
849
850impl From<i32> for FindStreamError {
851 fn from(err_code: i32) -> Self {
852 match err_code {
853 AVERROR_OUT_OF_MEMORY => FindStreamError::OutOfMemory,
854 AVERROR_INVALID_ARGUMENT => FindStreamError::InvalidArgument,
855 AVERROR_EOF => FindStreamError::EndOfFile,
856 AVERROR_TIMEOUT => FindStreamError::Timeout,
857 AVERROR_IO_ERROR => FindStreamError::IOError,
858 AVERROR_INVALIDDATA => FindStreamError::InvalidData,
859 AVERROR_NOT_IMPLEMENTED => FindStreamError::NotImplemented,
860 AVERROR_OPERATION_NOT_PERMITTED => FindStreamError::OperationNotPermitted,
861 _ => FindStreamError::UnknownError(err_code),
862 }
863 }
864}
865
866#[derive(thiserror::Error, Debug)]
867#[non_exhaustive]
868pub enum FilterGraphParseError {
869 #[error("Memory allocation error")]
870 OutOfMemory,
871
872 #[error("Invalid argument provided")]
873 InvalidArgument,
874
875 #[error("End of file reached during parsing")]
876 EndOfFile,
877
878 #[error("I/O error occurred during parsing")]
879 IOError,
880
881 #[error("Invalid data encountered during parsing")]
882 InvalidData,
883
884 #[error("Functionality not implemented or unsupported filter format")]
885 NotImplemented,
886
887 #[error("Permission denied during filter graph parsing")]
888 PermissionDenied,
889
890 #[error("Socket operation on non-socket during filter graph parsing")]
891 NotSocket,
892
893 #[error("Option not found during filter graph configuration")]
894 OptionNotFound,
895
896 #[error("Invalid file index {0} in filtergraph description {1}")]
897 InvalidFileIndexInFg(usize, String),
898
899 #[error("Invalid file index {0} in output url: {1}")]
900 InvalidFileIndexInOutput(usize, String),
901
902 #[error("Invalid filter specifier {0}")]
903 InvalidFilterSpecifier(String),
904
905 #[error("Filter '{0}' has output {1} ({2}) unconnected")]
906 OutputUnconnected(String, usize, String),
907
908 #[error("An unknown error occurred. ret: {0}")]
909 UnknownError(i32),
910}
911
912impl From<i32> for FilterGraphParseError {
913 fn from(err_code: i32) -> Self {
914 match err_code {
915 AVERROR_OUT_OF_MEMORY => FilterGraphParseError::OutOfMemory,
916 AVERROR_INVALID_ARGUMENT => FilterGraphParseError::InvalidArgument,
917 AVERROR_EOF => FilterGraphParseError::EndOfFile,
918 AVERROR_IO_ERROR => FilterGraphParseError::IOError,
919 AVERROR_INVALIDDATA => FilterGraphParseError::InvalidData,
920 AVERROR_NOT_IMPLEMENTED => FilterGraphParseError::NotImplemented,
921 AVERROR_OPTION_NOT_FOUND => FilterGraphParseError::OptionNotFound,
922 AVERROR_PERMISSION_DENIED => FilterGraphParseError::PermissionDenied,
926 AVERROR_NOT_SOCKET => FilterGraphParseError::NotSocket,
927 _ => FilterGraphParseError::UnknownError(err_code),
928 }
929 }
930}
931
932#[derive(thiserror::Error, Debug)]
933#[non_exhaustive]
934pub enum AllocOutputContextError {
935 #[error("Memory allocation error")]
936 OutOfMemory,
937
938 #[error("Invalid argument provided")]
939 InvalidArgument,
940
941 #[error("File or stream not found")]
942 NotFound,
943
944 #[error("I/O error occurred while allocating the output context")]
945 IOError,
946
947 #[error("Pipe error, possibly the stream or data connection was broken")]
948 PipeError,
949
950 #[error("Invalid file descriptor")]
951 BadFileDescriptor,
952
953 #[error("Functionality not implemented or unsupported output format")]
954 NotImplemented,
955
956 #[error("Operation not permitted to allocate the output context")]
957 OperationNotPermitted,
958
959 #[error("Permission denied while allocating the output context")]
960 PermissionDenied,
961
962 #[error("The connection timed out while trying to allocate the output context")]
963 Timeout,
964
965 #[error("{}. ret:{0}", crate::util::ffmpeg_utils::av_err2str(*.0))]
966 UnknownError(i32),
967}
968
969impl From<i32> for AllocOutputContextError {
970 fn from(err_code: i32) -> Self {
971 match err_code {
972 AVERROR_OUT_OF_MEMORY => AllocOutputContextError::OutOfMemory,
973 AVERROR_INVALID_ARGUMENT => AllocOutputContextError::InvalidArgument,
974 AVERROR_NOT_FOUND => AllocOutputContextError::NotFound,
975 AVERROR_IO_ERROR => AllocOutputContextError::IOError,
976 AVERROR_PIPE_ERROR => AllocOutputContextError::PipeError,
977 AVERROR_BAD_FILE_DESCRIPTOR => AllocOutputContextError::BadFileDescriptor,
978 AVERROR_NOT_IMPLEMENTED => AllocOutputContextError::NotImplemented,
979 AVERROR_OPERATION_NOT_PERMITTED => AllocOutputContextError::OperationNotPermitted,
980 AVERROR_PERMISSION_DENIED => AllocOutputContextError::PermissionDenied,
981 AVERROR_TIMEOUT => AllocOutputContextError::Timeout,
982 _ => AllocOutputContextError::UnknownError(err_code),
983 }
984 }
985}
986
987#[derive(thiserror::Error, Debug)]
988#[non_exhaustive]
989pub enum OpenOutputError {
990 #[error("Memory allocation error")]
991 OutOfMemory,
992
993 #[error("Invalid argument provided")]
994 InvalidArgument,
995
996 #[error("File or stream not found")]
997 NotFound,
998
999 #[error("I/O error occurred while opening the file or stream")]
1000 IOError,
1001
1002 #[error("Pipe error, possibly the stream or data connection was broken")]
1003 PipeError,
1004
1005 #[error("Invalid file descriptor")]
1006 BadFileDescriptor,
1007
1008 #[error("Functionality not implemented or unsupported output format")]
1009 NotImplemented,
1010
1011 #[error("Operation not permitted to open the file or stream")]
1012 OperationNotPermitted,
1013
1014 #[error("Permission denied while opening the file or stream")]
1015 PermissionDenied,
1016
1017 #[error("The connection timed out while trying to open the file or stream")]
1018 Timeout,
1019
1020 #[error("encoder not found")]
1021 EncoderNotFound,
1022
1023 #[error(
1031 "encoder '{name}' is not available in the linked FFmpeg build — link \
1032 an FFmpeg build that provides it (for example one configured with \
1033 --enable-libx264 for libx264), or select a different encoder via \
1034 Output::set_video_codec / set_audio_codec / set_subtitle_codec \
1035 (list what the build provides with codec::get_encoders)"
1036 )]
1037 EncoderUnavailable { name: String },
1038
1039 #[error("Stream map '{0}' matches no streams;")]
1040 MatchesNoStreams(String),
1041
1042 #[error("Invalid label {0}")]
1043 InvalidLabel(String),
1044
1045 #[error("not contain any stream")]
1046 NotContainStream,
1047
1048 #[error("unknown format of the frame")]
1049 UnknownFrameFormat,
1050
1051 #[error("Invalid file index {0} in input url: {1}")]
1052 InvalidFileIndexInIntput(usize, String),
1053
1054 #[error("{}. ret:{0}", crate::util::ffmpeg_utils::av_err2str(*.0))]
1055 UnknownError(i32),
1056
1057 #[error("Invalid sink provided")]
1058 InvalidSink,
1059
1060 #[error("No seek callback is provided")]
1061 SeekFunctionMissing,
1062
1063 #[error("Format '{0}' is unsupported")]
1064 FormatUnsupported(String),
1065
1066 #[error("Unknown pixel format: '{0}'")]
1067 UnknownPixelFormat(String),
1068
1069 #[error("Unknown sample format: '{0}'")]
1070 UnknownSampleFormat(String),
1071
1072 #[error("Invalid output option: {0}")]
1078 InvalidOption(String),
1079
1080 #[error("Failed to read attachment file '{0}'")]
1081 AttachmentRead(String, #[source] io::Error),
1082
1083 #[error("Attachment file '{0}' is empty")]
1084 AttachmentEmpty(String),
1085
1086 #[error("Attachment file '{0}' is too large ({1} bytes, limit {2} bytes)")]
1087 AttachmentTooLarge(String, u64, u64),
1088
1089 #[error("Attachment mimetype must not be empty (file '{0}')")]
1090 AttachmentEmptyMimetype(String),
1091
1092 #[error(
1101 "Filtergraph '{0}' was specified, but codec copy was selected for the \
1102 output's video stream. Filtering and streamcopy cannot be used together"
1103 )]
1104 FilterWithStreamCopy(String),
1105
1106 #[error(
1115 "Filtergraph '{0}' was specified for a video stream fed from a \
1116 context-level filtergraph. Simple and complex filtering cannot be \
1117 used together for the same stream"
1118 )]
1119 SimpleAndComplexFilter(String),
1120
1121 #[error(
1134 "Simple filtergraph '{desc}' is not a single connected chain: {reason}; \
1135 use FfmpegContextBuilder::filter_desc for complex graphs"
1136 )]
1137 SimpleFilterInvalidShape { desc: String, reason: String },
1138
1139 #[error(
1147 "video filter '{0}' was configured, but the output ended up with no \
1148 re-encoded video stream to run it (audio-only input, disable_video(), \
1149 or maps matching no video stream); remove the filter or map a video \
1150 stream"
1151 )]
1152 VideoFilterUnused(String),
1153
1154 #[error(
1164 "Simple filtergraph '{desc}' has a {found} pad, cannot connect it to \
1165 the {expected} stream of this output"
1166 )]
1167 SimpleFilterMediaTypeMismatch {
1168 desc: String,
1170 found: &'static str,
1172 expected: &'static str,
1174 },
1175}
1176
1177impl From<i32> for OpenOutputError {
1178 fn from(err_code: i32) -> Self {
1179 match err_code {
1180 AVERROR_OUT_OF_MEMORY => OpenOutputError::OutOfMemory,
1181 AVERROR_INVALID_ARGUMENT => OpenOutputError::InvalidArgument,
1182 AVERROR_NOT_FOUND => OpenOutputError::NotFound,
1183 AVERROR_IO_ERROR => OpenOutputError::IOError,
1184 AVERROR_PIPE_ERROR => OpenOutputError::PipeError,
1185 AVERROR_BAD_FILE_DESCRIPTOR => OpenOutputError::BadFileDescriptor,
1186 AVERROR_NOT_IMPLEMENTED => OpenOutputError::NotImplemented,
1187 AVERROR_OPERATION_NOT_PERMITTED => OpenOutputError::OperationNotPermitted,
1188 AVERROR_PERMISSION_DENIED => OpenOutputError::PermissionDenied,
1189 AVERROR_TIMEOUT => OpenOutputError::Timeout,
1190 AVERROR_ENCODER_NOT_FOUND => OpenOutputError::EncoderNotFound,
1191 _ => OpenOutputError::UnknownError(err_code),
1192 }
1193 }
1194}
1195
1196#[derive(thiserror::Error, Debug)]
1197#[non_exhaustive]
1198pub enum FindDevicesError {
1199 #[error("AVCaptureDevice class not found in macOS")]
1200 AVCaptureDeviceNotFound,
1201
1202 #[error("current media_type({0}) is not supported")]
1203 MediaTypeSupported(i32),
1204 #[error("current OS is not supported")]
1205 OsNotSupported,
1206 #[error("device_description can not to string")]
1207 UTF8Error,
1208
1209 #[error("Memory allocation error")]
1210 OutOfMemory,
1211 #[error("Invalid argument provided")]
1212 InvalidArgument,
1213 #[error("Device or stream not found")]
1214 NotFound,
1215 #[error("I/O error occurred while accessing the device or stream")]
1216 IOError,
1217 #[error("Operation not permitted for this device or stream")]
1218 OperationNotPermitted,
1219 #[error("Permission denied while accessing the device or stream")]
1220 PermissionDenied,
1221 #[error("This functionality is not implemented")]
1222 NotImplemented,
1223 #[error("Bad file descriptor")]
1224 BadFileDescriptor,
1225 #[error("{}. ret:{0}", crate::util::ffmpeg_utils::av_err2str(*.0))]
1226 UnknownError(i32),
1227}
1228
1229impl From<i32> for FindDevicesError {
1230 fn from(err_code: i32) -> Self {
1231 match err_code {
1232 AVERROR_OUT_OF_MEMORY => FindDevicesError::OutOfMemory,
1233 AVERROR_INVALID_ARGUMENT => FindDevicesError::InvalidArgument,
1234 AVERROR_NOT_FOUND => FindDevicesError::NotFound,
1235 AVERROR_IO_ERROR => FindDevicesError::IOError,
1236 AVERROR_OPERATION_NOT_PERMITTED => FindDevicesError::OperationNotPermitted,
1237 AVERROR_PERMISSION_DENIED => FindDevicesError::PermissionDenied,
1238 AVERROR_NOT_IMPLEMENTED => FindDevicesError::NotImplemented,
1239 AVERROR_BAD_FILE_DESCRIPTOR => FindDevicesError::BadFileDescriptor,
1240 _ => FindDevicesError::UnknownError(err_code),
1241 }
1242 }
1243}
1244
1245#[derive(thiserror::Error, Debug)]
1246#[non_exhaustive]
1247pub enum WriteHeaderError {
1248 #[error("Memory allocation error")]
1249 OutOfMemory,
1250
1251 #[error("Invalid argument provided")]
1252 InvalidArgument,
1253
1254 #[error("File or stream not found")]
1255 NotFound,
1256
1257 #[error("I/O error occurred while writing the header")]
1258 IOError,
1259
1260 #[error("Pipe error, possibly the stream or data connection was broken")]
1261 PipeError,
1262
1263 #[error("Invalid file descriptor")]
1264 BadFileDescriptor,
1265
1266 #[error("Functionality not implemented or unsupported output format")]
1267 NotImplemented,
1268
1269 #[error("Operation not permitted to write the header")]
1270 OperationNotPermitted,
1271
1272 #[error("Permission denied while writing the header")]
1273 PermissionDenied,
1274
1275 #[error("The connection timed out while trying to write the header")]
1276 Timeout,
1277
1278 #[error("{}. ret:{0}", crate::util::ffmpeg_utils::av_err2str(*.0))]
1279 UnknownError(i32),
1280}
1281
1282impl From<i32> for WriteHeaderError {
1283 fn from(err_code: i32) -> Self {
1284 match err_code {
1285 AVERROR_OUT_OF_MEMORY => WriteHeaderError::OutOfMemory,
1286 AVERROR_INVALID_ARGUMENT => WriteHeaderError::InvalidArgument,
1287 AVERROR_NOT_FOUND => WriteHeaderError::NotFound,
1288 AVERROR_IO_ERROR => WriteHeaderError::IOError,
1289 AVERROR_PIPE_ERROR => WriteHeaderError::PipeError,
1290 AVERROR_BAD_FILE_DESCRIPTOR => WriteHeaderError::BadFileDescriptor,
1291 AVERROR_NOT_IMPLEMENTED => WriteHeaderError::NotImplemented,
1292 AVERROR_OPERATION_NOT_PERMITTED => WriteHeaderError::OperationNotPermitted,
1293 AVERROR_PERMISSION_DENIED => WriteHeaderError::PermissionDenied,
1294 AVERROR_TIMEOUT => WriteHeaderError::Timeout,
1295 _ => WriteHeaderError::UnknownError(err_code),
1296 }
1297 }
1298}
1299
1300#[derive(thiserror::Error, Debug)]
1301#[non_exhaustive]
1302pub enum EncodeSubtitleError {
1303 #[error("Memory allocation error while encoding subtitle")]
1304 OutOfMemory,
1305
1306 #[error("Invalid argument provided for subtitle encoding")]
1307 InvalidArgument,
1308
1309 #[error("Operation not permitted while encoding subtitle")]
1310 OperationNotPermitted,
1311
1312 #[error("The encoding functionality is not implemented or unsupported")]
1313 NotImplemented,
1314
1315 #[error("Encoder temporarily unable to process, please retry")]
1316 TryAgain,
1317
1318 #[error("Subtitle encoding failed with unknown error. ret: {0}")]
1319 UnknownError(i32),
1320}
1321
1322impl From<i32> for EncodeSubtitleError {
1323 fn from(err_code: i32) -> Self {
1324 match err_code {
1325 AVERROR_OUT_OF_MEMORY => EncodeSubtitleError::OutOfMemory,
1326 AVERROR_INVALID_ARGUMENT => EncodeSubtitleError::InvalidArgument,
1327 AVERROR_OPERATION_NOT_PERMITTED => EncodeSubtitleError::OperationNotPermitted,
1328 AVERROR_NOT_IMPLEMENTED => EncodeSubtitleError::NotImplemented,
1329 AVERROR_AGAIN => EncodeSubtitleError::TryAgain,
1330 _ => EncodeSubtitleError::UnknownError(err_code),
1331 }
1332 }
1333}
1334
1335#[derive(thiserror::Error, Debug)]
1336#[non_exhaustive]
1337pub enum AllocPacketError {
1338 #[error("Memory allocation error while alloc packet")]
1339 OutOfMemory,
1340}
1341
1342#[derive(thiserror::Error, Debug)]
1343#[non_exhaustive]
1344pub enum AllocFrameError {
1345 #[error("Memory allocation error while alloc frame")]
1346 OutOfMemory,
1347}
1348
1349#[derive(thiserror::Error, Debug)]
1357#[non_exhaustive]
1358pub enum FrameWritableError {
1359 #[error("Memory allocation error while copying frame data")]
1360 OutOfMemory,
1361
1362 #[error("Invalid argument provided")]
1363 InvalidArgument,
1364
1365 #[error("{}. ret:{0}", crate::util::ffmpeg_utils::av_err2str(*.0))]
1366 UnknownError(i32),
1367}
1368
1369impl From<i32> for FrameWritableError {
1370 fn from(err_code: i32) -> Self {
1371 match err_code {
1372 AVERROR_OUT_OF_MEMORY => FrameWritableError::OutOfMemory,
1373 AVERROR_INVALID_ARGUMENT => FrameWritableError::InvalidArgument,
1374 _ => FrameWritableError::UnknownError(err_code),
1375 }
1376 }
1377}
1378
1379#[derive(thiserror::Error, Debug)]
1380#[non_exhaustive]
1381pub enum MuxingError {
1382 #[error("Memory allocation error")]
1383 OutOfMemory,
1384
1385 #[error("Invalid argument provided")]
1386 InvalidArgument,
1387
1388 #[error("I/O error occurred during muxing")]
1389 IOError,
1390
1391 #[error("Broken pipe during muxing")]
1392 PipeError,
1393
1394 #[error("Bad file descriptor encountered")]
1395 BadFileDescriptor,
1396
1397 #[error("Functionality not implemented or unsupported")]
1398 NotImplemented,
1399
1400 #[error("Operation not permitted")]
1401 OperationNotPermitted,
1402
1403 #[error("Resource temporarily unavailable")]
1404 TryAgain,
1405
1406 #[error("{}. ret:{0}", crate::util::ffmpeg_utils::av_err2str(*.0))]
1407 UnknownError(i32),
1408}
1409
1410impl From<i32> for MuxingError {
1411 fn from(err_code: i32) -> Self {
1412 match err_code {
1413 AVERROR_OUT_OF_MEMORY => MuxingError::OutOfMemory,
1414 AVERROR_INVALID_ARGUMENT => MuxingError::InvalidArgument,
1415 AVERROR_IO_ERROR => MuxingError::IOError,
1416 AVERROR_PIPE_ERROR => MuxingError::PipeError,
1417 AVERROR_BAD_FILE_DESCRIPTOR => MuxingError::BadFileDescriptor,
1418 AVERROR_NOT_IMPLEMENTED => MuxingError::NotImplemented,
1419 AVERROR_OPERATION_NOT_PERMITTED => MuxingError::OperationNotPermitted,
1420 AVERROR_AGAIN => MuxingError::TryAgain,
1421 _ => MuxingError::UnknownError(err_code),
1422 }
1423 }
1424}
1425
1426#[derive(thiserror::Error, Debug)]
1427#[non_exhaustive]
1428pub enum OpenEncoderError {
1429 #[error("Memory allocation error occurred during encoder initialization")]
1430 OutOfMemory,
1431
1432 #[error("Invalid argument provided to encoder")]
1433 InvalidArgument,
1434
1435 #[error("I/O error occurred while opening encoder")]
1436 IOError,
1437
1438 #[error("Broken pipe encountered during encoder initialization")]
1439 PipeError,
1440
1441 #[error("Bad file descriptor used in encoder")]
1442 BadFileDescriptor,
1443
1444 #[error("Encoder functionality not implemented or unsupported")]
1445 NotImplemented,
1446
1447 #[error("Operation not permitted while configuring encoder")]
1448 OperationNotPermitted,
1449
1450 #[error("Resource temporarily unavailable during encoder setup")]
1451 TryAgain,
1452
1453 #[error("An unknown error occurred in encoder setup. ret:{0}")]
1454 UnknownError(i32),
1455}
1456
1457impl From<i32> for OpenEncoderError {
1458 fn from(err_code: i32) -> Self {
1459 match err_code {
1460 AVERROR_OUT_OF_MEMORY => OpenEncoderError::OutOfMemory,
1461 AVERROR_INVALID_ARGUMENT => OpenEncoderError::InvalidArgument,
1462 AVERROR_IO_ERROR => OpenEncoderError::IOError,
1463 AVERROR_PIPE_ERROR => OpenEncoderError::PipeError,
1464 AVERROR_BAD_FILE_DESCRIPTOR => OpenEncoderError::BadFileDescriptor,
1465 AVERROR_NOT_IMPLEMENTED => OpenEncoderError::NotImplemented,
1466 AVERROR_OPERATION_NOT_PERMITTED => OpenEncoderError::OperationNotPermitted,
1467 AVERROR_AGAIN => OpenEncoderError::TryAgain,
1468 _ => OpenEncoderError::UnknownError(err_code),
1469 }
1470 }
1471}
1472
1473#[derive(thiserror::Error, Debug)]
1474#[non_exhaustive]
1475pub enum EncodingError {
1476 #[error("Memory allocation error during encoding")]
1477 OutOfMemory,
1478
1479 #[error("Invalid argument provided to encoder")]
1480 InvalidArgument,
1481
1482 #[error("I/O error occurred during encoding")]
1483 IOError,
1484
1485 #[error("Broken pipe encountered during encoding")]
1486 PipeError,
1487
1488 #[error("Bad file descriptor encountered during encoding")]
1489 BadFileDescriptor,
1490
1491 #[error("Functionality not implemented or unsupported encoding feature")]
1492 NotImplemented,
1493
1494 #[error("Operation not permitted for encoder")]
1495 OperationNotPermitted,
1496
1497 #[error("Resource temporarily unavailable, try again later")]
1498 TryAgain,
1499
1500 #[error("End of stream reached or no more frames to encode")]
1501 EndOfStream,
1502
1503 #[error("An unknown error occurred during encoding. ret: {0}")]
1504 UnknownError(i32),
1505}
1506
1507impl From<i32> for EncodingError {
1508 fn from(err_code: i32) -> Self {
1509 match err_code {
1510 AVERROR_OUT_OF_MEMORY => EncodingError::OutOfMemory,
1511 AVERROR_INVALID_ARGUMENT => EncodingError::InvalidArgument,
1512 AVERROR_IO_ERROR => EncodingError::IOError,
1513 AVERROR_PIPE_ERROR => EncodingError::PipeError,
1514 AVERROR_BAD_FILE_DESCRIPTOR => EncodingError::BadFileDescriptor,
1515 AVERROR_NOT_IMPLEMENTED => EncodingError::NotImplemented,
1516 AVERROR_OPERATION_NOT_PERMITTED => EncodingError::OperationNotPermitted,
1517 AVERROR_AGAIN => EncodingError::TryAgain,
1518 AVERROR_EOF => EncodingError::EndOfStream,
1519 _ => EncodingError::UnknownError(err_code),
1520 }
1521 }
1522}
1523
1524#[derive(thiserror::Error, Debug)]
1525#[non_exhaustive]
1526pub enum FilterGraphError {
1527 #[error("Memory allocation error during filter graph processing")]
1528 OutOfMemory,
1529
1530 #[error("Invalid argument provided to filter graph processing")]
1531 InvalidArgument,
1532
1533 #[error("I/O error occurred during filter graph processing")]
1534 IOError,
1535
1536 #[error("Broken pipe during filter graph processing")]
1537 PipeError,
1538
1539 #[error("Bad file descriptor encountered during filter graph processing")]
1540 BadFileDescriptor,
1541
1542 #[error("Functionality not implemented or unsupported during filter graph processing")]
1543 NotImplemented,
1544
1545 #[error("Operation not permitted during filter graph processing")]
1546 OperationNotPermitted,
1547
1548 #[error("Resource temporarily unavailable during filter graph processing")]
1549 TryAgain,
1550
1551 #[error("EOF")]
1552 EOF,
1553
1554 #[error("An unknown error occurred during filter graph processing. ret:{0}")]
1555 UnknownError(i32),
1556}
1557
1558impl From<i32> for FilterGraphError {
1559 fn from(err_code: i32) -> Self {
1560 match err_code {
1561 AVERROR_OUT_OF_MEMORY => FilterGraphError::OutOfMemory,
1562 AVERROR_INVALID_ARGUMENT => FilterGraphError::InvalidArgument,
1563 AVERROR_IO_ERROR => FilterGraphError::IOError,
1564 AVERROR_PIPE_ERROR => FilterGraphError::PipeError,
1565 AVERROR_BAD_FILE_DESCRIPTOR => FilterGraphError::BadFileDescriptor,
1566 AVERROR_NOT_IMPLEMENTED => FilterGraphError::NotImplemented,
1567 AVERROR_OPERATION_NOT_PERMITTED => FilterGraphError::OperationNotPermitted,
1568 AVERROR_AGAIN => FilterGraphError::TryAgain,
1569 AVERROR_EOF => FilterGraphError::EOF,
1570 _ => FilterGraphError::UnknownError(err_code),
1571 }
1572 }
1573}
1574
1575#[derive(thiserror::Error, Debug)]
1576#[non_exhaustive]
1577pub enum OpenDecoderError {
1578 #[error("Memory allocation error during decoder initialization")]
1579 OutOfMemory,
1580
1581 #[error("Invalid argument provided during decoder initialization")]
1582 InvalidArgument,
1583
1584 #[error("Functionality not implemented or unsupported during decoder initialization")]
1585 NotImplemented,
1586
1587 #[error("Resource temporarily unavailable during decoder initialization")]
1588 TryAgain,
1589
1590 #[error("I/O error occurred during decoder initialization")]
1591 IOError,
1592
1593 #[error("An unknown error occurred during decoder initialization: {0}")]
1594 UnknownError(i32),
1595}
1596
1597impl From<i32> for OpenDecoderError {
1598 fn from(err_code: i32) -> Self {
1599 match err_code {
1600 AVERROR_OUT_OF_MEMORY => OpenDecoderError::OutOfMemory,
1601 AVERROR_INVALID_ARGUMENT => OpenDecoderError::InvalidArgument,
1602 AVERROR_NOT_IMPLEMENTED => OpenDecoderError::NotImplemented,
1603 AVERROR_AGAIN => OpenDecoderError::TryAgain,
1604 AVERROR_IO_ERROR => OpenDecoderError::IOError,
1605 _ => OpenDecoderError::UnknownError(err_code),
1606 }
1607 }
1608}
1609
1610#[derive(thiserror::Error, Debug)]
1611#[non_exhaustive]
1612pub enum DecodingError {
1613 #[error("Memory allocation error")]
1614 OutOfMemory,
1615
1616 #[error("Invalid argument provided")]
1617 InvalidArgument,
1618
1619 #[error("I/O error occurred during decoding")]
1620 IOError,
1621
1622 #[error("Timeout occurred during decoding")]
1623 Timeout,
1624
1625 #[error("Broken pipe encountered during decoding")]
1626 PipeError,
1627
1628 #[error("Bad file descriptor encountered during decoding")]
1629 BadFileDescriptor,
1630
1631 #[error("Unsupported functionality or format encountered")]
1632 NotImplemented,
1633
1634 #[error("Operation not permitted")]
1635 OperationNotPermitted,
1636
1637 #[error("Resource temporarily unavailable")]
1638 TryAgain,
1639
1640 #[error("An unknown decoding error occurred. ret:{0}")]
1641 UnknownError(i32),
1642}
1643
1644impl From<i32> for DecodingError {
1645 fn from(err_code: i32) -> Self {
1646 match err_code {
1647 AVERROR_OUT_OF_MEMORY => DecodingError::OutOfMemory,
1648 AVERROR_INVALID_ARGUMENT => DecodingError::InvalidArgument,
1649 AVERROR_IO_ERROR => DecodingError::IOError,
1650 AVERROR_TIMEOUT => DecodingError::Timeout,
1651 AVERROR_PIPE_ERROR => DecodingError::PipeError,
1652 AVERROR_BAD_FILE_DESCRIPTOR => DecodingError::BadFileDescriptor,
1653 AVERROR_NOT_IMPLEMENTED => DecodingError::NotImplemented,
1654 AVERROR_OPERATION_NOT_PERMITTED => DecodingError::OperationNotPermitted,
1655 AVERROR_AGAIN => DecodingError::TryAgain,
1656 _ => DecodingError::UnknownError(err_code),
1657 }
1658 }
1659}
1660
1661#[derive(thiserror::Error, Debug)]
1662#[non_exhaustive]
1663pub enum DecoderError {
1664 #[error("decoder '{0}' not found")]
1665 NotFound(String),
1666}
1667
1668#[derive(thiserror::Error, Debug)]
1669#[non_exhaustive]
1670pub enum DemuxingError {
1671 #[error("Memory allocation error")]
1672 OutOfMemory,
1673
1674 #[error("Invalid argument provided")]
1675 InvalidArgument,
1676
1677 #[error("I/O error occurred during demuxing")]
1678 IOError,
1679
1680 #[error("End of file reached during demuxing")]
1681 EndOfFile,
1682
1683 #[error("Resource temporarily unavailable")]
1684 TryAgain,
1685
1686 #[error("Functionality not implemented or unsupported")]
1687 NotImplemented,
1688
1689 #[error("Operation not permitted")]
1690 OperationNotPermitted,
1691
1692 #[error("Bad file descriptor encountered")]
1693 BadFileDescriptor,
1694
1695 #[error("Invalid data found when processing input")]
1696 InvalidData,
1697
1698 #[error("{}. ret:{0}", crate::util::ffmpeg_utils::av_err2str(*.0))]
1699 UnknownError(i32),
1700}
1701
1702impl From<i32> for DemuxingError {
1703 fn from(err_code: i32) -> Self {
1704 match err_code {
1705 AVERROR_OUT_OF_MEMORY => DemuxingError::OutOfMemory,
1706 AVERROR_INVALID_ARGUMENT => DemuxingError::InvalidArgument,
1707 AVERROR_IO_ERROR => DemuxingError::IOError,
1708 AVERROR_EOF => DemuxingError::EndOfFile,
1709 AVERROR_AGAIN => DemuxingError::TryAgain,
1710 AVERROR_NOT_IMPLEMENTED => DemuxingError::NotImplemented,
1711 AVERROR_OPERATION_NOT_PERMITTED => DemuxingError::OperationNotPermitted,
1712 AVERROR_BAD_FILE_DESCRIPTOR => DemuxingError::BadFileDescriptor,
1713 AVERROR_INVALIDDATA => DemuxingError::InvalidData,
1714 _ => DemuxingError::UnknownError(err_code),
1715 }
1716 }
1717}
1718
1719#[derive(thiserror::Error, Debug)]
1721#[non_exhaustive]
1722pub enum PacketScannerError {
1723 #[error("while seeking: {0}")]
1725 SeekError(DemuxingError),
1726
1727 #[error("while reading packet: {0}")]
1729 ReadError(DemuxingError),
1730}
1731
1732#[cfg(test)]
1733mod tests {
1734 #[test]
1739 fn frame_source_thread_exited_equals_itself() {
1740 use super::Error;
1741 assert_eq!(
1742 Error::FrameSourceThreadExited,
1743 Error::FrameSourceThreadExited
1744 );
1745 assert_ne!(Error::FrameSourceThreadExited, Error::NotStarted);
1746 }
1747
1748 #[test]
1753 fn filter_graph_parse_error_maps_permission_and_socket_codes() {
1754 use super::{FilterGraphParseError, AVERROR_NOT_SOCKET, AVERROR_PERMISSION_DENIED};
1755 assert!(matches!(
1756 FilterGraphParseError::from(AVERROR_PERMISSION_DENIED),
1757 FilterGraphParseError::PermissionDenied
1758 ));
1759 assert!(matches!(
1760 FilterGraphParseError::from(AVERROR_NOT_SOCKET),
1761 FilterGraphParseError::NotSocket
1762 ));
1763 }
1764
1765 #[test]
1769 fn frame_writable_error_maps_codes_and_pins_display() {
1770 use super::{Error, FrameWritableError, AVERROR_INVALID_ARGUMENT, AVERROR_OUT_OF_MEMORY};
1771 assert!(matches!(
1772 FrameWritableError::from(AVERROR_OUT_OF_MEMORY),
1773 FrameWritableError::OutOfMemory
1774 ));
1775 assert!(matches!(
1776 FrameWritableError::from(AVERROR_INVALID_ARGUMENT),
1777 FrameWritableError::InvalidArgument
1778 ));
1779 assert!(matches!(
1780 FrameWritableError::from(-99),
1781 FrameWritableError::UnknownError(-99)
1782 ));
1783 let err = Error::from(FrameWritableError::from(AVERROR_OUT_OF_MEMORY));
1784 assert_eq!(
1785 err.to_string(),
1786 "Frame writable error: Memory allocation error while copying frame data"
1787 );
1788 }
1789
1790 #[cfg(feature = "opengl")]
1794 #[test]
1795 fn opengl_filter_error_pins_display() {
1796 use super::{Error, OpenGLFilterError};
1797 let err = Error::from(OpenGLFilterError::InvalidOption(
1798 "fragment shader must declare 'in vec2 TexCoord;'".to_string(),
1799 ));
1800 assert_eq!(
1801 err.to_string(),
1802 "OpenGL filter error: invalid OpenGL filter option: \
1803 fragment shader must declare 'in vec2 TexCoord;'"
1804 );
1805 let err = Error::from(OpenGLFilterError::ContextCreation(
1806 "Failed to create Surfman connection".to_string(),
1807 ));
1808 assert_eq!(
1809 err.to_string(),
1810 "OpenGL filter error: OpenGL context creation failed: \
1811 Failed to create Surfman connection"
1812 );
1813 }
1814}