X-Git-Url: https://git.nihav.org/?a=blobdiff_plain;f=nihav-core%2Fsrc%2Fcodecs%2Fmod.rs;h=5cf7d07b1eb1b230e5883e34f534d268e2f06ea7;hb=2757a0289c980aeba002609c777815b51ace8e56;hp=c6ee95ec71a844043d449af5b3e6ade48e7dc5ba;hpb=0975e7e77fc0b337dad578071a6deca6aa2b4697;p=nihav.git diff --git a/nihav-core/src/codecs/mod.rs b/nihav-core/src/codecs/mod.rs index c6ee95e..5cf7d07 100644 --- a/nihav-core/src/codecs/mod.rs +++ b/nihav-core/src/codecs/mod.rs @@ -18,6 +18,8 @@ pub enum DecoderError { TryAgain, /// Invalid input data was provided. InvalidData, + /// Checksum verification failed. + ChecksumError, /// Provided input turned out to be incomplete. ShortData, /// Decoder could not decode provided frame because it references some missing previous frame. @@ -102,7 +104,7 @@ pub struct DecoderInfo { /// Structure for registering known decoders. /// -/// It is supposed to be filled using `register_all_codecs()` from some decoders crate and then it can be used to create decoders for the requested codecs. +/// It is supposed to be filled using `register_all_decoders()` from some decoders crate and then it can be used to create decoders for the requested codecs. #[derive(Default)] pub struct RegisteredDecoders { decs: Vec, @@ -208,6 +210,13 @@ pub const ENC_MODE_CBR: u64 = 1 << 0; /// Encoding parameter flag to force constant framerate mode. pub const ENC_MODE_CFR: u64 = 1 << 1; +/// Encoder supports constant bitrate mode. +pub const ENC_CAPS_CBR: u64 = 1 << 0; +/// Encoder supports skip frames. +pub const ENC_CAPS_SKIPFRAME: u64 = 1 << 1; +/// Encoder supports mid-stream parameters change. +pub const ENC_CAPS_PARAMCHANGE: u64 = 1 << 2; + /// Encoding parameters. #[derive(Clone,Copy,PartialEq)] pub struct EncodeParameters { @@ -263,7 +272,7 @@ impl Default for EncodeParameters { /// while let Some(frame) = queue.get_frame() { /// // convert to the format encoder expects if required /// encoder.encode(frame)?; -/// while let Some(enc_pkt) = encoder.get_packet()? { +/// while let Ok(enc_pkt) = encoder.get_packet()? { /// // send encoded packet to a muxer for example /// } /// } @@ -298,6 +307,10 @@ pub trait NAEncoder: NAOptionHandler { /// // convert input into format defined in target_params, feed to the encoder, ... /// ``` fn negotiate_format(&self, encinfo: &EncodeParameters) -> EncoderResult; + /// Queries encoder capabilities. + /// + /// See `ENC_CAPS_*` for examples. + fn get_capabilities(&self) -> u64; /// Initialises the encoder. fn init(&mut self, stream_id: u32, encinfo: EncodeParameters) -> EncoderResult; /// Takes a single frame for encoding. @@ -319,7 +332,7 @@ pub struct EncoderInfo { /// Structure for registering known encoders. /// -/// It is supposed to be filled using `register_all_codecs()` from some encoders crate and then it can be used to create encoders for the requested codecs. +/// It is supposed to be filled using `register_all_decoders()` from some encoders crate and then it can be used to create encoders for the requested codecs. #[derive(Default)] pub struct RegisteredEncoders { encs: Vec, @@ -349,3 +362,71 @@ impl RegisteredEncoders { } } +/// Trait for packetisers (objects that form full packets from raw stream data). +pub trait NAPacketiser { + /// Queues new raw stream data for parsing. + /// + /// Returns false is the internal buffer grows too large. + fn add_data(&mut self, src: &[u8]) -> bool; + /// Tries to retrieve stream information from the data. + /// + /// Returns [`NAStream`] reference on success (with stream ID set to `id`), [`ShortData`] when there is not enough data to parse the headers and other errors in case there was an error parsing the data. + /// + /// [`NAStream`]: ../frame/struct.NAStream.html + /// [`ShortData`]: ./enum.DecoderError.html#variant.ShortData + fn parse_stream(&mut self, id: u32) -> DecoderResult; + /// Tries to discard junk data until the first possible packet header. + /// + /// Returns the number of bytes skipped. + fn skip_junk(&mut self) -> DecoderResult; + /// Tries to form full packet from the already queued data. + /// + /// The function should be called repeatedly until it returns nothing or an error. + fn get_packet(&mut self, stream: NAStreamRef) -> DecoderResult>; + /// Resets the internal buffer. + fn reset(&mut self); + /// Tells how much data is left in the internal buffer. + fn bytes_left(&self) -> usize; +} + +/// Decoder information used during creating a packetiser for requested codec. +#[derive(Clone,Copy)] +pub struct PacketiserInfo { + /// Short packetiser name. + pub name: &'static str, + /// The function that creates a packetiser instance. + pub get_packetiser: fn () -> Box, +} + +/// Structure for registering known packetisers. +/// +/// It is supposed to be filled using `register_all_packetisers()` from some decoders crate and then it can be used to create packetisers for the requested codecs. +#[derive(Default)] +pub struct RegisteredPacketisers { + packs: Vec, +} + +impl RegisteredPacketisers { + /// Constructs a new instance of `RegisteredPacketisers`. + pub fn new() -> Self { + Self { packs: Vec::new() } + } + /// Adds another packetiser to the registry. + pub fn add_packetiser(&mut self, pack: PacketiserInfo) { + self.packs.push(pack); + } + /// Searches for the packetiser for the provided name and returns a function for creating it on success. + pub fn find_packetiser(&self, name: &str) -> Option Box> { + for &pack in self.packs.iter() { + if pack.name == name { + return Some(pack.get_packetiser); + } + } + None + } + /// Provides an iterator over currently registered packetiser. + pub fn iter(&self) -> std::slice::Iter { + self.packs.iter() + } +} +