1use std::path::PathBuf;
4use thiserror::Error;
5
6#[derive(Error, Debug)]
8pub enum EncodeError {
9 #[error("Cannot create output file: {path}")]
11 CannotCreateFile {
12 path: PathBuf,
14 },
15
16 #[error("Unsupported codec: {codec}")]
18 UnsupportedCodec {
19 codec: String,
21 },
22
23 #[error("No suitable encoder found for {codec} (tried: {tried:?})")]
25 NoSuitableEncoder {
26 codec: String,
28 tried: Vec<String>,
30 },
31
32 #[error("Encoding failed at frame {frame}: {reason}")]
34 EncodingFailed {
35 frame: u64,
37 reason: String,
39 },
40
41 #[error("Invalid configuration: {reason}")]
43 InvalidConfig {
44 reason: String,
46 },
47
48 #[error("Hardware encoder unavailable: {encoder}")]
50 HwEncoderUnavailable {
51 encoder: String,
53 },
54
55 #[error("Muxing failed: {reason}")]
57 MuxingFailed {
58 reason: String,
60 },
61
62 #[error("FFmpeg error: {0}")]
64 Ffmpeg(String),
65
66 #[error("IO error: {0}")]
68 Io(#[from] std::io::Error),
69
70 #[error("Encoding cancelled by user")]
72 Cancelled,
73}
74
75impl EncodeError {
76 pub(crate) fn from_ffmpeg_error(errnum: i32) -> Self {
82 let error_msg = ff_sys::av_error_string(errnum);
83 EncodeError::Ffmpeg(format!("{} (code: {})", error_msg, errnum))
84 }
85}
86
87#[cfg(test)]
88mod tests {
89 use super::EncodeError;
90
91 #[test]
92 fn from_ffmpeg_error_returns_ffmpeg_variant() {
93 let err = EncodeError::from_ffmpeg_error(ff_sys::error_codes::EINVAL);
94 assert!(matches!(err, EncodeError::Ffmpeg(_)));
95 }
96
97 #[test]
98 fn from_ffmpeg_error_message_contains_code() {
99 let err = EncodeError::from_ffmpeg_error(ff_sys::error_codes::EINVAL);
100 let msg = err.to_string();
101 assert!(msg.contains("code: -22"), "expected 'code: -22' in '{msg}'");
102 }
103
104 #[test]
105 fn from_ffmpeg_error_message_nonempty() {
106 let err = EncodeError::from_ffmpeg_error(ff_sys::error_codes::ENOMEM);
107 let msg = err.to_string();
108 assert!(!msg.is_empty());
109 }
110
111 #[test]
112 fn from_ffmpeg_error_eof() {
113 let err = EncodeError::from_ffmpeg_error(ff_sys::error_codes::EOF);
114 assert!(matches!(err, EncodeError::Ffmpeg(_)));
115 assert!(!err.to_string().is_empty());
116 }
117}