Skip to main content

wedeo_codec/
decoder.rs

1use wedeo_core::channel_layout::ChannelLayout;
2use wedeo_core::codec_id::CodecId;
3use wedeo_core::error::Result;
4use wedeo_core::frame::Frame;
5use wedeo_core::media_type::MediaType;
6use wedeo_core::packet::Packet;
7use wedeo_core::pixel_format::PixelFormat;
8use wedeo_core::rational::Rational;
9use wedeo_core::sample_format::SampleFormat;
10
11use crate::descriptor::{CodecCapabilities, CodecDescriptor, CodecProperties};
12use crate::options::CodecOptions;
13
14/// Parameters needed to open a decoder, extracted from stream info.
15#[derive(Debug, Clone)]
16pub struct CodecParameters {
17    pub codec_id: CodecId,
18    pub media_type: MediaType,
19    pub extradata: Vec<u8>,
20
21    // Audio-specific
22    pub sample_rate: u32,
23    pub sample_format: SampleFormat,
24    pub channel_layout: ChannelLayout,
25
26    // Video-specific
27    pub width: u32,
28    pub height: u32,
29    pub pixel_format: PixelFormat,
30
31    pub bit_rate: i64,
32    pub time_base: Rational,
33    pub block_align: u32,
34    pub bits_per_coded_sample: u32,
35    pub bits_per_raw_sample: u32,
36
37    /// Number of threads for decoding. 0 = auto (let the runtime decide).
38    pub thread_count: u32,
39    /// Codec tag (fourcc) for disambiguation when codec_id alone is ambiguous.
40    /// 0 = unset.
41    pub codec_tag: u32,
42    /// Codec-private options (string key-value pairs).
43    pub options: CodecOptions,
44}
45
46impl CodecParameters {
47    pub fn new(codec_id: CodecId, media_type: MediaType) -> Self {
48        Self {
49            codec_id,
50            media_type,
51            extradata: Vec::new(),
52            sample_rate: 0,
53            sample_format: SampleFormat::None,
54            channel_layout: ChannelLayout::unspec(0),
55            width: 0,
56            height: 0,
57            pixel_format: PixelFormat::None,
58            bit_rate: 0,
59            time_base: Rational::new(0, 1),
60            block_align: 0,
61            bits_per_coded_sample: 0,
62            bits_per_raw_sample: 0,
63            thread_count: 0,
64            codec_tag: 0,
65            options: CodecOptions::new(),
66        }
67    }
68}
69
70/// Decoder trait — the main abstraction for all decoders.
71///
72/// Follows FFmpeg's send/receive model:
73/// 1. `send_packet()` — feed compressed data
74/// 2. `receive_frame()` — pull decoded data (may need multiple calls)
75/// 3. `flush()` — reset state after seeking
76pub trait Decoder: Send {
77    /// Send a compressed packet to the decoder.
78    /// Pass `None` to signal end-of-stream (drain mode).
79    fn send_packet(&mut self, packet: Option<&Packet>) -> Result<()>;
80
81    /// Receive a decoded frame from the decoder.
82    /// Returns `Error::Again` when more input is needed.
83    /// Returns `Error::Eof` when all data has been drained.
84    fn receive_frame(&mut self) -> Result<Frame>;
85
86    /// Flush the decoder (reset internal state for seeking).
87    fn flush(&mut self);
88
89    /// Get the codec descriptor.
90    fn descriptor(&self) -> &CodecDescriptor;
91}
92
93/// Builder for creating decoders.
94/// Follows the builder pattern instead of FFmpeg's allocate-then-mutate.
95pub struct DecoderBuilder {
96    params: CodecParameters,
97}
98
99impl DecoderBuilder {
100    pub fn new(params: CodecParameters) -> Self {
101        Self { params }
102    }
103
104    /// Set a codec-private option (string key-value pair).
105    pub fn option(mut self, key: &str, value: &str) -> Self {
106        self.params.options.set(key, value);
107        self
108    }
109
110    /// Consume the builder and open a decoder.
111    /// Uses the codec registry to find the appropriate decoder.
112    pub fn open(self) -> Result<Box<dyn Decoder>> {
113        crate::registry::find_decoder(self.params.codec_id)
114            .ok_or(wedeo_core::Error::DecoderNotFound)?
115            .create(self.params)
116    }
117
118    pub fn params(&self) -> &CodecParameters {
119        &self.params
120    }
121}
122
123/// Descriptor for a decoder implementation, used in the registry.
124#[derive(Debug, Clone)]
125pub struct DecoderDescriptor {
126    pub codec_id: CodecId,
127    pub name: &'static str,
128    pub long_name: &'static str,
129    pub media_type: MediaType,
130    pub capabilities: CodecCapabilities,
131    pub properties: CodecProperties,
132    /// Priority for registry selection. Higher priority wins when multiple
133    /// decoders support the same codec_id. Native implementations use 100,
134    /// wrapper/adapter implementations use 50.
135    pub priority: i32,
136}