make muxers report their capabilities
[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 /// Muxer capabilities.
32 #[derive(Clone,Copy,Debug,PartialEq)]
33 pub enum MuxerCapabilities {
34 /// Muxer accepts single video stream with certain codec.
35 ///
36 /// Codec name `"any"` means various codecs are supported.
37 SingleVideo(&'static str),
38 /// Muxer accepts single audio stream with certain codec.
39 ///
40 /// Codec name `"any"` means various codecs are supported.
41 SingleAudio(&'static str),
42 /// Muxer accepts single video stream and single audio stream with defined codecs.
43 SingleVideoAndAudio(&'static str, &'static str),
44 /// Muxer accepts only video streams but can mux several video streams.
45 OnlyVideo,
46 /// Muxer accepts only audio streams but can mux several video streams..
47 OnlyAudio,
48 /// Muxer accepts variable amount of streams of any type.
49 Universal,
50 }
51
52 impl From<ByteIOError> for MuxerError {
53 fn from(_: ByteIOError) -> Self { MuxerError::IOError }
54 }
55
56 /// A trait for muxing operations.
57 pub trait MuxCore<'a> {
58 /// Prepares everything for packet muxing.
59 fn create(&mut self, strmgr: &StreamManager) -> MuxerResult<()>;
60 /// Queues a packet for muxing.
61 fn mux_frame(&mut self, strmgr: &StreamManager, pkt: NAPacket) -> MuxerResult<()>;
62 /// Flushes the current muxing state.
63 fn flush(&mut self) -> MuxerResult<()>;
64 /// Finishes muxing and writes necessary header and trailer information if needed.
65 fn end(&mut self) -> MuxerResult<()>;
66 }
67
68 /// Muxer structure with auxiliary data.
69 pub struct Muxer<'a> {
70 mux: Box<dyn MuxCore<'a> + 'a>,
71 streams: StreamManager,
72 }
73
74 impl<'a> Muxer<'a> {
75 /// Constructs a new `Muxer` instance.
76 fn new(mux: Box<dyn MuxCore<'a> + 'a>, str: StreamManager) -> Self {
77 Muxer {
78 mux,
79 streams: str,
80 }
81 }
82 /// Returns a stream reference by its number.
83 pub fn get_stream(&self, idx: usize) -> Option<NAStreamRef> {
84 self.streams.get_stream(idx)
85 }
86 /// Returns a stream reference by its ID.
87 pub fn get_stream_by_id(&self, id: u32) -> Option<NAStreamRef> {
88 self.streams.get_stream_by_id(id)
89 }
90 /// Reports the total number of streams.
91 pub fn get_num_streams(&self) -> usize {
92 self.streams.get_num_streams()
93 }
94 /// Returns an iterator over streams.
95 pub fn get_streams(&self) -> StreamIter {
96 self.streams.iter()
97 }
98
99 /// Demuxes a new packet from the container.
100 pub fn mux_frame(&mut self, pkt: NAPacket) -> MuxerResult<()> {
101 self.mux.mux_frame(&self.streams, pkt)
102 }
103 /// Returns internal seek index.
104 pub fn flush(&mut self) -> MuxerResult<()> {
105 self.mux.flush()
106 }
107 /// Finishes muxing and writes necessary header and trailer information if needed.
108 pub fn end(mut self) -> MuxerResult<()> {
109 self.mux.end()
110 }
111 }
112
113 /// The trait for creating muxers.
114 pub trait MuxerCreator {
115 /// Creates new muxer instance that will use `ByteWriter` for output.
116 fn new_muxer<'a>(&self, bw: &'a mut ByteWriter<'a>) -> Box<dyn MuxCore<'a> + 'a>;
117 /// Returns the name of current muxer creator (equal to the container name it can create).
118 fn get_name(&self) -> &'static str;
119 /// Returns muxer capabilities for the current muxer.
120 fn get_capabilities(&self) -> MuxerCapabilities;
121 }
122
123 /// Creates muxer for a provided bytestream writer.
124 pub fn create_muxer<'a>(mxcr: &MuxerCreator, str: StreamManager, bw: &'a mut ByteWriter<'a>) -> MuxerResult<Muxer<'a>> {
125 let mut mux = mxcr.new_muxer(bw);
126 mux.create(&str)?;
127 Ok(Muxer::new(mux, str))
128 }
129
130 /// List of registered muxers.
131 #[derive(Default)]
132 pub struct RegisteredMuxers {
133 muxes: Vec<&'static MuxerCreator>,
134 }
135
136 impl RegisteredMuxers {
137 /// Constructs a new `RegisteredMuxers` instance.
138 pub fn new() -> Self {
139 Self { muxes: Vec::new() }
140 }
141 /// Registers a new muxer.
142 pub fn add_muxer(&mut self, mux: &'static MuxerCreator) {
143 self.muxes.push(mux);
144 }
145 /// Searches for a muxer that supports requested container format.
146 pub fn find_muxer(&self, name: &str) -> Option<&MuxerCreator> {
147 for &mux in self.muxes.iter() {
148 if mux.get_name() == name {
149 return Some(mux);
150 }
151 }
152 None
153 }
154 }