当前位置:首页 >> 信息与通信 >>

H.264代码与标准如何对应

H.264 代码与标准如何对应
总是有人说自己把代码和标准对应不起来。其实是因为你要么不知道标准各个章节讲的什 么,要么不知道代码中各个函数的功能,或者两者都不知道。今天再以 X264 的帧内编码为 例让大家体会一下读代码时该如何与标准对应。此贴是帖子“[原创 如何阅读代码 原创]如何阅读代码 原创 如何阅读代码”的延续, 因此采用的代码与编译环境设置与其一样,此处不再赘述。 上贴说过 Encode_frame 函数包含最核心的编码代码,那么我们现在就 F11 进去看看。 遇 到 的 第 一 个 函 数 是 x264_encoder_encode , 再 F11 进 去 , 执 行 到 x264_reference_update,它在干什么呢?顾名思义猜测一定是更新帧间参考要用到的一些 内存空间,因为我们现在还没有编码,所以 F11 进去后没执行什么操作就出来了。 继 续 F10 , 执 行 到 x264_frame_pop_unused 。 F11 跟 进 , 然 后 F10 , 发 现 它 走 了 x264_frame_new 的分支(x264_frame_pop 分支干什么用的呢?暂时先别管。跟着流程 走, 管多了就迷茫了) F11 跟进 x264_frame_new 发现通篇都是对变量结构体指针 frame , 里的成员变量执行 CHECKED_MALLOC,由此我们可以初步判断它是在为帧结构体分配 内存空间。 step out 跳出 x264_frame_pop_unused,F10 到 x264_frame_copy_picture,F11 进去 读读代码我们就知道这个函数的功能是将待编码图像从 pic_in 复制到 fenc->plane。继续 F10,到了 x264_frame_push,通过阅读该函数的代码我们知道它的功能是将当前帧结构 体 从 fenc 移 到 h->frames.next 中 。 后 面 的 函 数 x264_frame_init_lowres 、 x264_adaptive_quant_frame、x264_encoder_frame_end 都未被执行。既然没被执行,那 我们现在暂时就不管它们。 F10 到 x264_stack_align( x264_slicetype_decide, h ); x264_stack_align 顾名思义无非就 是平台优化方面考虑的对齐操作,因此这里我们要关心的是函数 x264_slicetype_decide, F11 我们会发现进不到 x264_slicetype_decide 里。怎么办呢?见下面第一个截图,将光 标点到 x264_slicetype_decide 上,点鼠标右键选择 go to definition,然后先在里面的第 一 行 代 码 下 断 点 ( 见 下 面 第 二 个 截 图 ), 然 后 再 按 F10 就 可 以 进 入 到 x264_slicetype_decide 函数了。该函数顾名思义是来决定当前 slice 的编码类型的,即到 底是 I 片还是 P 片或 B 片。通过浏览其代码,我们也会发现代码所做也正是这样。

step out 跳出 x264_slicetype_decide,继续 F10 执行到 x264_frame_push,这里实际要 执行两个函数,因为 x264_frame_push 的第二个参数是函数 x264_frame_shift,所以会 先执行它。 F11 首先进入的就是 x264_frame_shift, 然后 step out 跳出 x264_frame_shift, 继续 F11 就进入了 x264_frame_push,通过阅读这两个简短的函数的代码,我们知道它 们执行的操作是将当前编码帧结构体从 h->frames.next 移到 h->frames.current。 继续 F10, 又到了一个 x264_frame_shift 函数, F11 进去通过阅读代码我们可以知道该函 数的功能将当前帧结构体从 h->frames.current 移到 h->fenc(我有点奇怪,为什么 X264 要 这 么 麻 烦 地 把 一 个 变 量 移 来 移 去 呢 ? 一 次 搞 定 不 行 么 ? ) 继 续 F10 , 到 了 。 x264_reference_reset,其功能顾名思义,也有英文注释,具体有什么用,现在我还不知道, 暂时不管吧。 继续 F10,到了 x264_reference_build_list,顾名思义,参考列表构建,在 JM 里叫做参 考列表初始化(JM86 对应的函数是 init_lists) 。参考列表初始化的作用即构建帧间编码图 像所需要用到的参考图像列表。那么如何初始化呢?如果大家记得 H.264 标准的各个章节 的功能,那么就该知道 200503 版的 8.2.4 小节正是讲的这部分内容。这样这个函数就与 标准的内容对应起来了。 至于通过代码是如何实现的, 先看懂了标准的这个部分再来读这个 函数的代码吧。

