2014-09-26 215 views
1

我试图在Android中显示一个YUV视频文件,我有几个YUV视频文件正在使用。Y'UV420p(和Y'V12或YV12)RGB888转换

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

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

当我尝试在Android中播放相同内容时,未能正确再现颜色分量。图像几乎呈黑白色,图像帧之间有几条彩色痕迹。

要在Android中显示视频,我所做的是逐帧阅读yuv视频文件,其中每个帧的大小为(w * h * 1.5)个字节,并使用所提到的代码获取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; 
} 

使用上述我构造的位图中的ImageView显示从mehod convertYUV420_NV21toARGB8888获得的RGB []。

我试过各种其他代码来将yuv []转换为rgb [],但结果是一样的。此外,我尝试使用Android的YUVImage API,结果是一样的。我知道上面的代码是将Y'UV420sp(NV21)转换为ARGB8888,但是没有得到YUV to RGB和Y'UV420sp(NV21)与ARGB8888转换之间的区别(就在前面的链接下面)。 。)

请任何人都可以帮我....

回答

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)。

相关问题