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 pts = (u64::from(ext_time) << 24) | u64::from(time);
219 let ts = stream.make_ts(Some(pts), None, None);
220 self.apkts.push(self.src.read_packet(stream, ts, true, data_size)?);
224 let hdr = self.src.read_byte()?;
225 let ftype = match hdr >> 4 {
228 3 => FrameType::P, // droppable
229 4 => FrameType::Other, // generated key frame
230 5 => FrameType::Other, // video info/command frame
231 _ => return Err(DemuxerError::InvalidData),
233 let codec_tag = hdr & 0xF;
234 if let Some(id) = self.vtag {
235 validate!(id == codec_tag);
237 let cname = get_vcodec_name(codec_tag)?;
238 let is_avc = codec_tag == AVC_ID;
240 let pkt_type = self.src.read_byte()?;
241 validate!(pkt_type == 0);
242 self.src.read_u24be()?;
244 let mut edata = None;
245 let (width, height) = match codec_tag {
247 let mut buf = [0; 9];
248 self.src.peek_buf(&mut buf)?;
249 let mut br = BitReader::new(&buf, BitReaderMode::BE);
250 br.skip(30).unwrap_or(());
251 let sfmt = br.read(3).unwrap_or(7);
254 let w = br.read(8).unwrap_or(0) as usize;
255 let h = br.read(8).unwrap_or(0) as usize;
259 let w = br.read(16).unwrap_or(0) as usize;
260 let h = br.read(16).unwrap_or(0) as usize;
272 let mut buf = [0; 4];
273 self.src.peek_buf(&mut buf)?;
274 let w = (read_u16be(&buf[0..])? & 0xFFF) as usize;
275 let h = (read_u16be(&buf[2..])? & 0xFFF) as usize;
279 let mut buf = [0; 7];
280 self.src.peek_buf(&mut buf)?;
281 let off = if (buf[1] & 1) != 0 || (buf[2] & 6) == 0 { 5 } else { 3 };
282 validate!(buf[off] != 0 && buf[off + 1] != 0);
283 let w = usize::from(buf[off + 1]) * 16 - usize::from(buf[0] >> 4);
284 let h = usize::from(buf[off]) * 16 - usize::from(buf[0] & 0xF);
286 edata = Some(vec![buf[0]]);
291 let mut buf = [0; 10];
292 self.src.peek_buf(&mut buf)?;
293 let off = if (buf[4] & 1) != 0 || (buf[5] & 6) == 0 { 8 } else { 6 };
294 validate!(buf[off] != 0 && buf[off + 1] != 0);
295 let w = usize::from(buf[off + 1]) * 16 - usize::from(buf[0] >> 4);
296 let h = usize::from(buf[off]) * 16 - usize::from(buf[0] & 0xF);
298 edata = Some(vec![buf[0]]);
303 let pkt_hdr_size = (self.src.tell() - pkt_start) as usize;
304 validate!(data_size >= pkt_hdr_size);
305 data_size -= pkt_hdr_size;
306 let mut data = vec![0; data_size + 4];
307 data[..4].copy_from_slice(b"avcC");
308 self.src.read_buf(&mut data[4..])?;
310 (self.width, self.height)
315 let vhdr = NAVideoInfo::new(width, height, false, YUV420_FORMAT);
316 let vci = NACodecTypeInfo::Video(vhdr);
317 let vinfo = NACodecInfo::new(cname, vci, edata);
318 if let Some(id) = strmgr.add_stream(NAStream::new(StreamType::Video, 0, vinfo, 1, 1000, 0)) {
321 return Err(DemuxerError::MemoryError);
323 self.vtag = Some(codec_tag);
331 self.src.read_skip(1)?;
334 let pkt_type = self.src.read_byte()?;
336 cts = ((self.src.read_u24be()? << 8) as i32) >> 8;
337 } else if pkt_type == 2 {
338 let pkt_hdr_size = (self.src.tell() - pkt_start) as usize;
339 validate!(data_size >= pkt_hdr_size);
340 data_size -= pkt_hdr_size;
341 self.src.read_skip(data_size)?;
348 let pkt_hdr_size = (self.src.tell() - pkt_start) as usize;
349 validate!(data_size >= pkt_hdr_size);
350 data_size -= pkt_hdr_size;
353 let stream = strmgr.get_stream(self.vstream).unwrap();
354 let pts = (u64::from(ext_time) << 24) | u64::from(time);
355 let dts = ((pts as i64) + i64::from(cts)).max(0) as u64;
356 let ts = stream.make_ts(Some(pts), Some(dts), None);
357 self.vpkts.push(self.src.read_packet(stream, ts, ftype == FrameType::I, data_size)?);
361 let end = self.src.tell() + (data_size as u64);
362 let ntype = self.src.read_byte()?;
363 validate!(ntype == 2);
364 let nlen = self.src.read_u16be()? as usize;
366 let mut name = vec![0; nlen];
367 self.src.read_buf(&mut name)?;
368 if &name == b"onMetaData" {
369 let otype = self.src.read_byte()?;
370 validate!(otype == 8);
371 let _size = self.src.read_u32be()?;
372 while self.src.tell() < end {
373 let nlen = self.src.read_u16be()? as usize;
375 let emarker = self.src.peek_byte()?;
377 self.src.read_skip(1)?;
381 let mut name = vec![0; nlen];
382 self.src.read_buf(&mut name)?;
383 let vtype = self.src.read_byte()?;
386 let val = self.src.read_f64be()?;
387 match name.as_slice() {
388 b"duration" => self.duration = (val * 1000.0) as u64,
389 b"width" => self.width = val as usize,
390 b"height" => self.height = val as usize,
392 let codec_tag = val as u8;
393 if self.vtag.is_none() && codec_tag != AVC_ID && self.width != 0 && self.height != 0 {
394 let cname = get_vcodec_name(codec_tag)?;
395 let edata = if cname.starts_with("vp6") {
396 let ebyte = ((16 - (self.width & 0xF)) & 0xF) * 16 + ((16 - (self.height & 0xF)) & 0xF);
397 Some(vec![ebyte as u8])
399 let vhdr = NAVideoInfo::new(self.width, self.height, false, YUV420_FORMAT);
400 let vci = NACodecTypeInfo::Video(vhdr);
401 let vinfo = NACodecInfo::new(cname, vci, edata);
402 if let Some(id) = strmgr.add_stream(NAStream::new(StreamType::Video, 0, vinfo, 1, 1000, 0)) {
405 return Err(DemuxerError::MemoryError);
407 self.vtag = Some(codec_tag);
414 let _val = self.src.read_byte()?;
417 let len = self.src.read_u16be()? as usize;
418 let mut val = vec![0; len];
419 self.src.read_buf(&mut val)?;
422 break;//unimplemented!();
427 self.src.read_u16be()?;
436 self.src.read_f64be()?;
437 self.src.read_u16be()?;
440 let len = self.src.read_u16be()? as usize;
441 let mut val = vec![0; len];
442 self.src.read_buf(&mut val)?;
448 validate!(self.src.tell() <= end);
449 let to_skip = (end - self.src.tell()) as usize;
450 self.src.read_skip(to_skip)?;
453 self.src.read_skip(data_size)?;
460 pub struct FLVDemuxerCreator { }
462 impl DemuxerCreator for FLVDemuxerCreator {
463 fn new_demuxer<'a>(&self, br: &'a mut ByteReader<'a>) -> Box<dyn DemuxCore<'a> + 'a> {
464 Box::new(FLVDemuxer::new(br))
466 fn get_name(&self) -> &'static str { "flv" }
474 // sample: https://samples.mplayerhq.hu/A-codecs/Nelly_Moser/input.flv
476 fn test_flv_demux() {
477 let mut file = File::open("assets/Flash/input.flv").unwrap();
478 let mut fr = FileReader::new_read(&mut file);
479 let mut br = ByteReader::new(&mut fr);
480 let mut dmx = FLVDemuxer::new(&mut br);
481 let mut sm = StreamManager::new();
482 let mut si = SeekIndex::new();
483 dmx.open(&mut sm, &mut si).unwrap();
486 let pktres = dmx.get_frame(&mut sm);
487 if let Err(e) = pktres {
488 if e == DemuxerError::EOF { break; }
491 let pkt = pktres.unwrap();
492 println!("Got {}", pkt);
496 fn test_flv_demux_back() {
497 let mut file = File::open("assets/Flash/input.flv").unwrap();
498 let mut fr = FileReader::new_read(&mut file);
499 let mut br = ByteReader::new(&mut fr);
500 let mut dmx = FLVDemuxer::new(&mut br);
501 let mut sm = StreamManager::new();
502 let mut si = SeekIndex::new();
503 dmx.open(&mut sm, &mut si).unwrap();
504 dmx.src.seek(SeekFrom::End(-4)).unwrap();
505 dmx.seek(NATimePoint::Milliseconds(7500), &si).unwrap();
508 let pktres = dmx.get_frame(&mut sm);
509 if let Err(e) = pktres {
510 if e == DemuxerError::EOF { break; }
513 let pkt = pktres.unwrap();
514 println!("Got {}", pkt);