access_unit/
webm.rs

1/// EBML header magic bytes for WebM/Matroska
2const EBML_MAGIC: [u8; 4] = [0x1A, 0x45, 0xDF, 0xA3];
3
4/// Check for WebM container format.
5/// WebM uses EBML with magic bytes 0x1A 0x45 0xDF 0xA3 and DocType "webm".
6pub fn is_webm(data: &[u8]) -> bool {
7    if data.len() < 4 || data[0..4] != EBML_MAGIC {
8        return false;
9    }
10    // Look for "webm" DocType in the first 64 bytes
11    let search_len = data.len().min(64);
12    data[..search_len].windows(4).any(|w| w == b"webm")
13}
14
15/// Check for Matroska container format (MKV).
16/// Matroska uses EBML with magic bytes 0x1A 0x45 0xDF 0xA3 and DocType "matroska".
17pub fn is_matroska(data: &[u8]) -> bool {
18    if data.len() < 4 || data[0..4] != EBML_MAGIC {
19        return false;
20    }
21    // Look for "matroska" DocType in the first 64 bytes
22    let search_len = data.len().min(64);
23    data[..search_len].windows(8).any(|w| w == b"matroska")
24}
25
26/// Check for any EBML-based container (WebM or Matroska).
27pub fn is_ebml(data: &[u8]) -> bool {
28    data.len() >= 4 && data[0..4] == EBML_MAGIC
29}
30
31#[cfg(test)]
32mod tests {
33    use super::*;
34
35    #[test]
36    fn test_webm_detection() {
37        // Valid WebM header (EBML magic + some content with "webm" doctype)
38        let webm_data = [
39            0x1A, 0x45, 0xDF, 0xA3, // EBML magic
40            0x01, 0x00, 0x00, 0x00, // size
41            0x00, 0x00, 0x1F, 0x43, // some data
42            b'w', b'e', b'b', b'm', // doctype
43        ];
44        assert!(is_webm(&webm_data));
45        assert!(is_ebml(&webm_data));
46        assert!(!is_matroska(&webm_data));
47    }
48
49    #[test]
50    fn test_matroska_detection() {
51        // Valid Matroska header
52        let mkv_data = [
53            0x1A, 0x45, 0xDF, 0xA3, // EBML magic
54            0x01, 0x00, 0x00, 0x00, // size
55            b'm', b'a', b't', b'r', b'o', b's', b'k', b'a', // doctype
56        ];
57        assert!(!is_webm(&mkv_data));
58        assert!(is_ebml(&mkv_data));
59        assert!(is_matroska(&mkv_data));
60    }
61
62    #[test]
63    fn test_invalid_data() {
64        assert!(!is_webm(&[]));
65        assert!(!is_webm(&[0x00, 0x00, 0x00]));
66        assert!(!is_webm(b"RIFF"));
67        assert!(!is_ebml(&[]));
68    }
69}