]> git.nihav.org Git - nihav.git/blame - nihav-realmedia/src/muxers/rmvb/mod.rs
avimux: do not record palette change chunks in OpenDML index
[nihav.git] / nihav-realmedia / src / muxers / rmvb / mod.rs
CommitLineData
9dc1fb4b
KS
1use nihav_core::muxers::*;
2mod audiostream;
3use audiostream::*;
4mod videostream;
5use videostream::*;
6
7trait RMWriterHelper {
8 fn write_chunk(&mut self, id: &[u8], size: u32, version: u16) -> MuxerResult<()>;
9 fn write_string(&mut self, data: &[u8]) -> MuxerResult<()>;
10 fn patch_value(&mut self, val: u32, off: u64) -> MuxerResult<()>;
11}
12
13impl<'a> RMWriterHelper for ByteWriter<'a> {
14 fn write_chunk(&mut self, id: &[u8], size: u32, version: u16) -> MuxerResult<()> {
15 self.write_buf(id)?;
16 self.write_u32be(size)?;
17 self.write_u16be(version)?;
18 Ok(())
19 }
20 fn write_string(&mut self, data: &[u8]) -> MuxerResult<()> {
21 validate!(data.len() < 256);
22 self.write_byte(data.len() as u8)?;
23 self.write_buf(data)?;
24 Ok(())
25 }
26 fn patch_value(&mut self, val: u32, off: u64) -> MuxerResult<()> {
27 let cur_pos = self.tell();
28 self.seek(SeekFrom::Start(off))?;
29 self.write_u32be(val)?;
30 self.seek(SeekFrom::Start(cur_pos))?;
31 Ok(())
32 }
33}
34
35pub trait RMStreamWriter {
36 fn write_header(&mut self, bw: &mut ByteWriter, astream: &NAStream) -> MuxerResult<()>;
c5963b17
KS
37 fn queue_packet(&mut self, pkt: NAPacket, ms: u32) -> bool;
38 fn get_packet(&mut self) -> Option<(Vec<u8>, u32, bool)>;
9dc1fb4b
KS
39 fn flush(&mut self);
40 fn finish(&mut self, bw: &mut ByteWriter) -> MuxerResult<()>;
353373a3 41 fn set_pkt_size(&mut self, pkt_size: usize);
9dc1fb4b
KS
42}
43
44#[derive(Clone,Copy)]
45struct IndexEntry {
46 time: u32,
47 pos: u64,
48 pkt_no: u32,
49}
50
51struct RMStream {
52 packetiser: Box<dyn RMStreamWriter>,
53 stream_id: u16,
54 mdpr_pos: u64,
55 npkts: usize,
56 data_size: usize,
57 max_pkt_size: usize,
58 time: u32,
59 cur_time: u32,
60 keyframe: bool,
61 audio: bool,
62 index: Vec<IndexEntry>,
353373a3 63 debug: bool,
9dc1fb4b
KS
64}
65
66impl RMStream {
353373a3 67 fn new(strno: usize, stream: &NAStream, pkt_size: usize) -> MuxerResult<Self> {
9dc1fb4b 68 let packetiser = match stream.get_media_type() {
353373a3 69 StreamType::Video => create_video_stream(stream, pkt_size)?,
9dc1fb4b
KS
70 StreamType::Audio => create_audio_stream(stream)?,
71 _ => Box::new(DummyStreamWriter{}),
72 };
73 Ok(Self{
74 packetiser,
75 stream_id: strno as u16,
76 mdpr_pos: 0,
77 npkts: 0,
78 data_size: 0,
79 max_pkt_size: 0,
80 time: 0,
81 cur_time: 0,
82 keyframe: false,
83 audio: false,
84 index: Vec::new(),
353373a3 85 debug: false,
9dc1fb4b
KS
86 })
87 }
88 fn write_mdpr(&mut self, bw: &mut ByteWriter, strm: &NAStream) -> MuxerResult<()> {
89 self.mdpr_pos = bw.tell();
90
91 bw.write_chunk(b"MDPR", 0, 0)?;
e6aaad5c 92 bw.write_u16be(self.stream_id)?;
9dc1fb4b
KS
93 bw.write_u32be(0)?; //max br
94 bw.write_u32be(0)?; //avg br
95 bw.write_u32be(0)?; //max ps
96 bw.write_u32be(0)?; //avg ps
97 bw.write_u32be(0)?; //num packets
98 bw.write_u32be(0)?; //duration
99 bw.write_u32be(0)?; //preroll
100
101 match strm.get_media_type() {
102 StreamType::Video => {
103 bw.write_string(b"The Video Stream")?;
104 bw.write_string(b"video/x-pn-realvideo")?;
105 },
106 StreamType::Audio => {
107 bw.write_string(b"The Audio Stream")?;
108 bw.write_string(b"audio/x-pn-realaudio")?;
109 self.audio = true;
110 },
111 _ => {
112 bw.write_string(b"some other stream")?;
113 bw.write_string(b"data")?;
114 },
115 };
116 bw.write_u32be(0)?; //extradata size
117 let edata_start = bw.tell();
118 self.packetiser.write_header(bw, strm)?;
119 let edata_end = bw.tell();
120 bw.patch_value((edata_end - edata_start) as u32, edata_start - 4)?;
121
122 patch_size(bw, self.mdpr_pos)?;
123
124 Ok(())
125 }
126 fn write_packet(&mut self, bw: &mut ByteWriter, pkt: NAPacket, pkt_no: &mut u32) -> MuxerResult<()> {
127 if let Some(pts) = pkt.get_pts() {
128 let (tb_num, tb_den) = pkt.get_stream().get_timebase();
129 let ms = NATimeInfo::ts_to_time(pts, 1000, tb_num, tb_den) as u32;
130 self.time = self.time.max(ms);
131 self.cur_time = ms;
132 }
c5963b17
KS
133 self.keyframe = pkt.keyframe || self.audio;
134 self.packetiser.queue_packet(pkt, self.cur_time);
9dc1fb4b
KS
135 self.write_packets(bw, pkt_no)
136 }
137 fn write_packets(&mut self, bw: &mut ByteWriter, pkt_no: &mut u32) -> MuxerResult<()> {
c5963b17 138 while let Some((data, ts, first)) = self.packetiser.get_packet() {
9dc1fb4b
KS
139 validate!(data.len() < 65000);
140 if self.keyframe && first {
c5963b17 141 self.index.push(IndexEntry{ time: ts, pos: bw.tell(), pkt_no: *pkt_no });
9dc1fb4b
KS
142 }
143 let is_keyframe = self.keyframe && (!self.audio || first);
353373a3
KS
144 if self.debug {
145 println!(" writing packet for stream {} size {}{}", self.stream_id, data.len(), if is_keyframe { " kf" } else { "" });
146 }
9dc1fb4b
KS
147 bw.write_u16be(0)?; //version;
148 bw.write_u16be((data.len() + 12) as u16)?;
149 bw.write_u16be(self.stream_id)?;
c5963b17 150 bw.write_u32be(ts)?;
9dc1fb4b
KS
151 bw.write_byte(0)?; //packet group
152 bw.write_byte(if is_keyframe { 0x2 } else { 0x0 })?;
153 bw.write_buf(&data)?;
154
155 self.npkts += 1;
156 self.data_size += data.len();
157
158 *pkt_no += 1;
159 }
160 Ok(())
161 }
162 fn finish(&mut self, bw: &mut ByteWriter, pkt_no: &mut u32) -> MuxerResult<()> {
163 self.packetiser.flush();
164 self.write_packets(bw, pkt_no)?;
165
166 let pos = bw.tell();
167 bw.seek(SeekFrom::Start(self.mdpr_pos + 12))?;
168 bw.write_u32be(if self.time > 0 { (self.data_size * 1000 / (self.time as usize)) as u32 } else { 0 })?;
169 bw.write_u32be(if self.time > 0 { (self.data_size * 1000 / (self.time as usize)) as u32 } else { 0 })?;
170 bw.write_u32be(self.max_pkt_size as u32)?;
171 bw.write_u32be(if self.npkts > 0 { (self.data_size / self.npkts) as u32 } else { 0 })?;
172 bw.seek(SeekFrom::Current(8))?;
173 bw.write_u32be(self.time)?;
174
175 bw.seek(SeekFrom::Start(pos))?;
176 Ok(())
177 }
178}
179
180struct RMMuxer<'a> {
181 bw: &'a mut ByteWriter<'a>,
182 streams: Vec<RMStream>,
183 data_pos: u64,
184 num_chunks: u32,
185 cur_packet: u32,
353373a3
KS
186
187 debug: bool,
188 vpkt_size: usize,
9dc1fb4b
KS
189}
190
191impl<'a> RMMuxer<'a> {
192 fn new(bw: &'a mut ByteWriter<'a>) -> Self {
193 Self {
194 bw,
195 streams: Vec::new(),
196 data_pos: 0,
197 num_chunks: 0,
198 cur_packet: 0,
353373a3
KS
199
200 debug: false,
201 vpkt_size: 1400,
9dc1fb4b
KS
202 }
203 }
204 fn write_index(&mut self) -> MuxerResult<()> {
205 let mut indx_pos = 0x38;
206
207 for stream in self.streams.iter() {
208 let cur_pos = self.bw.tell();
209 self.bw.patch_value(cur_pos as u32, indx_pos)?;
210 indx_pos = cur_pos + 16;
211
212 let idx_size = 10 + 10 + stream.index.len() * 14;
213 self.bw.write_chunk(b"INDX", idx_size as u32, 0)?;
214 self.bw.write_u32be(stream.index.len() as u32)?;
215 self.bw.write_u16be(stream.stream_id)?;
216 self.bw.write_u32be(0)?; // next index position
217 for entry in stream.index.iter() {
218 self.bw.write_u16be(0)?; // version
219 self.bw.write_u32be(entry.time)?;
220 self.bw.write_u32be(entry.pos as u32)?;
221 self.bw.write_u32be(entry.pkt_no)?;
222 }
223
224 self.num_chunks += 1;
225 }
226
227 Ok(())
228 }
229 fn update_prop(&mut self) -> MuxerResult<()> {
230 let mut data_size = 0;
231 let mut npkts = 0;
232 let mut max_pkt_size = 0;
233 let mut time = 0;
234
235 for stream in self.streams.iter() {
236 data_size += stream.data_size;
237 time = time.max(stream.time);
238 npkts += stream.npkts;
239 max_pkt_size = max_pkt_size.max(stream.max_pkt_size);
240 }
241
242 if npkts > 0 && time > 0 {
243 let cur_pos = self.bw.tell();
244
245 let bitrate = (data_size * 1000 / (time as usize)) as u32;
246 self.bw.seek(SeekFrom::Start(28))?;
247 self.bw.write_u32be(bitrate)?;
248 self.bw.write_u32be(bitrate)?;
249 self.bw.write_u32be(max_pkt_size as u32)?;
250 self.bw.write_u32be((data_size / npkts) as u32)?;
251 self.bw.write_u32be(npkts as u32)?;
252 self.bw.write_u32be(time)?;
253
254 self.bw.seek(SeekFrom::Start(cur_pos))?;
255 }
256
257 self.bw.patch_value(self.data_pos as u32, 0x3C)?;
258
259 Ok(())
260 }
261}
262
263fn patch_size(bw: &mut ByteWriter, pos: u64) -> MuxerResult<()> {
264 let end = bw.tell();
265 bw.patch_value((end - pos) as u32, pos + 4)
266}
267
268impl<'a> MuxCore<'a> for RMMuxer<'a> {
269 fn create(&mut self, strmgr: &StreamManager) -> MuxerResult<()> {
270 if strmgr.get_num_streams() == 0 {
271 return Err(MuxerError::InvalidArgument);
272 }
273 if strmgr.get_num_streams() > 100 {
274 return Err(MuxerError::UnsupportedFormat);
275 }
276
277 self.bw.write_chunk(b".RMF", 18, 0)?;
278 self.bw.write_u32be(0)?; // container version
279 self.bw.write_u32be(0)?; // number of chunks
280
281 self.num_chunks = 1;
282 let prop_start = self.bw.tell();
283 self.bw.write_chunk(b"PROP", 0, 0)?;
284 self.bw.write_u32be(0)?; //max br
285 self.bw.write_u32be(0)?; //avg br
286 self.bw.write_u32be(0)?; //max ps
287 self.bw.write_u32be(0)?; //avg ps
288 self.bw.write_u32be(0)?; //num packets
289 self.bw.write_u32be(0)?; //duration
290 self.bw.write_u32be(0)?; //preroll
291 self.bw.write_u32be(0)?; //index offset
292 self.bw.write_u32be(0)?; //data offset
293 self.bw.write_u16be(strmgr.get_num_streams() as u16)?;
294 self.bw.write_u16be(0)?; // flags
295 patch_size(self.bw, prop_start)?;
296
297 self.streams.clear();
298 for (strno, strm) in strmgr.iter().enumerate() {
353373a3 299 let mut swriter = RMStream::new(strno, &strm, self.vpkt_size)?;
9dc1fb4b
KS
300 swriter.write_mdpr(self.bw, &strm)?;
301 self.streams.push(swriter);
302 self.num_chunks += 1;
303 }
304
305 self.data_pos = self.bw.tell();
306 self.bw.write_chunk(b"DATA", 0, 0)?;
307 self.bw.write_u32be(0)?; //num packets
308 self.bw.write_u32be(0)?; //next data chunk
309 self.num_chunks += 1;
310
311 Ok(())
312 }
313 fn mux_frame(&mut self, _strmgr: &StreamManager, pkt: NAPacket) -> MuxerResult<()> {
314 if self.data_pos == 0 {
315 return Err(MuxerError::NotCreated);
316 }
317 let stream = pkt.get_stream();
318 let str_num = stream.get_num();
319 if str_num > self.streams.len() {
320 return Err(MuxerError::UnsupportedFormat);
321 }
322 self.streams[str_num].write_packet(self.bw, pkt, &mut self.cur_packet)?;
323
324 Ok(())
325 }
326 fn flush(&mut self) -> MuxerResult<()> {
327 Ok(())
328 }
329 fn end(&mut self) -> MuxerResult<()> {
330 if self.data_pos == 0 {
331 return Err(MuxerError::NotCreated);
332 }
333 let mut tot_npkts = 0;
334 for stream in self.streams.iter_mut() {
335 stream.finish(self.bw, &mut self.cur_packet)?;
336 tot_npkts += stream.npkts;
337 }
338
339 let data_size = self.bw.tell() - self.data_pos;
340 self.bw.patch_value(data_size as u32, self.data_pos + 4)?;
341 self.bw.patch_value(tot_npkts as u32, self.data_pos + 10)?;
342
343 self.write_index()?;
344 self.update_prop()?;
345
346 self.bw.patch_value(self.num_chunks, 14)?;
347 Ok(())
348 }
349}
350
353373a3
KS
351const DEBUG_OPTION: &str = "debug";
352const VPKT_SIZE_OPTION: &str = "vpkt_size";
353
354const MUXER_OPTIONS: &[NAOptionDefinition] = &[
355 NAOptionDefinition {
356 name: DEBUG_OPTION, description: "print some muxer statistics",
357 opt_type: NAOptionDefinitionType::Bool },
358 NAOptionDefinition {
359 name: VPKT_SIZE_OPTION, description: "video packet maximum size",
360 opt_type: NAOptionDefinitionType::Int(Some(1024), Some(14800)) },
361];
362
9dc1fb4b 363impl<'a> NAOptionHandler for RMMuxer<'a> {
353373a3
KS
364 fn get_supported_options(&self) -> &[NAOptionDefinition] { MUXER_OPTIONS }
365 fn set_options(&mut self, options: &[NAOption]) {
366 for option in options.iter() {
367 for opt_def in MUXER_OPTIONS.iter() {
368 if opt_def.check(option).is_ok() {
369 match option.name {
370 DEBUG_OPTION => {
371 if let NAValue::Bool(val) = option.value {
372 self.debug = val;
373 for stream in self.streams.iter_mut() {
374 stream.debug = val;
375 }
376 }
377 },
378 VPKT_SIZE_OPTION => {
379 if let NAValue::Int(intval) = option.value {
380 self.vpkt_size = intval as usize;
381 for stream in self.streams.iter_mut() {
382 stream.packetiser.set_pkt_size(self.vpkt_size);
383 }
384 }
385 },
386 _ => {},
387 };
388 }
389 }
390 }
391 }
392 fn query_option_value(&self, name: &str) -> Option<NAValue> {
393 match name {
394 DEBUG_OPTION => Some(NAValue::Bool(self.debug)),
395 VPKT_SIZE_OPTION => Some(NAValue::Int(self.vpkt_size as i64)),
396 _ => None,
397 }
398 }
9dc1fb4b
KS
399}
400
401pub struct RealMediaMuxerCreator {}
402
403impl MuxerCreator for RealMediaMuxerCreator {
404 fn new_muxer<'a>(&self, bw: &'a mut ByteWriter<'a>) -> Box<dyn MuxCore<'a> + 'a> {
405 Box::new(RMMuxer::new(bw))
406 }
407 fn get_name(&self) -> &'static str { "realmedia" }
408 fn get_capabilities(&self) -> MuxerCapabilities { MuxerCapabilities::Universal }
46008a8f 409 fn get_quirks(&self) -> MuxerQuirks { MuxerQuirks::new() }
9dc1fb4b
KS
410}
411
412struct RAMuxer<'a> {
413 bw: &'a mut ByteWriter<'a>,
414 sw: Option<Box<dyn RMStreamWriter>>,
415}
416
417impl<'a> RAMuxer<'a> {
418 fn new(bw: &'a mut ByteWriter<'a>) -> Self {
419 Self {
420 bw,
421 sw: None,
422 }
423 }
424}
425
426impl<'a> MuxCore<'a> for RAMuxer<'a> {
427 fn create(&mut self, strmgr: &StreamManager) -> MuxerResult<()> {
428 if strmgr.get_num_streams() != 1 {
429 return Err(MuxerError::InvalidArgument);
430 }
431 let astream = strmgr.get_stream(0).unwrap();
432 if astream.get_media_type() != StreamType::Audio {
433 return Err(MuxerError::InvalidArgument);
434 }
435 self.sw = Some(create_audio_stream(&astream)?);
436 if let Some(ref mut sw) = self.sw {
437 sw.write_header(self.bw, &astream)?;
438 }
439 Ok(())
440 }
441 fn mux_frame(&mut self, _strmgr: &StreamManager, pkt: NAPacket) -> MuxerResult<()> {
442 if let Some(ref mut sw) = self.sw {
c5963b17
KS
443 sw.queue_packet(pkt, 0);
444 while let Some((data, _, _)) = sw.get_packet() {
9dc1fb4b
KS
445 self.bw.write_buf(&data)?;
446 }
447 Ok(())
448 } else {
449 Err(MuxerError::NotCreated)
450 }
451 }
452 fn flush(&mut self) -> MuxerResult<()> {
453 Ok(())
454 }
455 fn end(&mut self) -> MuxerResult<()> {
456 if let Some(ref mut sw) = self.sw {
e6aaad5c 457 sw.finish(self.bw)?;
9dc1fb4b
KS
458 }
459 Ok(())
460 }
461}
462
463impl<'a> NAOptionHandler for RAMuxer<'a> {
464 fn get_supported_options(&self) -> &[NAOptionDefinition] { &[] }
465 fn set_options(&mut self, _options: &[NAOption]) { }
466 fn query_option_value(&self, _name: &str) -> Option<NAValue> { None }
467}
468
469pub struct RealAudioMuxerCreator {}
470
471impl MuxerCreator for RealAudioMuxerCreator {
472 fn new_muxer<'a>(&self, bw: &'a mut ByteWriter<'a>) -> Box<dyn MuxCore<'a> + 'a> {
473 Box::new(RAMuxer::new(bw))
474 }
475 fn get_name(&self) -> &'static str { "realaudio" }
476 fn get_capabilities(&self) -> MuxerCapabilities { MuxerCapabilities::SingleAudio("any") }
46008a8f 477 fn get_quirks(&self) -> MuxerQuirks { MuxerQuirks::new() }
9dc1fb4b
KS
478}
479
480#[cfg(test)]
481mod test {
482 use nihav_core::codecs::*;
483 use nihav_core::demuxers::*;
484 use nihav_core::muxers::*;
485 use nihav_codec_support::test::enc_video::*;
486 use crate::*;
487
488 #[test]
489 fn test_rm_muxer() {
490 let mut dmx_reg = RegisteredDemuxers::new();
491 realmedia_register_all_demuxers(&mut dmx_reg);
492 // sample from a private collection
493 let dec_config = DecoderTestParams {
494 demuxer: "realmedia",
495 in_name: "assets/RV/rv30_weighted_mc.rm",
496 limit: None,
497 stream_type: StreamType::None,
498 dmx_reg, dec_reg: RegisteredDecoders::new(),
499 };
500 let mut mux_reg = RegisteredMuxers::new();
501 realmedia_register_all_muxers(&mut mux_reg);
502 /*let enc_config = EncoderTestParams {
503 muxer: "realmedia",
504 enc_name: "",
505 out_name: "muxed.rm",
506 mux_reg, enc_reg: RegisteredEncoders::new(),
507 };
508 test_remuxing(&dec_config, &enc_config);*/
509 test_remuxing_md5(&dec_config, "realmedia", &mux_reg,
48db8740 510 [0x9bc90ab0, 0x6b8c42f7, 0xaf81e8bf, 0x7c76ec57]);
9dc1fb4b
KS
511 }
512
513 #[test]
514 fn test_ra_muxer_v3() {
515 let mut dmx_reg = RegisteredDemuxers::new();
516 realmedia_register_all_demuxers(&mut dmx_reg);
517 //test sample: https://samples.mplayerhq.hu/real/RA/14_4/drummers.14.ra
518 let dec_config = DecoderTestParams {
519 demuxer: "realaudio",
520 in_name: "assets/RV/drummers.14.ra",
521 limit: None,
522 stream_type: StreamType::None,
523 dmx_reg, dec_reg: RegisteredDecoders::new(),
524 };
525 let mut mux_reg = RegisteredMuxers::new();
526 realmedia_register_all_muxers(&mut mux_reg);
527 /*let enc_config = EncoderTestParams {
528 muxer: "realaudio",
529 enc_name: "",
530 out_name: "v3.ra",
531 mux_reg, enc_reg: RegisteredEncoders::new(),
532 };
533 test_remuxing(&dec_config, &enc_config);*/
534 test_remuxing_md5(&dec_config, "realaudio", &mux_reg,
535 [0x8101a484, 0xf5d80805, 0x24577596, 0x9b27262f]);
536 }
537 #[test]
538 fn test_ra_muxer_v4() {
539 let mut dmx_reg = RegisteredDemuxers::new();
540 realmedia_register_all_demuxers(&mut dmx_reg);
541 //test sample: https://samples.mplayerhq.hu/real//RA/ra_with_comment_field/diemusik.ra
542 let dec_config = DecoderTestParams {
543 demuxer: "realaudio",
544 in_name: "assets/RV/diemusik.ra",
545 limit: None,
546 stream_type: StreamType::None,
547 dmx_reg, dec_reg: RegisteredDecoders::new(),
548 };
549 let mut mux_reg = RegisteredMuxers::new();
550 realmedia_register_all_muxers(&mut mux_reg);
551 /*let enc_config = EncoderTestParams {
552 muxer: "realaudio",
553 enc_name: "",
554 out_name: "v4.ra",
555 mux_reg, enc_reg: RegisteredEncoders::new(),
556 };
557 test_remuxing(&dec_config, &enc_config);*/
558 test_remuxing_md5(&dec_config, "realaudio", &mux_reg,
559 [0x33665ec3, 0x69b68ea2, 0x08d4b138, 0x318e305f]);
560 }
561 #[test]
562 fn test_ra_muxer_sipro() {
563 let mut dmx_reg = RegisteredDemuxers::new();
564 realmedia_register_all_demuxers(&mut dmx_reg);
565 //test sample: https://samples.mplayerhq.hu/real/AC-sipr/autahi-vox.rm
566 let dec_config = DecoderTestParams {
567 demuxer: "realmedia",
568 in_name: "assets/RV/autahi-vox.rm",
569 limit: None,
570 stream_type: StreamType::None,
571 dmx_reg, dec_reg: RegisteredDecoders::new(),
572 };
573 let mut mux_reg = RegisteredMuxers::new();
574 realmedia_register_all_muxers(&mut mux_reg);
575 /*let enc_config = EncoderTestParams {
576 muxer: "realaudio",
577 enc_name: "",
578 out_name: "v4-sipro.ra",
579 mux_reg, enc_reg: RegisteredEncoders::new(),
580 };
581 test_remuxing(&dec_config, &enc_config);*/
582 test_remuxing_md5(&dec_config, "realaudio", &mux_reg,
583 [0x08bd496d, 0x5f35d7ae, 0xe9c93c50, 0x9e803f76]);
584 }
585 #[test]
586 fn test_ra_muxer_v5() {
587 let mut dmx_reg = RegisteredDemuxers::new();
588 realmedia_register_all_demuxers(&mut dmx_reg);
589 //test sample: https://samples.mplayerhq.hu/real/AC-cook/cook_5.1/multichannel.rma
590 let dec_config = DecoderTestParams {
591 demuxer: "realmedia",
592 in_name: "assets/RV/multichannel.rma",
593 limit: None,
594 stream_type: StreamType::None,
595 dmx_reg, dec_reg: RegisteredDecoders::new(),
596 };
597 let mut mux_reg = RegisteredMuxers::new();
598 realmedia_register_all_muxers(&mut mux_reg);
599 /*let enc_config = EncoderTestParams {
600 muxer: "realaudio",
601 enc_name: "",
602 out_name: "v5.ra",
603 mux_reg, enc_reg: RegisteredEncoders::new(),
604 };
605 test_remuxing(&dec_config, &enc_config);*/
606 test_remuxing_md5(&dec_config, "realaudio", &mux_reg,
607 [0x52f42c49, 0x90ac79a7, 0x275a465f, 0x7a6f3659]);
608 }
609 #[test]
610 fn test_rm_muxer_aac() {
611 let mut dmx_reg = RegisteredDemuxers::new();
612 realmedia_register_all_demuxers(&mut dmx_reg);
613 //sample from a private collection
614 let dec_config = DecoderTestParams {
615 demuxer: "realmedia",
616 in_name: "assets/RV/rv40_weighted_mc_2.rmvb",
617 limit: None,
618 stream_type: StreamType::None,
619 dmx_reg, dec_reg: RegisteredDecoders::new(),
620 };
621 let mut mux_reg = RegisteredMuxers::new();
622 realmedia_register_all_muxers(&mut mux_reg);
623 /*let enc_config = EncoderTestParams {
624 muxer: "realmedia",
625 enc_name: "",
626 out_name: "aac.ram",
627 mux_reg, enc_reg: RegisteredEncoders::new(),
628 };
629 test_remuxing(&dec_config, &enc_config);*/
630 test_remuxing_md5(&dec_config, "realmedia", &mux_reg,
48db8740 631 [0x8392bb8c, 0xeb8f4d04, 0x25262829, 0x63b2fda7]);
9dc1fb4b
KS
632 }
633 #[test]
634 fn test_rm_muxer_ralf() {
635 let mut dmx_reg = RegisteredDemuxers::new();
636 realmedia_register_all_demuxers(&mut dmx_reg);
637 //sample from a private collection
638 let dec_config = DecoderTestParams {
639 demuxer: "realmedia",
640 in_name: "assets/RV/rv40_ralf.rmvb",
641 limit: None,
642 stream_type: StreamType::None,
643 dmx_reg, dec_reg: RegisteredDecoders::new(),
644 };
645 let mut mux_reg = RegisteredMuxers::new();
646 realmedia_register_all_muxers(&mut mux_reg);
647 /*let enc_config = EncoderTestParams {
648 muxer: "realmedia",
649 enc_name: "",
650 out_name: "ralf.ram",
651 mux_reg, enc_reg: RegisteredEncoders::new(),
652 };
653 test_remuxing(&dec_config, &enc_config);*/
654 test_remuxing_md5(&dec_config, "realmedia", &mux_reg,
48db8740 655 [0xe90893eb, 0x8634642c, 0xef679ac4, 0x2e89314a]);
9dc1fb4b
KS
656 }
657}