0

好的,我对大学课程的C知之甚少,所以我希望你能理解我的问题。我使用 FFmpeg 库 for android 所以我只需要了解他们的 C 代码中的一些东西。

所以,我有这个结构:

typedef struct AVFrame {
#define AV_NUM_DATA_POINTERS 8
    /**
     * pointer to the picture/channel planes.

     */
    uint8_t *data[AV_NUM_DATA_POINTERS];

  .......(some more types)
}

仅此而已,但是当我查看其他文件中的函数时-我看到了下一行,并且感到困惑,

函数外:

static AVFrame  *picture_hq;

在函数内部:

picture_hq->data[0][y * picture_hq->linesize[0] + x] = native_video_frame_data[0];

不要关注未知的参数,我只是不明白上面的结构中的一维数组data[]如何变成二维数组data[0][bla bla bla..]?

它与 uint8_t 类型有关吗?

4

2 回答 2

0

阅读声明的方式是这样的:

uint8_t *data[AV_NUM_DATA_POINTERS];
        ^   ^                    ^
        |   |                    |
        |  1. the identifier...  |
        |                        |
        |           2. ... is an array...
        |
  3. ...of pointers.

重要的是数组下标运算符[]比解引用运算符具有更高的优先级*。因此,当编译器看到

data[1][2]

它将执行以下操作:

  1. 它查找符号data。这有一个数组类型uint8_t *()[]

  2. 数组衰减为指向第一个元素的指针uint8_t **

  3. 第一个数组下标运算符[1]通过对衰减指针执行指针运算来访问数组的第一个元素。等价于*(data + 1),结果是类型uint8_t *

  4. 第二个数组下标运算符[2]对从数组中读取的指针执行相同的操作*(*(data + 1) + 2),产生 type 的结果uint8_t

于 2013-10-22T08:14:21.870 回答
0

数据数组不是 8 个 uint_8 的数组,而是 8个指向uint_8 的指针的数组。注意数据前的星号。- 类型是 uint8_t* - 即指向uint8_t 的指针。

uint8_t *data[AV_NUM_DATA_POINTERS];

在 C 中,数组类似于指针,因此如果您有一个指向 uint8_t 的指针,您可以将其指向的地址以及后续地址作为数组访问。

您确实需要正确分配它,否则您将遇到分段错误或一些您不期望的数据 - 但这可能由您的库正确处理。

C 还对指针使用特殊算术(指针算术)——所以指针的类型决定了元素之间的“间距”——所以如果你有一个指向 uint8_t 的指针,数组元素将被处理,每个元素距前一个 1 个字节。如果类型是 uint32_t,那么每个元素将是前一个元素的 4 个字节 - 以适应更大的类型。

您可以在此处找到有关 C 数组和指针算法的更多信息:

C 数组和指针算法

因此,由于 data[] 是指向 uint8_t 的指针数组,因此 data[0] 是指向 uint8_t 的指针。由于您可以将此指针视为 uint8_t 数组的开头,因此

picture_hq->data[0][y * picture_hq->linesize[0] + x] = native_video_frame_data[0];

从 data[0] 指向的地址访问 (y * picture_hq->linesize[0] + x) 偏移量,并将其视为 uint8_t。

于 2013-10-22T06:46:28.510 回答