farming

Hi,
I need control two monitors that I will write two different video images into either monitor. I found a function SetMonitor() in DirectShow. I am still confuse at which interface should I select, IVMRMonitorConfig, or IVMRMonitorConfig9

Now, I tried to use IVMRMonitorConfig9 like follows:
HRESULT hr;
IVMRMonitorConfig9 *pMonitorConfig = 0;
hr = pMonitorConfig->SetMonitor(1); //display image at the 2nd monitor
//but there is run error here: "access 0x000000"
pMonitorConfig->Release();


Should I use CoCreateInstance() function to initilize it and how to write the parameters in it

Thanks a lot.


Re: DirectShow Development How to configure monitors using DirectShow?

MVP User

On Fri, 5 Jan 2007 15:22:01 -0800, = UTF-8 B ZmFybWluZw== =@discussions.microsoft.com wrote: > Now, I tried to use IVMRMonitorConfig9 like follows: > HRESULT hr; > IVMRMonitorConfig9 *pMonitorConfig = 0; > hr = pMonitorConfig->SetMonitor(1); //display image at the 2nd > monitor > //but > there is run error here: "access 0x000000" > pMonitorConfig->Release(); > You're dereferencing a null pointer so it's no surprise that you're getting an access violation. CComQIPtr<IVMRMonitorConfig9> monitor_config(vmr9); // where vmr9 is a CComPtr<IBaseFilter> to the instance of the vmr9 you are trying to configure if (!monitor_config) return E_NOINTERFACE; hr = monitor_config->SetMonitor(1); // no need to call Release since you're using a smart pointer



Re: DirectShow Development How to configure monitors using DirectShow?

MVP User

