1 use nihav_core::demuxers::*;
3 struct VivoDemuxer<'a> {
4 src: &'a mut ByteReader<'a>,
21 fn read_size(br: &mut ByteReader) -> DemuxerResult<usize> {
24 let c = br.read_byte()?;
25 ret = (ret << 7) | ((c & 0x7F) as usize);
33 impl<'a> DemuxCore<'a> for VivoDemuxer<'a> {
34 fn open(&mut self, strmgr: &mut StreamManager, _seek_idx: &mut SeekIndex) -> DemuxerResult<()> {
35 let mut hdr_data: Vec<u8> = Vec::with_capacity(256);
37 let hdr = self.src.peek_byte()?;
38 if (hdr & 0xF0) != 0 { break; }
39 self.src.read_skip(1)?;
40 let hdr_len = read_size(&mut self.src)?;
41 hdr_data.resize(hdr_len, 0);
42 self.src.read_buf(&mut hdr_data)?;
43 self.parse_header_packet(&hdr_data)?;
46 validate!(self.vname != "none");
47 if self.width == 0 && self.height == 0 {
51 validate!(self.fps > 0.0 || (self.v_num > 0 && self.v_den > 0));
55 self.v_den = (self.fps * 1000.0) as u32;
58 let vhdr = NAVideoInfo::new(self.width, self.height, false, YUV420_FORMAT);
59 let vinfo = NACodecInfo::new(self.vname, NACodecTypeInfo::Video(vhdr), None);
60 let res = strmgr.add_stream(NAStream::new(StreamType::Video, 0, vinfo, self.v_num, self.v_den));
61 validate!(res.is_some());
62 self.video_id = res.unwrap();
64 if self.aname == "none" && self.vname == "vivo1" {
65 self.aname = "g723.1";
69 if self.aname != "none" {
70 let ahdr = NAAudioInfo::new(self.a_den, 1, SND_S16_FORMAT, self.a_num as usize);
71 let ainfo = NACodecInfo::new(self.aname, NACodecTypeInfo::Audio(ahdr), None);
72 let res = strmgr.add_stream(NAStream::new(StreamType::Audio, 1, ainfo, self.a_num, self.a_den));
73 validate!(res.is_some());
74 self.audio_id = res.unwrap();
79 fn get_frame(&mut self, strmgr: &mut StreamManager) -> DemuxerResult<NAPacket> {
80 let br = &mut self.src;
83 let ret = br.read_byte();
84 let hdr1 = match ret {
85 Err(ByteIOError::EOF) => return Err(DemuxerError::EOF),
86 Err(error) => return Err(error.into()),
89 let force_size = hdr1 == 0x82;
90 let hdr = if force_size { br.read_byte()? } else { hdr1 };
91 let (is_video, mut size) = match hdr >> 4 {
93 2 => { validate!(!force_size); (true, read_size(br)?) },
96 _ => return Err(DemuxerError::InvalidData),
99 size = read_size(br)?;
102 validate!(self.v_den != 0);
103 let cur_size = self.video_buf.len();
104 let new_size = cur_size + size;
105 self.video_buf.resize(new_size, 0);
106 br.read_buf(&mut self.video_buf[cur_size..])?;
108 let mut buf = Vec::new();
109 std::mem::swap(&mut self.video_buf, &mut buf);
110 let strres = strmgr.get_stream(self.video_id);
111 validate!(strres.is_some());
112 let stream = strres.unwrap();
113 let ts = NATimeInfo::new(Some(self.vpts), None, None, self.v_num, self.v_den);
114 let pkt = NAPacket::new(stream, ts, self.vpts == 0, buf);
119 validate!(self.a_den != 0);
120 let mut buf: Vec<u8> = vec![0; size];
121 br.read_buf(&mut buf)?;
122 let strres = strmgr.get_stream(self.audio_id);
123 validate!(strres.is_some());
124 let stream = strres.unwrap();
125 let ts = NATimeInfo::new(Some(self.apts), None, None, self.a_num, self.a_den);
126 let pkt = NAPacket::new(stream, ts, true, buf);
132 fn seek(&mut self, _time: u64, _seek_idx: &SeekIndex) -> DemuxerResult<()> {
133 Err(DemuxerError::NotPossible)
137 impl<'a> NAOptionHandler for VivoDemuxer<'a> {
138 fn get_supported_options(&self) -> &[NAOptionDefinition] { &[] }
139 fn set_options(&mut self, _options: &[NAOption]) { }
140 fn query_option_value(&self, _name: &str) -> Option<NAValue> { None }
143 impl<'a> VivoDemuxer<'a> {
144 fn new(io: &'a mut ByteReader<'a>) -> Self {
149 video_buf: Vec::new(),
163 fn parse_header_packet(&mut self, pkt: &[u8]) -> DemuxerResult<()> {
164 for entry in pkt.split(|ch| *ch == 0xD) {
165 if entry.len() < 3 || !entry.contains(&b':') { continue; }
166 let entry = if !entry.is_empty() && entry[0] == 0xA { &entry[1..] } else { entry };
167 let mut split = entry.split(|ch| *ch == b':');
168 let name = split.next().unwrap();
169 let value = split.next().unwrap();
171 let valstr = String::from_utf8_lossy(value);
175 b"Vivo/0.90" => { self.vname = "vivo1"; },
176 b"Vivo/1.00" => { self.vname = "vivo1"; },
177 b"Vivo/2.00" => { self.vname = "vivo2"; },
179 println!("Unknown codec name {}", valstr);
180 return Err(DemuxerError::InvalidData);
185 self.fps = if let Ok(val) = valstr.parse() {
187 } else { return Err(DemuxerError::InvalidData); };
188 validate!(self.fps > 0.0 && self.fps < 1000.0);
191 self.width = if let Ok(val) = valstr.parse() {
193 } else { return Err(DemuxerError::InvalidData); };
194 validate!(self.width > 0 && self.width <= 1024);
197 self.height = if let Ok(val) = valstr.parse() {
199 } else { return Err(DemuxerError::InvalidData); };
200 validate!(self.height > 0 && self.height <= 768);
202 b"SamplingFrequency" => {
203 let samp_freq: u32 = if let Ok(val) = valstr.parse() {
205 } else { return Err(DemuxerError::InvalidData); };
206 validate!(samp_freq == 8000 || samp_freq == 16000);
207 if samp_freq == 8000 {
208 self.aname = "g723.1";
211 } else if samp_freq == 16000 {
212 self.aname = "siren";
216 return Err(DemuxerError::InvalidData);
219 /* b"TimeUnitNumerator" => {
220 self.v_num = if let Ok(val) = valstr.parse() {
222 } else { return Err(DemuxerError::InvalidData); };
223 validate!(self.v_num > 0);
224 println!(" video codec tb_num {}", self.v_num);
226 b"TimeUnitDenominator" => {
227 self.v_den = if let Ok(val) = valstr.parse() {
229 } else { return Err(DemuxerError::InvalidData); };
230 validate!(self.v_den > 0);
231 println!(" video codec tb_den {}", self.v_den);
240 pub struct VivoDemuxerCreator { }
242 impl DemuxerCreator for VivoDemuxerCreator {
243 fn new_demuxer<'a>(&self, br: &'a mut ByteReader<'a>) -> Box<dyn DemuxCore<'a> + 'a> {
244 Box::new(VivoDemuxer::new(br))
246 fn get_name(&self) -> &'static str { "vivo" }
255 fn test_vivo_demux() {
256 // let mut file = File::open("assets/Misc/greetings.viv").unwrap();
257 let mut file = File::open("assets/Misc/favmovie.viv").unwrap();
258 let mut fr = FileReader::new_read(&mut file);
259 let mut br = ByteReader::new(&mut fr);
260 let mut dmx = VivoDemuxer::new(&mut br);
261 let mut sm = StreamManager::new();
262 let mut si = SeekIndex::new();
263 dmx.open(&mut sm, &mut si).unwrap();
265 let pktres = dmx.get_frame(&mut sm);
266 if let Err(e) = pktres {
267 if (e as i32) == (DemuxerError::EOF as i32) { break; }
268 panic!("error {:?}", e);
270 let pkt = pktres.unwrap();
271 println!("Got {}", pkt);