继续 F10,到了 x264_ratecontrol_start,顾名思义进行码率控制的一些准备工作。 继续 F10,到了 x264_slice_init,顾名思义片初始化,做了哪些工作呢?F11 进去执行了 分支 x264_slice_header_init,通过浏览其代码,我们发现通篇都是对结构体指针 sh 内的 成员变量的赋值操作。后面的 x264_macroblock_slice_init 函数在干什么,大家自己 F11 进去看,看不懂没关系,反正就是给一些变量赋初值嘛。继续 F10,到了 bs_init,顾名思 义是对码流相关的变量进行初始化,因为 bs 就是 bit stream 嘛。 继续 F10,到了 if( i_nal_type == NAL_SLICE_IDR && h->param.b_repeat_headers ),注 意前面的英文注释 /* Write SPS and PPS */,意思就是这里在向码流中写 SPS 和 PPS。 这里的三组函数,顾名思义第一组是在写 SEI、第二组是在写 SPS、第三组是在写 PPS。 那么如何写码流呢?当然是要遵循语法表了。 下面以写 SPS 为例简要说明一下, 如果大家 记得 H.264 标准的各个章节的功能,那么就该知道 200503 版的 7.3.2.1 小节就是 SPS 语法表。因为 7.3.2.1 规定了 SPS 在码流中的第一个语法元素是 profile_idc,因此当我 们 F11 进 入 x264_sps_write 的 时 候 会 发 现 该 函 数 第 一 行 代 码 正 是 在 写 sps->i_profile_idc,标准规定 SPS 第二个语法元素是 constraint_set0_flag,因此该函数 的第二行代码就是在写 sps->b_constraint_set0,其他同理。这里说的是写的顺序,那么写 的 方式 是什 么呢 ?H.264 中 的 熵 编码 方式 细分 起来 有很 多, 每个 语法 表的 最后 一列 descriptor 规定的就是对应的语法元素采用哪种熵编码方法。例如:profile_idc 是 u(8), 因此它采用 8 位无符号整数编码;constraint_set0_flag 是 u(1),因此它采用 1 比特无符 号整数编码。 各种熵编码方法在 200503 版 7.2 小节最后都有说明, 此处不再赘述。 好了, 我们知道了各个语法元素采用什么方式编码, 自然也就知道了代码中各个熵编码函数对应的 是什么编码方式。例如:对 profile_idc 编码采用的是 bs_write 函数,当然这个函数的功 能就是无符号熵编码了, i_id 编码采用的是 bs_write_ue 函数, 对 当然这个函数的功能就 是 ue(v)——无符号哥伦布编码。其他同理。其实这些我在帖子“[原创 如何读标准和代码 原创] 原创 如何读标准和代码” 中已经讲过了。 顺便提一下, 对码流的读写操作都要依据语法表所定义的语法元素顺序和熵编码类型。 上面 讲的是编码的具体例子, 解码的具体例子我以前用 JM 讲过, 参考帖子“如何结合标准看 JM 如何结合标准看 代码( 代码( JM86)”。好了,继续 F10,到了 x264_slices_write。F11 进入,再 F10,到了 ) x264_stack_align( x264_slice_write, h );我们关心的是 x264_slice_write,进入该函数,方 法在上面已经说过了。x264_slice_write 第一个函数为系统函数 memset,下一个为 x264_nal_start,其功能看下代码就知道是在设置将要写入码流的 NALU 的第一个字节的 值。第二个函数 x264_slice_header_write 顾名思义是在向码流中写入片头。如果大家记 得 H.264 标准的各个章节的功能,那么就该知道 200503 版的 7.3.3 小节就是片头的语 法表。写码流的过程与上面 SPS 的过程同理,此处不再赘述。 F10 到了 while 循环,顾名思义根据 while 循环的循环条件猜测一下该 while 循环的功 能, 肯定就是循环对整个图像的每个宏块一次编码了。 要验证一下猜测很简单, while 循 在 环体的第一行下断点,按一次 F5 就观察一下 mb_xy 变量的值的变化情况。另外还有个 信息说明了这一点,h->sh.i_last_mb 变量的值刚好等于待编码图像的总宏块数。 F10 到了 x264_fdec_filter_row,顾名思义猜测该函数的功能是去块滤波。如果大家记得 H.264 标准的各个章节的功能,那么就该知道 200503 版的 8.7 小节正是讲的这部分内

