1 use nihav_core::demuxers::*;
3 struct VivoDemuxer<'a> {
4 src: &'a mut ByteReader<'a>,
22 fn read_size(br: &mut ByteReader) -> DemuxerResult<usize> {
25 let c = br.read_byte()?;
26 ret = (ret << 7) | ((c & 0x7F) as usize);
34 impl<'a> DemuxCore<'a> for VivoDemuxer<'a> {
35 fn open(&mut self, strmgr: &mut StreamManager, _seek_idx: &mut SeekIndex) -> DemuxerResult<()> {
36 let mut hdr_data: Vec<u8> = Vec::with_capacity(256);
38 let hdr = self.src.peek_byte()?;
39 if (hdr & 0xF0) != 0 { break; }
40 self.src.read_skip(1)?;
41 let hdr_len = read_size(self.src)?;
42 hdr_data.resize(hdr_len, 0);
43 self.src.read_buf(&mut hdr_data)?;
44 self.parse_header_packet(&hdr_data)?;
47 validate!(self.vname != "none");
48 if self.width == 0 && self.height == 0 {
52 validate!(self.fps > 0.0 || (self.v_num > 0 && self.v_den > 0));
56 self.v_den = (self.fps * 1000.0) as u32;
59 let vhdr = NAVideoInfo::new(self.width, self.height, false, YUV420_FORMAT);
60 let vinfo = NACodecInfo::new(self.vname, NACodecTypeInfo::Video(vhdr), None);
61 let res = strmgr.add_stream(NAStream::new(StreamType::Video, 0, vinfo, self.v_num, self.v_den, 0));
62 validate!(res.is_some());
63 self.video_id = res.unwrap();
65 if self.aname == "none" && self.vname == "vivo1" {
66 self.aname = "g723.1";
70 if self.aname != "none" {
71 let ahdr = NAAudioInfo::new(self.a_den, 1, SND_S16_FORMAT, self.a_num as usize);
72 let ainfo = NACodecInfo::new(self.aname, NACodecTypeInfo::Audio(ahdr), None);
73 let res = strmgr.add_stream(NAStream::new(StreamType::Audio, 1, ainfo, self.a_num, self.a_den, 0));
74 validate!(res.is_some());
75 self.audio_id = res.unwrap();
80 fn get_frame(&mut self, strmgr: &mut StreamManager) -> DemuxerResult<NAPacket> {
81 let br = &mut self.src;
84 let ret = br.read_byte();
85 let hdr1 = match ret {
86 Err(ByteIOError::EOF) => return Err(DemuxerError::EOF),
87 Err(error) => return Err(error.into()),
90 let force_size = hdr1 == 0x82;
91 let hdr = if force_size { br.read_byte()? } else { hdr1 };
92 let (is_video, mut size) = match hdr >> 4 {
94 2 => { validate!(!force_size); (true, read_size(br)?) },
97 _ => return Err(DemuxerError::InvalidData),
100 size = read_size(br)?;
103 validate!(self.v_den != 0);
104 let cur_size = self.video_buf.len();
105 let new_size = cur_size + size;
106 self.video_buf.resize(new_size, 0);
107 br.read_buf(&mut self.video_buf[cur_size..])?;
109 let mut buf = Vec::new();
110 std::mem::swap(&mut self.video_buf, &mut buf);
111 let strres = strmgr.get_stream(self.video_id);
112 validate!(strres.is_some());
113 let stream = strres.unwrap();
114 let ts = NATimeInfo::new(Some(self.vpts), None, None, self.v_num, self.v_den);
115 let pkt = NAPacket::new(stream, ts, self.vpts == 0, buf);
120 validate!(self.a_den != 0);
121 let mut buf: Vec<u8> = vec![0; size];
122 br.read_buf(&mut buf)?;
123 let strres = strmgr.get_stream(self.audio_id);
124 validate!(strres.is_some());
125 let stream = strres.unwrap();
126 let ts = NATimeInfo::new(Some(self.apts), None, None, self.a_num, self.a_den);
127 let pkt = NAPacket::new(stream, ts, true, buf);
133 fn seek(&mut self, _time: NATimePoint, _seek_idx: &SeekIndex) -> DemuxerResult<()> {
134 Err(DemuxerError::NotPossible)
136 fn get_duration(&self) -> u64 { self.duration }
139 impl<'a> NAOptionHandler for VivoDemuxer<'a> {
140 fn get_supported_options(&self) -> &[NAOptionDefinition] { &[] }
141 fn set_options(&mut self, _options: &[NAOption]) { }
142 fn query_option_value(&self, _name: &str) -> Option<NAValue> { None }
145 impl<'a> VivoDemuxer<'a> {
146 fn new(io: &'a mut ByteReader<'a>) -> Self {
151 video_buf: Vec::new(),
166 fn parse_header_packet(&mut self, pkt: &[u8]) -> DemuxerResult<()> {
167 for entry in pkt.split(|ch| *ch == 0xD) {
168 if entry.len() < 3 || !entry.contains(&b':') { continue; }
169 let entry = if !entry.is_empty() && entry[0] == 0xA { &entry[1..] } else { entry };
170 let mut split = entry.split(|ch| *ch == b':');
171 let name = split.next().unwrap();
172 let value = split.next().unwrap();
174 let valstr = String::from_utf8_lossy(value);
178 b"Vivo/0.90" => { self.vname = "vivo1"; },
179 b"Vivo/1.00" => { self.vname = "vivo1"; },
180 b"Vivo/2.00" => { self.vname = "vivo2"; },
182 println!("Unknown codec name {}", valstr);
183 return Err(DemuxerError::InvalidData);
188 self.fps = if let Ok(val) = valstr.parse() {
190 } else { return Err(DemuxerError::InvalidData); };
191 validate!(self.fps > 0.0 && self.fps < 1000.0);
194 self.width = if let Ok(val) = valstr.parse() {
196 } else { return Err(DemuxerError::InvalidData); };
197 validate!(self.width > 0 && self.width <= 1024);
200 self.height = if let Ok(val) = valstr.parse() {
202 } else { return Err(DemuxerError::InvalidData); };
203 validate!(self.height > 0 && self.height <= 768);
205 b"SamplingFrequency" => {
206 let samp_freq: u32 = if let Ok(val) = valstr.parse() {
208 } else { return Err(DemuxerError::InvalidData); };
209 validate!(samp_freq == 8000 || samp_freq == 16000);
210 if samp_freq == 8000 {
211 self.aname = "g723.1";
214 } else if samp_freq == 16000 {
215 self.aname = "siren";
219 return Err(DemuxerError::InvalidData);
223 self.duration = if let Ok(val) = valstr.parse() {
227 /* b"TimeUnitNumerator" => {
228 self.v_num = if let Ok(val) = valstr.parse() {
230 } else { return Err(DemuxerError::InvalidData); };
231 validate!(self.v_num > 0);
232 println!(" video codec tb_num {}", self.v_num);
234 b"TimeUnitDenominator" => {
235 self.v_den = if let Ok(val) = valstr.parse() {
237 } else { return Err(DemuxerError::InvalidData); };
238 validate!(self.v_den > 0);
239 println!(" video codec tb_den {}", self.v_den);
248 pub struct VivoDemuxerCreator { }
250 impl DemuxerCreator for VivoDemuxerCreator {
251 fn new_demuxer<'a>(&self, br: &'a mut ByteReader<'a>) -> Box<dyn DemuxCore<'a> + 'a> {
252 Box::new(VivoDemuxer::new(br))
254 fn get_name(&self) -> &'static str { "vivo" }
263 fn test_vivo_demux() {
264 // let mut file = File::open("assets/Misc/greetings.viv").unwrap();
265 // sample: https://samples.mplayerhq.hu/vivo/vivo2/favmovie.viv
266 let mut file = File::open("assets/Misc/favmovie.viv").unwrap();
267 let mut fr = FileReader::new_read(&mut file);
268 let mut br = ByteReader::new(&mut fr);
269 let mut dmx = VivoDemuxer::new(&mut br);
270 let mut sm = StreamManager::new();
271 let mut si = SeekIndex::new();
272 dmx.open(&mut sm, &mut si).unwrap();
274 let pktres = dmx.get_frame(&mut sm);
275 if let Err(e) = pktres {
276 if (e as i32) == (DemuxerError::EOF as i32) { break; }
277 panic!("error {:?}", e);
279 let pkt = pktres.unwrap();
280 println!("Got {}", pkt);