1 use nihav_core::demuxers::*;
2 use nihav_core::io::bitreader::*;
6 struct FLVDemuxer<'a> {
7 src: &'a mut ByteReader<'a>,
19 fn get_vcodec_name(tag: u8) -> DemuxerResult<&'static str> {
27 _ => Err(DemuxerError::InvalidData),
31 impl<'a> DemuxCore<'a> for FLVDemuxer<'a> {
32 fn open(&mut self, strmgr: &mut StreamManager, seek_index: &mut SeekIndex) -> DemuxerResult<()> {
34 self.src.read_buf(&mut tag)?;
35 validate!(&tag == b"FLV");
36 let ver = self.src.read_byte()?;
37 validate!(ver == 0 || ver == 1);
38 let hdr = self.src.read_byte()?;
39 validate!((hdr & 0xF2) == 0);
40 let has_audio = (hdr & 4) != 0;
41 let has_video = (hdr & 1) != 0;
42 validate!(has_video || has_audio);
43 let hdr_size = self.src.read_u32be()?;
44 validate!(hdr_size >= 9);
46 let first_prev_tag = self.src.peek_u32be()?;
47 validate!(first_prev_tag == 0);
49 while (self.vtag.is_some() != has_video) || (self.atag.is_some() != has_audio) {
50 self.parse_tag(strmgr)?;
51 if self.apkts.len() > 100 || self.vpkts.len() > 100 {
52 return Err(DemuxerError::InvalidData);
56 seek_index.mode = SeekIndexMode::Automatic;
61 fn get_frame(&mut self, strmgr: &mut StreamManager) -> DemuxerResult<NAPacket> {
63 if !self.vpkts.is_empty() && self.vpkts.len() >= self.apkts.len() {
64 return Ok(self.vpkts.remove(0));
66 if !self.apkts.is_empty() {
67 return Ok(self.apkts.remove(0));
69 self.parse_tag(strmgr)?;
72 fn seek(&mut self, time: NATimePoint, _seek_index: &SeekIndex) -> DemuxerResult<()> {
73 let dst_ms = match time {
74 NATimePoint::PTS(pts) => pts,
75 NATimePoint::Milliseconds(ms) => ms,
76 NATimePoint::None => return Err(DemuxerError::SeekError),
82 let ppos = self.src.read_u32be()?;
83 let ret = self.src.read_byte();
84 if let Err(ByteIOError::EOF) = ret {
85 self.src.seek(SeekFrom::Current(-8 - i64::from(ppos)))?;
88 let data_size = self.src.read_u24be()?;
89 let time = self.src.read_u24be()?;
90 let ext_time = self.src.read_byte()?;
91 let _stream_id = self.src.read_u24be()?;
92 let ts = (u64::from(ext_time) << 32) | u64::from(time);
94 self.src.seek(SeekFrom::Current(-15))?;
97 if let Some(p_ts) = prev {
98 if dst_ms > p_ts && dst_ms < ts {
99 self.src.seek(SeekFrom::Current(-19 - i64::from(ppos)))?;
105 self.src.seek(SeekFrom::Current(-19 - i64::from(ppos)))?;
107 self.src.seek(SeekFrom::Current(i64::from(data_size)))?;
111 fn get_duration(&self) -> u64 { self.duration }
114 impl<'a> NAOptionHandler for FLVDemuxer<'a> {
115 fn get_supported_options(&self) -> &[NAOptionDefinition] { &[] }
116 fn set_options(&mut self, _options: &[NAOption]) { }
117 fn query_option_value(&self, _name: &str) -> Option<NAValue> { None }
120 impl<'a> FLVDemuxer<'a> {
121 fn new(io: &'a mut ByteReader<'a>) -> Self {
124 vpkts: Vec::with_capacity(2),
125 apkts: Vec::with_capacity(2),
135 fn parse_tag(&mut self, strmgr: &mut StreamManager) -> DemuxerResult<()> {
136 let _prev_tag_size = self.src.read_u32be()?;
137 let ret = self.src.read_byte();
138 if let Err(ByteIOError::EOF) = ret {
139 return Err(DemuxerError::EOF);
143 let mut data_size = self.src.read_u24be()? as usize;
144 let time = self.src.read_u24be()?;
145 let ext_time = self.src.read_byte()?;
146 let stream_id = self.src.read_u24be()?;
147 validate!(stream_id == 0);
151 let pkt_start = self.src.tell();
154 let hdr = self.src.read_byte()?;
155 if let Some(tag) = self.atag {
156 validate!(tag == (hdr >> 4));
157 } else if data_size > 0 {
158 let cname = match hdr >> 4 {
167 _ => return Err(DemuxerError::InvalidData),
169 let mut srate = match (hdr >> 2) & 0x3 {
175 let bits = if (hdr & 2) == 0 { 8 } else { 16 };
176 let mut channels = if (hdr & 1) == 0 { 1 } else { 2 };
177 let mut aac_edata = false;
179 4 => { srate = 16000; channels = 1; },
180 5 => { srate = 8000; channels = 1; },
181 10 => { aac_edata = self.src.read_byte()? == 0; },
185 let edata = if aac_edata {
186 let pkt_hdr_size = (self.src.tell() - pkt_start) as usize;
187 validate!(data_size >= pkt_hdr_size);
188 let mut data = vec![0; data_size - pkt_hdr_size];
189 self.src.read_buf(&mut data)?;
194 let soniton = if bits == 16 { SND_S16P_FORMAT } else { SND_U8_FORMAT };
195 let ahdr = NAAudioInfo::new(srate, channels, soniton, 0);
196 let ci = NACodecTypeInfo::Audio(ahdr);
197 let ainfo = NACodecInfo::new(cname, ci, edata);
198 if let Some(id) = strmgr.add_stream(NAStream::new(StreamType::Audio, 1, ainfo, 1, 1000, 0)) {
201 return Err(DemuxerError::MemoryError);
203 self.atag = Some(hdr >> 4);
209 if (hdr >> 4) == 10 {
210 let pkt_type = self.src.read_byte()?;
211 validate!(pkt_type == 1);
213 let pkt_hdr_size = (self.src.tell() - pkt_start) as usize;
214 validate!(data_size >= pkt_hdr_size);
215 data_size -= pkt_hdr_size;
217 let stream = strmgr.get_stream(self.astream).unwrap();
218 let (tb_num, tb_den) = stream.get_timebase();
219 let pts = (u64::from(ext_time) << 24) | u64::from(time);
220 let ts = NATimeInfo::new(Some(pts), None, None, tb_num, tb_den);
221 self.apkts.push(self.src.read_packet(stream, ts, true, data_size)?);
225 let hdr = self.src.read_byte()?;
226 let ftype = match hdr >> 4 {
229 3 => FrameType::P, // droppable
230 4 => FrameType::Other, // generated key frame
231 5 => FrameType::Other, // video info/command frame
232 _ => return Err(DemuxerError::InvalidData),
234 let codec_tag = hdr & 0xF;
235 if let Some(id) = self.vtag {
236 validate!(id == codec_tag);
238 let cname = get_vcodec_name(codec_tag)?;
239 let is_avc = codec_tag == AVC_ID;
241 let pkt_type = self.src.read_byte()?;
242 validate!(pkt_type == 0);
243 self.src.read_u24be()?;
245 let mut edata = None;
246 let (width, height) = match codec_tag {
248 let mut buf = [0; 9];
249 self.src.peek_buf(&mut buf)?;
250 let mut br = BitReader::new(&buf, BitReaderMode::BE);
251 br.skip(30).unwrap_or(());
252 let sfmt = br.read(3).unwrap_or(7);
255 let w = br.read(8).unwrap_or(0) as usize;
256 let h = br.read(8).unwrap_or(0) as usize;
260 let w = br.read(16).unwrap_or(0) as usize;
261 let h = br.read(16).unwrap_or(0) as usize;
273 let mut buf = [0; 4];
274 self.src.peek_buf(&mut buf)?;
275 let w = (read_u16be(&buf[0..])? & 0xFFF) as usize;
276 let h = (read_u16be(&buf[2..])? & 0xFFF) as usize;
280 let mut buf = [0; 7];
281 self.src.peek_buf(&mut buf)?;
282 let off = if (buf[1] & 1) != 0 || (buf[2] & 6) == 0 { 5 } else { 3 };
283 validate!(buf[off] != 0 && buf[off + 1] != 0);
284 let w = usize::from(buf[off + 1]) * 16 - usize::from(buf[0] >> 4);
285 let h = usize::from(buf[off]) * 16 - usize::from(buf[0] & 0xF);
287 edata = Some(vec![buf[0]]);
292 let mut buf = [0; 10];
293 self.src.peek_buf(&mut buf)?;
294 let off = if (buf[4] & 1) != 0 || (buf[5] & 6) == 0 { 8 } else { 6 };
295 validate!(buf[off] != 0 && buf[off + 1] != 0);
296 let w = usize::from(buf[off + 1]) * 16 - usize::from(buf[0] >> 4);
297 let h = usize::from(buf[off]) * 16 - usize::from(buf[0] & 0xF);
299 edata = Some(vec![buf[0]]);
304 let pkt_hdr_size = (self.src.tell() - pkt_start) as usize;
305 validate!(data_size >= pkt_hdr_size);
306 data_size -= pkt_hdr_size;
307 let mut data = vec![0; data_size + 4];
308 data[..4].copy_from_slice(b"avcC");
309 self.src.read_buf(&mut data[4..])?;
311 (self.width, self.height)
316 let vhdr = NAVideoInfo::new(width, height, false, YUV420_FORMAT);
317 let vci = NACodecTypeInfo::Video(vhdr);
318 let vinfo = NACodecInfo::new(cname, vci, edata);
319 if let Some(id) = strmgr.add_stream(NAStream::new(StreamType::Video, 0, vinfo, 1, 1000, 0)) {
322 return Err(DemuxerError::MemoryError);
324 self.vtag = Some(codec_tag);
332 self.src.read_skip(1)?;
335 let pkt_type = self.src.read_byte()?;
337 cts = ((self.src.read_u24be()? << 8) as i32) >> 8;
338 } else if pkt_type == 2 {
339 let pkt_hdr_size = (self.src.tell() - pkt_start) as usize;
340 validate!(data_size >= pkt_hdr_size);
341 data_size -= pkt_hdr_size;
342 self.src.read_skip(data_size)?;
349 let pkt_hdr_size = (self.src.tell() - pkt_start) as usize;
350 validate!(data_size >= pkt_hdr_size);
351 data_size -= pkt_hdr_size;
354 let stream = strmgr.get_stream(self.vstream).unwrap();
355 let (tb_num, tb_den) = stream.get_timebase();
356 let pts = (u64::from(ext_time) << 24) | u64::from(time);
357 let dts = ((pts as i64) + i64::from(cts)).max(0) as u64;
358 let ts = NATimeInfo::new(Some(pts), Some(dts), None, tb_num, tb_den);
359 self.vpkts.push(self.src.read_packet(stream, ts, ftype == FrameType::I, data_size)?);
363 let end = self.src.tell() + (data_size as u64);
364 let ntype = self.src.read_byte()?;
365 validate!(ntype == 2);
366 let nlen = self.src.read_u16be()? as usize;
368 let mut name = vec![0; nlen];
369 self.src.read_buf(&mut name)?;
370 if &name == b"onMetaData" {
371 let otype = self.src.read_byte()?;
372 validate!(otype == 8);
373 let _size = self.src.read_u32be()?;
374 while self.src.tell() < end {
375 let nlen = self.src.read_u16be()? as usize;
377 let emarker = self.src.peek_byte()?;
379 self.src.read_skip(1)?;
383 let mut name = vec![0; nlen];
384 self.src.read_buf(&mut name)?;
385 let vtype = self.src.read_byte()?;
388 let val = self.src.read_f64be()?;
389 match name.as_slice() {
390 b"duration" => self.duration = (val * 1000.0) as u64,
391 b"width" => self.width = val as usize,
392 b"height" => self.height = val as usize,
394 let codec_tag = val as u8;
395 if self.vtag.is_none() && codec_tag != AVC_ID && self.width != 0 && self.height != 0 {
396 let cname = get_vcodec_name(codec_tag)?;
397 let edata = if cname.starts_with("vp6") {
398 let ebyte = ((16 - (self.width & 0xF)) & 0xF) * 16 + ((16 - (self.height & 0xF)) & 0xF);
399 Some(vec![ebyte as u8])
401 let vhdr = NAVideoInfo::new(self.width, self.height, false, YUV420_FORMAT);
402 let vci = NACodecTypeInfo::Video(vhdr);
403 let vinfo = NACodecInfo::new(cname, vci, edata);
404 if let Some(id) = strmgr.add_stream(NAStream::new(StreamType::Video, 0, vinfo, 1, 1000, 0)) {
407 return Err(DemuxerError::MemoryError);
409 self.vtag = Some(codec_tag);
416 let _val = self.src.read_byte()?;
419 let len = self.src.read_u16be()? as usize;
420 let mut val = vec![0; len];
421 self.src.read_buf(&mut val)?;
424 break;//unimplemented!();
429 self.src.read_u16be()?;
438 self.src.read_f64be()?;
439 self.src.read_u16be()?;
442 let len = self.src.read_u16be()? as usize;
443 let mut val = vec![0; len];
444 self.src.read_buf(&mut val)?;
450 validate!(self.src.tell() <= end);
451 let to_skip = (end - self.src.tell()) as usize;
452 self.src.read_skip(to_skip)?;
455 self.src.read_skip(data_size)?;
462 pub struct FLVDemuxerCreator { }
464 impl DemuxerCreator for FLVDemuxerCreator {
465 fn new_demuxer<'a>(&self, br: &'a mut ByteReader<'a>) -> Box<dyn DemuxCore<'a> + 'a> {
466 Box::new(FLVDemuxer::new(br))
468 fn get_name(&self) -> &'static str { "flv" }
477 fn test_flv_demux() {
478 let mut file = File::open("assets/Flash/input.flv").unwrap();
479 let mut fr = FileReader::new_read(&mut file);
480 let mut br = ByteReader::new(&mut fr);
481 let mut dmx = FLVDemuxer::new(&mut br);
482 let mut sm = StreamManager::new();
483 let mut si = SeekIndex::new();
484 dmx.open(&mut sm, &mut si).unwrap();
487 let pktres = dmx.get_frame(&mut sm);
488 if let Err(e) = pktres {
489 if e == DemuxerError::EOF { break; }
492 let pkt = pktres.unwrap();
493 println!("Got {}", pkt);
497 fn test_flv_demux_back() {
498 let mut file = File::open("assets/Flash/input.flv").unwrap();
499 let mut fr = FileReader::new_read(&mut file);
500 let mut br = ByteReader::new(&mut fr);
501 let mut dmx = FLVDemuxer::new(&mut br);
502 let mut sm = StreamManager::new();
503 let mut si = SeekIndex::new();
504 dmx.open(&mut sm, &mut si).unwrap();
505 dmx.src.seek(SeekFrom::End(-4)).unwrap();
506 dmx.seek(NATimePoint::Milliseconds(7500), &si).unwrap();
509 let pktres = dmx.get_frame(&mut sm);
510 if let Err(e) = pktres {
511 if e == DemuxerError::EOF { break; }
514 let pkt = pktres.unwrap();
515 println!("Got {}", pkt);