X-Git-Url: https://git.nihav.org/?a=blobdiff_plain;f=nihav-core%2Fsrc%2Fcodecs%2Fmod.rs;h=80e2da813ff4084ec814eb570ac0726b4258b2c3;hb=649cacccb6019eb40cfac6befade1ec0700fad88;hp=b6a1820d6bcf6bb87b3c9cad6f0c41aea7af6dc4;hpb=7f754c49a843d9b63885a1fa7e06f4d2cf6ccc5f;p=nihav.git diff --git a/nihav-core/src/codecs/mod.rs b/nihav-core/src/codecs/mod.rs index b6a1820..80e2da8 100644 --- a/nihav-core/src/codecs/mod.rs +++ b/nihav-core/src/codecs/mod.rs @@ -134,10 +134,79 @@ impl RegisteredDecoders { } } +/// Multithreaded decoder trait. +pub trait NADecoderMT: NAOptionHandler { + /// Initialises the decoder. + /// + /// It takes [`NADecoderSupport`] allocated by the caller and `NACodecInfoRef` provided by demuxer. + /// + /// [`NADecoderSupport`]: ./struct.NADecoderSupport.html + fn init(&mut self, supp: &mut NADecoderSupport, info: NACodecInfoRef, nthreads: usize) -> DecoderResult<()>; + /// Checks if a new frame can be queued for encoding. + fn can_take_input(&mut self) -> bool; + /// Queues a frame for decoding. + /// + /// Returns flag signalling whether the frame was queued or an error if it occured during the preparation stage. + /// + /// Parameter `id` is used to distinguish pictures as the output may be an error code with no timestamp available. + fn queue_pkt(&mut self, supp: &mut NADecoderSupport, pkt: &NAPacket, id: u32) -> DecoderResult; + /// Checks if some frames are already decoded and waiting to be retrieved. + fn has_output(&mut self) -> bool; + /// Waits for a frame to be decoded. + /// + /// In case there are no decoded frames yet, `None` is returned. + /// Otherwise, a decoding result and the input picture ID are returned. + fn get_frame(&mut self) -> (DecoderResult, u32); + /// Tells decoder to clear internal state (e.g. after error or seeking). + fn flush(&mut self); +} + +/// Decoder information used during creating a multi-threaded decoder for requested codec. +#[derive(Clone,Copy)] +pub struct MTDecoderInfo { + /// Short decoder name. + pub name: &'static str, + /// The function that creates a multi-threaded decoder instance. + pub get_decoder: fn () -> Box, +} + +/// Structure for registering known multi-threaded decoders. +/// +/// It is supposed to be filled using `register_all_mt_decoders()` from some decoders crate and then it can be used to create multi-threaded decoders for the requested codecs. +#[derive(Default)] +pub struct RegisteredMTDecoders { + decs: Vec, +} + +impl RegisteredMTDecoders { + /// Constructs a new instance of `RegisteredMTDecoders`. + pub fn new() -> Self { + Self { decs: Vec::new() } + } + /// Adds another decoder to the registry. + pub fn add_decoder(&mut self, dec: MTDecoderInfo) { + self.decs.push(dec); + } + /// Searches for the decoder for the provided name and returns a function for creating it on success. + pub fn find_decoder(&self, name: &str) -> Option Box> { + for &dec in self.decs.iter() { + if dec.name == name { + return Some(dec.get_decoder); + } + } + None + } + /// Provides an iterator over currently registered decoders. + pub fn iter(&self) -> std::slice::Iter { + self.decs.iter() + } +} + /// Frame skipping mode for decoders. -#[derive(Clone,Copy,PartialEq,Debug)] +#[derive(Clone,Copy,PartialEq,Debug,Default)] pub enum FrameSkipMode { /// Decode all frames. + #[default] None, /// Decode all key frames. KeyframesOnly, @@ -145,12 +214,6 @@ pub enum FrameSkipMode { IntraOnly, } -impl Default for FrameSkipMode { - fn default() -> Self { - FrameSkipMode::None - } -} - impl FromStr for FrameSkipMode { type Err = DecoderError; @@ -210,6 +273,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 { @@ -219,7 +289,7 @@ pub struct EncodeParameters { pub tb_num: u32, /// Time base denominator. Ignored for audio. pub tb_den: u32, - /// Bitrate in kilobits per second. + /// Bitrate in bits per second. pub bitrate: u32, /// A collection of various boolean encoder settings like CBR mode. /// @@ -300,6 +370,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. @@ -353,16 +427,22 @@ impl RegisteredEncoders { /// Trait for packetisers (objects that form full packets from raw stream data). pub trait NAPacketiser { + /// Provides the reference stream from the demuxer to the packetiser. + /// + /// This may be useful in cases when packetiser cannot determine stream parameters by itself. + fn attach_stream(&mut self, stream: NAStreamRef); /// 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. + /// Returns [`NAStream`] reference on success (with stream ID set to `id`), [`ShortData`] when there is not enough data to parse the headers, [`MissingReference`] when stream parsing is not possible without reference information provided by [`attach_stream`] and other errors in case there was an error parsing the data. /// /// [`NAStream`]: ../frame/struct.NAStream.html /// [`ShortData`]: ./enum.DecoderError.html#variant.ShortData + /// [`MissingReference`]: ./enum.DecoderError.html#variant.MissingReference + /// [`attach_stream`]: ./trait.NAPacketiser.html#tymethod.attach_stream fn parse_stream(&mut self, id: u32) -> DecoderResult; /// Tries to discard junk data until the first possible packet header. ///