1 /*****************************************************************************
3 *****************************************************************************
4 * Copyright (C) 2012-2014 L-SMASH project
6 * Authors: Yusuke Nakamura <muken.the.vfrmaniac@gmail.com>
8 * Permission to use, copy, modify, and/or distribute this software for any
9 * purpose with or without fee is hereby granted, provided that the above
10 * copyright notice and this permission notice appear in all copies.
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
13 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
14 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
15 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
16 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
17 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
18 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19 *****************************************************************************/
21 /* This file is available under an ISC license. */
23 #include "common/internal.h" /* must be placed first */
31 /***************************************************************************
34 ***************************************************************************/
37 #define IF_INVALID_VALUE( x ) if( x )
39 struct lsmash_vc1_header_tag
47 VC1_ADVANCED_PICTURE_TYPE_P
= 0x0, /* 0b0 */
48 VC1_ADVANCED_PICTURE_TYPE_B
= 0x2, /* 0b10 */
49 VC1_ADVANCED_PICTURE_TYPE_I
= 0x6, /* 0b110 */
50 VC1_ADVANCED_PICTURE_TYPE_BI
= 0xE, /* 0b1110 */
51 VC1_ADVANCED_PICTURE_TYPE_SKIPPED
= 0xF, /* 0b1111 */
56 VC1_ADVANCED_FIELD_PICTURE_TYPE_II
= 0x0, /* 0b000 */
57 VC1_ADVANCED_FIELD_PICTURE_TYPE_IP
= 0x1, /* 0b001 */
58 VC1_ADVANCED_FIELD_PICTURE_TYPE_PI
= 0x2, /* 0b010 */
59 VC1_ADVANCED_FIELD_PICTURE_TYPE_PP
= 0x3, /* 0b011 */
60 VC1_ADVANCED_FIELD_PICTURE_TYPE_BB
= 0x4, /* 0b100 */
61 VC1_ADVANCED_FIELD_PICTURE_TYPE_BBI
= 0x5, /* 0b101 */
62 VC1_ADVANCED_FIELD_PICTURE_TYPE_BIB
= 0x6, /* 0b110 */
63 VC1_ADVANCED_FIELD_PICTURE_TYPE_BIBI
= 0x7, /* 0b111 */
64 } vc1_field_picture_type
;
68 VC1_FRAME_CODING_MODE_PROGRESSIVE
= 0x0, /* 0b0 */
69 VC1_FRAME_CODING_MODE_FRAME_INTERLACE
= 0x2, /* 0b10 */
70 VC1_FRAME_CODING_MODE_FIELD_INTERLACE
= 0x3, /* 0b11 */
71 } vc1_frame_coding_mode
;
73 static void vc1_destroy_header( lsmash_vc1_header_t
*hdr
)
77 lsmash_free( hdr
->ebdu
);
81 void lsmash_destroy_vc1_headers( lsmash_vc1_specific_parameters_t
*param
)
85 vc1_destroy_header( param
->seqhdr
);
86 vc1_destroy_header( param
->ephdr
);
91 void vc1_destruct_specific_data( void *data
)
95 lsmash_destroy_vc1_headers( data
);
99 void vc1_cleanup_parser( vc1_info_t
*info
)
103 lsmash_destroy_vc1_headers( &info
->dvc1_param
);
104 lsmash_destroy_multiple_buffers( info
->buffer
.bank
);
105 lsmash_bits_adhoc_cleanup( info
->bits
);
117 memset( info
, 0, sizeof(vc1_info_t
) );
118 vc1_stream_buffer_t
*sb
= &info
->buffer
;
119 sb
->bank
= lsmash_create_multiple_buffers( parse_only
? 1 : 3, VC1_DEFAULT_BUFFER_SIZE
);
122 sb
->rbdu
= lsmash_withdraw_buffer( sb
->bank
, 1 );
125 info
->access_unit
.data
= lsmash_withdraw_buffer( sb
->bank
, 2 );
126 info
->access_unit
.incomplete_data
= lsmash_withdraw_buffer( sb
->bank
, 3 );
128 info
->bits
= lsmash_bits_adhoc_create();
131 lsmash_destroy_multiple_buffers( sb
->bank
);
134 info
->prev_bdu_type
= 0xFF; /* 0xFF is a forbidden value. */
138 uint64_t vc1_find_next_start_code_prefix
142 uint64_t *trailing_zero_bytes
145 uint64_t length
= 0; /* the length of the latest EBDU */
146 uint64_t count
= 0; /* the number of the trailing zero bytes after the latest EBDU */
147 if( !lsmash_bs_is_end( bs
, VC1_START_CODE_LENGTH
- 1 )
148 && 0x000001 == lsmash_bs_show_be24( bs
, 0 ) )
150 *bdu_type
= lsmash_bs_show_byte( bs
, VC1_START_CODE_PREFIX_LENGTH
);
151 length
= VC1_START_CODE_LENGTH
;
152 /* Find the start code of the next EBDU and get the length of the latest EBDU. */
153 int no_more
= lsmash_bs_is_end( bs
, length
+ VC1_START_CODE_LENGTH
- 1 );
156 uint32_t sync_bytes
= lsmash_bs_show_be24( bs
, length
);
157 while( 0x000001 != sync_bytes
)
159 no_more
= lsmash_bs_is_end( bs
, ++length
+ VC1_START_CODE_LENGTH
- 1 );
163 sync_bytes
|= lsmash_bs_show_byte( bs
, length
+ VC1_START_CODE_PREFIX_LENGTH
- 1 );
164 sync_bytes
&= 0xFFFFFF;
168 length
= lsmash_bs_get_remaining_buffer_size( bs
);
169 /* Any EBDU has no consecutive zero bytes at the end. */
170 while( 0x00 == lsmash_bs_show_byte( bs
, length
- 1 ) )
177 *bdu_type
= 0xFF; /* 0xFF is a forbidden value. */
178 *trailing_zero_bytes
= count
;
182 int vc1_check_next_start_code_suffix
188 uint8_t bdu_type
= *((uint8_t *)lsmash_bs_get_buffer_data( bs
) + VC1_START_CODE_PREFIX_LENGTH
);
189 if( (bdu_type
>= 0x00 && bdu_type
<= 0x09)
190 || (bdu_type
>= 0x20 && bdu_type
<= 0xFF) )
191 return -1; /* SMPTE reserved or forbidden value */
192 *p_bdu_type
= bdu_type
;
196 static inline uint8_t vc1_get_vlc( lsmash_bits_t
*bits
, int length
)
199 for( int i
= 0; i
< length
; i
++ )
200 if( lsmash_bits_get( bits
, 1 ) )
201 value
= (value
<< 1) | 1;
210 /* Convert EBDU (Encapsulated Byte Data Unit) to RBDU (Raw Byte Data Unit). */
211 static uint8_t *vc1_remove_emulation_prevention( uint8_t *src
, uint64_t src_length
, uint8_t *dst
)
213 uint8_t *src_end
= src
+ src_length
;
214 while( src
< src_end
)
215 if( ((src
+ 2) < src_end
) && !src
[0] && !src
[1] && (src
[2] == 0x03) )
217 /* 0x000003 -> 0x0000 */
220 src
++; /* Skip emulation_prevention_three_byte (0x03). */
227 static int vc1_import_rbdu_from_ebdu( lsmash_bits_t
*bits
, uint8_t *rbdu_buffer
, uint8_t *ebdu
, uint64_t ebdu_size
)
229 uint8_t *rbdu_start
= rbdu_buffer
;
230 uint8_t *rbdu_end
= vc1_remove_emulation_prevention( ebdu
, ebdu_size
, rbdu_buffer
);
231 uint64_t rbdu_length
= rbdu_end
- rbdu_start
;
232 return lsmash_bits_import_data( bits
, rbdu_start
, rbdu_length
);
235 static void vc1_parse_hrd_param( lsmash_bits_t
*bits
, vc1_hrd_param_t
*hrd_param
)
237 hrd_param
->hrd_num_leaky_buckets
= lsmash_bits_get( bits
, 5 );
238 lsmash_bits_get( bits
, 4 ); /* bitrate_exponent */
239 lsmash_bits_get( bits
, 4 ); /* buffer_size_exponent */
240 for( uint8_t i
= 0; i
< hrd_param
->hrd_num_leaky_buckets
; i
++ )
242 lsmash_bits_get( bits
, 16 ); /* hrd_rate */
243 lsmash_bits_get( bits
, 16 ); /* hrd_buffer */
247 int vc1_parse_sequence_header( vc1_info_t
*info
, uint8_t *ebdu
, uint64_t ebdu_size
, int try_append
)
249 lsmash_bits_t
*bits
= info
->bits
;
250 vc1_sequence_header_t
*sequence
= &info
->sequence
;
251 if( vc1_import_rbdu_from_ebdu( bits
, info
->buffer
.rbdu
, ebdu
+ VC1_START_CODE_LENGTH
, ebdu_size
) )
253 memset( sequence
, 0, sizeof(vc1_sequence_header_t
) );
254 sequence
->profile
= lsmash_bits_get( bits
, 2 );
255 if( sequence
->profile
!= 3 )
256 return -1; /* SMPTE Reserved */
257 sequence
->level
= lsmash_bits_get( bits
, 3 );
258 if( sequence
->level
> 4 )
259 return -1; /* SMPTE Reserved */
260 sequence
->colordiff_format
= lsmash_bits_get( bits
, 2 );
261 if( sequence
->colordiff_format
!= 1 )
262 return -1; /* SMPTE Reserved */
263 lsmash_bits_get( bits
, 9 ); /* frmrtq_postproc (3)
264 * bitrtq_postproc (5)
265 * postproc_flag (1) */
266 sequence
->max_coded_width
= lsmash_bits_get( bits
, 12 );
267 sequence
->max_coded_height
= lsmash_bits_get( bits
, 12 );
268 lsmash_bits_get( bits
, 1 ); /* pulldown */
269 sequence
->interlace
= lsmash_bits_get( bits
, 1 );
270 lsmash_bits_get( bits
, 4 ); /* tfcntrflag (1)
274 if( lsmash_bits_get( bits
, 1 ) ) /* display_ext */
276 sequence
->disp_horiz_size
= lsmash_bits_get( bits
, 14 ) + 1;
277 sequence
->disp_vert_size
= lsmash_bits_get( bits
, 14 ) + 1;
278 if( lsmash_bits_get( bits
, 1 ) ) /* aspect_ratio_flag */
280 uint8_t aspect_ratio
= lsmash_bits_get( bits
, 4 );
281 if( aspect_ratio
== 15 )
283 sequence
->aspect_width
= lsmash_bits_get( bits
, 8 ) + 1; /* aspect_horiz_size */
284 sequence
->aspect_height
= lsmash_bits_get( bits
, 8 ) + 1; /* aspect_vert_size */
290 uint32_t aspect_width
;
291 uint32_t aspect_height
;
292 } vc1_aspect_ratio
[15] =
294 { 0, 0 }, { 1, 1 }, { 12, 11 }, { 10, 11 }, { 16, 11 }, { 40, 33 }, { 24, 11 },
295 { 20, 11 }, { 32, 11 }, { 80, 33 }, { 18, 11 }, { 15, 11 }, { 64, 33 }, { 160, 99 },
296 { 0, 0 } /* SMPTE Reserved */
298 sequence
->aspect_width
= vc1_aspect_ratio
[ aspect_ratio
].aspect_width
;
299 sequence
->aspect_height
= vc1_aspect_ratio
[ aspect_ratio
].aspect_height
;
302 sequence
->framerate_flag
= lsmash_bits_get( bits
, 1 );
303 if( sequence
->framerate_flag
)
305 if( lsmash_bits_get( bits
, 1 ) ) /* framerateind */
307 sequence
->framerate_numerator
= lsmash_bits_get( bits
, 16 ) + 1;
308 sequence
->framerate_denominator
= 32;
312 static const uint32_t vc1_frameratenr_table
[8] = { 0, 24, 25, 30, 50, 60, 48, 72 };
313 uint8_t frameratenr
= lsmash_bits_get( bits
, 8 );
314 IF_INVALID_VALUE( frameratenr
== 0 )
315 return -1; /* Forbidden */
316 if( frameratenr
> 7 )
317 return -1; /* SMPTE Reserved */
318 uint8_t frameratedr
= lsmash_bits_get( bits
, 4 );
319 if( frameratedr
!= 1 && frameratedr
!= 2 )
320 return -1; /* 0: Forbidden, 3-15: SMPTE Reserved */
321 if( frameratedr
== 1 )
323 sequence
->framerate_numerator
= vc1_frameratenr_table
[ frameratenr
];
324 sequence
->framerate_denominator
= 1;
328 sequence
->framerate_numerator
= vc1_frameratenr_table
[ frameratenr
] * 1000;
329 sequence
->framerate_denominator
= 1001;
333 if( lsmash_bits_get( bits
, 1 ) ) /* color_format_flag */
335 sequence
->color_prim
= lsmash_bits_get( bits
, 8 );
336 sequence
->transfer_char
= lsmash_bits_get( bits
, 8 );
337 sequence
->matrix_coef
= lsmash_bits_get( bits
, 8 );
339 sequence
->hrd_param_flag
= lsmash_bits_get( bits
, 1 );
340 if( sequence
->hrd_param_flag
)
341 vc1_parse_hrd_param( bits
, &sequence
->hrd_param
);
343 /* '1' and stuffing bits ('0's) */
344 IF_INVALID_VALUE( !lsmash_bits_get( bits
, 1 ) )
346 lsmash_bits_empty( bits
);
347 /* Preparation for creating VC1SpecificBox */
350 /* Update some specific parameters. */
351 lsmash_vc1_specific_parameters_t
*param
= &info
->dvc1_param
;
352 lsmash_vc1_header_t
*seqhdr
= param
->seqhdr
;
355 seqhdr
= lsmash_malloc( sizeof(lsmash_vc1_header_t
) );
358 seqhdr
->ebdu
= lsmash_memdup( ebdu
, ebdu_size
);
361 lsmash_free( seqhdr
);
364 seqhdr
->ebdu_size
= ebdu_size
;
365 param
->seqhdr
= seqhdr
;
367 else if( seqhdr
&& seqhdr
->ebdu
&& (seqhdr
->ebdu_size
== ebdu_size
) )
368 param
->multiple_sequence
|= !!memcmp( ebdu
, seqhdr
->ebdu
, seqhdr
->ebdu_size
);
369 param
->profile
= sequence
->profile
<< 2;
370 param
->level
= LSMASH_MAX( param
->level
, sequence
->level
);
371 param
->interlaced
|= sequence
->interlace
;
372 uint32_t framerate
= sequence
->framerate_flag
373 ? ((double)sequence
->framerate_numerator
/ sequence
->framerate_denominator
) + 0.5
374 : 0xffffffff; /* 0xffffffff means framerate is unknown or unspecified. */
375 if( param
->framerate
== 0 )
376 param
->framerate
= framerate
;
377 else if( param
->framerate
!= framerate
)
378 param
->framerate
= 0xffffffff;
380 info
->sequence
.present
= 1;
381 return bits
->bs
->error
? -1 : 0;
384 int vc1_parse_entry_point_header( vc1_info_t
*info
, uint8_t *ebdu
, uint64_t ebdu_size
, int try_append
)
386 lsmash_bits_t
*bits
= info
->bits
;
387 vc1_sequence_header_t
*sequence
= &info
->sequence
;
388 vc1_entry_point_t
*entry_point
= &info
->entry_point
;
389 if( vc1_import_rbdu_from_ebdu( bits
, info
->buffer
.rbdu
, ebdu
+ VC1_START_CODE_LENGTH
, ebdu_size
) )
391 memset( entry_point
, 0, sizeof(vc1_entry_point_t
) );
392 uint8_t broken_link_flag
= lsmash_bits_get( bits
, 1 ); /* 0: no concatenation between the current and the previous entry points
393 * 1: concatenated and needed to discard B-pictures */
394 entry_point
->closed_entry_point
= lsmash_bits_get( bits
, 1 ); /* 0: Open RAP, 1: Closed RAP */
395 IF_INVALID_VALUE( broken_link_flag
&& entry_point
->closed_entry_point
)
396 return -1; /* invalid combination */
397 lsmash_bits_get( bits
, 4 ); /* panscan_flag (1)
401 uint8_t extended_mv
= lsmash_bits_get( bits
, 1 );
402 lsmash_bits_get( bits
, 6 ); /* dquant (2)
406 if( sequence
->hrd_param_flag
)
407 for( uint8_t i
= 0; i
< sequence
->hrd_param
.hrd_num_leaky_buckets
; i
++ )
408 lsmash_bits_get( bits
, 8 ); /* hrd_full */
409 /* Decide coded size here.
410 * The correct formula is defined in Amendment 2:2011 to SMPTE ST 421M:2006.
411 * Don't use the formula specified in SMPTE 421M-2006. */
412 uint16_t coded_width
;
413 uint16_t coded_height
;
414 if( lsmash_bits_get( bits
, 1 ) ) /* coded_size_flag */
416 coded_width
= lsmash_bits_get( bits
, 12 );
417 coded_height
= lsmash_bits_get( bits
, 12 );
421 coded_width
= sequence
->max_coded_width
;
422 coded_height
= sequence
->max_coded_height
;
424 coded_width
= 2 * (coded_width
+ 1); /* corrected */
425 coded_height
= 2 * (coded_height
+ 1); /* corrected */
426 if( sequence
->disp_horiz_size
== 0 || sequence
->disp_vert_size
== 0 )
428 sequence
->disp_horiz_size
= coded_width
;
429 sequence
->disp_vert_size
= coded_height
;
433 lsmash_bits_get( bits
, 1 ); /* extended_dmv */
434 if( lsmash_bits_get( bits
, 1 ) ) /* range_mapy_flag */
435 lsmash_bits_get( bits
, 3 ); /* range_mapy */
436 if( lsmash_bits_get( bits
, 1 ) ) /* range_mapuv_flag */
437 lsmash_bits_get( bits
, 3 ); /* range_mapuv */
438 /* '1' and stuffing bits ('0's) */
439 IF_INVALID_VALUE( !lsmash_bits_get( bits
, 1 ) )
441 lsmash_bits_empty( bits
);
442 /* Preparation for creating VC1SpecificBox */
445 lsmash_vc1_specific_parameters_t
*param
= &info
->dvc1_param
;
446 lsmash_vc1_header_t
*ephdr
= param
->ephdr
;
449 ephdr
= lsmash_malloc( sizeof(lsmash_vc1_header_t
) );
452 ephdr
->ebdu
= lsmash_memdup( ebdu
, ebdu_size
);
455 lsmash_free( ephdr
);
458 ephdr
->ebdu_size
= ebdu_size
;
459 param
->ephdr
= ephdr
;
461 else if( ephdr
&& ephdr
->ebdu
&& (ephdr
->ebdu_size
== ebdu_size
) )
462 param
->multiple_entry
|= !!memcmp( ebdu
, ephdr
->ebdu
, ephdr
->ebdu_size
);
464 info
->entry_point
.present
= 1;
465 return bits
->bs
->error
? -1 : 0;
468 int vc1_parse_advanced_picture( lsmash_bits_t
*bits
,
469 vc1_sequence_header_t
*sequence
, vc1_picture_info_t
*picture
,
470 uint8_t *rbdu_buffer
, uint8_t *ebdu
, uint64_t ebdu_size
)
472 if( vc1_import_rbdu_from_ebdu( bits
, rbdu_buffer
, ebdu
+ VC1_START_CODE_LENGTH
, ebdu_size
) )
474 if( sequence
->interlace
)
475 picture
->frame_coding_mode
= vc1_get_vlc( bits
, 2 );
477 picture
->frame_coding_mode
= 0;
478 if( picture
->frame_coding_mode
!= 0x3 )
479 picture
->type
= vc1_get_vlc( bits
, 4 ); /* ptype (variable length) */
481 picture
->type
= lsmash_bits_get( bits
, 3 ); /* fptype (3) */
482 picture
->present
= 1;
483 lsmash_bits_empty( bits
);
484 return bits
->bs
->error
? -1 : 0;
487 void vc1_update_au_property( vc1_access_unit_t
*access_unit
, vc1_picture_info_t
*picture
)
489 access_unit
->random_accessible
= picture
->random_accessible
;
490 access_unit
->closed_gop
= picture
->closed_gop
;
492 * Be coded using information only from itself. (independent)
493 * All the macroblocks in an I-picture are intra-coded.
495 * Be coded using motion compensated prediction from past reference fields or frame.
496 * Can contain macroblocks that are inter-coded (i.e. coded using prediction) and macroblocks that are intra-coded.
498 * Be coded using motion compensated prediction from past and/or future reference fields or frames. (bi-predictive)
499 * Cannot be used for predicting any other picture. (disposable)
501 * All the macroblocks in BI-picture are intra-coded. (independent)
502 * Cannot be used for predicting any other picture. (disposable) */
503 if( picture
->frame_coding_mode
== 0x3 )
505 /* field interlace */
506 access_unit
->independent
= picture
->type
== VC1_ADVANCED_FIELD_PICTURE_TYPE_II
|| picture
->type
== VC1_ADVANCED_FIELD_PICTURE_TYPE_BIBI
;
507 access_unit
->non_bipredictive
= picture
->type
< VC1_ADVANCED_FIELD_PICTURE_TYPE_BB
|| picture
->type
== VC1_ADVANCED_FIELD_PICTURE_TYPE_BIBI
;
508 access_unit
->disposable
= picture
->type
>= VC1_ADVANCED_FIELD_PICTURE_TYPE_BB
;
512 /* frame progressive/interlace */
513 access_unit
->independent
= picture
->type
== VC1_ADVANCED_PICTURE_TYPE_I
|| picture
->type
== VC1_ADVANCED_PICTURE_TYPE_BI
;
514 access_unit
->non_bipredictive
= picture
->type
!= VC1_ADVANCED_PICTURE_TYPE_B
;
515 access_unit
->disposable
= picture
->type
== VC1_ADVANCED_PICTURE_TYPE_B
|| picture
->type
== VC1_ADVANCED_PICTURE_TYPE_BI
;
517 picture
->present
= 0;
519 picture
->closed_gop
= 0;
520 picture
->start_of_sequence
= 0;
521 picture
->random_accessible
= 0;
524 int vc1_find_au_delimit_by_bdu_type( uint8_t bdu_type
, uint8_t prev_bdu_type
)
526 /* In any access unit, EBDU with smaller least significant 8-bits of BDU type doesn't precede EBDU with larger one.
527 * Therefore, the condition: (bdu_type 0xF) > (prev_bdu_type & 0xF) is more precisely.
528 * No two or more frame start codes shall be in the same access unit. */
529 return bdu_type
> prev_bdu_type
|| (bdu_type
== 0x0D && prev_bdu_type
== 0x0D);
532 int vc1_supplement_buffer( vc1_stream_buffer_t
*sb
, vc1_access_unit_t
*access_unit
, uint32_t size
)
534 lsmash_multiple_buffers_t
*bank
= lsmash_resize_multiple_buffers( sb
->bank
, size
);
538 sb
->rbdu
= lsmash_withdraw_buffer( bank
, 1 );
539 if( access_unit
&& bank
->number_of_buffers
== 3 )
541 access_unit
->data
= lsmash_withdraw_buffer( bank
, 2 );
542 access_unit
->incomplete_data
= lsmash_withdraw_buffer( bank
, 3 );
547 uint8_t *lsmash_create_vc1_specific_info( lsmash_vc1_specific_parameters_t
*param
, uint32_t *data_length
)
549 if( !param
|| !data_length
)
551 if( !param
->seqhdr
&& !param
->ephdr
)
553 /* Calculate enough buffer size. */
554 lsmash_vc1_header_t
*seqhdr
= param
->seqhdr
;
555 lsmash_vc1_header_t
*ephdr
= param
->ephdr
;
556 uint32_t buffer_size
= ISOM_BASEBOX_COMMON_SIZE
+ 7 + seqhdr
->ebdu_size
+ ephdr
->ebdu_size
;
557 /* Set up bitstream writer. */
558 uint8_t buffer
[buffer_size
];
559 lsmash_bits_t bits
= { 0 };
560 lsmash_bs_t bs
= { 0 };
561 bs
.buffer
.data
= buffer
;
562 bs
.buffer
.alloc
= buffer_size
;
563 lsmash_bits_init( &bits
, &bs
);
564 /* Create a VC1SpecificBox */
565 lsmash_bits_put( &bits
, 32, 0 ); /* box size */
566 lsmash_bits_put( &bits
, 32, ISOM_BOX_TYPE_DVC1
.fourcc
); /* box type: 'dvc1' */
567 lsmash_bits_put( &bits
, 4, param
->profile
); /* profile */
568 lsmash_bits_put( &bits
, 3, param
->level
); /* level */
569 lsmash_bits_put( &bits
, 1, 0 ); /* reserved */
570 /* VC1AdvDecSpecStruc (for Advanced Profile) */
571 lsmash_bits_put( &bits
, 3, param
->level
); /* level (identical to the previous level field) */
572 lsmash_bits_put( &bits
, 1, param
->cbr
); /* cbr */
573 lsmash_bits_put( &bits
, 6, 0 ); /* reserved */
574 lsmash_bits_put( &bits
, 1, !param
->interlaced
); /* no_interlace */
575 lsmash_bits_put( &bits
, 1, !param
->multiple_sequence
); /* no_multiple_seq */
576 lsmash_bits_put( &bits
, 1, !param
->multiple_entry
); /* no_multiple_entry */
577 lsmash_bits_put( &bits
, 1, !param
->slice_present
); /* no_slice_code */
578 lsmash_bits_put( &bits
, 1, !param
->bframe_present
); /* no_bframe */
579 lsmash_bits_put( &bits
, 1, 0 ); /* reserved */
580 lsmash_bits_put( &bits
, 32, param
->framerate
); /* framerate */
582 for( uint32_t i
= 0; i
< seqhdr
->ebdu_size
; i
++ )
583 lsmash_bits_put( &bits
, 8, *(seqhdr
->ebdu
+ i
) );
584 for( uint32_t i
= 0; i
< ephdr
->ebdu_size
; i
++ )
585 lsmash_bits_put( &bits
, 8, *(ephdr
->ebdu
+ i
) );
587 uint8_t *data
= lsmash_bits_export_data( &bits
, data_length
);
588 /* Update box size. */
589 LSMASH_SET_BE32( data
, *data_length
);
593 static int vc1_try_to_put_header( lsmash_vc1_header_t
**p_hdr
, uint8_t *multiple_hdr
, void *hdr_data
, uint32_t hdr_length
)
595 lsmash_vc1_header_t
*hdr
= *p_hdr
;
598 hdr
= lsmash_malloc_zero( sizeof(lsmash_vc1_header_t
) );
604 *multiple_hdr
|= hdr
->ebdu_size
== hdr_length
? !!memcmp( hdr_data
, hdr
->ebdu
, hdr
->ebdu_size
) : 1;
607 hdr
->ebdu
= lsmash_memdup( hdr_data
, hdr_length
);
608 hdr
->ebdu_size
= hdr
->ebdu
? hdr_length
: 0;
610 return hdr
->ebdu
? 0 : -1;
613 int lsmash_put_vc1_header( lsmash_vc1_specific_parameters_t
*param
, void *hdr_data
, uint32_t hdr_length
)
615 if( !param
|| !hdr_data
|| hdr_length
< 5 )
617 /* Check start code prefix (0x000001). */
618 uint8_t *data
= (uint8_t *)hdr_data
;
619 if( data
[0] != 0x00 || data
[1] != 0x00 || data
[2] != 0x01 )
621 if( data
[3] == 0x0F ) /* sequence header */
622 return vc1_try_to_put_header( ¶m
->seqhdr
, ¶m
->multiple_sequence
, hdr_data
, hdr_length
);
623 else if( data
[3] == 0x0E ) /* entry point header */
624 return vc1_try_to_put_header( ¶m
->ephdr
, ¶m
->multiple_entry
, hdr_data
, hdr_length
);
628 static int vc1_parse_succeeded( vc1_info_t
*info
, lsmash_vc1_specific_parameters_t
*param
)
631 if( info
->sequence
.present
&& info
->entry_point
.present
)
633 *param
= info
->dvc1_param
;
634 /* Avoid freeing headers. */
635 info
->dvc1_param
.seqhdr
= NULL
;
636 info
->dvc1_param
.ephdr
= NULL
;
641 vc1_cleanup_parser( info
);
645 static inline int vc1_parse_failed( vc1_info_t
*info
)
647 vc1_cleanup_parser( info
);
651 int lsmash_setup_vc1_specific_parameters_from_access_unit( lsmash_vc1_specific_parameters_t
*param
, uint8_t *data
, uint32_t data_length
)
653 if( !param
|| !data
|| data_length
== 0 )
655 vc1_info_t
*info
= &(vc1_info_t
){ { 0 } };
656 lsmash_bs_t
*bs
= &(lsmash_bs_t
){ 0 };
657 if( lsmash_bs_set_empty_stream( bs
, data
, data_length
) < 0 )
659 if( vc1_setup_parser( info
, 1 ) < 0 )
660 return vc1_parse_failed( info
);
661 info
->dvc1_param
= *param
;
662 vc1_stream_buffer_t
*sb
= &info
->buffer
;
666 uint64_t trailing_zero_bytes
;
667 uint64_t ebdu_length
= vc1_find_next_start_code_prefix( bs
, &bdu_type
, &trailing_zero_bytes
);
668 if( ebdu_length
<= VC1_START_CODE_LENGTH
&& lsmash_bs_is_end( bs
, ebdu_length
) )
669 /* For the last EBDU. This EBDU already has been parsed. */
670 return vc1_parse_succeeded( info
, param
);
671 else if( bdu_type
== 0xFF )
672 return vc1_parse_failed( info
);
673 uint64_t next_ebdu_head_pos
= info
->ebdu_head_pos
675 + trailing_zero_bytes
;
676 if( bdu_type
>= 0x0A && bdu_type
<= 0x0F )
678 /* Complete the current access unit if encountered delimiter of current access unit. */
679 if( vc1_find_au_delimit_by_bdu_type( bdu_type
, info
->prev_bdu_type
) )
680 /* The last video coded EBDU belongs to the access unit you want at this time. */
681 return vc1_parse_succeeded( info
, param
);
682 /* Increase the buffer if needed. */
683 if( sb
->bank
->buffer_size
< ebdu_length
684 && vc1_supplement_buffer( sb
, NULL
, 2 * ebdu_length
) < 0 )
685 return vc1_parse_failed( info
);
686 /* Process EBDU by its BDU type. */
687 uint8_t *ebdu
= lsmash_bs_get_buffer_data( bs
);
690 /* FRM_SC: Frame start code
691 * FLD_SC: Field start code
692 * SLC_SC: Slice start code
693 * SEQ_SC: Sequence header start code
694 * EP_SC: Entry-point start code
695 * PIC_L: Picture layer
697 * SEQ_L: Sequence layer
698 * EP_L: Entry-point layer */
700 * For the Progressive or Frame Interlace mode, shall signal the beginning of a new video frame.
701 * For the Field Interlace mode, shall signal the beginning of a sequence of two independently coded video fields.
702 * [FRM_SC][PIC_L][[FLD_SC][PIC_L] (optional)][[SLC_SC][SLC_L] (optional)] ... */
704 vc1_picture_info_t
*picture
= &info
->picture
;
705 if( vc1_parse_advanced_picture( info
->bits
, &info
->sequence
, picture
, info
->buffer
.rbdu
, ebdu
, ebdu_length
) < 0 )
706 return vc1_parse_failed( info
);
707 info
->dvc1_param
.bframe_present
|= picture
->frame_coding_mode
== 0x3
708 ? picture
->type
>= VC1_ADVANCED_FIELD_PICTURE_TYPE_BB
709 : picture
->type
== VC1_ADVANCED_PICTURE_TYPE_B
|| picture
->type
== VC1_ADVANCED_PICTURE_TYPE_BI
;
712 * Shall only be used for Field Interlaced frames
713 * and shall only be used to signal the beginning of the second field of the frame.
714 * [FRM_SC][PIC_L][FLD_SC][PIC_L][[SLC_SC][SLC_L] (optional)] ...
715 * Field start code is followed by INTERLACE_FIELD_PICTURE_FIELD2() which doesn't have info of its field picture type.*/
718 * Shall not be used for start code of the first slice of a frame.
719 * Shall not be used for start code of the first slice of an interlace field coded picture.
720 * [FRM_SC][PIC_L][[FLD_SC][PIC_L] (optional)][SLC_SC][SLC_L][[SLC_SC][SLC_L] (optional)] ...
721 * Slice layer may repeat frame header. We just ignore it. */
722 info
->dvc1_param
.slice_present
= 1;
724 case 0x0E : /* Entry-point header
725 * Entry-point indicates the direct followed frame is a start of group of frames.
726 * Entry-point doesn't indicates the frame is a random access point when multiple sequence headers are present,
727 * since it is necessary to decode sequence header which subsequent frames belong to for decoding them.
728 * Entry point shall be followed by
729 * 1. I-picture - progressive or frame interlace
730 * 2. I/I-picture, I/P-picture, or P/I-picture - field interlace
731 * [[SEQ_SC][SEQ_L] (optional)][EP_SC][EP_L][FRM_SC][PIC_L] ... */
732 if( vc1_parse_entry_point_header( info
, ebdu
, ebdu_length
, 1 ) < 0 )
733 return vc1_parse_failed( info
);
735 case 0x0F : /* Sequence header
736 * [SEQ_SC][SEQ_L][EP_SC][EP_L][FRM_SC][PIC_L] ... */
737 if( vc1_parse_sequence_header( info
, ebdu
, ebdu_length
, 1 ) < 0 )
738 return vc1_parse_failed( info
);
740 default : /* End-of-sequence (0x0A) */
744 /* Move to the first byte of the next EBDU. */
745 info
->prev_bdu_type
= bdu_type
;
746 if( lsmash_bs_read_seek( bs
, next_ebdu_head_pos
, SEEK_SET
) != next_ebdu_head_pos
)
747 return vc1_parse_failed( info
);
748 /* Check if no more data to read from the stream. */
749 if( !lsmash_bs_is_end( bs
, VC1_START_CODE_PREFIX_LENGTH
) )
750 info
->ebdu_head_pos
= next_ebdu_head_pos
;
752 return vc1_parse_succeeded( info
, param
);
756 static inline int vc1_check_next_start_code_prefix( uint8_t *buf_pos
, uint8_t *buf_end
)
758 return ((buf_pos
+ 2) < buf_end
) && !buf_pos
[0] && !buf_pos
[1] && (buf_pos
[2] == 0x01);
761 int vc1_construct_specific_parameters( lsmash_codec_specific_t
*dst
, lsmash_codec_specific_t
*src
)
763 assert( dst
&& dst
->data
.structured
&& src
&& src
->data
.unstructured
);
764 if( src
->size
< ISOM_BASEBOX_COMMON_SIZE
+ 7 )
766 lsmash_vc1_specific_parameters_t
*param
= (lsmash_vc1_specific_parameters_t
*)dst
->data
.structured
;
767 uint8_t *data
= src
->data
.unstructured
;
768 uint64_t size
= LSMASH_GET_BE32( data
);
769 data
+= ISOM_BASEBOX_COMMON_SIZE
;
772 size
= LSMASH_GET_BE64( data
);
775 if( size
!= src
->size
)
777 param
->profile
= (data
[0] >> 4) & 0x0F;
778 if( param
->profile
!= 12 )
779 return -1; /* We don't support profile other than 12 (Advanced profile). */
780 param
->level
= (data
[0] >> 1) & 0x07;
781 param
->cbr
= (data
[1] >> 4) & 0x01;
782 param
->interlaced
= !((data
[2] >> 5) & 0x01);
783 param
->multiple_sequence
= !((data
[2] >> 4) & 0x01);
784 param
->multiple_entry
= !((data
[2] >> 3) & 0x01);
785 param
->slice_present
= !((data
[2] >> 2) & 0x01);
786 param
->bframe_present
= !((data
[2] >> 1) & 0x01);
787 param
->framerate
= LSMASH_GET_BE32( &data
[3] );
788 /* Try to get seqhdr_ephdr[]. */
791 param
->seqhdr
= lsmash_malloc_zero( sizeof(lsmash_vc1_header_t
) );
797 param
->ephdr
= lsmash_malloc_zero( sizeof(lsmash_vc1_header_t
) );
801 lsmash_vc1_header_t
*seqhdr
= param
->seqhdr
;
802 lsmash_vc1_header_t
*ephdr
= param
->ephdr
;
805 uint8_t *end
= src
->data
.unstructured
+ src
->size
;
806 /* Find the start point of Sequence header EBDU. */
809 if( vc1_check_next_start_code_prefix( pos
, end
) && (pos
+ 3 < end
) && *(pos
+ 3) == 0x0F )
811 seqhdr
->ebdu_size
= 4;
817 /* Find the end point of Sequence header EBDU. */
820 if( vc1_check_next_start_code_prefix( pos
, end
) )
822 ++ seqhdr
->ebdu_size
;
824 /* Find the start point of Entry-point header EBDU. */
827 if( vc1_check_next_start_code_prefix( pos
, end
) && (pos
+ 3 < end
) && *(pos
+ 3) == 0x0E )
829 ephdr
->ebdu_size
= 4;
835 /* Find the end point of Entry-point header EBDU. */
838 if( vc1_check_next_start_code_prefix( pos
, end
) )
842 /* Append the Sequence header EBDU and Entry-point header EBDU if present. */
843 if( seqhdr
->ebdu_size
)
846 lsmash_free( seqhdr
->ebdu
);
847 seqhdr
->ebdu
= lsmash_memdup( data
, seqhdr
->ebdu_size
);
851 if( ephdr
->ebdu_size
)
854 lsmash_free( ephdr
->ebdu
);
855 ephdr
->ebdu
= lsmash_memdup( data
, ephdr
->ebdu_size
);
862 int vc1_copy_codec_specific( lsmash_codec_specific_t
*dst
, lsmash_codec_specific_t
*src
)
864 assert( src
&& src
->format
== LSMASH_CODEC_SPECIFIC_FORMAT_STRUCTURED
&& src
->data
.structured
);
865 assert( dst
&& dst
->format
== LSMASH_CODEC_SPECIFIC_FORMAT_STRUCTURED
&& dst
->data
.structured
);
866 lsmash_vc1_specific_parameters_t
*src_data
= (lsmash_vc1_specific_parameters_t
*)src
->data
.structured
;
867 lsmash_vc1_specific_parameters_t
*dst_data
= (lsmash_vc1_specific_parameters_t
*)dst
->data
.structured
;
868 lsmash_destroy_vc1_headers( dst_data
);
869 *dst_data
= *src_data
;
870 if( !src_data
->seqhdr
&& !src_data
->ephdr
)
872 if( src_data
->seqhdr
)
874 dst_data
->seqhdr
= lsmash_malloc_zero( sizeof(lsmash_vc1_header_t
) );
875 if( !dst_data
->seqhdr
)
877 if( src_data
->seqhdr
->ebdu_size
)
879 dst_data
->seqhdr
->ebdu
= lsmash_memdup( src_data
->seqhdr
->ebdu
, src_data
->seqhdr
->ebdu_size
);
880 if( !dst_data
->seqhdr
->ebdu
)
882 lsmash_destroy_vc1_headers( dst_data
);
886 dst_data
->seqhdr
->ebdu_size
= src_data
->seqhdr
->ebdu_size
;
888 if( src_data
->ephdr
)
890 dst_data
->ephdr
= lsmash_malloc_zero( sizeof(lsmash_vc1_header_t
) );
891 if( !dst_data
->ephdr
)
893 lsmash_destroy_vc1_headers( dst_data
);
896 if( src_data
->ephdr
->ebdu_size
)
898 dst_data
->ephdr
->ebdu
= lsmash_memdup( src_data
->ephdr
->ebdu
, src_data
->ephdr
->ebdu_size
);
899 if( !dst_data
->ephdr
->ebdu
)
901 lsmash_destroy_vc1_headers( dst_data
);
905 dst_data
->ephdr
->ebdu_size
= src_data
->ephdr
->ebdu_size
;
910 int vc1_print_codec_specific( FILE *fp
, lsmash_file_t
*file
, isom_box_t
*box
, int level
)
912 assert( fp
&& file
&& box
&& (box
->manager
& LSMASH_BINARY_CODED_BOX
) );
914 lsmash_ifprintf( fp
, indent
++, "[%s: VC1 Specific Box]\n", isom_4cc2str( box
->type
.fourcc
) );
915 lsmash_ifprintf( fp
, indent
, "position = %"PRIu64
"\n", box
->pos
);
916 lsmash_ifprintf( fp
, indent
, "size = %"PRIu64
"\n", box
->size
);
917 if( box
->size
< ISOM_BASEBOX_COMMON_SIZE
+ 7 )
919 uint8_t *data
= box
->binary
;
920 isom_skip_box_common( &data
);
921 uint8_t profile
= (data
[0] >> 4) & 0x0F;
923 return 0; /* We don't support profile other than 12 (Advanced profile). */
924 lsmash_ifprintf( fp
, indent
, "profile = %"PRIu8
"\n", profile
);
925 lsmash_ifprintf( fp
, indent
, "level = %"PRIu8
"\n", (data
[0] >> 1) & 0x07 );
926 lsmash_ifprintf( fp
, indent
, "reserved = %"PRIu8
"\n", data
[0] & 0x01 );
927 lsmash_ifprintf( fp
, indent
, "level = %"PRIu8
"\n", (data
[1] >> 5) & 0x07 );
928 lsmash_ifprintf( fp
, indent
, "cbr = %"PRIu8
"\n", (data
[1] >> 4) & 0x01 );
929 lsmash_ifprintf( fp
, indent
, "reserved1 = 0x%02"PRIx8
"\n", (data
[1] & 0x0F) | ((data
[2] >> 6) & 0x03) );
930 lsmash_ifprintf( fp
, indent
, "no_interlace = %"PRIu8
"\n", (data
[2] >> 5) & 0x01 );
931 lsmash_ifprintf( fp
, indent
, "no_multiple_seq = %"PRIu8
"\n", (data
[2] >> 4) & 0x01 );
932 lsmash_ifprintf( fp
, indent
, "no_multiple_entry = %"PRIu8
"\n", (data
[2] >> 3) & 0x01 );
933 lsmash_ifprintf( fp
, indent
, "no_slice_code = %"PRIu8
"\n", (data
[2] >> 2) & 0x01 );
934 lsmash_ifprintf( fp
, indent
, "no_bframe = %"PRIu8
"\n", (data
[2] >> 1) & 0x01 );
935 lsmash_ifprintf( fp
, indent
, "reserved2 = %"PRIu8
"\n", data
[2] & 0x01 );
936 uint32_t framerate
= LSMASH_GET_BE32( &data
[3] );
937 lsmash_ifprintf( fp
, indent
, "framerate = %"PRIu32
"\n", framerate
);
938 uint32_t seqhdr_ephdr_size
= box
->size
- (data
- box
->binary
+ 7);
939 if( seqhdr_ephdr_size
)
941 lsmash_ifprintf( fp
, indent
, "seqhdr_ephdr[]\n" );
943 for( uint32_t i
= 0; i
< seqhdr_ephdr_size
; i
+= 8 )
945 lsmash_ifprintf( fp
, indent
+ 1, "" );
946 for( uint32_t j
= 0; ; j
++ )
947 if( j
== 7 || (i
+ j
== seqhdr_ephdr_size
- 1) )
949 fprintf( fp
, "0x%02"PRIx8
"\n", data
[i
+ j
] );
953 fprintf( fp
, "0x%02"PRIx8
" ", data
[i
+ j
] );