rv34: remove debug cruft
[nihav.git] / src / demuxers / realmedia.rs
CommitLineData
ce52b3b5
KS
1use super::*;
2use super::DemuxerError::*;
3//use io::byteio::*;
4//use frame::*;
5use formats::*;
6use std::io::SeekFrom;
7use std::mem;
8
9macro_rules! mktag {
10 ($a:expr, $b:expr, $c:expr, $d:expr) => ({
11 (($a as u32) << 24) | (($b as u32) << 16) | (($c as u32) << 8) | ($d as u32)
12 });
13 ($arr:expr) => ({
14 (($arr[0] as u32) << 24) | (($arr[1] as u32) << 16) | (($arr[2] as u32) << 8) | ($arr[3] as u32)
15 });
16}
17
18struct RMVideoStream {
19 frame: Vec<u8>,
20 hdr_size: usize,
21 frame_size: usize,
22 frame_pos: usize,
23}
24
25impl RMVideoStream {
26 fn new() -> Self {
27 RMVideoStream {
28 frame: Vec::new(),
29 hdr_size: 0,
30 frame_size: 0,
31 frame_pos: 0,
32 }
33 }
34 fn flush(&mut self) {
35 self.frame.truncate(0);
36 self.frame_size = 0;
37 self.frame_pos = 0;
38 }
39 fn start_slice(&mut self, num_slices: usize, frame_size: usize, data: &[u8]) {
40 self.hdr_size = num_slices * 8 + 1;
41 self.frame.resize(frame_size + self.hdr_size, 0);
42 self.frame[0] = (num_slices - 1) as u8;
43 self.frame_pos = 0;
44 self.add_slice(1, data);
45 }
46 fn add_slice(&mut self, slice_no: usize, data: &[u8]) {
47 self.write_slice_info(slice_no);
9037cf6b 48 let dslice = &mut self.frame[self.hdr_size + self.frame_pos..][..data.len()];
ce52b3b5
KS
49 dslice.copy_from_slice(data);
50 self.frame_pos += data.len();
51 }
52 fn write_slice_info(&mut self, slice_no: usize) {
53 let off = 1 + (slice_no - 1) * 8;
54 self.frame[off + 0] = 0;
55 self.frame[off + 1] = 0;
56 self.frame[off + 2] = 0;
57 self.frame[off + 3] = 1;
58 self.frame[off + 4] = (self.frame_pos >> 24) as u8;
59 self.frame[off + 5] = (self.frame_pos >> 16) as u8;
60 self.frame[off + 6] = (self.frame_pos >> 8) as u8;
61 self.frame[off + 7] = (self.frame_pos >> 0) as u8;
62 }
63 fn get_frame_data(&mut self) -> Vec<u8> {
64 let mut v: Vec<u8> = Vec::new();
65 mem::swap(&mut v, &mut self.frame);
66 self.flush();
67 v
68 }
69}
70
b1ef37ee 71#[allow(dead_code)]
ce52b3b5
KS
72#[derive(Clone,Copy,PartialEq)]
73enum Deinterleaver {
74 None,
c19ce782 75 RA28_8,
ce52b3b5
KS
76 Generic,
77 Sipro,
78 VBR,
79}
80
b1ef37ee 81#[allow(dead_code)]
ce52b3b5
KS
82struct RMAudioStream {
83 deint: Deinterleaver,
c19ce782 84 iinfo: Option<InterleaveInfo>,
fe07b469
KS
85 buf: Vec<u8>,
86 sub_packet: usize,
ce52b3b5
KS
87}
88
c19ce782
KS
89const RM_ILEAVE_INT0: u32 = mktag!(b"Int0");
90const RM_ILEAVE_INT4: u32 = mktag!(b"Int4");
91const RM_ILEAVE_GENR: u32 = mktag!(b"genr");
92const RM_ILEAVE_SIPR: u32 = mktag!(b"sipr");
93const RM_ILEAVE_VBRS: u32 = mktag!(b"vbrs");
94
ce52b3b5 95impl RMAudioStream {
c19ce782
KS
96 fn new(iinfo: Option<InterleaveInfo>) -> Self {
97 let deint;
fe07b469 98 let mut buf: Vec<u8>;
c19ce782
KS
99 if let Some(info) = iinfo {
100 deint = match info.id {
101 RM_ILEAVE_INT0 => Deinterleaver::None,
102 RM_ILEAVE_INT4 => Deinterleaver::RA28_8,
103 RM_ILEAVE_GENR => Deinterleaver::Generic,
104 RM_ILEAVE_SIPR => Deinterleaver::Sipro,
105 RM_ILEAVE_VBRS => Deinterleaver::VBR,
106 _ => {println!("unknown deint {:X}", info.id); Deinterleaver::None },
107 };
fe07b469
KS
108 match deint {
109 Deinterleaver::None => { buf = Vec::new(); },
6669c73b
KS
110 Deinterleaver::RA28_8 |
111 Deinterleaver::Generic |
112 Deinterleaver::Sipro => {
fe07b469
KS
113 let bsize = (info.frame_size as usize) * (info.factor as usize);
114 buf = Vec::with_capacity(bsize);
115 buf.resize(bsize, 0u8);
116 },
fe07b469
KS
117 Deinterleaver::VBR => { unimplemented!("deint"); },
118 };
c19ce782
KS
119 } else {
120 deint = Deinterleaver::None;
fe07b469
KS
121 buf = Vec::new();
122 }
123 RMAudioStream { deint: deint, iinfo: iinfo, buf: buf, sub_packet: 0 }
124 }
6669c73b 125 fn read_apackets(&mut self, queued_packets: &mut Vec<NAPacket>, src: &mut ByteReader, stream: Rc<NAStream>, ts: u32, keyframe: bool, payload_size: usize) -> DemuxerResult<NAPacket> {
fe07b469
KS
126 let (tb_num, tb_den) = stream.get_timebase();
127 let ts = NATimeInfo::new(Some(ts as u64), None, None, tb_num, tb_den);
128
129 if keyframe {
130 self.sub_packet = 0;
131 }
132 match self.deint {
6669c73b 133 Deinterleaver::None => { return src.read_packet(stream, ts, keyframe, payload_size); },
fe07b469
KS
134 Deinterleaver::RA28_8 => {
135 let iinfo = self.iinfo.unwrap();
136 let factor = iinfo.factor as usize;
137 let halffact = factor >> 1;
138 let fsize = iinfo.frame_size as usize;
139 let bsize = iinfo.block_size as usize;
140 let ppos = self.sub_packet;
141 for sb in 0..halffact {
142 let mut dst = &mut self.buf[sb * 2 * fsize + ppos * bsize..][..bsize];
143 src.read_buf(&mut dst)?;
144 }
145 self.sub_packet += 1;
146 if self.sub_packet == factor {
147 self.sub_packet = 0;
6669c73b 148 return Ok(NAPacket::new(stream, ts, true, self.buf.clone()));
fe07b469 149 } else {
6669c73b 150 return Err(DemuxerError::TryAgain);
fe07b469
KS
151 }
152 },
6669c73b
KS
153 Deinterleaver::Generic => {
154 let iinfo = self.iinfo.unwrap();
155 let factor = iinfo.factor as usize;
156 let fsize = iinfo.frame_size as usize;
157 let bsize = iinfo.block_size as usize;
158 let factor2 = fsize / bsize;
159 let ppos = self.sub_packet;
160
161 for sb in 0..factor2 {
162 let sb_pos = factor * sb + ((factor + 1) >> 1) * (ppos & 1) + (ppos >> 1);
163 let mut dst = &mut self.buf[bsize * sb_pos..][..bsize];
164 src.read_buf(&mut dst)?;
165 }
166 },
167 Deinterleaver::Sipro => {
168 let iinfo = self.iinfo.unwrap();
169 let fsize = iinfo.frame_size as usize;
170 let ppos = self.sub_packet;
171
172 let mut dst = &mut self.buf[fsize * ppos..][..fsize];
173 src.read_buf(&mut dst)?;
174 },
175 _ => { return src.read_packet(stream, ts, keyframe, payload_size); },
176 };
177
178 let iinfo = self.iinfo.unwrap();
179 let factor = iinfo.factor as usize;
180 let fsize = iinfo.frame_size as usize;
181
182 self.sub_packet += 1;
183 if self.sub_packet < factor {
184 return Err(DemuxerError::TryAgain);
185 }
186
187 self.sub_packet = 0;
188
189 if self.deint == Deinterleaver::Sipro {
190// todo sipro deinterleave
191 }
192
193 let mut frames_iter = self.buf.chunks(fsize);
194 let pkt0 = frames_iter.next().unwrap();
195
196 let pkt_ts = NATimeInfo::new(None, None, None, tb_num, tb_den);
197 for pkts in frames_iter {
198 let pkt = NAPacket::new(stream.clone(), pkt_ts, true, pkts.to_vec());
199 queued_packets.push(pkt);
c19ce782 200 }
6669c73b
KS
201 queued_packets.reverse();
202 Ok(NAPacket::new(stream, ts, true, pkt0.to_vec()))
ce52b3b5
KS
203 }
204}
205
206enum RMStreamType {
207 Audio(RMAudioStream),
208 Video(RMVideoStream),
209 Logical,
210 Unknown,
211}
212
213struct RealMediaDemuxer<'a> {
214 src: &'a mut ByteReader<'a>,
215 data_pos: u64,
216 num_packets: u32,
217 cur_packet: u32,
218
219 streams: Vec<RMStreamType>,
220 str_ids: Vec<u16>,
221
222 queued_pkts: Vec<NAPacket>,
223 slice_buf: Vec<u8>,
224}
225
226fn find_codec_name(registry: &[(&[u8;4], &'static str)], fcc: u32) -> &'static str {
227 for &(fourcc, name) in registry {
228 if mktag!(fourcc) == fcc { return name; }
229 }
230 "unknown"
231}
232
233fn read_14or30(src: &mut ByteReader) -> DemuxerResult<(bool, u32)> {
234 let tmp = src.read_u16be()?;
235 let flag = (tmp & 0x8000) != 0;
236 if (tmp & 0x4000) == 0x4000 {
237 Ok((flag, ((tmp & 0x3FFF) as u32)))
238 } else {
239 let val = ((tmp as u32) << 16) | (src.read_u16be()? as u32);
240 Ok((flag, val & 0x3FFFFFFF))
241 }
242}
243
244fn read_video_buf(src: &mut ByteReader, stream: Rc<NAStream>, ts: u32, keyframe: bool, frame_size: usize) -> DemuxerResult<NAPacket> {
245 let size = (frame_size as usize) + 9;
246 let mut vec: Vec<u8> = Vec::with_capacity(size);
247 vec.resize(size, 0);
248 //v[0] = 0; // 1 slice
249 vec[4] = 1;
250 src.read_buf(&mut vec[9..])?;
251
252 let (tb_num, tb_den) = stream.get_timebase();
253 let ts = NATimeInfo::new(Some(ts as u64), None, None, tb_num, tb_den);
254 Ok(NAPacket::new(stream, ts, keyframe, vec))
255}
256
257fn read_multiple_frame(src: &mut ByteReader, stream: Rc<NAStream>, keyframe: bool, skip_mtype: bool) -> DemuxerResult<NAPacket> {
258 if !skip_mtype {
259 let mtype = src.read_byte()?;
260 validate!(mtype == 0xC0);
261 }
262 let (_, frame_size) = read_14or30(src)?;
263 let (_, timestamp) = read_14or30(src)?;
c9aba47e
KS
264 let _seq_no = src.read_byte()?;
265//println!(" multiple frame size {} ts {} seq {}", frame_size, timestamp, seq_no);
ce52b3b5
KS
266
267 read_video_buf(src, stream, timestamp, keyframe, frame_size as usize)
268}
269
270impl<'a> DemuxCore<'a> for RealMediaDemuxer<'a> {
271 #[allow(unused_variables)]
272 fn open(&mut self, strmgr: &mut StreamManager) -> DemuxerResult<()> {
273 self.read_header(strmgr)?;
274 Ok(())
275 }
276
277#[allow(unused_variables)]
278 fn get_frame(&mut self, strmgr: &mut StreamManager) -> DemuxerResult<NAPacket> {
279 if !self.queued_pkts.is_empty() {
280 let pkt = self.queued_pkts.pop().unwrap();
281 return Ok(pkt);
282 }
283 loop {
284 if self.cur_packet >= self.num_packets { return Err(DemuxerError::EOF); }
285
286 let pkt_start = self.src.tell();
287 let ver = self.src.read_u16le()?;
288 validate!(ver <= 1);
289 let len = self.src.read_u16be()? as usize;
290 let str_no = self.src.read_u16be()?;
291 let ts = self.src.read_u32be()?;
c9aba47e 292 let _pkt_grp;
ce52b3b5 293 if ver == 0 {
c9aba47e 294 _pkt_grp = self.src.read_byte()?;
ce52b3b5
KS
295 } else {
296 //asm_rule = self.src.read_u16le()?;
297 self.src.read_skip(2)?;
c9aba47e 298 _pkt_grp = 0;
ce52b3b5
KS
299 }
300 let flags = self.src.read_byte()?;
301 let hdr_size = self.src.tell() - pkt_start;
9f45e528 302//println!("packet @{:X} size {} for {} ts {} grp {} flags {:X}", pkt_start, len, str_no, ts, _pkt_grp, flags);
ce52b3b5
KS
303 self.cur_packet += 1;
304
305 let payload_size = len - (hdr_size as usize);
306
307 let sr = self.str_ids.iter().position(|x| *x == str_no);
308 if sr.is_none() {
c9aba47e 309//println!("stream {} not found", str_no);
ce52b3b5
KS
310 self.src.read_skip(payload_size)?;
311 return Err(DemuxerError::InvalidData);
312 }
313 let str_id = sr.unwrap();
c9aba47e
KS
314 let streamres = strmgr.get_stream_by_id(str_no as u32);
315 if streamres.is_none() {
316 self.src.read_skip(payload_size)?;
317 continue;
318 }
319 let stream = streamres.unwrap();
320//println!(" stream {}", str_id);
ce52b3b5
KS
321 if strmgr.is_ignored_id(str_no as u32) {
322 self.src.read_skip(payload_size)?;
323 continue;
324 }
325 //todo skip unwanted packet
326 let keyframe = (flags & KEYFRAME_FLAG) != 0;
327
328 let result = match self.streams[str_id] {
329 RMStreamType::Video(ref mut vstr) => {
330
331 let pos = self.src.tell();
332 let b0 = self.src.read_byte()?;
333 match b0 >> 6 {
334 0 => { // partial frame
335 let b1 = self.src.read_byte()?;
336 let hdr1 = ((b0 as u16) << 8) | (b1 as u16);
337 let num_pkts = ((hdr1 >> 7) & 0x7F) as usize;
338 let packet_num = hdr1 & 0x7F;
339 let (_, frame_size) = read_14or30(self.src)?;
340 let (_, off) = read_14or30(self.src)?;
341 let seq_no = self.src.read_byte()?;
c9aba47e 342//println!(" mode 0 pkt {}/{} off {}/{} seq {}", packet_num, num_pkts, off, frame_size, seq_no);
ce52b3b5
KS
343 let hdr_skip = (self.src.tell() - pos) as usize;
344
345 let slice_size = (payload_size - hdr_skip) as usize;
346 self.slice_buf.resize(slice_size, 0);
347 self.src.read_buf(self.slice_buf.as_mut_slice())?;
348 if packet_num == 1 {
349 vstr.start_slice(num_pkts, frame_size as usize, self.slice_buf.as_slice());
350 } else {
351 vstr.add_slice(packet_num as usize, self.slice_buf.as_slice());
352 }
8a5cb596
KS
353 if (packet_num as usize) < num_pkts {
354 continue;
355 }
356 //todo: check if full frame is received
357 let (tb_num, tb_den) = stream.get_timebase();
358 let ts = NATimeInfo::new(Some(ts as u64), None, None, tb_num, tb_den);
359 let pkt = NAPacket::new(stream, ts, keyframe, vstr.get_frame_data());
360 Ok(pkt)
ce52b3b5
KS
361 },
362 1 => { // whole frame
363 let seq_no = self.src.read_byte()?;
c9aba47e 364//println!(" mode 1 seq {}", seq_no);
ce52b3b5
KS
365 read_video_buf(self.src, stream, ts, keyframe, payload_size - 1)
366 },
367 2 => { // last partial frame
368 let b1 = self.src.read_byte()?;
369 let hdr1 = ((b0 as u16) << 8) | (b1 as u16);
370 let num_pkts = ((hdr1 >> 7) & 0x7F) as usize;
371 let packet_num = hdr1 & 0x7F;
372 let (_, frame_size) = read_14or30(self.src)?;
373 let (_, tail_size) = read_14or30(self.src)?;
374 let seq_no = self.src.read_byte()?;
c9aba47e 375//println!(" mode 2 pkt {}/{} tail {}/{} seq {}", packet_num, num_pkts, tail_size, frame_size, seq_no);
ce52b3b5
KS
376 self.slice_buf.resize(tail_size as usize, 0);
377 self.src.read_buf(self.slice_buf.as_mut_slice())?;
5b744f82
KS
378 if packet_num == 1 && frame_size == tail_size {
379 vstr.start_slice(num_pkts, frame_size as usize, self.slice_buf.as_slice());
380 } else {
381 vstr.add_slice(packet_num as usize, self.slice_buf.as_slice());
382 }
ce52b3b5
KS
383
384 while self.src.tell() < pos + (payload_size as u64) {
385 let res = read_multiple_frame(self.src, stream.clone(), false, false);
386 if res.is_err() { break; }
387 self.queued_pkts.push(res.unwrap());
388 }
389 self.queued_pkts.reverse();
390 let (tb_num, tb_den) = stream.get_timebase();
391 let ts = NATimeInfo::new(Some(ts as u64), None, None, tb_num, tb_den);
392 let pkt = NAPacket::new(stream, ts, keyframe, vstr.get_frame_data());
393 Ok(pkt)
394 },
395 _ => { // multiple frames
c9aba47e 396//println!(" mode 3");
ce52b3b5
KS
397 let res = read_multiple_frame(self.src, stream.clone(), keyframe, true);
398 if res.is_err() { return res; }
399 while self.src.tell() < pos + (payload_size as u64) {
400 let res = read_multiple_frame(self.src, stream.clone(), false, false);
401 if res.is_err() { break; }
402 self.queued_pkts.push(res.unwrap());
403 }
404 self.queued_pkts.reverse();
405 res
406 },
407 }
408 },
409 RMStreamType::Audio(ref mut astr) => {
fe07b469
KS
410 let ret = astr.read_apackets(&mut self.queued_pkts, &mut self.src, stream, ts, keyframe, payload_size);
411 if let Err(DemuxerError::TryAgain) = ret {
412 continue;
413 }
414 ret
ce52b3b5
KS
415 },
416 _ => {
417// self.src.read_skip(payload_size)?;
418 Err(DemuxerError::InvalidData)
419 },
420 };
421 return result;
422 }
423 }
424
425 #[allow(unused_variables)]
426 fn seek(&mut self, time: u64) -> DemuxerResult<()> {
427 Err(NotImplemented)
428 }
429}
430
431fn read_chunk(src: &mut ByteReader) -> DemuxerResult<(u32, u32, u16)> {
432 let id = src.read_u32be()?;
6132225f 433if id == 0 { return Ok((0, 0, 0)); }
ce52b3b5 434 let size = src.read_u32be()?;
9f45e528
KS
435if size == 0 {
436 let ver = src.read_u16be()?;
437 validate!(ver <= 1);
438 return Ok((id, 0x0FFFFFFF, ver));
439}
ce52b3b5
KS
440 validate!(size >= 10);
441 let ver = src.read_u16be()?;
442 validate!(ver <= 1);
443 Ok((id, size, ver))
444}
445
c19ce782
KS
446#[derive(Clone,Copy,Debug)]
447struct InterleaveInfo {
448 id: u32,
449 factor: u16,
450 block_size: u16,
451 frame_size: u16,
452}
453
454#[derive(Clone,Copy,Debug)]
455struct RealAudioInfo {
456 fcc: u32,
457 sample_rate: u32,
458 sample_size: u16,
459 channels: u16,
460 channel_mask: u32,
461 granularity: u32,
462 bytes_per_minute: u32,
463 total_bytes: u32,
464 edata_size: u32,
465 ileave_info: Option<InterleaveInfo>
466}
467
468fn skip_ra_metadata(src: &mut ByteReader) -> DemuxerResult<()> {
469 let title_len = src.read_byte()? as usize;
470 src.read_skip(title_len)?;
471 let author_len = src.read_byte()? as usize;
472 src.read_skip(author_len)?;
473 let copywrong_len = src.read_byte()? as usize;
474 src.read_skip(copywrong_len)?;
475 let comment_len = src.read_byte()? as usize;
476 src.read_skip(comment_len)?;
477 Ok(())
478}
479
480#[allow(unused_variables)]
481fn parse_aformat3(src: &mut ByteReader) -> DemuxerResult<RealAudioInfo> {
482 let start = src.tell();
483 let header_len = src.read_u16be()?;
484 validate!(header_len >= 24);
485 let flavor = src.read_u16be()?;
486 let granularity = src.read_u32be()?;
487 let bytes_per_minute = src.read_u32be()?;
488 let total_bytes = src.read_u32be()?;
489
490 skip_ra_metadata(src)?;
491
492 let _can_copy = src.read_byte()?;
493 let fcc_len = src.read_byte()?;
494 validate!(fcc_len == 4);
495 let fcc = src.read_u32be()?;
496
497 let end = src.tell();
498 validate!(end - start <= (header_len as u64) + 2);
499
500 Ok(RealAudioInfo {
501 fcc: fcc, sample_rate: 8000, sample_size: 16, channels: 1, channel_mask: 0,
502 granularity: granularity, bytes_per_minute: bytes_per_minute,
503 total_bytes: total_bytes, edata_size: 0,
504 ileave_info: None,
505 })
506}
507
508#[allow(unused_variables)]
509fn parse_aformat4(src: &mut ByteReader) -> DemuxerResult<RealAudioInfo> {
510 let start = src.tell();
511 src.read_skip(2)?; // zeroes
512 let id = src.read_u32be()?;
513 validate!(id == mktag!(b".ra4"));
514 let data_size = src.read_u32be()?;
515 let _ver4 = src.read_u16be()?; // should be 4
516 let header_size = src.read_u32be()?;
517 let _flavor = src.read_u16be()?;
518 let granularity = src.read_u32be()?;
519 let total_bytes = src.read_u32be()?;
520 let bytes_per_minute = src.read_u32be()?;
521 let _bytes_per_minute2 = src.read_u32be()?;
522 let ileave_factor = src.read_u16be()?;
523 let ileave_block_size = src.read_u16be()?;
524 let _user_data = src.read_u16be()?;
525 let sample_rate = src.read_u32be()?;
526 let sample_size = src.read_u32be()?;
527 let channels = src.read_u16be()?;
528 let interleaver_id_len = src.read_byte()?;
529 validate!(interleaver_id_len == 4);
530 let interleaver_id = src.read_u32be()?;
531 let fcc_len = src.read_byte()?;
532 validate!(fcc_len == 4);
533 let fcc = src.read_u32be()?;
534 let is_interleaved = src.read_byte()?;
535 let _can_copy = src.read_byte()?;
536 let _stream_type = src.read_byte()?;
537
538 skip_ra_metadata(src)?;
539
540 let end = src.tell();
541 validate!(end - start <= (header_size as u64) + 10);
542
543 let ileave_info = if is_interleaved != 0 {
544 Some(InterleaveInfo {
fe07b469
KS
545 id: interleaver_id, factor: ileave_factor, block_size: granularity as u16,
546 frame_size: ileave_block_size,
c19ce782
KS
547 })
548 } else {
549 None
550 };
551
552 Ok(RealAudioInfo {
553 fcc: fcc, sample_rate: sample_rate, sample_size: sample_size as u16, channels: channels, channel_mask: 0,
554 granularity: granularity, bytes_per_minute: bytes_per_minute,
555 total_bytes: total_bytes & 0xFFFFFF, edata_size: 0,
556 ileave_info: ileave_info,
557 })
558}
559
560#[allow(unused_variables)]
561fn parse_aformat5(src: &mut ByteReader) -> DemuxerResult<RealAudioInfo> {
562 let start = src.tell();
563 src.read_skip(2)?; // zeroes
564 let id = src.read_u32be()?;
565 validate!(id == mktag!(b".ra5"));
566 let data_size = src.read_u32be()?;
567 let _ver5 = src.read_u16be()?; // should be 5
568 let header_size = src.read_u32be()?;
569 let _flavor = src.read_u16be()?;
570 let granularity = src.read_u32be()?;
571 let total_bytes = src.read_u32be()?;
572 let bytes_per_minute = src.read_u32be()?;
573 let _bytes_per_minute2 = src.read_u32be()?;
574 let ileave_factor = src.read_u16be()?;
c19ce782 575 let frame_size = src.read_u16be()?;
6669c73b 576 let ileave_block_size = src.read_u16be()?;
c19ce782
KS
577 let user_data = src.read_u32be()?;
578 let _sample_rate1 = src.read_u16be()?;
579 let sample_rate = src.read_u32be()?;
580 let sample_size = src.read_u32be()?;
581 let channels = src.read_u16be()?;
582 let interleaver_id = src.read_u32be()?;
583 let fcc = src.read_u32be()?;
584 let is_interleaved = src.read_byte()?;
585 let _can_copy = src.read_byte()?;
586 let _stream_type = src.read_byte()?;
587 let has_ileave_pattern = src.read_byte()?;
588 if has_ileave_pattern != 0 {
589unimplemented!("ra5 interleave pattern");
590 }
591 let edata_size = src.read_u32be()?;
592
593 let end = src.tell();
594 validate!(end - start <= (header_size as u64) + 10);
595 src.read_skip((end as usize) - (header_size as usize))?;
596
597 let ileave_info = if is_interleaved != 0 {
598 Some(InterleaveInfo {
599 id: interleaver_id, factor: ileave_factor, block_size: ileave_block_size, frame_size: frame_size,
600 })
601 } else {
602 None
603 };
604
605 Ok(RealAudioInfo {
606 fcc: fcc, sample_rate: sample_rate, sample_size: sample_size as u16, channels: channels, channel_mask: 0,
607 granularity: granularity, bytes_per_minute: bytes_per_minute,
608 total_bytes: total_bytes & 0xFFFFFF, edata_size: edata_size,
609 ileave_info: ileave_info,
610 })
611}
612
ce52b3b5
KS
613const RMVB_HDR_SIZE: u32 = 18;
614const RMVB_PROP_SIZE: u32 = 50;
615const KEYFRAME_FLAG: u8 = 0x02;
616
617impl<'a> RealMediaDemuxer<'a> {
618 fn new(io: &'a mut ByteReader<'a>) -> Self {
619 RealMediaDemuxer {
620 src: io,
621 data_pos: 0,
622 num_packets: 0,
623 cur_packet: 0,
624 streams: Vec::new(),
625 str_ids: Vec::new(),
626 queued_pkts: Vec::new(),
627 slice_buf: Vec::new(),
628 }
629 }
630#[allow(unused_variables)]
631 fn read_header(&mut self, strmgr: &mut StreamManager) -> DemuxerResult<()> {
632 let (id, size, ver) = read_chunk(self.src)?;
633 validate!(id == mktag!(b".RMF"));
634 validate!(size >= RMVB_HDR_SIZE);
635 let fver = self.src.read_u32be()?;
636 validate!(fver <= 1);
637 let num_hdr = self.src.read_u32be()? as usize;
638 validate!(num_hdr >= 1);
639 if size > RMVB_HDR_SIZE {
640 self.src.read_skip((size - RMVB_HDR_SIZE) as usize)?;
641 }
642
643 let (id, size, ver) = read_chunk(self.src)?;
644 validate!(size >= RMVB_PROP_SIZE);
645 validate!(ver == 0);
646 let maxbr = self.src.read_u32be()?;
647 let avgbr = self.src.read_u32be()?;
648 let maxps = self.src.read_u32be()?;
649 let avgps = self.src.read_u32be()?;
650 let num_pkt = self.src.read_u32be()? as usize;
651 let duration = self.src.read_u32be()?;
652 let preroll = self.src.read_u32be()?;
653 let idx_off = self.src.read_u32be()?;
654 let data_off = self.src.read_u32be()?;
655 let num_streams = self.src.read_u16be()? as usize;
656 let flags = self.src.read_u16be()?;
657 if size > RMVB_PROP_SIZE {
658 self.src.read_skip((size - RMVB_PROP_SIZE) as usize)?;
659 }
660
661 for _ in 0..num_hdr {
c9aba47e
KS
662 if self.src.is_eof() {
663 //warn maybe?
664 break;
665 }
666 let res = self.parse_chunk(strmgr);
667 match res {
668 Ok(last) => { if last { break; } },
669 Err(DemuxerError::IOError) => { break; },
670 Err(etype) => { return Err(etype); },
671 };
ce52b3b5 672 }
c9aba47e 673//println!("now @ {:X} / {}", self.src.tell(), self.data_pos);
ce52b3b5
KS
674 validate!(self.data_pos > 0);
675 self.src.seek(SeekFrom::Start(self.data_pos))?;
676 let num_packets = self.src.read_u32be()?;
677 let next_data_hdr = self.src.read_u32be()?;
9f45e528 678 self.num_packets = if num_packets > 0 { num_packets } else { 0xFFFFFF };
ce52b3b5
KS
679 self.cur_packet = 0;
680 Ok(())
681 }
6132225f 682 fn parse_chunk(&mut self, strmgr: &mut StreamManager) -> DemuxerResult<bool> {
ce52b3b5
KS
683 let (id, size, ver) = read_chunk(self.src)?;
684 let end_pos = self.src.tell() - 10 + (size as u64);
685
686 validate!(ver == 0);
687 if id == mktag!(b"CONT") { self.parse_content_desc()?; }
688 else if id == mktag!(b"MDPR") { self.parse_mdpr(strmgr)?; }
689 else if id == mktag!(b"DATA") { if self.data_pos == 0 { self.data_pos = self.src.tell(); } }
690 else if id == mktag!(b"INDX") { /* do nothing for now */ }
6132225f 691 else if id == 0 { return Ok(true); }
ce52b3b5
KS
692 else { println!("unknown chunk type {:08X}", id); }
693
694 let cpos = self.src.tell();
695 if cpos < end_pos {
696 self.src.read_skip((end_pos - cpos) as usize)?;
697 }
6132225f 698 Ok(false)
ce52b3b5
KS
699 }
700#[allow(unused_variables)]
701 fn parse_content_desc(&mut self) -> DemuxerResult<()> {
702 let title_len = self.src.read_u16be()? as usize;
703 self.src.read_skip(title_len)?;
704 let author_len = self.src.read_u16be()? as usize;
705 self.src.read_skip(author_len)?;
706 let copywrong_len = self.src.read_u16be()? as usize;
707 self.src.read_skip(copywrong_len)?;
708 let comment_len = self.src.read_u16be()? as usize;
709 self.src.read_skip(comment_len)?;
710 Ok(())
711 }
712#[allow(unused_variables)]
713 fn parse_mdpr(&mut self, strmgr: &mut StreamManager) -> DemuxerResult<()> {
714 let stream_no = self.src.read_u16be()?;
715//todo check stream_no for duplicates
716 let maxbr = self.src.read_u32be()?;
717 let avgbr = self.src.read_u32be()?;
718 let maxps = self.src.read_u32be()?;
719 let avgps = self.src.read_u32be()?;
720 let start = self.src.read_u32be()?;
721 let preroll = self.src.read_u32be()?;
722 let duration = self.src.read_u32be()?;
723 let sname_size = self.src.read_byte()? as usize;
724 let sname = read_string_size(self.src, sname_size)?;
c9aba47e 725//println!("str #{} sname = {} pkts {}/{} start {} preroll {}", stream_no, sname, maxps, avgps, start, preroll);
ce52b3b5
KS
726 let mime_size = self.src.read_byte()? as usize;
727 let mime = read_string_size(self.src, mime_size)?;
c9aba47e 728//println!("mime = {}", mime);
ce52b3b5
KS
729 let edata_size = self.src.read_u32be()? as usize;
730 let edata: Option<Vec<u8>> = if edata_size == 0 { None } else {
731 let mut edvec: Vec<u8> = Vec::with_capacity(edata_size);
732 edvec.resize(edata_size, 0);
733 self.src.read_buf(&mut edvec)?;
734 Some(edvec)
735 };
736 self.str_ids.push(stream_no);
737 if edata_size > 8 {
738 if let Some(edata_) = edata {
739 let mut mr = MemoryReader::new_read(edata_.as_slice());
740 let mut src = ByteReader::new(&mut mr);
741
742 let tag = src.read_u32be()?;
743 let tag2 = src.peek_u32be()?;
c9aba47e 744//println!("tag1 {:X} tag2 {:X}", tag, tag2);
ce52b3b5 745 if tag == mktag!('.', 'r', 'a', 0xFD) {
c19ce782
KS
746 let ver = src.read_u16be()?;
747 let ainfo = match ver {
748 3 => {
749 parse_aformat3(&mut src)?
750 },
751 4 => {
752 parse_aformat4(&mut src)?
753 },
754 5 => {
755 parse_aformat5(&mut src)?
756 },
757 _ => {
758 println!("unknown version {}", ver);
759 return Err(DemuxerError::InvalidData);
760 },
761 };
762println!(" got ainfo {:?}", ainfo);
763 let cname = find_codec_name(RM_AUDIO_CODEC_REGISTER, ainfo.fcc);
764 let srate = ainfo.sample_rate;
765 let soniton = NASoniton::new(ainfo.sample_size as u8, SONITON_FLAG_SIGNED);
766 let ahdr = NAAudioInfo::new(srate, ainfo.channels as u8, soniton, 1);
767 let extradata = if ainfo.edata_size == 0 {
768 None
769 } else {
770 let eslice = &edata_[(src.tell() as usize)..];
771 Some(eslice.to_vec())
772 };
773 let nainfo = NACodecInfo::new(cname, NACodecTypeInfo::Audio(ahdr), extradata);
774 let res = strmgr.add_stream(NAStream::new(StreamType::Audio, stream_no as u32, nainfo, 1, srate));
ce52b3b5
KS
775 if res.is_none() { return Err(MemoryError); }
776
c19ce782 777 let astr = RMAudioStream::new(ainfo.ileave_info);
ce52b3b5
KS
778 self.streams.push(RMStreamType::Audio(astr));
779 } else if ((tag2 == mktag!('V', 'I', 'D', 'O')) || (tag2 == mktag!('I', 'M', 'A', 'G'))) && ((tag as usize) <= edata_size) {
780 src.read_skip(4)?;
781 let fcc = src.read_u32be()?;
782 let width = src.read_u16be()? as usize;
783 let height = src.read_u16be()? as usize;
784 let bpp = src.read_u16be()?;
785 let pad_w = src.read_u16be()?;
786 let pad_h = src.read_u16be()?;
787 let fps;
788 if tag2 == mktag!('V', 'I', 'D', 'O') {
789 fps = src.read_u32be()?;
790 } else {
791 fps = 0x10000;
792 }
793 let extradata: Option<Vec<u8>>;
794 if src.left() > 0 {
795 let eslice = &edata_[(src.tell() as usize)..];
796 extradata = Some(eslice.to_vec());
797 } else {
798 extradata = None;
799 }
800 let cname = find_codec_name(RM_VIDEO_CODEC_REGISTER, fcc);
801
802 let vhdr = NAVideoInfo::new(width, height, false, RGB24_FORMAT);
803 let vinfo = NACodecInfo::new(cname, NACodecTypeInfo::Video(vhdr), extradata);
804 let res = strmgr.add_stream(NAStream::new(StreamType::Video, stream_no as u32, vinfo, 0x10000, fps));
805 if res.is_none() { return Err(DemuxerError::MemoryError); }
806
807 let vstr = RMVideoStream::new();
808 self.streams.push(RMStreamType::Video(vstr));
c19ce782
KS
809 } else if tag == mktag!(b"LSD:") {
810 let extradata = Some(edata_.to_vec());
811
812 src.read_skip(4)?; //version
813 let channels = src.read_u16be()?;
814 let samp_size = src.read_u16be()?;
815 let sample_rate = src.read_u32be()?;
816
817 println!("LSD sr {}, {} ch", sample_rate, channels);
818 let soniton = NASoniton::new(samp_size as u8, SONITON_FLAG_SIGNED);
819 let ahdr = NAAudioInfo::new(sample_rate, channels as u8, soniton, 1);
820 let nainfo = NACodecInfo::new("ralf", NACodecTypeInfo::Audio(ahdr), extradata);
821 let res = strmgr.add_stream(NAStream::new(StreamType::Audio, stream_no as u32, nainfo, 1, sample_rate));
822 if res.is_none() { return Err(MemoryError); }
823 let astr = RMAudioStream::new(None);
824 self.streams.push(RMStreamType::Audio(astr));
ce52b3b5
KS
825 } else {
826 self.streams.push(RMStreamType::Logical);
827 }
828 }
829 } else {
830 self.streams.push(RMStreamType::Unknown);
831 }
832
833 Ok(())
834 }
835/*#[allow(unused_variables)]
836 fn read_pkt_header(&mut self) -> DemuxerResult<()> {
837 let ver = self.src.read_u16be()?;
838 validate!(ver <= 1);
839 let str_no = self.src.read_u16be()?;
840 let timestamp = self.src.read_u32be()?;
841 if ver == 0 {
842 let pkt_group = self.src.read_byte()?;
843 let pkt_flags = self.src.read_byte()?;
844 } else {
845 let asm_rule = self.src.read_u16be()?;
846 let asm_flags = self.src.read_byte()?;
847 }
848 Ok(())
849 }*/
850}
851
852fn read_string(src: &mut ByteReader) -> DemuxerResult<String> {
853 let mut vec: Vec<u8> = Vec::new();
854 loop {
855 let c = src.read_byte()?;
856 if c == 0 { break; }
857 vec.push(c);
858 }
859 let str = String::from_utf8(vec);
860 if str.is_ok() {
861 Ok(str.unwrap())
862 } else {
863 Ok(String::new())
864 }
865}
866
867fn read_string_size(src: &mut ByteReader, size: usize) -> DemuxerResult<String> {
868 let mut vec: Vec<u8> = Vec::new();
869 for _ in 0..size {
870 let c = src.read_byte()?;
871 vec.push(c);
872 }
873 let str = String::from_utf8(vec);
874 if str.is_ok() {
875 Ok(str.unwrap())
876 } else {
877 Ok(String::new())
878 }
879}
880
881#[allow(dead_code)]
882#[allow(unused_variables)]
883fn parse_rm_stream(io: &mut ByteReader) -> DemuxerResult<NAStream> {
884 let mimetype = read_string(io)?;
885 let strname = read_string(io)?;
886 let strnum = io.read_u32le()?;
887 let maxbr = io.read_u32le()?;
888 let avgbr = io.read_u32le()?;
889 let maxsize = io.read_u32le()?;
890 let avgsize = io.read_u32le()?;
891 let duration = io.read_u32le()?;
892 let preroll = io.read_u32le()?;
893 let start = io.read_u32le()?;
894 let edatalen = io.read_u32le()? as usize;
895 let mut edata: Vec<u8> = Vec::with_capacity(edatalen);
896 edata.resize(edatalen, 0);
897 io.read_buf(&mut edata)?;
898 let numprops = io.read_u32le()? as usize;
899 //read properties
900 unimplemented!();
901}
902
903#[allow(dead_code)]
904#[allow(unused_variables)]
905fn read_ra_vbr_stream(io: &mut ByteReader) -> DemuxerResult<NAPacket> {
906 let hdrsizesize = io.read_u16le()?;
907 let num_entries = (hdrsizesize / 16) as usize;
908 let mut sizes: Vec<usize> = Vec::with_capacity(num_entries);
909 for _ in 0..num_entries {
910 let sz = io.read_u16le()? as usize;
911 sizes.push(sz);
912 }
913 for i in 0..num_entries {
914//read packet of sizes[i]
915 }
916 unimplemented!();
917}
918
919//todo interleavers
920
921//todo opaque data
922
923
924static RM_VIDEO_CODEC_REGISTER: &'static [(&[u8;4], &str)] = &[
925 (b"RV10", "realvideo1"),
926 (b"RV20", "realvideo2"),
927 (b"RVTR", "realvideo2"),
928 (b"RV30", "realvideo3"),
929 (b"RV40", "realvideo4"),
750b299c 930 (b"CLV1", "clearvideo_rm"),
ce52b3b5
KS
931];
932
b1ef37ee 933#[allow(dead_code)]
ce52b3b5
KS
934static RM_AUDIO_CODEC_REGISTER: &'static [(&[u8;4], &str)] = &[
935 (b"lpcJ", "ra14.4"),
936 (b"28_8", "ra28.8"),
937 (b"cook", "cook"),
938 (b"dnet", "ac3"),
939 (b"sipr", "sipro"),
940 (b"atrc", "atrac3"),
941 (b"LSD:", "ralf"),
942 (b"raac", "aac"),
943 (b"racp", "aac"),
944];
945
946pub struct RealMediaDemuxerCreator { }
947
948impl DemuxerCreator for RealMediaDemuxerCreator {
949 fn new_demuxer<'a>(&self, br: &'a mut ByteReader<'a>) -> Box<DemuxCore<'a> + 'a> {
950 Box::new(RealMediaDemuxer::new(br))
951 }
952 fn get_name(&self) -> &'static str { "realmedia" }
953}
954
955#[cfg(test)]
956mod test {
957 use super::*;
958 use std::fs::File;
959
960 #[test]
961 fn test_rm_demux() {
962 let mut file =
963 File::open("assets/RV/rv10_dnet_640x352_realvideo_encoder_4.0.rm").unwrap();
964// File::open("assets/RV/rv20_cook_640x352_realproducer_plus_8.51.rm").unwrap();
965// File::open("assets/RV/rv20_svt_atrc_640x352_realproducer_plus_8.51.rm").unwrap();
966// File::open("assets/RV/rv30_atrc_384x208_realproducer_plus_8.51.rm").unwrap();
967// File::open("assets/RV/rv30_chroma_drift.rm").unwrap();
968// File::open("assets/RV/rv30_weighted_mc.rm").unwrap();
969// File::open("assets/RV/rv40_weighted_mc.rmvb").unwrap();
970// File::open("assets/RV/rv40_weighted_mc_2.rmvb").unwrap();
971// File::open("assets/RV/clv1_sipr_384x208_realvideo_encoder_4.0.rm").unwrap();
972// File::open("assets/RV/luckynight.rmvb").unwrap();
973// File::open("assets/RV/rv40_ralf.rmvb").unwrap();
974 let mut fr = FileReader::new_read(&mut file);
975 let mut br = ByteReader::new(&mut fr);
976 let mut dmx = RealMediaDemuxer::new(&mut br);
977 let mut sm = StreamManager::new();
978 dmx.open(&mut sm).unwrap();
979
980 loop {
981 let pktres = dmx.get_frame(&mut sm);
982 if let Err(e) = pktres {
983 if e == DemuxerError::EOF { break; }
984 panic!("error");
985 }
986 let pkt = pktres.unwrap();
987 println!("Got {}", pkt);
988 }
41f11b2b 989//panic!("the end");
ce52b3b5
KS
990 }
991}