Convert YUY2 to YV12

核能气质少年 提交于 2019-12-10 07:53:26

问题


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 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;
}



回答2:


  1. Separate the Y, U, and V values into separate arrays.
  2. 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.
  3. Concatenate the Y, V, and U arrays.


来源:https://stackoverflow.com/questions/12396156/convert-yuy2-to-yv12

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!