h264取流解码分析
来源:互联网 发布:兄弟连java视频下载 编辑:程序博客网 时间:2024/06/05 06:27
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 nalvcl_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 mbhttp://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/380262907typedef 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/http://www.baidu.com/s?ie=utf-8&f=8&tn=baidu&wd=first_mb_in_slice&rsv_bp=1&rsv_enter=1&rsv_n=2&rsv_sug3=1&rsv_sug4=385&rsv_sug2=0&inputT=842
阅读全文
0 0
- h264取流解码分析
- H264 解码耗时分析
- S3C6410 MFC H264 解码分析
- S3C6410 MFC H264 解码分析
- ffmpeg 解码 H264源码分析
- ffmpeg 解码 H264源码分析
- S3C6410 MFC H264 解码分析
- MediaCodec解码h264流
- h264码流分析(二)---以ffmpeg中h264解码为例
- s3c6410硬件mfc解码分析-H264
- h264解码器,s3c6410硬件mfc解码分析-H264
- h264解码器,s3c6410硬件mfc解码分析-H264
- h264解码器,s3c6410硬件mfc解码分析-H264
- h264解码器,s3c6410硬件mfc解码分析-H264
- h264解码器,s3c6410硬件mfc解码分析-H264
- ffmpeg 解码摄像机H264流
- h264解码
- H264--5--H264解码
- Mybatis高级映射结果集---注解---(一对多,多对一)
- python利用urlib2进行简单爬虫实例
- Appium使用教程(一)——安装appium
- Java 中 Comparable 和 Comparator 比较
- 让家庭生活更有温度,这家厂商推出了“新概念打印”
- h264取流解码分析
- 从参与者到跻身第一梯队:中国开源云计算的崛起
- 常见的代码规范
- myeclipse添加新tomcat
- 派生类的派生类中(override)的表现
- Go 深度好文汇总
- SylixOS中APIC HPET定时器字符驱动实现
- ubuntu14.04设置默认用户为root
- 够励志!困难也是生产力