分析一段H264视频数据
分析一段H264视频数据
Posted on 2007-05-31 09:42 vcommon 阅读(1968) 评论(8) 编辑 收藏 引用
分析
00 00 00 01 67 42 00 1E 99 A0 B1 31 00 00 00 01
H264的数据流分为两种,一种是NAL UNIT stream(RTP),一种是 bits stream,
两者可以互相转换。我们分析的这个是 bit stream,根据Annex B
00 00 00 01 67 42 00 1E 99 A0 B1 31 是 一个NAL,在两个00 00 00 01之间
0110 0111 0100 0010 0000 0000 0001 1110 1001 1001 1010 0000 1011 0001 0011 0001
forbidden_zero_bit(1) = 0
nal_ref_idc(2)= 11
nal_unit_type(5) = 0 0111:seq_parameter_set_rbsp( )
所以 processSPS
profile_idc(8):42:0100 0010
constraint_set0_flag(1):0
constraint_set1_flag(1):0
constraint_set2_flag(1):0
constraint_set3_flag(1):0
reserved_zero_4bits(4):0
level_idc(8):1E
seq_parameter_set_id(UE(V)):
ue(v): unsigned integer Exp-Golomb-coded syntax element with the left bit first. The parsing process for this descriptor is specified in subclause 9.1
uvlC: 1001:根据Table9.1 , value= 0,只占1bit.
根据profile_idc忽略掉一部分。
log2_max_frame_num_minus4(ue(v): 001 1001,len = 5,value= 5
pic_order_cnt_type(ue(v)):01 1010,len = 3,value = 2
根据pic_order_cnt_type忽略几个参数
num_ref_frames(ue):010,len = 3,value = 1
0000 1011 0001 0011 0001
gaps_in_frame_num_value_allowed_flag(1) = 0
pic_width_in_mbs_minus1(ue):000 1011 ,len = 7,value = 10;
pic_height_in_map_units_minus1(ue):0001 001,len = 7,value = 8
frame_mbs_only_flag(1) = 1
忽略1
direct_8x8_inference_flag(1):0
忽略
vui_parameters_present_flag(1):0
忽略
NALU结束
68 CE 38 80 00 00 00 01
0110 1000
forbidden_zero_bit(1) = 0
nal_ref_idc(2)= 11
nal_unit_type(5) =01000:pic_parameter_set_rbsp( ),7.3.2.2
1100
pic_parameter_set_id (ue)=0
seq_parameter_set_id(ue)=0
entropy_coding_mode_flag(1) :0, 重要的flag,0 表示编码Exp-Golomb coded and CAVLC,1表示CABAC
pic_order_present_flag(1):0
1110
num_slice_groups_minus1(ue):0
忽略
num_ref_idx_l0_active_minus1(ue):0
num_ref_idx_l1_active_minus1(ue):0
weighted_pred_flag(1);0
0011 1000 1000 0000
weighted_bipred_idc(2):00
pic_init_qp_minus26 /* relative to 26 */(se):0
pic_init_qs_minus26 /* relative to 26 */(se):0
chroma_qp_index_offset(se):0
deblocking_filter_control_present_flag(1);0
constrained_intra_pred_flag(1):0
redundant_pic_cnt_present_flag(1):0
忽略
NALU结束
65 88 80 21 71 27 1B 88…….3888*16 byte
65:0110 0101
forbidden_zero_bit(1) = 0
nal_ref_idc(2)= 11
nal_unit_type(5) =0 0101:slice_layer_without_partitioning_rbsp( ),IDR浈
Slice
Slice_Header:
first_mb_in_slice(ue):0
slice_type(ue):000 1000 = 7
pic_parameter_set_id(ue) = 0
80 21:000 0000 0010 0001
frame_num(u(v): frame_num is used as an identifier for pictures and shall be represented by log2_max_frame_num_minus4 + 4 bits,9 bits = 0
忽略
if( nal_unit_type = = 5 ) //IDR frame
idr_pic_id(u(e)):0
忽略N多
ref_pic_list_reordering( ) 见7。3。3。1忽略,Islice,SI slice,B slice
nal_ref_idc =11 所以dec_ref_pic_marking( )
nal_unit_type = 5,所以
no_output_of_prior_pics_flag(1):0
long_term_reference_flag(1):0
忽略
。。71 27
001 0111 0001 0010 0111
slice_qp_delta(se(v):001 01 ,4:-2
忽略
slice_data( ):7.3.4
对I-Slice:忽略N多
进入if( moreDataFlag ) { if( MbaffFrameFlag && ( CurrMbAddr % 2 = = 0 | | ( CurrMbAddr % 2 = = 1 && prevMbSkipped ) ) )mb_field_decoding_flag
macroblock_layer( )}
mb_field_decoding_flag忽略
macroblock_layer( )
mb_type(ue(v):0
mb_pred( mb_type )
prev_intra4x4_pred_mode_flag[ luma4x4BlkIdx ] (1bit, 对babac是ae(v)):1
1 27:0001 0010 0111
prev_intra4x4_pred_mode_flag[ 1 ] : 0001,0,001
0010 0111
prev_intra4x4_pred_mode_flag[ 2 ] : 0010,0,010
prev_intra4x4_pred_mode_flag[ 3] : 0111,0,111
……16个
1b 88 00 3e cf.
intra_chroma_pred_mode(ue(v)) : 最后的一个1bit:0
接下来是macroblock_layer的coded_block_pattern和run level,既系数
c0 06 ad a0 18
1100 0000 0000 0110 1010 0000 0001 1000
coded_block_pattern(me(v):0,根据Table 9?4,= 47,0x2f
mb_qp_delta(se(v):):0 len =1
residual( )见7.3.5.3
residual_block( LumaLevel[ i8x8 * 4 + i4x4 ], 16 )
coeff_token(ce(v): 00 0000 0000 0110 1
nc = 0(left block and top block 相关的):
len: { // 0702
{ 1, 6, 8, 9,10,11,13,13,13,14,14,15,15,16,16,16,16},
{ 0, 2, 6, 8, 9,10,11,13,13,14,14,15,15,15,16,16,16},
{ 0, 0, 3, 7, 8, 9,10,11,13,13,14,14,15,15,16,16,16},
{ 0, 0, 0, 5, 6, 7, 8, 9,10,11,13,14,14,15,15,16,16},
},
{
{ 2, 6, 6, 7, 8, 8, 9,11,11,12,12,12,13,13,13,14,14},
{ 0, 2, 5, 6, 6, 7, 8, 9,11,11,12,12,13,13,14,14,14},
{ 0, 0, 3, 6, 6, 7, 8, 9,11,11,12,12,13,13,13,14,14},
{ 0, 0, 0, 4, 4, 5, 6, 6, 7, 9,11,11,12,13,13,13,14},
},
{
{ 4, 6, 6, 6, 7, 7, 7, 7, 8, 8, 9, 9, 9,10,10,10,10},
{ 0, 4, 5, 5, 5, 5, 6, 6, 7, 8, 8, 9, 9, 9,10,10,10},
{ 0, 0, 4, 5, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9,10,10,10},
{ 0, 0, 0, 4, 4, 4, 4, 4, 5, 6, 7, 8, 8, 9,10,10,10},
},
code:
{ 1, 5, 7, 7, 7, 7,15,11, 8,15,11,15,11,15,11, 7,4},
{ 0, 1, 4, 6, 6, 6, 6,14,10,14,10,14,10, 1,14,10,6},
{ 0, 0, 1, 5, 5, 5, 5, 5,13, 9,13, 9,13, 9,13, 9,5},
{ 0, 0, 0, 3, 3, 4, 4, 4, 4, 4,12,12, 8,12, 8,12,8},
},
{
{ 3,11, 7, 7, 7, 4, 7,15,11,15,11, 8,15,11, 7, 9,7},
{ 0, 2, 7,10, 6, 6, 6, 6,14,10,14,10,14,10,11, 8,6},
{ 0, 0, 3, 9, 5, 5, 5, 5,13, 9,13, 9,13, 9, 6,10,5},
{ 0, 0, 0, 5, 4, 6, 8, 4, 4, 4,12, 8,12,12, 8, 1,4},
},
{
{15,15,11, 8,15,11, 9, 8,15,11,15,11, 8,13, 9, 5,1},
{ 0,14,15,12,10, 8,14,10,14,14,10,14,10, 7,12, 8,4},
{ 0, 0,13,14,11, 9,13, 9,13,10,13, 9,13, 9,11, 7,3},
{ 0, 0, 0,12,11,10, 9, 8,13,12,12,12, 8,12,10, 6,2},
},
根据表查的:
code = 13,len = 15,i= 12,j=2
所以numcoeff = 12,numtrailingones = 2
010 0000 0001 1000: totalzeros:根据numcoeff
int lentab[TOTRUN_NUM][16] =
{
{ 1,3,3,4,4,5,5,6,6,7,7,8,8,9,9,9},
{ 3,3,3,3,3,4,4,4,4,5,5,6,6,6,6},
{ 4,3,3,3,4,4,3,3,4,5,5,6,5,6},
{ 5,3,4,4,3,3,3,4,3,4,5,5,5},
{ 4,4,4,3,3,3,3,3,4,5,4,5},
{ 6,5,3,3,3,3,3,3,4,3,6},
{ 6,5,3,3,3,2,3,4,3,6},
{ 6,4,5,3,2,2,3,3,6},
{ 6,6,4,2,2,3,2,5},
{ 5,5,3,2,2,2,4},
{ 4,4,3,3,1,3},
{ 4,4,2,1,3}, numcoeff开始
{ 3,3,1,2},
{ 2,2,1},
{ 1,1},
};
int codtab[TOTRUN_NUM][16] =
{
{1,3,2,3,2,3,2,3,2,3,2,3,2,3,2,1},
{7,6,5,4,3,5,4,3,2,3,2,3,2,1,0},
{5,7,6,5,4,3,4,3,2,3,2,1,1,0},
{3,7,5,4,6,5,4,3,3,2,2,1,0},
{5,4,3,7,6,5,4,3,2,1,1,0},
{1,1,7,6,5,4,3,2,1,1,0},
{1,1,5,4,3,3,2,1,1,0},
{1,1,1,3,3,2,2,1,0},
{1,0,1,3,2,1,1,1,},
{1,0,1,3,2,1,1,},
{0,1,1,2,1,3},
{0,1,1,1,1}, numcoeff开始
{0,1,1,1},
{0,1,1},
{0,1},
};
Code = 1,len = 2,i=2,j = 0, totzeros = 2
Read run: 0 0000 0001 1000根据totzeros = 2
int lentab[TOTRUN_NUM][16] =
{
{1,1},
{1,2,2},
{2,2,2,2},
{2,2,2,3,3},
{2,2,3,3,3,3},
{2,3,3,3,3,3,3},
{3,3,3,3,3,3,3,4,5,6,7,8,9,10,11},
};
int codtab[TOTRUN_NUM][16] =
{
{1,0},
{1,1,0},
{3,2,1,0},
{3,2,1,1,0},
{3,2,3,2,1,0},
{3,0,1,3,2,5,4},
{7,6,5,4,3,2,1,1,1,1,1,1,1,1,1},
Code = 1,len =1,I = 0,j = 0
0.1.1 Slice data syntax
slice_data( ) { |
C |
Descriptor |
if( entropy_coding_mode_flag ) |
||
while( !byte_aligned( ) ) |
||
cabac_alignment_one_bit |
2 |
f(1) |
CurrMbAddr = first_mb_in_slice * ( 1 + MbaffFrameFlag ) |
||
moreDataFlag = 1 |
||
prevMbSkipped = 0 |
||
do { |
||
if( slice_type != I && slice_type != SI ) |
||
if( !entropy_coding_mode_flag ) { |
||
mb_skip_run |
2 |
ue(v) |
prevMbSkipped = ( mb_skip_run > 0 ) |
||
for( i="0"; i<mb_skip_run; i++ ) |
||
CurrMbAddr = NextMbAddress( CurrMbAddr ) |
||
moreDataFlag = more_rbsp_data( ) |
||
} else { |
||
mb_skip_flag |
2 |
ae(v) |
moreDataFlag = !mb_skip_flag |
||
} |
||
if( moreDataFlag ) { |
||
if( MbaffFrameFlag && ( CurrMbAddr % 2 = = 0 | | ( CurrMbAddr % 2 = = 1 && prevMbSkipped ) ) ) |
||
mb_field_decoding_flag |
2 |
u(1) | ae(v) |
macroblock_layer( ) |
2 | 3 | 4 |
|
} |
||
if( !entropy_coding_mode_flag ) |
||
moreDataFlag = more_rbsp_data( ) |
||
else { |
||
if( slice_type != I && slice_type != SI ) |
||
prevMbSkipped = mb_skip_flag |
||
if( MbaffFrameFlag && CurrMbAddr % 2 = = 0 ) |
||
moreDataFlag = 1 |
||
else { |
||
end_of_slice_flag |
2 |
ae(v) |
moreDataFlag = !end_of_slice_flag |
||
} |
||
} |
||
CurrMbAddr = NextMbAddress( CurrMbAddr ) |
||
} while( moreDataFlag ) |
||
} |
se(v) : CABAC正式介绍。根据Table 9 5 – coeff_token mapping to TotalCoeff( coeff_token ) and TrailingOnes( coeff_token )。
chroma_format_idc 无
Bit string form |
Range of codeNum |
1 |
0 |
0 1 x0 |
1-2 |
0 0 1 x1 x0 |
3-6 |
0 0 0 1 x2 x1 x0 |
7-14 |
0 0 0 0 1 x3 x2 x1 x0 |
15-30 |
0 0 0 0 0 1 x4 x3 x2 x1 x0 |
31-62 |
… |
… |
0.1.1.1 Slice layer without partitioning RBSP syntax
slice_layer_without_partitioning_rbsp( ) { |
C |
Descriptor |
slice_header( ) |
2 |
|
slice_data( ) /* all categories of slice_data( ) syntax */ |
2 | 3 | 4 |
|
rbsp_slice_trailing_bits( ) |
2 |
|
} |
0.1.1.2 Sequence parameter set RBSP syntax
seq_parameter_set_rbsp( ) { |
C |
Descriptor |
profile_idc |
0 |
u(8) |
constraint_set0_flag |
0 |
u(1) |
constraint_set1_flag |
0 |
u(1) |
constraint_set2_flag |
0 |
u(1) |
constraint_set3_flag |
0 |
u(1) |
reserved_zero_4bits /* equal to 0 */ |
0 |
u(4) |
level_idc |
0 |
u(8) |
seq_parameter_set_id |
0 |
ue(v) |
if( profile_idc = = 100 | | profile_idc = = 110 | | |
||
chroma_format_idc |
0 |
ue(v) |
if( chroma_format_idc = = 3 ) |
||
residual_colour_transform_flag |
0 |
u(1) |
bit_depth_luma_minus8 |
0 |
ue(v) |
bit_depth_chroma_minus8 |
0 |
ue(v) |
qpprime_y_zero_transform_bypass_flag |
0 |
u(1) |
seq_scaling_matrix_present_flag |
0 |
u(1) |
if( seq_scaling_matrix_present_flag ) |
||
for( i = 0; i < 8; i++ ) { |
||
seq_scaling_list_present_flag[ i ] |
0 |
u(1) |
if( seq_scaling_list_present_flag[ i ] ) |
||
if( i < 6 ) |
||
scaling_list( ScalingList4x4[ i ], 16, |
0 |
|
else |
||
scaling_list( ScalingList8x8[ i – 6 ], 64, |
0 |
|
} |
||
} |
||
log2_max_frame_num_minus4 |
0 |
ue(v) |
pic_order_cnt_type |
0 |
ue(v) |
if( pic_order_cnt_type = = 0 ) |
||
log2_max_pic_order_cnt_lsb_minus4 |
0 |
ue(v) |
else if( pic_order_cnt_type = = 1 ) { |
||
delta_pic_order_always_zero_flag |
0 |
u(1) |
offset_for_non_ref_pic |
0 |
se(v) |
offset_for_top_to_bottom_field |
0 |
se(v) |
num_ref_frames_in_pic_order_cnt_cycle |
0 |
ue(v) |
for( i = 0; i < num_ref_frames_in_pic_order_cnt_cycle; i++ ) |
||
offset_for_ref_frame[ i ] |
0 |
se(v) |
} |
||
num_ref_frames |
0 |
ue(v) |
gaps_in_frame_num_value_allowed_flag |
0 |
u(1) |
pic_width_in_mbs_minus1 |
0 |
ue(v) |
pic_height_in_map_units_minus1 |
0 |
ue(v) |
frame_mbs_only_flag |
0 |
u(1) |
if( !frame_mbs_only_flag ) |
||
mb_adaptive_frame_field_flag |
0 |
u(1) |
direct_8x8_inference_flag |
0 |
u(1) |
frame_cropping_flag |
0 |
u(1) |
if( frame_cropping_flag ) { |
||
frame_crop_left_offset |
0 |
ue(v) |
frame_crop_right_offset |
0 |
ue(v) |
frame_crop_top_offset |
0 |
ue(v) |
frame_crop_bottom_offset |
0 |
ue(v) |
} |
||
vui_parameters_present_flag |
0 |
u(1) |
if( vui_parameters_present_flag ) |
||
vui_parameters( ) |
0 |
|
rbsp_trailing_bits( ) |
0 |
|
} |
Table 7?1 – NAL unit type codes
nal_unit_type |
Content of NAL unit and RBSP syntax structure |
C |
0 |
Unspecified |
|
1 |
Coded slice of a non-IDR picture |
2, 3, 4 |
2 |
Coded slice data partition A |
2 |
3 |
Coded slice data partition B |
3 |
4 |
Coded slice data partition C |
4 |
5 |
Coded slice of an IDR picture |
2, 3 |
6 |
Supplemental enhancement information (SEI) |
5 |
7 |
Sequence parameter set |
0 |
8 |
Picture parameter set |
1 |
9 |
Access unit delimiter |
6 |
10 |
End of sequence |
7 |
11 |
End of stream |
8 |
12 |
Filler data |
9 |
13 |
Sequence parameter set extension |
10 |
14..18 |
Reserved |
|
19 |
Coded slice of an auxiliary coded picture without partitioning |
2, 3, 4 |
20..23 |
Reserved |
|
24..31 |
Unspecified |
byte_stream_nal_unit( NumBytesInNALunit ) { |
C |
Descriptor |
while( next_bits( 24 ) != 0x000001 && |
||
leading_zero_8bits /* equal to 0x00 */ |
f(8) |
|
if( next_bits( 24 ) != 0x000001 ) |
||
zero_byte /* equal to 0x00 */ |
f(8) |
|
start_code_prefix_one_3bytes /* equal to 0x000001 */ |
f(24) |
|
nal_unit( NumBytesInNALunit ) |
||
while( more_data_in_byte_stream( ) && |
||
trailing_zero_8bits /* equal to 0x00 */ |
f(8) |
|
} |
0.1.1.3 Picture parameter set RBSP syntax
pic_parameter_set_rbsp( ) { |
C |
Descriptor |
pic_parameter_set_id |
1 |
ue(v) |
seq_parameter_set_id |
1 |
ue(v) |
entropy_coding_mode_flag |
1 |
u(1) |
pic_order_present_flag |
1 |
u(1) |
num_slice_groups_minus1 |
1 |
ue(v) |
if( num_slice_groups_minus1 > 0 ) { |
||
slice_group_map_type |
1 |
ue(v) |
if( slice_group_map_type = = 0 ) |
||
for( iGroup = 0; iGroup <= num_slice_groups_minus1; iGroup++ ) |
||
run_length_minus1[ iGroup ] |
1 |
ue(v) |
else if( slice_group_map_type = = 2 ) |
||
for( iGroup = 0; iGroup < num_slice_groups_minus1; iGroup++ ) { |
||
top_left[ iGroup ] |
1 |
ue(v) |
bottom_right[ iGroup ] |
1 |
ue(v) |
} |
||
else if( slice_group_map_type = = 3 | | |
||
slice_group_change_direction_flag |
1 |
u(1) |
slice_group_change_rate_minus1 |
1 |
ue(v) |
} else if( slice_group_map_type = = 6 ) { |
||
pic_size_in_map_units_minus1 |
1 |
ue(v) |
for( i = 0; i <= pic_size_in_map_units_minus1; i++ ) |
||
slice_group_id[ i ] |
1 |
u(v) |
} |
||
} |
||
num_ref_idx_l0_active_minus1 |
1 |
ue(v) |
num_ref_idx_l1_active_minus1 |
1 |
ue(v) |
weighted_pred_flag |
1 |
u(1) |
weighted_bipred_idc |
1 |
u(2) |
pic_init_qp_minus26 /* relative to 26 */ |
1 |
se(v) |
pic_init_qs_minus26 /* relative to 26 */ |
1 |
se(v) |
chroma_qp_index_offset |
1 |
se(v) |
deblocking_filter_control_present_flag |
1 |
u(1) |
constrained_intra_pred_flag |
1 |
u(1) |
redundant_pic_cnt_present_flag |
1 |
u(1) |
if( more_rbsp_data( ) ) { |
||
transform_8x8_mode_flag |
1 |
u(1) |
pic_scaling_matrix_present_flag |
1 |
u(1) |
if( pic_scaling_matrix_present_flag ) |
||
for( i = 0; i < 6 + 2* transform_8x8_mode_flag; i++ ) { |
||
pic_scaling_list_present_flag[ i ] |
1 |
u(1) |
if( pic_scaling_list_present_flag[ i ] ) |
||
if( i < 6 ) |
||
scaling_list( ScalingList4x4[ i ], 16, |
1 |
|
else |
||
scaling_list( ScalingList8x8[ i – 6 ], 64, |
1 |
|
} |
||
second_chroma_qp_index_offset |
1 |
se(v) |
} |
||
rbsp_trailing_bits( ) |
1 |
|
} |
0.1.2 Slice header syntax
slice_header( ) { |
C |
Descriptor |
first_mb_in_slice |
2 |
ue(v) |
slice_type |
2 |
ue(v) |
pic_parameter_set_id |
2 |
ue(v) |
frame_num |
2 |
u(v) |
if( !frame_mbs_only_flag ) { |
||
field_pic_flag |
2 |
u(1) |
if( field_pic_flag ) |
||
bottom_field_flag |
2 |
u(1) |
} |
||
if( nal_unit_type = = 5 ) |
||
idr_pic_id |
2 |
ue(v) |
if( pic_order_cnt_type = = 0 ) { |
||
pic_order_cnt_lsb |
2 |
u(v) |
if( pic_order_present_flag && !field_pic_flag ) |
||
delta_pic_order_cnt_bottom |
2 |
se(v) |
} |
||
if( pic_order_cnt_type = = 1 && !delta_pic_order_always_zero_flag ) { |
||
delta_pic_order_cnt[ 0 ] |
2 |
se(v) |
if( pic_order_present_flag && !field_pic_flag ) |
||
delta_pic_order_cnt[ 1 ] |
2 |
se(v) |
} |
||
if( redundant_pic_cnt_present_flag ) |
||
redundant_pic_cnt |
2 |
ue(v) |
if( slice_type = = B ) |
||
direct_spatial_mv_pred_flag |
2 |
u(1) |
if( slice_type = = P | | slice_type = = SP | | slice_type = = B ) { |
||
num_ref_idx_active_override_flag |
2 |
u(1) |
if( num_ref_idx_active_override_flag ) { |
||
num_ref_idx_l0_active_minus1 |
2 |
ue(v) |
if( slice_type = = B ) |
||
num_ref_idx_l1_active_minus1 |
2 |
ue(v) |
} |
||
} |
||
ref_pic_list_reordering( ) |
2 |
|
if( ( weighted_pred_flag && ( slice_type = = P | | slice_type = = SP ) ) | | |
||
pred_weight_table( ) |
2 |
|
if( nal_ref_idc != 0 ) |
||
dec_ref_pic_marking( ) |
2 |
|
if( entropy_coding_mode_flag && slice_type != I && slice_type != SI ) |
||
cabac_init_idc |
2 |
ue(v) |
slice_qp_delta |
2 |
se(v) |
if( slice_type = = SP | | slice_type = = SI ) { |
||
if( slice_type = = SP ) |
||
sp_for_switch_flag |
2 |
u(1) |
slice_qs_delta |
2 |
se(v) |
} |
||
if( deblocking_filter_control_present_flag ) { |
||
disable_deblocking_filter_idc |
2 |
ue(v) |
if( disable_deblocking_filter_idc != 1 ) { |
||
slice_alpha_c0_offset_div2 |
2 |
se(v) |
slice_beta_offset_div2 |
2 |
se(v) |
} |
||
} |
||
if( num_slice_groups_minus1 > 0 && |
||
slice_group_change_cycle |
2 |
u(v) |
} |
0.1.3 Slice data syntax
slice_data( ) { |
C |
Descriptor |
if( entropy_coding_mode_flag ) |
||
while( !byte_aligned( ) ) |
||
cabac_alignment_one_bit |
2 |
f(1) |
CurrMbAddr = first_mb_in_slice * ( 1 + MbaffFrameFlag ) |
||
moreDataFlag = 1 |
||
prevMbSkipped = 0 |
||
do { |
||
if( slice_type != I && slice_type != SI ) |
||
if( !entropy_coding_mode_flag ) { |
||
mb_skip_run |
2 |
ue(v) |
prevMbSkipped = ( mb_skip_run > 0 ) |
||
for( i="0"; i<mb_skip_run; i++ ) |
||
CurrMbAddr = NextMbAddress( CurrMbAddr ) |
||
moreDataFlag = more_rbsp_data( ) |
||
} else { |
||
mb_skip_flag |
2 |
ae(v) |
moreDataFlag = !mb_skip_flag |
||
} |
||
if( moreDataFlag ) { |
||
if( MbaffFrameFlag && ( CurrMbAddr % 2 = = 0 | | ( CurrMbAddr % 2 = = 1 && prevMbSkipped ) ) ) |
||
mb_field_decoding_flag |
2 |
u(1) | ae(v) |
macroblock_layer( ) |
2 | 3 | 4 |
|
} |
||
if( !entropy_coding_mode_flag ) |
||
moreDataFlag = more_rbsp_data( ) |
||
else { |
||
if( slice_type != I && slice_type != SI ) |
||
prevMbSkipped = mb_skip_flag |
||
if( MbaffFrameFlag && CurrMbAddr % 2 = = 0 ) |
||
moreDataFlag = 1 |
||
else { |
||
end_of_slice_flag |
2 |
ae(v) |
moreDataFlag = !end_of_slice_flag |
||
} |
||
} |
||
CurrMbAddr = NextMbAddress( CurrMbAddr ) |
||
} while( moreDataFlag ) |
||
} |
The variable MbaffFrameFlag is derived as follows.
MbaffFrameFlag = ( mb_adaptive_frame_field_flag && !field_pic_flag ) (7-22)
0.1.4 Macroblock layer syntax
macroblock_layer( ) { |
C |
Descriptor |
mb_type |
2 |
ue(v) | ae(v) |
if( mb_type = = I_PCM ) { |
||
while( !byte_aligned( ) ) |
||
pcm_alignment_zero_bit |
2 |
f(1) |
for( i = 0; i < 256; i++ ) |
||
pcm_sample_luma[ i ] |
2 |
u(v) |
for( i = 0; i < 2 * MbWidthC * MbHeightC; i++ ) |
||
pcm_sample_chroma[ i ] |
2 |
u(v) |
} else { |
||
noSubMbPartSizeLessThan8x8Flag = 1 |
||
if( mb_type != I_NxN && MbPartPredMode( mb_type, 0 ) != Intra_16x16 && NumMbPart( mb_type ) = = 4 ) { |
||
sub_mb_pred( mb_type ) |
2 |
|
for( mbPartIdx = 0; mbPartIdx < 4; mbPartIdx++ ) |
||
if( sub_mb_type[ mbPartIdx ] != B_Direct_8x8 ) { |
||
if( NumSubMbPart( sub_mb_type[ mbPartIdx ] ) > 1 ) |
||
noSubMbPartSizeLessThan8x8Flag = 0 |
||
} else if( !direct_8x8_inference_flag ) |
||
noSubMbPartSizeLessThan8x8Flag = 0 |
||
} else { |
||
if( transform_8x8_mode_flag && mb_type = = I_NxN ) |
||
transform_size_8x8_flag |
2 |
u(1) | ae(v) |
mb_pred( mb_type ) |
2 |
|
} |
||
if( MbPartPredMode( mb_type, 0 ) != Intra_16x16 ) { |
||
coded_block_pattern |
2 |
me(v) | ae(v) |
if( CodedBlockPatternLuma > 0 && transform_8x8_mode_flag && mb_type != I_NxN && noSubMbPartSizeLessThan8x8Flag && ( mb_type != B_Direct_16x16 | | direct_8x8_inference_flag ) ) |
||
transform_size_8x8_flag |
2 |
u(1) | ae(v) |
} |
||
if( CodedBlockPatternLuma > 0 | | CodedBlockPatternChroma > 0 | | |
||
mb_qp_delta |
2 |
se(v) | ae(v) |
residual( ) |
3 | 4 |
|
} |
||
} |
||
} |
0.1.4.1 Macroblock prediction syntax
mb_pred( mb_type ) { |
C |
Descriptor |
if( MbPartPredMode( mb_type, 0 ) = = Intra_4x4 | | |
||
if( MbPartPredMode( mb_type, 0 ) = = Intra_4x4 ) |
||
for( luma4x4BlkIdx=0; luma4x4BlkIdx<16; luma4x4BlkIdx++ ) { |
||
prev_intra4x4_pred_mode_flag[ luma4x4BlkIdx ] |
2 |
u(1) | ae(v) |
if( !prev_intra4x4_pred_mode_flag[ luma4x4BlkIdx ] ) |
||
rem_intra4x4_pred_mode[ luma4x4BlkIdx ] |
2 |
u(3) | ae(v) |
} |
||
if( MbPartPredMode( mb_type, 0 ) = = Intra_8x8 ) |
||
for( luma8x8BlkIdx=0; luma8x8BlkIdx<4; luma8x8BlkIdx++ ) { |
||
prev_intra8x8_pred_mode_flag[ luma8x8BlkIdx ] |
2 |
u(1) | ae(v) |
if( !prev_intra8x8_pred_mode_flag[ luma8x8BlkIdx ] ) |
||
rem_intra8x8_pred_mode[ luma8x8BlkIdx ] |
2 |
u(3) | ae(v) |
} |
||
if( chroma_format_idc != 0 ) |
||
intra_chroma_pred_mode |
2 |
ue(v) | ae(v) |
} else if( MbPartPredMode( mb_type, 0 ) != Direct ) { |
||
for( mbPartIdx = 0; mbPartIdx < NumMbPart( mb_type ); mbPartIdx++) |
||
if( ( num_ref_idx_l0_active_minus1 > 0 | | |
||
ref_idx_l0[ mbPartIdx ] |
2 |
te(v) | ae(v) |
for( mbPartIdx = 0; mbPartIdx < NumMbPart( mb_type ); mbPartIdx++) |
||
if( ( num_ref_idx_l1_active_minus1 > 0 | | |
||
ref_idx_l1[ mbPartIdx ] |
2 |
te(v) | ae(v) |
for( mbPartIdx = 0; mbPartIdx < NumMbPart( mb_type ); mbPartIdx++) |
||
if( MbPartPredMode ( mb_type, mbPartIdx ) != Pred_L1 ) |
||
for( compIdx = 0; compIdx < 2; compIdx++ ) |
||
mvd_l0[ mbPartIdx ][ 0 ][ compIdx ] |
2 |
se(v) | ae(v) |
for( mbPartIdx = 0; mbPartIdx < NumMbPart( mb_type ); mbPartIdx++) |
||
if( MbPartPredMode( mb_type, mbPartIdx ) != Pred_L0 ) |
||
for( compIdx = 0; compIdx < 2; compIdx++ ) |
||
mvd_l1[ mbPartIdx ][ 0 ][ compIdx ] |
2 |
se(v) | ae(v) |
} |
||
} |
0.1.4.2 Residual data syntax
residual( ) { |
C |
Descriptor |
if( !entropy_coding_mode_flag ) |
||
residual_block = residual_block_cavlc |
||
else |
||
residual_block = residual_block_cabac |
||
if( MbPartPredMode( mb_type, 0 ) = = Intra_16x16 ) |
||
residual_block( Intra16x16DCLevel, 16 ) |
3 |
|
for( i8x8 = 0; i8x8 < 4; i8x8++ ) /* each luma 8x8 block */ |
||
if( !transform_size_8x8_flag | | !entropy_coding_mode_flag ) |
||
for( i4x4 = 0; i4x4 < 4; i4x4++ ) { /* each 4x4 sub-block of block */ |
||
if( CodedBlockPatternLuma & ( 1 << i8x8 ) ) |
||
if( MbPartPredMode( mb_type, 0 ) = = Intra_16x16 ) |
||
residual_block( Intra16x16ACLevel[ i8x8 * 4 + i4x4 ], 15 ) |
3 |
|
else |
||
residual_block( LumaLevel[ i8x8 * 4 + i4x4 ], 16 ) |
3 | 4 |
|
else if( MbPartPredMode( mb_type, 0 ) = = Intra_16x16 ) |
||
for( i = 0; i < 15; i++ ) |
||
Intra16x16ACLevel[ i8x8 * 4 + i4x4 ][ i ] = 0 |
||
else |
||
for( i = 0; i < 16; i++ ) |
||
LumaLevel[ i8x8 * 4 + i4x4 ][ i ] = 0 |
||
if( !entropy_coding_mode_flag && transform_size_8x8_flag ) |
||
for( i = 0; i < 16; i++ ) |
||
LumaLevel8x8[ i8x8 ][ 4 * i + i4x4 ] = |
||
} |
||
else if( CodedBlockPatternLuma & ( 1 << i8x8 ) ) |
||
residual_block( LumaLevel8x8[ i8x8 ], 64 ) |
3 | 4 |
|
else |
||
for( i = 0; i < 64; i++ ) |
||
LumaLevel8x8[ i8x8 ][ i ] = 0 |
||
if( chroma_format_idc != 0 ) { |
||
NumC8x8 = 4 / ( SubWidthC * SubHeightC ) |
||
for( iCbCr = 0; iCbCr < 2; iCbCr++ ) |
||
if( CodedBlockPatternChroma & 3 ) /* chroma DC residual present */ |
||
residual_block( ChromaDCLevel[ iCbCr ], 4 * NumC8x8 ) |
3 | 4 |
|
else |
||
for( i = 0; i < 4 * NumC8x8; i++ ) |
||
ChromaDCLevel[ iCbCr ][ i ] = 0 |
||
for( iCbCr = 0; iCbCr < 2; iCbCr++ ) |
||
for( i8x8 = 0; i8x8 < NumC8x8; i8x8++ ) |
||
for( i4x4 = 0; i4x4 < 4; i4x4++ ) |
||
if( CodedBlockPatternChroma & 2 ) |
||
residual_block( ChromaACLevel[ iCbCr ][ i8x8*4+i4x4 ], 15) |
3 | 4 |
|
else |
||
for( i = 0; i < 15; i++ ) |
||
ChromaACLevel[ iCbCr ][ i8x8*4+i4x4 ][ i ] = 0 |
||
} |
residual_block_cavlc( coeffLevel, maxNumCoeff ) { |
C |
Descriptor |
for( i = 0; i < maxNumCoeff; i++ ) |
||
coeffLevel[ i ] = 0 |
||
coeff_token |
3 | 4 |
ce(v) |
if( TotalCoeff( coeff_token ) > 0 ) { |
||
if( TotalCoeff( coeff_token ) > 10 && TrailingOnes( coeff_token ) < 3 ) |
||
suffixLength = 1 |
||
else |
||
suffixLength = 0 |
||
for( i = 0; i < TotalCoeff( coeff_token ); i++ ) |
||
if( i < TrailingOnes( coeff_token ) ) { |
||
trailing_ones_sign_flag |
3 | 4 |
u(1) |
level[ i ] = 1 – 2 * trailing_ones_sign_flag |
||
} else { |
||
level_prefix |
3 | 4 |
ce(v) |
levelCode = ( Min( 15, level_prefix ) << suffixLength ) |
||
if( suffixLength > 0 | | level_prefix >= 14 ) { |
||
level_suffix |
3 | 4 |
u(v) |
levelCode += level_suffix |
||
} |
||
if( level_prefix > = 15 && suffixLength = = 0 ) |
||
levelCode += 15 |
||
if( level_prefix > = 16 ) |
||
levelCode += ( 1 << ( level_prefix – 3 ) ) – 4096 |
||
if( i = = TrailingOnes( coeff_token ) && |
||
levelCode += 2 |
||
if( levelCode % 2 = = 0 ) |
||
level[ i ] = ( levelCode + 2 ) >> 1 |
||
else |
||
level[ i ] = ( –levelCode – 1 ) >> 1 |
||
if( suffixLength = = 0 ) |
||
suffixLength = 1 |
||
if( Abs( level[ i ] ) > ( 3 << ( suffixLength – 1 ) ) && |
||
suffixLength++ |
||
} |
||
if( TotalCoeff( coeff_token ) < maxNumCoeff ) { |
||
total_zeros |
3 | 4 |
ce(v) |
zerosLeft = total_zeros |
||
} else |
||
zerosLeft = 0 |
||
for( i = 0; i < TotalCoeff( coeff_token ) – 1; i++ ) { |
||
if( zerosLeft > 0 ) { |
||
run_before |
3 | 4 |
ce(v) |
run[ i ] = run_before |
||
} else |
||
run[ i ] = 0 |
||
zerosLeft = zerosLeft – run[ i ] |
||
} |
||
run[ TotalCoeff( coeff_token ) – 1 ] = zerosLeft |
||
coeffNum = ?1 |
||
for( i = TotalCoeff( coeff_token ) – 1; i >= 0; i-- ) { |
||
coeffNum += run[ i ] + 1 |
||
coeffLevel[ coeffNum ] = level[ i ] |
||
} |
||
} |
||
} |
分析一段H264视频数据相关推荐
- 基于Android4.2系统的H264视频数据的获取
基于Android4.2系统的H264视频数据的获取 0引言 Andriod系统本身不支持H264视频原始压缩数据(即符合H264压缩标准,具有NAL头的裸数据)的实时获取,基本上都是利用MediaR ...
- android player通过rtp协议接收h264视频数据播放
android recorder通过rtp发送h264视频数据给vlc播放 android player通过rtp协议接收h264视频数据播放 Android recorder通过rtp发送aac数据 ...
- 【FFMPEG】基于RTP的H264视频数据打包解包类
最近考虑使用RTP替换原有的高清视频传输协议,遂上网查找有关H264视频RTP打包.解包的文档和代码.功夫不负有心人,找到不少有价值的文档和代码.参考这些资料,写了H264 RTP打包类.解包类,实现 ...
- java aac rtp封装_分享一段H264视频和AAC音频的RTP封包代码
1. H264视频的RTP封包 static int h264_parse(Track *tr, uint8_t *data, size_t len) { h264_priv *priv = tr-& ...
- 关于从海康威视或者大华摄像头获取PS数据流中的H264视频数据
PS流数据原理网上基本能够搜索到,这里我也就没必要粘贴复制,解析PS数据包主要分 00 00 00 ba 这是ps头,然后是系统头00 00 00 bb ,然后是Program Stream map包 ...
- ffmpeg获取h264视频数据
源资源来自教程,来自慕课网 李超,本人仅仅是添加注释 #include <stdio.h> #include <libavutil/log.h> #include <li ...
- WebRTC视频数据流程分析
本文来自<WebRTC Native开发实战>书籍作者许建林在LiveVideoStack线上分享中的内容,详细分析总结 WebRTC 的视频数据流程,并对大型项目如何快速上手:分析方法, ...
- 实例说明代码段(.text)、数据段(.data)、bss段、只读数据段(.rodata)、堆栈的划分依据
目录 程序实例介绍各个段内容.分析段(segment)分布 分析代码段(.text).数据段(.data).bss段.只读数据段(.rodata)划分依据 程序实例介绍各个段内容.分析段(segmen ...
- Android音频学习之MediaExtractor,提取音频视频轨道数据(从视频中分离音频视频数据)
一个音视频文件是由音频和视频组成的,我们可以通过MediaExtractor.MediaMuxer把音频或视频给单独抽取出来,抽取出来的音频和视频能单独播放: 1 MediaExtractor 说明 ...
最新文章
- 【Linux笔记(002) 】-- centos7 文档操作基本命令
- FPGA设计心得(5)Aurora 例子工程分析与仿真实例分析(streaming版)
- ARM处理器全解析:A8/A9/A15都是什么?
- from html参数传到另外php文件中_在 PHP 中格式化并高亮 SQL 语句
- 解决Mono for android的xml编辑器无法代码完成的问题
- org.hibernate.service.ServiceRegistryBuilder被弃用
- js 拾遗 js时间戳转换
- [HDU] 3491 Thieves
- SQL Server 数据库操作类
- 将桌面文件映射至E盘
- CentOS系统优化
- 【NLP】统计自然语言处理(第2版)思维导图
- maxdea如何计算指数_MaxDEA
- 基于PTPX的功耗分析
- HDU - 1166 敌兵布阵(线段树模板)(入门题)
- He's a Pirate---David Garrett
- ZooKeeper示例 实时更新server列表
- HDCP Key工作原理
- 小米usb测试软件,你还在用USB传文件?小米10系列USB详细测试——《小米10十大槽点》番外 图文版...
- Playwright + Python爬虫
热门文章
- etl构建数据仓库五步法_带你了解数据仓库的基本架构
- 【ZOJ - 3956】Course Selection System(01背包)
- 【CodeForces - 892C 】Pride (数学,思维构造,gcd)
- 【 HDU - 5363】Key Set(水题,快速幂,组合数学)
- 【HDU - 4217 】Data Structure? (线段树求第k小数)
- 几位无人驾驶领域的杰出科学家
- Python之Numpy入门实战教程(1):基础篇
- matlab考试试题,matlab-考试试题-
- 关闭 Pycharm 更新提示
- Caused by: org.springframework.boot.web.server.PortInUseException: Port 8081 is already in use 端口占用