Q:

Convert YUY2 to YV12

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.

A:

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 array byte frame[M * N * 3 / 2]. We have:

frame[i] for i in [0, M * N) are the Y-values of the pixels.
frame[j] for j in [M * N, M * N * 5/4) are the V-values of each 2 × 2-pixel tile.
frame[j] for k 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;
}

A:

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 be w/2 * h/2.
Concatenate the Y, V, and U arrays.

