1 use nihav_core::demuxers::*;
2 use nihav_registry::register::*;
3 use nihav_core::compr::deflate::*;
6 ($a:expr, $b:expr, $c:expr, $d:expr) => ({
7 (($a as u32) << 24) | (($b as u32) << 16) | (($c as u32) << 8) | ($d as u32)
10 (($arr[0] as u32) << 24) | (($arr[1] as u32) << 16) | (($arr[2] as u32) << 8) | ($arr[3] as u32)
15 fn skip64(&mut self, size: u64) -> ByteIOResult<()>;
18 impl<'a> Skip64 for ByteReader<'a> {
19 fn skip64(&mut self, size: u64) -> ByteIOResult<()> {
20 if (size as usize as u64) != size {
21 self.seek(SeekFrom::Current(size as i64))?;
23 self.read_skip(size as usize)?;
29 fn read_chunk_header(br: &mut ByteReader) -> DemuxerResult<(u32, u64)> {
30 let size = br.read_u32be()?;
31 let ctype = br.read_u32be()?;
33 Ok((ctype, br.left() as u64))
35 let size64 = br.read_u64be()?;
36 validate!(size64 >= 16);
37 Ok((ctype, size64 - 16))
40 Ok((ctype, (size as u64) - 8))
44 fn read_palette(br: &mut ByteReader, size: u64, pal: &mut [u8; 1024]) -> DemuxerResult<u64> {
45 let _seed = br.read_u32be()?;
46 let _flags = br.read_u16be()?;
47 let palsize = (br.read_u16be()? as usize) + 1;
48 validate!(palsize <= 256);
49 validate!((palsize as u64) * 8 + 8 == size);
51 let a = br.read_u16be()?;
52 let r = br.read_u16be()?;
53 let g = br.read_u16be()?;
54 let b = br.read_u16be()?;
55 pal[i * 4] = (r >> 8) as u8;
56 pal[i * 4 + 1] = (g >> 8) as u8;
57 pal[i * 4 + 2] = (b >> 8) as u8;
58 pal[i * 4 + 3] = (a >> 8) as u8;
63 struct RootChunkHandler {
65 parse: fn(dmx: &mut MOVDemuxer, strmgr: &mut StreamManager, size: u64) -> DemuxerResult<u64>,
68 struct TrackChunkHandler {
70 parse: fn(track: &mut Track, br: &mut ByteReader, size: u64) -> DemuxerResult<u64>,
73 const IGNORED_CHUNKS: &[u32] = &[
74 mktag!(b"free"), mktag!(b"skip"), mktag!(b"udta"), mktag!(b"wide")
77 const ROOT_CHUNK_HANDLERS: &[RootChunkHandler] = &[
78 RootChunkHandler { ctype: mktag!(b"ftyp"), parse: read_ftyp },
79 RootChunkHandler { ctype: mktag!(b"mdat"), parse: read_mdat },
80 RootChunkHandler { ctype: mktag!(b"moov"), parse: read_moov },
83 fn print_cname(ctype: u32, size: u64, off: u64, depth: u8) {
84 for _ in 0..depth { print!(" "); }
85 let tag = [(ctype >> 24) as u8, (ctype >> 16) as u8, (ctype >> 8) as u8, ctype as u8];
86 let mut printable = true;
87 for &ch in tag.iter() {
88 if ch < 0x20 || ch > 0x7F {
94 print!(" '{}{}{}{}'", tag[0] as char, tag[1] as char, tag[2] as char, tag[3] as char);
96 print!(" {:08X}", ctype);
98 println!(" size {} @ {:X}", size, off);
101 macro_rules! read_chunk_list {
102 (root; $name: expr, $fname: ident, $handlers: ident) => {
103 fn $fname(&mut self, strmgr: &mut StreamManager, size: u64) -> DemuxerResult<()> {
105 validate!(self.depth < 32);
106 let list_end = self.src.tell() + size;
107 while self.src.tell() < list_end {
108 let ret = read_chunk_header(&mut self.src);
109 if ret.is_err() { break; }
110 let (ctype, size) = ret.unwrap();
111 if self.print_chunks {
112 print_cname(ctype, size, self.src.tell(), self.depth as u8);
114 if self.src.tell() + size > list_end {
117 if IGNORED_CHUNKS.contains(&ctype) {
118 self.src.skip64(size)?;
121 let handler = $handlers.iter().find(|x| x.ctype == ctype);
123 if let Some(ref handler) = handler {
124 read_size = (handler.parse)(self, strmgr, size)?;
126 println!("skipping unknown chunk {:08X} size {}", ctype, size);
129 validate!(read_size <= size);
130 self.src.skip64(size - read_size)?;
133 validate!(self.src.tell() == list_end);
137 (track; $name: expr, $fname: ident, $handlers: ident) => {
138 fn $fname(&mut self, br: &mut ByteReader, size: u64) -> DemuxerResult<()> {
140 validate!(self.depth < 32);
141 let list_end = br.tell() + size;
142 while br.tell() < list_end {
143 let ret = read_chunk_header(br);
144 if ret.is_err() { break; }
145 let (ctype, size) = ret.unwrap();
146 if self.print_chunks {
147 print_cname(ctype, size, br.tell(), self.depth + 1);
149 if br.tell() + size > list_end {
152 if IGNORED_CHUNKS.contains(&ctype) {
156 let handler = $handlers.iter().find(|x| x.ctype == ctype);
158 if let Some(ref handler) = handler {
159 read_size = (handler.parse)(self, br, size)?;
163 validate!(read_size <= size);
164 br.skip64(size - read_size)?;
167 validate!(br.tell() == list_end);
173 fn skip_chunk(_track: &mut Track, br: &mut ByteReader, size: u64) -> DemuxerResult<u64> {
178 fn read_ftyp(dmx: &mut MOVDemuxer, _strmgr: &mut StreamManager, size: u64) -> DemuxerResult<u64> {
179 dmx.src.skip64(size)?;
183 fn read_mdat(dmx: &mut MOVDemuxer, _strmgr: &mut StreamManager, size: u64) -> DemuxerResult<u64> {
184 dmx.mdat_pos = dmx.src.tell();
185 dmx.mdat_size = size;
186 dmx.src.skip64(size)?;
190 fn read_moov(dmx: &mut MOVDemuxer, strmgr: &mut StreamManager, size: u64) -> DemuxerResult<u64> {
191 dmx.read_moov(strmgr, size)?;
195 const MOOV_CHUNK_HANDLERS: &[RootChunkHandler] = &[
196 RootChunkHandler { ctype: mktag!(b"mvhd"), parse: read_mvhd },
197 RootChunkHandler { ctype: mktag!(b"cmov"), parse: read_cmov },
198 RootChunkHandler { ctype: mktag!(b"ctab"), parse: read_ctab },
199 RootChunkHandler { ctype: mktag!(b"trak"), parse: read_trak },
200 RootChunkHandler { ctype: mktag!(b"meta"), parse: read_meta },
203 fn read_mvhd(dmx: &mut MOVDemuxer, _strmgr: &mut StreamManager, size: u64) -> DemuxerResult<u64> {
204 const KNOWN_MVHD_SIZE: u64 = 100;
205 let br = &mut dmx.src;
206 validate!(size >= KNOWN_MVHD_SIZE);
207 let version = br.read_byte()?;
208 validate!(version == 0);
209 let _flags = br.read_u24be()?;
210 let _ctime = br.read_u32be()?;
211 let _mtime = br.read_u32be()?;
212 let tscale = br.read_u32be()?;
213 let duration = br.read_u32be()?;
214 let _pref_rate = br.read_u32be()?;
215 let _pref_volume = br.read_u16be()?;
217 br.read_skip(36)?; // matrix
218 let _preview_time = br.read_u32be()?;
219 let _preview_duration = br.read_u32be()?;
220 let _poster_time = br.read_u32be()?;
221 let _sel_time = br.read_u32be()?;
222 let _sel_duration = br.read_u32be()?;
223 let _cur_time = br.read_u32be()?;
224 let _next_track_id = br.read_u32be()?;
225 dmx.duration = duration;
231 fn read_cmov(dmx: &mut MOVDemuxer, strmgr: &mut StreamManager, size: u64) -> DemuxerResult<u64> {
232 let br = &mut dmx.src;
233 validate!(size > 24);
234 let dcom_size = br.read_u32be()?;
235 let dcom_tag = br.read_tag()?;
236 let compr_type = br.read_tag()?;
237 validate!(&dcom_tag == b"dcom" && dcom_size == 12);
238 if &compr_type != b"zlib" {
239 return Err(DemuxerError::NotImplemented);
241 let cmvd_size = u64::from(br.read_u32be()?);
242 let cmvd_tag = br.read_tag()?;
243 validate!(&cmvd_tag == b"cmvd" && cmvd_size > 14 && cmvd_size == size - 12);
244 let comp_size = (cmvd_size - 12) as usize;
245 let uncomp_size = br.read_u32be()? as usize;
246 validate!(uncomp_size > 8);
247 let mut sbuf = vec![0; comp_size];
248 let mut dbuf = vec![0; uncomp_size];
249 br.read_buf(sbuf.as_mut_slice())?;
250 let ret = Inflate::uncompress(sbuf.as_slice(), dbuf.as_mut_slice());
252 return Err(DemuxerError::InvalidData);
254 let len = ret.unwrap();
255 validate!(len == uncomp_size);
256 let mut mr = MemoryReader::new_read(dbuf.as_slice());
257 let mut br = ByteReader::new(&mut mr);
258 let (ctype, csize) = read_chunk_header(&mut br)?;
259 validate!(ctype == mktag!(b"moov"));
260 let mut ddmx = MOVDemuxer::new(&mut br);
261 ddmx.print_chunks = dmx.print_chunks;
262 ddmx.read_moov(strmgr, csize)?;
263 std::mem::swap(&mut dmx.tracks, &mut ddmx.tracks);
264 dmx.duration = ddmx.duration;
265 dmx.tb_den = ddmx.tb_den;
266 std::mem::swap(&mut dmx.pal, &mut ddmx.pal);
271 fn read_ctab(dmx: &mut MOVDemuxer, _strmgr: &mut StreamManager, size: u64) -> DemuxerResult<u64> {
272 let mut pal = [0; 1024];
273 let size = read_palette(&mut dmx.src, size, &mut pal)?;
274 dmx.pal = Some(Arc::new(pal));
278 fn read_meta(dmx: &mut MOVDemuxer, _strmgr: &mut StreamManager, size: u64) -> DemuxerResult<u64> {
279 dmx.src.skip64(size)?;
283 fn read_trak(dmx: &mut MOVDemuxer, strmgr: &mut StreamManager, size: u64) -> DemuxerResult<u64> {
284 let mut track = Track::new(dmx.cur_track as u32, dmx.tb_den);
285 track.print_chunks = dmx.print_chunks;
286 track.read_trak(&mut dmx.src, size)?;
287 validate!(track.tkhd_found && track.stsd_found);
288 validate!(strmgr.get_stream_by_id(track.track_id).is_none());
291 std::mem::swap(&mut track.stream, &mut str);
292 if let Some(stream) = str {
293 let str_id = strmgr.add_stream(stream).unwrap();
294 track.track_str_id = str_id;
296 dmx.tracks.push(track);
300 const TRAK_CHUNK_HANDLERS: &[TrackChunkHandler] = &[
301 TrackChunkHandler { ctype: mktag!(b"clip"), parse: skip_chunk },
302 TrackChunkHandler { ctype: mktag!(b"matt"), parse: skip_chunk },
303 TrackChunkHandler { ctype: mktag!(b"edts"), parse: skip_chunk },
304 TrackChunkHandler { ctype: mktag!(b"tref"), parse: skip_chunk },
305 TrackChunkHandler { ctype: mktag!(b"load"), parse: skip_chunk },
306 TrackChunkHandler { ctype: mktag!(b"imap"), parse: skip_chunk },
307 TrackChunkHandler { ctype: mktag!(b"tkhd"), parse: read_tkhd },
308 TrackChunkHandler { ctype: mktag!(b"mdia"), parse: read_mdia },
311 fn read_tkhd(track: &mut Track, br: &mut ByteReader, size: u64) -> DemuxerResult<u64> {
312 const KNOWN_TKHD_SIZE: u64 = 84;
313 validate!(size >= KNOWN_TKHD_SIZE);
314 let version = br.read_byte()?;
315 validate!(version == 0);
316 let _flags = br.read_u24be()?;
317 let _ctime = br.read_u32be()?;
318 let _mtime = br.read_u32be()?;
319 let track_id = br.read_u32be()?;
321 let duration = br.read_u32be()?;
323 let _layer = br.read_u16be()?;
324 let _alt_group = br.read_u16be()?;
325 let _volume = br.read_u16be()?;
327 br.read_skip(36)?; // matrix
328 let width = br.read_u32be()? as usize;
329 let height = br.read_u32be()? as usize;
330 track.width = width >> 16;
331 track.height = height >> 16;
332 track.track_id = track_id;
333 track.duration = duration;
335 track.tkhd_found = true;
339 fn read_mdia(track: &mut Track, br: &mut ByteReader, size: u64) -> DemuxerResult<u64> {
340 track.stream_type = StreamType::None;
341 track.read_mdia(br, size)?;
345 const MDIA_CHUNK_HANDLERS: &[TrackChunkHandler] = &[
346 TrackChunkHandler { ctype: mktag!(b"mdhd"), parse: skip_chunk },
347 TrackChunkHandler { ctype: mktag!(b"hdlr"), parse: read_hdlr },
348 TrackChunkHandler { ctype: mktag!(b"minf"), parse: read_minf },
351 fn read_hdlr(track: &mut Track, br: &mut ByteReader, size: u64) -> DemuxerResult<u64> {
352 const KNOWN_HDLR_SIZE: u64 = 24;
353 validate!(size >= KNOWN_HDLR_SIZE);
354 let version = br.read_byte()?;
355 validate!(version == 0);
356 let flags = br.read_u24be()?;
357 validate!(flags == 0);
358 let comp_type = br.read_u32be()?;
359 let comp_subtype = br.read_u32be()?;
360 let _comp_manufacturer = br.read_u32be()?;
361 let _comp_flags = br.read_u32be()?;
362 let _comp_flags_mask = br.read_u32be()?;
364 if comp_type == mktag!(b"mhlr") || comp_type == 0 {
365 if comp_subtype == mktag!(b"vide") {
366 track.stream_type = StreamType::Video;
367 } else if comp_subtype == mktag!(b"soun") {
368 track.stream_type = StreamType::Audio;
370 track.stream_type = StreamType::Data;
372 } else if comp_type == mktag!(b"dhlr") {
373 track.stream_type = StreamType::Data;
375 println!("Unknown stream type");
376 track.stream_type = StreamType::Data;
382 fn read_minf(track: &mut Track, br: &mut ByteReader, size: u64) -> DemuxerResult<u64> {
383 track.read_minf(br, size)?;
387 const MINF_CHUNK_HANDLERS: &[TrackChunkHandler] = &[
388 TrackChunkHandler { ctype: mktag!(b"hdlr"), parse: skip_chunk },
389 TrackChunkHandler { ctype: mktag!(b"dinf"), parse: skip_chunk },
390 TrackChunkHandler { ctype: mktag!(b"vmhd"), parse: read_vmhd },
391 TrackChunkHandler { ctype: mktag!(b"smhd"), parse: read_smhd },
392 TrackChunkHandler { ctype: mktag!(b"gmhd"), parse: read_gmhd },
393 TrackChunkHandler { ctype: mktag!(b"gmin"), parse: read_gmin },
394 TrackChunkHandler { ctype: mktag!(b"stbl"), parse: read_stbl },
397 fn read_vmhd(track: &mut Track, br: &mut ByteReader, size: u64) -> DemuxerResult<u64> {
398 const KNOWN_VMHD_SIZE: u64 = 12;
399 validate!(track.stream_type == StreamType::Video);
400 validate!(size >= KNOWN_VMHD_SIZE);
401 let version = br.read_byte()?;
402 validate!(version == 0);
403 let _flags = br.read_u24be()?;
404 br.read_skip(2)?; // graphics mode
405 br.read_skip(6)?; // opcolor
409 fn read_smhd(track: &mut Track, br: &mut ByteReader, size: u64) -> DemuxerResult<u64> {
410 const KNOWN_SMHD_SIZE: u64 = 8;
411 validate!(track.stream_type == StreamType::Audio);
412 validate!(size >= KNOWN_SMHD_SIZE);
413 let version = br.read_byte()?;
414 validate!(version == 0);
415 let _flags = br.read_u24be()?;
416 br.read_skip(2)?; // balance
421 fn read_gmhd(track: &mut Track, _br: &mut ByteReader, _size: u64) -> DemuxerResult<u64> {
422 validate!(track.stream_type == StreamType::Data);
426 fn read_gmin(track: &mut Track, br: &mut ByteReader, size: u64) -> DemuxerResult<u64> {
427 validate!(track.stream_type == StreamType::Data);
428 const KNOWN_GMIN_SIZE: u64 = 16;
429 validate!(size >= KNOWN_GMIN_SIZE);
430 let version = br.read_byte()?;
431 validate!(version == 0);
432 let _flags = br.read_u24be()?;
433 br.read_skip(2)?; // graphics mode
434 br.read_skip(6)?; // opcolor
435 br.read_skip(2)?; // balance
440 fn read_stbl(track: &mut Track, br: &mut ByteReader, size: u64) -> DemuxerResult<u64> {
441 track.read_stbl(br, size)?;
445 const STBL_CHUNK_HANDLERS: &[TrackChunkHandler] = &[
446 TrackChunkHandler { ctype: mktag!(b"stsd"), parse: read_stsd },
447 TrackChunkHandler { ctype: mktag!(b"stts"), parse: read_stts },
448 TrackChunkHandler { ctype: mktag!(b"stss"), parse: read_stss },
449 TrackChunkHandler { ctype: mktag!(b"stsc"), parse: read_stsc },
450 TrackChunkHandler { ctype: mktag!(b"stsz"), parse: read_stsz },
451 TrackChunkHandler { ctype: mktag!(b"stco"), parse: read_stco },
452 TrackChunkHandler { ctype: mktag!(b"stsh"), parse: skip_chunk },
453 TrackChunkHandler { ctype: mktag!(b"ctts"), parse: read_ctts },
456 fn parse_audio_edata(br: &mut ByteReader, start_pos: u64, size: u64) -> DemuxerResult<Option<Vec<u8>>> {
457 let read_part = br.tell() - start_pos;
458 if read_part + 8 < size {
459 let mut buf = [0; 8];
460 br.peek_buf(&mut buf)?;
461 if &buf[4..8] != b"wave" {
462 let mut buf = vec![0; (size - read_part) as usize];
463 br.read_buf(&mut buf)?;
464 return Ok(Some(buf));
467 let csize = br.read_u32be()? as u64;
468 let ctag = br.read_u32be()?;
469 validate!(read_part + csize <= size);
470 validate!(ctag == mktag!(b"wave"));
474 let mut buf = [0; 8];
475 br.peek_buf(&mut buf)?;
476 if &buf[4..8] == b"frma" {
479 let mut buf = vec![0; (csize - 20) as usize];
480 br.read_buf(&mut buf)?;
485 } else if csize > 8 {
486 let mut buf = vec![0; (csize as usize) - 8];
487 br.read_buf(&mut buf)?;
497 fn read_stsd(track: &mut Track, br: &mut ByteReader, size: u64) -> DemuxerResult<u64> {
498 const KNOWN_STSD_SIZE: u64 = 24;
499 validate!(size >= KNOWN_STSD_SIZE);
500 let start_pos = br.tell();
501 let version = br.read_byte()?;
502 validate!(version == 0);
503 let _flags = br.read_u24be()?;
504 let entries = br.read_u32be()?;
505 validate!(entries > 0);
506 let esize = u64::from(br.read_u32be()?);
507 validate!(esize + 8 <= size);
508 let mut fcc = [0u8; 4];
509 br.read_buf(&mut fcc)?;
511 let _data_ref = br.read_u16be()?;
516 match track.stream_type {
517 StreamType::Video => {
518 let _ver = br.read_u16be()?;
519 let _revision = br.read_u16le()?;
520 let _vendor = br.read_u32be()?;
521 let _temp_quality = br.read_u32be()?;
522 let _spat_quality = br.read_u32be()?;
523 let width = br.read_u16be()? as usize;
524 let height = br.read_u16be()? as usize;
525 let _hor_res = br.read_u32be()?;
526 let _vert_res = br.read_u32be()?;
527 let data_size = br.read_u32be()?;
528 validate!(data_size == 0);
529 let _frame_count = br.read_u16be()? as usize;
530 let _cname_len = br.read_byte()? as usize;
531 br.read_skip(31)?; // actual compressor name
532 let depth = br.read_u16be()?;
533 let ctable_id = br.read_u16be()?;
534 let grayscale = depth > 0x20 || depth == 1;
535 let depth = if grayscale { depth & 0x1F } else { depth };
536 validate!(depth <= 8 || (ctable_id == 0xFFFF));
538 let max_pal_size = start_pos + size - br.tell();
539 let mut pal = [0; 1024];
540 read_palette(br, max_pal_size, &mut pal)?;
541 track.pal = Some(Arc::new(pal));
542 } else if (depth <= 8) && !grayscale {
545 let mut pal = [0; 1024];
546 (&mut pal[..4 * 4]).copy_from_slice(&MOV_DEFAULT_PAL_2BIT);
547 track.pal = Some(Arc::new(pal));
550 let mut pal = [0; 1024];
551 (&mut pal[..16 * 4]).copy_from_slice(&MOV_DEFAULT_PAL_4BIT);
552 track.pal = Some(Arc::new(pal));
555 track.pal = Some(Arc::new(MOV_DEFAULT_PAL_8BIT));
559 } else if grayscale && ctable_id != 0xFFFF {
560 let mut pal = [0; 1024];
561 let cdepth = depth & 0x1F;
562 let size = 1 << cdepth;
564 let mut clr = ((size - 1 - i) as u8) << (8 - cdepth);
565 let mut off = 8 - cdepth;
566 while off >= cdepth {
567 clr |= clr >> (8 - off);
571 clr |= clr >> (8 - off);
574 pal[i * 4 + 1] = clr;
575 pal[i * 4 + 2] = clr;
577 track.pal = Some(Arc::new(pal));
579 // todo other atoms, put as extradata
580 let cname = if let Some(name) = find_codec_from_mov_video_fourcc(&fcc) {
582 } else if let Some(name) = find_codec_from_avi_fourcc(&fcc) {
587 let format = if depth > 8 { RGB24_FORMAT } else { PAL8_FORMAT };
588 let mut vhdr = NAVideoInfo::new(width, height, false, format);
589 vhdr.bits = depth as u8;
590 let edata = if br.tell() - start_pos + 4 < size {
591 //todo skip various common atoms
592 let edata_size = br.read_u32be()? as usize;
593 validate!(edata_size >= 4);
594 let mut buf = vec![0; edata_size - 4];
595 br.read_buf(buf.as_mut_slice())?;
600 codec_info = NACodecInfo::new(cname, NACodecTypeInfo::Video(vhdr), edata);
602 StreamType::Audio => {
603 let sver = br.read_u16be()?;
604 let _revision = br.read_u16le()?;
605 let _vendor = br.read_u32be()?;
606 let nchannels = br.read_u16be()?;
607 validate!(nchannels <= 64);
608 let sample_size = br.read_u16be()?;
609 validate!(sample_size <= 128);
610 let _compr_id = br.read_u16be()?;
611 let packet_size = br.read_u16be()? as usize;
612 validate!(packet_size == 0);
613 let sample_rate = br.read_u32be()?;
614 validate!(sample_rate > (1 << 16));
615 let cname = if let Some(name) = find_codec_from_mov_audio_fourcc(&fcc) {
617 } else if let (true, Some(name)) = ((fcc[0] == b'm' && fcc[1] == b's'), find_codec_from_wav_twocc(u16::from(fcc[2]) * 256 + u16::from(fcc[3]))) {
622 let mut soniton = NASoniton::new(sample_size as u8, SONITON_FLAG_SIGNED | SONITON_FLAG_BE);
623 if &fcc == b"raw " && sample_size == 8 {
624 soniton.signed = false;
628 let samples_per_packet = br.read_u32be()?;
629 let _bytes_per_packet = br.read_u32be()?;
630 let bytes_per_frame = br.read_u32be()?;
631 let _bytes_per_sample = br.read_u32be()?;
632 track.bsize = bytes_per_frame as usize;
633 track.frame_samples = samples_per_packet as usize;
634 track.tb_num = samples_per_packet;
636 track.bsize = (sample_size / 8) as usize;
638 track.tb_den = sample_rate >> 16;
639 track.raw_audio = match &fcc {
640 b"NONE" | b"raw " | b"twos" | b"sowt" |
641 b"in24" | b"in32" | b"fl32" | b"fl64" |
642 b"ima4" | b"ms\x00\x02" | b"ms\x00\x21" |
644 b"MAC3" | b"MAC6" => true,
647 let ahdr = NAAudioInfo::new(sample_rate >> 16, nchannels as u8, soniton, block_align);
648 let edata = parse_audio_edata(br, start_pos, size)?;
649 codec_info = NACodecInfo::new(cname, NACodecTypeInfo::Audio(ahdr), edata);
650 track.channels = nchannels as usize;
651 track.bits = sample_size as usize;
653 StreamType::None => {
654 return Err(DemuxerError::InvalidData);
657 //todo put it all into extradata
659 codec_info = NACodecInfo::new("unknown", NACodecTypeInfo::None, edata);
662 let read_size = br.tell() - start_pos;
663 validate!(read_size <= size);
664 track.stream = Some(NAStream::new(track.stream_type, track.track_no, codec_info, track.tb_num, track.tb_den, u64::from(track.duration)));
665 track.stsd_found = true;
669 fn read_stts(track: &mut Track, br: &mut ByteReader, size: u64) -> DemuxerResult<u64> {
670 validate!(size >= 8);
671 let start_pos = br.tell();
672 let version = br.read_byte()?;
673 validate!(version == 0);
674 let _flags = br.read_u24be()?;
675 let entries = br.read_u32be()? as usize;
676 validate!(entries as u64 <= (size - 8) / 8);
678 } else if entries == 1 {
679 let _count = br.read_u32be()?;
680 let tb_num = br.read_u32be()?;
681 validate!(tb_num != 0);
682 track.tb_div = tb_num;
683 if let Some(ref mut stream) = track.stream {
684 let tb_den = stream.tb_den;
685 let (tb_num, tb_den) = reduce_timebase(tb_num * stream.tb_num, tb_den);
686 stream.duration /= u64::from(stream.tb_den / tb_den);
687 stream.tb_num = tb_num;
688 stream.tb_den = tb_den;
689 track.tb_num = tb_num;
690 track.tb_den = tb_den;
693 track.time_to_sample.truncate(0);
694 track.time_to_sample.reserve(entries);
695 for _ in 0..entries {
696 let count = br.read_u32be()?;
697 let mult = br.read_u32be()?;
698 track.time_to_sample.push((count, mult));
701 let read_size = br.tell() - start_pos;
702 validate!(read_size <= size);
706 fn read_stss(track: &mut Track, br: &mut ByteReader, size: u64) -> DemuxerResult<u64> {
707 let version = br.read_byte()?;
708 validate!(version == 0);
709 let _flags = br.read_u24be()?;
710 let entries = br.read_u32be()? as usize;
711 validate!(entries < ((std::u32::MAX >> 2) - 8) as usize);
712 validate!((entries * 4 + 8) as u64 == size);
713 track.keyframes = Vec::with_capacity(entries);
714 let mut last_sample_no = 0;
715 for _ in 0..entries {
716 let sample_no = br.read_u32be()?;
717 validate!(sample_no > last_sample_no);
718 track.keyframes.push(sample_no);
719 last_sample_no = sample_no;
724 fn read_stsc(track: &mut Track, br: &mut ByteReader, size: u64) -> DemuxerResult<u64> {
725 let version = br.read_byte()?;
726 validate!(version == 0);
727 let _flags = br.read_u24be()?;
728 let entries = br.read_u32be()? as usize;
729 validate!(entries < ((std::u32::MAX / 12) - 8) as usize);
730 validate!((entries * 12 + 8) as u64 == size);
731 track.sample_map = Vec::with_capacity(entries);
732 let mut last_sample_no = 0;
733 for _i in 0..entries {
734 let sample_no = br.read_u32be()?;
735 validate!(sample_no > last_sample_no);
736 let nsamples = br.read_u32be()?;
737 let _sample_desc = br.read_u32be()?;
738 track.sample_map.push((sample_no, nsamples));
739 last_sample_no = sample_no;
744 fn read_stsz(track: &mut Track, br: &mut ByteReader, size: u64) -> DemuxerResult<u64> {
745 let version = br.read_byte()?;
746 validate!(version == 0);
747 let _flags = br.read_u24be()?;
748 let sample_size = br.read_u32be()?;
749 if sample_size != 0 {
750 track.sample_size = sample_size;
751 if track.sample_size != 1 || track.bsize == 0 {
752 track.bsize = sample_size as usize;
756 let entries = br.read_u32be()? as usize;
757 validate!((entries * 4 + 12) as u64 == size);
758 track.chunk_sizes = Vec::with_capacity(entries);
759 for _ in 0..entries {
760 let sample_size = br.read_u32be()?;
761 track.chunk_sizes.push(sample_size);
767 fn read_stco(track: &mut Track, br: &mut ByteReader, size: u64) -> DemuxerResult<u64> {
768 let version = br.read_byte()?;
769 validate!(version == 0);
770 let _flags = br.read_u24be()?;
771 let entries = br.read_u32be()? as usize;
772 validate!((entries * 4 + 8) as u64 == size);
773 track.chunk_offsets = Vec::with_capacity(entries);
774 for _i in 0..entries {
775 let sample_offset = br.read_u32be()?;
776 track.chunk_offsets.push(u64::from(sample_offset));
781 fn read_ctts(track: &mut Track, br: &mut ByteReader, size: u64) -> DemuxerResult<u64> {
782 validate!(size >= 8);
783 let version = br.read_byte()?;
784 let _flags = br.read_u24be()?;
786 return Err(DemuxerError::NotImplemented);
788 let entries = br.read_u32be()? as usize;
789 track.ctts_version = version;
790 track.ctts_map.resize(entries);
793 validate!(size == (entries as u64) * 8 + 8);
794 for _ in 0..entries {
795 let samp_count = br.read_u32be()?;
796 let samp_offset = br.read_u32be()?;
797 track.ctts_map.add(samp_count, samp_offset / track.tb_div);
802 track.ctts_map.reset();
807 struct MOVDemuxer<'a> {
808 src: &'a mut ByteReader<'a>,
816 pal: Option<Arc<[u8; 1024]>>,
834 stream_type: StreamType,
842 chunk_sizes: Vec<u32>,
843 chunk_offsets: Vec<u64>,
844 time_to_sample: Vec<(u32, u32)>,
845 sample_map: Vec<(u32, u32)>,
847 frame_samples: usize,
848 ctts_map: RLESearcher<u32>,
850 stream: Option<NAStream>,
855 pal: Option<Arc<[u8; 1024]>>,
856 timesearch: TimeSearcher,
862 struct TimeSearcher {
871 fn new() -> Self { Self::default() }
872 fn reset(&mut self) {
873 *self = Self::default();
875 fn map_time(&mut self, sample: u32, tts: &Vec<(u32, u32)>) -> u64 {
878 } else if sample >= self.sbase {
879 let mut sample = sample - self.sbase;
881 let (cur_len, cur_mul) = tts[0];
882 self.cur_len = cur_len;
883 self.cur_mul = cur_mul;
886 while self.idx < tts.len() && sample > self.cur_len {
887 sample -= self.cur_len;
888 self.sbase += self.cur_len;
889 self.base += u64::from(self.cur_len) * u64::from(self.cur_mul);
890 self.cur_len = tts[self.idx].0;
891 self.cur_mul = tts[self.idx].1;
894 self.base + u64::from(sample) * u64::from(self.cur_mul)
897 self.map_time(sample, tts)
903 struct RLESearcher<T> {
904 array: Vec<(u32, T)>,
910 impl<T:Default+Copy> RLESearcher<T> {
911 fn new() -> Self { Self::default() }
912 fn resize(&mut self, size: usize) {
913 self.array.truncate(0);
914 self.array.reserve(size);
916 fn add(&mut self, len: u32, val: T) {
917 self.array.push((len, val));
919 fn reset(&mut self) {
921 if !self.array.is_empty() {
923 self.next = u64::from(self.array[0].0);
925 self.idx = self.array.len();
929 fn map(&mut self, sample: u64) -> Option<T> {
930 if sample < self.start {
933 if self.idx < self.array.len() {
934 if sample < self.next {
935 Some(self.array[self.idx].1)
937 while (self.idx < self.array.len()) && (sample >= self.next) {
938 self.start = self.next;
940 if self.idx < self.array.len() {
941 self.next += u64::from(self.array[self.idx].0);
944 if self.idx < self.array.len() {
945 Some(self.array[self.idx].1)
957 fn new(track_no: u32, tb_den: u32) -> Self {
970 stream_type: StreamType::None,
977 keyframes: Vec::new(),
978 chunk_sizes: Vec::new(),
979 chunk_offsets: Vec::new(),
980 time_to_sample: Vec::new(),
981 sample_map: Vec::new(),
984 ctts_map: RLESearcher::new(),
993 timesearch: TimeSearcher::new(),
998 read_chunk_list!(track; "trak", read_trak, TRAK_CHUNK_HANDLERS);
999 read_chunk_list!(track; "mdia", read_mdia, MDIA_CHUNK_HANDLERS);
1000 read_chunk_list!(track; "minf", read_minf, MINF_CHUNK_HANDLERS);
1001 read_chunk_list!(track; "stbl", read_stbl, STBL_CHUNK_HANDLERS);
1002 fn fill_seek_index(&self, seek_index: &mut SeekIndex) {
1003 if !self.keyframes.is_empty() {
1004 seek_index.mode = SeekIndexMode::Present;
1006 let mut tsearch = TimeSearcher::new();
1007 for kf_time in self.keyframes.iter() {
1008 let pts = tsearch.map_time(*kf_time - 1, &self.time_to_sample);
1009 let time = NATimeInfo::ts_to_time(pts, 1000, self.tb_num, self.tb_den);
1010 seek_index.add_entry(self.track_no as u32, SeekEntry { time, pts: u64::from(*kf_time - 1), pos: 0 });
1013 fn calculate_chunk_size(&self, nsamp: usize) -> usize {
1018 b"NONE" | b"raw " | b"twos" | b"sowt" => {
1019 (nsamp * self.bits * self.channels + 7) >> 3
1022 let nblocks = (nsamp + 63) >> 6;
1023 nblocks * 34 * self.channels
1026 (nsamp + 5) / 6 * 2 * self.channels
1029 (nsamp + 5) / 6 * self.channels
1031 b"in24" => nsamp * 3 * self.channels,
1032 b"in32" | b"fl32" => nsamp * 4 * self.channels,
1033 b"fl64" => nsamp * 8 * self.channels,
1034 b"ulaw" | b"alaw" => nsamp,
1035 b"ms\x00\x02" => { //MS ADPCM
1036 ((nsamp - 1) / 2 + 7) * self.channels
1038 b"ms\x00\x21" => { //IMA ADPCM
1039 (nsamp / 2 + 4) * self.channels
1045 fn get_next_chunk(&mut self) -> Option<(NATimeInfo, u64, usize)> {
1046 let pts_val = self.timesearch.map_time(self.cur_sample as u32, &self.time_to_sample);
1047 let dts = if let Some(dts_corr) = self.ctts_map.map(self.cur_sample as u64) {
1048 let dts = match self.ctts_version {
1049 0 => pts_val.wrapping_add(u64::from(dts_corr)),
1050 1 => pts_val.wrapping_add(i64::from(dts_corr as i32) as u64),
1051 _ => unimplemented!(),
1053 if (dts as i64) < 0 {
1061 let mut pts = NATimeInfo::new(Some(pts_val), dts, None, self.tb_num, self.tb_den);
1062 if self.chunk_offsets.len() == self.chunk_sizes.len() { // simple one-to-one mapping
1063 if self.cur_sample >= self.chunk_sizes.len() {
1066 let offset = self.chunk_offsets[self.cur_sample];
1067 let size = self.chunk_sizes[self.cur_sample] as usize;
1068 self.cur_sample += 1;
1069 Some((pts, offset, size))
1071 if self.samples_left == 0 {
1072 if self.cur_chunk >= self.chunk_offsets.len() {
1075 for (idx, samples) in self.sample_map.iter() {
1076 if *idx as usize <= self.cur_chunk + 1 {
1077 self.samples_left = *samples as usize;
1082 self.last_offset = self.chunk_offsets[self.cur_chunk];
1083 self.cur_chunk += 1;
1085 let offset = self.last_offset;
1086 let size = self.get_size(self.cur_sample);
1087 self.last_offset += size as u64;
1088 if self.stream_type == StreamType::Video {
1089 self.samples_left -= 1;
1090 } else if self.frame_samples != 0 && self.bsize != 0 {
1091 let nblocks = size / self.bsize;
1093 pts.pts = Some(self.raw_apos);
1094 pts.duration = Some(nblocks as u64);
1095 self.raw_apos += nblocks as u64;
1098 let consumed = (nblocks * self.frame_samples).min(self.samples_left);
1099 self.samples_left -= consumed;
1101 self.samples_left = 0;
1103 } else if !self.raw_audio {
1104 self.samples_left -= 1;
1106 const BLOCK_SAMPLES: usize = 1024 * 6; // should be multiple of 64 and 6 to fit both IMA ADPCM and MACE 6:1 blocks
1107 let max_size = self.calculate_chunk_size(BLOCK_SAMPLES);
1108 let cur_size = self.calculate_chunk_size(self.samples_left);
1109 let add_off = (size - cur_size) as u64;
1110 let dsize = cur_size.min(max_size);
1111 if self.samples_left >= BLOCK_SAMPLES {
1112 self.cur_sample += BLOCK_SAMPLES;
1113 self.samples_left -= BLOCK_SAMPLES;
1114 self.last_offset -= size as u64;
1116 self.cur_sample += self.samples_left;
1117 self.samples_left = 0;
1119 return Some((pts, offset + add_off, dsize));
1121 self.cur_sample += 1;
1122 Some((pts, offset, size))
1125 fn get_size(&self, sample_no: usize) -> usize {
1126 if !self.chunk_sizes.is_empty() {
1127 self.chunk_sizes[sample_no] as usize
1128 } else if !self.sample_map.is_empty() {
1130 for (idx, samples) in self.sample_map.iter() {
1131 if *idx as usize <= self.cur_chunk {
1137 self.calculate_chunk_size(nsamp as usize)
1142 fn seek(&mut self, pts: u64, tpoint: NATimePoint) -> DemuxerResult<()> {
1143 self.cur_sample = pts as usize;
1144 self.samples_left = 0;
1145 if self.stream_type == StreamType::Audio {
1146 if let NATimePoint::Milliseconds(ms) = tpoint {
1147 let exp_pts = NATimeInfo::time_to_ts(ms, 1000, self.tb_num, self.tb_den);
1149 if self.frame_samples != 0 {
1150 self.raw_apos = exp_pts / (self.frame_samples as u64);
1152 self.cur_sample = 0;
1154 let mut cmap = self.sample_map.iter();
1155 let mut cur_samps = 0;
1156 let (mut next_idx, mut next_samples) = cmap.next().unwrap();
1158 if self.cur_chunk + 1 == next_idx as usize {
1159 self.samples_left = cur_samps;
1160 cur_samps = next_samples as usize;
1161 if let Some((new_idx, new_samples)) = cmap.next() {
1162 next_idx = *new_idx;
1163 next_samples = *new_samples;
1166 self.raw_apos = apos;
1167 apos += (cur_samps / self.frame_samples) as u64;
1169 if cur_samps == self.frame_samples || apos > exp_pts + 1 {
1170 if self.cur_chunk >= self.chunk_offsets.len() {
1171 return Err(DemuxerError::SeekError);
1173 self.last_offset = self.chunk_offsets[self.cur_chunk];
1177 self.cur_chunk += 1;
1179 self.samples_left = cur_samps;
1180 self.cur_chunk += 1;
1182 self.raw_apos = exp_pts;
1183 self.cur_sample = exp_pts as usize;
1186 let mut cmap = self.sample_map.iter();
1187 let mut cur_samps = 0;
1188 let (mut next_idx, mut next_samples) = cmap.next().unwrap();
1190 if self.cur_chunk + 1 == next_idx as usize {
1191 self.samples_left = cur_samps;
1192 cur_samps = next_samples as usize;
1193 if let Some((new_idx, new_samples)) = cmap.next() {
1194 next_idx = *new_idx;
1195 next_samples = *new_samples;
1199 if csamp > self.cur_sample {
1200 if self.cur_chunk >= self.chunk_offsets.len() {
1201 return Err(DemuxerError::SeekError);
1203 self.last_offset = self.chunk_offsets[self.cur_chunk];
1206 self.cur_chunk += 1;
1208 self.samples_left = csamp - self.cur_sample;
1209 self.cur_chunk += 1;
1212 self.cur_chunk = self.cur_sample;
1215 self.cur_chunk = self.cur_sample;
1217 } else if self.chunk_offsets.len() != self.chunk_sizes.len() && !self.sample_map.is_empty() {
1220 let mut cmap = self.sample_map.iter();
1221 let mut cur_samps = 0;
1222 let (mut next_idx, mut next_samples) = cmap.next().unwrap();
1224 if self.cur_chunk + 1 == next_idx as usize {
1225 self.samples_left = cur_samps;
1226 cur_samps = next_samples as usize;
1227 if let Some((new_idx, new_samples)) = cmap.next() {
1228 next_idx = *new_idx;
1229 next_samples = *new_samples;
1233 if csamp >= self.cur_sample {
1234 if self.cur_chunk >= self.chunk_offsets.len() {
1235 return Err(DemuxerError::SeekError);
1237 self.last_offset = self.chunk_offsets[self.cur_chunk];
1240 self.cur_chunk += 1;
1243 for sample_no in csamp..self.cur_sample {
1244 self.last_offset += self.get_size(sample_no) as u64;
1246 self.samples_left = csamp + cur_samps - self.cur_sample;
1247 self.cur_chunk += 1;
1253 impl<'a> DemuxCore<'a> for MOVDemuxer<'a> {
1254 fn open(&mut self, strmgr: &mut StreamManager, seek_index: &mut SeekIndex) -> DemuxerResult<()> {
1255 self.read_root(strmgr)?;
1256 validate!(self.mdat_pos > 0);
1257 validate!(!self.tracks.is_empty());
1258 for track in self.tracks.iter() {
1259 track.fill_seek_index(seek_index);
1261 self.src.seek(SeekFrom::Start(self.mdat_pos))?;
1266 fn get_frame(&mut self, strmgr: &mut StreamManager) -> DemuxerResult<NAPacket> {
1267 if self.tracks.is_empty() {
1268 return Err(DemuxerError::EOF);
1270 for _ in 0..self.tracks.len() {
1271 if self.cur_track >= self.tracks.len() {
1274 let track = &mut self.tracks[self.cur_track];
1275 self.cur_track += 1;
1276 let first = track.cur_sample == 0;
1277 if let Some((pts, offset, size)) = track.get_next_chunk() {
1278 let str = strmgr.get_stream(track.track_str_id);
1279 if str.is_none() { return Err(DemuxerError::InvalidData); }
1280 let stream = str.unwrap();
1281 self.src.seek(SeekFrom::Start(offset))?;
1282 let mut pkt = self.src.read_packet(stream, pts, false, size)?;
1283 if let Some(ref pal) = track.pal {
1284 let side_data = NASideData::Palette(first, pal.clone());
1285 pkt.add_side_data(side_data);
1290 Err(DemuxerError::EOF)
1293 fn seek(&mut self, time: NATimePoint, seek_index: &SeekIndex) -> DemuxerResult<()> {
1294 let ret = seek_index.find_pos(time);
1296 return Err(DemuxerError::SeekError);
1298 let seek_info = ret.unwrap();
1299 for track in self.tracks.iter_mut() {
1300 track.seek(seek_info.pts, time)?;
1304 fn get_duration(&self) -> u64 {
1305 if self.tb_den != 0 {
1306 u64::from(self.duration) * 1000 / u64::from(self.tb_den)
1313 const PRINT_CHUNKS: &str = "print_chunks";
1315 const DEMUXER_OPTIONS: &[NAOptionDefinition] = &[
1316 NAOptionDefinition {
1318 description: "Print parsed file structure",
1319 opt_type: NAOptionDefinitionType::Bool },
1322 impl<'a> NAOptionHandler for MOVDemuxer<'a> {
1323 fn get_supported_options(&self) -> &[NAOptionDefinition] { DEMUXER_OPTIONS }
1324 fn set_options(&mut self, options: &[NAOption]) {
1325 for option in options.iter() {
1326 for opt_def in DEMUXER_OPTIONS.iter() {
1327 if opt_def.check(option).is_ok() {
1328 match (option.name, &option.value) {
1329 (PRINT_CHUNKS, NAValue::Bool(val)) => {
1330 self.print_chunks = *val;
1338 fn query_option_value(&self, name: &str) -> Option<NAValue> {
1340 PRINT_CHUNKS => Some(NAValue::Bool(self.print_chunks)),
1346 impl<'a> MOVDemuxer<'a> {
1347 fn new(io: &'a mut ByteReader<'a>) -> Self {
1353 tracks: Vec::with_capacity(2),
1359 print_chunks: false,
1362 fn read_root(&mut self, strmgr: &mut StreamManager) -> DemuxerResult<()> {
1364 while self.src.left() != 0 {
1365 let ret = read_chunk_header(&mut self.src);
1366 if ret.is_err() { break; }
1367 let (ctype, size) = ret.unwrap();
1368 if IGNORED_CHUNKS.contains(&ctype) {
1369 self.src.skip64(size)?;
1372 let handler = ROOT_CHUNK_HANDLERS.iter().find(|x| x.ctype == ctype);
1374 if let Some(ref handler) = handler {
1375 read_size = (handler.parse)(self, strmgr, size)?;
1377 println!("skipping unknown chunk {:08X} size {}", ctype, size);
1380 validate!(read_size <= size);
1381 self.src.skip64(size - read_size)?;
1383 //todo check if all needed chunks are found
1386 read_chunk_list!(root; "moov", read_moov, MOOV_CHUNK_HANDLERS);
1389 pub struct MOVDemuxerCreator { }
1391 impl DemuxerCreator for MOVDemuxerCreator {
1392 fn new_demuxer<'a>(&self, br: &'a mut ByteReader<'a>) -> Box<dyn DemuxCore<'a> + 'a> {
1393 Box::new(MOVDemuxer::new(br))
1395 fn get_name(&self) -> &'static str { "mov" }
1398 const MOV_DEFAULT_PAL_2BIT: [u8; 4 * 4] = [
1399 0x93, 0x65, 0x5E, 0x00,
1400 0xFF, 0xFF, 0xFF, 0x00,
1401 0xDF, 0xD0, 0xAB, 0x00,
1402 0x00, 0x00, 0x00, 0x00
1404 const MOV_DEFAULT_PAL_4BIT: [u8; 16 * 4] = [
1405 0xFF, 0xFB, 0xFF, 0x00,
1406 0xEF, 0xD9, 0xBB, 0x00,
1407 0xE8, 0xC9, 0xB1, 0x00,
1408 0x93, 0x65, 0x5E, 0x00,
1409 0xFC, 0xDE, 0xE8, 0x00,
1410 0x9D, 0x88, 0x91, 0x00,
1411 0xFF, 0xFF, 0xFF, 0x00,
1412 0xFF, 0xFF, 0xFF, 0x00,
1413 0xFF, 0xFF, 0xFF, 0x00,
1414 0x47, 0x48, 0x37, 0x00,
1415 0x7A, 0x5E, 0x55, 0x00,
1416 0xDF, 0xD0, 0xAB, 0x00,
1417 0xFF, 0xFB, 0xF9, 0x00,
1418 0xE8, 0xCA, 0xC5, 0x00,
1419 0x8A, 0x7C, 0x77, 0x00,
1420 0x00, 0x00, 0x00, 0x00
1422 const MOV_DEFAULT_PAL_8BIT: [u8; 256 * 4] = [
1423 0xFF, 0xFF, 0xFF, 0x00,
1424 0xFF, 0xFF, 0xCC, 0x00,
1425 0xFF, 0xFF, 0x99, 0x00,
1426 0xFF, 0xFF, 0x66, 0x00,
1427 0xFF, 0xFF, 0x33, 0x00,
1428 0xFF, 0xFF, 0x00, 0x00,
1429 0xFF, 0xCC, 0xFF, 0x00,
1430 0xFF, 0xCC, 0xCC, 0x00,
1431 0xFF, 0xCC, 0x99, 0x00,
1432 0xFF, 0xCC, 0x66, 0x00,
1433 0xFF, 0xCC, 0x33, 0x00,
1434 0xFF, 0xCC, 0x00, 0x00,
1435 0xFF, 0x99, 0xFF, 0x00,
1436 0xFF, 0x99, 0xCC, 0x00,
1437 0xFF, 0x99, 0x99, 0x00,
1438 0xFF, 0x99, 0x66, 0x00,
1439 0xFF, 0x99, 0x33, 0x00,
1440 0xFF, 0x99, 0x00, 0x00,
1441 0xFF, 0x66, 0xFF, 0x00,
1442 0xFF, 0x66, 0xCC, 0x00,
1443 0xFF, 0x66, 0x99, 0x00,
1444 0xFF, 0x66, 0x66, 0x00,
1445 0xFF, 0x66, 0x33, 0x00,
1446 0xFF, 0x66, 0x00, 0x00,
1447 0xFF, 0x33, 0xFF, 0x00,
1448 0xFF, 0x33, 0xCC, 0x00,
1449 0xFF, 0x33, 0x99, 0x00,
1450 0xFF, 0x33, 0x66, 0x00,
1451 0xFF, 0x33, 0x33, 0x00,
1452 0xFF, 0x33, 0x00, 0x00,
1453 0xFF, 0x00, 0xFF, 0x00,
1454 0xFF, 0x00, 0xCC, 0x00,
1455 0xFF, 0x00, 0x99, 0x00,
1456 0xFF, 0x00, 0x66, 0x00,
1457 0xFF, 0x00, 0x33, 0x00,
1458 0xFF, 0x00, 0x00, 0x00,
1459 0xCC, 0xFF, 0xFF, 0x00,
1460 0xCC, 0xFF, 0xCC, 0x00,
1461 0xCC, 0xFF, 0x99, 0x00,
1462 0xCC, 0xFF, 0x66, 0x00,
1463 0xCC, 0xFF, 0x33, 0x00,
1464 0xCC, 0xFF, 0x00, 0x00,
1465 0xCC, 0xCC, 0xFF, 0x00,
1466 0xCC, 0xCC, 0xCC, 0x00,
1467 0xCC, 0xCC, 0x99, 0x00,
1468 0xCC, 0xCC, 0x66, 0x00,
1469 0xCC, 0xCC, 0x33, 0x00,
1470 0xCC, 0xCC, 0x00, 0x00,
1471 0xCC, 0x99, 0xFF, 0x00,
1472 0xCC, 0x99, 0xCC, 0x00,
1473 0xCC, 0x99, 0x99, 0x00,
1474 0xCC, 0x99, 0x66, 0x00,
1475 0xCC, 0x99, 0x33, 0x00,
1476 0xCC, 0x99, 0x00, 0x00,
1477 0xCC, 0x66, 0xFF, 0x00,
1478 0xCC, 0x66, 0xCC, 0x00,
1479 0xCC, 0x66, 0x99, 0x00,
1480 0xCC, 0x66, 0x66, 0x00,
1481 0xCC, 0x66, 0x33, 0x00,
1482 0xCC, 0x66, 0x00, 0x00,
1483 0xCC, 0x33, 0xFF, 0x00,
1484 0xCC, 0x33, 0xCC, 0x00,
1485 0xCC, 0x33, 0x99, 0x00,
1486 0xCC, 0x33, 0x66, 0x00,
1487 0xCC, 0x33, 0x33, 0x00,
1488 0xCC, 0x33, 0x00, 0x00,
1489 0xCC, 0x00, 0xFF, 0x00,
1490 0xCC, 0x00, 0xCC, 0x00,
1491 0xCC, 0x00, 0x99, 0x00,
1492 0xCC, 0x00, 0x66, 0x00,
1493 0xCC, 0x00, 0x33, 0x00,
1494 0xCC, 0x00, 0x00, 0x00,
1495 0x99, 0xFF, 0xFF, 0x00,
1496 0x99, 0xFF, 0xCC, 0x00,
1497 0x99, 0xFF, 0x99, 0x00,
1498 0x99, 0xFF, 0x66, 0x00,
1499 0x99, 0xFF, 0x33, 0x00,
1500 0x99, 0xFF, 0x00, 0x00,
1501 0x99, 0xCC, 0xFF, 0x00,
1502 0x99, 0xCC, 0xCC, 0x00,
1503 0x99, 0xCC, 0x99, 0x00,
1504 0x99, 0xCC, 0x66, 0x00,
1505 0x99, 0xCC, 0x33, 0x00,
1506 0x99, 0xCC, 0x00, 0x00,
1507 0x99, 0x99, 0xFF, 0x00,
1508 0x99, 0x99, 0xCC, 0x00,
1509 0x99, 0x99, 0x99, 0x00,
1510 0x99, 0x99, 0x66, 0x00,
1511 0x99, 0x99, 0x33, 0x00,
1512 0x99, 0x99, 0x00, 0x00,
1513 0x99, 0x66, 0xFF, 0x00,
1514 0x99, 0x66, 0xCC, 0x00,
1515 0x99, 0x66, 0x99, 0x00,
1516 0x99, 0x66, 0x66, 0x00,
1517 0x99, 0x66, 0x33, 0x00,
1518 0x99, 0x66, 0x00, 0x00,
1519 0x99, 0x33, 0xFF, 0x00,
1520 0x99, 0x33, 0xCC, 0x00,
1521 0x99, 0x33, 0x99, 0x00,
1522 0x99, 0x33, 0x66, 0x00,
1523 0x99, 0x33, 0x33, 0x00,
1524 0x99, 0x33, 0x00, 0x00,
1525 0x99, 0x00, 0xFF, 0x00,
1526 0x99, 0x00, 0xCC, 0x00,
1527 0x99, 0x00, 0x99, 0x00,
1528 0x99, 0x00, 0x66, 0x00,
1529 0x99, 0x00, 0x33, 0x00,
1530 0x99, 0x00, 0x00, 0x00,
1531 0x66, 0xFF, 0xFF, 0x00,
1532 0x66, 0xFF, 0xCC, 0x00,
1533 0x66, 0xFF, 0x99, 0x00,
1534 0x66, 0xFF, 0x66, 0x00,
1535 0x66, 0xFF, 0x33, 0x00,
1536 0x66, 0xFF, 0x00, 0x00,
1537 0x66, 0xCC, 0xFF, 0x00,
1538 0x66, 0xCC, 0xCC, 0x00,
1539 0x66, 0xCC, 0x99, 0x00,
1540 0x66, 0xCC, 0x66, 0x00,
1541 0x66, 0xCC, 0x33, 0x00,
1542 0x66, 0xCC, 0x00, 0x00,
1543 0x66, 0x99, 0xFF, 0x00,
1544 0x66, 0x99, 0xCC, 0x00,
1545 0x66, 0x99, 0x99, 0x00,
1546 0x66, 0x99, 0x66, 0x00,
1547 0x66, 0x99, 0x33, 0x00,
1548 0x66, 0x99, 0x00, 0x00,
1549 0x66, 0x66, 0xFF, 0x00,
1550 0x66, 0x66, 0xCC, 0x00,
1551 0x66, 0x66, 0x99, 0x00,
1552 0x66, 0x66, 0x66, 0x00,
1553 0x66, 0x66, 0x33, 0x00,
1554 0x66, 0x66, 0x00, 0x00,
1555 0x66, 0x33, 0xFF, 0x00,
1556 0x66, 0x33, 0xCC, 0x00,
1557 0x66, 0x33, 0x99, 0x00,
1558 0x66, 0x33, 0x66, 0x00,
1559 0x66, 0x33, 0x33, 0x00,
1560 0x66, 0x33, 0x00, 0x00,
1561 0x66, 0x00, 0xFF, 0x00,
1562 0x66, 0x00, 0xCC, 0x00,
1563 0x66, 0x00, 0x99, 0x00,
1564 0x66, 0x00, 0x66, 0x00,
1565 0x66, 0x00, 0x33, 0x00,
1566 0x66, 0x00, 0x00, 0x00,
1567 0x33, 0xFF, 0xFF, 0x00,
1568 0x33, 0xFF, 0xCC, 0x00,
1569 0x33, 0xFF, 0x99, 0x00,
1570 0x33, 0xFF, 0x66, 0x00,
1571 0x33, 0xFF, 0x33, 0x00,
1572 0x33, 0xFF, 0x00, 0x00,
1573 0x33, 0xCC, 0xFF, 0x00,
1574 0x33, 0xCC, 0xCC, 0x00,
1575 0x33, 0xCC, 0x99, 0x00,
1576 0x33, 0xCC, 0x66, 0x00,
1577 0x33, 0xCC, 0x33, 0x00,
1578 0x33, 0xCC, 0x00, 0x00,
1579 0x33, 0x99, 0xFF, 0x00,
1580 0x33, 0x99, 0xCC, 0x00,
1581 0x33, 0x99, 0x99, 0x00,
1582 0x33, 0x99, 0x66, 0x00,
1583 0x33, 0x99, 0x33, 0x00,
1584 0x33, 0x99, 0x00, 0x00,
1585 0x33, 0x66, 0xFF, 0x00,
1586 0x33, 0x66, 0xCC, 0x00,
1587 0x33, 0x66, 0x99, 0x00,
1588 0x33, 0x66, 0x66, 0x00,
1589 0x33, 0x66, 0x33, 0x00,
1590 0x33, 0x66, 0x00, 0x00,
1591 0x33, 0x33, 0xFF, 0x00,
1592 0x33, 0x33, 0xCC, 0x00,
1593 0x33, 0x33, 0x99, 0x00,
1594 0x33, 0x33, 0x66, 0x00,
1595 0x33, 0x33, 0x33, 0x00,
1596 0x33, 0x33, 0x00, 0x00,
1597 0x33, 0x00, 0xFF, 0x00,
1598 0x33, 0x00, 0xCC, 0x00,
1599 0x33, 0x00, 0x99, 0x00,
1600 0x33, 0x00, 0x66, 0x00,
1601 0x33, 0x00, 0x33, 0x00,
1602 0x33, 0x00, 0x00, 0x00,
1603 0x00, 0xFF, 0xFF, 0x00,
1604 0x00, 0xFF, 0xCC, 0x00,
1605 0x00, 0xFF, 0x99, 0x00,
1606 0x00, 0xFF, 0x66, 0x00,
1607 0x00, 0xFF, 0x33, 0x00,
1608 0x00, 0xFF, 0x00, 0x00,
1609 0x00, 0xCC, 0xFF, 0x00,
1610 0x00, 0xCC, 0xCC, 0x00,
1611 0x00, 0xCC, 0x99, 0x00,
1612 0x00, 0xCC, 0x66, 0x00,
1613 0x00, 0xCC, 0x33, 0x00,
1614 0x00, 0xCC, 0x00, 0x00,
1615 0x00, 0x99, 0xFF, 0x00,
1616 0x00, 0x99, 0xCC, 0x00,
1617 0x00, 0x99, 0x99, 0x00,
1618 0x00, 0x99, 0x66, 0x00,
1619 0x00, 0x99, 0x33, 0x00,
1620 0x00, 0x99, 0x00, 0x00,
1621 0x00, 0x66, 0xFF, 0x00,
1622 0x00, 0x66, 0xCC, 0x00,
1623 0x00, 0x66, 0x99, 0x00,
1624 0x00, 0x66, 0x66, 0x00,
1625 0x00, 0x66, 0x33, 0x00,
1626 0x00, 0x66, 0x00, 0x00,
1627 0x00, 0x33, 0xFF, 0x00,
1628 0x00, 0x33, 0xCC, 0x00,
1629 0x00, 0x33, 0x99, 0x00,
1630 0x00, 0x33, 0x66, 0x00,
1631 0x00, 0x33, 0x33, 0x00,
1632 0x00, 0x33, 0x00, 0x00,
1633 0x00, 0x00, 0xFF, 0x00,
1634 0x00, 0x00, 0xCC, 0x00,
1635 0x00, 0x00, 0x99, 0x00,
1636 0x00, 0x00, 0x66, 0x00,
1637 0x00, 0x00, 0x33, 0x00,
1638 0xEE, 0x00, 0x00, 0x00,
1639 0xDD, 0x00, 0x00, 0x00,
1640 0xBB, 0x00, 0x00, 0x00,
1641 0xAA, 0x00, 0x00, 0x00,
1642 0x88, 0x00, 0x00, 0x00,
1643 0x77, 0x00, 0x00, 0x00,
1644 0x55, 0x00, 0x00, 0x00,
1645 0x44, 0x00, 0x00, 0x00,
1646 0x22, 0x00, 0x00, 0x00,
1647 0x11, 0x00, 0x00, 0x00,
1648 0x00, 0xEE, 0x00, 0x00,
1649 0x00, 0xDD, 0x00, 0x00,
1650 0x00, 0xBB, 0x00, 0x00,
1651 0x00, 0xAA, 0x00, 0x00,
1652 0x00, 0x88, 0x00, 0x00,
1653 0x00, 0x77, 0x00, 0x00,
1654 0x00, 0x55, 0x00, 0x00,
1655 0x00, 0x44, 0x00, 0x00,
1656 0x00, 0x22, 0x00, 0x00,
1657 0x00, 0x11, 0x00, 0x00,
1658 0x00, 0x00, 0xEE, 0x00,
1659 0x00, 0x00, 0xDD, 0x00,
1660 0x00, 0x00, 0xBB, 0x00,
1661 0x00, 0x00, 0xAA, 0x00,
1662 0x00, 0x00, 0x88, 0x00,
1663 0x00, 0x00, 0x77, 0x00,
1664 0x00, 0x00, 0x55, 0x00,
1665 0x00, 0x00, 0x44, 0x00,
1666 0x00, 0x00, 0x22, 0x00,
1667 0x00, 0x00, 0x11, 0x00,
1668 0xEE, 0xEE, 0xEE, 0x00,
1669 0xDD, 0xDD, 0xDD, 0x00,
1670 0xBB, 0xBB, 0xBB, 0x00,
1671 0xAA, 0xAA, 0xAA, 0x00,
1672 0x88, 0x88, 0x88, 0x00,
1673 0x77, 0x77, 0x77, 0x00,
1674 0x55, 0x55, 0x55, 0x00,
1675 0x44, 0x44, 0x44, 0x00,
1676 0x22, 0x22, 0x22, 0x00,
1677 0x11, 0x11, 0x11, 0x00,
1678 0x00, 0x00, 0x00, 0x00
1687 fn test_mov_demux() {
1688 let mut file = File::open("assets/Indeo/cubes.mov").unwrap();
1689 let mut fr = FileReader::new_read(&mut file);
1690 let mut br = ByteReader::new(&mut fr);
1691 let mut dmx = MOVDemuxer::new(&mut br);
1692 let mut sm = StreamManager::new();
1693 let mut si = SeekIndex::new();
1694 dmx.open(&mut sm, &mut si).unwrap();
1697 let pktres = dmx.get_frame(&mut sm);
1698 if let Err(e) = pktres {
1699 if e == DemuxerError::EOF { break; }
1702 let pkt = pktres.unwrap();
1703 println!("Got {}", pkt);