代码已经过测试,能正确获取宽高。

  SPS数据是完整的,没有去掉头。如果要去掉,注意NAL_HEADER即可。测试时应该是:0, 0, 0, 1, 0x67, 0x42。。。

JAVA版

package net.quantum6.mediacodec;import net.quantum6.kit.Log;public class H264SpsParser
{private final static String TAG = H264SpsParser.class.getCanonicalName();private final static int NAL_HEADER = 4;private static int nStartBit = 0;private static int Ue(byte[] pBuff, int nLen){int nZeroNum = 0;while (nStartBit < nLen * 8){if ((pBuff[nStartBit / 8] & (0x80 >> (nStartBit % 8))) != 0){break;}nZeroNum++;nStartBit++;}nStartBit ++;int dwRet = 0;for (int i=0; i<nZeroNum; i++){dwRet <<= 1;if ((pBuff[nStartBit / 8] & (0x80 >> (nStartBit % 8))) != 0){dwRet += 1;}nStartBit++;}return (1 << nZeroNum) - 1 + dwRet;}private static int Se(byte[] pBuff, int nLen){int UeVal =Ue(pBuff,nLen);double k  =UeVal;int nValue=(int)Math.ceil(k/2);if (UeVal % 2==0){    nValue=-nValue;}return nValue;}private static int u(int BitCount, byte[] buf){int dwRet = 0;for (int i=0; i<BitCount; i++){dwRet <<= 1;if ((buf[nStartBit / 8] & (0x80 >> (nStartBit % 8))) != 0){dwRet += 1;}nStartBit++;}return dwRet;}private static boolean h264_decode_seq_parameter_set(byte[] buf, int nLen, int[] size){nStartBit = NAL_HEADER*8;int forbidden_zero_bit=u(1, buf);int nal_ref_idc       =u(2, buf);int nal_unit_type     =u(5, buf);if(nal_unit_type==7){int profile_idc         =u(8, buf);int constraint_set0_flag=u(1, buf);//(buf[1] & 0x80)>>7;int constraint_set1_flag=u(1, buf);//(buf[1] & 0x40)>>6;int constraint_set2_flag=u(1, buf);//(buf[1] & 0x20)>>5;int constraint_set3_flag=u(1, buf);//(buf[1] & 0x10)>>4;int reserved_zero_4bits =u(4, buf);int level_idc           =u(8, buf);int seq_parameter_set_id=Ue(buf, nLen);if ( profile_idc == 100 || profile_idc == 110 ||profile_idc == 122 || profile_idc == 144 ){int chroma_format_idc=Ue(buf, nLen);if ( chroma_format_idc == 3 ){int residual_colour_transform_flag=u(1,buf);}int bit_depth_luma_minus8               =Ue(buf, nLen);int bit_depth_chroma_minus8             =Ue(buf, nLen);int qpprime_y_zero_transform_bypass_flag=u(1, buf);int seq_scaling_matrix_present_flag     =u(1, buf);int[] seq_scaling_list_present_flag = new int[8];if ( seq_scaling_matrix_present_flag != 0){for( int i = 0; i < 8; i++ ){seq_scaling_list_present_flag[i]=u(1, buf);}}}int log2_max_frame_num_minus4=Ue(buf, nLen);int pic_order_cnt_type       =Ue(buf, nLen);if ( pic_order_cnt_type == 0 ){int log2_max_pic_order_cnt_lsb_minus4=Ue(buf, nLen);}else if( pic_order_cnt_type == 1 ){int delta_pic_order_always_zero_flag     =u(1,     buf);int offset_for_non_ref_pic               =Se(buf, nLen);int offset_for_top_to_bottom_field       =Se(buf, nLen);int num_ref_frames_in_pic_order_cnt_cycle=Ue(buf, nLen);int[] offset_for_ref_frame=new int[num_ref_frames_in_pic_order_cnt_cycle];for( int i = 0; i < num_ref_frames_in_pic_order_cnt_cycle; i++ ){offset_for_ref_frame[i]=Se(buf, nLen);}}int num_ref_frames                      =Ue(buf, nLen);int gaps_in_frame_num_value_allowed_flag=u(1,     buf);int pic_width_in_mbs_minus1             =Ue(buf, nLen);int pic_height_in_map_units_minus1      =Ue(buf, nLen);size[0]=(pic_width_in_mbs_minus1       +1)*16;size[1]=(pic_height_in_map_units_minus1+1)*16;/*int frame_mbs_only_flag=u(1,buf,StartBit);  if(!frame_mbs_only_flag)  int mb_adaptive_frame_field_flag=u(1,buf,StartBit);  int direct_8x8_inference_flag=u(1,buf,StartBit);  int frame_cropping_flag=u(1,buf,StartBit);  if(frame_cropping_flag)  {  int frame_crop_left_offset=Ue(buf,nLen,StartBit);  int frame_crop_right_offset=Ue(buf,nLen,StartBit);  int frame_crop_top_offset=Ue(buf,nLen,StartBit);  int frame_crop_bottom_offset=Ue(buf,nLen,StartBit);  }  int vui_parameter_present_flag=u(1,buf,StartBit);  if(vui_parameter_present_flag)  {  int aspect_ratio_info_present_flag=u(1,buf,StartBit);  if(aspect_ratio_info_present_flag)  {  int aspect_ratio_idc=u(8,buf,StartBit);  if(aspect_ratio_idc==255)  {  int sar_width=u(16,buf,StartBit);  int sar_height=u(16,buf,StartBit);  }  }  int overscan_info_present_flag=u(1,buf,StartBit);  if(overscan_info_present_flag)  int overscan_appropriate_flagu=u(1,buf,StartBit);  int video_signal_type_present_flag=u(1,buf,StartBit);  if(video_signal_type_present_flag)  {  int video_format=u(3,buf,StartBit);  int video_full_range_flag=u(1,buf,StartBit);  int colour_description_present_flag=u(1,buf,StartBit);  if(colour_description_present_flag)  {  int colour_primaries=u(8,buf,StartBit);  int transfer_characteristics=u(8,buf,StartBit);  int matrix_coefficients=u(8,buf,StartBit);  }  }  int chroma_loc_info_present_flag=u(1,buf,StartBit);  if(chroma_loc_info_present_flag)  {  int chroma_sample_loc_type_top_field=Ue(buf,nLen,StartBit);  int chroma_sample_loc_type_bottom_field=Ue(buf,nLen,StartBit);  }  int timing_info_present_flag=u(1,buf,StartBit);  if(timing_info_present_flag)  {  int num_units_in_tick=u(32,buf,StartBit);  int time_scale=u(32,buf,StartBit);  fps=time_scale/num_units_in_tick;  int fixed_frame_rate_flag=u(1,buf,StartBit);  if(fixed_frame_rate_flag)  {  fps=fps/2;  }  }  }
*/return true;}return false;}public static int[] getSizeFromSps(byte[] data){for (int i=0; i<data.length-4; i++){if (data[i]==0 && data[i+1]==0 && data[i+2]==0 && data[i+3]==1 && data[i+4]==0x67){int[] size = new int[2];h264_decode_seq_parameter_set(data, data.length, size);Log.d(TAG, "Sps=("+size[0]+", "+size[1]+")");return size;}}return null;}}

