X-Git-Url: https://git.nihav.org/?a=blobdiff_plain;f=nihav-commonfmt%2Fsrc%2Fdemuxers%2Fmov.rs;h=24431f9a7416e0a9fae179fd7256f005c942167b;hb=12cf91eafb8d48fc3d27153e119504163edbb6d8;hp=35fac0d6a112787cd0cea80d2bc72ed6fc91a0bf;hpb=fbf1f900e6e6da46026938f90f1eaba2034aa79a;p=nihav.git diff --git a/nihav-commonfmt/src/demuxers/mov.rs b/nihav-commonfmt/src/demuxers/mov.rs index 35fac0d..24431f9 100644 --- a/nihav-commonfmt/src/demuxers/mov.rs +++ b/nihav-commonfmt/src/demuxers/mov.rs @@ -223,9 +223,7 @@ fn read_cmov(dmx: &mut MOVDemuxer, strmgr: &mut StreamManager, size: u64) -> Dem let mut sbuf = vec![0; comp_size]; let mut dbuf = vec![0; uncomp_size]; br.read_buf(sbuf.as_mut_slice())?; - validate!(sbuf[0] == 0x78); - validate!(sbuf[1] == 0x9C); - let ret = Inflate::uncompress(&sbuf[2..], dbuf.as_mut_slice()); + let ret = Inflate::uncompress(sbuf.as_slice(), dbuf.as_mut_slice()); if ret.is_err() { return Err(DemuxerError::InvalidData); } @@ -427,6 +425,39 @@ const STBL_CHUNK_HANDLERS: &[TrackChunkHandler] = &[ TrackChunkHandler { ctype: mktag!(b"stsh"), parse: skip_chunk }, ]; +fn parse_audio_edata(br: &mut ByteReader, start_pos: u64, size: u64) -> DemuxerResult>> { + let read_part = br.tell() - start_pos; + if read_part + 8 < size { + let csize = br.read_u32be()? as u64; + let ctag = br.read_u32be()?; + validate!(read_part + csize <= size); + validate!(ctag == mktag!(b"wave")); + if csize == 8 { + return Ok(None); + } + let mut buf = [0; 8]; + br.peek_buf(&mut buf)?; + if &buf[4..8] == b"frma" { + br.read_skip(12)?; + if csize > 20 { + let mut buf = vec![0; (csize - 20) as usize]; + br.read_buf(&mut buf)?; + Ok(Some(buf)) + } else { + Ok(None) + } + } else if csize > 8 { + let mut buf = vec![0; (csize as usize) - 8]; + br.read_buf(&mut buf)?; + Ok(Some(buf)) + } else { + Ok(None) + } + } else { + Ok(None) + } +} + fn read_stsd(track: &mut Track, br: &mut ByteReader, size: u64) -> DemuxerResult { const KNOWN_STSD_SIZE: u64 = 24; validate!(size >= KNOWN_STSD_SIZE); @@ -532,7 +563,7 @@ fn read_stsd(track: &mut Track, br: &mut ByteReader, size: u64) -> DemuxerResult codec_info = NACodecInfo::new(cname, NACodecTypeInfo::Video(vhdr), edata); }, StreamType::Audio => { - let _ver = br.read_u16be()?; + let sver = br.read_u16be()?; let _revision = br.read_u16le()?; let _vendor = br.read_u32be()?; let nchannels = br.read_u16be()?; @@ -554,8 +585,18 @@ fn read_stsd(track: &mut Track, br: &mut ByteReader, size: u64) -> DemuxerResult //todo adjust format for various PCM kinds let soniton = NASoniton::new(sample_size as u8, SONITON_FLAG_SIGNED | SONITON_FLAG_BE); let block_align = 1; + if sver == 1 { + let samples_per_packet = br.read_u32be()?; + let _bytes_per_packet = br.read_u32be()?; + let bytes_per_frame = br.read_u32be()?; + let _bytes_per_sample = br.read_u32be()?; + track.bsize = bytes_per_frame as usize; + track.frame_samples = samples_per_packet as usize; + } else { + track.bsize = sample_size as usize; + } let ahdr = NAAudioInfo::new(sample_rate >> 16, nchannels as u8, soniton, block_align); - let edata = None; + let edata = parse_audio_edata(br, start_pos, size)?; codec_info = NACodecInfo::new(cname, NACodecTypeInfo::Audio(ahdr), edata); track.channels = nchannels as usize; track.bits = sample_size as usize; @@ -621,6 +662,9 @@ fn read_stsz(track: &mut Track, br: &mut ByteReader, size: u64) -> DemuxerResult let sample_size = br.read_u32be()?; if sample_size != 0 { track.sample_size = sample_size; + if track.sample_size != 1 || track.bsize == 0 { + track.bsize = sample_size as usize; + } Ok(8) } else { let entries = br.read_u32be()? as usize; @@ -673,12 +717,14 @@ struct Track { height: usize, channels: usize, bits: usize, + bsize: usize, fcc: [u8; 4], keyframes: Vec, chunk_sizes: Vec, chunk_offsets: Vec, sample_map: Vec<(u32, u32)>, sample_size: u32, + frame_samples: usize, stream: Option, cur_chunk: usize, cur_sample: usize, @@ -701,12 +747,14 @@ impl Track { height: 0, channels: 0, bits: 0, + bsize: 0, fcc: [0; 4], keyframes: Vec::new(), chunk_sizes: Vec::new(), chunk_offsets: Vec::new(), sample_map: Vec::new(), sample_size: 0, + frame_samples: 0, stream: None, depth: 0, cur_chunk: 0, @@ -736,7 +784,7 @@ impl Track { } fn calculate_chunk_size(&self, nsamp: usize) -> usize { if nsamp == 0 { - self.sample_size as usize + self.bsize } else { match &self.fcc { b"NONE" | b"raw " | b"twos" | b"sowt" => { @@ -762,7 +810,7 @@ impl Track { b"ms\x00\x21" => { //IMA ADPCM (nsamp / 2 + 4) * self.channels }, - _ => self.sample_size as usize, + _ => self.bsize, } } } @@ -797,6 +845,8 @@ impl Track { self.last_offset += size as u64; if self.stream_type == StreamType::Video { self.samples_left -= 1; + } else if self.frame_samples != 0 { + self.samples_left -= self.frame_samples.min(self.samples_left); } else { self.samples_left = 0; } @@ -818,7 +868,7 @@ impl Track { } self.calculate_chunk_size(nsamp as usize) } else { - self.sample_size as usize + self.bsize } } fn seek(&mut self, pts: u64) {