之前做的SDP对于h264编码的视频没有做"a=fmtp"字段的解析,今天加上,主要是为了解析出视频的宽高信息。

RFC3984的8.2节对field做了介绍,这里只介绍sprop-parameter-sets字段的解码方法,因为我的主要目的是解析出视频宽高信息

该字段用BASE-64编码,因此,首先解码BASE-64,这里给出解码方法:

long CBase64::Decode(const char *pSrc, long srcLen, unsigned char *pDest, long destLen)
{int i = 0;int iCnt = 0;unsigned char * p = pDest;for (i=0; i<srcLen; i++){if (pSrc[i] > 127){continue;}if (pSrc[i] == '='){return p-pDest+1;}unsigned char a = Base64IdxTab[pSrc[i]];if (a == 255){continue;}switch (iCnt){case 0:{*p = a << 2;iCnt++;}break;case 1:{*p++ |= a >> 4;*p = a << 4;iCnt++;}break;case 2:{*p++ |= a >> 2;*p = a << 6;iCnt++;}break;case 3:{*p++ |= a;iCnt = 0;}break;} }*p = 0x00;return p-pDest;
}

其中返回值为解出的目标串的长度

然后,针对接触的字符串,它的第一个字节是个NUL头,我们希望它的NAL_TYPE为7,也就是序列参数集(sps)

针对该参数集,对照h.264文档的7.3.2.1对语法,我们希望解出pic_width_in_mbs_minus1字段和pic_height_in_map_units_minus1字段

这里遇到了一个问题,因为它是指数哥伦布编码,因此又需要解码:

int GolombDecode(bool *pBinaryArray, int &Des)
{if (pBinaryArray == NULL){return -1;}int iter = 0;int NumOfZero = 0;int M_bit = 0;int INFO = 0;double result;//找到第一个1while(pBinaryArray[iter++] == 0){NumOfZero++;}for (int i=NumOfZero-1; i>=0; i--){INFO += pBinaryArray[iter++]<<i;}result = pow((double)2, (double)NumOfZero) + INFO - 1;Des = result;return iter;
}

其中,返回值是二进制字符串的偏移地址

因为指数哥伦布编码不定长的特性,我们需要解出整个SPS(依据ITU-T H264  7.3.2.1.1):

int ParseSPS(unsigned char *pSrc, unsigned long SrcLen, unsigned long &VideoWidth, unsigned long &VideoHeight)
{int ret = 0;unsigned long offset = 0;bool *pBinaryArray = new bool[SrcLen*8];unsigned long iter = 0;unsigned char mask = 0x80;for (int i=0; i<SrcLen; i++){mask = 0x80;for (int j=0; j<8; j++){if (pSrc[i] & (mask >> j)){pBinaryArray[iter] = 1;}else{pBinaryArray[iter] = 0;}iter++;}}iter = 0;unsigned char profile_idc = *pSrc;int seq_parameter_set_id;offset = 24;ret = GolombDecode(pBinaryArray+offset, seq_parameter_set_id);offset += ret;if (profile_idc == 100 || profile_idc == 110 || profile_idc == 122 || profile_idc == 144){int chroma_format_idc;ret = GolombDecode(pBinaryArray+offset, chroma_format_idc);offset += ret;if(chroma_format_idc == 3){offset += 1;}int bit_depth_luma_minus8, bit_depth_chroma_minus8;ret = GolombDecode(pBinaryArray+offset, bit_depth_luma_minus8);offset += ret;ret = GolombDecode(pBinaryArray+offset, bit_depth_chroma_minus8);offset += ret;offset += 2;bool seq_scaling_matrix_present_flag = pBinaryArray[offset];if (seq_scaling_matrix_present_flag){offset += 1;}}int log2_max_frame_num_minus4, pic_order_cnt_type;ret = GolombDecode(pBinaryArray+offset, log2_max_frame_num_minus4);offset += ret;ret = GolombDecode(pBinaryArray+offset, pic_order_cnt_type);offset += ret;if (pic_order_cnt_type == 0){int log2_max_pic_order_cnt_lsb_minus4;ret = GolombDecode(pBinaryArray+offset, pic_order_cnt_type);offset += ret;}else if (pic_order_cnt_type == 1){offset += 1;int offset_for_non_ref_pic, offset_for_top_to_bottom_field, num_ref_frames_in_pic_order_cnt_cycle, offset_for_ref_frame;ret = GolombDecode(pBinaryArray+offset, offset_for_non_ref_pic);offset += ret;ret = GolombDecode(pBinaryArray+offset, offset_for_top_to_bottom_field);offset += ret;ret = GolombDecode(pBinaryArray+offset, num_ref_frames_in_pic_order_cnt_cycle);offset += ret;for (int i=0; i<num_ref_frames_in_pic_order_cnt_cycle ;i++){ret = GolombDecode(pBinaryArray+offset, offset_for_ref_frame);offset += ret;}}int num_ref_frames;ret = GolombDecode(pBinaryArray+offset, num_ref_frames);offset += ret;offset += 1;int pic_width_in_mbs_minus1, pic_height_in_map_units_minus1;ret = GolombDecode(pBinaryArray+offset, pic_width_in_mbs_minus1);offset += ret;ret = GolombDecode(pBinaryArray+offset, pic_height_in_map_units_minus1);offset += ret;VideoWidth = (pic_width_in_mbs_minus1 + 1) * 16;VideoHeight = (pic_height_in_map_units_minus1 + 1) * 16;delete []pBinaryArray;pBinaryArray = NULL;return 0;
}

