【问题标题】:Y'UV420p (and Y'V12 or YV12) to RGB888 conversionY'UV420p(和 Y'V12 或 YV12)到 RGB888 的转换
【发布时间】:2014-09-26 13:22:54
【问题描述】:

我正在尝试在 android 中显示一个 yuv 视频文件,我有一些正在使用的 yuv 视频文件。

This video yuv file video1(160*120 分辨率)是我从服务器捕获的原始 h264 数据,并使用 OpenH264 转换为 yuv 文件。

我用YUV Player Deluxe播放了上面的yuv视频文件,效果很好。

当我尝试在 Android 中玩同样的游戏时,颜色分量无法正确再现。图像几乎呈现为黑白,图像帧之间有一些颜色痕迹。 p>

为了在 Android 中显示视频,我所做的是逐帧读取 yuv 视频文件,其中每一帧的大小 = (w*h*1.5)bytes,并使用下面提到的代码从中获取 rgb 数组

public static int[] convertYUV420_NV21toARGB8888(byte [] data, int width, int height) {
int size = width*height;
int offset = size;
int[] pixels = new int[size];
int u, v, y1, y2, y3, y4;

// i along Y and the final pixels
// k along pixels U and V
for(int i=0, k=0; i < size; i+=2, k+=2) {
    y1 = data[i  ]&0xff;
    y2 = data[i+1]&0xff;
    y3 = data[width+i  ]&0xff;
    y4 = data[width+i+1]&0xff;

    v = data[offset+k  ]&0xff;
    u = data[offset+k+1]&0xff;
    v = v-128;
    u = u-128;

    pixels[i  ] = convertYUVtoARGB(y1, u, v);
    pixels[i+1] = convertYUVtoARGB(y2, u, v);
    pixels[width+i  ] = convertYUVtoARGB(y3, u, v);
    pixels[width+i+1] = convertYUVtoARGB(y4, u, v);

    if (i!=0 && (i+2)%width==0)
        i += width;
}

return pixels;
}

private static int convertYUVtoARGB(int y, int u, int v) {
int r = y + (int)(1.772f*v);
int g = y - (int)(0.344f*v + 0.714f*u);
int b = y + (int)(1.402f*u);
r = r>255? 255 : r<0 ? 0 : r;
g = g>255? 255 : g<0 ? 0 : g;
b = b>255? 255 : b<0 ? 0 : b;
return 0xff000000 | (r<<16) | (g<<8) | b;
}

使用上面的方法 convertYUV420_NV21toARGB8888 得到的 rgb[],我构建了一个位图显示在 ImageView 中。

我尝试了各种其他代码将 yuv[] 转换为 rgb[] 但结果是一样的。我也尝试使用 Androids YUVImage API,结果还是一样。

我知道上述代码是将 Y'UV420sp (NV21) 转换为 ARGB8888,但我没有得到 YUV to RGB 和 Y'UV420sp (NV21) 到 ARGB8888 转换之间的区别(就在上一个链接的下方.. ..)

谁能帮帮我....

【问题讨论】:

    标签: android h.264 yuv


    【解决方案1】:

    您的主要问题是您将输入数据视为 NV21 而不是 YUV。这两种格式的区别在于,在 NV21 格式中,色度 (U/V) 样本是交错的(即 VUVUVUVUVU...),而在 YUV 格式中,它们位于不同的平面中(即 UUUUU...VVVVV...)和另一个顺序所以这部分代码应该如下所示:

    u = data[offset+k  ]&0xff;
    v = data[offset+k + size/4]&0xff;
    

    并且循环中的 k 应该增加 1(而不是 2)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-08-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-02-17
      • 2017-06-19
      • 1970-01-01
      相关资源
      最近更新 更多