vp8/common/reconinter.c
):
void vp8_copy_mem16x16_c(unsigned char *src, int src_stride, unsigned char *dst,
int dst_stride) {
int r;
for (r = 0; r < 16; ++r) {
memcpy(dst, src, 16);
src += src_stride;
dst += dst_stride;
}
}
(8x8 和 8x4 版本也存在于同一源文件中。)
它将 16 个字节从
src
复制到 dst
16 次,但同时,它向 stride
和 src
添加自定义 dst
。如果没有计算机图形和 DSP 方面的先验知识,我对这些功能感到非常困惑:在 stride
和 src
中支持自定义 dst
有什么意义?使用此类函数而不是仅仅将整个 16 x 16 字节复制在一起有哪些示例或好处?
非常感谢!
更新:为了明确起见,当矢量优化版本在目标平台上不可用时,
vp8_copy_mem16x16_c
在构建阶段被重新定义为vp8_copy_mem16x16
。
如果我理解正确的话,你的问题是步幅的用途是什么。
在
libvpx
的背景下,它有两个大的用例:
对源流中的各个块进行编码。如果您有整个图像,则可以使用等于
<image width + image stride - block width>
的源步幅和 0 的目标步幅(或算法中所需的任何内容)来有效地提取块。编辑:要明确的是,大多数编码和解码视频操作都在正方形或矩形块上进行。 JPEG 就是一个例子,但所有 mp4 和 VP8/9 操作也是基于块的。这是一个非常基本、非常常用的操作。
虽然大多数 API 允许非二次幂图像、高效内存访问,尤其是在 GPU 上,但几乎需要它(或者至少需要一些对齐填充)。源和目的地都可以有不同的此类要求,并且两个跨步参数都在这里发挥作用。
然而,一般来说,步幅还有第三种用例:精灵块传输。与上面的第一点类似,您可以通过使用步幅复制内存来非常有效地将精灵传输到纹理(和/或屏幕,如果没有双缓冲)。
这是试图在两个图像之间复制一个 16x16 的方块(即二维数组)。
预期用途是将
src
和dst
设置为块的起始位置,并将stride
设置为整个图像的宽度。