1use std::{
2 collections::HashMap,
3 sync::{Arc, LazyLock, RwLock},
4};
5
6use media_core::{frame::Frame, variant::Variant, Result};
7
8use crate::{
9 codec::{find_codec, find_codec_by_name, register_codec, Codec, CodecBuilder, CodecID, CodecList, CodecParameters, LazyCodecList},
10 packet::Packet,
11};
12
13pub trait Decoder: Codec + Send + Sync {
14 fn send_packet(&mut self, parameters: Option<&CodecParameters>, packet: &Packet) -> Result<()>;
15 fn receive_frame(&mut self, parameters: Option<&CodecParameters>) -> Result<Frame<'static>> {
16 self.receive_frame_borrowed(parameters).map(|frame| frame.into_owned())
17 }
18 fn receive_frame_borrowed(&mut self, parameters: Option<&CodecParameters>) -> Result<Frame<'_>>;
19}
20
21pub trait DecoderBuilder: CodecBuilder {
22 fn new_decoder(&self, codec_id: CodecID, parameters: Option<CodecParameters>, options: Option<Variant>) -> Result<Box<dyn Decoder>>;
23}
24
25type DecoderBuilderList = CodecList<Arc<dyn DecoderBuilder>>;
26
27pub struct DecoderContext {
28 pub parameters: Option<CodecParameters>,
29 pub options: Option<Variant>,
30 decoder: Box<dyn Decoder>,
31}
32
33static CODEC_LIST: LazyCodecList<dyn DecoderBuilder> = LazyLock::new(|| {
34 RwLock::new(DecoderBuilderList {
35 codecs: HashMap::new(),
36 })
37});
38
39pub fn register_decoder(builder: Arc<dyn DecoderBuilder>, default: bool) -> Result<()> {
40 register_codec(&CODEC_LIST, builder, default)
41}
42
43pub(crate) fn find_decoder(codec_id: CodecID) -> Result<Arc<dyn DecoderBuilder>> {
44 find_codec(&CODEC_LIST, codec_id)
45}
46
47pub(crate) fn find_decoder_by_name(name: &str) -> Result<Arc<dyn DecoderBuilder>> {
48 find_codec_by_name(&CODEC_LIST, name)
49}
50
51impl DecoderContext {
52 pub fn from_codec_id(codec_id: CodecID, parameters: Option<CodecParameters>, options: Option<Variant>) -> Result<Self> {
53 let builder = find_decoder(codec_id)?;
54 let decoder = builder.new_decoder(codec_id, parameters.clone(), options.clone())?;
55
56 Ok(Self {
57 parameters,
58 options,
59 decoder,
60 })
61 }
62
63 pub fn from_codec_name(name: &str, parameters: Option<CodecParameters>, options: Option<Variant>) -> Result<Self> {
64 let builder = find_decoder_by_name(name)?;
65 let decoder = builder.new_decoder(builder.id(), parameters.clone(), options.clone())?;
66
67 Ok(Self {
68 parameters,
69 options,
70 decoder,
71 })
72 }
73
74 pub fn send_packet(&mut self, packet: &Packet) -> Result<()> {
75 let params = self.parameters.as_ref();
76 self.decoder.send_packet(params, packet)
77 }
78
79 pub fn receive_frame(&mut self) -> Result<Frame<'static>> {
80 let params = self.parameters.as_ref();
81 self.decoder.receive_frame(params)
82 }
83
84 pub fn receive_frame_borrowed(&mut self) -> Result<Frame<'_>> {
85 let params = self.parameters.as_ref();
86 self.decoder.receive_frame_borrowed(params)
87 }
88}