这样,就完成了目标,得到了视频信息的长和宽

SDP的fmtp部分相关推荐

  1. Asterisk 1.8 sip 协议栈分析

    引用自:http://blog.csdn.net/z1623866465/archive/2011/01/02/6113057.aspx 看了一下 asterisk 1.8 ,chan_sip 更新了 ...

  2. rfc4588 RTP重传有效载荷格式

    蚂蚱google中文翻译版   Network Working Group J. Rey Request for Comments: 4588 Panasonic Category: Standard ...

  3. SDP 协议分析 http://www.cnblogs.com/qingquan/archive/2011/08/02/2125585.html

    SDP 协议分析 一.SDP协议介绍 SDP 完全是一种会话描述格式 ― 它不属于传输协议 ― 它只使用不同的适当的传输协议,包括会话通知协议(SAP).会话初始协议(SIP).实时流协议(RTSP) ...

  4. 转--SDP 协议分析

    原文地址:http://www.cnblogs.com/qingquan/archive/2011/08/02/2125585.html 一.SDP协议介绍 SDP 完全是一种会话描述格式 ― 它不属 ...

  5. DSS转发中sdp文件的简化

    如文章<用VLC读取摄像头产生RTSP流,DSS侦听并转发(二)>中用vlc推送产生的sdp文件如下: v=0 o=- 15535216080726474763 1553521608072 ...

  6. live555 源码分析:子会话 SDP 行生成

    如我们在前文 live555 源码分析:ServerMediaSession 中看到的,H264VideoFileServerMediaSubsession 的继承层次体系如下图: 在这个继承层次体系 ...

  7. SDP协议基本分析(RTSP、WebRTC使用)

    目录 一.介绍 二.标准 SDP 规范 1. SDP 的格式 2. SDP 的结构 (1)会话描述 (2)媒体描述 三.WebRTC 中的 SDP 一.介绍 SDP(Session Descripti ...

  8. SDP协议 学习笔记

    SDP:Session Description Protocol SDP格式:    Session description        v=  (protocolversion)        o ...

  9. 硬货专栏 |WebRTC SDP 详解和剖析

    WebRTC 是 Web Real-Time Communication,即网页实时通信的缩写,是 RTC 协议的一种Web实现,项目由 Google 开源,并和 IETF 和 W3C 制定了行业标准 ...

  10. WebRTC 之 SDP

    SDP 即 Session Description Protocol 会话描述协议, 它描述了所传输的媒体信息. 之所以需要在多媒体通信之前交换 SDP, 就在于 接收方需要知道传输的是什么媒体类型, ...

最新文章

  1. 【怎样写代码】小技巧 -- 关于方法中修饰形参的关键词
  2. keep-alive的深入理解与使用(配合router-view缓存整个路由页面)
  3. 日期控件的点击事件,在js中添加callback属性,不在html中直接添加
  4. SAP Fiori 的 UI 新主题 Horizon
  5. python反射、闭包、装饰器_python之闭包、装饰器、生成器、反射
  6. python生成数据库登录界面_python 生成数据库
  7. 第一:Java+MyBatis(快速入门)
  8. TeamCity : .NET Core 插件
  9. android可以root的版本,Android8.0以上系统ROOT时,Magisk框架替代SpuerSU
  10. 数据、运营相关试题(三)【牛客网:数据运营试题广场】
  11. 达梦数据库DM7手把手安装教程
  12. Golang 编译成DLL文件
  13. 汽车电工及电子技术基础【1】
  14. 阿里出品的在线图表制作工具
  15. swagger注解类说明
  16. 新代系统9服务器警报,新代系统数控铣加工中心。新代系统龙门加工中心故障与报警...
  17. 微信支付委托代扣的服务商模式和直连模式
  18. ios平台实现视频H264硬编码及软编码(附完整demo)
  19. Educational Codeforces Round 61 (Rated for Div. 2) D. Stressful Training(贪心+二分)
  20. vba 读取图片尺寸

热门文章

  1. 黑苹果 惠普笔记本电池补丁_黑苹果笔记本:关于DSDT亮度表的分析与修改
  2. Windows系统下显卡挖零币(ZEC)的方法
  3. SPSS25安装教程
  4. Springboot 内嵌 Tomcat 版本查看
  5. 计算机实验室场地报告,实验室申请报告.doc
  6. 我的世界HMCL如何安装Java_Ubuntu 18.04 LTS 使用 Minecraft 我的世界第三方启动器 HMCL...
  7. Ubuntu分辨率修改
  8. ACM 算法详细分类
  9. Java项目实战--健康管理系统设计实现【Springboot+mybatis+layui等实现】
  10. ChartControl控件绘制折线图