1 /*****************************************************************************
3 *****************************************************************************
4 * Copyright (C) 2012-2017 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 struct lsmash_vc1_header_tag
45 VC1_ADVANCED_PICTURE_TYPE_P
= 0x0, /* 0b0 */
46 VC1_ADVANCED_PICTURE_TYPE_B
= 0x2, /* 0b10 */
47 VC1_ADVANCED_PICTURE_TYPE_I
= 0x6, /* 0b110 */
48 VC1_ADVANCED_PICTURE_TYPE_BI
= 0xE, /* 0b1110 */
49 VC1_ADVANCED_PICTURE_TYPE_SKIPPED
= 0xF, /* 0b1111 */
54 VC1_ADVANCED_FIELD_PICTURE_TYPE_II
= 0x0, /* 0b000 */
55 VC1_ADVANCED_FIELD_PICTURE_TYPE_IP
= 0x1, /* 0b001 */
56 VC1_ADVANCED_FIELD_PICTURE_TYPE_PI
= 0x2, /* 0b010 */
57 VC1_ADVANCED_FIELD_PICTURE_TYPE_PP
= 0x3, /* 0b011 */
58 VC1_ADVANCED_FIELD_PICTURE_TYPE_BB
= 0x4, /* 0b100 */
59 VC1_ADVANCED_FIELD_PICTURE_TYPE_BBI
= 0x5, /* 0b101 */
60 VC1_ADVANCED_FIELD_PICTURE_TYPE_BIB
= 0x6, /* 0b110 */
61 VC1_ADVANCED_FIELD_PICTURE_TYPE_BIBI
= 0x7, /* 0b111 */
62 } vc1_field_picture_type
;
66 VC1_FRAME_CODING_MODE_PROGRESSIVE
= 0x0, /* 0b0 */
67 VC1_FRAME_CODING_MODE_FRAME_INTERLACE
= 0x2, /* 0b10 */
68 VC1_FRAME_CODING_MODE_FIELD_INTERLACE
= 0x3, /* 0b11 */
69 } vc1_frame_coding_mode
;
71 static void vc1_destroy_header( lsmash_vc1_header_t
*hdr
)
75 lsmash_free( hdr
->ebdu
);
79 void lsmash_destroy_vc1_headers( lsmash_vc1_specific_parameters_t
*param
)
83 vc1_destroy_header( param
->seqhdr
);
84 vc1_destroy_header( param
->ephdr
);
89 void vc1_destruct_specific_data( void *data
)
93 lsmash_destroy_vc1_headers( data
);
97 void vc1_cleanup_parser( vc1_info_t
*info
)
101 lsmash_destroy_vc1_headers( &info
->dvc1_param
);
102 lsmash_destroy_multiple_buffers( info
->buffer
.bank
);
103 lsmash_bits_adhoc_cleanup( info
->bits
);
114 memset( info
, 0, sizeof(vc1_info_t
) );
115 vc1_stream_buffer_t
*sb
= &info
->buffer
;
116 sb
->bank
= lsmash_create_multiple_buffers( parse_only
? 1 : 3, VC1_DEFAULT_BUFFER_SIZE
);
118 return LSMASH_ERR_MEMORY_ALLOC
;
119 sb
->rbdu
= lsmash_withdraw_buffer( sb
->bank
, 1 );
122 info
->access_unit
.data
= lsmash_withdraw_buffer( sb
->bank
, 2 );
123 info
->access_unit
.incomplete_data
= lsmash_withdraw_buffer( sb
->bank
, 3 );
125 info
->bits
= lsmash_bits_adhoc_create();
128 lsmash_destroy_multiple_buffers( sb
->bank
);
129 return LSMASH_ERR_MEMORY_ALLOC
;
131 info
->prev_bdu_type
= 0xFF; /* 0xFF is a forbidden value. */
135 uint64_t vc1_find_next_start_code_prefix
139 uint64_t *trailing_zero_bytes
142 uint64_t length
= 0; /* the length of the latest EBDU */
143 uint64_t count
= 0; /* the number of the trailing zero bytes after the latest EBDU */
144 if( !lsmash_bs_is_end( bs
, VC1_START_CODE_LENGTH
- 1 )
145 && 0x000001 == lsmash_bs_show_be24( bs
, 0 ) )
147 *bdu_type
= lsmash_bs_show_byte( bs
, VC1_START_CODE_PREFIX_LENGTH
);
148 length
= VC1_START_CODE_LENGTH
;
149 /* Find the start code of the next EBDU and get the length of the latest EBDU. */
150 int no_more
= lsmash_bs_is_end( bs
, length
+ VC1_START_CODE_LENGTH
- 1 );
153 uint32_t sync_bytes
= lsmash_bs_show_be24( bs
, length
);
154 while( 0x000001 != sync_bytes
)
156 no_more
= lsmash_bs_is_end( bs
, ++length
+ VC1_START_CODE_LENGTH
- 1 );
160 sync_bytes
|= lsmash_bs_show_byte( bs
, length
+ VC1_START_CODE_PREFIX_LENGTH
- 1 );
161 sync_bytes
&= 0xFFFFFF;
165 length
= lsmash_bs_get_remaining_buffer_size( bs
);
166 /* Any EBDU has no consecutive zero bytes at the end. */
167 while( 0x00 == lsmash_bs_show_byte( bs
, length
- 1 ) )
174 *bdu_type
= 0xFF; /* 0xFF is a forbidden value. */
175 *trailing_zero_bytes
= count
;
179 int vc1_check_next_start_code_suffix
185 uint8_t bdu_type
= *((uint8_t *)lsmash_bs_get_buffer_data( bs
) + VC1_START_CODE_PREFIX_LENGTH
);
186 if( (bdu_type
>= 0x00 && bdu_type
<= 0x09)
187 || (bdu_type
>= 0x20 && bdu_type
<= 0x7F) )
188 return LSMASH_ERR_NAMELESS
; /* SMPTE reserved */
189 if( bdu_type
>= 0x80 && bdu_type
<= 0xFF )
190 return LSMASH_ERR_INVALID_DATA
; /* Forbidden */
191 *p_bdu_type
= bdu_type
;
195 static inline uint8_t vc1_get_vlc( lsmash_bits_t
*bits
, int length
)
198 for( int i
= 0; i
< length
; i
++ )
199 if( lsmash_bits_get( bits
, 1 ) )
200 value
= (value
<< 1) | 1;
209 /* Convert EBDU (Encapsulated Byte Data Unit) to RBDU (Raw Byte Data Unit). */
210 static uint8_t *vc1_remove_emulation_prevention( uint8_t *src
, uint64_t src_length
, uint8_t *dst
)
212 uint8_t *src_end
= src
+ src_length
;
213 while( src
< src_end
)
214 if( ((src
+ 2) < src_end
) && !src
[0] && !src
[1] && (src
[2] == 0x03) )
216 /* 0x000003 -> 0x0000 */
219 src
++; /* Skip emulation_prevention_three_byte (0x03). */
226 static int vc1_import_rbdu_from_ebdu( lsmash_bits_t
*bits
, uint8_t *rbdu_buffer
, uint8_t *ebdu
, uint64_t ebdu_size
)
228 uint8_t *rbdu_start
= rbdu_buffer
;
229 uint8_t *rbdu_end
= vc1_remove_emulation_prevention( ebdu
, ebdu_size
, rbdu_buffer
);
230 uint64_t rbdu_length
= rbdu_end
- rbdu_start
;
231 return lsmash_bits_import_data( bits
, rbdu_start
, rbdu_length
);
234 static void vc1_parse_hrd_param( lsmash_bits_t
*bits
, vc1_hrd_param_t
*hrd_param
)
236 hrd_param
->hrd_num_leaky_buckets
= lsmash_bits_get( bits
, 5 );
237 lsmash_bits_get( bits
, 4 ); /* bitrate_exponent */
238 lsmash_bits_get( bits
, 4 ); /* buffer_size_exponent */
239 for( uint8_t i
= 0; i
< hrd_param
->hrd_num_leaky_buckets
; i
++ )
241 lsmash_bits_get( bits
, 16 ); /* hrd_rate */
242 lsmash_bits_get( bits
, 16 ); /* hrd_buffer */
246 int vc1_parse_sequence_header( vc1_info_t
*info
, uint8_t *ebdu
, uint64_t ebdu_size
, int try_append
)
248 lsmash_bits_t
*bits
= info
->bits
;
249 vc1_sequence_header_t
*sequence
= &info
->sequence
;
250 int err
= 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 LSMASH_ERR_NAMELESS
; /* SMPTE Reserved */
257 sequence
->level
= lsmash_bits_get( bits
, 3 );
258 if( sequence
->level
> 4 )
259 return LSMASH_ERR_NAMELESS
; /* SMPTE Reserved */
260 sequence
->colordiff_format
= lsmash_bits_get( bits
, 2 );
261 if( sequence
->colordiff_format
!= 1 )
262 return LSMASH_ERR_NAMELESS
; /* 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( frameratenr
== 0 )
315 return LSMASH_ERR_INVALID_DATA
; /* Forbidden */
316 if( frameratenr
> 7 )
317 return LSMASH_ERR_NAMELESS
; /* SMPTE Reserved */
318 uint8_t frameratedr
= lsmash_bits_get( bits
, 4 );
319 if( frameratedr
!= 1 && frameratedr
!= 2 )
320 /* 0: Forbidden, 3-15: SMPTE Reserved */
321 return frameratedr
== 0
322 ? LSMASH_ERR_INVALID_DATA
323 : LSMASH_ERR_NAMELESS
;
324 if( frameratedr
== 1 )
326 sequence
->framerate_numerator
= vc1_frameratenr_table
[ frameratenr
];
327 sequence
->framerate_denominator
= 1;
331 sequence
->framerate_numerator
= vc1_frameratenr_table
[ frameratenr
] * 1000;
332 sequence
->framerate_denominator
= 1001;
336 if( lsmash_bits_get( bits
, 1 ) ) /* color_format_flag */
338 sequence
->color_prim
= lsmash_bits_get( bits
, 8 );
339 sequence
->transfer_char
= lsmash_bits_get( bits
, 8 );
340 sequence
->matrix_coef
= lsmash_bits_get( bits
, 8 );
342 sequence
->hrd_param_flag
= lsmash_bits_get( bits
, 1 );
343 if( sequence
->hrd_param_flag
)
344 vc1_parse_hrd_param( bits
, &sequence
->hrd_param
);
346 /* '1' and stuffing bits ('0's) */
347 if( !lsmash_bits_get( bits
, 1 ) )
348 return LSMASH_ERR_INVALID_DATA
;
349 lsmash_bits_empty( bits
);
350 /* Preparation for creating VC1SpecificBox */
353 /* Update some specific parameters. */
354 lsmash_vc1_specific_parameters_t
*param
= &info
->dvc1_param
;
355 lsmash_vc1_header_t
*seqhdr
= param
->seqhdr
;
358 seqhdr
= lsmash_malloc( sizeof(lsmash_vc1_header_t
) );
360 return LSMASH_ERR_MEMORY_ALLOC
;
361 seqhdr
->ebdu
= lsmash_memdup( ebdu
, ebdu_size
);
364 lsmash_free( seqhdr
);
365 return LSMASH_ERR_MEMORY_ALLOC
;
367 seqhdr
->ebdu_size
= ebdu_size
;
368 param
->seqhdr
= seqhdr
;
370 else if( seqhdr
&& seqhdr
->ebdu
&& (seqhdr
->ebdu_size
== ebdu_size
) )
371 param
->multiple_sequence
|= !!memcmp( ebdu
, seqhdr
->ebdu
, seqhdr
->ebdu_size
);
372 param
->profile
= sequence
->profile
<< 2;
373 param
->level
= LSMASH_MAX( param
->level
, sequence
->level
);
374 param
->interlaced
|= sequence
->interlace
;
375 uint32_t framerate
= sequence
->framerate_flag
376 ? ((double)sequence
->framerate_numerator
/ sequence
->framerate_denominator
) + 0.5
377 : 0xffffffff; /* 0xffffffff means framerate is unknown or unspecified. */
378 if( param
->framerate
== 0 )
379 param
->framerate
= framerate
;
380 else if( param
->framerate
!= framerate
)
381 param
->framerate
= 0xffffffff;
383 info
->sequence
.present
= 1;
384 return bits
->bs
->error
? LSMASH_ERR_NAMELESS
: 0;
387 int vc1_parse_entry_point_header( vc1_info_t
*info
, uint8_t *ebdu
, uint64_t ebdu_size
, int try_append
)
389 lsmash_bits_t
*bits
= info
->bits
;
390 vc1_sequence_header_t
*sequence
= &info
->sequence
;
391 vc1_entry_point_t
*entry_point
= &info
->entry_point
;
392 int err
= vc1_import_rbdu_from_ebdu( bits
, info
->buffer
.rbdu
, ebdu
+ VC1_START_CODE_LENGTH
, ebdu_size
);
395 memset( entry_point
, 0, sizeof(vc1_entry_point_t
) );
396 uint8_t broken_link_flag
= lsmash_bits_get( bits
, 1 ); /* 0: no concatenation between the current and the previous entry points
397 * 1: concatenated and needed to discard B-pictures */
398 entry_point
->closed_entry_point
= lsmash_bits_get( bits
, 1 ); /* 0: Open RAP, 1: Closed RAP */
399 if( broken_link_flag
&& entry_point
->closed_entry_point
)
400 return LSMASH_ERR_INVALID_DATA
; /* invalid combination */
401 lsmash_bits_get( bits
, 4 ); /* panscan_flag (1)
405 uint8_t extended_mv
= lsmash_bits_get( bits
, 1 );
406 lsmash_bits_get( bits
, 6 ); /* dquant (2)
410 if( sequence
->hrd_param_flag
)
411 for( uint8_t i
= 0; i
< sequence
->hrd_param
.hrd_num_leaky_buckets
; i
++ )
412 lsmash_bits_get( bits
, 8 ); /* hrd_full */
413 /* Decide coded size here.
414 * The correct formula is defined in Amendment 2:2011 to SMPTE ST 421M:2006.
415 * Don't use the formula specified in SMPTE 421M-2006. */
416 uint16_t coded_width
;
417 uint16_t coded_height
;
418 if( lsmash_bits_get( bits
, 1 ) ) /* coded_size_flag */
420 coded_width
= lsmash_bits_get( bits
, 12 );
421 coded_height
= lsmash_bits_get( bits
, 12 );
425 coded_width
= sequence
->max_coded_width
;
426 coded_height
= sequence
->max_coded_height
;
428 coded_width
= 2 * (coded_width
+ 1); /* corrected */
429 coded_height
= 2 * (coded_height
+ 1); /* corrected */
430 if( sequence
->disp_horiz_size
== 0 || sequence
->disp_vert_size
== 0 )
432 sequence
->disp_horiz_size
= coded_width
;
433 sequence
->disp_vert_size
= coded_height
;
437 lsmash_bits_get( bits
, 1 ); /* extended_dmv */
438 if( lsmash_bits_get( bits
, 1 ) ) /* range_mapy_flag */
439 lsmash_bits_get( bits
, 3 ); /* range_mapy */
440 if( lsmash_bits_get( bits
, 1 ) ) /* range_mapuv_flag */
441 lsmash_bits_get( bits
, 3 ); /* range_mapuv */
442 /* '1' and stuffing bits ('0's) */
443 if( !lsmash_bits_get( bits
, 1 ) )
444 return LSMASH_ERR_INVALID_DATA
;
445 lsmash_bits_empty( bits
);
446 /* Preparation for creating VC1SpecificBox */
449 lsmash_vc1_specific_parameters_t
*param
= &info
->dvc1_param
;
450 lsmash_vc1_header_t
*ephdr
= param
->ephdr
;
453 ephdr
= lsmash_malloc( sizeof(lsmash_vc1_header_t
) );
455 return LSMASH_ERR_MEMORY_ALLOC
;
456 ephdr
->ebdu
= lsmash_memdup( ebdu
, ebdu_size
);
459 lsmash_free( ephdr
);
460 return LSMASH_ERR_MEMORY_ALLOC
;
462 ephdr
->ebdu_size
= ebdu_size
;
463 param
->ephdr
= ephdr
;
465 else if( ephdr
&& ephdr
->ebdu
&& (ephdr
->ebdu_size
== ebdu_size
) )
466 param
->multiple_entry
|= !!memcmp( ebdu
, ephdr
->ebdu
, ephdr
->ebdu_size
);
468 info
->entry_point
.present
= 1;
469 return bits
->bs
->error
? LSMASH_ERR_NAMELESS
: 0;
472 int vc1_parse_advanced_picture( lsmash_bits_t
*bits
,
473 vc1_sequence_header_t
*sequence
, vc1_picture_info_t
*picture
,
474 uint8_t *rbdu_buffer
, uint8_t *ebdu
, uint64_t ebdu_size
)
476 int err
= vc1_import_rbdu_from_ebdu( bits
, rbdu_buffer
, ebdu
+ VC1_START_CODE_LENGTH
, ebdu_size
);
479 if( sequence
->interlace
)
480 picture
->frame_coding_mode
= vc1_get_vlc( bits
, 2 );
482 picture
->frame_coding_mode
= 0;
483 if( picture
->frame_coding_mode
!= 0x3 )
484 picture
->type
= vc1_get_vlc( bits
, 4 ); /* ptype (variable length) */
486 picture
->type
= lsmash_bits_get( bits
, 3 ); /* fptype (3) */
487 picture
->present
= 1;
488 lsmash_bits_empty( bits
);
489 return bits
->bs
->error
? LSMASH_ERR_NAMELESS
: 0;
492 void vc1_update_au_property( vc1_access_unit_t
*access_unit
, vc1_picture_info_t
*picture
)
494 access_unit
->random_accessible
= picture
->random_accessible
;
495 access_unit
->closed_gop
= picture
->closed_gop
;
497 * Be coded using information only from itself. (independent)
498 * All the macroblocks in an I-picture are intra-coded.
500 * Be coded using motion compensated prediction from past reference fields or frame.
501 * Can contain macroblocks that are inter-coded (i.e. coded using prediction) and macroblocks that are intra-coded.
503 * Be coded using motion compensated prediction from past and/or future reference fields or frames. (bi-predictive)
504 * Cannot be used for predicting any other picture. (disposable)
506 * All the macroblocks in BI-picture are intra-coded. (independent)
507 * Cannot be used for predicting any other picture. (disposable) */
508 if( picture
->frame_coding_mode
== 0x3 )
510 /* field interlace */
511 access_unit
->independent
= picture
->type
== VC1_ADVANCED_FIELD_PICTURE_TYPE_II
|| picture
->type
== VC1_ADVANCED_FIELD_PICTURE_TYPE_BIBI
;
512 access_unit
->non_bipredictive
= picture
->type
< VC1_ADVANCED_FIELD_PICTURE_TYPE_BB
|| picture
->type
== VC1_ADVANCED_FIELD_PICTURE_TYPE_BIBI
;
513 access_unit
->disposable
= picture
->type
>= VC1_ADVANCED_FIELD_PICTURE_TYPE_BB
;
517 /* frame progressive/interlace */
518 access_unit
->independent
= picture
->type
== VC1_ADVANCED_PICTURE_TYPE_I
|| picture
->type
== VC1_ADVANCED_PICTURE_TYPE_BI
;
519 access_unit
->non_bipredictive
= picture
->type
!= VC1_ADVANCED_PICTURE_TYPE_B
;
520 access_unit
->disposable
= picture
->type
== VC1_ADVANCED_PICTURE_TYPE_B
|| picture
->type
== VC1_ADVANCED_PICTURE_TYPE_BI
;
522 picture
->present
= 0;
524 picture
->closed_gop
= 0;
525 picture
->start_of_sequence
= 0;
526 picture
->random_accessible
= 0;
529 int vc1_find_au_delimit_by_bdu_type( uint8_t bdu_type
, uint8_t prev_bdu_type
)
531 /* In any access unit, EBDU with smaller least significant 8-bits of BDU type doesn't precede EBDU with larger one.
532 * Therefore, the condition: (bdu_type 0xF) > (prev_bdu_type & 0xF) is more precisely.
533 * No two or more frame start codes shall be in the same access unit. */
534 return bdu_type
> prev_bdu_type
|| (bdu_type
== 0x0D && prev_bdu_type
== 0x0D);
537 int vc1_supplement_buffer( vc1_stream_buffer_t
*sb
, vc1_access_unit_t
*access_unit
, uint32_t size
)
539 lsmash_multiple_buffers_t
*bank
= lsmash_resize_multiple_buffers( sb
->bank
, size
);
541 return LSMASH_ERR_MEMORY_ALLOC
;
543 sb
->rbdu
= lsmash_withdraw_buffer( bank
, 1 );
544 if( access_unit
&& bank
->number_of_buffers
== 3 )
546 access_unit
->data
= lsmash_withdraw_buffer( bank
, 2 );
547 access_unit
->incomplete_data
= lsmash_withdraw_buffer( bank
, 3 );
552 uint8_t *lsmash_create_vc1_specific_info( lsmash_vc1_specific_parameters_t
*param
, uint32_t *data_length
)
554 if( !param
|| !data_length
)
556 if( !param
->seqhdr
|| !param
->ephdr
)
558 /* Calculate enough buffer size. */
559 lsmash_vc1_header_t
*seqhdr
= param
->seqhdr
;
560 lsmash_vc1_header_t
*ephdr
= param
->ephdr
;
561 /* Create a VC1SpecificBox */
562 lsmash_bits_t
*bits
= lsmash_bits_adhoc_create();
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 lsmash_bits_adhoc_cleanup( bits
);
589 /* Update box size. */
590 LSMASH_SET_BE32( data
, *data_length
);
594 static int vc1_try_to_put_header( lsmash_vc1_header_t
**p_hdr
, uint8_t *multiple_hdr
, void *hdr_data
, uint32_t hdr_length
)
596 lsmash_vc1_header_t
*hdr
= *p_hdr
;
599 hdr
= lsmash_malloc_zero( sizeof(lsmash_vc1_header_t
) );
601 return LSMASH_ERR_MEMORY_ALLOC
;
605 *multiple_hdr
|= hdr
->ebdu_size
== hdr_length
? !!memcmp( hdr_data
, hdr
->ebdu
, hdr
->ebdu_size
) : 1;
608 hdr
->ebdu
= lsmash_memdup( hdr_data
, hdr_length
);
609 hdr
->ebdu_size
= hdr
->ebdu
? hdr_length
: 0;
611 return hdr
->ebdu
? 0 : LSMASH_ERR_MEMORY_ALLOC
;
614 int lsmash_put_vc1_header( lsmash_vc1_specific_parameters_t
*param
, void *hdr_data
, uint32_t hdr_length
)
616 if( !param
|| !hdr_data
|| hdr_length
< 5 )
617 return LSMASH_ERR_FUNCTION_PARAM
;
618 /* Check start code prefix (0x000001). */
619 uint8_t *data
= (uint8_t *)hdr_data
;
620 if( data
[0] != 0x00 || data
[1] != 0x00 || data
[2] != 0x01 )
621 return LSMASH_ERR_INVALID_DATA
;
622 if( data
[3] == 0x0F ) /* sequence header */
623 return vc1_try_to_put_header( ¶m
->seqhdr
, ¶m
->multiple_sequence
, hdr_data
, hdr_length
);
624 else if( data
[3] == 0x0E ) /* entry point header */
625 return vc1_try_to_put_header( ¶m
->ephdr
, ¶m
->multiple_entry
, hdr_data
, hdr_length
);
626 return LSMASH_ERR_INVALID_DATA
;
629 static int vc1_parse_succeeded
632 lsmash_vc1_specific_parameters_t
*param
636 if( info
->sequence
.present
&& info
->entry_point
.present
)
638 *param
= info
->dvc1_param
;
639 /* Avoid freeing headers. */
640 info
->dvc1_param
.seqhdr
= NULL
;
641 info
->dvc1_param
.ephdr
= NULL
;
645 ret
= LSMASH_ERR_INVALID_DATA
;
646 vc1_cleanup_parser( info
);
650 static inline int vc1_parse_failed
656 vc1_cleanup_parser( info
);
660 int lsmash_setup_vc1_specific_parameters_from_access_unit( lsmash_vc1_specific_parameters_t
*param
, uint8_t *data
, uint32_t data_length
)
662 if( !param
|| !data
|| data_length
== 0 )
663 return LSMASH_ERR_FUNCTION_PARAM
;
664 vc1_info_t
*info
= &(vc1_info_t
){ { 0 } };
665 lsmash_bs_t
*bs
= &(lsmash_bs_t
){ 0 };
666 int err
= lsmash_bs_set_empty_stream( bs
, data
, data_length
);
669 if( (err
= vc1_setup_parser( info
, 1 )) < 0 )
670 return vc1_parse_failed( info
, err
);
671 info
->dvc1_param
= *param
;
672 vc1_stream_buffer_t
*sb
= &info
->buffer
;
676 uint64_t trailing_zero_bytes
;
677 uint64_t ebdu_length
= vc1_find_next_start_code_prefix( bs
, &bdu_type
, &trailing_zero_bytes
);
678 if( ebdu_length
<= VC1_START_CODE_LENGTH
&& lsmash_bs_is_end( bs
, ebdu_length
) )
679 /* For the last EBDU. This EBDU already has been parsed. */
680 return vc1_parse_succeeded( info
, param
);
681 else if( bdu_type
== 0xFF )
682 return vc1_parse_failed( info
, LSMASH_ERR_INVALID_DATA
);
683 uint64_t next_ebdu_head_pos
= info
->ebdu_head_pos
685 + trailing_zero_bytes
;
686 if( bdu_type
>= 0x0A && bdu_type
<= 0x0F )
688 /* Complete the current access unit if encountered delimiter of current access unit. */
689 if( vc1_find_au_delimit_by_bdu_type( bdu_type
, info
->prev_bdu_type
) )
690 /* The last video coded EBDU belongs to the access unit you want at this time. */
691 return vc1_parse_succeeded( info
, param
);
692 /* Increase the buffer if needed. */
693 if( sb
->bank
->buffer_size
< ebdu_length
694 && (err
= vc1_supplement_buffer( sb
, NULL
, 2 * ebdu_length
)) < 0 )
695 return vc1_parse_failed( info
, err
);
696 /* Process EBDU by its BDU type. */
697 uint8_t *ebdu
= lsmash_bs_get_buffer_data( bs
);
700 /* FRM_SC: Frame start code
701 * FLD_SC: Field start code
702 * SLC_SC: Slice start code
703 * SEQ_SC: Sequence header start code
704 * EP_SC: Entry-point start code
705 * PIC_L: Picture layer
707 * SEQ_L: Sequence layer
708 * EP_L: Entry-point layer */
710 * For the Progressive or Frame Interlace mode, shall signal the beginning of a new video frame.
711 * For the Field Interlace mode, shall signal the beginning of a sequence of two independently coded video fields.
712 * [FRM_SC][PIC_L][[FLD_SC][PIC_L] (optional)][[SLC_SC][SLC_L] (optional)] ... */
714 vc1_picture_info_t
*picture
= &info
->picture
;
715 if( (err
= vc1_parse_advanced_picture( info
->bits
, &info
->sequence
, picture
, info
->buffer
.rbdu
, ebdu
, ebdu_length
)) < 0 )
716 return vc1_parse_failed( info
, err
);
717 info
->dvc1_param
.bframe_present
|= picture
->frame_coding_mode
== 0x3
718 ? picture
->type
>= VC1_ADVANCED_FIELD_PICTURE_TYPE_BB
719 : picture
->type
== VC1_ADVANCED_PICTURE_TYPE_B
|| picture
->type
== VC1_ADVANCED_PICTURE_TYPE_BI
;
722 * Shall only be used for Field Interlaced frames
723 * and shall only be used to signal the beginning of the second field of the frame.
724 * [FRM_SC][PIC_L][FLD_SC][PIC_L][[SLC_SC][SLC_L] (optional)] ...
725 * Field start code is followed by INTERLACE_FIELD_PICTURE_FIELD2() which doesn't have info of its field picture type.*/
728 * Shall not be used for start code of the first slice of a frame.
729 * Shall not be used for start code of the first slice of an interlace field coded picture.
730 * [FRM_SC][PIC_L][[FLD_SC][PIC_L] (optional)][SLC_SC][SLC_L][[SLC_SC][SLC_L] (optional)] ...
731 * Slice layer may repeat frame header. We just ignore it. */
732 info
->dvc1_param
.slice_present
= 1;
734 case 0x0E : /* Entry-point header
735 * Entry-point indicates the direct followed frame is a start of group of frames.
736 * Entry-point doesn't indicates the frame is a random access point when multiple sequence headers are present,
737 * since it is necessary to decode sequence header which subsequent frames belong to for decoding them.
738 * Entry point shall be followed by
739 * 1. I-picture - progressive or frame interlace
740 * 2. I/I-picture, I/P-picture, or P/I-picture - field interlace
741 * [[SEQ_SC][SEQ_L] (optional)][EP_SC][EP_L][FRM_SC][PIC_L] ... */
742 if( (err
= vc1_parse_entry_point_header( info
, ebdu
, ebdu_length
, 1 )) < 0 )
743 return vc1_parse_failed( info
, err
);
745 case 0x0F : /* Sequence header
746 * [SEQ_SC][SEQ_L][EP_SC][EP_L][FRM_SC][PIC_L] ... */
747 if( (err
= vc1_parse_sequence_header( info
, ebdu
, ebdu_length
, 1 )) < 0 )
748 return vc1_parse_failed( info
, err
);
750 default : /* End-of-sequence (0x0A) */
754 /* Move to the first byte of the next EBDU. */
755 info
->prev_bdu_type
= bdu_type
;
756 if( lsmash_bs_read_seek( bs
, next_ebdu_head_pos
, SEEK_SET
) != next_ebdu_head_pos
)
757 return vc1_parse_failed( info
, LSMASH_ERR_NAMELESS
);
758 /* Check if no more data to read from the stream. */
759 if( !lsmash_bs_is_end( bs
, VC1_START_CODE_PREFIX_LENGTH
) )
760 info
->ebdu_head_pos
= next_ebdu_head_pos
;
762 return vc1_parse_succeeded( info
, param
);
766 static inline int vc1_check_next_start_code_prefix( uint8_t *buf_pos
, uint8_t *buf_end
)
768 return ((buf_pos
+ 2) < buf_end
) && !buf_pos
[0] && !buf_pos
[1] && (buf_pos
[2] == 0x01);
771 int vc1_construct_specific_parameters( lsmash_codec_specific_t
*dst
, lsmash_codec_specific_t
*src
)
773 assert( dst
&& dst
->data
.structured
&& src
&& src
->data
.unstructured
);
774 if( src
->size
< ISOM_BASEBOX_COMMON_SIZE
+ 7 )
775 return LSMASH_ERR_INVALID_DATA
;
776 lsmash_vc1_specific_parameters_t
*param
= (lsmash_vc1_specific_parameters_t
*)dst
->data
.structured
;
777 uint8_t *data
= src
->data
.unstructured
;
778 uint64_t size
= LSMASH_GET_BE32( data
);
779 data
+= ISOM_BASEBOX_COMMON_SIZE
;
782 size
= LSMASH_GET_BE64( data
);
785 if( size
!= src
->size
)
786 return LSMASH_ERR_INVALID_DATA
;
787 param
->profile
= (data
[0] >> 4) & 0x0F;
788 if( param
->profile
!= 12 )
789 return LSMASH_ERR_PATCH_WELCOME
; /* We don't support profile other than 12 (Advanced profile). */
790 param
->level
= (data
[0] >> 1) & 0x07;
791 param
->cbr
= (data
[1] >> 4) & 0x01;
792 param
->interlaced
= !((data
[2] >> 5) & 0x01);
793 param
->multiple_sequence
= !((data
[2] >> 4) & 0x01);
794 param
->multiple_entry
= !((data
[2] >> 3) & 0x01);
795 param
->slice_present
= !((data
[2] >> 2) & 0x01);
796 param
->bframe_present
= !((data
[2] >> 1) & 0x01);
797 param
->framerate
= LSMASH_GET_BE32( &data
[3] );
798 /* Try to get seqhdr_ephdr[]. */
801 param
->seqhdr
= lsmash_malloc_zero( sizeof(lsmash_vc1_header_t
) );
803 return LSMASH_ERR_MEMORY_ALLOC
;
807 param
->ephdr
= lsmash_malloc_zero( sizeof(lsmash_vc1_header_t
) );
809 return LSMASH_ERR_MEMORY_ALLOC
;
811 lsmash_vc1_header_t
*seqhdr
= param
->seqhdr
;
812 lsmash_vc1_header_t
*ephdr
= param
->ephdr
;
815 uint8_t *end
= src
->data
.unstructured
+ src
->size
;
816 /* Find the start point of Sequence header EBDU. */
819 if( vc1_check_next_start_code_prefix( pos
, end
) && (pos
+ 3 < end
) && *(pos
+ 3) == 0x0F )
821 seqhdr
->ebdu_size
= 4;
827 /* Find the end point of Sequence header EBDU. */
830 if( vc1_check_next_start_code_prefix( pos
, end
) )
832 ++ seqhdr
->ebdu_size
;
834 /* Find the start point of Entry-point header EBDU. */
837 if( vc1_check_next_start_code_prefix( pos
, end
) && (pos
+ 3 < end
) && *(pos
+ 3) == 0x0E )
839 ephdr
->ebdu_size
= 4;
845 /* Find the end point of Entry-point header EBDU. */
848 if( vc1_check_next_start_code_prefix( pos
, end
) )
852 /* Append the Sequence header EBDU and Entry-point header EBDU if present. */
853 if( seqhdr
->ebdu_size
)
855 lsmash_free( seqhdr
->ebdu
);
856 seqhdr
->ebdu
= lsmash_memdup( data
, seqhdr
->ebdu_size
);
858 return LSMASH_ERR_MEMORY_ALLOC
;
860 if( ephdr
->ebdu_size
)
862 lsmash_free( ephdr
->ebdu
);
863 ephdr
->ebdu
= lsmash_memdup( data
, ephdr
->ebdu_size
);
865 return LSMASH_ERR_MEMORY_ALLOC
;
870 int vc1_copy_codec_specific( lsmash_codec_specific_t
*dst
, lsmash_codec_specific_t
*src
)
872 assert( src
&& src
->format
== LSMASH_CODEC_SPECIFIC_FORMAT_STRUCTURED
&& src
->data
.structured
);
873 assert( dst
&& dst
->format
== LSMASH_CODEC_SPECIFIC_FORMAT_STRUCTURED
&& dst
->data
.structured
);
874 lsmash_vc1_specific_parameters_t
*src_data
= (lsmash_vc1_specific_parameters_t
*)src
->data
.structured
;
875 lsmash_vc1_specific_parameters_t
*dst_data
= (lsmash_vc1_specific_parameters_t
*)dst
->data
.structured
;
876 lsmash_destroy_vc1_headers( dst_data
);
877 *dst_data
= *src_data
;
878 if( !src_data
->seqhdr
&& !src_data
->ephdr
)
880 if( src_data
->seqhdr
)
882 dst_data
->seqhdr
= lsmash_malloc_zero( sizeof(lsmash_vc1_header_t
) );
883 if( !dst_data
->seqhdr
)
884 return LSMASH_ERR_MEMORY_ALLOC
;
885 if( src_data
->seqhdr
->ebdu_size
)
887 dst_data
->seqhdr
->ebdu
= lsmash_memdup( src_data
->seqhdr
->ebdu
, src_data
->seqhdr
->ebdu_size
);
888 if( !dst_data
->seqhdr
->ebdu
)
890 lsmash_destroy_vc1_headers( dst_data
);
891 return LSMASH_ERR_MEMORY_ALLOC
;
894 dst_data
->seqhdr
->ebdu_size
= src_data
->seqhdr
->ebdu_size
;
896 if( src_data
->ephdr
)
898 dst_data
->ephdr
= lsmash_malloc_zero( sizeof(lsmash_vc1_header_t
) );
899 if( !dst_data
->ephdr
)
901 lsmash_destroy_vc1_headers( dst_data
);
902 return LSMASH_ERR_MEMORY_ALLOC
;
904 if( src_data
->ephdr
->ebdu_size
)
906 dst_data
->ephdr
->ebdu
= lsmash_memdup( src_data
->ephdr
->ebdu
, src_data
->ephdr
->ebdu_size
);
907 if( !dst_data
->ephdr
->ebdu
)
909 lsmash_destroy_vc1_headers( dst_data
);
910 return LSMASH_ERR_MEMORY_ALLOC
;
913 dst_data
->ephdr
->ebdu_size
= src_data
->ephdr
->ebdu_size
;
918 int vc1_print_codec_specific( FILE *fp
, lsmash_file_t
*file
, isom_box_t
*box
, int level
)
920 assert( box
->manager
& LSMASH_BINARY_CODED_BOX
);
922 lsmash_ifprintf( fp
, indent
++, "[%s: VC1 Specific Box]\n", isom_4cc2str( box
->type
.fourcc
) );
923 lsmash_ifprintf( fp
, indent
, "position = %"PRIu64
"\n", box
->pos
);
924 lsmash_ifprintf( fp
, indent
, "size = %"PRIu64
"\n", box
->size
);
925 if( box
->size
< ISOM_BASEBOX_COMMON_SIZE
+ 7 )
926 return LSMASH_ERR_INVALID_DATA
;
927 uint8_t *data
= box
->binary
;
928 isom_skip_box_common( &data
);
929 uint8_t profile
= (data
[0] >> 4) & 0x0F;
931 return 0; /* We don't support profile other than 12 (Advanced profile). */
932 lsmash_ifprintf( fp
, indent
, "profile = %"PRIu8
"\n", profile
);
933 lsmash_ifprintf( fp
, indent
, "level = %"PRIu8
"\n", (data
[0] >> 1) & 0x07 );
934 lsmash_ifprintf( fp
, indent
, "reserved = %"PRIu8
"\n", data
[0] & 0x01 );
935 lsmash_ifprintf( fp
, indent
, "level = %"PRIu8
"\n", (data
[1] >> 5) & 0x07 );
936 lsmash_ifprintf( fp
, indent
, "cbr = %"PRIu8
"\n", (data
[1] >> 4) & 0x01 );
937 lsmash_ifprintf( fp
, indent
, "reserved1 = 0x%02"PRIx8
"\n", (data
[1] & 0x0F) | ((data
[2] >> 6) & 0x03) );
938 lsmash_ifprintf( fp
, indent
, "no_interlace = %"PRIu8
"\n", (data
[2] >> 5) & 0x01 );
939 lsmash_ifprintf( fp
, indent
, "no_multiple_seq = %"PRIu8
"\n", (data
[2] >> 4) & 0x01 );
940 lsmash_ifprintf( fp
, indent
, "no_multiple_entry = %"PRIu8
"\n", (data
[2] >> 3) & 0x01 );
941 lsmash_ifprintf( fp
, indent
, "no_slice_code = %"PRIu8
"\n", (data
[2] >> 2) & 0x01 );
942 lsmash_ifprintf( fp
, indent
, "no_bframe = %"PRIu8
"\n", (data
[2] >> 1) & 0x01 );
943 lsmash_ifprintf( fp
, indent
, "reserved2 = %"PRIu8
"\n", data
[2] & 0x01 );
944 uint32_t framerate
= LSMASH_GET_BE32( &data
[3] );
945 lsmash_ifprintf( fp
, indent
, "framerate = %"PRIu32
"\n", framerate
);
946 uint32_t seqhdr_ephdr_size
= box
->size
- (data
- box
->binary
+ 7);
947 if( seqhdr_ephdr_size
)
949 lsmash_ifprintf( fp
, indent
, "seqhdr_ephdr[]\n" );
951 for( uint32_t i
= 0; i
< seqhdr_ephdr_size
; i
+= 8 )
953 lsmash_ifprintf( fp
, indent
+ 1, "" );
954 for( uint32_t j
= 0; ; j
++ )
955 if( j
== 7 || (i
+ j
== seqhdr_ephdr_size
- 1) )
957 fprintf( fp
, "0x%02"PRIx8
"\n", data
[i
+ j
] );
961 fprintf( fp
, "0x%02"PRIx8
" ", data
[i
+ j
] );