GPU Readback in YUV format

Started by
1 comment, last by gpu_noob 11 years, 3 months ago

Hello, I'm trying to capture each frame of the renderer in YUV420P format for encoding. I don`t really understand how to do this yet. Right now I'm getting the data in RGB format like this:


// initialize
d3d->CreateTexture(width,height,1,D3DUSAGE_RENDERTARGET,D3DFMT_X8R8G8B8,D3DPOOL_DEFAULT,&backBuffer, NULL);
backbuffer->GetSurfaceLevel(0,&backBufferSurface);
d3d->CreateOffscreenPlainSurface(width,height,D3DFMT_X8R8G8B8,D3DPOOL_SYSTEMMEM,&tempSurface,NULL);
d3d->GetRenderTargetData(backbufferSurface,tempSurface);

// in render loop
D3DLOCKED_RECT lr;
tempSurface->LockRect(&lr,0, D3DLOCK_READONLY);
// Do processing with lr.pBits
tempSurface->UnlockRect();

So from what I understand from reading other threads is that I can:

- convert the lr.pBits to Y U V planes on CPU or

- use pixel shader to convert the RGB texture to YUV texture and lockrect that to get pBits in YUV

I'm really not sure how to do either of these methods. Could someone please enlighten me on how would I go about doing either of these or if there's any better method (perhaps using DXVA)?

Advertisement

There is an open source library called libyuv. Refer to the conversion functions in that library for any kind of format conversions you're looking for.

Once you get it right, then use pixel shader to convert the RGB texture to YUV texture and lockrect that to get pBits in YUV.

Thank you. I'm trying to convert the RGB data into YUV420 (specifically I420). Libyuv only seems to only have NV12. I am newbie in GPU / DirectX programming so I'm not really sure how to work with YUV textures (filling/writing to the texture) or writing pixel shaders. Are there any good tutorials on this?

Here's what I'm planning to do:


// Create 3 8-bit textures (Luminance, Blue Chrominance, Red Chrominance)
d3d->CreateTexture (  width,height, 1, 0, D3DFMT_L8, D3DPOOL_DEFAULT, &(yTexture), NULL   );
d3d->CreateTexture (  width/2, height/2, 1, 0, D3DFMT_L8, D3DPOOL_DEFAULT, &(uTexture), NULL   );
d3d->CreateTexture (  width/2, height/2, 1, 0, D3DFMT_L8, D3DPOOL_DEFAULT, &(vTexture), NULL   );

// Use pixel shader to calculate Y U V Texture Pixel values (not really sure how to do this yet)

// Lockrect yTexture, Copy pBits. Repeat for uTexture and vTexture (can they even be lockrected since its in the video memory and GetRenderTargetData may not work)

Am I on the right track or completely wrong?

This topic is closed to new replies.

Advertisement