Android 上的 libyuv::ConvertToI420 有问题?

Issue with libyuv::ConvertToI420 on Android?

我设置了 onPreviewFrame 回调。这会得到一个包含 NV21 数据的 byte[]。我已将预览大小设置为 176*144。当设备处于横向模式时,176*144 尺寸的 byte[] 是完美的,但是当设备处于纵向模式时,我仍然得到相同尺寸的 byte[]。

我想将byte[]旋转90度得到144*176尺寸的byte[]

那么问题来了,如何旋转数据,而不仅仅是预览图像? Camera.Parameters.setRotation 只影响拍照,不影响录像。 Camera.setDisplayOrientation具体说只影响显示预览,不影响帧字节:

This does not affect the order of byte array passed in      
onPreviewFrame(byte[], Camera), JPEG pictures, or recorded videos.

查看各种帖子后,我发现 this 一篇声明使用 libyuv 中的 ConvertToI420。

现在我已经编译了 libyuv 并能够调用 libyuv::ConvertToI420 方法,但是我得到的结果 I420 在颜色和显示线条等方面都一团糟......但是我得到的尺寸现在是144 * 176,可以查看图像here

我使用的代码片段如下。

    //sourceWidth = 176 and sourceHeight = 144  
    unsigned char I420M = new unsigned char[(int)(sourceWidth*sourceHeight*1.5)];

    unsigned int YSize = sourceWidth * sourceHeight;
    // yuvPtr is the NV21 data passed from onPreviewCallback (from JAVA layer)
    const uint8* src_frame = const_cast<const uint8*>(yuvPtr);
    size_t src_size = YSize;

    uint8* pDstY = I420M;
    uint8* pDstU = I420M + YSize;
    uint8* pDstV = I420M + (YSize/4);

    libyuv::RotationMode mode;
    if(landscapeLeft){
        mode = libyuv::kRotate90;
    }else{
        mode = libyuv::kRotate270;
    }


    uint32 format = libyuv::FOURCC_NV21;
    int retVal = libyuv::ConvertToI420(src_frame, src_size,
              pDstY, sourceHeight,
              pDstU, (sourceHeight/2),
              pDstV, (sourceHeight/2),
              0, 0,
              sourceWidth, sourceHeight,
              sourceWidth, sourceHeight,
              mode,
              format);

我不想裁剪图像,只需将其旋转 90 (clockwise/anticlockwise) 附件图像适用于 kRotate90。

任何人都可以指出我哪里出了问题,我强烈怀疑它是否对传递给 ConvertToI420 方法的参数做了什么。

感谢任何帮助。

我已经弄清楚出了什么问题。上面的代码片段运行良好,I420M 包含 144*176 尺寸的旋转 YUV。

问题出在我将 I420M 转换为 jbyte[] 并将其传回 Java 层的方式。

使用 sourceWidth 而不是 sourceHeight int retVal = libyuv::ConvertToI420(src_frame, src_size, pDstY, sourceWidth, pDstU, (sourceWidth/2), pDstV, (sourceWidth/2), 0, 0, sourceWidth, sourceHeight, sourceWidth, sourceHeight, mode, format);