3

下面是 FFMPEG 库中的两段代码,具体位于此处:libavcodec/h263data.h ( http://ffmpeg.org/doxygen/0.6/h263data_8h-source.html )。

我想更多地了解这两个段如何在编​​解码器库的更大上下文中运行。下面,在这些例子之后,我描述了我到目前为止的理解,并提供了两个更清晰的问题,我希望得到答案。

感谢您的任何帮助!

例 1

00035 /* intra MCBPC, mb_type = (intra), then (intraq) */
00036 const uint8_t ff_h263_intra_MCBPC_code[9] = { 1, 1, 2, 3, 1, 1, 2, 3, 1 };
00037 const uint8_t ff_h263_intra_MCBPC_bits[9] = { 1, 3, 3, 3, 4, 6, 6, 6, 9 };

和示例 2

00039 /* inter MCBPC, mb_type = (inter), (intra), (interq), (intraq), (inter4v) */
00040 /* Changed the tables for interq and inter4v+q, following the standard ** Juanjo ** */
00041 const uint8_t ff_h263_inter_MCBPC_code[28] = {
00042     1, 3, 2, 5,
00043     3, 4, 3, 3,
00044     3, 7, 6, 5,
00045     4, 4, 3, 2,
00046     2, 5, 4, 5,
00047     1, 0, 0, 0, /* Stuffing */
00048     2, 12, 14, 15,
00049 };

我知道我们正在研究影响正交方案的较大压缩算法库的一小部分,这些算法预测“正确”或更恰当地说是“原始”运动间或运动内矢量,在此处表示在名称“ff_h263_inter_MCBPC_code”、“ff_h263_intra_MCBPC_code”和“ff_h263_intra_MCBPC_bits”中。

我知道这两个代码块中的名称划分了以下内容:

  1. const指的是一个只读变量的声明,它仍然可以像任何其他变量一样在其范围之外使用。以另一种方式表述的不同之处在于,该数组中的值不能被任何在其自身之外调用的方法更改。

  2. uint8_t是长度为 8 位的无符号整数,是 C99 标准的一部分,称为“固定宽度整数类型”。这种特殊类型,“精确宽度整数”,计算最小值为 0 和最大值为 8 的有符号或无符号位的范围(即 8x8 宏块),它保证了跨平台的这个位数,无论是,比方说,32 位或 64 位操作系统。(我在这里研究了这一点:“固定宽度整数类型” http://en.wikipedia.org/wiki/Stdint.h#stdint.h

  3. MCBPC指的是色度的宏块类型和编码块模式,但我不完全理解这些特定数组在文件和 libavcodec 的方案中的确切作用。我对概念的理解比这些示例中定义的详细信息/数值要多。

因此,考虑到这一点,这就是我想了解的更多信息:

  1. 到目前为止,我的理解是否有任何偏差?

  2. 有人可以帮助分解每个代码段的作用吗?更具体地说,这些数字值在每种情况下表示/做什么?

  3. “填塞”是什么意思?

再次感谢您在这件事上的任何帮助!

4

1 回答 1

1

让我们从这对数组开始,因为它更短:

const uint8_t ff_h263_intra_MCBPC_code[9] = { 1, 1, 2, 3, 1, 1, 2, 3, 1 };
const uint8_t ff_h263_intra_MCBPC_bits[9] = { 1, 3, 3, 3, 4, 6, 6, 6, 9 };

FFmpeg 将这些输入到 ituh263dec.c 中的这个函数中:

INIT_VLC_STATIC(&ff_h263_intra_MCBPC_vlc, INTRA_MCBPC_VLC_BITS, 9,
         ff_h263_intra_MCBPC_bits, 1, 1,
         ff_h263_intra_MCBPC_code, 1, 1, 72);

FFmpeg 使用这些位/代码数组对来设置可变长度代码 (VLC),也就是霍夫曼代码。在这种情况下,该函数将初始化一个名为 的数据结构ff_h263_intra_MCBPC_vlc。每个数组中有 9 个项目的事实意味着有 9 个可能的值 (0..8)。第一项是代码 1 和 1 位长。第二项也是代码 1,但长度为 3。这意味着,在二进制中,它是 001。让我们将其展开:

value  code  bitcount  bits
  0      1       1     1
  1      1       3     001
  2      2       3     010
  3      3       3     011
  4      1       4     0001
  5      1       6     000001
  6      2       6     000010
  7      3       6     000011
  8      1       9     000000001

解码器将能够利用ff_h263_intra_MCBPC_vlc数据结构,将比特流输入其中并取回一个值,范围从 (0..8),然后从流中消耗介于 (1..9) 位之间的某个值。

至于您的问题:“填充”是什么意思?,请注意,在代码和位数组中,都有为 0 的条目——即代码为 0,并且它的位长为 0。这些是无效值。由于这些数组有 28 个值,范围为 (0..27)。这意味着无法表示 21、22 和 23。

我希望我已经回答了您关于 FFmpeg 如何处理这些数组的机制的问题(我希望这是您查询的主要内容)。

美图时间:

Huffman/VLC 代码通常使用树来说明。从顶部开始,0 向左移动,1 向右侧移动。当您到达叶节点时,您已经解码了一个值。

用于色度 VLC 表的 H.263 帧内宏块编码块模式

于 2013-04-05T05:32:23.643 回答