1

我想从 NV12 交换 YUV 格式的 U 和 V 位

YYYYYYYY UVUV // each letter presents a bit

到 NV21

YYYYYYYY VUVU

我单独保留 Y 平面,并通过以下函数处理 U 和 V 平面

uchar swap(uchar in) {
    uchar out = ((in >> 1) & 0x55) | ((in << 1) & 0xaa);
    return out;
}

但我无法得到想要的结果,输出图像的颜色仍然不正确。

如何正确交换 U 和 V 平面?

4

2 回答 2

0

试试这个方法(-_-)

    IFrameCallback iFrameCallback = new IFrameCallback() {
    @Override
    public void onFrame(ByteBuffer frame) {
        //get nv12 data
        byte[] b = new byte[frame.remaining()];
        frame.get(b);
        //nv12 data to nv21
        NV12ToNV21(b, 1280, 720);
        //send NV21 data
        BVPU.InputVideoData(nv21, nv21.length,
                System.currentTimeMillis() * 1000, 1280, 720);
    }
};

byte[] nv21;
private void NV12ToNV21(byte[] data, int width, int height) {
    nv21 = new byte[data.length];

    int framesize = width * height;
    int i = 0, j = 0;
    System.arraycopy(data, 0, nv21, 0, framesize);
    for (i = 0; i < framesize; i++) {
        nv21[i] = data[i];
    }
    for (j = 0; j < framesize / 2; j += 2) {
        nv21[framesize + j - 1] = data[j + framesize];
    }
    for (j = 0; j < framesize / 2; j += 2) {
        nv21[framesize + j] = data[j + framesize - 1];
    }
}
于 2018-08-30T11:19:14.463 回答
0

发现了问题。UV 应该以字节格式操作,而不是位。

    byte[] yuv = // ...
    final int length = yuv.length;
    for (int i1 = 0; i1 < length; i1 += 2) {
        if (i1 >= width * height) {
            byte tmp = yuv[i1];
            yuv[i1] = yuv[i1+1];
            yuv[i1+1] = tmp;
        }
    }
于 2016-06-22T09:38:24.300 回答