@@ -158,15 +158,33 @@ impl<W: Write> WriteBox<&mut W> for Hev1Box {
158158 }
159159}
160160
161- #[ derive( Debug , Clone , PartialEq , Eq , Default , Serialize ) ]
161+ #[ derive( Default , Debug , Clone , PartialEq , Eq , Serialize ) ]
162162pub struct HvcCBox {
163163 pub configuration_version : u8 ,
164+ pub general_profile_space : u8 ,
165+ pub general_tier_flag : bool ,
166+ pub general_profile_idc : u8 ,
167+ pub general_profile_compatibility_flags : u32 ,
168+ pub general_constraint_indicator_flag : u64 ,
169+ pub general_level_idc : u8 ,
170+ pub min_spatial_segmentation_idc : u16 ,
171+ pub parallelism_type : u8 ,
172+ pub chroma_format_idc : u8 ,
173+ pub bit_depth_luma_minus8 : u8 ,
174+ pub bit_depth_chroma_minus8 : u8 ,
175+ pub avg_frame_rate : u16 ,
176+ pub constant_frame_rate : u8 ,
177+ pub num_temporal_layers : u8 ,
178+ pub temporal_id_nested : bool ,
179+ pub length_size_minus_one : u8 ,
180+ pub arrays : Vec < HvcCArray > ,
164181}
165182
166183impl HvcCBox {
167184 pub fn new ( ) -> Self {
168185 Self {
169186 configuration_version : 1 ,
187+ ..Default :: default ( )
170188 }
171189 }
172190}
@@ -177,29 +195,122 @@ impl Mp4Box for HvcCBox {
177195 }
178196
179197 fn box_size ( & self ) -> u64 {
180- HEADER_SIZE + 1
198+ HEADER_SIZE
199+ + 23
200+ + self
201+ . arrays
202+ . iter ( )
203+ . map ( |a| 3 + a. nalus . iter ( ) . map ( |x| 2 + x. data . len ( ) as u64 ) . sum :: < u64 > ( ) )
204+ . sum :: < u64 > ( )
181205 }
182206
183207 fn to_json ( & self ) -> Result < String > {
184208 Ok ( serde_json:: to_string ( & self ) . unwrap ( ) )
185209 }
186210
187211 fn summary ( & self ) -> Result < String > {
188- let s = format ! ( "configuration_version={}" , self . configuration_version) ;
189- Ok ( s)
212+ Ok ( format ! ( "configuration_version={} general_profile_space={} general_tier_flag={} general_profile_idc={} general_profile_compatibility_flags={} general_constraint_indicator_flag={} general_level_idc={} min_spatial_segmentation_idc={} parallelism_type={} chroma_format_idc={} bit_depth_luma_minus8={} bit_depth_chroma_minus8={} avg_frame_rate={} constant_frame_rate={} num_temporal_layers={} temporal_id_nested={} length_size_minus_one={}" ,
213+ self . configuration_version,
214+ self . general_profile_space,
215+ self . general_tier_flag,
216+ self . general_profile_idc,
217+ self . general_profile_compatibility_flags,
218+ self . general_constraint_indicator_flag,
219+ self . general_level_idc,
220+ self . min_spatial_segmentation_idc,
221+ self . parallelism_type,
222+ self . chroma_format_idc,
223+ self . bit_depth_luma_minus8,
224+ self . bit_depth_chroma_minus8,
225+ self . avg_frame_rate,
226+ self . constant_frame_rate,
227+ self . num_temporal_layers,
228+ self . temporal_id_nested,
229+ self . length_size_minus_one
230+ ) )
190231 }
191232}
192233
193- impl < R : Read + Seek > ReadBox < & mut R > for HvcCBox {
194- fn read_box ( reader : & mut R , size : u64 ) -> Result < Self > {
195- let start = box_start ( reader) ?;
234+ #[ derive( Debug , Clone , PartialEq , Eq , Default , Serialize ) ]
235+ pub struct HvcCArrayNalu {
236+ pub size : u16 ,
237+ pub data : Vec < u8 > ,
238+ }
196239
197- let configuration_version = reader. read_u8 ( ) ?;
240+ #[ derive( Debug , Clone , PartialEq , Eq , Default , Serialize ) ]
241+ pub struct HvcCArray {
242+ pub completeness : bool ,
243+ pub nal_unit_type : u8 ,
244+ pub nalus : Vec < HvcCArrayNalu > ,
245+ }
198246
199- skip_bytes_to ( reader, start + size) ?;
247+ impl < R : Read + Seek > ReadBox < & mut R > for HvcCBox {
248+ fn read_box ( reader : & mut R , _size : u64 ) -> Result < Self > {
249+ let configuration_version = reader. read_u8 ( ) ?;
250+ let params = reader. read_u8 ( ) ?;
251+ let general_profile_space = params & 0b11000000 >> 6 ;
252+ let general_tier_flag = ( params & 0b00100000 >> 5 ) > 0 ;
253+ let general_profile_idc = params & 0b00011111 ;
254+
255+ let general_profile_compatibility_flags = reader. read_u32 :: < BigEndian > ( ) ?;
256+ let general_constraint_indicator_flag = reader. read_u48 :: < BigEndian > ( ) ?;
257+ let general_level_idc = reader. read_u8 ( ) ?;
258+ let min_spatial_segmentation_idc = reader. read_u16 :: < BigEndian > ( ) ? & 0x0FFF ;
259+ let parallelism_type = reader. read_u8 ( ) ? & 0b11 ;
260+ let chroma_format_idc = reader. read_u8 ( ) ? & 0b11 ;
261+ let bit_depth_luma_minus8 = reader. read_u8 ( ) ? & 0b111 ;
262+ let bit_depth_chroma_minus8 = reader. read_u8 ( ) ? & 0b111 ;
263+ let avg_frame_rate = reader. read_u16 :: < BigEndian > ( ) ?;
264+
265+ let params = reader. read_u8 ( ) ?;
266+ let constant_frame_rate = params & 0b11000000 >> 6 ;
267+ let num_temporal_layers = params & 0b00111000 >> 3 ;
268+ let temporal_id_nested = ( params & 0b00000100 >> 2 ) > 0 ;
269+ let length_size_minus_one = params & 0b000011 ;
270+
271+ let num_of_arrays = reader. read_u8 ( ) ?;
272+
273+ let mut arrays = Vec :: with_capacity ( num_of_arrays as _ ) ;
274+ for _ in 0 ..num_of_arrays {
275+ let params = reader. read_u8 ( ) ?;
276+ let num_nalus = reader. read_u16 :: < BigEndian > ( ) ?;
277+ let mut nalus = Vec :: with_capacity ( num_nalus as usize ) ;
278+
279+ for _ in 0 ..num_nalus {
280+ let size = reader. read_u16 :: < BigEndian > ( ) ?;
281+ let mut data = vec ! [ 0 ; size as usize ] ;
282+
283+ reader. read_exact ( & mut data) ?;
284+
285+ nalus. push ( HvcCArrayNalu { size, data } )
286+ }
287+
288+ arrays. push ( HvcCArray {
289+ completeness : ( params & 0b10000000 ) > 0 ,
290+ nal_unit_type : params & 0b111111 ,
291+ nalus,
292+ } ) ;
293+ }
200294
201295 Ok ( HvcCBox {
202296 configuration_version,
297+ general_profile_space,
298+ general_tier_flag,
299+ general_profile_idc,
300+ general_profile_compatibility_flags,
301+ general_constraint_indicator_flag,
302+ general_level_idc,
303+ min_spatial_segmentation_idc,
304+ parallelism_type,
305+ chroma_format_idc,
306+ bit_depth_luma_minus8,
307+ bit_depth_chroma_minus8,
308+ avg_frame_rate,
309+ constant_frame_rate,
310+ num_temporal_layers,
311+ temporal_id_nested,
312+ length_size_minus_one,
313+ arrays,
203314 } )
204315 }
205316}
@@ -210,6 +321,40 @@ impl<W: Write> WriteBox<&mut W> for HvcCBox {
210321 BoxHeader :: new ( self . box_type ( ) , size) . write ( writer) ?;
211322
212323 writer. write_u8 ( self . configuration_version ) ?;
324+ let general_profile_space = ( self . general_profile_space & 0b11 ) << 6 ;
325+ let general_tier_flag = u8:: from ( self . general_tier_flag ) << 5 ;
326+ let general_profile_idc = self . general_profile_idc & 0b11111 ;
327+
328+ writer. write_u8 ( general_profile_space | general_tier_flag | general_profile_idc) ?;
329+ writer. write_u32 :: < BigEndian > ( self . general_profile_compatibility_flags ) ?;
330+ writer. write_u48 :: < BigEndian > ( self . general_constraint_indicator_flag ) ?;
331+ writer. write_u8 ( self . general_level_idc ) ?;
332+
333+ writer. write_u16 :: < BigEndian > ( self . min_spatial_segmentation_idc & 0x0FFF ) ?;
334+ writer. write_u8 ( self . parallelism_type & 0b11 ) ?;
335+ writer. write_u8 ( self . chroma_format_idc & 0b11 ) ?;
336+ writer. write_u8 ( self . bit_depth_luma_minus8 & 0b111 ) ?;
337+ writer. write_u8 ( self . bit_depth_chroma_minus8 & 0b111 ) ?;
338+ writer. write_u16 :: < BigEndian > ( self . avg_frame_rate ) ?;
339+
340+ let constant_frame_rate = ( self . constant_frame_rate & 0b11 ) << 6 ;
341+ let num_temporal_layers = ( self . num_temporal_layers & 0b111 ) << 3 ;
342+ let temporal_id_nested = u8:: from ( self . temporal_id_nested ) << 2 ;
343+ let length_size_minus_one = self . length_size_minus_one & 0b11 ;
344+ writer. write_u8 (
345+ constant_frame_rate | num_temporal_layers | temporal_id_nested | length_size_minus_one,
346+ ) ?;
347+ writer. write_u8 ( self . arrays . len ( ) as u8 ) ?;
348+ for arr in & self . arrays {
349+ writer. write_u8 ( ( arr. nal_unit_type & 0b111111 ) | u8:: from ( arr. completeness ) << 7 ) ?;
350+ writer. write_u16 :: < BigEndian > ( arr. nalus . len ( ) as _ ) ?;
351+
352+ for nalu in & arr. nalus {
353+ writer. write_u16 :: < BigEndian > ( nalu. size ) ?;
354+ writer. write_all ( & nalu. data ) ?;
355+ }
356+ }
357+
213358 Ok ( size)
214359 }
215360}
@@ -232,6 +377,7 @@ mod tests {
232377 depth : 24 ,
233378 hvcc : HvcCBox {
234379 configuration_version : 1 ,
380+ ..Default :: default ( )
235381 } ,
236382 } ;
237383 let mut buf = Vec :: new ( ) ;
0 commit comments