将NV21转换为NV12,旋转90度由libyuv?

时间:2016-07-21 09:21:40

标签: android camera libyuv

我正在开发Android相机应用程序。当我处理框架时,我遇到了一些麻烦。

在相机的 onPreviewFrame(byte []数据,相机相机)功能中,我设置数据的格式是 NV21 fromat,因为NV21是支持所有Android设备。

当我使用MediaCodec对帧进行编码时,KEY_COLOR_FORMAT为COLOR_FormatYUV420SemiPlanar( NV12 )。

所以我需要将NV21转换为NV12。

而且,框架旋转-90度,我想旋转回来,意味着向后旋转90度。

我是用java创建的:

    // 1. rotate 90 degree clockwise
// 2. convert NV21 to NV12
private byte[] rotateYUV420SemiPlannerFrame(byte[] input, int width, int height) {
//from:https://github.com/upyun/android-push-sdk/blob/7d74e3c941bbede0b6f9f588b1d4e7926a5f2733/uppush/src/main/java/com/upyun/hardware/VideoEncoder.java
    int frameSize = width * height;

    byte[] output = new byte[frameSize * 3 / 2];


    int i = 0;
    for (int col = 0; col < width; col++) {
        for (int row = height - 1; row >= 0; row--) {
            output[i++] = input[width * row + col]; // Y
        }
    }

    i = 0;
    for (int col = 0; col < width / 2; col++) {
        for (int row = height / 2 - 1; row >= 0; row--) {
            int i2 = i * 2;
            int fwrc2 = frameSize + width * row + col * 2;
            output[frameSize + i2 + 1] = input[fwrc2]; // Cb (U)
            output[frameSize + i2] = input[fwrc2 + 1]; // Cr (V)
            i++;
        }
    }

    return output;
}

该功能效果很好,但花费很长时间,超过50毫秒。

据我所知, libyuv 可以更快地处理YUV img,我想在我的Android相机应用程序中使用它。

在libyuv中,我发现三个功能可能有所帮助:

// Convert NV21 to I420.
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);

// Rotate I420 frame.
LIBYUV_API
int I420Rotate(const uint8* src_y, int src_stride_y,
               const uint8* src_u, int src_stride_u,
               const uint8* src_v, int src_stride_v,
               uint8* dst_y, int dst_stride_y,
               uint8* dst_u, int dst_stride_u,
               uint8* dst_v, int dst_stride_v,
               int src_width, int src_height, enum RotationMode mode);

LIBYUV_API
int I420ToNV12(const uint8* src_y, int src_stride_y,
               const uint8* src_u, int src_stride_u,
               const uint8* src_v, int src_stride_v,
               uint8* dst_y, int dst_stride_y,
               uint8* dst_uv, int dst_stride_uv,
               int width, int height);

使用这些功能,可能会起作用。但转换和旋转可能会花费更多的时间(我猜..)。

有没有办法通过使用更少的功能来实现我的目标?感谢。

我也找到了一些答案here,而不是我想要的答案。

0 个答案:

没有答案