@@ -1161,6 +1161,7 @@ pub enum VideoCodecSpecific {
1161
1161
AV1Config ( AV1ConfigBox ) ,
1162
1162
ESDSConfig ( TryVec < u8 > ) ,
1163
1163
H263Config ( TryVec < u8 > ) ,
1164
+ HEVCConfig ( HEVCConfigBox ) ,
1164
1165
}
1165
1166
1166
1167
#[ derive( Debug ) ]
@@ -1233,6 +1234,44 @@ impl AV1ConfigBox {
1233
1234
}
1234
1235
}
1235
1236
1237
+ // Spec 8.3.2.1.2 HEVCDecoderConfigurationRecord
1238
+ #[ derive( Debug ) ]
1239
+ pub struct NALUnit {
1240
+ pub nal_unit_length : u16 ,
1241
+ pub nal_unit_content : TryVec < u8 > ,
1242
+ }
1243
+
1244
+ #[ derive( Debug ) ]
1245
+ pub struct HEVCArrayInfo {
1246
+ pub array_completeness : u8 ,
1247
+ pub nal_unit_type : u8 ,
1248
+ pub num_nalus : u16 ,
1249
+ pub nal_units : TryVec < NALUnit > ,
1250
+ }
1251
+
1252
+ #[ derive( Debug ) ]
1253
+ pub struct HEVCConfigBox {
1254
+ pub configuration_version : u8 ,
1255
+ pub general_profile_space : u8 ,
1256
+ pub general_tier_flag : u8 ,
1257
+ pub general_profile_idc : u8 ,
1258
+ pub general_profile_compatibility_flags : u32 ,
1259
+ pub general_constraint_indicator_flags : u64 ,
1260
+ pub general_level_idc : u8 ,
1261
+ pub min_spatial_segmentation_idc : u16 ,
1262
+ pub parallelism_type : u8 ,
1263
+ pub chroma_format_idc : u8 ,
1264
+ pub bit_depth_luma_minus8 : u8 ,
1265
+ pub bit_depth_chroma_minus8 : u8 ,
1266
+ pub avg_frame_rate : u16 ,
1267
+ pub constant_frame_rate : u8 ,
1268
+ pub num_temporal_layers : u8 ,
1269
+ pub temporal_id_nested : u8 ,
1270
+ pub length_size_minus_one : u8 ,
1271
+ pub num_of_arrays : u8 ,
1272
+ pub array_infos : TryVec < HEVCArrayInfo > ,
1273
+ }
1274
+
1236
1275
#[ derive( Debug ) ]
1237
1276
pub struct FLACMetadataBlock {
1238
1277
pub block_type : u8 ,
@@ -2060,6 +2099,7 @@ pub enum CodecType {
2060
2099
LPCM , // QT
2061
2100
ALAC ,
2062
2101
H263 ,
2102
+ HEVC ,
2063
2103
#[ cfg( feature = "3gpp" ) ]
2064
2104
AMRNB ,
2065
2105
#[ cfg( feature = "3gpp" ) ]
@@ -4927,6 +4967,102 @@ fn read_av1c<T: Read>(src: &mut BMFFBox<T>) -> Result<AV1ConfigBox> {
4927
4967
} )
4928
4968
}
4929
4969
4970
+ fn read_hvcc < T : Read > ( src : & mut BMFFBox < T > ) -> Result < HEVCConfigBox > {
4971
+ let configuration_version = src. read_u8 ( ) ?;
4972
+ let ( general_profile_space, general_tier_flag, general_profile_idc) = {
4973
+ let byte = src. read_u8 ( ) ?;
4974
+ ( ( byte >> 6 ) & 0x03 , ( byte >> 5 ) & 0x01 , byte & 0x1F )
4975
+ } ;
4976
+ let general_profile_compatibility_flags = src. read_u32 :: < byteorder:: BigEndian > ( ) ?;
4977
+ let general_constraint_indicator_flags = {
4978
+ let flag_high = src. read_u32 :: < byteorder:: BigEndian > ( ) ?;
4979
+ let flag_low: u16 = src. read_u16 :: < byteorder:: BigEndian > ( ) ?;
4980
+ ( flag_high as u64 ) << 16 | flag_low as u64
4981
+ } ;
4982
+ let general_level_idc = src. read_u8 ( ) ?;
4983
+ let ( min_spatial_segmentation_idc, parallelism_type, chroma_format_idc) = {
4984
+ let byte = src. read_u32 :: < byteorder:: BigEndian > ( ) ?;
4985
+ (
4986
+ ( ( byte >> 16 ) & 0x0FFF ) as u16 ,
4987
+ ( ( byte >> 8 ) & 0x03 ) as u8 ,
4988
+ ( byte & 0x03 ) as u8 ,
4989
+ )
4990
+ } ;
4991
+ let ( bit_depth_luma_minus8, bit_depth_chroma_minus8) = {
4992
+ let byte = src. read_u16 :: < byteorder:: BigEndian > ( ) ?;
4993
+ ( ( ( byte >> 8 ) & 0x07 ) as u8 , ( byte & 0x07 ) as u8 )
4994
+ } ;
4995
+ let avg_frame_rate = src. read_u16 :: < byteorder:: BigEndian > ( ) ?;
4996
+ let ( constant_frame_rate, num_temporal_layers, temporal_id_nested, length_size_minus_one) = {
4997
+ let byte = src. read_u8 ( ) ?;
4998
+ (
4999
+ ( byte >> 6 ) & 0x03 ,
5000
+ ( byte >> 3 ) & 0x07 ,
5001
+ ( byte >> 2 ) & 0x01 ,
5002
+ byte & 0x03 ,
5003
+ )
5004
+ } ;
5005
+ let num_of_arrays = src. read_u8 ( ) ?;
5006
+ let mut array_infos = TryVec :: new ( ) ;
5007
+ for _i in 0 ..num_of_arrays {
5008
+ let array_info = read_hevc_arry_info ( src) ?;
5009
+ array_infos. push ( array_info) ?;
5010
+ }
5011
+ Ok ( HEVCConfigBox {
5012
+ configuration_version,
5013
+ general_profile_space,
5014
+ general_tier_flag,
5015
+ general_profile_idc,
5016
+ general_profile_compatibility_flags,
5017
+ general_constraint_indicator_flags,
5018
+ general_level_idc,
5019
+ min_spatial_segmentation_idc,
5020
+ parallelism_type,
5021
+ chroma_format_idc,
5022
+ bit_depth_luma_minus8,
5023
+ bit_depth_chroma_minus8,
5024
+ avg_frame_rate,
5025
+ constant_frame_rate,
5026
+ num_temporal_layers,
5027
+ temporal_id_nested,
5028
+ length_size_minus_one,
5029
+ num_of_arrays,
5030
+ array_infos,
5031
+ } )
5032
+ }
5033
+
5034
+ fn read_hevc_arry_info < T : Read > ( src : & mut BMFFBox < T > ) -> Result < HEVCArrayInfo > {
5035
+ let ( array_completeness, nal_unit_type) = {
5036
+ let byte = src. read_u8 ( ) ?;
5037
+ ( ( byte >> 7 ) & 0x01 , byte & 0x3F )
5038
+ } ;
5039
+ let num_nalus = src. read_u16 :: < byteorder:: BigEndian > ( ) ?;
5040
+ let mut nal_units = TryVec :: new ( ) ;
5041
+ for _i in 0 ..num_nalus {
5042
+ let nal = read_nal_unit ( src) ?;
5043
+ nal_units. push ( nal) ?;
5044
+ }
5045
+ Ok ( HEVCArrayInfo {
5046
+ array_completeness,
5047
+ nal_unit_type,
5048
+ num_nalus,
5049
+ nal_units,
5050
+ } )
5051
+ }
5052
+
5053
+ fn read_nal_unit < T : Read > ( src : & mut BMFFBox < T > ) -> Result < NALUnit > {
5054
+ let nal_unit_length = src. read_u16 :: < byteorder:: BigEndian > ( ) ?;
5055
+ let mut nal_unit_content = TryVec :: new ( ) ;
5056
+ for _i in 0 ..nal_unit_length {
5057
+ let byte = src. read_u8 ( ) ?;
5058
+ nal_unit_content. push ( byte) ?;
5059
+ }
5060
+ Ok ( NALUnit {
5061
+ nal_unit_length,
5062
+ nal_unit_content,
5063
+ } )
5064
+ }
5065
+
4930
5066
fn read_flac_metadata < T : Read > ( src : & mut BMFFBox < T > ) -> Result < FLACMetadataBlock > {
4931
5067
let temp = src. read_u8 ( ) ?;
4932
5068
let block_type = temp & 0x7f ;
@@ -5456,6 +5592,8 @@ fn read_video_sample_entry<T: Read>(src: &mut BMFFBox<T>) -> Result<SampleEntry>
5456
5592
BoxType :: AV1SampleEntry => CodecType :: AV1 ,
5457
5593
BoxType :: ProtectedVisualSampleEntry => CodecType :: EncryptedVideo ,
5458
5594
BoxType :: H263SampleEntry => CodecType :: H263 ,
5595
+ BoxType :: HEVCSampleEntry => CodecType :: HEVC ,
5596
+ BoxType :: HEVCSampleEntry2 => CodecType :: HEVC ,
5459
5597
_ => {
5460
5598
debug ! ( "Unsupported video codec, box {:?} found" , name) ;
5461
5599
CodecType :: Unknown
@@ -5567,6 +5705,13 @@ fn read_video_sample_entry<T: Read>(src: &mut BMFFBox<T>) -> Result<SampleEntry>
5567
5705
debug ! ( "{:?} (sinf)" , sinf) ;
5568
5706
protection_info. push ( sinf) ?;
5569
5707
}
5708
+ BoxType :: HEVCConfigurationBox => {
5709
+ if name != BoxType :: HEVCSampleEntry && name != BoxType :: HEVCSampleEntry2 {
5710
+ return Status :: StsdBadVideoSampleEntry . into ( ) ;
5711
+ }
5712
+ let hvcc = read_hvcc ( & mut b) ?;
5713
+ codec_specific = Some ( VideoCodecSpecific :: HEVCConfig ( hvcc) ) ;
5714
+ }
5570
5715
_ => {
5571
5716
debug ! ( "Unsupported video codec, box {:?} found" , b. head. name) ;
5572
5717
skip_box_content ( & mut b) ?;
0 commit comments