Thursday, May 10, 2007

Simple DirectX transform filter completed

I refered the AMGetErrorText() fn in DirectX transform filter.
To refer this function, we have to include
Quartz.lib and dshow.h files


00000000 8:58:52.593 AM [3244]
00000001 8:58:52.593 AM [3244] CDXTWipe::OnSetup() fn
00000002 8:58:52.593 AM [3244]
00000003 8:58:52.593 AM [3244] CDXTWipe::OnInitInstData() fn
00000004 8:58:52.593 AM [3244]
00000005 8:58:52.593 AM [3244] InputSurface(0)->GetDirectDrawSurface() failed
00000006 8:58:52.609 AM [3244] Unknown Error: 0x887a0001
00000007 8:58:52.609 AM [3244] Clip's mediatimes are invalid, or DibSeq too short, or a previous error caused this
00000008 8:58:52.609 AM [3244]

I added my filter as effect in Slomo.xtl file and put the debug string in my programme.

within my filter I get the DirectDraw surface from the IDXSurface interface.

if the filter is called by using XTLTest sample application (simply adding the filter's CLASSID in an Effect option).

The GetDirectDrawSurface() fn is failed with unknown error. so I has to change the program.

Instead of using DirectDrawSurface () directly use IDXARGBReadPtr interface to get the

surface data.


//One more thing we have to register all our filters in the registry under the category

// of CLSID_VIdeoEffects1category (for one input DirectX transform filter)

// and CLSID_VideoEffects2Category (for two input DirectX transform filter).


So I have to change it and use IDXARGBPtr for reading data from the IDXSurface.


Next to be Done :
--------------------------
1.Text overlay filter - use IDXARGBReadPtr interface.
2.Merge Filter

I found the reason for this error...
DXSurface does not have an underlying IDXSurface::GetDirectDrawSurface.
This is the case for some surfaces, such as procedural surfaces.
DirectX transform filter is made up of Procedural surfaces.



About the DC:
----------------------

IDXDCLock Interface

--------------------------------------------------------------------------------

The IDXDCLock interface is used to lock a surface and to obtain a device context (DC) that can be used with Microsoft® Windows® Graphics Device Interface (GDI) calls.

IDXDCLock Members

GetDC Retrieves the current DC.

Remarks

You can use IDXDCLock by calling the IDXSurface::LockSurface method and by specifying IID_IDXDCLock as the desired interface, or by calling the IDXSurface::LockSurfaceDC method. When the IDXDCLock interface is finally released, the underlying GDI DC is released.

IDXDCLock can be used by any transform that enables you to specify the desired output bounds.

Interface Information


I found out another way to get the DC of an IDXSurface interface :

IDXDCLock* pDCInputLock = NULL;
IDXDCLock* pDCOutputLock = NULL;
HDC hdcInput;
HDC hdcOutput;

OutputDebugString("\n CDXTWipe::WorkProc() fn");

InputSurface(0)->LockSurfaceDC(NULL,INFINITE,DXLOCKF_READ, &pDCInputLock);
OutputSurface()->LockSurfaceDC(NULL,INFINITE,DXLOCKF_READWRITE, &pDCOutputLock);

hdcInput = pDCInputLock->GetDC();
hdcOutput = pDCOutputLock->GetDC();

BitBlt(hdcOutput,0,0,m_OutputSize.cx,m_OutputSize.cy,hdcInput,0,0,SRCCOPY);
TextOut(hdcOutput,10,10,"sundar",6);

if(pDCInputLock)
{
pDCInputLock->Release();
pDCInputLock = NULL;
}
if(pDCOutputLock)
{
pDCOutputLock->Release();
pDCOutputLock = NULL;
}
return hr;


Next I used the LockSurfaceDC() fn of an IDXSurface it is also failed with error...

instead of adding text over it use RGB to Gray functionality using IDXARGBReadPtr interface.

IDXARGBReadPtr


To Be done :
--------------------
1.Add the Effect filter functionality to convert from RGB to Gray.
using IDXARGBReadWritePtr interface.




The following code simply copy the input surface to the output surface :
---------------------------------------------------------------------------------------------------

CDXDBnds srcBnds(InputSurface(),hr);

if(FAILED(hr))
{
OutputDebugString("\n failed in getting InputSurface()'s Bounds fn");
return E_FAIL;
}
CDXDBnds destBnds(OutputSurface(),hr);
if(FAILED(hr))
{
OutputDebugString("\n failed in getting OutputSurface()'s Bounds fn");
return E_FAIL;
}
hr = DXBitBlt(OutputSurface(),destBnds,InputSurface(),srcBnds,DXBOF_DO_OVER ,m_ulLockTimeOut);

return hr;


I tested the filter by simlply adding a color rectangle to my source image..

Thru XTL test it is now working...


For color rectangle, I did the following :
this will display the blue color rectangle in an image...
RECT rect;
rect.left = 0;
rect.top = 0;
rect.bottom = 50;
rect.right = 50;

hr = DXFillSurfaceRect(OutputSurface(),rect,0xff,FALSE,m_ulLockTimeOut);


I completed the testing of my filter with simple color rectangle effect and

added it with SlomoEffect.bat in XTLTest application.


So Next I will convert my Directshow baseclasses filters to Directx transform filters.

I Tested the filter with the graph.


How can we change the DirectXTransform filter's output size :

we can determine the output surface's bounds using CDXBaseNTo1::DetermineBnds() Method
if we override the base class method then we will get desired output.

we can build the merge filter in an easy manner in DirectX transform filter.


To Be done next :
--------------------------------
1. After lunch work with WMCSApp and Windows services application : - completed
2. Work with Merge filter -...
3.How can we pass two surfaces and create the output surface...

3 comments:

Unknown said...

Did you test this transform filter in DES(DirectShow Editing Service)?
When I use this filter in DES,

hr = InputSurface(0)->LockSurfaceDC(NULL, INFINITE, DXLOCKF_READ, &pDCInputLock);
failed.

But it is succeeded in DxeTool.exe.

ajitpal said...

Could u plz tell me how to ad transistion effect ot video in DES using C#...

예산계원 said...

DirectShow Editing Services

hr = InputSurface(0)->LockSurfaceDC(NULL, INFINITE, DXLOCKF_READ, &pDCInputLock);

Failed...ㅡㅡ;