1use std::collections::HashMap;
2
3use av_data::frame::ArcFrame;
4use av_data::packet::Packet;
5
6use crate::common::CodecList;
7use crate::error::*;
8
9pub trait Decoder: Send + Sync {
11 fn set_extradata(&mut self, extra: &[u8]);
15 fn send_packet(&mut self, pkt: &Packet) -> Result<()>;
17 fn receive_frame(&mut self) -> Result<ArcFrame>;
19 fn configure(&mut self) -> Result<()>;
21 fn flush(&mut self) -> Result<()>;
23}
24
25#[derive(Debug)]
29pub struct Descr {
30 pub codec: &'static str,
32 pub name: &'static str,
34 pub desc: &'static str,
36 pub mime: &'static str,
38 }
40
41pub struct Context<D: Decoder> {
44 dec: D,
45 }
47
48impl<D: Decoder> Context<D> {
49 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 pub fn set_extradata(&mut self, extra: &[u8]) {
62 self.dec.set_extradata(extra);
63 }
64
65 pub fn send_packet(&mut self, pkt: &Packet) -> Result<()> {
67 self.dec.send_packet(pkt)
68 }
69 pub fn receive_frame(&mut self) -> Result<ArcFrame> {
71 self.dec.receive_frame()
72 }
73 pub fn configure(&mut self) -> Result<()> {
75 self.dec.configure()
76 }
77
78 pub fn flush(&mut self) -> Result<()> {
80 self.dec.flush()
81 }
82
83 pub fn decoder(&self) -> &D {
85 &self.dec
86 }
87}
88
89pub trait Descriptor {
91 type OutputDecoder: Decoder;
93
94 fn create(&self) -> Self::OutputDecoder;
96 fn describe(&self) -> &Descr;
98}
99
100pub 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 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}