以下文字只是本人在学习H.264代码过程中一些心得体.doc

以下文字只是本人在学习H.264代码过程中一些心得体.doc

  1. 1、本文档共28页,可阅读全部内容。
  2. 2、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
  3. 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载
  4. 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
查看更多
以下的文字只是本人在学习H.264代码过程中的一些心得体会,限于本人水平有限,所以有错误的地方请阅读者谅解,并提出,大家共同讨论学习。 在这里,特别感谢H264乐园版主天之骄子及群里兄弟姐妹们的帮助! ? 说明: 红色表示函数 绿色表示函数中的参数 褐色表示函数内部的代码 ? 正文 本文主要讲述了一些H.264中后处理错误隐藏的知识,而且也集中在解码端实现,根据空域和时域不同的掩盖方法,文章分为两大部分,第一部分主要讲帧内掩盖,相对应的c文件是erc_do_i.c;第二部分主要讲帧间掩盖,相对应的c文件是erc_do_p.c,这一部分相对于帧内掩盖要复杂得多,也是本文的重点。下面,我们就从简到难,细细讲述其中的原理。 ? 第一部分:帧内误码掩盖(erc_do_i.c) 大家先对整个帧内误码掩盖有个大体的框架,请看下图,其中ercConcealIntraFrame ()是帧内的入口函数。 帧内的掩盖方式为像素平均权值,方法相对来说比较简单。下面,我们通过一个一个函数分析来了解帧内掩盖算法。 int ercConcealIntraFrame( frame *recfr, int32 picSizeX, int32 picSizeY, ercVariables_t *errorVar ) ? 函数功能简述:这是帧内掩盖的入口函数,被image.c中的exit_picture()函数所调用。这里, 没有太多的代码,只是做了坐标级之间的转换,并调用了concealBlocks()。 函数参数解释:frame *recfr 表示当前帧指针结构体,这个结构体包含了指向当前帧Y,U和V块的指针。 int32 picSizeX 表示一帧的宽度,当QCIF图像时,该值为176,当CIF图像时,该值为352。 int32 picSizeY表示一帧的高度,当QCIF图像时,该值为144,当CIF图像时,该值为288。 ercVariables_t *errorVar 表示包含了一些掩盖状态和信息的结构体。 注意点:1. ercVariables_t结构体中变量的含义(详看我的erc_api.c初探)。 2.不同基本单位之间的转换,我的意思是指以宏块为单位的横纵坐标转换成以8x8 块为单位的坐标之类的问题。 函数详述: 函数内部的动作比较简单,但是照顾到刚刚接触误码掩盖的朋友,在介绍第一个函数的时候,我更多的会讲一些变量的含义以及代码的操作习惯。这边我主要现讲两方面,一个就是errorVar-yCondition、errorVar-uCondition和errorVar-vCondition指的是什么?另外一个就是不同基本单位之间的转换。 在接收端,有一个宏块状态图的概念,它的作用就是记录一帧图像所有宏块的接收状态。如下图: ? 标记为ERC_BLOCK_OK的宏块表示正确接收,标记为ERC_BLOCK_CONCEALED的宏块表示错误的块但是已经被掩盖过,标记为ERC_BLOCK_CORRUPTED或ERC_BLOCK_EMPTY就表示错误接收或已经丢失的块。这样,我们在程序中就可以通过这张表来知道哪些块是需要进行误码掩盖的,而errorVar-yCondition、errorVar-uCondition和errorVar-vCondition这三个数组就是分别存放了YUV块的这种状态标志,但是这边需要注意的是,在程序中存放的时候,并不是以宏块为单位的,而是进一步将一个宏块分割成4个8x8的子块,存放的是这些子块的状态信息。当然,对于UV来说,不用分割,基本单位已经是8x8了。由此我们知道,接下去误码掩盖处理的过程中,并不是以整像素单位进行的,而是以8x8块为单位的。 进一步,我们现在应该明白为什么程序一开始对于YUV的lastRow和lastColumn所作的赋值。 //Y lastRow = (int) (picSizeY3); lastColumn = (int) (picSizeX3); ? //UV lastRow = (int) (picSizeY4); lastColumn = (int) (picSizeX4); 假设对于一个DCIF图像来说,picSizeX=176 picSizeY=144,作了处理后,对于Y块就被分割成22x18个8x8块,而对于UV块就被分割成11x9个8x8块。其实这个就是我所说的不同基本单位之间的转换。 明白了上面这两点,这个函数就理解了,下面就是调用了concealBlocks()。 static void concealBlocks( int lastColumn, int lastRow, int comp, frame *recfr, int

文档评论(0)

00625 + 关注
实名认证
内容提供者

该用户很懒,什么也没介绍

1亿VIP精品文档

相关文档