falcon_ffmpeg/testing/
mkv.rs1use super::av1::{el, uint};
6
7pub fn pcm_matroska(webm: bool, rate: u32, samples: &[i16]) -> Vec<u8> {
11 let doc: &[u8] = if webm { b"webm" } else { b"matroska" };
12 let header = el(
13 0x1A45DFA3,
14 &[uint(0x4286, 1), uint(0x42F7, 1), uint(0x42F2, 4), uint(0x42F3, 8), el(0x4282, doc), uint(0x4287, 4), uint(0x4285, 2)].concat(),
15 );
16 let duration_ms = samples.len() as f64 * 1000.0 / f64::from(rate);
17 let info = el(0x1549A966, &[uint(0x2AD7B1, 1_000_000), el(0x4489, &duration_ms.to_be_bytes()), el(0x4D80, b"falcon tests"), el(0x5741, b"falcon tests")].concat());
18 let audio = el(0xE1, &[el(0xB5, &f64::from(rate).to_be_bytes()), uint(0x9F, 1), uint(0x6264, 16)].concat());
19 let track = el(0xAE, &[uint(0xD7, 1), uint(0x73C5, 1), uint(0x83, 2), el(0x86, b"A_PCM/INT/LIT"), audio].concat());
20 let tracks = el(0x1654AE6B, &track);
21
22 let block = (rate / 50) as usize;
23 let per_cluster = 50;
24 let (mut clusters, mut starts) = (Vec::new(), Vec::new());
25 for (c, chunk) in samples.chunks(block * per_cluster).enumerate() {
26 let start_ms = c as u64 * 1000;
27 starts.push((start_ms, clusters.len()));
28 let mut body = uint(0xE7, start_ms);
29 for (i, part) in chunk.chunks(block).enumerate() {
30 let mut b = vec![0x81];
31 b.extend_from_slice(&((i * 20) as i16).to_be_bytes());
32 b.push(0x80);
33 b.extend(part.iter().flat_map(|s| s.to_le_bytes()));
34 body.extend(el(0xA3, &b));
35 }
36 clusters.extend(el(0x1F43B675, &body));
37 }
38 let before = info.len() + tracks.len();
40 let cues: Vec<u8> = starts
41 .iter()
42 .map(|&(ms, at)| el(0xBB, &[uint(0xB3, ms), el(0xB7, &[uint(0xF7, 1), uint(0xF1, (before + at) as u64)].concat())].concat()))
43 .collect::<Vec<_>>()
44 .concat();
45 let segment = el(0x18538067, &[info, tracks, clusters, el(0x1C53BB6B, &cues)].concat());
46 [header, segment].concat()
47}