Skip to content

Commit ed25af6

Browse files
committed
Expose xhe-aac it in the C layer
1 parent 7128fb5 commit ed25af6

File tree

3 files changed

+126
-0
lines changed

3 files changed

+126
-0
lines changed

mp4parse_capi/src/lib.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,7 @@ pub enum Mp4parseCodec {
105105
AMRNB,
106106
#[cfg(feature = "3gpp")]
107107
AMRWB,
108+
XHEAAC, // xHE-AAC (Extended High Efficiency AAC)
108109
}
109110

110111
#[repr(C)]
@@ -737,6 +738,11 @@ fn get_track_audio_info(
737738
AudioCodecSpecific::ES_Descriptor(ref esds) if esds.audio_codec == CodecType::AAC => {
738739
Mp4parseCodec::Aac
739740
}
741+
AudioCodecSpecific::ES_Descriptor(ref esds)
742+
if esds.audio_codec == CodecType::XHEAAC =>
743+
{
744+
Mp4parseCodec::XHEAAC
745+
}
740746
AudioCodecSpecific::ES_Descriptor(ref esds) if esds.audio_codec == CodecType::MP3 => {
741747
Mp4parseCodec::Mp3
742748
}
Binary file not shown.

mp4parse_capi/tests/test_xhe_aac.rs

Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
// Test for xHE-AAC codec detection via C API
2+
3+
use mp4parse_capi::*;
4+
use std::fs::File;
5+
use std::io::Read;
6+
7+
static XHE_AAC_FILE: &str = "tests/sine-3s-xhe-aac-44khz-mono.mp4";
8+
9+
extern "C" fn buf_read(buf: *mut u8, size: usize, userdata: *mut std::os::raw::c_void) -> isize {
10+
let input: &mut File = unsafe { &mut *(userdata as *mut _) };
11+
let buf = unsafe { std::slice::from_raw_parts_mut(buf, size) };
12+
match input.read(buf) {
13+
Ok(n) => n as isize,
14+
Err(_) => -1,
15+
}
16+
}
17+
18+
#[test]
19+
fn test_xhe_aac_codec_detection() {
20+
unsafe {
21+
let mut file = File::open(XHE_AAC_FILE).expect("Failed to open xHE-AAC test file");
22+
let io = Mp4parseIo {
23+
read: Some(buf_read),
24+
userdata: &mut file as *mut _ as *mut std::os::raw::c_void,
25+
};
26+
27+
let mut parser = std::ptr::null_mut();
28+
let rv = mp4parse_new(&io, &mut parser);
29+
assert_eq!(rv, Mp4parseStatus::Ok);
30+
assert!(!parser.is_null());
31+
32+
let mut count: u32 = 0;
33+
let rv = mp4parse_get_track_count(parser, &mut count);
34+
assert_eq!(rv, Mp4parseStatus::Ok);
35+
assert_eq!(count, 1, "Expected exactly one track");
36+
37+
let mut track_info = Mp4parseTrackInfo::default();
38+
let rv = mp4parse_get_track_info(parser, 0, &mut track_info);
39+
assert_eq!(rv, Mp4parseStatus::Ok);
40+
assert_eq!(track_info.track_type, Mp4parseTrackType::Audio);
41+
42+
let mut audio_info = Mp4parseTrackAudioInfo::default();
43+
let rv = mp4parse_get_track_audio_info(parser, 0, &mut audio_info);
44+
assert_eq!(rv, Mp4parseStatus::Ok);
45+
assert_eq!(audio_info.sample_info_count, 1);
46+
47+
let sample_info = &*audio_info.sample_info;
48+
assert_eq!(sample_info.codec_type, Mp4parseCodec::XHEAAC);
49+
50+
assert_eq!(sample_info.channels, 1); // mono
51+
assert_eq!(sample_info.sample_rate, 44100); // 44.1kHz
52+
assert_eq!(sample_info.profile, 42); // audio object type 42 (xHE-AAC)
53+
assert_eq!(sample_info.extended_profile, 42);
54+
55+
assert!(sample_info.codec_specific_config.length > 0);
56+
assert!(!sample_info.codec_specific_config.data.is_null());
57+
58+
mp4parse_free(parser);
59+
}
60+
}
61+
62+
#[test]
63+
fn test_xhe_aac_vs_regular_aac() {
64+
unsafe {
65+
let mut file = File::open(XHE_AAC_FILE).expect("Failed to open xHE-AAC test file");
66+
let io = Mp4parseIo {
67+
read: Some(buf_read),
68+
userdata: &mut file as *mut _ as *mut std::os::raw::c_void,
69+
};
70+
71+
let mut parser = std::ptr::null_mut();
72+
let rv = mp4parse_new(&io, &mut parser);
73+
assert_eq!(rv, Mp4parseStatus::Ok);
74+
75+
let mut audio_info = Mp4parseTrackAudioInfo::default();
76+
let rv = mp4parse_get_track_audio_info(parser, 0, &mut audio_info);
77+
assert_eq!(rv, Mp4parseStatus::Ok);
78+
79+
let sample_info = &*audio_info.sample_info;
80+
assert_eq!(sample_info.codec_type, Mp4parseCodec::XHEAAC);
81+
assert_eq!(sample_info.profile, 42); // xHE-AAC audio object type
82+
83+
mp4parse_free(parser);
84+
}
85+
}
86+
87+
#[test]
88+
fn test_xhe_aac_codec_not_unknown() {
89+
unsafe {
90+
let mut file = File::open(XHE_AAC_FILE).expect("Failed to open xHE-AAC test file");
91+
let io = Mp4parseIo {
92+
read: Some(buf_read),
93+
userdata: &mut file as *mut _ as *mut std::os::raw::c_void,
94+
};
95+
96+
let mut parser = std::ptr::null_mut();
97+
let rv = mp4parse_new(&io, &mut parser);
98+
assert_eq!(rv, Mp4parseStatus::Ok);
99+
100+
let mut audio_info = Mp4parseTrackAudioInfo::default();
101+
let rv = mp4parse_get_track_audio_info(parser, 0, &mut audio_info);
102+
assert_eq!(rv, Mp4parseStatus::Ok);
103+
104+
let sample_info = &*audio_info.sample_info;
105+
106+
assert_ne!(
107+
sample_info.codec_type,
108+
Mp4parseCodec::Unknown,
109+
"xHE-AAC should not be detected as Unknown codec"
110+
);
111+
112+
assert_eq!(
113+
sample_info.codec_type,
114+
Mp4parseCodec::XHEAAC,
115+
"xHE-AAC should be detected as XHEAAC codec"
116+
);
117+
118+
mp4parse_free(parser);
119+
}
120+
}

0 commit comments

Comments
 (0)