blob: 65ab4de95a8689b2e17135fbf17c7130fa565467 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
|
/*
This file is part of jellything (https://codeberg.org/metamuffin/jellything)
which is licensed under the GNU Affero General Public License (version 3); see /COPYING.
Copyright (C) 2025 metamuffin <metamuffin.org>
*/
use crate::ContainerFormat;
use anyhow::Result;
use std::io::Read;
use winter_ebml::{Ebml, EbmlHeader, read_vint_slice};
use winter_matroska::MatroskaFile;
pub fn detect_container_format(reader: &mut dyn Read) -> Result<Option<ContainerFormat>> {
let mut data = Vec::new();
reader.take(128).read_to_end(&mut data)?;
Ok(test_matroska(&data))
}
fn test_matroska(mut data: &[u8]) -> Option<ContainerFormat> {
let tag = read_vint_slice(&mut data)?;
if tag != MatroskaFile::TAG_EBML_HEADER {
return None;
};
let size = read_vint_slice(&mut data)? as usize;
if size > data.len() {
return None;
}
let header = EbmlHeader::read(&data[..size]).ok()?;
match header.doc_type.as_str() {
"matroska" => Some(ContainerFormat::Matroska),
"webm" => Some(ContainerFormat::Webm),
_ => None,
}
}
#[test]
fn verify_matroska() {
// WebM
let sample = "\
1a45dfa39f4286810142f7810142f2810442f381084282847765626d4287\
8104428581021853806701000000088a9c1a114d9b74bc4dbb8b53ab8415\
49a96653ac81a14dbb8b53ab841654ae6b53ac81d64dbb8c53ab841254c3\
6753ac8201a04dbb8e53ab841c53bb6b53ac84088a9accec010000000000\
0057000000000000";
let sample = hex::decode(sample).unwrap();
assert_eq!(test_matroska(&sample), Some(ContainerFormat::Webm));
// Matroska
let sample = "\
1a45dfa3a34286810142f7810142f2810442f381084282886d6174726f73\
6b61428781044285810218538067010000005d66b4a2114d9b74c2bf8492\
1ae3e14dbb8b53ab841549a96653ac81a14dbb8b53ab841654ae6b53ac81\
ef4dbb8c53ab841254c36753ac82019b4dbb8e53ab841c53bb6b53ac845d\
66a14aec01000000";
let sample = hex::decode(sample).unwrap();
assert_eq!(test_matroska(&sample), Some(ContainerFormat::Matroska));
// GIF
let sample = "\
47494638396100010001f71f000000002400004800006c0000900000b400\
00d80000fc00000024002424004824006c2400902400b42400d82400fc24\
000048002448004848006c4800904800b44800d84800fc4800006c00246c\
00486c006c6c00906c00b46c00d86c00fc6c000090002490004890006c90\
00909000b49000d8";
let sample = hex::decode(sample).unwrap();
assert_eq!(test_matroska(&sample), None)
}
|