How to swap bit U with bit V in YUV format

420 Views Asked by At

I want to swap the U and V bit in YUV format, from NV12

YYYYYYYY UVUV // each letter presents a bit

to NV21

YYYYYYYY VUVU

I leave the Y planar alone, and handle the U and V planar by the function below

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

But I cannot get the desired result, the colour of the output image still not correct.

How can I swap U and V planar correctly?

2

There are 2 best solutions below

0
On

Found the problem. UV should be manipulated in byte format, not bit.

    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;
        }
    }
0
On

try this method (-_-)

    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];
    }
}