容。要读懂这个函数的代码就先学习一下 8.7 小节吧。 F10 到了 x264_macroblock_cache_load,通过浏览代码我们知道是在对一些变量赋值, 各 个 变 量 的 含 义 顾 名 思 义 。 这 也 属 于 编 码 前 的 准 备 工 作 。 继 续 F10 到 了 x264_macroblock_analyse,看见英文注释了吧?不用我们顾名思义就知道它的功能了,是 在进行模式选择。F11 进入该函数。第一个被调用的函数是 x264_ratecontrol_qp,顾名思 义获取当前宏块 QP。第二个被调用的函数是 x264_mb_analyse_init,F11 进去后发现只 有非 I 片才进行一些操作,那暂时就不管它。 F10 到了 x264_mb_cache_fenc_satd,F11 进去。一开始是个 4*4 的双重循环。我们现 在是在对一个宏块进行操作,这里又出现 4*4 的循环,那么很明显了这个双重循环肯定是 在计算每个 4*4 的块,下面的 2*2 的双重循环肯定是在计算 8*8 的块。因为宏块的尺寸 是 16*16 嘛,宽高分成 4 份不正好是 4*4,分成 2 份不正好是 8*8 么?做视频的人应 该对 4、8、16 等常用的数字敏感。先分析第一个 4*4 的双重循环。注意,for 循环里的 h->pixf.satd 和 h->pixf.sad 都是函数指针,因此要用 F11 跟进。h->pixf.satd 的两个输入 是 zero 和 fenc,跟进之后的函数 pixel_satd_wxh 在计算他们之差,然后作 Hadamard 变换,然后计算 SATD。由此可以猜测 fenc 里存放的是原始待编码宏块(到底是不是呢? 读者自己反回去找到 h->mb.pic.p_fenc[0] 被赋值的地方看看就知道了) 。后面代码的功能 类似了,不重复叙述。总的来说,x264_mb_cache_fenc_satd 这个函数就是计算原始待编 码宏块 4*4 和 8*8 的 STAD。算来做什么?暂时还不知道。 step out , 跳 出 x264_mb_cache_fenc_satd 函 数 , 继 续 F10 , 到 了 x264_mb_analyse_intra,F11 进入。F10 到了 predict_16x16_mode_available,顾名思 义并结合该函数代码,可以确定它是在检查当前宏块有几种可用的 16*16 帧内预测模式。 继续 F10 到了 for 循环 for( i = 0; i < i_max; i++ ),其循环条件 i_max 是函数 predict_16x16_mode_available 的返回值,那么很显然这个 for 循环是在循环计算可用预 测模式了。继续 F10,进循环体到了 h->predict_16x16[i_mode],这又是个函数指针,顾 名思义并结合改函数代码,可以确定它是在取得 16*16 块当前预测模式下的帧内预测块。 如果大家记得 H.264 标准的各个章节的功能,那么就该知道 200503 版的 8.3.3 小节正 是讲了 16*16 块的各种预测模式下如何进行帧内预测的。要读懂这个函数的代码就先学习 一下 8.3.3 小节吧。继续 F10,到了 h->pixf.mbcmp[PIXEL_16x16],又是个函数指针, 其功能大家自己跟进吧。 for 循环完成后就把 16*16 块的最佳预测模式计算出来并存储 该 起来了。 继续 F10,到了帧内 4*4 的预测模式选择部分。for 循环 for( idx = 0;; idx++ ),idx 是什 么?因为这是帧内 4*4 预测,所以我们很自然应该联想到 idx 就应该是 16 个 4*4 块的 编号,这个决定了 16 个 4*4 块的处理顺序,这个顺序可不是乱来的哦,200503 版标准/ 图 6-10 对顺序做了规定。继续 F10,到了 x264_mb_predict_intra4x4_mode 顾名思义 并结合该函数代码可以确定它是在获得最可能预测模式,如果大家记得 H.264 标准的各个 章节的功能,那么就该知道 200503 版的 8.3.1.1 小节正是讲的这部分内容。要读懂这个 函数的代码就先学习一下 8.3.1.1 小节吧。继续 F10 到了 predict_4x4_mode_available 跟上面 16*16 块类似,功能顾名思义就不多说了。继续 F10,进入第二个 for 循环 for( ; i<i_max; i++ ),一看就知道该 for 循环跟上面 16*16 块同理是在计算当前 4*4 块的最佳 预测模式。继续 F10,进入循环体到了 h->predict_4x4[i_mode] 顾名思义并结合该函数代

