ba6f780081297c52b8c7e9eade5dfc7db16ada25
[nihav.git] / nihav-core / src / muxers / mod.rs
1 //! Muxer definitions.
2 pub use crate::frame::*;
3 pub use crate::io::byteio::*;
4 pub use crate::demuxers::{StreamManager, StreamIter};
5
6 /// A list specifying general muxing errors.
7 #[derive(Debug,Clone,Copy,PartialEq)]
8 #[allow(dead_code)]
9 pub enum MuxerError {
10 /// An invalid argument was provided to the muxer.
11 InvalidArgument,
12 /// Trying to mux data without header being written.
13 NotCreated,
14 /// Muxer encountered invalid input packet.
15 InvalidData,
16 /// Input stream cannot be stored in this container format.
17 UnsupportedFormat,
18 /// Data writing error.
19 IOError,
20 /// Feature is not implemented.
21 NotImplemented,
22 /// Allocation failed.
23 MemoryError,
24 /// Operation cannot succeed in principle (e.g. seeking in an output stream not supporting seeking).
25 NotPossible,
26 }
27
28 /// A specialised `Result` type for muxing operations.
29 pub type MuxerResult<T> = Result<T, MuxerError>;
30
31 impl From<ByteIOError> for MuxerError {
32 fn from(_: ByteIOError) -> Self { MuxerError::IOError }
33 }
34
35 /// A trait for muxing operations.
36 pub trait MuxCore<'a> {
37 /// Prepares everything for packet muxing.
38 fn create(&mut self, strmgr: &StreamManager) -> MuxerResult<()>;
39 /// Queues a packet for muxing.
40 fn mux_frame(&mut self, strmgr: &StreamManager, pkt: NAPacket) -> MuxerResult<()>;
41 /// Flushes the current muxing state.
42 fn flush(&mut self) -> MuxerResult<()>;
43 /// Finishes muxing and writes necessary header and trailer information if needed.
44 fn end(&mut self) -> MuxerResult<()>;
45 }
46
47 /// Muxer structure with auxiliary data.
48 pub struct Muxer<'a> {
49 mux: Box<dyn MuxCore<'a> + 'a>,
50 streams: StreamManager,
51 }
52
53 impl<'a> Muxer<'a> {
54 /// Constructs a new `Muxer` instance.
55 fn new(mux: Box<dyn MuxCore<'a> + 'a>, str: StreamManager) -> Self {
56 Muxer {
57 mux,
58 streams: str,
59 }
60 }
61 /// Returns a stream reference by its number.
62 pub fn get_stream(&self, idx: usize) -> Option<NAStreamRef> {
63 self.streams.get_stream(idx)
64 }
65 /// Returns a stream reference by its ID.
66 pub fn get_stream_by_id(&self, id: u32) -> Option<NAStreamRef> {
67 self.streams.get_stream_by_id(id)
68 }
69 /// Reports the total number of streams.
70 pub fn get_num_streams(&self) -> usize {
71 self.streams.get_num_streams()
72 }
73 /// Returns an iterator over streams.
74 pub fn get_streams(&self) -> StreamIter {
75 self.streams.iter()
76 }
77
78 /// Demuxes a new packet from the container.
79 pub fn mux_frame(&mut self, pkt: NAPacket) -> MuxerResult<()> {
80 self.mux.mux_frame(&self.streams, pkt)
81 }
82 /// Returns internal seek index.
83 pub fn flush(&mut self) -> MuxerResult<()> {
84 self.mux.flush()
85 }
86 /// Finishes muxing and writes necessary header and trailer information if needed.
87 pub fn end(mut self) -> MuxerResult<()> {
88 self.mux.end()
89 }
90 }
91
92 /// The trait for creating muxers.
93 pub trait MuxerCreator {
94 /// Creates new muxer instance that will use `ByteWriter` for output.
95 fn new_muxer<'a>(&self, bw: &'a mut ByteWriter<'a>) -> Box<dyn MuxCore<'a> + 'a>;
96 /// Returns the name of current muxer creator (equal to the container name it can create).
97 fn get_name(&self) -> &'static str;
98 }
99
100 /// Creates muxer for a provided bytestream writer.
101 pub fn create_muxer<'a>(mxcr: &MuxerCreator, str: StreamManager, bw: &'a mut ByteWriter<'a>) -> MuxerResult<Muxer<'a>> {
102 let mut mux = mxcr.new_muxer(bw);
103 mux.create(&str)?;
104 Ok(Muxer::new(mux, str))
105 }
106
107 /// List of registered muxers.
108 #[derive(Default)]
109 pub struct RegisteredMuxers {
110 muxes: Vec<&'static MuxerCreator>,
111 }
112
113 impl RegisteredMuxers {
114 /// Constructs a new `RegisteredMuxers` instance.
115 pub fn new() -> Self {
116 Self { muxes: Vec::new() }
117 }
118 /// Registers a new muxer.
119 pub fn add_muxer(&mut self, mux: &'static MuxerCreator) {
120 self.muxes.push(mux);
121 }
122 /// Searches for a muxer that supports requested container format.
123 pub fn find_muxer(&self, name: &str) -> Option<&MuxerCreator> {
124 for &mux in self.muxes.iter() {
125 if mux.get_name() == name {
126 return Some(mux);
127 }
128 }
129 None
130 }
131 }