media_codec/
encoder.rs

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},
10    packet::Packet,
11};
12
13pub trait Encoder: Codec + Send + Sync {
14    fn send_frame(&mut self, parameters: Option<&CodecParameters>, frame: &Frame) -> Result<()>;
15    fn receive_packet(&mut self, parameters: Option<&CodecParameters>) -> Result<Packet<'static>>;
16    fn receive_packet_borrowed(&mut self, parameters: Option<&CodecParameters>) -> Result<Packet<'_>>;
17}
18
19pub trait EncoderBuilder: CodecBuilder {
20    fn new_encoder(&self, codec_id: CodecID, parameters: Option<CodecParameters>, options: Option<Variant>) -> Result<Box<dyn Encoder>>;
21}
22
23type EncoderBuilderList = CodecList<Arc<dyn EncoderBuilder>>;
24
25pub struct EncoderContext {
26    pub parameters: Option<CodecParameters>,
27    pub options: Option<Variant>,
28    encoder: Box<dyn Encoder>,
29}
30
31static CODEC_LIST: LazyLock<RwLock<EncoderBuilderList>> = LazyLock::new(|| {
32    RwLock::new(EncoderBuilderList {
33        codecs: HashMap::new(),
34    })
35});
36
37pub fn register_encoder(builder: Arc<dyn EncoderBuilder>, default: bool) -> Result<()> {
38    register_codec(&CODEC_LIST, builder, default)
39}
40
41pub(crate) fn find_encoder(codec_id: CodecID) -> Result<Arc<dyn EncoderBuilder>> {
42    find_codec(&CODEC_LIST, codec_id)
43}
44
45pub(crate) fn find_encoder_by_name(name: &str) -> Result<Arc<dyn EncoderBuilder>> {
46    find_codec_by_name(&CODEC_LIST, name)
47}
48
49impl EncoderContext {
50    pub fn from_codec_id(codec_id: CodecID, parameters: Option<CodecParameters>, options: Option<Variant>) -> Result<Self> {
51        let builder = find_encoder(codec_id)?;
52        let encoder = builder.new_encoder(codec_id, parameters.clone(), options.clone())?;
53
54        Ok(Self {
55            parameters,
56            options,
57            encoder,
58        })
59    }
60
61    pub fn from_codec_name(name: &str, parameters: Option<CodecParameters>, options: Option<Variant>) -> Result<Self> {
62        let builder = find_encoder_by_name(name)?;
63        let encoder = builder.new_encoder(builder.id(), parameters.clone(), options.clone())?;
64
65        Ok(Self {
66            parameters,
67            options,
68            encoder,
69        })
70    }
71
72    pub fn send_frame(&mut self, frame: &Frame) -> Result<()> {
73        let params = self.parameters.as_ref();
74        self.encoder.send_frame(params, frame)
75    }
76
77    pub fn receive_packet(&mut self) -> Result<Packet<'static>> {
78        let params = self.parameters.as_ref();
79        self.encoder.receive_packet(params)
80    }
81
82    pub fn receive_packet_borrowed(&mut self) -> Result<Packet<'_>> {
83        let params = self.parameters.as_ref();
84        self.encoder.receive_packet_borrowed(params)
85    }
86}