码可以确定它是在取得当前 4*4 块在当前可用预测模式下的帧内预测块,如果大家记得 H.264 标准的各个章节的功能,那么就该知道 200503 版的 8.3.1.2 小节正是讲的这部分 内 容 。 要 读 懂 这 个 函 数 的 代 码 就 先 学 习 一 下 8.3.1.2 小 节 吧 。 继 续 F10 , 到 了 h->pixf.mbcmp[PIXEL_4x4],也跟上面 16*16 块类似,功能顾名思义。 继续 F10, 第二个 for 循环执行完后就把当前 4*4 块的最佳预测模式计算出来并存储起来 了,到了函数指针 h->predict_4x4[a->i_predict4x4[idx]],很显然是在取得当前 4*4 块的最 佳预测模式下的预测块了。算来干什么?从 H.264 帧内宏块编码的原理上我们知道帧内预 测要以相邻块的重建值为参考,不先计算预测块,残差从哪里来?不得到残差,又哪里得到 重建呢?(所以这里也体现了,读代码前要对编码原理和框架熟悉,否则你咋能明白这里为 什么要取得预测块呢?) 。继续 F10,到了 x264_mb_encode_i4x4,顾名思义并联想帧内 编码原理和框架,我们猜测它是在进行当前 4*4 块的重建。F11 进去验证一下我们的猜测 是 否 正 确 。 x264_mb_encode_i4x4 函 数 里 依 次 执 行 了 h->dctf.sub4x4_dct 、 x264_quant_4x4、h->zigzagf.scan_4x4、h->quantf.dequant_4x4、h->dctf.add4x4_idct, 各函数功能顾名思义, 的确验证了我们对 x264_mb_encode_i4x4 这个函数的功能的猜测。 那么这些函数为什么要以这些顺序调用呢?因为编码原理和框架就是这样(这也再次体现 了,读代码前要对编码原理和框架熟悉) 。 step out,跳出 x264_mb_analyse_intra 函数,继续 F10,到了 x264_intra_rd,F11 跟 进。 继续 F10, 到了函数 x264_analyse_update_cache, 顾名思义无法猜测其功能, F11 跟 进之后发现它只调用了一个函数 x264_mb_analyse_intra_chroma, 这个函数又是什么功能 呢?留给读者自己去跟进吧。step out,跳出 x264_analyse_update_cache 函数,继续 F10,到了 x264_rd_cost_mb,顾名思义猜测是进行 RDO 模式选择。这种方法的失真测 度 通 常 是 使 用 SSD , 即 原 始 像 素 与 重 建 像 素 的 误 差 平 方 和 。 那 么 如 果 我 们 对 x264_rd_cost_mb 的功能猜测正确, 其函数中必然有编码宏块的代码和计算 SSD 的代码。 F11 跟进去验证我们的猜测, x264_rd_cost_mb 里的确调用了 x264_macroblock_encode 和 ssd_mb。这两个函数是否是在执行编码和计算 SSD 的功能呢?留给读者自己去验证 吧。提醒一句,X264 在这里用的失真测度不仅仅是 SSD,另外还有什么成分,读者自己 去 跟 踪 ssd_mb 函 数 。 x264_rd_cost_mb 函 数 最 后 执 行 的 函 数 是 x264_macroblock_size_cavlc,顾名思义是在对当前宏块进行熵编码了。为什么要熵编码, 因为 RDO 的率失真准则中要用到编码比特数啊。 step out,跳出 x264_rd_cost_mb 函数,后面的代码不说大家也知道了。step out,跳出 x264_intra_rd 函数,该函数下面的 6 行代码(见下图)的功能大家得弄清楚。因为算了 这么多模式,这么多代价,最后编码到底选哪个模式呢?答案就这里了。

