Thursday, August 02, 2007

if we want to display two input video and output video in a client application


How we must have to develop the Direct show client application ?.



( 2 In 1 out )


we can use two different ways to this problem .

if we want to display the both input and output video passed to the filter then the following way of graph building is a way to solve the problem.


1. Tee Filter

2. Sample Grabber




Tee filter approach:













Sample Grabber approach:






Series of Steps to be done in GraphEdit For Displaying input and output videos of a Two Input pin Filter :

1.Add the Source Filter1 by Filename

2.Add the Source Filter2 by Filename

3.Render the Source Filter1's output pin, Find the Video Renderer and Remove the video Renderer

4.Insert the Tee Filter at the end of the SourceFilter1 series


//Render the Tee Filter's first output pin ( Tee Filter's Second output pin left as unconnected..)


5.Render The Source Filter2's output pin , Find the Video Renderer and Remove the video Renderer



Here I faced the problem, First Time render the pin and remove the video renderer works... if I tried it in the second time,

then I got the problem that is the video renderer is named as video renderer 004 and we might not be able to identify the

Video Renderer for removing.


Solution :


I solved this problem as follows :

// I added the temporary renderer filter with the Graph.

// Connect the m_pSourceFilter's first output pin to the Temporary Renderer filter's first input pin

// Connect the m_pSourceFilter2's first output pin to the Temporary Renderer filter2's first input pin


// while connecting the intermediate filters are automatically added by the Directshow

//Remove the Temporary Renderer Filter

//Remove the Temporary Renderer Filter2



hr = AddFilterByCLSID(m_pGraph,CLSID_VideoRenderer,L"Temp Renderer 001",&pTempRenderer001);

hr = AddFilterByCLSID(m_pGraph,CLSID_VideoRenderer,L"Temp Renderer 002",&pTempRenderer002);

hr = Connect( m_pGraph,

m_pSourceFilter,

0,

pTempRenderer001,

0

);


hr = Connect( m_pGraph,

m_pSourceFilter2,

0,

pTempRenderer002,

0

);


hr = RemoveRenderer(m_pGraph,&pUnConnectedPin,L"Temp Renderer 001");

hr = RemoveRenderer(m_pGraph,&pUnConnectedPin2,L"Temp Renderer 002");




6.Insert the Tee Filter2 at the end of the SourceFilter2 series


7.Add the Video Renderer 001 filter to the graph


8.Add the Video Renderer 002 filter to the graph

//Render the Tee Filter2's first output pin ( Tee Filter2's Second output pin left as unconnected..)


9.Add the Video Renderer Filter 003 to the graph

10. Connect the Tee Filter's output pin1 to the VideoRenderer 001

11.Connect the Tee Filter2's output pin1 to the VideoRenderer 002


12. Add the two input pin filter

13. Connect the Tee Filter's output pin2 to the Two Input Pin Filter's Input pin1.

14. Connect the Tee Filter2's output pin2 to the Two Input pin Filter's Input Pin 2

15.Connect the Two Input Pin Filter's output pin to the Video Renderer 003




For Filter's First Input Video,Query the video window from the Video Renderer 001

For Filter's Second Input Video,Query the video window from the Video Renderer 002

For Filter's Output Video,Query the video window from the Video Renderer 003








How to create an object for the renderer filter ?


By using the following way we can predict the video renderer easily by using Filter name as follows :


pGraphBuilder->AddFilter(pVideoRenderer, L"Video Renderer 001");


otherwise the graph builder will automatically add the number at the end if the graph have more than one renderer...


So the number is put on the filter name like Video Renderer 001 and so on. if the graph builder automatically adds the Video renderer then we have to use extensive search to identify the filter. To avoid this one it is better to add the renderer filter by the user.







IBaseFilter* pVideoRenderer=NULL;
//Create and add video renderer filter
CoCreateInstance(CLSID_VideoRenderer, NULL, CLSCTX_INPROC_SERVER,
IID_IBaseFilter, (void **)&pVideoRenderer);
pGraphBuilder->AddFilter(pVideoRenderer, L"Video Renderer");


//Querying IVideoWindow interface from pVideoRenderer
pVideoRenderer->QueryInterface(IID_IVideoWindow, (void
**)&pVideoWindow);



Directshow Client :

CTeeVideoRenderer* m_pTeeVideoRenderer;

CRect rc;

m_pTeeVideoRenderer = new CTeeVideoRenderer();

m_pTeeVideoRenderer->InitGraph();

m_pTeeVideoRenderer->AddSourceFilter(L"D:\worksundar.avi");

m_pTeeVideoRenderer->AddSourceFilter(L"D:\work\sundar_1.avi");

m_pTeeVideoRenderer->AddVQFilter();

m_pTeeVideoRenderer->AddTeeFilter();

m_pTeeVideoRenderer->SetNotifyWindow(this ->m_hWnd);

m_pTeeVideoRenderer->Render();



m_pTeeVideoRenderer->SetVideoWindowIn(m_VideoInput1.m_hWnd, 0,0, rc.width(), rc.height());

m_pTeeVideoRenderer->SetVideoWindowIn2(m_VideoInput2.m_hWnd, 0,0, rc.width(), rc.height());

m_pTeeVideoRenderer->SetVideoWindowOut(m_VideoOutput.m_hWnd, 0,0, rc.width(), rc.height());

m_pTeeVideoRenderer->Start();

ReleasePtr ( m_pTeeVideoRenderer);









No comments: