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