@@ -218,6 +218,8 @@ static VIDEO_H263_3GP: &str = "tests/bbb_sunflower_QCIF_30fps_h263_noaudio_1f.3g
218
218
// The 1 frame hevc mp4 file generated by ffmpeg with command
219
219
// "ffmpeg -f lavfi -i color=c=white:s=640x480 -c:v libx265 -frames:v 1 -pix_fmt yuv420p hevc_white_frame.mp4"
220
220
static VIDEO_HEVC_MP4 : & str = "tests/hevc_white_frame.mp4" ;
221
+ // xHE-AAC test file generated by exhale encoder - 3 seconds, 44.1kHz mono, ~14.6kbps
222
+ static AUDIO_XHE_AAC_MP4 : & str = "tests/sine-3s-xhe-aac-44khz-mono.mp4" ;
221
223
// The 1 frame AMR-NB 3gp file can be generated by ffmpeg with command
222
224
// "ffmpeg -i [input file] -f 3gp -acodec amr_nb -ar 8000 -ac 1 -frames:a 1 -vn output.3gp"
223
225
#[ cfg( feature = "3gpp" ) ]
@@ -1580,3 +1582,80 @@ fn public_video_mp4v() {
1580
1582
} ;
1581
1583
}
1582
1584
}
1585
+
1586
+ #[ test]
1587
+ fn public_audio_xhe_aac ( ) {
1588
+ let mut fd = File :: open ( AUDIO_XHE_AAC_MP4 ) . expect ( "Unknown file" ) ;
1589
+ let mut buf = Vec :: new ( ) ;
1590
+ fd. read_to_end ( & mut buf) . expect ( "File error" ) ;
1591
+
1592
+ let mut c = Cursor :: new ( & buf) ;
1593
+ let context = mp4:: read_mp4 ( & mut c, ParseStrictness :: Normal ) . expect ( "read_mp4 failed" ) ;
1594
+
1595
+ println ! ( "xHE-AAC MP4 file parsed successfully" ) ;
1596
+ println ! ( "Number of tracks: {}" , context. tracks. len( ) ) ;
1597
+
1598
+ // This file contains a single xHE-AAC audio track at 44.1kHz mono, ~14.6kbps, 3 seconds
1599
+ assert_eq ! ( context. tracks. len( ) , 1 , "Expected exactly one track" ) ;
1600
+
1601
+ let track = & context. tracks [ 0 ] ;
1602
+ assert_eq ! (
1603
+ track. track_type,
1604
+ mp4:: TrackType :: Audio ,
1605
+ "Expected audio track"
1606
+ ) ;
1607
+
1608
+ // Check sample description
1609
+ let stsd = track. stsd . as_ref ( ) . expect ( "expected an stsd" ) ;
1610
+ assert_eq ! (
1611
+ stsd. descriptions. len( ) ,
1612
+ 1 ,
1613
+ "Expected one sample description"
1614
+ ) ;
1615
+
1616
+ let a = match stsd. descriptions . first ( ) . expect ( "expected a SampleEntry" ) {
1617
+ mp4:: SampleEntry :: Audio ( ref a) => a,
1618
+ _ => panic ! ( "expected an AudioSampleEntry" ) ,
1619
+ } ;
1620
+
1621
+ println ! ( "Audio track details:" ) ;
1622
+ println ! ( " Codec type: {:?}" , a. codec_type) ;
1623
+ println ! ( " Sample rate: {}" , a. samplerate) ;
1624
+ println ! ( " Channel count: {}" , a. channelcount) ;
1625
+
1626
+ // The parser should detect this as xHE-AAC
1627
+ assert_eq ! ( a. codec_type, mp4:: CodecType :: XHEAAC ) ;
1628
+
1629
+ // Based on ffprobe: 44.1kHz, 1 channel (mono)
1630
+ assert_eq ! ( a. samplerate, 44100.0 ) ;
1631
+ assert_eq ! ( a. channelcount, 1 ) ;
1632
+
1633
+ // Check codec-specific data
1634
+ match & a. codec_specific {
1635
+ mp4:: AudioCodecSpecific :: ES_Descriptor ( ref esds) => {
1636
+ println ! ( " ESDS present" ) ;
1637
+ println ! ( " Audio object type: {:?}" , esds. audio_object_type) ;
1638
+ println ! (
1639
+ " Extended audio object type: {:?}" ,
1640
+ esds. extended_audio_object_type
1641
+ ) ;
1642
+ println ! ( " Audio sample rate: {:?}" , esds. audio_sample_rate) ;
1643
+ println ! ( " Audio channel count: {:?}" , esds. audio_channel_count) ;
1644
+
1645
+ // Should be xHE-AAC with audio object type 42
1646
+ assert_eq ! ( esds. audio_codec, mp4:: CodecType :: XHEAAC ) ;
1647
+ assert_eq ! ( esds. audio_object_type, Some ( 42 ) ) ;
1648
+
1649
+ // Verify ESDS matches the container info
1650
+ if let Some ( sample_rate) = esds. audio_sample_rate {
1651
+ assert_eq ! ( sample_rate, 44100 ) ;
1652
+ }
1653
+ if let Some ( channel_count) = esds. audio_channel_count {
1654
+ assert_eq ! ( channel_count, 1 ) ;
1655
+ }
1656
+ }
1657
+ _ => panic ! ( "Expected ES descriptor for xHE-AAC audio" ) ,
1658
+ }
1659
+
1660
+ println ! ( "xHE-AAC file parsing test completed successfully" ) ;
1661
+ }
0 commit comments