In GraphEdit, I can view the output of my webcam by setting up a
simple graph like this:
1. Create webcam filter
2. Right-click on capture pin (the only pin), click "render"
3. Click play button
The preview window then pops up and shows the video from the camera.
It works fine in GraphEdit, but when I try to do it programmatically,
something weird happens: the window pops up, but the video freezes
after a few seconds. When I move my mouse over it, I have an
hourglass. The window doesn't redraw either, and I can't drag it.
I'm not sure what's going on...
Note--this program is EXTREMELY simple--it's just a win32 command-line
program that includes DirectShow headers. My code follows this basic
flow (parts omitted for clarity):
int main(int argc, char* argv[])
{
HRESULT hr = S_OK;
CComPtr <IGraphBuilder> pGraph;
CComPtr <ICaptureGraphBuilder2> pBuilder;
CComPtr <IMediaControl> pControl;
CComPtr <IMediaEvent> pEvent;
CoInitialize();
// Create the System Device Enumerator.
...
// Bind moniker for camera to capture filter
...
// Assemble graph:
hr = pGraph.CoCreateInstance(CLSID_FilterGraph);
if (SUCCEEDED(hr))
{
// Create the Capture Graph Builder.
hr = pBuilder.CoCreateInstance(CLSID_CaptureGraphBuilder2);
}
if (SUCCEEDED(hr))
{
// Attach the capture graph builder to the filter graph
hr = pBuilder->SetFiltergraph(pGraph);
}
if (SUCCEEDED(hr))
{
hr = pGraph->AddFilter(pCamera, L"WebCam");
}
if (SUCCEEDED(hr))
{
// Connect the sample grabber filter to the NULL renderer
hr = pBuilder->RenderStream(NULL, &MEDIATYPE_Video, pCamera,
NULL, NULL);
}
if (SUCCEEDED(hr))
{
hr = pGraph->QueryInterface(IID_IMediaControl, (void**)
&pControl);
}
if (SUCCEEDED(hr))
{
hr = pGraph->QueryInterface(IID_IMediaEventEx, (void
**)&pEvent);
}
if (SUCCEEDED(hr))
{
hr = pControl->Run(); // Run the graph.
}
while(1)
{
Sleep(1000);
printf("Current recorded time: %I64d\n", myCam1.GetVidTime());
if (SUCCEEDED(pEvent->GetEvent(&ev, ¶m1, ¶m2, 0)))
{
switch (ev)
{
case EC_COMPLETE:
printf("Graph complete\n");
break;
case EC_USERABORT:
printf("User abort\n");
break;
case EC_ERRORABORT:
printf("Graph complete/aborted\n");
break;
case EC_PAUSED:
printf("Pause event\n");
break;
default:
printf("Event code 0x%x\n", ev);
break;
}
pEvent->FreeEventParams(ev, param1, param2);
}
}
// Stop graph, clean up and release smart pointers
CoUninitialize();
return 0;
}
When I run the graph, the following events occur almost immediately,
then the video stream freezes:
EC_PALETTE_CHANGED
EC_VIDEO_SIZE_CHANGED
EC_CLOCK_CHANGED
EC_PAUSED
Any idea what's going on here? What part am I missing?
Thanks!
> Any idea what's going on here? What part am I missing?
You do not have a windows event message loop so the messages needed to keep
the video window running are not being processed.
Also, you need will likely need to use the Event handling as described in
the SDK docs section "Responding to Events".
--
Please read this before replying:
1. Dshow & posting help: http://tmhare.mvps.org/help.htm
2. Trim & respond inline (please don't top post or snip everything)
3. Benefit others: follow up if you are helped or you found a solution
> (SUCCEEDED(pEvent->GetEvent(&ev, ¶m1,
As TMH told you, you are missing a message pump. The thread
that creates the video window must dispatch the window
messages. Since the default window is created for you by the
video renderer, the thread is the one that creates the video
renderer, either directly or by letting the graph manager do
it.
IMediaEvent::GetEvent() blocks without dispatching anything
and so does ::Sleep(). IMediaEvent::WaitForCompletion()
dispatches the messages. Otherwise you will need to wait and
dispatch yourself using a message- or event-based approach:
http://msdn.microsoft.com/en-us/library/ms787243(VS.85).aspx
http://msdn.microsoft.com/en-us/library/ms787582(VS.85).aspx
BaseClasses\wxutil.cpp in the SDK contains a function names
WaitDispatchingMessages() that uses
MsgWaitForMultipleObjects() to wait and dispatch.
--
// Alessandro Angeli
// MVP :: DirectShow / MediaFoundation
// mvpnews at riseoftheants dot com
// http://www.riseoftheants.com/mmx/faq.htm