Last time I used those classes I had memory issues from them internally.
The format should not really need data rate or frame rate. It merely specifies how pixels are arranged in memory.
I would advise to handle the bytes in arrays if possible.
Think of RGBA data. Each word in the memory is 4 pixels. [RGBA][RGBA]... And typically it writes out the bottom left first, and ends at the top right. The size of data is easy to know and specific pixels easy to manipulate.
YUV is a planar or semi planar format with 12 bits per pixel on average rather than 32 bits. This is achieved by having 8 bits Y and 8 bits U and V with the U and V double sized. The 8 bits of U and V cover 4 pixels of the Y plane.
So if the picture size is 320 by 240, the first 320 * 240 bytes will be the Y-plane data.
The next bytes in memory are either interlaced U/V lines as semi planar or all planar with first all U then all V data.
The stride of Y is the width.
The stride of U/V is half the width.
The offset of Y is the number of bytes between pixel rows/strides.
The offset of U is the number of bytes between pixel rows/strides.
The offset of V is the number of bytes between pixel rows/strides.
They also have 'base address' which is not exposed in java. The memory address of the first Y pixel data.
On systems that can only allocate 32 bit words of memory as a minimum, images using 12 bit color depth or odd pixel sizes can make the host system behave in different ways regarding where the pixel data resides in addressed memory.
for instance,
write all the Y data packed, it will have a zero offset.
Next write one horizontal line of U data.
Next write one horizontal line of V data.
Next write one horizontal line of U data.
Next write one horizontal line of V data.
The stride of U and V are half the stride of Y.
In java, you should be able to use zero offsets by writing pixel data without gaps between U and V data.
The other format of yuv writes all the U and then all the V data in full chunks.
The offset corresponds to the number of bytes between single Y/U/V rows.
Base address would correspond to the starting address of the U/V planes.
data starts 'here(base)' is this 'wide(stride)' with the next row starting there(offset)
With java the base address is likely given.
Probably didnt answer the question lol
{
unsigned int planeSize;
unsigned int halfWidth;
unsigned char * yplane;
unsigned char * uplane;
unsigned char * vplane;
const unsigned char * rgbIndex;
int x, y;
unsigned char * yline;
unsigned char * uline;
unsigned char * vline;
planeSize = srcFrameWidth * srcFrameHeight;
halfWidth = srcFrameWidth >> 1;
// get pointers to the data
yplane = yuv;
uplane = yuv + planeSize;
vplane = yuv + planeSize + (planeSize >> 2);
rgbIndex = rgb;
for (y = 0; y < srcFrameHeight; y++)
{
yline = yplane + (y * srcFrameWidth);
uline = uplane + ((y >> 1) * halfWidth);
vline = vplane + ((y >> 1) * halfWidth);
if (flip)
rgbIndex = rgb + (srcFrameWidth*(srcFrameHeight-1-y)*rgbIncrement);
for (x = 0; x < (int) srcFrameWidth; x+=2)
{
rgbtoyuv(rgbIndex[0], rgbIndex[1], rgbIndex[2], *yline, *uline, *vline);
rgbIndex += rgbIncrement;
yline++;
rgbtoyuv(rgbIndex[0], rgbIndex[1], rgbIndex[2], *yline, *uline, *vline);
rgbIndex += rgbIncrement;
yline++;
uline++;
vline++;
}
}
}
In java..
public static byte[] YV12toYUV420Planar(byte[] input, byte[] output, int width, int height) {
final int frameSize = width * height;
final int qFrameSize = frameSize/4;
System.arraycopy(input, 0, output, 0, frameSize); // Y
System.arraycopy(input, frameSize, output, frameSize + qFrameSize, qFrameSize); // Cr (V)
System.arraycopy(input, frameSize + qFrameSize, output, frameSize, qFrameSize); // Cb (U)
return output;
}