• 嵌入式 H264参数语法文档: SPS、PPS、IDR以及NALU编码规律


    // 【h264编码出的NALU规律】
    // 第一帧 SPS【0 0 0 1 0x67】 PPS【0 0 0 1 0x68】 SEI【0 0 0 1 0x6】 IDR【0 0 0 1 0x65】
    // p帧      P【0 0 0 1 0x61】
    // I帧    SPS【0 0 0 1 0x67】 PPS【0 0 0 1 0x68】 IDR【0 0 0 1 0x65】
    // 【mp4v2封装函数MP4WriteSample】
    // 此函数接收I/P nalu,该nalu需要用4字节的数据大小头替换原有的起始头,并且数据大小为big-endian格式

    示例文件下载地址:“NALU中SPS、PPS、SEI、IDR、P帧标识

    H.264码流第一个 NALU 是 SPS(序列参数集Sequence Parameter Set)
    对应H264标准文档 7.3.2.1 序列参数集的语法进行解析

    SPS参数解析// fill sps with content of p
    [cpp] view plaincopy
     
    1. int InterpretSPS (VideoParameters *p_Vid, DataPartition *p, seq_parameter_set_rbsp_t *sps)  
    2. {  
    3.   unsigned i;  
    4.   unsigned n_ScalingList;  
    5.   int reserved_zero;  
    6.   Bitstream *s = p->bitstream;  
    7.   
    8.   assert (p != NULL);  
    9.   assert (p->bitstream != NULL);  
    10.   assert (p->bitstream->streamBuffer != 0);  
    11.   assert (sps != NULL);  
    12.   
    13.   p_Dec->UsedBits = 0;  
    14.   
    15.   sps->profile_idc                            = u_v  (8, "SPS: profile_idc"                           , s);  
    16.   
    17.   if ((sps->profile_idc!=BASELINE       ) &&  
    18.       (sps->profile_idc!=MAIN           ) &&  
    19.       (sps->profile_idc!=EXTENDED       ) &&  
    20.       (sps->profile_idc!=FREXT_HP       ) &&  
    21.       (sps->profile_idc!=FREXT_Hi10P    ) &&  
    22.       (sps->profile_idc!=FREXT_Hi422    ) &&  
    23.       (sps->profile_idc!=FREXT_Hi444    ) &&  
    24.       (sps->profile_idc!=FREXT_CAVLC444 )  
    25. #if (MVC_EXTENSION_ENABLE)  
    26.       && (sps->profile_idc!=MVC_HIGH)  
    27.       && (sps->profile_idc!=STEREO_HIGH)  
    28. #endif  
    29.       )  
    30.   {  
    31.     printf("Invalid Profile IDC (%d) encountered. /n", sps->profile_idc);  
    32.     return p_Dec->UsedBits;  
    33.   }  
    34.   
    35.   sps->constrained_set0_flag                  = u_1  (   "SPS: constrained_set0_flag"                 , s);  
    36.   sps->constrained_set1_flag                  = u_1  (   "SPS: constrained_set1_flag"                 , s);  
    37.   sps->constrained_set2_flag                  = u_1  (   "SPS: constrained_set2_flag"                 , s);  
    38.   sps->constrained_set3_flag                  = u_1  (   "SPS: constrained_set3_flag"                 , s);  
    39. #if (MVC_EXTENSION_ENABLE)  
    40.   sps->constrained_set4_flag                  = u_1  (   "SPS: constrained_set4_flag"                 , s);  
    41.   reserved_zero                               = u_v  (3, "SPS: reserved_zero_3bits"                   , s);  
    42. #else  
    43.   reserved_zero                               = u_v  (4, "SPS: reserved_zero_4bits"                   , s);  
    44. #endif  
    45.   assert (reserved_zero==0);  
    46.   
    47.   sps->level_idc                              = u_v  (8, "SPS: level_idc"                             , s);  
    48.   
    49.   sps->seq_parameter_set_id                   = ue_v ("SPS: seq_parameter_set_id"                     , s);  
    50.   
    51.   // Fidelity Range Extensions stuff  
    52.   sps->chroma_format_idc = 1;  
    53.   sps->bit_depth_luma_minus8   = 0;  
    54.   sps->bit_depth_chroma_minus8 = 0;  
    55.   p_Vid->lossless_qpprime_flag   = 0;  
    56.   sps->separate_colour_plane_flag = 0;  
    57.   
    58.   if((sps->profile_idc==FREXT_HP   ) ||  
    59.      (sps->profile_idc==FREXT_Hi10P) ||  
    60.      (sps->profile_idc==FREXT_Hi422) ||  
    61.      (sps->profile_idc==FREXT_Hi444) ||  
    62.      (sps->profile_idc==FREXT_CAVLC444)  
    63. #if (MVC_EXTENSION_ENABLE)  
    64.      || (sps->profile_idc==MVC_HIGH)  
    65.      || (sps->profile_idc==STEREO_HIGH)  
    66. #endif  
    67.      )  
    68.   {  
    69.     sps->chroma_format_idc                      = ue_v ("SPS: chroma_format_idc"                       , s);  
    70.   
    71.     if(sps->chroma_format_idc == YUV444)  
    72.     {  
    73.       sps->separate_colour_plane_flag           = u_1  ("SPS: separate_colour_plane_flag"              , s);  
    74.     }  
    75.   
    76.     sps->bit_depth_luma_minus8                  = ue_v ("SPS: bit_depth_luma_minus8"                   , s);  
    77.     sps->bit_depth_chroma_minus8                = ue_v ("SPS: bit_depth_chroma_minus8"                 , s);  
    78.     //checking;  
    79.     if((sps->bit_depth_luma_minus8+8 > sizeof(imgpel)*8) || (sps->bit_depth_chroma_minus8+8> sizeof(imgpel)*8))  
    80.       error ("Source picture has higher bit depth than imgpel data type. /nPlease recompile with larger data type for imgpel.", 500);  
    81.   
    82.     p_Vid->lossless_qpprime_flag                  = u_1  ("SPS: lossless_qpprime_y_zero_flag"            , s);  
    83.   
    84.     sps->seq_scaling_matrix_present_flag        = u_1  (   "SPS: seq_scaling_matrix_present_flag"       , s);  
    85.       
    86.     if(sps->seq_scaling_matrix_present_flag)  
    87.     {  
    88.       n_ScalingList = (sps->chroma_format_idc != YUV444) ? 8 : 12;  
    89.       for(i=0; iseq_scaling_list_present_flag[i]   = u_1  (   "SPS: seq_scaling_list_present_flag"         , s);  
    90.         if(sps->seq_scaling_list_present_flag[i])  
    91.         {  
    92.           if(i<6) scaling_list="">ScalingList4x4[i], 16, &sps->UseDefaultScalingMatrix4x4Flag[i], s);  
    93.           else  
    94.             Scaling_List(sps->ScalingList8x8[i-6], 64, &sps->UseDefaultScalingMatrix8x8Flag[i-6], s);  
    95.         }  
    96.       }  
    97.     }  
    98.   }  
    99.   
    100.   sps->log2_max_frame_num_minus4              = ue_v ("SPS: log2_max_frame_num_minus4"                , s);  
    101.   sps->pic_order_cnt_type                     = ue_v ("SPS: pic_order_cnt_type"                       , s);  
    102.   
    103.   if (sps->pic_order_cnt_type == 0)  
    104.     sps->log2_max_pic_order_cnt_lsb_minus4 = ue_v ("SPS: log2_max_pic_order_cnt_lsb_minus4"           , s);  
    105.   else if (sps->pic_order_cnt_type == 1)  
    106.   {  
    107.     sps->delta_pic_order_always_zero_flag      = u_1  ("SPS: delta_pic_order_always_zero_flag"       , s);  
    108.     sps->offset_for_non_ref_pic                = se_v ("SPS: offset_for_non_ref_pic"                 , s);  
    109.     sps->offset_for_top_to_bottom_field        = se_v ("SPS: offset_for_top_to_bottom_field"         , s);  
    110.     sps->num_ref_frames_in_pic_order_cnt_cycle = ue_v ("SPS: num_ref_frames_in_pic_order_cnt_cycle"  , s);  
    111.     for(i=0; inum_ref_frames_in_pic_order_cnt_cycle; i++)  
    112.       sps->offset_for_ref_frame[i]               = se_v ("SPS: offset_for_ref_frame[i]"              , s);  
    113.   }  
    114.   sps->num_ref_frames                        = ue_v ("SPS: num_ref_frames"                         , s);  
    115.   sps->gaps_in_frame_num_value_allowed_flag  = u_1  ("SPS: gaps_in_frame_num_value_allowed_flag"   , s);  
    116.   sps->pic_width_in_mbs_minus1               = ue_v ("SPS: pic_width_in_mbs_minus1"                , s);  
    117.   sps->pic_height_in_map_units_minus1        = ue_v ("SPS: pic_height_in_map_units_minus1"         , s);  
    118.   sps->frame_mbs_only_flag                   = u_1  ("SPS: frame_mbs_only_flag"                    , s);  
    119.   if (!sps->frame_mbs_only_flag)  
    120.   {  
    121.     sps->mb_adaptive_frame_field_flag        = u_1  ("SPS: mb_adaptive_frame_field_flag"           , s);  
    122.   }  
    123.   sps->direct_8x8_inference_flag             = u_1  ("SPS: direct_8x8_inference_flag"              , s);  
    124.   sps->frame_cropping_flag                   = u_1  ("SPS: frame_cropping_flag"                    , s);  
    125.   
    126.   if (sps->frame_cropping_flag)  
    127.   {  
    128.     sps->frame_cropping_rect_left_offset      = ue_v ("SPS: frame_cropping_rect_left_offset"           , s);  
    129.     sps->frame_cropping_rect_right_offset     = ue_v ("SPS: frame_cropping_rect_right_offset"          , s);  
    130.     sps->frame_cropping_rect_top_offset       = ue_v ("SPS: frame_cropping_rect_top_offset"            , s);  
    131.     sps->frame_cropping_rect_bottom_offset    = ue_v ("SPS: frame_cropping_rect_bottom_offset"         , s);  
    132.   }  
    133.   sps->vui_parameters_present_flag           = (Boolean) u_1  ("SPS: vui_parameters_present_flag"      , s);  
    134.   
    135.   InitVUI(sps);  
    136.   ReadVUI(p, sps);  
    137.   
    138.   sps->Valid = TRUE;  
    139.   return p_Dec->UsedBits;  
    140. }  

    H.264码流第二个 NALU 是 PPS(图像参数集Picture Parameter Set)
    对应H264标准文档 7.3.2.2 序列参数集的语法进行解析

    PPS参数解析
    [cpp] view plaincopy
     
    1. int InterpretPPS (VideoParameters *p_Vid, DataPartition *p, pic_parameter_set_rbsp_t *pps)  
    2. {  
    3.   unsigned i;  
    4.   unsigned n_ScalingList;  
    5.   int chroma_format_idc;  
    6.   int NumberBitsPerSliceGroupId;  
    7.   Bitstream *s = p->bitstream;  
    8.   
    9.   assert (p != NULL);  
    10.   assert (p->bitstream != NULL);  
    11.   assert (p->bitstream->streamBuffer != 0);  
    12.   assert (pps != NULL);  
    13.   
    14.   p_Dec->UsedBits = 0;  
    15.   
    16.   pps->pic_parameter_set_id                  = ue_v ("PPS: pic_parameter_set_id"                   , s);  
    17.   pps->seq_parameter_set_id                  = ue_v ("PPS: seq_parameter_set_id"                   , s);  
    18.   pps->entropy_coding_mode_flag              = u_1  ("PPS: entropy_coding_mode_flag"               , s);  
    19.   
    20.   //! Note: as per JVT-F078 the following bit is unconditional.  If F078 is not accepted, then  
    21.   //! one has to fetch the correct SPS to check whether the bit is present (hopefully there is  
    22.   //! no consistency problem :-(  
    23.   //! The current encoder code handles this in the same way.  When you change this, don't forget  
    24.   //! the encoder!  StW, 12/8/02  
    25.   pps->bottom_field_pic_order_in_frame_present_flag                = u_1  ("PPS: bottom_field_pic_order_in_frame_present_flag"                 , s);  
    26.   
    27.   pps->num_slice_groups_minus1               = ue_v ("PPS: num_slice_groups_minus1"                , s);  
    28.   
    29.   // FMO stuff begins here  
    30.   if (pps->num_slice_groups_minus1 > 0)  
    31.   {  
    32.     pps->slice_group_map_type               = ue_v ("PPS: slice_group_map_type"                , s);  
    33.     if (pps->slice_group_map_type == 0)  
    34.     {  
    35.       for (i=0; i<=pps->num_slice_groups_minus1; i++)  
    36.         pps->run_length_minus1 [i]                  = ue_v ("PPS: run_length_minus1 [i]"              , s);  
    37.     }  
    38.     else if (pps->slice_group_map_type == 2)  
    39.     {  
    40.       for (i=0; inum_slice_groups_minus1; i++)  
    41.       {  
    42.         //! JVT-F078: avoid reference of SPS by using ue(v) instead of u(v)  
    43.         pps->top_left [i]                          = ue_v ("PPS: top_left [i]"                        , s);  
    44.         pps->bottom_right [i]                      = ue_v ("PPS: bottom_right [i]"                    , s);  
    45.       }  
    46.     }  
    47.     else if (pps->slice_group_map_type == 3 ||  
    48.              pps->slice_group_map_type == 4 ||  
    49.              pps->slice_group_map_type == 5)  
    50.     {  
    51.       pps->slice_group_change_direction_flag     = u_1  ("PPS: slice_group_change_direction_flag"      , s);  
    52.       pps->slice_group_change_rate_minus1        = ue_v ("PPS: slice_group_change_rate_minus1"         , s);  
    53.     }  
    54.     else if (pps->slice_group_map_type == 6)  
    55.     {  
    56.       if (pps->num_slice_groups_minus1+1 >4)  
    57.         NumberBitsPerSliceGroupId = 3;  
    58.       else if (pps->num_slice_groups_minus1+1 > 2)  
    59.         NumberBitsPerSliceGroupId = 2;  
    60.       else  
    61.         NumberBitsPerSliceGroupId = 1;  
    62.       pps->pic_size_in_map_units_minus1      = ue_v ("PPS: pic_size_in_map_units_minus1"               , s);  
    63.       if ((pps->slice_group_id = calloc (pps->pic_size_in_map_units_minus1+1, 1)) == NULL)  
    64.         no_mem_exit ("InterpretPPS: slice_group_id");  
    65.       for (i=0; i<=pps->pic_size_in_map_units_minus1; i++)  
    66.         pps->slice_group_id[i] = (byte) u_v (NumberBitsPerSliceGroupId, "slice_group_id[i]", s);  
    67.     }  
    68.   }  
    69.   
    70.   // End of FMO stuff  
    71.   
    72.   pps->num_ref_idx_l0_active_minus1          = ue_v ("PPS: num_ref_idx_l0_active_minus1"           , s);  
    73.   pps->num_ref_idx_l1_active_minus1          = ue_v ("PPS: num_ref_idx_l1_active_minus1"           , s);  
    74.   pps->weighted_pred_flag                    = u_1  ("PPS: weighted_pred_flag"                     , s);  
    75.   pps->weighted_bipred_idc                   = u_v  ( 2, "PPS: weighted_bipred_idc"                , s);  
    76.   pps->pic_init_qp_minus26                   = se_v ("PPS: pic_init_qp_minus26"                    , s);  
    77.   pps->pic_init_qs_minus26                   = se_v ("PPS: pic_init_qs_minus26"                    , s);  
    78.   
    79.   pps->chroma_qp_index_offset                = se_v ("PPS: chroma_qp_index_offset"                 , s);  
    80.   
    81.   pps->deblocking_filter_control_present_flag = u_1 ("PPS: deblocking_filter_control_present_flag" , s);  
    82.   pps->constrained_intra_pred_flag           = u_1  ("PPS: constrained_intra_pred_flag"            , s);  
    83.   pps->redundant_pic_cnt_present_flag        = u_1  ("PPS: redundant_pic_cnt_present_flag"         , s);  
    84.   
    85.   if(more_rbsp_data(s->streamBuffer, s->frame_bitoffset,s->bitstream_length)) // more_data_in_rbsp()  
    86.   {  
    87.     //Fidelity Range Extensions Stuff  
    88.     pps->transform_8x8_mode_flag           = u_1  ("PPS: transform_8x8_mode_flag"                , s);  
    89.     pps->pic_scaling_matrix_present_flag   =  u_1  ("PPS: pic_scaling_matrix_present_flag"        , s);  
    90.   
    91.     if(pps->pic_scaling_matrix_present_flag)  
    92.     {  
    93.       chroma_format_idc = p_Vid->SeqParSet[pps->seq_parameter_set_id].chroma_format_idc;  
    94.       n_ScalingList = 6 + ((chroma_format_idc != YUV444) ? 2 : 6) * pps->transform_8x8_mode_flag;  
    95.       for(i=0; ipic_scaling_list_present_flag[i]= u_1  ("PPS: pic_scaling_list_present_flag"          , s);  
    96.   
    97.         if(pps->pic_scaling_list_present_flag[i])  
    98.         {  
    99.           if(i<6) scaling_list="">ScalingList4x4[i], 16, &pps->UseDefaultScalingMatrix4x4Flag[i], s);  
    100.           else  
    101.             Scaling_List(pps->ScalingList8x8[i-6], 64, &pps->UseDefaultScalingMatrix8x8Flag[i-6], s);  
    102.         }  
    103.       }  
    104.     }  
    105.     pps->second_chroma_qp_index_offset      = se_v ("PPS: second_chroma_qp_index_offset"          , s);  
    106.   }  
    107.   else  
    108.   {  
    109.     pps->second_chroma_qp_index_offset      = pps->chroma_qp_index_offset;  
    110.   }  
    111.   
    112.   pps->Valid = TRUE;  
    113.   return p_Dec->UsedBits;  
    114. }  

    H.264码流第三个 NALU 是 IDR(即时解码器刷新)
    对应H264标准文档 7.3.3 序列参数集的语法进行解析

    IDR参数解析
    [cpp] view plaincopy
     
    1. case NALU_TYPE_IDR:  
    2.         img->idr_flag = (nalu->nal_unit_type == NALU_TYPE_IDR);  
    3.         img->nal_reference_idc = nalu->nal_reference_idc;  
    4.         img->disposable_flag = (nalu->nal_reference_idc == NALU_PRIORITY_DISPOSABLE);  
    5.         currSlice->dp_mode = PAR_DP_1;   //++ dp_mode:数据分割模式;PAR_DP_1=0:没有数据分割  
    6.         currSlice->max_part_nr = 1;  
    7.         currSlice->ei_flag = 0;  //++ 该处赋值直接影响decode_slice()函数中对decode_one_slice()函数的调用  
    8.                                     //++ 该值不为0,表明当前片出错,解码程序将忽略当前片的解码过程,而使用错误隐藏  
    9.         currStream = currSlice->partArr[0].bitstream;  
    10.         currStream->ei_flag = 0; //++ 此处的赋值为最终赋值,以后不再改变。该值将对每个宏块的ei_flag产生影响  
    11.                                     //++ 参见macroblock.c文件read_one_macroblock()函数的如下语句:  
    12.                                     //++        :if(!dP->bitstream->ei_flag)      :currMB->ei_flag = 0;  
    13.                                     //++ 该值还在macroblock.c文件if(IS_INTRA (currMB) && dP->bitstream->ei_flag && img->number)中用到  
    14.         currStream->frame_bitoffset = currStream->read_len = 0;  
    15.         memcpy (currStream->streamBuffer, &nalu->buf[1], nalu->len-1);  
    16.         currStream->code_len = currStream->bitstream_length = RBSPtoSODB(currStream->streamBuffer, nalu->len-1);  
    17.   
    18.         // Some syntax of the Slice Header depends on the parameter set, which depends on  
    19.         // the parameter set ID of the SLice header.  Hence, read the pic_parameter_set_id  
    20.         // of the slice header first, then setup the active parameter sets, and then read  
    21.         // the rest of the slice header  
    22.         BitsUsedByHeader = FirstPartOfSliceHeader();    //++ 参见标准7.3.3  
    23.         UseParameterSet (currSlice->pic_parameter_set_id);  
    24.         BitsUsedByHeader+= RestOfSliceHeader ();    //++ 参见标准7.3.3  
    25.         //++ BitsUsedByHeader在程序中没有实际用处,而且BitsUsedByHeader+= RestOfSliceHeader ()  
    26.         //++ 重复计算了FirstPartOfSliceHeader()所用到的比特数。因为在FirstPartOfSliceHeader()  
    27.         //++ 之后,变量UsedBits值并未被置零就代入RestOfSliceHeader()运算,从而RestOfSliceHeader ()  
    28.         //++ 在返回时,BitsUsedByHeader+= RestOfSliceHeader()多加了一个BitsUsedByHeader值  
    29.   
    30.         FmoInit (active_pps, active_sps);  
    31.   
    32.         if(is_new_picture())  
    33.         {  
    34.           init_picture(img, input);  
    35.             
    36.           current_header = SOP;  
    37.           //check zero_byte if it is also the first NAL unit in the access unit  
    38.           CheckZeroByteVCL(nalu, &ret);  
    39.         }  
    40.         else  
    41.           current_header = SOS;  
    42.     
    43.         init_lists(img->type, img->currentSlice->structure);  
    44.         reorder_lists (img->type, img->currentSlice);  
    45.   
    46.         if (img->structure==FRAME)  
    47.         {  
    48.           init_mbaff_lists();  
    49.         }  
    50.   
    51. /*        if (img->frame_num==1) // write a reference list 
    52.         { 
    53.           count ++; 
    54.           if (count==1) 
    55.             for (i=0; i 
    56.  
    57.         // From here on, active_sps, active_pps and the slice header are valid 
    58.         if (img->MbaffFrameFlag) 
    59.           img->current_mb_nr = currSlice->start_mb_nr << 1="" style="color: #0000ff">else 
    60.           img->current_mb_nr = currSlice->start_mb_nr; 
    61.  
    62.         if (active_pps->entropy_coding_mode_flag) 
    63.         { 
    64.           int ByteStartPosition = currStream->frame_bitoffset/8; 
    65.           if (currStream->frame_bitoffset%8 != 0)  
    66.           { 
    67.             ByteStartPosition++; 
    68.           } 
    69.           arideco_start_decoding (&currSlice->partArr[0].de_cabac, currStream->streamBuffer, ByteStartPosition, &currStream->read_len, img->type); 
    70.         } 
    71. // printf ("read_new_slice: returning %s/n", current_header == SOP?"SOP":"SOS"); 
    72.         FreeNALU(nalu); 
    73.         return current_header; 
    74.         break; 
    75.       case NALU_TYPE_DPA: 
    76.         //! The state machine here should follow the same ideas as the old readSliceRTP() 
    77.         //! basically: 
    78.         //! work on DPA (as above) 
    79.         //! read and process all following SEI/SPS/PPS/PD/Filler NALUs 
    80.         //! if next video NALU is dpB,  
    81.         //!   then read and check whether it belongs to DPA, if yes, use it 
    82.         //! else 
    83.         //!   ;   // nothing 
    84.         //! read and process all following SEI/SPS/PPS/PD/Filler NALUs 
    85.         //! if next video NALU is dpC 
    86.         //!   then read and check whether it belongs to DPA (and DPB, if present), if yes, use it, done 
    87.         //! else 
    88.         //!   use the DPA (and the DPB if present) 
    89.  
    90.         /*  
    91.             LC: inserting the code related to DP processing, mainly copying some of the parts 
    92.             related to NALU_TYPE_SLICE, NALU_TYPE_IDR. 
    93.         */  
    94.   
    95.         if(expected_slice_type != NALU_TYPE_DPA)  
    96.         {  
    97.           /* oops... we found the next slice, go back! */  
    98.           fseek(bits, ftell_position, SEEK_SET);  
    99.           FreeNALU(nalu);  
    100.           return current_header;  
    101.         }  
    102.   
    103.         img->idr_flag          = (nalu->nal_unit_type == NALU_TYPE_IDR);  
    104.         img->nal_reference_idc = nalu->nal_reference_idc;  
    105.         img->disposable_flag   = (nalu->nal_reference_idc == NALU_PRIORITY_DISPOSABLE);  
    106.         currSlice->dp_mode     = PAR_DP_3;  
    107.         currSlice->max_part_nr = 3;  
    108.         currSlice->ei_flag     = 0;  
    109.         currStream             = currSlice->partArr[0].bitstream;  
    110.         currStream->ei_flag    = 0;  
    111.         currStream->frame_bitoffset = currStream->read_len = 0;  
    112.         memcpy (currStream->streamBuffer, &nalu->buf[1], nalu->len-1);  
    113.         currStream->code_len = currStream->bitstream_length = RBSPtoSODB(currStream->streamBuffer, nalu->len-1);    //++ 剔除停止比特和填充比特  
    114.           
    115.         BitsUsedByHeader     = FirstPartOfSliceHeader();  
    116.         UseParameterSet (currSlice->pic_parameter_set_id);  
    117.         BitsUsedByHeader    += RestOfSliceHeader ();  
    118.           
    119.         FmoInit (active_pps, active_sps);  
    120.   
    121.         if(is_new_picture())  
    122.         {  
    123.           init_picture(img, input);  
    124.           current_header = SOP;  
    125.           CheckZeroByteVCL(nalu, &ret);  
    126.         }  
    127.         else  
    128.           current_header = SOS;  
    129.   
    130.           
    131.         init_lists(img->type, img->currentSlice->structure);  
    132.         reorder_lists (img->type, img->currentSlice);  
    133.           
    134.         if (img->structure==FRAME)  
    135.         {  
    136.           init_mbaff_lists();  
    137.         }  
    138.   
    139.         // From here on, active_sps, active_pps and the slice header are valid  
    140.         if (img->MbaffFrameFlag)  
    141.           img->current_mb_nr = currSlice->start_mb_nr << 1="" style="color: #0000ff">else  
    142.    
    143.          img->current_mb_nr = currSlice->start_mb_nr;  
    144.   
    145.   
    146.         /*  
    147.            LC: 
    148.               Now I need to read the slice ID, which depends on the value of  
    149.               redundant_pic_cnt_present_flag (pag.49).  
    150.         */  
    151.   
    152.         slice_id_a  = ue_v("NALU:SLICE_A slice_idr", currStream);  
    153.         if (active_pps->entropy_coding_mode_flag)  
    154.         {  
    155.           int ByteStartPosition = currStream->frame_bitoffset/8;  
    156.           if (currStream->frame_bitoffset%8 != 0)   
    157.           {  
    158.             ByteStartPosition++;  
    159.           }  
    160.           arideco_start_decoding (&currSlice->partArr[0].de_cabac, currStream->streamBuffer, ByteStartPosition, &currStream->read_len, img->type);  
    161.         }  
    162. // printf ("read_new_slice: returning %s/n", current_header == SOP?"SOP":"SOS");  
    163.         break;  
    164.       case NALU_TYPE_DPB:  
    165.         /* LC: inserting the code related to DP processing */  
    166.   
    167.         currStream             = currSlice->partArr[1].bitstream;  
    168.         currStream->ei_flag    = 0;  
    169.         currStream->frame_bitoffset = currStream->read_len = 0;  
    170.         memcpy (currStream->streamBuffer, &nalu->buf[1], nalu->len-1);  
    171.         currStream->code_len = currStream->bitstream_length = RBSPtoSODB(currStream->streamBuffer, nalu->len-1);  
    172.   
    173.         slice_id_b  = ue_v("NALU:SLICE_B slice_idr", currStream);  
    174.         if (active_pps->redundant_pic_cnt_present_flag)  
    175.           redundant_pic_cnt_b = ue_v("NALU:SLICE_B redudand_pic_cnt", currStream);  
    176.         else  
    177.           redundant_pic_cnt_b = 0;  
    178.           
    179.         /*  LC: Initializing CABAC for the current data stream. */  
    180.   
    181.         if (active_pps->entropy_coding_mode_flag)  
    182.         {  
    183.           int ByteStartPosition = currStream->frame_bitoffset/8;  
    184.           if (currStream->frame_bitoffset % 8 != 0)   
    185.             ByteStartPosition++;  
    186.             
    187.           arideco_start_decoding (&currSlice->partArr[1].de_cabac, currStream->streamBuffer,   
    188.             ByteStartPosition, &currStream->read_len, img->type);  
    189.             
    190.         }  
    191.   
    192.         /* LC: resilience code to be inserted */  
    193.         /*         FreeNALU(nalu); */  
    194.         /*         return current_header; */  
    195.   
    196.         break;  
    IDR参数解析/*!
    [cpp] view plaincopy
     
    1. <pre name="code" class="cpp"> ************************************************************************  
    2.  * /brief  
    3.  *    read the first part of the header (only the pic_parameter_set_id)  
    4.  * /return  
    5.  *    Length of the first part of the slice header (in bits)  
    6.  ************************************************************************  
    7.  */  
    8. //++ 参见标准7.3.3  
    9. int FirstPartOfSliceHeader()  
    10. {  
    11.   Slice *currSlice = img->currentSlice;  
    12.   int dP_nr = assignSE2partition[currSlice->dp_mode][SE_HEADER];  
    13.   DataPartition *partition = &(currSlice->partArr[dP_nr]);  
    14.   Bitstream *currStream = partition->bitstream;  
    15.   int tmp;  
    16.   
    17.   UsedBits= partition->bitstream->frame_bitoffset; // was hardcoded to 31 for previous start-code. This is better.  
    18.   
    19.   // Get first_mb_in_slice  
    20.   currSlice->start_mb_nr = ue_v ("SH: first_mb_in_slice", currStream);  
    21.   
    22.   tmp = ue_v ("SH: slice_type", currStream);  
    23.     
    24.   if (tmp>4) tmp -=5;  
    25.   
    26.   img->type = currSlice->picture_type = (SliceType) tmp;  
    27.   
    28.   currSlice->pic_parameter_set_id = ue_v ("SH: pic_parameter_set_id", currStream);  
    29.     
    30.   return UsedBits;  
    31. }  
    32. </pre><br><br>  
  • 相关阅读:
    ubuntu16.04下安装Wineqq+Firefox flash安装+搜狗输入法+截图软件ksnatshot
    集合数据类型
    hadoop2.7ubuntu伪分布式搭建
    广播变量&累加变量
    第一行代码----服务的最佳实践(体会,问题,解决)
    c语言中产生随机数
    如何把StringBuilder类型字符串中的字符换位置
    判断字母的大小写方法(3种)
    方法的参数个数讨论。
    中缀表达式->后缀表达式
  • 原文地址:https://www.cnblogs.com/lidabo/p/5384073.html
Copyright © 2020-2023  润新知