av_codec/
decoder.rs

1use std::collections::HashMap;
2
3use av_data::frame::ArcFrame;
4use av_data::packet::Packet;
5
6use crate::common::CodecList;
7use crate::error::*;
8
9/// Used to interact with a decoder.
10pub trait Decoder: Send + Sync {
11    // TODO support codec configuration using set_option
12    // fn open(&mut self) -> Result<()>;
13    /// Saves the extra data contained in a codec.
14    fn set_extradata(&mut self, extra: &[u8]);
15    /// Sends to the decoder a packet to be decoded.
16    fn send_packet(&mut self, pkt: &Packet) -> Result<()>;
17    /// Returns a decoded frame.
18    fn receive_frame(&mut self) -> Result<ArcFrame>;
19    /// Configures the decoder.
20    fn configure(&mut self) -> Result<()>;
21    /// Tells decoder to clear its internal state.
22    fn flush(&mut self) -> Result<()>;
23}
24
25/// Codec descriptor.
26///
27/// Contains information on a codec and its own decoder.
28#[derive(Debug)]
29pub struct Descr {
30    /// The codec name.
31    pub codec: &'static str,
32    /// The extended codec name.
33    pub name: &'static str,
34    /// The codec description.
35    pub desc: &'static str,
36    /// The codec MIME.
37    pub mime: &'static str,
38    // TODO more fields regarding capabilities
39}
40
41/// Auxiliary structure to encapsulate a decoder object and
42/// its additional data.
43pub struct Context<D: Decoder> {
44    dec: D,
45    // TODO: Queue up packets/frames
46}
47
48impl<D: Decoder> Context<D> {
49    // TODO: More constructors
50    /// Retrieves a codec descriptor from a codec list through its name,
51    /// creates the relative decoder, and encapsulates it into a new `Context`.
52    pub fn by_name<T: Descriptor<OutputDecoder = D> + ?Sized>(
53        codecs: &Codecs<T>,
54        name: &str,
55    ) -> Option<Self> {
56        codecs.by_name(name).map(|builder| Context {
57            dec: builder.create(),
58        })
59    }
60    /// Saves the extra data contained in a codec.
61    pub fn set_extradata(&mut self, extra: &[u8]) {
62        self.dec.set_extradata(extra);
63    }
64
65    /// Sends to the decoder a packet to be decoded.
66    pub fn send_packet(&mut self, pkt: &Packet) -> Result<()> {
67        self.dec.send_packet(pkt)
68    }
69    /// Returns a decoded frame.
70    pub fn receive_frame(&mut self) -> Result<ArcFrame> {
71        self.dec.receive_frame()
72    }
73    /// Configures the decoder.
74    pub fn configure(&mut self) -> Result<()> {
75        self.dec.configure()
76    }
77
78    /// Tells decoder to clear its internal state.
79    pub fn flush(&mut self) -> Result<()> {
80        self.dec.flush()
81    }
82
83    /// Returns the underlying decoder.
84    pub fn decoder(&self) -> &D {
85        &self.dec
86    }
87}
88
89/// Used to get the descriptor of a codec and create its own decoder.
90pub trait Descriptor {
91    /// The specific type of the decoder.
92    type OutputDecoder: Decoder;
93
94    /// Creates a new decoder for the requested codec.
95    fn create(&self) -> Self::OutputDecoder;
96    /// Returns the codec descriptor.
97    fn describe(&self) -> &Descr;
98}
99
100/// A list of codec descriptors.
101pub struct Codecs<T: 'static + Descriptor + ?Sized> {
102    list: HashMap<&'static str, Vec<&'static T>>,
103}
104
105impl<T: Descriptor + ?Sized> CodecList for Codecs<T> {
106    type D = T;
107
108    fn new() -> Self {
109        Self {
110            list: HashMap::new(),
111        }
112    }
113
114    // TODO more lookup functions
115    fn by_name(&self, name: &str) -> Option<&'static Self::D> {
116        self.list.get(name).map(|descs| descs[0])
117    }
118
119    fn append(&mut self, desc: &'static Self::D) {
120        let codec_name = desc.describe().codec;
121
122        self.list.entry(codec_name).or_default().push(desc);
123    }
124}
125
126#[cfg(test)]
127mod test {
128    use super::*;
129
130    mod dummy {
131        use super::super::*;
132
133        pub struct Dec {
134            state: usize,
135        }
136
137        pub struct Des {
138            descr: Descr,
139        }
140
141        impl Descriptor for Des {
142            type OutputDecoder = Dec;
143
144            fn create(&self) -> Self::OutputDecoder {
145                Dec { state: 0 }
146            }
147
148            fn describe(&self) -> &Descr {
149                &self.descr
150            }
151        }
152
153        impl Decoder for Dec {
154            fn configure(&mut self) -> Result<()> {
155                Ok(())
156            }
157            fn set_extradata(&mut self, extra: &[u8]) {
158                if extra.len() > 4 {
159                    self.state = 42;
160                } else {
161                    self.state = 12;
162                }
163            }
164            fn send_packet(&mut self, _packet: &Packet) -> Result<()> {
165                self.state += 1;
166                Ok(())
167            }
168            fn receive_frame(&mut self) -> Result<ArcFrame> {
169                unimplemented!()
170            }
171            fn flush(&mut self) -> Result<()> {
172                Ok(())
173            }
174        }
175
176        pub const DUMMY_DESCR: &Des = &Des {
177            descr: Descr {
178                codec: "dummy",
179                name: "dummy",
180                desc: "Dummy decoder",
181                mime: "x-application/dummy",
182            },
183        };
184    }
185    use self::dummy::DUMMY_DESCR;
186
187    #[test]
188    fn lookup() {
189        let codecs = Codecs::from_list(&[DUMMY_DESCR]);
190
191        let _dec = codecs.by_name("dummy").unwrap();
192    }
193}