上次我使用这些类时,我在内部遇到了内存问题。
格式不应该真的需要数据速率或帧速率。它仅指定像素在内存中的排列方式。
如果可能,我建议处理数组中的字节。
想想 RGBA 数据。内存中的每个单词是 4 个像素。[RGBA][RGBA]... 通常它首先写出左下角,然后在右上角结束。数据的大小很容易知道,特定的像素很容易操作。
YUV 是一种平面或半平面格式,平均每像素 12 位,而不是 32 位。这是通过将 8 位 Y 和 8 位 U 和 V 与 U 和 V 双倍大小来实现的。U 和 V 的 8 位覆盖了 Y 平面的 4 个像素。
因此,如果图片大小为 320 x 240,则前 320 * 240 字节将是 Y 平面数据。
内存中的下一个字节是交错的 U/V 线半平面或全平面,首先是所有 U,然后是所有 V 数据。
Y 的步幅是宽度。U/V 的步幅是宽度的一半。Y 的偏移量是像素行/步长之间的字节数。U 的偏移量是像素行/步长之间的字节数。V 的偏移量是像素行/步长之间的字节数。
它们还具有未在 java 中公开的“基地址”。第一个 Y 像素数据的内存地址。
在至少只能分配 32 位字的内存的系统上,使用 12 位颜色深度或奇数像素大小的图像可以使主机系统以不同的方式处理像素数据在寻址内存中的位置。
例如,写入所有打包的 Y 数据,它的偏移量为零。接下来写入一个水平行的 U 数据。接下来写入一条水平行的 V 数据。接下来写入一个水平行的 U 数据。接下来写入一条水平行的 V 数据。
U 和 V 的步幅是 Y 步幅的一半。
在 java 中,您应该能够通过写入像素数据来使用零偏移,而 U 和 V 数据之间没有间隙。
yuv 的另一种格式将所有 U 数据写入完整的块中,然后写入所有 V 数据。
偏移量对应于单个 Y/U/V 行之间的字节数。
基地址对应于 U/V 平面的起始地址。
数据开始'here(base)'是这个'wide(stride)',下一行从那里开始(偏移量)
使用 java 可能会给出基地址。
可能没有回答问题哈哈
{
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++;
}
}
}
在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;
}