如何利用JM8.6解码器提取码流中P帧宏块(所有4*4块)的运动矢量(考虑B帧,设x264编码的12帧为IDR BBPBBPBBPBP)
来源:互联网 发布:千牛mac官方下载 编辑:程序博客网 时间:2024/06/04 18:55
说明:有好心的读者对下面程序提出了质疑,我觉得有道理,有兴趣的读者可以看看文章后面的评论。感谢那位提出质疑的读者,同时也欢迎各位批评指正。
之前已经讨论过提取P帧各个宏块的第一个4*4块对应的运动矢量,现在考虑提取所有4*4块的运动矢量. 我们知道,在H.264中,宏块是有分块的的,不同情况下分块方式不一样,所以与MPEG2不同,每一个宏块并不只是对应一个运动矢量. 而由于分块的复杂性和多样性,我们可以这样认为:每个4*4块都有一个运动矢量. 比如,对于一个P-skip宏块而言,尽管运动矢量只有一个,但我们认为该宏块的每个4*4块都有一个运动矢量.
在P帧中,为了处理方便,本人认为I宏块有运动矢量,其值为零. 在P帧中,有3种基本的宏块:I宏块,skip形式的P宏块和非skip形式的P宏块. 对于前面两种宏块,仅有唯一的运动矢量,因此提取其每个4*4块的运动矢量时,只需要把一个运动矢量重复16次就OK了,很简单,搞一个16次的循环就可以了,但对于非skip形式的P宏块则相对复杂,因为分块不同, 所以在写的时候要特别注意. 下面仅仅给出提取非skip形式的P宏块的运动矢量的代码: (该代码在readMotionInfoFromNAL函数中)
// first make mv-predictionSetMotionVectorPredictor (img, pmv, pmv+1, refframe, LIST_0, dec_picture->ref_idx, dec_picture->mv, i, j, 4*step_h, 4*step_v);for (k=0; k < 2; k++) { TRACE_STRING("mvd_l0"); img->subblock_x = i; // position used for context determination img->subblock_y = j; // position used for context determination currSE.value2 = k<<1; // identifies the component; only used for context determination dP->readSyntaxElement(&currSE,img,inp,dP); curr_mvd = currSE.value1; // vec就是运动矢量 vec=curr_mvd+pmv[k]; /* find motion vector */ // myFlag用作标记 // buffer数组用作保存运动矢量的x分量和y分量 // buffer[0]存x分量,buffer[1]存y分量 if(myFlag < 2) buffer[myFlag++] = vec; if(2 == myFlag) { // 一个运动矢量对应的块数为step_h * step_v for(ii=0; ii < step_h * step_v; ii++) {if(img->type == P_SLICE) // 保证是P帧(片){fprintf(myMV, "%-4d %-4d ", buffer[0], buffer[1]);} } myFlag = 0; } for(ii=0;ii<step_h;ii++) { for(jj=0;jj<step_v;jj++) { dec_picture->mv [LIST_0][i4+ii][j4+jj][k] = vec; currMB->mvd [LIST_0][j+jj] [i+ii] [k] = curr_mvd; } }}
经与H.264visa提取的结果进行对比,发现上面的代码提取的结果完全正确. OK, 到此为止,P帧运动矢量的提取总算大功告成.
- 如何利用JM8.6解码器提取码流中P帧宏块(所有4*4块)的运动矢量(考虑B帧,设x264编码的12帧为IDR BBPBBPBBPBP)
- 如何利用JM8.6解码器提取码流中P帧宏块(第一个4*4块)的运动矢量(考虑B帧,设x264编码的12帧为IDR BBPBBPBBPBP)
- 如何利用JM8.6解码器提取码流中P帧宏块的运动矢量(假设编码不用B帧,仅为IDR P P)
- 如何在JM8.6中设置编码帧类型为IDR B B P B B P B B P B B I B B P...?
- 如何在JM8.6代码的编码端提取残差(为简便起见,仅以I4x4宏块为例)
- 如何在JM8.6代码的编码端提取残差(为简便起见,仅以I4x4宏块为例)
- 如何用JM8.6将所有的帧都编码为I帧?
- I 帧,B帧,P帧,IDR帧的区别
- I帧 B帧 p帧 IDR帧的区别
- I 帧,B帧,P帧,IDR帧的区别
- I帧 B帧 p帧 IDR帧的区别
- I帧 B帧 p帧 IDR帧的区别
- I 帧,B帧,P帧,IDR帧的区别
- I帧 B帧 p帧 IDR帧的区别
- I帧 B帧 p帧 IDR帧的区别
- I 帧,B帧,P帧,IDR帧的区别
- I帧 B帧 p帧 IDR帧的区别
- 如何从JM8.6的编码端和解码端提取滤波前的像素值?
- Linux 常用命令——cd, pwd, mkdir, rmdir, PATH设置
- 添加删除windows的系统服务
- ucos-ii的任务控制块
- Powerdesigner数据库开发指南
- Unity动画事件
- 如何利用JM8.6解码器提取码流中P帧宏块(所有4*4块)的运动矢量(考虑B帧,设x264编码的12帧为IDR BBPBBPBBPBP)
- 基础文章7:chap15 进程通信之管道 补充
- STL algorithm之copy
- RPG游戏中阻碍半透明遮挡(C# XNA)
- java7 NIO2(6) watching service API
- 开源 免费 java CMS - FreeCMS-标签 infoList
- 磁盘分区
- Android Bundle类
- Python类