H.264(H264)解码SPS获取分辨率和帧率

  1. #include <stdio.h>  
  2. #include <stdint.h>  
  3. #include <string.h>  
  4. #include <math.h>  
  5.   
  6. typedef  unsigned int UINT;  
  7. typedef  unsigned char BYTE;  
  8. typedef  unsigned long DWORD;  
  9.   
  10. UINT Ue(BYTE *pBuff, UINT nLen, UINT &nStartBit)  
  11. {  
  12.     //计算0bit的个数  
  13.     UINT nZeroNum = 0;  
  14.     while (nStartBit < nLen * 8)  
  15.     {  
  16.         if (pBuff[nStartBit / 8] & (0x80 >> (nStartBit % 8))) //&:按位与,%取余  
  17.         {  
  18.             break;  
  19.         }  
  20.         nZeroNum++;  
  21.         nStartBit++;  
  22.     }  
  23.     nStartBit ++;  
  24.   
  25.   
  26.     //计算结果  
  27.     DWORD dwRet = 0;  
  28.     for (UINT i=0; i<nZeroNum; i++)  
  29.     {  
  30.         dwRet <<= 1;  
  31.         if (pBuff[nStartBit / 8] & (0x80 >> (nStartBit % 8)))  
  32.         {  
  33.             dwRet += 1;  
  34.         }  
  35.         nStartBit++;  
  36.     }  
  37.     return (1 << nZeroNum) - 1 + dwRet;  
  38. }  
  39.   
  40.   
  41. int Se(BYTE *pBuff, UINT nLen, UINT &nStartBit)  
  42. {  
  43.     int UeVal=Ue(pBuff,nLen,nStartBit);  
  44.     double k=UeVal;  
  45.     int nValue=ceil(k/2);//ceil函数:ceil函数的作用是求不小于给定实数的最小整数。ceil(2)=ceil(1.2)=cei(1.5)=2.00  
  46.     if (UeVal % 2==0)  
  47.         nValue=-nValue;  
  48.     return nValue;  
  49. }  
  50.   
  51.   
  52. DWORD u(UINT BitCount,BYTE * buf,UINT &nStartBit)  
  53. {  
  54.     DWORD dwRet = 0;  
  55.     for (UINT i=0; i<BitCount; i++)  
  56.     {  
  57.         dwRet <<= 1;  
  58.         if (buf[nStartBit / 8] & (0x80 >> (nStartBit % 8)))  
  59.         {  
  60.             dwRet += 1;  
  61.         }  
  62.         nStartBit++;  
  63.     }  
  64.     return dwRet;  
  65. }  
  66.   
  67. /** 
  68.  * H264的NAL起始码防竞争机制 
  69.  * 
  70.  * @param buf SPS数据内容 
  71.  * 
  72.  * @无返回值 
  73.  */  
  74. void de_emulation_prevention(BYTE* buf,unsigned int* buf_size)  
  75. {  
  76.     int i=0,j=0;  
  77.     BYTE* tmp_ptr=NULL;  
  78.     unsigned int tmp_buf_size=0;  
  79.     int val=0;  
  80.   
  81.     tmp_ptr=buf;  
  82.     tmp_buf_size=*buf_size;  
  83.     for(i=0;i<(tmp_buf_size-2);i++)  
  84.     {  
  85.         //check for 0x000003  
  86.         val=(tmp_ptr[i]^0x00) +(tmp_ptr[i+1]^0x00)+(tmp_ptr[i+2]^0x03);  
  87.         if(val==0)  
  88.         {  
  89.             //kick out 0x03  
  90.             for(j=i+2;j<tmp_buf_size-1;j++)  
  91.                 tmp_ptr[j]=tmp_ptr[j+1];  
  92.   
  93.             //and so we should devrease bufsize  
  94.             (*buf_size)--;  
  95.         }  
  96.     }  
  97. }  
  98.   
  99. /** 
  100.  * 解码SPS,获取视频图像宽、高和帧率信息 
  101.  * 
  102.  * @param buf SPS数据内容 
  103.  * @param nLen SPS数据的长度 
  104.  * @param width 图像宽度 
  105.  * @param height 图像高度 
  106.  
  107.  * @成功则返回true , 失败则返回false 
  108.  */  
  109. bool h264_decode_sps(BYTE * buf,unsigned int nLen,int &width,int &height,int &fps)  
  110. {  
  111.     UINT StartBit=0;  
  112.     fps=0;  
  113.     de_emulation_prevention(buf,&nLen);  
  114.   
  115.     int forbidden_zero_bit=u(1,buf,StartBit);  
  116.     int nal_ref_idc=u(2,buf,StartBit);  
  117.     int nal_unit_type=u(5,buf,StartBit);  
  118.     if(nal_unit_type==7)  
  119.     {  
  120.         int profile_idc=u(8,buf,StartBit);  
  121.         int constraint_set0_flag=u(1,buf,StartBit);//(buf[1] & 0x80)>>7;  
  122.         int constraint_set1_flag=u(1,buf,StartBit);//(buf[1] & 0x40)>>6;  
  123.         int constraint_set2_flag=u(1,buf,StartBit);//(buf[1] & 0x20)>>5;  
  124.         int constraint_set3_flag=u(1,buf,StartBit);//(buf[1] & 0x10)>>4;  
  125.         int reserved_zero_4bits=u(4,buf,StartBit);  
  126.         int level_idc=u(8,buf,StartBit);  
  127.   
  128.         int seq_parameter_set_id=Ue(buf,nLen,StartBit);  
  129.   
  130.         if( profile_idc == 100 || profile_idc == 110 ||  
  131.             profile_idc == 122 || profile_idc == 144 )  
  132.         {  
  133.             int chroma_format_idc=Ue(buf,nLen,StartBit);  
  134.             if( chroma_format_idc == 3 )  
  135.                 int residual_colour_transform_flag=u(1,buf,StartBit);  
  136.             int bit_depth_luma_minus8=Ue(buf,nLen,StartBit);  
  137.             int bit_depth_chroma_minus8=Ue(buf,nLen,StartBit);  
  138.             int qpprime_y_zero_transform_bypass_flag=u(1,buf,StartBit);  
  139.             int seq_scaling_matrix_present_flag=u(1,buf,StartBit);  
  140.   
  141.             int seq_scaling_list_present_flag[8];  
  142.             if( seq_scaling_matrix_present_flag )  
  143.             {  
  144.                 forint i = 0; i < 8; i++ ) {  
  145.                     seq_scaling_list_present_flag[i]=u(1,buf,StartBit);  
  146.                 }  
  147.             }  
  148.         }  
  149.         int log2_max_frame_num_minus4=Ue(buf,nLen,StartBit);  
  150.         int pic_order_cnt_type=Ue(buf,nLen,StartBit);  
  151.         if( pic_order_cnt_type == 0 )  
  152.             int log2_max_pic_order_cnt_lsb_minus4=Ue(buf,nLen,StartBit);  
  153.         else if( pic_order_cnt_type == 1 )  
  154.         {  
  155.             int delta_pic_order_always_zero_flag=u(1,buf,StartBit);  
  156.             int offset_for_non_ref_pic=Se(buf,nLen,StartBit);  
  157.             int offset_for_top_to_bottom_field=Se(buf,nLen,StartBit);  
  158.             int num_ref_frames_in_pic_order_cnt_cycle=Ue(buf,nLen,StartBit);  
  159.   
  160.             int *offset_for_ref_frame=new int[num_ref_frames_in_pic_order_cnt_cycle];  
  161.             forint i = 0; i < num_ref_frames_in_pic_order_cnt_cycle; i++ )  
  162.                 offset_for_ref_frame[i]=Se(buf,nLen,StartBit);  
  163.             delete [] offset_for_ref_frame;  
  164.         }  
  165.         int num_ref_frames=Ue(buf,nLen,StartBit);  
  166.         int gaps_in_frame_num_value_allowed_flag=u(1,buf,StartBit);  
  167.         int pic_width_in_mbs_minus1=Ue(buf,nLen,StartBit);  
  168.         int pic_height_in_map_units_minus1=Ue(buf,nLen,StartBit);  
  169.   
  170.         width=(pic_width_in_mbs_minus1+1)*16;  
  171.         height=(pic_height_in_map_units_minus1+1)*16;  
  172.   
  173.         int frame_mbs_only_flag=u(1,buf,StartBit);  
  174.         if(!frame_mbs_only_flag)  
  175.             int mb_adaptive_frame_field_flag=u(1,buf,StartBit);  
  176.   
  177.         int direct_8x8_inference_flag=u(1,buf,StartBit);  
  178.         int frame_cropping_flag=u(1,buf,StartBit);  
  179.         if(frame_cropping_flag)  
  180.         {  
  181.             int frame_crop_left_offset=Ue(buf,nLen,StartBit);  
  182.             int frame_crop_right_offset=Ue(buf,nLen,StartBit);  
  183.             int frame_crop_top_offset=Ue(buf,nLen,StartBit);  
  184.             int frame_crop_bottom_offset=Ue(buf,nLen,StartBit);  
  185.         }  
  186.         int vui_parameter_present_flag=u(1,buf,StartBit);  
  187.         if(vui_parameter_present_flag)  
  188.         {  
  189.             int aspect_ratio_info_present_flag=u(1,buf,StartBit);  
  190.             if(aspect_ratio_info_present_flag)  
  191.             {  
  192.                 int aspect_ratio_idc=u(8,buf,StartBit);  
  193.                 if(aspect_ratio_idc==255)  
  194.                 {  
  195.                     int sar_width=u(16,buf,StartBit);  
  196.                     int sar_height=u(16,buf,StartBit);  
  197.                 }  
  198.             }  
  199.             int overscan_info_present_flag=u(1,buf,StartBit);  
  200.             if(overscan_info_present_flag)  
  201.                 int overscan_appropriate_flagu=u(1,buf,StartBit);  
  202.             int video_signal_type_present_flag=u(1,buf,StartBit);  
  203.             if(video_signal_type_present_flag)  
  204.             {  
  205.                 int video_format=u(3,buf,StartBit);  
  206.                 int video_full_range_flag=u(1,buf,StartBit);  
  207.                 int colour_description_present_flag=u(1,buf,StartBit);  
  208.                 if(colour_description_present_flag)  
  209.                 {  
  210.                     int colour_primaries=u(8,buf,StartBit);  
  211.                     int transfer_characteristics=u(8,buf,StartBit);  
  212.                     int matrix_coefficients=u(8,buf,StartBit);  
  213.                 }  
  214.             }  
  215.             int chroma_loc_info_present_flag=u(1,buf,StartBit);  
  216.             if(chroma_loc_info_present_flag)  
  217.             {  
  218.                 int chroma_sample_loc_type_top_field=Ue(buf,nLen,StartBit);  
  219.                 int chroma_sample_loc_type_bottom_field=Ue(buf,nLen,StartBit);  
  220.             }  
  221.             int timing_info_present_flag=u(1,buf,StartBit);  
  222.   
  223.             if(timing_info_present_flag)  
  224.             {  
  225.                 int num_units_in_tick=u(32,buf,StartBit);  
  226.                 int time_scale=u(32,buf,StartBit);  
  227.                 fps=time_scale/num_units_in_tick;  
  228.                 int fixed_frame_rate_flag=u(1,buf,StartBit);  
  229.                 if(fixed_frame_rate_flag)  
  230.                 {  
  231.                     fps=fps/2;  
  232.                 }  
  233.             }  
  234.         }  
  235.         return true;  
  236.     }  
  237.     else  
  238.         return false;  
  239. }  
timing_info_present_flag等于1表示num_units_in_tick,time_scale和fixed_frame_rate_flag在比特流中存在。

timing_info_present_flag等于0表示num_units_in_tick,time_scale和fixed_frame_rate_flag在比特流中不存在。

因此,当timing_info_present_flag等于0时,无法得到码率,bool h264_decode_sps(BYTE * buf,unsigned int nLen,int &width,int &height,int &fps)参数fps返回值为0,可据此设置一个默认帧率。

转自:https://blog.csdn.net/caoshangpa/article/details/53083410


猜你喜欢

转载自blog.csdn.net/lbc2100/article/details/79928689