android中的NV21到I420

android中的NV21到I420,android,android-camera,yuv,Android,Android Camera,Yuv,编辑:我遇到了一个libyuv,它可以进行NV21到I420的转换,但我真的不知道如何调用它 // Convert NV21 to I420. Same as NV12 but u and v pointers swapped. LIBYUV_API int NV21ToI420(const uint8* src_y, int src_stride_y, const uint8* src_vu, int src_stride_vu, uint8* d

编辑:我遇到了一个libyuv,它可以进行NV21到I420的转换,但我真的不知道如何调用它

// Convert NV21 to I420.  Same as NV12 but u and v pointers swapped.
LIBYUV_API
int NV21ToI420(const uint8* src_y, int src_stride_y,
           const uint8* src_vu, int src_stride_vu,
           uint8* dst_y, int dst_stride_y,
           uint8* dst_u, int dst_stride_u,
           uint8* dst_v, int dst_stride_v,
           int width, int height) 
我将从摄像头回调中获得的NV21字节[]传递到jni层,并将其转换为无符号字符*,如下所示

int yuvBufLen = env->GetArrayLength(yuvNV21);
unsigned char* yuvNV21Buf = new unsigned char[yuvBufLen];
env->GetByteArrayRegion(yuvNV21, 0, yuvBufLen,reinterpret_cast<jbyte*>(yuvNV21Buf));

获取的帧数据是NV21格式的,我正在尝试将NV21转换为I420。

我无法使用我在问题中发布的方法,它一直崩溃

但多亏了彼得,我发现了这种转变,它对我来说非常有效

它只需要NV21和I420指针

unsigned char* yuvPtr; //NV21 data
unsigned char* I420 = new unsigned char[sourceWidth*sourceHeight*1.5]; //destination I420 pointer where the converted yuv will be stored 
NV21toI420(yuvPtr, I420, sourceWidth, sourceHeight);
仅此而已……

加上这一点(因为答案中的链接似乎已过期)。可以使用代码将YUV格式转换为NV21


所以我修改了这样的代码,将其转换为I420。现在mediaEncoder生成的视频可以正常工作。

为什么需要转换为I420?你们想做什么?开发视频会议应用程序,服务器需要I420格式。当我从Android传输NV21时,它在服务器上看起来失真了。像这样吗?完全相同..我的图像看起来像上面链接(第二幅图像)中显示的那样扭曲。。。发生这种情况是因为我的服务器将其视为I420,所以我必须将其转换为I420以使其正常工作..有没有办法将NV21转换为I420?如果我的格式正确,NV21是半平面的,而I420是平面的。所以这不是一个简单的交换U和V的问题。你必须从“所有U值,然后所有V值”转换为“交替U和V值”。
unsigned char* yuvPtr; //NV21 data
unsigned char* I420 = new unsigned char[sourceWidth*sourceHeight*1.5]; //destination I420 pointer where the converted yuv will be stored 
NV21toI420(yuvPtr, I420, sourceWidth, sourceHeight);