Pergunta

In our application, we need to transfer video, we are using Camera class to capture the buffer and send to destination,

I have set format is YV12 as a Camera parameter to receive the buffer,

for the 500X300 buffer, we receive buffer of 230400 bytes,

i want to know , is this expected buffer size ?
I believe the size would be

Y Plane = width * height = 500X300 = 150000

U Plane = width/2 * height/2 = = 37500

V Plane = width/2 * height/2 = = 37500

                               ========
                                 225000                                     
                               ======== 

Can anyone explain me, if i need to get stride values of each component, how can i get that

Is there any way to get it ?

Foi útil?

Solução

I guess Android document is already explained it:

http://developer.android.com/reference/android/graphics/ImageFormat.html#YV12

Outras dicas

I can show you how you can get int rgb[] from this:

public int[] decodeYUV420SP(byte[] yuv420sp, int width, int height) {

        final int frameSize = width * height;

        int rgb[] = new int[width * height];
        for (int j = 0, yp = 0; j < height; j++) {
            int uvp = frameSize + (j >> 1) * width, u = 0, v = 0;
            for (int i = 0; i < width; i++, yp++) {
                int y = (0xff & ((int) yuv420sp[yp])) - 16;
                if (y < 0)
                    y = 0;
                if ((i & 1) == 0) {
                    v = (0xff & yuv420sp[uvp++]) - 128;
                    u = (0xff & yuv420sp[uvp++]) - 128;
                }

                int y1192 = 1192 * y;
                int r = (y1192 + 1634 * v);
                int g = (y1192 - 833 * v - 400 * u);
                int b = (y1192 + 2066 * u);

                if (r < 0)
                    r = 0;
                else if (r > 262143)
                    r = 262143;
                if (g < 0)
                    g = 0;
                else if (g > 262143)
                    g = 262143;
                if (b < 0)
                    b = 0;
                else if (b > 262143)
                    b = 262143;

                rgb[yp] = 0xff000000 | ((r << 6) & 0xff0000)
                        | ((g >> 2) & 0xff00) | ((b >> 10) & 0xff);

            }
        }
        return rgb;
    }

I think this is simple. chekout YUVImage class from android. You can construct an YUV Image from byte[]data coming from camera preview. You can write like this:

//width and height you get it from camera properties, image width and height of camera preview
YuvImage image=new YuvImage(data, ImageFormat.NV21, int width, int height, null);
byte[] newData = image.getYuvData();
//or if you want int format = image.getYuvFormat();

It's a quite old question, but I've struggled with the same issue for a few days. So I decided to write some comments to help others. YV12 described in the Android developer site(here) seems not a kind of YV12 but IMC1. The page says that both of the y-stride and the uv-stride should be aligned in 16bytes.

And also this page says that:

For YV12, the image buffer that is received is not necessarily tightly packed, as there may be padding at the end of each row of pixel data, as described in YV12.

Based on the above comments, I calculated it using python command line:

>>> w = 500
>>> h = 300
>>> y_stride = (500 + 15) / 16 * 16.0
>>> y_stride
512.0
>>> y_size = y_stride * h
>>> y_size
153600.0
>>> uv_stride = (500 / 2 + 15) / 16 * 16.0
>>> uv_stride
256.0
>>> u_size = uv_stride * h / 2
>>> v_size = uv_stride * h / 2
>>> size = y_size + u_size + v_size
>>> size
230400.0
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top