@@ -11,6 +11,7 @@ extern crate afl;
11
11
extern crate byteorder;
12
12
use byteorder:: ReadBytesExt ;
13
13
use std:: io:: { Read , Take } ;
14
+ use std:: io:: Cursor ;
14
15
use std:: cmp;
15
16
16
17
mod boxes;
@@ -203,10 +204,17 @@ pub enum SampleEntry {
203
204
Unknown ,
204
205
}
205
206
207
+ #[ allow( non_camel_case_types) ]
208
+ #[ derive( Debug , Clone ) ]
209
+ pub struct ES_Descriptor {
210
+ pub audio_codec : CodecType ,
211
+ pub codec_specific_config : Vec < u8 > ,
212
+ }
213
+
206
214
#[ allow( non_camel_case_types) ]
207
215
#[ derive( Debug , Clone ) ]
208
216
pub enum AudioCodecSpecific {
209
- ES_Descriptor ( Vec < u8 > ) ,
217
+ ES_Descriptor ( ES_Descriptor ) ,
210
218
FLACSpecificBox ( FLACSpecificBox ) ,
211
219
OpusSpecificBox ( OpusSpecificBox ) ,
212
220
}
@@ -310,9 +318,10 @@ impl Default for TrackType {
310
318
fn default ( ) -> Self { TrackType :: Unknown }
311
319
}
312
320
313
- #[ derive( Debug ) ]
321
+ #[ derive( Debug , Clone , Copy , PartialEq ) ]
314
322
pub enum CodecType {
315
323
Unknown ,
324
+ MP3 ,
316
325
AAC ,
317
326
FLAC ,
318
327
Opus ,
@@ -1105,16 +1114,84 @@ fn read_flac_metadata<T: Read>(src: &mut BMFFBox<T>) -> Result<FLACMetadataBlock
1105
1114
} )
1106
1115
}
1107
1116
1108
- fn read_esds < T : Read > ( src : & mut BMFFBox < T > ) -> Result < AudioCodecSpecific > {
1117
+ fn read_esds < T : Read > ( src : & mut BMFFBox < T > ) -> Result < ES_Descriptor > {
1118
+ // Tags for elementary stream description
1119
+ const ESDESCR_TAG : u8 = 0x03 ;
1120
+ const DECODER_CONFIG_TAG : u8 = 0x04 ;
1121
+
1109
1122
let ( _, _) = try!( read_fullbox_extra ( src) ) ;
1110
1123
1111
1124
let esds_size = src. head . size - src. head . offset - 4 ;
1112
1125
if esds_size > BUF_SIZE_LIMIT {
1113
1126
return Err ( Error :: InvalidData ( "esds box exceeds BUF_SIZE_LIMIT" ) ) ;
1114
1127
}
1115
- let esds = try!( read_buf ( & mut src. content , esds_size as usize ) ) ;
1128
+ let esds_array = try!( read_buf ( src, esds_size as usize ) ) ;
1129
+
1130
+ // Parsing DecoderConfig descriptor to get the object_profile_indicator
1131
+ // for correct codec type.
1132
+ let object_profile_indicator = {
1133
+ // clone a esds cursor for parsing.
1134
+ let esds = & mut Cursor :: new ( & esds_array) ;
1135
+ let esds_tag = try!( esds. read_u8 ( ) ) ;
1136
+
1137
+ if esds_tag != ESDESCR_TAG {
1138
+ return Err ( Error :: Unsupported ( "fail to parse ES descriptor" ) ) ;
1139
+ }
1140
+
1141
+ let esds_extend = try!( esds. read_u8 ( ) ) ;
1142
+ // extension tag start from 0x80.
1143
+ if esds_extend >= 0x80 {
1144
+ // skip remaining extension and length.
1145
+ try!( skip ( esds, 5 ) ) ;
1146
+ } else {
1147
+ try!( skip ( esds, 2 ) ) ;
1148
+ }
1149
+
1150
+ let esds_flags = try!( esds. read_u8 ( ) ) ;
1116
1151
1117
- Ok ( AudioCodecSpecific :: ES_Descriptor ( esds) )
1152
+ // Stream dependency flag, first bit from left most.
1153
+ if esds_flags & 0x80 > 0 {
1154
+ // Skip uninteresting fields.
1155
+ try!( skip ( esds, 2 ) ) ;
1156
+ }
1157
+
1158
+ // Url flag, second bit from left most.
1159
+ if esds_flags & 0x40 > 0 {
1160
+ // Skip uninteresting fields.
1161
+ let skip_es_len: usize = try!( esds. read_u8 ( ) ) as usize + 2 ;
1162
+ try!( skip ( esds, skip_es_len) ) ;
1163
+ }
1164
+
1165
+ // find DecoderConfig descriptor (tag = DECODER_CONFIG_TAG)
1166
+ let dcds = try!( esds. read_u8 ( ) ) ;
1167
+ if dcds != DECODER_CONFIG_TAG {
1168
+ return Err ( Error :: Unsupported ( "fail to parse decoder config descriptor" ) ) ;
1169
+ }
1170
+
1171
+ let dcds_extend = try!( esds. read_u8 ( ) ) ;
1172
+ // extension tag start from 0x80.
1173
+ if dcds_extend >= 0x80 {
1174
+ // skip remains extension and length.
1175
+ try!( skip ( esds, 3 ) ) ;
1176
+ }
1177
+
1178
+ try!( esds. read_u8 ( ) )
1179
+ } ;
1180
+
1181
+ let codec = match object_profile_indicator {
1182
+ 0x40 | 0x41 => CodecType :: AAC ,
1183
+ 0x6B => CodecType :: MP3 ,
1184
+ _ => CodecType :: Unknown ,
1185
+ } ;
1186
+
1187
+ if codec == CodecType :: Unknown {
1188
+ return Err ( Error :: Unsupported ( "unknown audio codec" ) ) ;
1189
+ }
1190
+
1191
+ Ok ( ES_Descriptor {
1192
+ audio_codec : codec,
1193
+ codec_specific_config : esds_array,
1194
+ } )
1118
1195
}
1119
1196
1120
1197
/// Parse `FLACSpecificBox`.
@@ -1325,7 +1402,7 @@ fn read_video_sample_entry<T: Read>(src: &mut BMFFBox<T>, track: &mut Track) ->
1325
1402
. ok_or_else ( || Error :: InvalidData ( "malformed video sample entry" ) )
1326
1403
}
1327
1404
1328
- fn read_qt_wave_atom < T : Read > ( src : & mut BMFFBox < T > ) -> Result < AudioCodecSpecific > {
1405
+ fn read_qt_wave_atom < T : Read > ( src : & mut BMFFBox < T > ) -> Result < ES_Descriptor > {
1329
1406
let mut codec_specific = None ;
1330
1407
let mut iter = src. box_iter ( ) ;
1331
1408
while let Some ( mut b) = try!( iter. next_box ( ) ) {
@@ -1398,14 +1475,16 @@ fn read_audio_sample_entry<T: Read>(src: &mut BMFFBox<T>, track: &mut Track) ->
1398
1475
}
1399
1476
1400
1477
let esds = try!( read_esds ( & mut b) ) ;
1401
- codec_specific = Some ( esds) ;
1478
+ track. codec_type = esds. audio_codec ;
1479
+ codec_specific = Some ( AudioCodecSpecific :: ES_Descriptor ( esds) ) ;
1402
1480
}
1403
1481
BoxType :: FLACSpecificBox => {
1404
1482
if name != BoxType :: FLACSampleEntry ||
1405
1483
codec_specific. is_some ( ) {
1406
1484
return Err ( Error :: InvalidData ( "malformed audio sample entry" ) ) ;
1407
1485
}
1408
1486
let dfla = try!( read_dfla ( & mut b) ) ;
1487
+ track. codec_type = CodecType :: FLAC ;
1409
1488
codec_specific = Some ( AudioCodecSpecific :: FLACSpecificBox ( dfla) ) ;
1410
1489
}
1411
1490
BoxType :: OpusSpecificBox => {
@@ -1414,11 +1493,13 @@ fn read_audio_sample_entry<T: Read>(src: &mut BMFFBox<T>, track: &mut Track) ->
1414
1493
return Err ( Error :: InvalidData ( "malformed audio sample entry" ) ) ;
1415
1494
}
1416
1495
let dops = try!( read_dops ( & mut b) ) ;
1496
+ track. codec_type = CodecType :: Opus ;
1417
1497
codec_specific = Some ( AudioCodecSpecific :: OpusSpecificBox ( dops) ) ;
1418
1498
}
1419
1499
BoxType :: QTWaveAtom => {
1420
- let qt_desc = try!( read_qt_wave_atom ( & mut b) ) ;
1421
- codec_specific = Some ( qt_desc) ;
1500
+ let qt_esds = try!( read_qt_wave_atom ( & mut b) ) ;
1501
+ track. codec_type = qt_esds. audio_codec ;
1502
+ codec_specific = Some ( AudioCodecSpecific :: ES_Descriptor ( qt_esds) ) ;
1422
1503
}
1423
1504
_ => try!( skip_box_content ( & mut b) ) ,
1424
1505
}
0 commit comments