Let's try that again looks like posting from nntp has issues: You're dereferencing a null pointer so it's no surprise that you're getting an access violation. First query interface: CComQIPtr<IVMRMonitorConfig9> monitor_config(vmr9); (where vmr9 is a CComPtr<IBaseFilter> (or IBaseFilter*) to the instance of the vmr9 you are trying to configure). Then check that you got a valid pointer: if (!monitor_config) return E_NOINTERFACE; Then set the monitor: hr = monitor_config->SetMonitor(1); (no need to call Release since you're using a smart pointer).



Re: DirectShow Development How to configure monitors using DirectShow?

farming

Hi,
Thank you reply so fast. I changed the program as:
CComQIPtr<IVMRMonitorConfig9> monitor_config(vmr9); //error here
if (!monitor_config)
return E_NOINTERFACE;

hr = monitor_config->SetMonitor(1);

And I add the include file "atlcomcli.h"

But there is a error: error C2065: 'vmr9' : undeclared identifier
How can I do

Thanks.
Farming




Re: DirectShow Development How to configure monitors using DirectShow?

MVP User

As I wrote already, vmr9 is a CComPtr<IBaseFilter> or IBaseFilter* to the VMR9 instance (the one in your graph). You query interface for the other VMR9 instances from this pointer. It's likely you already created the IBaseFilter with CoCreateInstance to add it to your graph. The best way is with a smart pointer: CComPtr<IBaseFilter> vmr9; hr = vmr9.CoCreateInstance(CLSID_VideoMixingRenderer9); Don't create a new one for setting the monitor though, you need to use the filter in the graph. See the MonitorInfo9 sample in the SDK samples.



Re: DirectShow Development How to configure monitors using DirectShow?

MVP User

I wrote: You query interface for the other VMR9 instances [ should be "interfaces" instead of "instances"] from this pointer. Long week :(



Re: DirectShow Development How to configure monitors using DirectShow?

farming

Dear NNTP User,

I am a little understood how to use 'IVMRMonitorConfig9' after I read the sample in SDK. My whole program can run, however, I cannot control the live video to display in the second monitor till now. I list the whole code as follows, could help me find out why I can realize my objective Is there any similar function as IDirect3D9::CreatDevice() in DirectShow

//my code, console mode by Vs.2005
#include "stdafx.h"
#include <dshow.h>
#include <D3d9.h>
#include <Vmr9.h>
#include <atlcomcli.h>
#include <multimon.h>

int _tmain(int argc, _TCHAR* argv[])
{
IGraphBuilder *pGraph = 0; //high-level object: filter graph manager(FGM)
ICreateDevEnum *pDevEnum = 0; //get number of display adapters
ICaptureGraphBuilder2 *pBuild = 0; //another high-level object, for capture live video
IMediaControl *pMediaControl = 0; //for control camera
IMediaEvent *pEvent = 0; //event
IVMRMonitorConfig9 *pMonitorConfig = NULL; //config which monitor will be used
IBaseFilter* pVmr = NULL; //for set monitors

HRESULT hr;
CoInitialize(NULL); //initialize COM lib

// Create the FGM.object
hr = CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER,
IID_IGraphBuilder, (void **)&pGraph );

// Create the capture graph builder helper object
hr = CoCreateInstance(CLSID_CaptureGraphBuilder2, NULL,
CLSCTX_INPROC_SERVER, IID_ICaptureGraphBuilder2,
(void **)&pBuild );

hr = CoCreateInstance(CLSID_VideoMixingRenderer9, NULL,
CLSCTX_INPROC, IID_IBaseFilter, (void**)&pVmr);
if (SUCCEEDED(hr))
{
hr = pGraph->AddFilter(pVmr,L"Video Mixing Renderer 0");
if (SUCCEEDED(hr))
{
hr = pVmr->QueryInterface(IID_IVMRMonitorConfig9,(void **)&pMonitorConfig);
if (SUCCEEDED(hr))
{
//set video display at the second monitor
hr = pMonitorConfig->SetMonitor(1);
}
}
}
//hr = CoCreateInstance(CLSID_IVMRMonitorConfig9,NULL,CLSCTX_INPROC_SERVER,IID_IVMRMonitorConfig9,(void **)&pMonitorConfig);

// Obtain the interface used to run, stop, and pause the graph
pGraph->QueryInterface(IID_IMediaControl, (void **)&pMediaControl);
// Obtain the interface to receive events from the graph
pGraph->QueryInterface(IID_IMediaEvent, (void **)&pEvent);

// Tell the capture graph builder about the FGM.
hr = pBuild->SetFiltergraph(pGraph);

// Create a helper object to find the capture device.
hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL,
CLSCTX_INPROC_SERVER,
IID_ICreateDevEnum, (LPVOID*)&pDevEnum);

// Use the first capture filter that we find.
IEnumMoniker* pEnum = 0;
IMoniker* pMoniker = 0;
IBaseFilter *pCapture = 0;
hr = pDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory,
&pEnum, 0);
if (S_OK == pEnum->Next(1, &pMoniker, NULL))
{
hr = pMoniker->BindToObject(0, 0, IID_IBaseFilter, (void
**)&pCapture);
}

pMoniker->Release();
pEnum->Release();
pDevEnum->Release();

// Add the capture filter to the filter graph
hr = pGraph->AddFilter(pCapture, L"CaptureFilter");

// Build the preview part of the graph.
hr = pBuild->RenderStream(&PIN_CATEGORY_PREVIEW, &MEDIATYPE_Video,
pCapture, NULL, NULL);

// Build the file writing part of the graph.
IBaseFilter *pMux = 0;
pBuild->SetOutputFileName(&MEDIASUBTYPE_Avi, L"C:\\temp\\test.avi",
&pMux, 0);
hr = pBuild->RenderStream(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video,
pCapture, NULL, pMux);

// Run the graph.
pMediaControl->Run();

// Wait for completion.
long evCode;
pEvent->WaitForCompletion(INFINITE, &evCode);

pMediaControl->Release();
pEvent->Release();
pGraph->Release();
pBuild->Release();
pCapture->Release();
pMux->Release();
pVmr->Release();
CoUninitialize();
return 0;
}




Re: DirectShow Development How to configure monitors using DirectShow?

farming

Hi, everyone,

