@@ -158,15 +158,33 @@ impl<W: Write> WriteBox<&mut W> for Hev1Box {
158
158
}
159
159
}
160
160
161
- #[ derive( Debug , Clone , PartialEq , Eq , Default , Serialize ) ]
161
+ #[ derive( Default , Debug , Clone , PartialEq , Eq , Serialize ) ]
162
162
pub struct HvcCBox {
163
163
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 > ,
164
181
}
165
182
166
183
impl HvcCBox {
167
184
pub fn new ( ) -> Self {
168
185
Self {
169
186
configuration_version : 1 ,
187
+ ..Default :: default ( )
170
188
}
171
189
}
172
190
}
@@ -177,29 +195,122 @@ impl Mp4Box for HvcCBox {
177
195
}
178
196
179
197
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 > ( )
181
205
}
182
206
183
207
fn to_json ( & self ) -> Result < String > {
184
208
Ok ( serde_json:: to_string ( & self ) . unwrap ( ) )
185
209
}
186
210
187
211
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
+ ) )
190
231
}
191
232
}
192
233
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
+ }
196
239
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
+ }
198
246
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
+ }
200
294
201
295
Ok ( HvcCBox {
202
296
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,
203
314
} )
204
315
}
205
316
}
@@ -210,6 +321,40 @@ impl<W: Write> WriteBox<&mut W> for HvcCBox {
210
321
BoxHeader :: new ( self . box_type ( ) , size) . write ( writer) ?;
211
322
212
323
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
+
213
358
Ok ( size)
214
359
}
215
360
}
@@ -232,6 +377,7 @@ mod tests {
232
377
depth : 24 ,
233
378
hvcc : HvcCBox {
234
379
configuration_version : 1 ,
380
+ ..Default :: default ( )
235
381
} ,
236
382
} ;
237
383
let mut buf = Vec :: new ( ) ;
0 commit comments