/ / Konwertowanie YUV422 na RGB za pomocą modułu cieniującego GPU HLSL - directx, shader, hlsl

Konwersja YUV422 na RGB za pomocą modułu cieniującego GPU HLSL - directx, shader, hlsl

Rozważam wykonanie przestrzeni kolorówkonwersja z YUV422 na RGB za pomocą HLSL. Czterobajtowy YUYV da 2 trzy bajtowe wartości RGB, na przykład Y1UY2V da R1G1B1 (lewy piksel) i R2G2B2 (prawy piksel). Biorąc pod uwagę współrzędne tekstury w cieniu pikselu, zwiększano stopniowo, jak można odróżnić współrzędne tekstury dla lewych pikseli, tj. Wszystkich R1G1B1 i współrzędnych tekstury dla prawych pikseli, tj. Wszystkich R2G2B2. W ten sposób mogłem renderować wszystkie R1G1B1 i wszystkie R2G2B2 na pojedynczej teksturze zamiast dwóch.

Dzięki!

Odpowiedzi:

1 dla odpowiedzi № 1

Nie wiesz, jakiej wersji DirectX używasz, aletutaj jest wersja, której używam dla dx11 (proszę zauważyć, że w tym przypadku wysyłam dane yuv w StructuredBuffer, co oszczędza mi faktu radzenia sobie z krokiem wiersza. Możesz zastosować tę samą technikę wysyłając swoje dane yuv jako teksturę oczywiście (z kilkoma małe zmiany w kodzie poniżej).

Oto kod pixel shadera (zakładam, że twój cel renderowania ma taki sam rozmiar jak obraz wejściowy i renderujesz quad / trójkąt na pełnym ekranie).

StructuredBuffer<uint> yuy;

int w;
int h;

struct psInput
{
float4 p : SV_Position;
float2 uv : TEXCOORD0;
};

float4 PS(psInput input) : SV_Target
{
//Calculate pixel location within buffer (if you use texture change lookup here)
uint2 xy = input.p.xy;
uint p = (xy.x) + (xy.y * w);
uint pixloc = p / 2;

uint pixdata = yuy[pixloc];

//Since pixdata is packed, use some bitshift to remove non useful data
uint v  = (pixdata & 0xff000000) >> 24;
uint y1  = (pixdata & 0xff0000) >> 16;
uint u  = (pixdata & 0xff00) >> 8;
uint y0  = pixdata & 0x000000FF;

//Check if you are left/right pixel
uint y = p % 2 == 0 ? y0: y1;

//Convert yuv to rgb
float cb = u;
float cr = v;

float r  = (y + 1.402 * (cr - 128.0));
float g =  (y - 0.344 * (cb - 128.0) - 0.714 * (cr - 128));
float b =  (y + 1.772 * (cb - 128));

return float4(r,g,b,1.0f) / 256.0f;
}

Nadzieja, która pomaga.