1 use nihav_core::frame::*;
2 use nihav_core::io::byteio::*;
3 use nihav_core::demuxers::*;
4 use nihav_core::formats::YUV420_FORMAT;
6 struct RawH264Demuxer<'a> {
7 src: &'a mut ByteReader<'a>,
12 fn read_nal(src: &mut ByteReader, dst: &mut Vec<u8>) -> DemuxerResult<()> {
15 let b = src.read_byte()?;
17 let b2 = src.read_byte()?;
19 let b3 = src.read_byte()?;
21 while src.read_byte()? != 1 { }
41 fn put_nal(dst: &mut Vec<u8>, src: &[u8]) {
43 dst.push((len >> 24) as u8);
44 dst.push((len >> 16) as u8);
45 dst.push((len >> 8) as u8);
47 dst.extend_from_slice(src);
50 impl<'a> DemuxCore<'a> for RawH264Demuxer<'a> {
51 #[allow(clippy::unreadable_literal)]
52 fn open(&mut self, strmgr: &mut StreamManager, _seek_idx: &mut SeekIndex) -> DemuxerResult<()> {
53 let src = &mut self.src;
55 while src.read_byte()? != 1 { }
57 let mut edata: Vec<u8> = Vec::with_capacity(64);
59 let mut sps_buf = Vec::new();
61 let mut pps_buf = Vec::new();
65 let mut nal_buf = Vec::with_capacity(65536);
67 read_nal(src, &mut nal_buf)?;
68 if !nal_buf.is_empty() {
69 let nal_type = nal_buf[0] & 0x1F;
72 if nal_buf.len() < 4 {
73 return Err(DemuxerError::InvalidData);
77 sps_buf.push((nal_buf.len() >> 8) as u8);
78 sps_buf.push(nal_buf.len() as u8);
79 sps_buf.extend_from_slice(&nal_buf);
83 pps_buf.push((nal_buf.len() >> 8) as u8);
84 pps_buf.push(nal_buf.len() as u8);
85 pps_buf.extend_from_slice(&nal_buf);
89 self.frame_buf = nal_buf;
96 if num_sps == 0 || num_pps == 0 {
97 return Err(DemuxerError::InvalidData);
99 edata.extend_from_slice(b"avcC");
105 edata.push(0xE0 | num_sps);
106 edata.extend_from_slice(&sps_buf);
108 edata.extend_from_slice(&pps_buf);
113 let vhdr = NAVideoInfo::new(width, height, false, YUV420_FORMAT);
114 let vinfo = NACodecInfo::new("h264", NACodecTypeInfo::Video(vhdr), Some(edata));
115 if let None = strmgr.add_stream(NAStream::new(StreamType::Video, 0, vinfo, 1, 25, 0)) {
116 return Err(DemuxerError::InvalidData);
122 fn get_frame(&mut self, strmgr: &mut StreamManager) -> DemuxerResult<NAPacket> {
123 let ts = NATimeInfo::new(Some(self.cur_frame), None, None, 1, 25);
124 let mut buf: Vec<u8> = Vec::with_capacity(65536);
125 if !self.frame_buf.is_empty() {
126 put_nal(&mut buf, &self.frame_buf);
127 self.frame_buf.clear();
129 let strres = strmgr.get_stream(0);
130 if strres.is_none() {
131 return Err(DemuxerError::InvalidData);
133 let stream = strres.unwrap();
135 let mut keyframe = false;
137 let mut nal_buf = Vec::with_capacity(65536);
138 let mut is_eof = false;
140 match read_nal(&mut self.src, &mut nal_buf) {
142 Err(DemuxerError::IOError) => { is_eof = true; },
143 Err(err) => return Err(err),
145 if !nal_buf.is_empty() {
146 let nal_type = nal_buf[0] & 0x1F;
147 keyframe = nal_type == 5;
150 let first_slice = (nal_buf[1] & 0x80) != 0;
151 if first_slice && !buf.is_empty() {
152 self.frame_buf.extend_from_slice(&nal_buf);
155 put_nal(&mut buf, &nal_buf);
159 //println!("non-slice NAL {} @ {:X}", nal_type, self.src.tell());
160 put_nal(&mut buf, &nal_buf);
166 if is_eof && buf.is_empty() {
167 return Err(DemuxerError::EOF);
170 let pkt = NAPacket::new(stream, ts, keyframe, buf);
176 fn seek(&mut self, _time: NATimePoint, _seek_idx: &SeekIndex) -> DemuxerResult<()> {
177 Err(DemuxerError::NotImplemented)
179 fn get_duration(&self) -> u64 { 0 }
182 impl<'a> NAOptionHandler for RawH264Demuxer<'a> {
183 fn get_supported_options(&self) -> &[NAOptionDefinition] { &[] }
184 fn set_options(&mut self, _options: &[NAOption]) { }
185 fn query_option_value(&self, _name: &str) -> Option<NAValue> { None }
188 impl<'a> RawH264Demuxer<'a> {
189 fn new(io: &'a mut ByteReader<'a>) -> Self {
193 frame_buf: Vec::new(),
198 pub struct RawH264DemuxerCreator { }
200 impl DemuxerCreator for RawH264DemuxerCreator {
201 fn new_demuxer<'a>(&self, br: &'a mut ByteReader<'a>) -> Box<dyn DemuxCore<'a> + 'a> {
202 Box::new(RawH264Demuxer::new(br))
204 fn get_name(&self) -> &'static str { "rawh264" }