0

我正在应用一个 NV12 视频转换,它会随机播放视频的像素。在诸如 Google Nexus 7 2013 之类的 ARM 设备上,使用以下 C 代码在 1024x512 区域的 30fps 时性能相当糟糕:

* 在视频开始时只进行一次预处理 *

//Temporary tables for the destination
for (j = 0; j < height; j++)
    for (i = 0; i < width; i++) {
        toY[i][j] = j * width + i;
        toUV[i][j] = j / 2 * width + ((int)(i / 2)) * 2;
    }

//Temporary tables for the source
for (j = 0; j < height; j++)
    for (i = 0; i < width; i++) {
        fromY[i][j] = funcY(i, j) * width + funcX(i, j);
        fromUV[i][j] = funcY(i, j) / 2 * width + ((int)(funcX(i, j) / 2)) * 2;
    }

* 在每一帧完成的过程 *

for (j = 0; j < height; j++)
    for (i = 0; i < width; i++) {
        destY[ toY[i][j] ] = srcY[ fromY[i][j] ];
        if ((i % 2 == 0) && (j % 2 == 0)) {
            destUV[ toUV[i][j] ] = srcUV[ fromUV[i][j] ];
            destUV[ toUV[i][j] + 1 ] = srcUV[ fromUV[i][j] + 1 ];
        }
    }

虽然只计算了一次,funcX/Y 是一个相当复杂的转换,所以优化这部分不是很容易。

有没有办法用给定的“从”表来固定在每一帧计算的双循环?

4

1 回答 1

0

您创建了 4 个 8 倍于原始图像的查找表?

您在最里面的循环中放置了一个不必要的 if 语句?

交换 i 和 j 怎么样?

老实说,您的问题应该以 [c] 而不是 arm、neon 或 image-processing 开头。

由于您没有展示 funcY 和 funcX 的作用,因此我可以给出的最佳答案是以下。(性能飙升。这是非常基础的东西)

//Temporary tables for the source
pTemp = fromYUV;
for (j = 0; j < height; j+=2)
{
    for (i = 0; i < width; i+=2) {
       *pTemp++ = funcY(i, j) * width + funcX(i, j);
       *pTemp++ = funcY(i+1, j) * width + funcX(i+1, j);
       *pTemp++ = funcY(i, j) / 2 * width + ((int)(funcX(i, j) / 2)) * 2;
   }
    for (i = 0; i < width; i+=2) {
       *pTemp++ = funcY(i, j+1) * width + funcX(i, j+1);
       *pTemp++ = funcY(i+1, j+1) * width + funcX(i+1, j+1);
   }
}

* Process done at each frame *
pTemp = fromYUV;
pTempY = destY;
pTempUV = destUV;
for (j = 0; j < height; j+=2)
{
    for (i = 0; i < width; i+=2) {
        *pTempY++ = srcY[*pTemp++];
        *pTempY++ = srcY[*pTemp++];
        *pTempUV++ = srcUV[*pTemp++];
    }
    for (i = 0; i < width; i+=2) {
        *pTempY++ = srcY[*pTemp++];
        *pTempY++ = srcY[*pTemp++];
    }
}

您应该避免(如果可能):

  • 访问多个内存区域
  • 随机内存访问
  • 循环中的 if 语句

你犯下的最严重罪行是 i 和 j 的顺序。(你不需要开始)

如果您访问坐标 x 和 y 处的像素,则它是 pixel = image[y][x] 而不是image[x][y]

于 2013-10-23T01:03:17.330 回答