ARM NEON优化图像转换

时间:2013-10-18 04:56:24

标签: image-processing arm neon

我正在应用NV12视频转换,这会改变视频的像素。在诸如Google Nexus 7 2013之类的ARM设备上,对于1024x512区域,使用以下C代码,性能非常差,为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是一个非常复杂的转换,因此优化这部分并不是很容易。

还有办法用给定的“from”表来固定每一帧计算的双循环吗?

1 个答案:

答案 0 :(得分:0)

您创建的FOUR查找表是原始图像的8倍吗?

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

交换i和j怎么样?

老实说,你的问题应该用[c]而不是手臂,霓虹灯或图像处理来标记。

由于你没有显示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]和 NOT image [x] [y]