step out,跳出 x264_macroblock_analyse 函数,到了 x264_macroblock_encode,顾名 思义并结合编码流程可以确定这里调用这个函数就是在用最终选定的那个最优的模式对当 前宏块进行实际编码了。继续 F10,到了 x264_bitstream_check_buffer,顾名思义猜测是 进行写码流前的一些准备工作。继续 F10,到了 x264_macroblock_write_cavlc,顾名思 义并联想编码流程,很明显是在将最后的编码结果写入码流了。 至此,一个宏块帧内编码的过程就剖析完了。相信大家看完这么长的帖子之后,应该对我以 前提出的学习建议中的两点有了深刻体会:1、读代码前一定要熟悉编码原理和框架;2、 弄清楚标准各个章节讲的什么内容。 当然这也是怎么看标准, 怎么用标准的问题——先很粗 略地了解各个章节是讲的什么,等到需要详细了解其内容时候再去细读相关章节。当然,C 语言功底在读代码过程中也是必须的,否则像函数指针这些东西你都搞不清楚怎么回事。 有了这个实际的例子,切身的体验,再回头去看看我和别人以前总结的学习方法的帖子,相 信你会有更深的体会。最后还要说一句:别人不可能为你做所有的事,很多还是要靠自己努 力!


相关文章:
H.264代码与标准如何对应.doc
H.264代码与标准如何对应 - 此文档介绍了H.264代码与标准对应的方法,对
H.264与其它标准的比较_图文.doc
H.264 是 ITU-T VCEG 和 ISO/IEC MPEG 的联合小组(JVT:Joint Video Team)...H.264标准简介 8页 免费 H.264代码与标准如何对应... 6页 1下载券 H...
H.264 标准详解.doc
一、H.264 视频压缩系统 H.264 标准压缩系统由视频编码层(VCL)和网络提取层(...亮度信号的 1/4 像素精度对应于色度部分的 1/8 像素的运动矢量,因此需 要对...
H.264标准的特点及应用.doc
一般情况下进行预测的基本单元是宏块(MacroBlock,MB),即一个宏块对应 一个运动矢量。H.264 视频编码标准定义了 7 种块划分模式,目的是为了做到更为精确的块匹配...
浅谈视频会议中H.264编码标准的技术发展.doc
浅谈视频会议中H.264编码标准的技术发展_计算机软件应用_IT/计算机_...(于 是每个宏块包含4个帧间预测方块所对应的4个运动矢量) ,重叠块运动...
H264标准详解.doc
H264标准详解 - H.264 标准详解 JVT(Joint Video Team,视频联合工作组)于 2001 年 12 月在泰国 Pattaya 成立。它由 ITU-T ISO ...
H.264标准_图文.ppt
H.264标准_信息与通信_工程科技_专业资料。新电视技术 The Technology of New ...基于内容的编码:先把视频帧分成对应于不同物体的区域,然后对其编码。 具体说来...
纵览最新视频编码标准H.264-AVC.doc
纵览最新视频编码标准H.264-AVC_互联网_IT/计算机_专业资料。纵览最新视频编码标准 H.264/AVC 作者:王祖寿 王彩云 H.264/AVC 是 ITU-T VCEG 和...
h.264标准简介.doc
h.264标准简介 - H.264 标准简介 H.264/MPEG-4 AVC H.264,或称 MPEG-4 第十部分,是由 ITU-T 视频编码专家组(VCEG)和 ISO/IEC 动态图 ...
第五讲H264压缩编码标准(一).ppt [兼容模式]_图文.pdf
第五讲H264压缩编码标准(一).ppt [兼容模式]_信息与通信_工程科技_专业资料...级:每一型设置不同的参数如 取样速率、图像规格、编码 比特率等,成为对应编...
H264视频压缩编码标准_图文.ppt
变换与量化 SLIDE 2 H.264/AVC编解码器 H.264编解码器特点 H.264并不明确地规定一个编解码器如何实现, 而是规定了一个编码的视频比特流的句法, 和该比特流...
第五讲H264压缩编码标准(二).ppt [兼容模式]_图文.pdf
H.264标准支持52个量化步长,对应于不同的 量化参数(QP)如表所示,QP值每增加6, Qstep值增加一倍。量化步长取值范围很广, 这就为编码中兼顾比特率和编码质量...
新一代视频压缩编码标准H264学习心得.doc
新一代视频压缩编码标准H264学习心得_计算机软件及应用_IT/计算机_专业资料。新...这时候就称为加权均值滤波;对于中值滤波,对应的像素点的灰 度值用 窗口内的...
从H_261到H_264看视频编码标准的进展_图文.pdf
H_261到H_264看视频编码标准的进展_信息与通信_工程科技_专业资料。3&%&!...中对宏块( XY )的,即一个宏块对应于 + 个亮度块 # 个色度块, 可以表示...
一种基于H264编码标准的快速运动估计算法_图文.pdf
黧论点算漆 ELECTRONIC 电子测量技术 MEASUREMENTTECHNoLDGY 第32卷第8期2009年8月 一种基于H264编码标准的快速运动估计算法张纪铃1 夏超z 黄富良1 (1-湛江91388...
H.264视频压缩标准_图文.pdf
2标准相比, H.264 编码器可使数字视频文件的大小分 别减少80% 和50%以上。...每个等级都规定了从QCIF 到HDTV 等各种 分辨率所对应的比特率编码速率 (每秒...
H.264兼容的全景视频编码方法_图文.pdf
P帧,通过中间帧插入获得B帧,从而将原 始视频“间接地”编码标准H.264码流...部分像素,与 后一帧内TT.部分像素完全相同。这两部分像素相 对于相邻帧内对应...
H264学习指南.txt
分三个阶段学习 1、第一个阶段: 学习H.264,首先要把最基本最必要的资料拿在...这时你再来看标准文档就有了针对性。也因为能将标准文档和代码对应起来,从而看...
如何在FPGA上实现H.264_AVC视频编码标准.pdf
如何在FPGA上实现H.264_AVC视频编码标准如何在FPGA上实现H.264_AVC视频编码标准隐藏>> 通信与计算机■ Xilinx公司 WilsonC.Chung 在 FPGA 上实现 H.264/AVC 视...
H264_图文.pdf
H264_信息与通信_工程科技_专业资料。技术标准 H.264压缩编码标准 Co
更多相关标签: