--- /dev/null
+//! Muxer definitions.
+pub use crate::frame::*;
+pub use crate::io::byteio::*;
+pub use crate::demuxers::{StreamManager, StreamIter};
+
+/// A list specifying general muxing errors.
+#[derive(Debug,Clone,Copy,PartialEq)]
+#[allow(dead_code)]
+pub enum MuxerError {
+ /// An invalid argument was provided to the muxer.
+ InvalidArgument,
+ /// Trying to mux data without header being written.
+ NotCreated,
+ /// Muxer encountered invalid input packet.
+ InvalidData,
+ /// Input stream cannot be stored in this container format.
+ UnsupportedFormat,
+ /// Data writing error.
+ IOError,
+ /// Feature is not implemented.
+ NotImplemented,
+ /// Allocation failed.
+ MemoryError,
+ /// Operation cannot succeed in principle (e.g. seeking in an output stream not supporting seeking).
+ NotPossible,
+}
+
+/// A specialised `Result` type for muxing operations.
+pub type MuxerResult<T> = Result<T, MuxerError>;
+
+impl From<ByteIOError> for MuxerError {
+ fn from(_: ByteIOError) -> Self { MuxerError::IOError }
+}
+
+/// A trait for muxing operations.
+pub trait MuxCore<'a> {
+ /// Prepares everything for packet muxing.
+ fn create(&mut self, strmgr: &StreamManager) -> MuxerResult<()>;
+ /// Queues a packet for muxing.
+ fn mux_frame(&mut self, strmgr: &StreamManager, pkt: NAPacket) -> MuxerResult<()>;
+ /// Flushes the current muxing state.
+ fn flush(&mut self) -> MuxerResult<()>;
+ /// Finishes muxing and writes necessary header and trailer information if needed.
+ fn end(&mut self) -> MuxerResult<()>;
+}
+
+/// Muxer structure with auxiliary data.
+pub struct Muxer<'a> {
+ mux: Box<dyn MuxCore<'a> + 'a>,
+ streams: StreamManager,
+}
+
+impl<'a> Muxer<'a> {
+ /// Constructs a new `Muxer` instance.
+ fn new(mux: Box<dyn MuxCore<'a> + 'a>, str: StreamManager) -> Self {
+ Muxer {
+ mux,
+ streams: str,
+ }
+ }
+ /// Returns a stream reference by its number.
+ pub fn get_stream(&self, idx: usize) -> Option<NAStreamRef> {
+ self.streams.get_stream(idx)
+ }
+ /// Returns a stream reference by its ID.
+ pub fn get_stream_by_id(&self, id: u32) -> Option<NAStreamRef> {
+ self.streams.get_stream_by_id(id)
+ }
+ /// Reports the total number of streams.
+ pub fn get_num_streams(&self) -> usize {
+ self.streams.get_num_streams()
+ }
+ /// Returns an iterator over streams.
+ pub fn get_streams(&self) -> StreamIter {
+ self.streams.iter()
+ }
+
+ /// Demuxes a new packet from the container.
+ pub fn mux_frame(&mut self, pkt: NAPacket) -> MuxerResult<()> {
+ self.mux.mux_frame(&self.streams, pkt)
+ }
+ /// Returns internal seek index.
+ pub fn flush(&mut self) -> MuxerResult<()> {
+ self.mux.flush()
+ }
+ /// Finishes muxing and writes necessary header and trailer information if needed.
+ pub fn end(mut self) -> MuxerResult<()> {
+ self.mux.end()
+ }
+}
+
+/// The trait for creating muxers.
+pub trait MuxerCreator {
+ /// Creates new muxer instance that will use `ByteWriter` for output.
+ fn new_muxer<'a>(&self, bw: &'a mut ByteWriter<'a>) -> Box<dyn MuxCore<'a> + 'a>;
+ /// Returns the name of current muxer creator (equal to the container name it can create).
+ fn get_name(&self) -> &'static str;
+}
+
+/// Creates muxer for a provided bytestream writer.
+pub fn create_muxer<'a>(mxcr: &MuxerCreator, str: StreamManager, bw: &'a mut ByteWriter<'a>) -> MuxerResult<Muxer<'a>> {
+ let mut mux = mxcr.new_muxer(bw);
+ mux.create(&str)?;
+ Ok(Muxer::new(mux, str))
+}
+
+/// List of registered muxers.
+#[derive(Default)]
+pub struct RegisteredMuxers {
+ muxes: Vec<&'static MuxerCreator>,
+}
+
+impl RegisteredMuxers {
+ /// Constructs a new `RegisteredMuxers` instance.
+ pub fn new() -> Self {
+ Self { muxes: Vec::new() }
+ }
+ /// Registers a new muxer.
+ pub fn add_muxer(&mut self, mux: &'static MuxerCreator) {
+ self.muxes.push(mux);
+ }
+ /// Searches for a muxer that supports requested container format.
+ pub fn find_muxer(&self, name: &str) -> Option<&MuxerCreator> {
+ for &mux in self.muxes.iter() {
+ if mux.get_name() == name {
+ return Some(mux);
+ }
+ }
+ None
+ }
+}