H264解码SPS获取宽高和帧率

来源:互联网 发布:制造图片的软件 编辑:程序博客网 时间:2024/05/22 16:41
  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,可据此设置一个默认帧率。


参考链接:http://blog.csdn.net/qq_27727131/article/details/51799663

转自:http://blog.csdn.net/caoshangpa/article/details/53083410
阅读全文
'); })();
0 0
原创粉丝点击
热门IT博客
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 一生一世,黑白影画 墨宝非宝 系统之绝色尤物 淡画书墨 快穿女配的幸福h淡画书墨 墨痕 凌天 墨痕 墨白作品 墨白 墨白渊浅吧 墨白popo 墨白popo御宅 墨白 凌天剑尊 墨白作品精选 凌天剑尊 墨白 墨白渊浅 这个残王我罩了墨白 打印机墨盒 墨盒 墨盒加墨 硒鼓墨盒 墨盒回收 墨盒价格 hp墨盒价格 回收墨盒 回收旧墨盒 佳能墨盒 墨盒打印机 hp墨盒 惠普墨盒 佳能815墨盒 墨盒图片 如何换墨盒 r330墨盒 墨盒灌墨粉 回收新墨盒 维护墨盒 书法墨盒 收墨盒 墨盒怎么样 连供墨盒 打印机墨盒怎么加墨 打印机换墨盒