use ffmpeg_next::Packet;
use crate::backend::Backend;
pub type Result<T> = std::result::Result<T, Error>;
#[derive(Debug, thiserror::Error)]
pub enum Error {
#[error("ffmpeg error: {0}")]
Ffmpeg(#[from] ffmpeg_next::Error),
#[error("no decoder for codec id {0}")]
NoCodec(u32),
#[error("codec does not support backend {0:?}")]
BackendUnsupportedByCodec(Backend),
#[error(transparent)]
HwDeviceInitFailed(#[from] HwDeviceInitFailed),
#[error(transparent)]
AllBackendsFailed(#[from] AllBackendsFailed),
#[error(transparent)]
FallbackFailed(#[from] FallbackFailed),
}
#[derive(Debug, Clone, PartialEq, Eq, thiserror::Error)]
#[error("hardware device init failed for {backend:?}: {source}")]
pub struct HwDeviceInitFailed {
backend: Backend,
source: ffmpeg_next::Error,
}
impl HwDeviceInitFailed {
#[inline]
pub const fn new(backend: Backend, source: ffmpeg_next::Error) -> Self {
Self { backend, source }
}
#[inline]
pub const fn backend(&self) -> Backend {
self.backend
}
#[inline]
pub const fn source(&self) -> &ffmpeg_next::Error {
&self.source
}
#[inline]
pub fn into_parts(self) -> (Backend, ffmpeg_next::Error) {
(self.backend, self.source)
}
}
#[derive(thiserror::Error)]
#[error("all hardware backends failed; attempts: {attempts:?}")]
pub struct AllBackendsFailed {
attempts: Vec<(Backend, Box<Error>)>,
unconsumed_packets: Vec<Packet>,
}
impl AllBackendsFailed {
#[inline]
pub fn new(attempts: Vec<(Backend, Box<Error>)>, unconsumed_packets: Vec<Packet>) -> Self {
Self {
attempts,
unconsumed_packets,
}
}
#[inline]
pub fn attempts(&self) -> &[(Backend, Box<Error>)] {
&self.attempts
}
#[inline]
pub fn unconsumed_packets(&self) -> &[Packet] {
&self.unconsumed_packets
}
#[inline]
pub fn into_unconsumed_packets(self) -> Vec<Packet> {
self.unconsumed_packets
}
#[inline]
pub fn into_parts(self) -> (Vec<(Backend, Box<Error>)>, Vec<Packet>) {
(self.attempts, self.unconsumed_packets)
}
}
impl std::fmt::Debug for AllBackendsFailed {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("AllBackendsFailed")
.field("attempts", &self.attempts)
.field(
"unconsumed_packets",
&format_args!("[{} packets]", self.unconsumed_packets.len()),
)
.finish()
}
}
#[derive(thiserror::Error)]
#[error("HW->SW fallback failed: {source}")]
pub struct FallbackFailed {
source: Box<Error>,
unconsumed_packets: Vec<Packet>,
}
impl FallbackFailed {
#[inline]
pub fn new(source: Box<Error>, unconsumed_packets: Vec<Packet>) -> Self {
Self {
source,
unconsumed_packets,
}
}
#[inline]
pub fn source(&self) -> &Error {
&self.source
}
#[inline]
pub fn unconsumed_packets(&self) -> &[Packet] {
&self.unconsumed_packets
}
#[inline]
pub fn into_unconsumed_packets(self) -> Vec<Packet> {
self.unconsumed_packets
}
#[inline]
pub fn into_parts(self) -> (Box<Error>, Vec<Packet>) {
(self.source, self.unconsumed_packets)
}
}
impl std::fmt::Debug for FallbackFailed {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("FallbackFailed")
.field("source", &self.source)
.field(
"unconsumed_packets",
&format_args!("[{} packets]", self.unconsumed_packets.len()),
)
.finish()
}
}