rmdec: more deinterleavers work
[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;
c9aba47e 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())?;
378 vstr.add_slice(packet_num as usize, self.slice_buf.as_slice());
379
380 while self.src.tell() < pos + (payload_size as u64) {
381 let res = read_multiple_frame(self.src, stream.clone(), false, false);
382 if res.is_err() { break; }
383 self.queued_pkts.push(res.unwrap());
384 }
385 self.queued_pkts.reverse();
386 let (tb_num, tb_den) = stream.get_timebase();
387 let ts = NATimeInfo::new(Some(ts as u64), None, None, tb_num, tb_den);
388 let pkt = NAPacket::new(stream, ts, keyframe, vstr.get_frame_data());
389 Ok(pkt)
390 },
391 _ => { // multiple frames
c9aba47e 392//println!(" mode 3");
ce52b3b5
KS
393 let res = read_multiple_frame(self.src, stream.clone(), keyframe, true);
394 if res.is_err() { return res; }
395 while self.src.tell() < pos + (payload_size as u64) {
396 let res = read_multiple_frame(self.src, stream.clone(), false, false);
397 if res.is_err() { break; }
398 self.queued_pkts.push(res.unwrap());
399 }
400 self.queued_pkts.reverse();
401 res
402 },
403 }
404 },
405 RMStreamType::Audio(ref mut astr) => {
fe07b469
KS
406 let ret = astr.read_apackets(&mut self.queued_pkts, &mut self.src, stream, ts, keyframe, payload_size);
407 if let Err(DemuxerError::TryAgain) = ret {
408 continue;
409 }
410 ret
ce52b3b5
KS
411 },
412 _ => {
413// self.src.read_skip(payload_size)?;
414 Err(DemuxerError::InvalidData)
415 },
416 };
417 return result;
418 }
419 }
420
421 #[allow(unused_variables)]
422 fn seek(&mut self, time: u64) -> DemuxerResult<()> {
423 Err(NotImplemented)
424 }
425}
426
427fn read_chunk(src: &mut ByteReader) -> DemuxerResult<(u32, u32, u16)> {
428 let id = src.read_u32be()?;
6132225f 429if id == 0 { return Ok((0, 0, 0)); }
ce52b3b5
KS
430 let size = src.read_u32be()?;
431 validate!(size >= 10);
432 let ver = src.read_u16be()?;
433 validate!(ver <= 1);
434 Ok((id, size, ver))
435}
436
c19ce782
KS
437#[derive(Clone,Copy,Debug)]
438struct InterleaveInfo {
439 id: u32,
440 factor: u16,
441 block_size: u16,
442 frame_size: u16,
443}
444
445#[derive(Clone,Copy,Debug)]
446struct RealAudioInfo {
447 fcc: u32,
448 sample_rate: u32,
449 sample_size: u16,
450 channels: u16,
451 channel_mask: u32,
452 granularity: u32,
453 bytes_per_minute: u32,
454 total_bytes: u32,
455 edata_size: u32,
456 ileave_info: Option<InterleaveInfo>
457}
458
459fn skip_ra_metadata(src: &mut ByteReader) -> DemuxerResult<()> {
460 let title_len = src.read_byte()? as usize;
461 src.read_skip(title_len)?;
462 let author_len = src.read_byte()? as usize;
463 src.read_skip(author_len)?;
464 let copywrong_len = src.read_byte()? as usize;
465 src.read_skip(copywrong_len)?;
466 let comment_len = src.read_byte()? as usize;
467 src.read_skip(comment_len)?;
468 Ok(())
469}
470
471#[allow(unused_variables)]
472fn parse_aformat3(src: &mut ByteReader) -> DemuxerResult<RealAudioInfo> {
473 let start = src.tell();
474 let header_len = src.read_u16be()?;
475 validate!(header_len >= 24);
476 let flavor = src.read_u16be()?;
477 let granularity = src.read_u32be()?;
478 let bytes_per_minute = src.read_u32be()?;
479 let total_bytes = src.read_u32be()?;
480
481 skip_ra_metadata(src)?;
482
483 let _can_copy = src.read_byte()?;
484 let fcc_len = src.read_byte()?;
485 validate!(fcc_len == 4);
486 let fcc = src.read_u32be()?;
487
488 let end = src.tell();
489 validate!(end - start <= (header_len as u64) + 2);
490
491 Ok(RealAudioInfo {
492 fcc: fcc, sample_rate: 8000, sample_size: 16, channels: 1, channel_mask: 0,
493 granularity: granularity, bytes_per_minute: bytes_per_minute,
494 total_bytes: total_bytes, edata_size: 0,
495 ileave_info: None,
496 })
497}
498
499#[allow(unused_variables)]
500fn parse_aformat4(src: &mut ByteReader) -> DemuxerResult<RealAudioInfo> {
501 let start = src.tell();
502 src.read_skip(2)?; // zeroes
503 let id = src.read_u32be()?;
504 validate!(id == mktag!(b".ra4"));
505 let data_size = src.read_u32be()?;
506 let _ver4 = src.read_u16be()?; // should be 4
507 let header_size = src.read_u32be()?;
508 let _flavor = src.read_u16be()?;
509 let granularity = src.read_u32be()?;
510 let total_bytes = src.read_u32be()?;
511 let bytes_per_minute = src.read_u32be()?;
512 let _bytes_per_minute2 = src.read_u32be()?;
513 let ileave_factor = src.read_u16be()?;
514 let ileave_block_size = src.read_u16be()?;
515 let _user_data = src.read_u16be()?;
516 let sample_rate = src.read_u32be()?;
517 let sample_size = src.read_u32be()?;
518 let channels = src.read_u16be()?;
519 let interleaver_id_len = src.read_byte()?;
520 validate!(interleaver_id_len == 4);
521 let interleaver_id = src.read_u32be()?;
522 let fcc_len = src.read_byte()?;
523 validate!(fcc_len == 4);
524 let fcc = src.read_u32be()?;
525 let is_interleaved = src.read_byte()?;
526 let _can_copy = src.read_byte()?;
527 let _stream_type = src.read_byte()?;
528
529 skip_ra_metadata(src)?;
530
531 let end = src.tell();
532 validate!(end - start <= (header_size as u64) + 10);
533
534 let ileave_info = if is_interleaved != 0 {
535 Some(InterleaveInfo {
fe07b469
KS
536 id: interleaver_id, factor: ileave_factor, block_size: granularity as u16,
537 frame_size: ileave_block_size,
c19ce782
KS
538 })
539 } else {
540 None
541 };
542
543 Ok(RealAudioInfo {
544 fcc: fcc, sample_rate: sample_rate, sample_size: sample_size as u16, channels: channels, channel_mask: 0,
545 granularity: granularity, bytes_per_minute: bytes_per_minute,
546 total_bytes: total_bytes & 0xFFFFFF, edata_size: 0,
547 ileave_info: ileave_info,
548 })
549}
550
551#[allow(unused_variables)]
552fn parse_aformat5(src: &mut ByteReader) -> DemuxerResult<RealAudioInfo> {
553 let start = src.tell();
554 src.read_skip(2)?; // zeroes
555 let id = src.read_u32be()?;
556 validate!(id == mktag!(b".ra5"));
557 let data_size = src.read_u32be()?;
558 let _ver5 = src.read_u16be()?; // should be 5
559 let header_size = src.read_u32be()?;
560 let _flavor = src.read_u16be()?;
561 let granularity = src.read_u32be()?;
562 let total_bytes = src.read_u32be()?;
563 let bytes_per_minute = src.read_u32be()?;
564 let _bytes_per_minute2 = src.read_u32be()?;
565 let ileave_factor = src.read_u16be()?;
c19ce782 566 let frame_size = src.read_u16be()?;
6669c73b 567 let ileave_block_size = src.read_u16be()?;
c19ce782
KS
568 let user_data = src.read_u32be()?;
569 let _sample_rate1 = src.read_u16be()?;
570 let sample_rate = src.read_u32be()?;
571 let sample_size = src.read_u32be()?;
572 let channels = src.read_u16be()?;
573 let interleaver_id = src.read_u32be()?;
574 let fcc = src.read_u32be()?;
575 let is_interleaved = src.read_byte()?;
576 let _can_copy = src.read_byte()?;
577 let _stream_type = src.read_byte()?;
578 let has_ileave_pattern = src.read_byte()?;
579 if has_ileave_pattern != 0 {
580unimplemented!("ra5 interleave pattern");
581 }
582 let edata_size = src.read_u32be()?;
583
584 let end = src.tell();
585 validate!(end - start <= (header_size as u64) + 10);
586 src.read_skip((end as usize) - (header_size as usize))?;
587
588 let ileave_info = if is_interleaved != 0 {
589 Some(InterleaveInfo {
590 id: interleaver_id, factor: ileave_factor, block_size: ileave_block_size, frame_size: frame_size,
591 })
592 } else {
593 None
594 };
595
596 Ok(RealAudioInfo {
597 fcc: fcc, sample_rate: sample_rate, sample_size: sample_size as u16, channels: channels, channel_mask: 0,
598 granularity: granularity, bytes_per_minute: bytes_per_minute,
599 total_bytes: total_bytes & 0xFFFFFF, edata_size: edata_size,
600 ileave_info: ileave_info,
601 })
602}
603
ce52b3b5
KS
604const RMVB_HDR_SIZE: u32 = 18;
605const RMVB_PROP_SIZE: u32 = 50;
606const KEYFRAME_FLAG: u8 = 0x02;
607
608impl<'a> RealMediaDemuxer<'a> {
609 fn new(io: &'a mut ByteReader<'a>) -> Self {
610 RealMediaDemuxer {
611 src: io,
612 data_pos: 0,
613 num_packets: 0,
614 cur_packet: 0,
615 streams: Vec::new(),
616 str_ids: Vec::new(),
617 queued_pkts: Vec::new(),
618 slice_buf: Vec::new(),
619 }
620 }
621#[allow(unused_variables)]
622 fn read_header(&mut self, strmgr: &mut StreamManager) -> DemuxerResult<()> {
623 let (id, size, ver) = read_chunk(self.src)?;
624 validate!(id == mktag!(b".RMF"));
625 validate!(size >= RMVB_HDR_SIZE);
626 let fver = self.src.read_u32be()?;
627 validate!(fver <= 1);
628 let num_hdr = self.src.read_u32be()? as usize;
629 validate!(num_hdr >= 1);
630 if size > RMVB_HDR_SIZE {
631 self.src.read_skip((size - RMVB_HDR_SIZE) as usize)?;
632 }
633
634 let (id, size, ver) = read_chunk(self.src)?;
635 validate!(size >= RMVB_PROP_SIZE);
636 validate!(ver == 0);
637 let maxbr = self.src.read_u32be()?;
638 let avgbr = self.src.read_u32be()?;
639 let maxps = self.src.read_u32be()?;
640 let avgps = self.src.read_u32be()?;
641 let num_pkt = self.src.read_u32be()? as usize;
642 let duration = self.src.read_u32be()?;
643 let preroll = self.src.read_u32be()?;
644 let idx_off = self.src.read_u32be()?;
645 let data_off = self.src.read_u32be()?;
646 let num_streams = self.src.read_u16be()? as usize;
647 let flags = self.src.read_u16be()?;
648 if size > RMVB_PROP_SIZE {
649 self.src.read_skip((size - RMVB_PROP_SIZE) as usize)?;
650 }
651
652 for _ in 0..num_hdr {
c9aba47e
KS
653 if self.src.is_eof() {
654 //warn maybe?
655 break;
656 }
657 let res = self.parse_chunk(strmgr);
658 match res {
659 Ok(last) => { if last { break; } },
660 Err(DemuxerError::IOError) => { break; },
661 Err(etype) => { return Err(etype); },
662 };
ce52b3b5 663 }
c9aba47e 664//println!("now @ {:X} / {}", self.src.tell(), self.data_pos);
ce52b3b5
KS
665 validate!(self.data_pos > 0);
666 self.src.seek(SeekFrom::Start(self.data_pos))?;
667 let num_packets = self.src.read_u32be()?;
668 let next_data_hdr = self.src.read_u32be()?;
669 self.num_packets = num_packets;
670 self.cur_packet = 0;
671 Ok(())
672 }
6132225f 673 fn parse_chunk(&mut self, strmgr: &mut StreamManager) -> DemuxerResult<bool> {
ce52b3b5
KS
674 let (id, size, ver) = read_chunk(self.src)?;
675 let end_pos = self.src.tell() - 10 + (size as u64);
676
677 validate!(ver == 0);
678 if id == mktag!(b"CONT") { self.parse_content_desc()?; }
679 else if id == mktag!(b"MDPR") { self.parse_mdpr(strmgr)?; }
680 else if id == mktag!(b"DATA") { if self.data_pos == 0 { self.data_pos = self.src.tell(); } }
681 else if id == mktag!(b"INDX") { /* do nothing for now */ }
6132225f 682 else if id == 0 { return Ok(true); }
ce52b3b5
KS
683 else { println!("unknown chunk type {:08X}", id); }
684
685 let cpos = self.src.tell();
686 if cpos < end_pos {
687 self.src.read_skip((end_pos - cpos) as usize)?;
688 }
6132225f 689 Ok(false)
ce52b3b5
KS
690 }
691#[allow(unused_variables)]
692 fn parse_content_desc(&mut self) -> DemuxerResult<()> {
693 let title_len = self.src.read_u16be()? as usize;
694 self.src.read_skip(title_len)?;
695 let author_len = self.src.read_u16be()? as usize;
696 self.src.read_skip(author_len)?;
697 let copywrong_len = self.src.read_u16be()? as usize;
698 self.src.read_skip(copywrong_len)?;
699 let comment_len = self.src.read_u16be()? as usize;
700 self.src.read_skip(comment_len)?;
701 Ok(())
702 }
703#[allow(unused_variables)]
704 fn parse_mdpr(&mut self, strmgr: &mut StreamManager) -> DemuxerResult<()> {
705 let stream_no = self.src.read_u16be()?;
706//todo check stream_no for duplicates
707 let maxbr = self.src.read_u32be()?;
708 let avgbr = self.src.read_u32be()?;
709 let maxps = self.src.read_u32be()?;
710 let avgps = self.src.read_u32be()?;
711 let start = self.src.read_u32be()?;
712 let preroll = self.src.read_u32be()?;
713 let duration = self.src.read_u32be()?;
714 let sname_size = self.src.read_byte()? as usize;
715 let sname = read_string_size(self.src, sname_size)?;
c9aba47e 716//println!("str #{} sname = {} pkts {}/{} start {} preroll {}", stream_no, sname, maxps, avgps, start, preroll);
ce52b3b5
KS
717 let mime_size = self.src.read_byte()? as usize;
718 let mime = read_string_size(self.src, mime_size)?;
c9aba47e 719//println!("mime = {}", mime);
ce52b3b5
KS
720 let edata_size = self.src.read_u32be()? as usize;
721 let edata: Option<Vec<u8>> = if edata_size == 0 { None } else {
722 let mut edvec: Vec<u8> = Vec::with_capacity(edata_size);
723 edvec.resize(edata_size, 0);
724 self.src.read_buf(&mut edvec)?;
725 Some(edvec)
726 };
727 self.str_ids.push(stream_no);
728 if edata_size > 8 {
729 if let Some(edata_) = edata {
730 let mut mr = MemoryReader::new_read(edata_.as_slice());
731 let mut src = ByteReader::new(&mut mr);
732
733 let tag = src.read_u32be()?;
734 let tag2 = src.peek_u32be()?;
c9aba47e 735//println!("tag1 {:X} tag2 {:X}", tag, tag2);
ce52b3b5 736 if tag == mktag!('.', 'r', 'a', 0xFD) {
c19ce782
KS
737 let ver = src.read_u16be()?;
738 let ainfo = match ver {
739 3 => {
740 parse_aformat3(&mut src)?
741 },
742 4 => {
743 parse_aformat4(&mut src)?
744 },
745 5 => {
746 parse_aformat5(&mut src)?
747 },
748 _ => {
749 println!("unknown version {}", ver);
750 return Err(DemuxerError::InvalidData);
751 },
752 };
753println!(" got ainfo {:?}", ainfo);
754 let cname = find_codec_name(RM_AUDIO_CODEC_REGISTER, ainfo.fcc);
755 let srate = ainfo.sample_rate;
756 let soniton = NASoniton::new(ainfo.sample_size as u8, SONITON_FLAG_SIGNED);
757 let ahdr = NAAudioInfo::new(srate, ainfo.channels as u8, soniton, 1);
758 let extradata = if ainfo.edata_size == 0 {
759 None
760 } else {
761 let eslice = &edata_[(src.tell() as usize)..];
762 Some(eslice.to_vec())
763 };
764 let nainfo = NACodecInfo::new(cname, NACodecTypeInfo::Audio(ahdr), extradata);
765 let res = strmgr.add_stream(NAStream::new(StreamType::Audio, stream_no as u32, nainfo, 1, srate));
ce52b3b5
KS
766 if res.is_none() { return Err(MemoryError); }
767
c19ce782 768 let astr = RMAudioStream::new(ainfo.ileave_info);
ce52b3b5
KS
769 self.streams.push(RMStreamType::Audio(astr));
770 } else if ((tag2 == mktag!('V', 'I', 'D', 'O')) || (tag2 == mktag!('I', 'M', 'A', 'G'))) && ((tag as usize) <= edata_size) {
771 src.read_skip(4)?;
772 let fcc = src.read_u32be()?;
773 let width = src.read_u16be()? as usize;
774 let height = src.read_u16be()? as usize;
775 let bpp = src.read_u16be()?;
776 let pad_w = src.read_u16be()?;
777 let pad_h = src.read_u16be()?;
778 let fps;
779 if tag2 == mktag!('V', 'I', 'D', 'O') {
780 fps = src.read_u32be()?;
781 } else {
782 fps = 0x10000;
783 }
784 let extradata: Option<Vec<u8>>;
785 if src.left() > 0 {
786 let eslice = &edata_[(src.tell() as usize)..];
787 extradata = Some(eslice.to_vec());
788 } else {
789 extradata = None;
790 }
791 let cname = find_codec_name(RM_VIDEO_CODEC_REGISTER, fcc);
792
793 let vhdr = NAVideoInfo::new(width, height, false, RGB24_FORMAT);
794 let vinfo = NACodecInfo::new(cname, NACodecTypeInfo::Video(vhdr), extradata);
795 let res = strmgr.add_stream(NAStream::new(StreamType::Video, stream_no as u32, vinfo, 0x10000, fps));
796 if res.is_none() { return Err(DemuxerError::MemoryError); }
797
798 let vstr = RMVideoStream::new();
799 self.streams.push(RMStreamType::Video(vstr));
c19ce782
KS
800 } else if tag == mktag!(b"LSD:") {
801 let extradata = Some(edata_.to_vec());
802
803 src.read_skip(4)?; //version
804 let channels = src.read_u16be()?;
805 let samp_size = src.read_u16be()?;
806 let sample_rate = src.read_u32be()?;
807
808 println!("LSD sr {}, {} ch", sample_rate, channels);
809 let soniton = NASoniton::new(samp_size as u8, SONITON_FLAG_SIGNED);
810 let ahdr = NAAudioInfo::new(sample_rate, channels as u8, soniton, 1);
811 let nainfo = NACodecInfo::new("ralf", NACodecTypeInfo::Audio(ahdr), extradata);
812 let res = strmgr.add_stream(NAStream::new(StreamType::Audio, stream_no as u32, nainfo, 1, sample_rate));
813 if res.is_none() { return Err(MemoryError); }
814 let astr = RMAudioStream::new(None);
815 self.streams.push(RMStreamType::Audio(astr));
ce52b3b5
KS
816 } else {
817 self.streams.push(RMStreamType::Logical);
818 }
819 }
820 } else {
821 self.streams.push(RMStreamType::Unknown);
822 }
823
824 Ok(())
825 }
826/*#[allow(unused_variables)]
827 fn read_pkt_header(&mut self) -> DemuxerResult<()> {
828 let ver = self.src.read_u16be()?;
829 validate!(ver <= 1);
830 let str_no = self.src.read_u16be()?;
831 let timestamp = self.src.read_u32be()?;
832 if ver == 0 {
833 let pkt_group = self.src.read_byte()?;
834 let pkt_flags = self.src.read_byte()?;
835 } else {
836 let asm_rule = self.src.read_u16be()?;
837 let asm_flags = self.src.read_byte()?;
838 }
839 Ok(())
840 }*/
841}
842
843fn read_string(src: &mut ByteReader) -> DemuxerResult<String> {
844 let mut vec: Vec<u8> = Vec::new();
845 loop {
846 let c = src.read_byte()?;
847 if c == 0 { break; }
848 vec.push(c);
849 }
850 let str = String::from_utf8(vec);
851 if str.is_ok() {
852 Ok(str.unwrap())
853 } else {
854 Ok(String::new())
855 }
856}
857
858fn read_string_size(src: &mut ByteReader, size: usize) -> DemuxerResult<String> {
859 let mut vec: Vec<u8> = Vec::new();
860 for _ in 0..size {
861 let c = src.read_byte()?;
862 vec.push(c);
863 }
864 let str = String::from_utf8(vec);
865 if str.is_ok() {
866 Ok(str.unwrap())
867 } else {
868 Ok(String::new())
869 }
870}
871
872#[allow(dead_code)]
873#[allow(unused_variables)]
874fn parse_rm_stream(io: &mut ByteReader) -> DemuxerResult<NAStream> {
875 let mimetype = read_string(io)?;
876 let strname = read_string(io)?;
877 let strnum = io.read_u32le()?;
878 let maxbr = io.read_u32le()?;
879 let avgbr = io.read_u32le()?;
880 let maxsize = io.read_u32le()?;
881 let avgsize = io.read_u32le()?;
882 let duration = io.read_u32le()?;
883 let preroll = io.read_u32le()?;
884 let start = io.read_u32le()?;
885 let edatalen = io.read_u32le()? as usize;
886 let mut edata: Vec<u8> = Vec::with_capacity(edatalen);
887 edata.resize(edatalen, 0);
888 io.read_buf(&mut edata)?;
889 let numprops = io.read_u32le()? as usize;
890 //read properties
891 unimplemented!();
892}
893
894#[allow(dead_code)]
895#[allow(unused_variables)]
896fn read_ra_vbr_stream(io: &mut ByteReader) -> DemuxerResult<NAPacket> {
897 let hdrsizesize = io.read_u16le()?;
898 let num_entries = (hdrsizesize / 16) as usize;
899 let mut sizes: Vec<usize> = Vec::with_capacity(num_entries);
900 for _ in 0..num_entries {
901 let sz = io.read_u16le()? as usize;
902 sizes.push(sz);
903 }
904 for i in 0..num_entries {
905//read packet of sizes[i]
906 }
907 unimplemented!();
908}
909
910//todo interleavers
911
912//todo opaque data
913
914
915static RM_VIDEO_CODEC_REGISTER: &'static [(&[u8;4], &str)] = &[
916 (b"RV10", "realvideo1"),
917 (b"RV20", "realvideo2"),
918 (b"RVTR", "realvideo2"),
919 (b"RV30", "realvideo3"),
920 (b"RV40", "realvideo4"),
750b299c 921 (b"CLV1", "clearvideo_rm"),
ce52b3b5
KS
922];
923
b1ef37ee 924#[allow(dead_code)]
ce52b3b5
KS
925static RM_AUDIO_CODEC_REGISTER: &'static [(&[u8;4], &str)] = &[
926 (b"lpcJ", "ra14.4"),
927 (b"28_8", "ra28.8"),
928 (b"cook", "cook"),
929 (b"dnet", "ac3"),
930 (b"sipr", "sipro"),
931 (b"atrc", "atrac3"),
932 (b"LSD:", "ralf"),
933 (b"raac", "aac"),
934 (b"racp", "aac"),
935];
936
937pub struct RealMediaDemuxerCreator { }
938
939impl DemuxerCreator for RealMediaDemuxerCreator {
940 fn new_demuxer<'a>(&self, br: &'a mut ByteReader<'a>) -> Box<DemuxCore<'a> + 'a> {
941 Box::new(RealMediaDemuxer::new(br))
942 }
943 fn get_name(&self) -> &'static str { "realmedia" }
944}
945
946#[cfg(test)]
947mod test {
948 use super::*;
949 use std::fs::File;
950
951 #[test]
952 fn test_rm_demux() {
953 let mut file =
954 File::open("assets/RV/rv10_dnet_640x352_realvideo_encoder_4.0.rm").unwrap();
955// File::open("assets/RV/rv20_cook_640x352_realproducer_plus_8.51.rm").unwrap();
956// File::open("assets/RV/rv20_svt_atrc_640x352_realproducer_plus_8.51.rm").unwrap();
957// File::open("assets/RV/rv30_atrc_384x208_realproducer_plus_8.51.rm").unwrap();
958// File::open("assets/RV/rv30_chroma_drift.rm").unwrap();
959// File::open("assets/RV/rv30_weighted_mc.rm").unwrap();
960// File::open("assets/RV/rv40_weighted_mc.rmvb").unwrap();
961// File::open("assets/RV/rv40_weighted_mc_2.rmvb").unwrap();
962// File::open("assets/RV/clv1_sipr_384x208_realvideo_encoder_4.0.rm").unwrap();
963// File::open("assets/RV/luckynight.rmvb").unwrap();
964// File::open("assets/RV/rv40_ralf.rmvb").unwrap();
965 let mut fr = FileReader::new_read(&mut file);
966 let mut br = ByteReader::new(&mut fr);
967 let mut dmx = RealMediaDemuxer::new(&mut br);
968 let mut sm = StreamManager::new();
969 dmx.open(&mut sm).unwrap();
970
971 loop {
972 let pktres = dmx.get_frame(&mut sm);
973 if let Err(e) = pktres {
974 if e == DemuxerError::EOF { break; }
975 panic!("error");
976 }
977 let pkt = pktres.unwrap();
978 println!("Got {}", pkt);
979 }
41f11b2b 980//panic!("the end");
ce52b3b5
KS
981 }
982}