C版
   JAVA代码是从C改过来的。没有运行。也许有小错误,各位参考JAVA再改。

#include <cstdint>
#include <cmath>#define NAL_HEADEER 4uint32_t Ue(uint8_t *pBuff, uint32_t nLen, uint32_t &nStartBit)
{//计算0bit的个数uint32_t nZeroNum = 0;while (nStartBit < nLen * 8){if (pBuff[nStartBit / 8] & (0x80 >> (nStartBit % 8))) //&:按位与,%取余{break;}nZeroNum++;nStartBit++;}nStartBit ++;//计算结果uint32_t dwRet = 0;for (uint32_t i=0; i<nZeroNum; i++){dwRet <<= 1;if (pBuff[nStartBit / 8] & (0x80 >> (nStartBit % 8))){dwRet += 1;}nStartBit++;}return (1 << nZeroNum) - 1 + dwRet;
}int Se(uint8_t *pBuff, uint32_t nLen, uint32_t &nStartBit)
{int UeVal=Ue(pBuff,nLen,nStartBit);double k=UeVal;int nValue=ceil(k/2);//ceil函数:ceil函数的作用是求不小于给定实数的最小整数。ceil(2)=ceil(1.2)=cei(1.5)=2.00if (UeVal % 2==0){nValue=-nValue;}return nValue;}uint32_t u(uint32_t BitCount, uint8_t * buf, uint32_t &nStartBit)
{uint32_t dwRet = 0;for (uint32_t i=0; i<BitCount; i++){dwRet <<= 1;if (buf[nStartBit / 8] & (0x80 >> (nStartBit % 8))){dwRet += 1;}nStartBit++;}return dwRet;
}bool h264_decode_seq_parameter_set(uint8_t * buf, uint32_t nLen ,int &Width, int &Height)
{uint32_t StartBit=NAL_HEADEER*8;int forbidden_zero_bit=u(1, buf, StartBit);int nal_ref_idc       =u(2, buf, StartBit);int nal_unit_type     =u(5, buf, StartBit);if (nal_unit_type==7){int profile_idc         =u(8, buf, StartBit);int constraint_set0_flag=u(1, buf, StartBit);//(buf[1] & 0x80)>>7;int constraint_set1_flag=u(1, buf, StartBit);//(buf[1] & 0x40)>>6;int constraint_set2_flag=u(1, buf, StartBit);//(buf[1] & 0x20)>>5;int constraint_set3_flag=u(1, buf, StartBit);//(buf[1] & 0x10)>>4;int reserved_zero_4bits =u(4, buf, StartBit);int level_idc=u(8, buf, StartBit);int seq_parameter_set_id=Ue(buf, nLen, StartBit);if ( profile_idc == 100 || profile_idc == 110 ||profile_idc == 122 || profile_idc == 144 ){int chroma_format_idc=Ue(buf, nLen, StartBit);if ( chroma_format_idc == 3 ){int residual_colour_transform_flag  =u(1, buf, StartBit);}int bit_depth_luma_minus8               =Ue(buf, nLen, StartBit);int bit_depth_chroma_minus8             =Ue(buf, nLen, StartBit);int qpprime_y_zero_transform_bypass_flag=u(1,     buf, StartBit);int seq_scaling_matrix_present_flag     =u(1,     buf, StartBit);int seq_scaling_list_present_flag[8];if ( seq_scaling_matrix_present_flag ){for ( int i = 0; i < 8; i++ ){seq_scaling_list_present_flag[i]=u(1, buf, StartBit);}}}int log2_max_frame_num_minus4=Ue(buf, nLen, StartBit);int pic_order_cnt_type       =Ue(buf, nLen, StartBit);if ( pic_order_cnt_type == 0 ){int log2_max_pic_order_cnt_lsb_minus4=Ue(buf, nLen, StartBit);}else if ( pic_order_cnt_type == 1 ){int delta_pic_order_always_zero_flag     =u(1,     buf, StartBit);int offset_for_non_ref_pic               =Se(buf, nLen, StartBit);int offset_for_top_to_bottom_field       =Se(buf, nLen, StartBit);int num_ref_frames_in_pic_order_cnt_cycle=Ue(buf, nLen, StartBit);int *offset_for_ref_frame=new int[num_ref_frames_in_pic_order_cnt_cycle];for ( int i = 0; i < num_ref_frames_in_pic_order_cnt_cycle; i++ ){offset_for_ref_frame[i]=Se(buf, nLen, StartBit);}delete [] offset_for_ref_frame;}int num_ref_frames=Ue(buf,nLen,StartBit);int gaps_in_frame_num_value_allowed_flag=u(1,    buf, StartBit);int pic_width_in_mbs_minus1             =Ue(buf, nLen, StartBit);int pic_height_in_map_units_minus1      =Ue(buf, nLen, StartBit);Width =(pic_width_in_mbs_minus1       +1)*16;Height=(pic_height_in_map_units_minus1+1)*16;return true;}return false;
}int main()
{int Width, Height;if (h264_decode_seq_parameter_set(str, 11, Width, Height)){}return 0;
}

H264 SPS中得到宽高的代码(java/c),测试通过相关推荐

  1. 视频知识点(20)- H264码流如何在SPS中获取宽高信息?

    <音视频开发>系列-总览 前沿 了解H264视频编码格式的小伙伴都知道,H264编码中存在两个非常重要的参数集.没错,它们就是序列参数集(SPS)和图像参数集(PPS),而且通常情况下,P ...

  2. php将img中的宽高删除,PHP删除HTML中宽高样式的详解

    这篇文章主要介绍了PHP正则删除HTML代码中宽高样式的方法,涉及php针对HTML代码的正则匹配.替换等操作技巧,需要的朋友可以参考下 本文实例讲述了PHP正则删除HTML代码中宽高样式的方法.分享 ...

  3. H264 SPS 中 VUI 自己碰到的一些比较关键的 字段介绍。

    VUI 中有这样的信息: num_reorder_frames 是用于标示 出 显示的时候需要缓冲多少帧 以方便排序,比如IPP序列 是不需要缓冲,或者重排序的,如果缓冲太多帧会造成延迟.当然这个也有 ...

  4. html商城选择尺寸,Html 中各种宽高尺寸汇总

    1. window innerHeight 和 outerHeight innerHeight 表示浏览器中页面内部呈现部分的高度,包括水平滚动条部分(如果有的话),不包括页面标签部分. outerH ...

  5. android中屏幕宽高显示不全,Android 获取屏幕宽度跟高度

    Android 获取屏幕宽度跟高度 在android开发过程中,对于控件的高度,宽度,通过下面的函数调用,轻松实现编程中设置控件的相对宽度跟高度: // 获得屏幕的宽度 public static i ...

  6. CSS中的宽高自适应以及最小最大宽/高

    目录 一.宽度自适应 二.高度自适应 三.最小和最大宽度值 四.最小和最大高度值 一.宽度自适应 宽度自适应的4种方法: 1.块元素未设置宽度默认占整行,在浏览器窗口发生变化的时候宽度会跟随发生变化 ...

  7. 控制富文本中图片宽高_tinyMCE富文本编辑器如何设置默认的图片宽度

    大佬们 我想在用户上传图片后给编辑器里的图片设置一个默认宽度 这该在哪里进行设置啊 以下是我现在的tinyMCE初始化设置 tinymce.init({ selector: '#' + this.el ...

  8. 音视频系列--哥伦布编码和H264片段sps解析宽高信息

    H.264码流中的NALU进行了一个简单的划分,标出了NALU的类型和长度等信息.因为我们在解析SPS和PPS中要使用到指数哥伦布编码的解析,所以有必要了解一下指数哥伦布编码. 一.指数哥伦布编码(理 ...

  9. 从h264码流中获取图像的宽高---版本1 (移植于ffmpeg)

    在工程中,我们常常需要知道视频流的宽高,虽然可以借助一些开源库,但是仅为了获取宽高,却需要调用几十或是几百K的开源库,不太划算.因此,本文从开源库中移植了解析264码流宽高的代码,具体如下: ##1 ...

  10. 从h264码流中获取图像的宽高---版本2(简洁版)

    从264码流中获取图像的宽高,代码如下,注意代码文件应该为cpp文件 #include <stdio.h> #include <stdlib.h> #include <s ...

最新文章

  1. python 查看数据结构类型_python标准数据结构类型
  2. Linux下查看进程和线程
  3. php 出错处理,PHP 错误处理机制
  4. 在Spring + Hibernate中使用二级缓存配置步骤
  5. C++学习之路 | PTA乙级—— 1043 输出PATest (20 分)(精简)
  6. 基于JavaScript实现放大镜效果
  7. @controlleradvice注解作用_springboot的常用注解分析
  8. **Dijkstra算法**
  9. C#探秘系列(八)WPF数据绑定
  10. HTML简介及常用标签介绍
  11. 安卓随机通话记录_几款安卓amp;苹果虚拟来电软件,带你快速逃离尬聊现场,留有情面慰人心扉...
  12. java在线反编译class文件
  13. 实验一 常用元器件的识别与简单测试
  14. OV2640拍摄jpg图像无法解析
  15. 机器学习之线性回归缩减维度
  16. url“forum.php,如何让discuz论坛首页打开不显示forum.php的方法分享
  17. java计算机毕业设计springboot+vue青少年编程在线考试系统
  18. python开源项目贡献_为开源项目做出第一笔贡献
  19. 做软文营销发布有哪些常见平台?
  20. Subversion的安装部署与用户验证配置

热门文章

  1. centos7 django mysql_安装和部署centos7 python3。X Django MySQL,centos7python3Xdjangomysql
  2. 求每个月最后一天mysql函数_计算指定年月的最后一天的自定义MYSQL函数_MySQL
  3. python数据库def函数_Python:函数
  4. JAVA中super和this关键字的区别
  5. Linux常用网络带宽监控工具(转)
  6. 线性表的链式存储结构的实现及其应用(C/C++实现)
  7. Flexbox属性介绍
  8. cygwin+hadoop+eclipse (三) 运行wordcount实例
  9. 玩转Android---组件篇---Broadcast Receiver(广播接收器)
  10. enq: HW - contention等待事件