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