多媒体开发之---h264 取流解码分析
1.
nalu_unit_type = *((unsigned char *)pEmptyBuf->bufVirtAddr+4);
nalu_unit_type = nalu_unit_type&0x1F;
if(nalu_unit_type<= 5 && nalu_unit_type>=1)
{
slice_sum ++;
printf("%s:nalu_unit_type = %d ,frame_size = %d, frame_id = %d,slice_sum = %d\n",__func__,nalu_unit_type,pEmptyBuf->filledBufSize,frame_id,slice_sum);
}
else
{
frame_flag++;
if(nalu_unit_type==6)printf("sei ...\n");
else if(nalu_unit_type==7)printf("sps ...\n");
else if(nalu_unit_type==8)printf("pps ...\n");
else if(nalu_unit_type == 9)printf("cut fp ...\n");
else if(nalu_unit_type == 10)printf("sps end ...\n");
else if(nalu_unit_type == 11)printf("stream end ...\n");
else printf("unknow frame !\n");
printf("nalu_unit_type = %d, frame_flag = %d, slice_sum = %d,frame_id =%d\n",nalu_unit_type,frame_flag,slice_sum,frame_id);
}
first_mb_in_slice = *((unsigned char *)pEmptyBuf->bufVirtAddr+5);
if((first_mb_in_slice&0x80)==0x80)
printf("%s:first_mb_in_slice = %d frame_id = %d\n\n\n",__func__,first_mb_in_slice,frame_id);//per frame all is iframe
for (wordCount = 4; wordCount < bufferLen; wordCount++)
{
loopCount = wordCount;
if ((stream[loopCount++] == 0 && stream[loopCount++] == 0 &&
stream[loopCount++] == 0 && stream[loopCount++] == 0x01) ||
(stream[loopCount++] == 0 && stream[loopCount++] == 0 &&
stream[loopCount++] == 1))
{
NewNalType = stream[loopCount++] & 0x1f;
firstMbInSliceFlag = stream[loopCount++] & 0x80;//reuser header nal
vcl_nal_flag = ((NewNalType <=5) && (NewNalType > 0));
if(vcl_nal_flag && prev_vcl_nal_flag)//是两帧之间的新帧,且又是第片块,i帧或p帧,新一帧的开始,上一帧的结束
{
prev_nal_type = NewNalType;
prev_vcl_nal_flag = vcl_nal_flag;
if( (firstMbInSliceFlag))
break;
}
if ((prev_vcl_nal_flag && !vcl_nal_flag))//非slice ,但是可能是sps pps sei idr,没宏块,也做为一帧
{
prev_nal_type = NewNalType;
prev_vcl_nal_flag = vcl_nal_flag;
break;
}
prev_nal_type = NewNalType;
prev_vcl_nal_flag = vcl_nal_flag;
}
nalLength++;
}
2.
以sps开头的*(addr+5)&0x1f 的之为07(67) 后续pps 08(68),sei 06 ,idr 05(65) 为解码第一帧
3.
后续就是i,和p帧 i帧 05(65) ,p帧 01(41)
一个sps 包括sps pps sei idr为第一次帧以first_mb_slice为基本帧分界线
mw3 9 个idr frame
每个0001 都是一个slice mb
http://www.cnitblog.com/vcommon/archive/2007/05/31/27842.html 哥伦布编码!!!
http://70565912.blog.51cto.com/1358202/533736/
- // 判断是否帧结束
- for (uint32_t i = 3; i < nal_length; i++)
- {
- if (p_nal[i] & 0x80)
- {
- // 找到frame_begin!!!!上一帧frame的结束,下一帧frame的开始
- }
- }
解析到位于帧结束位置的NALU,就可以判断出每一帧(slice)的开始和结尾。解析slice的slice_type,根据slice_type,可以判断出这个slice的IPB类型。
- // 根据slice类型判断帧类型
- switch(slice.i_slice_type)
- {
- case 2: case 7:
- case 4: case 9:
- *p_flags = 0x0002/*BLOCK_FLAG_TYPE_I*/;
- break;
- case 0: case 5:
- case 3: case 8:
- *p_flags = 0x0004/*BLOCK_FLAG_TYPE_P*/;
- break;
- case 1:
- case 6:
- *p_flags = 0x0008/*BLOCK_FLAG_TYPE_B*/;
- break;
- default:
- *p_flags = 0;
- break;
- }
http://bbs.csdn.net/topics/380262907
typedef struct
{
/*分层结构最大的不同时取消了序列层和图像层,并将原本属于序列和头部的大部分句法元素游离出来形成
序列和图像两级参数集。 其余部分则放入片层*/
x264_sps_t *sps; /*序列参数集*/
x264_pps_t *pps; /*图像参数集*/
/*slice_type
指明片的类型*/
int i_type;
//first_mb_in_slice
/*片中第一个宏块的地址,片通过这个句法元素来标定它自己的地址。
在帧场自适应模式下,宏块都是成对出现的,这是本句法元素表示的是第几个宏块对,
对应第一个宏块的真实地址应该是 2*first_mb_in_slice*/
int i_first_mb;
int i_last_mb;
int i_pps_id; /*图像参数集的序号*/
//frame_num
/*每个参考帧都有一个一次连续的frame_num作为他们的标识,这指明了各图像的解码顺序。
但事实上我们在表中看到,frame_num的出现没有if语句限定条件,这表明非参考帧的片头也会出现frame_num
指示当该个图像是参考帧时候,它携带的这个句法元素在解码时候才有意义*/
int i_frame_num;
int b_mbaff;
//field_pic_flag
/*在片层表示图像编码模式的唯一一个句法元素,所谓的编码模式是指帧编码,场编码 ,帧场自适应编码
这个句法元素取1的时候属于场编码,0时为非场编码*/
int b_field_pic;
/*等于1的时候说明当前图像是属于底场,等于0时候说明当前图像是属于顶场*/
int b_bottom_field;
/*IDR图像标示,不同的IDR图像有不同的idr_pic_id值,IDR图像不等同于I图像*/
int i_idr_pic_id; /* -1 if nal_type != 5 */
/*POC 的第一种算法中用本句法元素来计算POC值,在POC的第一种算法中是显式的传递POC值*/
int i_poc_lsb;
int i_delta_poc_bottom;
/*POC的第二种和第三种算法是从frame_num映射得来的,这两个句法元素用于映射算法。
delta_pic_order_cnt[0]用于帧场编码方式下的底场和场编码方式的场,
delta_pic_order_cnt[1]用于帧编码方式下的顶场。*/
int i_delta_poc[2];
//redundant_pic_cnt
/*冗余片的id号*/
int i_redundant_pic_cnt;
//direct_spatial_mv_pred_flag
/*指明B图像的直接预测的模式下, 用时间预测还是空间预测 值为1空间预测 值为0时间预测*/
int b_direct_spatial_mv_pred;
//num_ref_idx_active_override_flag
/*图像参数集中我们看到已经出现句法元素num_ref_idx_10_active_minus1 和 num_ref_idx_11_active_minus1
制定当前参考帧队列中实际可用的参考帧的数目。在片头重载这对句法元素,以给某特定图像更大的灵活度。
这句法元素就是指明片头是否会重载,如果等于1,下面会出现新的num_ref_idx_10_active_minus1*/
int b_num_ref_idx_override;
int i_num_ref_idx_l0_active;
int i_num_ref_idx_l1_active;
/*参考图像重新排列的语义*/
/*指明是否进行重排序操作,这个句法等于1时,表明紧跟着会有一系列句法元素用于参考帧队列的重排序*/
int b_ref_pic_list_reordering_l0;
int b_ref_pic_list_reordering_l1;
struct {
int idc;
int arg;
} ref_pic_list_order[2][16];
//cabac_init_idc
/*给出cabac初始化时表格的选择 范围为0~2*/
int i_cabac_init_idc;
int i_qp;
/*指出用于当前片的所有宏块的量化参数的初始值QP*/
int i_qp_delta;
/*sp帧中的p宏块的解码方式是否是switching方式*/
int b_sp_for_swidth;
/*和i_qp_delta语义相似*/
int i_qs_delta;
/* deblocking filter */
/*指明一些滤波的设置*/
int i_disable_deblocking_filter_idc;
int i_alpha_c0_offset;
int i_beta_offset;
} x264_slice_header_t;
http://linfengdu.blog.163.com/blog/static/117710732009111861540971/
多媒体开发之---h264 取流解码分析的更多相关文章
- 多媒体开发之---h264 取流解码实现
解码器在解码时,首先逐个字节读取NAL的数据,统计NAL的长度,然后再开始解码. nal_unit( NumBytesInNALunit ) { /* NumBytesInNALunit为统计出来的 ...
- H264码流打包分析(精华)
H264码流打包分析 SODB 数据比特串-->最原始的编码数据 RBSP 原始字节序列载荷-->在SODB的后面填加了结尾比特(RBSP trailing bits 一个bit“1”)若 ...
- 多媒体开发之---h264 高度和宽度获取
( School of Computer Science & Technology, Soochow University,SuZhou 215006:) Abstract: H.264 is ...
- 多媒体开发之---H264—MP4格式及在MP4文件中提取H264的SPS、PPS及码流
一.MP4格式基本概念 MP4格式对应标准MPEG-4标准(ISO/IEC14496) 二.MP4封装格式核心概念 1 MP4封装格式对应标准为 ISO/IEC 14496-12(信息技术 视听对象 ...
- H264码流打包分析
转自:http://www.360doc.com/content/13/0124/08/9008018_262076786.shtml SODB 数据比特串-->最原始的编码数据 RBSP ...
- 多媒体开发之---h264格式slice_header
从Slice_Header学习H.264 写在前面: $ H.264我是结合标准和毕厚杰的书一块学的.看句法语义时最是头疼,一大堆的元素,很需要耐心.标准中在介绍某个元素的语义时,经常会突然冒 ...
- 多媒体开发之---h264 NALU 语法结构
补充笔记: 关于VCL:VCL层是指视频编码层,VCL NAL 单元是指那些nal_unit_type 值等于 1 到 5(包括 1 和 5)的 NAL 单元,这些单元都包含了视频数据.所有其他的 N ...
- 多媒体开发之--- h264 图像、帧、片、NALU
图像.帧.片.NALU 是学习 H.264的人常常感到困惑的一些概念,我在这里对自己的理解做一些阐述,欢迎大家讨论: H.264 是一次概念的革新,它打破常规,完全没有 I 帧.P帧.B 帧的概念,也 ...
- 多媒体开发之---h264中 的RTP PAYLOAD 格式
H.264 视频 RTP 负载格式 1. 网络抽象层单元类型 (NALU) NALU 头由一个字节组成, 它的语法如下: +---------------+ |0|1|2|3|4|5|6|7 ...
随机推荐
- wlan
一.概述 CSMA/CD --->以太网介质 CSMA/CA------->无线介质 IEEE----->802.11 a b g e f h i j 分类 ...
- php 注册与登录
<body background="timg.jpg"><div class="dak"> <div class="zu ...
- HDU1007 TLE代码和AC代码对比
这题卡了一天,上午开始看算法导论,然后实现了,一开始是wa,后来TLE,由于我开始的实现方式比较笨,而且在递归调用的时候很是混乱,用了好多数组.导致我的代码不断的出问题.具体是算法导论33-4. 后来 ...
- 编辑被标记为“只读”的Word文档
从邮件接收到的Word文档,打开时总是被标记为“只读”,在阅读时对其进行编辑,但不能保存,会提示文档为只读的.要想对其进行编辑并保存,需要进行一定的操作. 进入文件所在的目录,鼠标右键点击Word文档 ...
- 对Netflix Ribbon的Loadbalancer类源码设计合理性的一点质疑
首先,这只是我个人的一点质疑,可能是因为我自己菜没有领悟到作者的意思,也正因此,想发出来跟大家一起探讨. 在昨晚,我因为在编写自己的开源项目的负载均衡模块(这是我开源项目的介绍:https://www ...
- php——离线执行任务
<?php//设置忽略是否关闭终端窗口ignore_user_abort(true);ini_set('max_execution_time', '0');//采集页面函数,看不懂执行百度cur ...
- Codeforces 665C Simple Strings【暴力,贪心】
题目链接: http://codeforces.com/contest/665/problem/C 题意: 改变最少的字符,使得最终序列无相同的连续的字符. 分析: 对每一个与前一个字符相同的字符,枚 ...
- Codeforces 515E Drazil and Park (ST表)
题目链接 Drazil and Park 中文题面 传送门 如果他选择了x和y,那么他消耗的能量为dx + dx + 1 + ... + dy - 1 + 2 * (hx + hy). 把这个式子写成 ...
- DFS与BFS对比
前面已经说过了深搜和广搜了,是不是有点还不是很好的分清他们?(其实分不分的请都没大有关系) 下面我们来看一看广搜与深搜的区别吧. 算法步骤上的区别 深度优先遍历图算法步骤: 1.访问顶点v 2,.依次 ...
- NOIP临考经验(转)
[COGS]NOIP临考经验 1. 提前15分钟入场,此时静坐调整心态,适当的深呼吸 2. 打开编辑器并调整为自己喜欢的界面 3. 熟悉文件目录,写好准确无误的代码模板 4. 压缩包或许还不能 ...