telemetry_parser/sony/
mxf.rs

1// SPDX-License-Identifier: MIT OR Apache-2.0
2// Copyright © 2021 Adrian <adrian.eddy at gmail>
3
4use std::io::*;
5use std::sync::{ Arc, atomic::AtomicBool };
6use byteorder::{ ReadBytesExt, BigEndian };
7
8use crate::*;
9use crate::tags_impl::*;
10
11pub fn parse<T: Read + Seek, F: Fn(f64)>(stream: &mut T, size: usize, progress_cb: F, cancel_flag: Arc<AtomicBool>) -> Result<Vec<SampleInfo>> {
12    let mut stream = std::io::BufReader::with_capacity(128*1024, stream);
13    let mut samples = Vec::new();
14
15    let mut index = 0;
16    let mut id = [0u8; 16];
17    while let Ok(_) = stream.read_exact(&mut id) {
18        let length = read_ber(&mut stream)?;
19
20        if cancel_flag.load(std::sync::atomic::Ordering::Relaxed) { break; }
21        if size > 0 {
22            progress_cb(stream.stream_position()? as f64 / size as f64);
23        }
24
25        // log::debug!("{}: {}", util::to_hex(&id), length);
26
27        if id == [0x06, 0x0e, 0x2b, 0x34, 0x01, 0x02, 0x01, 0x01, 0x0d, 0x01, 0x03, 0x01, 0x17, 0x01, 0x02, 0x01] { // Metadata, Ancillary, SMPTE ST 436
28            let mut data = vec![0; length];
29            stream.read_exact(&mut data)?;
30            let data = parse_ancillary(&data)?;
31
32            if let Ok(map) = super::Sony::parse_metadata(&data) {
33                let mut frame_rate = 25.0; // Probably wrong assumption, but it's better than 0 (at least we'll have some timestamps)
34                if let Some(group) = map.get(&GroupId::Default) {
35                    if let Some(val) = group.get(&TagId::FrameRate) {
36                        match &val.value {
37                            TagValue::f32(vv) => frame_rate = *vv.get() as f64,
38                            TagValue::f64(vv) => frame_rate = *vv.get(),
39                            _ => {}
40                        }
41                    }
42                }
43                let duration_ms = 1000.0 / frame_rate;
44
45                // log::debug!("Index: {}, Duration: {}, Frame rate: {}, Timestamp: {}", index, duration_ms, frame_rate, index as f64 * duration_ms);
46
47                samples.push(SampleInfo {
48                    sample_index: index,
49                    duration_ms,
50                    timestamp_ms: index as f64 * duration_ms,
51                    tag_map: Some(map),
52                    ..Default::default()
53                });
54                index += 1;
55            }
56        } else {
57            stream.seek(SeekFrom::Current(length as i64))?;
58        }
59    }
60
61    Ok(samples)
62}
63
64fn read_ber<T: Read + Seek>(stream: &mut T) -> Result<usize> {
65    let mut size = stream.read_u8()? as usize;
66
67    if size & 0x80 != 0 {
68        let bytes = size & 0x7f;
69        assert!(bytes <= 8);
70        size = 0;
71        for _ in 0..bytes {
72            size = size << 8 | (stream.read_u8()? as usize);
73        }
74    }
75    Ok(size)
76}
77
78fn parse_ancillary(buffer: &[u8]) -> Result<Vec<u8>> {
79    let mut slice = Cursor::new(&buffer);
80
81    let count = slice.read_u16::<BigEndian>()?; // number of lines
82    assert!(count as usize * 14 <= buffer.len());
83
84    let mut full_data = Vec::with_capacity(buffer.len());
85    for _ in 0..count {
86        let _line_number = slice.read_u16::<BigEndian>()?;
87        let _wrapping_type = slice.read_u8()?;
88        let _payload_sample_coding = slice.read_u8()?;
89        let sample_count = slice.read_u16::<BigEndian>()?;
90        let array_count = slice.read_u32::<BigEndian>()?;
91        let array_length = slice.read_u32::<BigEndian>()?;
92
93        let pos = slice.position() as usize;
94
95        let array_size = (array_count * array_length) as usize;
96
97        let parsing_size = (sample_count as usize)
98            .min(buffer.len() - pos)
99            .min(array_size);
100
101        let array_data = &buffer[pos..pos+parsing_size];
102        if array_data[0] == 0x43 && array_data[1] == 0x05 {
103            // let size = array_data[2] as usize;
104            // let idx = array_data[3];
105            let payload = &array_data[4..];
106
107            full_data.extend_from_slice(&payload);
108        }
109        slice.seek(SeekFrom::Current(array_size as i64))?;
110    }
111    Ok(full_data)
112}