I can control my video file to play in the monitor I want now, through using of IDirect3D::CreatDevice() function. However, I sitll feel diffcult to make my live video to display on the monitor I want.

In MSDN, there is an example on how to use windowless mode by "IVMRFilterConfig9::SetRenderingMode(VMR9Mode_Windowless)", and "RenderFileToVMR9()" function. I cannot find any functions like "RenderVideoToVMR9()". I list my code. For this test, I build a MFC-based dialogue application. Please help find out a method to make my live video go into my dialogue box.




Re: DirectShow Development How to configure monitors using DirectShow?

farming

My monitor control code:
//for initialize
HRESULT CWebCamEx5Dlg::InitializeWindowlessVMR()
{
//-----------------------------------------------------
//those three filters are global variables
//IBaseFilter *pVmr = Null;
//IVMRWindowlessControl9 *pWC = NULL;
//IVMRMonitorConfig9 *pMonitorConfig = NULL;
//------------------------------------------------------

// Create the VMR and add it to the filter graph.
HRESULT hr = CoCreateInstance(CLSID_VideoMixingRenderer9, NULL,
CLSCTX_INPROC, IID_IBaseFilter, (void**)&pVmr);
if (SUCCEEDED(hr))
{
hr = pGB->AddFilter(pVmr, L"Video Mixing Renderer 9");
if (SUCCEEDED(hr))
{
// Set the rendering mode and number of streams
CComPtr <IVMRFilterConfig9> pConfig;

pVmr->QueryInterface(IID_IVMRFilterConfig9, (void**)&pConfig);
pConfig->SetRenderingMode(VMR9Mode_Windowless); //Set windowless mode

hr = pVmr->QueryInterface(IID_IVMRWindowlessControl9, (void**)&pWC);
if( SUCCEEDED(hr))
{
pWC->SetVideoClippingWindow(CWebCamEx5Dlg::m_hWnd);
pWC->SetBorderColor(RGB(0,0,0));
}

//set video display at the second monitor
hr = pVmr->QueryInterface(IID_IVMRMonitorConfig9,(void **)&pMonitorConfig);
if (SUCCEEDED(hr))
{
//set video display at the second monitor
hr = pMonitorConfig->SetMonitor(1); //this line seems useless
}
//set to full secrren
hr = pVmr->QueryInterface(IID_IVideoWindow,(void **)&pVideoFull);
if (SUCCEEDED(hr))
{
//set full screen mode
hr = pVideoFull->put_FullScreenMode(OATRUE); //this line seems useless
}
}
}

return hr;
}

//live capture video
void CWebCamEx5Dlg::OnBnClickedBtnCapture()
{
// TODO: Add your control notification handler code here
//run
// Create a helper object to find the capture device.
m_hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL,
CLSCTX_INPROC_SERVER,
IID_ICreateDevEnum, (LPVOID*)&pDevEnum);

// Use the first capture filter that we find.
IEnumMoniker* pEnum = 0;
IMoniker* pMoniker = 0;

m_hr = pDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory,
&pEnum, 0);
if (S_OK == pEnum->Next(1, &pMoniker, NULL))
{
m_hr = pMoniker->BindToObject(0, 0, IID_IBaseFilter, (void
**)&pCapture);
}

pMoniker->Release();
pEnum->Release();
pDevEnum->Release();

// Add the capture filter to the filter graph
m_hr = pGB->AddFilter(pCapture, L"CaptureFilter");

// Build the preview part of the graph. but it seem it only render to the default monitor
m_hr = pBuild->RenderStream(&PIN_CATEGORY_PREVIEW, &MEDIATYPE_Video,
pCapture, NULL, NULL);

// Build the file writing part of the graph.
IBaseFilter *pMux = 0;
pBuild->SetOutputFileName(&MEDIASUBTYPE_Avi, L"C:\\temp\\test.avi",
&pMux, 0);
m_hr = pBuild->RenderStream(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video,
pCapture, NULL, pMux);

// Run the graph.
pMC->Run();

}