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