问题
I am almost sure that this is much simpler than I think it is, but I have been scouring the internet for a much longer time than I care to admit to try and figure out how the frig to convert the two formats. I am able to extract the Y0, Cb, Y1, Cr data from a stream of unsigned bytes (unsigned char), but I have no idea how these bytes are arranged in YV12 - is this document implying that the various values are actually contained in different rows?
I've literally been searching all day for things like "c++ convert YUY2 to YV12," and have turned up absolutely no tutorials or code samples. I would think that this would have some form of documentation that I could use, but the information seems to be scarce on this particular subject.
回答1:
Looks like the linked entry on YUY2 together with the Wikipedia article on YV12 makes this pretty clear:
YUY2 stores every two adjacent, horizontal pixels as four bytes,
[Y1, U, Y2, V]
.YV12 stores an entire M × N frame in a contiguous array of
M*N + 2 * (M/2 * N/2)
bytes. Let's call the arraybyte frame[M * N * 3 / 2]
. We have:frame[i]
fori
in[0, M * N)
are the Y-values of the pixels.frame[j]
forj
in[M * N, M * N * 5/4)
are the V-values of each 2 × 2-pixel tile.frame[j]
fork
in[M * N * 5/4, M * N * 6/4)
are the U-values of each 2 × 2-pixel tile.
So as you convert from YUY2 to YV12, you have to halve the amount of U- and V-data, possibly by taking the average of two adjacent rows.
Example:
byte YUY2Source[M * N * 2] = /* source frame */;
byte YV12Dest[M * N * 3/2];
for (unsigned int i = 0; i != M * N; ++i)
{
YV12Dest[i] = YUY2Source[2 * i];
}
for (unsigned int j = 0; j != M * N / 4; ++j)
{
YV12Dest[M * N + j] = ( YUY2Source[N*(j / N/2 ) + 4 * j + 3]
+ YUY2Source[N*(j / N/2 + 1) + 4 * j + 3] ) / 2;
YV12Dest[M * N * 5/4 + j] = ( YUY2Source[N*(j / N/2 ) + 4 * j + 1]
+ YUY2Source[N*(j / N/2 + 1) + 4 * j + 1] ) / 2;
}
回答2:
- Separate the Y, U, and V values into separate arrays.
- Average together the values from the even and odd lines of the U and V arrays to combine two lines into one. This will cut the height of those arrays in half. The Y array will be
w * h
, and the U and V arrays will now bew/2 * h/2
. - Concatenate the Y, V, and U arrays.
来源:https://stackoverflow.com/questions/12396156/convert-yuy2-to-yv12