-
|
|
Direct3D YV12 Rendering - D3DLoadSurfaceFromMemory -> D3DX: Unsupported image format
|
Hi,
I am writing a renderer to render YV12 frames using Direct3D technology.
I have a dump of Planar YV12 data in memory i.e. Y followed by V followed by U in user defined buffer. Basically i load the buffer from a file dump which i took from a decoder.
- Create the D3D object
- Check if the D3D device supports conversion from YV12 -> RGB. The call succeeds.
| HRESULT hr = g_pD3D->CheckDeviceFormatConversion( D3DADAPTER_DEFAULT , D3DDEVTYPE_HAL, (D3DFORMAT)MAKEFOURCC('Y', 'V', '1', '2'), D3DFMT_X8R8G8B8); |
| |
| |
- Then i try to load the source surface with YV12 format with the in memory buffer.
| RECT srcRect; |
| srcRect.left = 0; |
| srcRect.top = 0; |
| srcRect.bottom = width; |
| srcRect.right = height; |
| |
| HRESULT hr = lpDevice->CreateOffscreenPlainSurface(rWidth, rHeight, format, D3DPOOL_SYSTEMMEM, &srcSurface, NULL); |
| |
| if(SUCCEEDED(hr)) |
| { |
| hr = D3DXLoadSurfaceFromMemory(srcSurface, NULL, NULL, imageBuf, format, width, NULL, &srcRect, D3DX_FILTER_NONE, D3DCOLOR_ARGB(255,255, 0, 255) ); |
| } |
| |
| |
For some reason or the other the D3DLoadSurfaceFromMemory fails it says unsupported image format
Could some one please help me in figuring out how the input imageBuf look like. I also tried creating some sample test data for a 32x4 YUV frame as show below but still i get unsupported image format.
BYTE testData[ = { 0x40, 0x40, 0x40, 0x40, 0x40,0x40,0x40,0x40, 0x40,0x40,0x40,0x40, 0x40,0x40,0x40,0x40, 0x40,0x40,0x40,0x40, 0x40,0x40,0x40,0x40, 0x40,0x40,0x40,0x40, 0x40,0x40,0x40,0x40,
0x7A, 0x7A, 0x7A, 0x7A, 0x7A, 0x7A, 0x7A, 0x7A,
0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88 };
the CheckDeviceFormat call succeeds so i assume that my video card is capable of converting from YV12 to RGB. Below is the remaining code of loading to the texture but since D3DXLoadSurfaceFromMemory is failing it it is not proceeding. I have tried sample that loads a bitmap image from file into a source surface and then copy it to the destination surface of the texture which worked. Any Sample for YV12 in Direct3D would be really helpful.
| // Create a texture to hold image from offscreen surface. |
| if(SUCCEEDED(D3DXCreateTexture(lpDevice, rWidth, rHeight, 0, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &_texture)) ) |
| { |
| // Copy offscreen memory surface to texture surface. |
| if(SUCCEEDED(_texture->GetSurfaceLevel(0, &dstSurface)) ) |
| { |
| D3DSURFACE_DESC desc; |
| srcSurface->GetDesc(&desc); |
| |
| srcRect.left = 0; |
| srcRect.top = 0; |
| srcRect.bottom = desc.Width - 1; |
| srcRect.right = desc.Height - 1; |
| |
| D3DSURFACE_DESC desc1; |
| dstSurface->GetDesc(&desc1); |
| |
| RECT dstRect; |
| dstRect.left = 0; |
| dstRect.top = 0; |
| dstRect.bottom = desc1.Width - 1; |
| dstRect.right = desc1.Height - 1; |
| |
| hr = D3DXLoadSurfaceFromSurface(dstSurface, NULL, &dstRect, srcSurface, NULL, &srcRect, D3DX_FILTER_NONE, D3DCOLOR_ARGB(255,255, 0, 255)); |
| } |
| } |
|
|
-
|
|
Re: Direct3D YV12 Rendering - D3DLoadSurfaceFromMemory -> D3DX: Unsupported image format
|
It looks like D3DX doesn't understand this image format, so you'll have to lock and fill the surface with data yourself.
|
|
-
|
|
Re: Direct3D YV12 Rendering - D3DLoadSurfaceFromMemory -> D3DX: Unsupported image format
|
yup now i am directly writing the data to the texture rather than the surface and it works but now i am trying to set 3 textures but for some reason or the other only the first textures content is coming up .. i am trying to understand what i need to do to get multi-texturing working in Direct3D.
|
|
-
|
|
Re: Direct3D YV12 Rendering - D3DLoadSurfaceFromMemory -> D3DX: Unsupported image format
|
If you are using the fixed-function pipeline, then you have to configure the stages you're using and disable the stage after the last one you're using. You need to configure both the color and the alpha for each stage, including the disabled stage.
If you are using a shader, then you configure the samplers for the various textures and just sample them with the shaders.
|
|
-
|
|
Re: Direct3D YV12 Rendering - D3DLoadSurfaceFromMemory -> D3DX: Unsupported image format
|
I am little confused when you say disable the last stage. What do i need to do to disable it.
BTW i am using a shader so i assume i am fine with just the below settings where i am not disabling the last stage. it is kinda working for me though the colors are still messed up so i was wondering if i need to disable the last stage
void set_sampler_state(void)
{
//sampler_state { texture = <colorTexture> ;
//magfilter = POINT; minfilter = POINT; mipfilter=POINT; ADDRESSU = mirror; ADDRESSV = mirror;};
g_lpDevice->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR );
g_lpDevice->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR );
g_lpDevice->SetSamplerState(0, D3DSAMP_MIPFILTER, D3DTEXF_NONE );
g_lpDevice->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_MIRROR );
g_lpDevice->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_MIRROR );
g_lpDevice->SetSamplerState(1, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR );
g_lpDevice->SetSamplerState(1, D3DSAMP_MINFILTER, D3DTEXF_LINEAR );
g_lpDevice->SetSamplerState(1, D3DSAMP_MIPFILTER, D3DTEXF_NONE );
g_lpDevice->SetSamplerState(1, D3DSAMP_ADDRESSU, D3DTADDRESS_MIRROR );
g_lpDevice->SetSamplerState(1, D3DSAMP_ADDRESSV, D3DTADDRESS_MIRROR );
g_lpDevice->SetSamplerState(2, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR );
g_lpDevice->SetSamplerState(2, D3DSAMP_MINFILTER, D3DTEXF_LINEAR );
g_lpDevice->SetSamplerState(2, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
g_lpDevice->SetSamplerState(2, D3DSAMP_ADDRESSU, D3DTADDRESS_MIRROR );
g_lpDevice->SetSamplerState(2, D3DSAMP_ADDRESSV, D3DTADDRESS_MIRROR );
}
void set_render_state(void)
{
g_lpDevice->SetRenderState(D3DRS_LIGHTING, FALSE);
g_lpDevice->SetRenderState( D3DRS_ZENABLE, FALSE );
g_lpDevice->SetRenderState( D3DRS_FOGENABLE, FALSE );
g_lpDevice->SetRenderState( D3DRS_FOGTABLEMODE, D3DFOG_NONE );
g_lpDevice->SetRenderState( D3DRS_FILLMODE, D3DFILL_SOLID );
g_lpDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, FALSE );
g_lpDevice->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_ONE );
g_lpDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_ZERO );
}
void set_texture_state(void)
{
g_lpDevice->SetTextureStageState(0, D3DTSS_COLOROP , D3DTOP_SELECTARG1 );
g_lpDevice->SetTextureStageState(1, D3DTSS_COLOROP , D3DTOP_SELECTARG1 );
g_lpDevice->SetTextureStageState(2, D3DTSS_COLOROP , D3DTOP_SELECTARG1 );
g_lpDevice->SetTextureStageState(0, D3DTSS_COLORARG1 , D3DTA_TEXTURE );
g_lpDevice->SetTextureStageState(1, D3DTSS_COLORARG1 , D3DTA_TEXTURE );
g_lpDevice->SetTextureStageState(2, D3DTSS_COLORARG1 , D3DTA_TEXTURE );
}
|
|
-
|
|
Re: Direct3D YV12 Rendering - D3DLoadSurfaceFromMemory -> D3DX: Unsupported image format
|
Hi Dimple.
Had you fixed your problem??
I am trying to do something like your application.
I want display YUV or RGB 720x576 images with DirectX.
But i dont know if i have to use Surfaces or Textures or Vertex.
I dont know what should i had to use.
Could you help me??
Thanks in advance
|
|
-
|
|
Re: Direct3D YV12 Rendering - D3DLoadSurfaceFromMemory -> D3DX: Unsupported image format
|
I am using a totally different approach where i create 3 textures each one for Y, U & V and hook up a pixel shader in the graphics pipeline to do the YUV to RGB conversion .... I have valid image as output with a color conversion problem where only few of the colors dont look right. The output is very much fine with a little deviation from the correct colors. For eg. the purple looks light brown ... dont feel the pixel shader color conversion equations is the problem (since had it been that then all the colors would be messed up) ... I am wondering if there is some setting i need to do on the direct3D object ... feeling so close to this thing working ...
do you know yuv to rgb color equations compatible with Direct3D .... or do you have a YUV to RGB HLSL Pixel Shader - I am currently using the below HLSL shader i put together with some equations i found on the internet -
struct pixel_in {
float2 texcoord1 : TEXCOORD1;
float2 texcoord2 : TEXCOORD2;
float2 texcoord3 : TEXCOORD3;
float4 color : COLOR0;
};
struct pixel_out {
float4 color : COLOR0;
};
sampler2D input : register(s0);
sampler2D input1 : register(s1);
sampler2D input2 : register(s2);
pixel_out
main (pixel_in IN)
{
pixel_out OUT;
float3 YUV = float3(tex2D (input, IN.texcoord1).x - (16.0 / 256.0) ,
tex2D (input1, IN.texcoord2).x - (128.0 / 256.0),
tex2D (input2, IN.texcoord3).x - (128.0 / 256.0));
OUT.color.r = clamp((1.164 * YUV.x + 1.596 * YUV.y),0,255);
OUT.color.g = clamp((1.164 * YUV.x - 0.813 * YUV.z - 0.391 * YUV.y), 0,255);
OUT.color.b = clamp((1.164 * YUV.x + 2.018 * YUV.z),0,255);
OUT.color.a = IN.color.a;
return OUT;
}
|
|
|