improve raw stream handling
[nihav-tool.git] / src / demux.rs
CommitLineData
55d3e99f
KS
1use std::io::SeekFrom;
2use nihav_core::codecs::*;
3use nihav_core::demuxers::*;
4use nihav_registry::detect;
5use nihav_core::io::byteio::ByteReader;
6use nihav_allstuff::*;
7
8pub struct FullRegister {
9 pub dmx_reg: RegisteredDemuxers,
10 pub rdmx_reg: RegisteredRawDemuxers,
11 pub pkt_reg: RegisteredPacketisers,
12 pub dec_reg: RegisteredDecoders,
13}
14
15impl FullRegister {
16 pub fn new() -> Self {
17 let mut dmx_reg = RegisteredDemuxers::new();
18 nihav_register_all_demuxers(&mut dmx_reg);
19 let mut rdmx_reg = RegisteredRawDemuxers::new();
20 nihav_register_all_raw_demuxers(&mut rdmx_reg);
21 let mut dec_reg = RegisteredDecoders::new();
22 nihav_register_all_decoders(&mut dec_reg);
23 let mut pkt_reg = RegisteredPacketisers::new();
24 nihav_register_all_packetisers(&mut pkt_reg);
25 Self { dmx_reg, rdmx_reg, pkt_reg, dec_reg }
26 }
27}
28
e01dfa5a
KS
29pub struct RawStreamCtx<'a> {
30 stream: NAStreamRef,
31 pkt: Box<dyn NAPacketiser + Send>,
32 br: &'a mut ByteReader<'a>,
33 pts: u64,
34}
35
36impl<'a> RawStreamCtx<'a> {
37 fn new(stream: NAStreamRef, packetiser: Box<dyn NAPacketiser + Send>, br: &'a mut ByteReader<'a>) -> Self {
38 Self { stream, pkt: packetiser, br, pts: 0 }
39 }
40}
41
55d3e99f
KS
42pub enum DemuxerObject<'a> {
43 None,
44 Normal(Demuxer<'a>),
45 Raw(RawDemuxer<'a>, Vec<Option<Box<dyn NAPacketiser + Send>>>, bool),
e01dfa5a 46 RawStream(RawStreamCtx<'a>),
55d3e99f
KS
47}
48
49impl<'a> DemuxerObject<'a> {
50 pub fn create(br: &'a mut ByteReader<'a>, reg: &FullRegister, name: &str, is_raw: bool) -> DemuxerObject<'a> {
51 if !is_raw {
52 let res = detect::detect_format(name, br);
53 let (dmx_name, _) = res.unwrap_or(("", detect::DetectionScore::No));
54 if dmx_name != "" {
55 println!("trying demuxer {} on {}", dmx_name, name);
56 if let Some(dmx_fact) = reg.dmx_reg.find_demuxer(dmx_name) {
57 br.seek(SeekFrom::Start(0)).unwrap();
58 let dmx = create_demuxer(dmx_fact, br).unwrap();
59 return DemuxerObject::Normal(dmx);
60 }
61 }
62 if dmx_name != "" {
63 println!("trying raw demuxer {} on {}", dmx_name, name);
64 if let Some(rdmx_fact) = reg.rdmx_reg.find_demuxer(dmx_name) {
65 br.seek(SeekFrom::Start(0)).unwrap();
66 let dmx = create_raw_demuxer(rdmx_fact, br).unwrap();
67 let mut pkts = Vec::new();
68 for stream in dmx.get_streams() {
69 if let Some(pcreate) = reg.pkt_reg.find_packetiser(stream.get_info().get_name()) {
70 let packetiser = (pcreate)();
71 pkts.push(Some(packetiser));
72 } else {
73 pkts.push(None);
74 }
75 }
76 return DemuxerObject::Raw(dmx, pkts, false);
77 }
78 }
79 for rdmx in reg.rdmx_reg.iter() {
80 if rdmx.check_format(br) {
81 println!("detected {} as {}", name, rdmx.get_name());
82 br.seek(SeekFrom::Start(0)).unwrap();
83 let dmx = create_raw_demuxer(*rdmx, br).unwrap();
84 let mut pkts = Vec::new();
85 for stream in dmx.get_streams() {
86 if let Some(pcreate) = reg.pkt_reg.find_packetiser(stream.get_info().get_name()) {
87 let packetiser = (pcreate)();
88 pkts.push(Some(packetiser));
89 } else {
90 pkts.push(None);
91 }
92 }
93 return DemuxerObject::Raw(dmx, pkts, false);
94 }
95 }
96 }
97 br.seek(SeekFrom::Start(0)).unwrap();
98 let mut buf = vec![0; 1048576];
99 let size = br.peek_buf(&mut buf).unwrap();
100 let mut pname = "";
101
102 for pinfo in reg.pkt_reg.iter() {
103 let mut packetiser = (pinfo.get_packetiser)();
104 packetiser.add_data(&buf[..size]);
105 if packetiser.parse_stream(0).is_ok() {
106 pname = pinfo.name;
107 break;
108 }
109 }
110 if pname != "" {
111 println!("found raw stream of type {} for {}", pname, name);
112 let pcreate = reg.pkt_reg.find_packetiser(pname).unwrap();
113 let mut packetiser = (pcreate)();
114 packetiser.add_data(&buf[..size]);
115 let stream = packetiser.parse_stream(0).unwrap();
116 packetiser.reset();
e01dfa5a 117 DemuxerObject::RawStream(RawStreamCtx::new(stream, packetiser, br))
55d3e99f
KS
118 } else {
119 DemuxerObject::None
120 }
121 }
122 pub fn is_none(&self) -> bool {
123 match *self {
124 DemuxerObject::None => true,
125 _ => false,
126 }
127 }
128 pub fn get_duration(&self) -> u64 {
129 match *self {
130 DemuxerObject::Normal(ref dmx) => dmx.get_duration(),
131 DemuxerObject::Raw(ref dmx, _, _) => dmx.get_duration(),
132 _ => 0,
133 }
134 }
135 pub fn get_num_streams(&self) -> usize {
136 match *self {
137 DemuxerObject::None => 0,
138 DemuxerObject::Normal(ref dmx) => dmx.get_num_streams(),
139 DemuxerObject::Raw(ref dmx, _, _) => dmx.get_num_streams(),
e01dfa5a 140 DemuxerObject::RawStream(_) => 1,
55d3e99f
KS
141 }
142 }
143 pub fn get_stream(&self, idx: usize) -> Option<NAStreamRef> {
144 match *self {
145 DemuxerObject::Normal(ref dmx) => dmx.get_stream(idx),
146 DemuxerObject::Raw(ref dmx, _, _) => dmx.get_stream(idx),
e01dfa5a 147 DemuxerObject::RawStream(ref ctx) if idx == 0 => Some(ctx.stream.clone()),
55d3e99f
KS
148 _ => None,
149 }
150 }
151 pub fn get_frame(&mut self) -> DemuxerResult<NAPacket> {
152 match *self {
153 DemuxerObject::Normal(ref mut dmx) => dmx.get_frame(),
154 DemuxerObject::Raw(ref mut dmx, ref mut packetisers, ref mut eof) => {
155 loop {
156 let mut has_some = false;
157 for (stream, p) in dmx.get_streams().zip(packetisers.iter_mut()) {
158 if let Some(ref mut pkts) = p {
159 match pkts.get_packet(stream.clone()) {
160 Ok(Some(pkt)) => return Ok(pkt),
161 Ok(None) | Err(DecoderError::ShortData) => {
162 if *eof {
163 *p = None;
164 }
165 },
166 Err(err) => {
167 println!("packetisation error {:?}", err);
168 return Err(DemuxerError::InvalidData);
169 }
170 };
171 has_some |= p.is_some();
172 }
173 }
174 if !has_some {
175 return Err(DemuxerError::EOF);
176 }
177 if let Ok(data) = dmx.get_data() {
178 let id = data.get_stream().get_id();
179 for (i, stream) in dmx.get_streams().enumerate() {
180 if stream.get_id() == id {
181 if let Some(ref mut pkts) = packetisers[i] {
182 pkts.add_data(&data.get_buffer());
183 }
184 break;
185 }
186 }
187 } else {
188 *eof = true;
189 }
190 }
191 },
e01dfa5a 192 DemuxerObject::RawStream(ref mut ctx) => {
55d3e99f
KS
193 let mut buf = [0; 1048576];
194 loop {
e01dfa5a
KS
195 match ctx.pkt.get_packet(ctx.stream.clone()) {
196 Ok(Some(mut packet)) => {
197 if packet.get_pts().is_none() && packet.get_duration().is_some() {
198 packet.ts.pts = Some(ctx.pts);
199 }
200 ctx.pts += packet.get_duration().unwrap_or(0);
201 return Ok(packet);
202 },
55d3e99f
KS
203 Ok(None) => {},
204 Err(DecoderError::ShortData) => {},
205 _ => return Err(DemuxerError::InvalidData),
206 };
e01dfa5a 207 match ctx.br.read_buf_some(&mut buf) {
55d3e99f 208 Ok(size) => {
e01dfa5a 209 ctx.pkt.add_data(&buf[..size]);
55d3e99f
KS
210 },
211 Err(_) => {
e01dfa5a
KS
212 match ctx.pkt.get_packet(ctx.stream.clone()) {
213 Ok(Some(mut packet)) => {
214 if packet.get_pts().is_none() && packet.get_duration().is_some() {
215 packet.ts.pts = Some(ctx.pts);
216 }
217 ctx.pts += packet.get_duration().unwrap_or(0);
218 return Ok(packet);
219 },
55d3e99f
KS
220 Ok(None) | Err(DecoderError::ShortData) => return Err(DemuxerError::EOF),
221 _ => return Err(DemuxerError::InvalidData),
222 };
223 },
224 };
225 }
226 },
227 _ => unreachable!(),
228 }
229 }
230 pub fn seek(&mut self, seek_time: NATimePoint) -> DemuxerResult<()> {
231 match *self {
232 DemuxerObject::Normal(ref mut dmx) => dmx.seek(seek_time),
233 DemuxerObject::Raw(ref mut dmx, _, _) => dmx.seek(seek_time),
234 _ => Err(DemuxerError::NotImplemented),
235 }
236 }
237}
238
239pub fn detect_tags(br: &mut ByteReader) -> (bool, u64, Option<u64>) {
240 let mut is_raw = false;
241 let mut start = 0;
242 let mut end = None;
243
244 // check for ID3v{2-4}
245 let mut buf = [0; 5];
246 br.peek_buf(&mut buf).unwrap();
247 if &buf[0..3] == b"ID3" && buf[3] > 0 && buf[3] < 5 && buf[4] == 0 { //ID3 tag found, must be a raw stream
248 br.read_skip(6).unwrap();
249 let mut size = 0;
250 for _ in 0..4 {
251 let b = br.read_byte().unwrap();
252 if (b & 0x80) != 0 {
253 println!("Invalid ID3 size");
254 break;
255 }
256 size = (size << 7) | u64::from(b);
257 }
258 start = size + 10;
259 is_raw = true;
260 }
261 // check for ID3v1
262 br.seek(SeekFrom::End(-128)).unwrap();
263 let off = br.tell();
264 br.peek_buf(&mut buf[..3]).unwrap();
265 if &buf[0..3] == b"TAG" {
266 end = Some(off);
267 }
268 // check for APETAG
269 let mut buf = [0; 8];
270 if let Some(off) = end {
271 br.seek(SeekFrom::Start(off - 32)).unwrap();
272 } else {
273 br.seek(SeekFrom::End(-32)).unwrap();
274 }
275 let off = br.tell();
276 br.read_buf(&mut buf).unwrap();
277 if &buf == b"APETAGEX" {
278 let ver = br.read_u32le().unwrap();
279 let size = u64::from(br.read_u32le().unwrap());
280 let _items = br.read_u32le().unwrap();
281 let flags = br.read_u32le().unwrap();
282 if ver == 1000 || (flags & 0x80000000) == 0 {
283 end = Some(off - size + 32);
284 } else {
285 end = Some(off - size);
286 }
287 }
288
289 (is_raw, start, end)
290}