directshow capture and preview
- From: superbobm@xxxxxxxxxxx
- Date: 25 May 2005 05:19:01 -0700
I am trying to create an application that captures video and previews
at the same time. I have included most of my code below, but it only
works occasionally, if I save my filter graph, sometimes it is
connected properly but most of the time only the mux-filewriter is
connected and the other filters are unconnected. Any ideas as to why
this is happening and how can I fix it? Thanks.
I am using Visual C++ 6 and DirectX 9.0b and directx 9.0 extras
(directshow)
// Declared earlier
// DirectShow pointers
IBaseFilter *pSrcFilter = NULL;
IVideoWindow *g_pVW = NULL;
IMediaControl *g_pMC = NULL;
IMediaEventEx *g_pME = NULL;
IGraphBuilder *g_pGraph = NULL;
ICaptureGraphBuilder2 *g_pCapture = NULL;
PLAYSTATE g_psCurrent = Stopped; // playstate is an enumeration
// start preview & capture function
HRESULT hr;
hr = CoInitialize(NULL);
if (FAILED(hr))
{
MessageBox(hwnd, "Error initialising COM", szCaption, MB_OK);
return;
}
// Create the filter graph
hr = CoCreateInstance (CLSID_FilterGraph, NULL, CLSCTX_INPROC,
IID_IGraphBuilder, (void **)&g_pGraph);
if (FAILED(hr))
{
MessageBox(hwnd, "Error creating filter graph", szCaption, MB_OK);
return hr;
}
// Create the capture graph builder
hr = CoCreateInstance (CLSID_CaptureGraphBuilder2 , NULL,
CLSCTX_INPROC,
IID_ICaptureGraphBuilder2, (void
**)&g_pCapture);
if (FAILED(hr)) return hr;
// Obtain interfaces for media control, Video Window & event
handler
hr = g_pGraph->QueryInterface(IID_IMediaControl, (void **)&g_pMC);
if (FAILED(hr)) return hr;
hr = g_pGraph->QueryInterface(IID_IVideoWindow, (void **)&g_pVW);
if (FAILED(hr)) return hr;
hr = g_pGraph->QueryInterface(IID_IMediaEvent, (void **)&g_pME);
if (FAILED(hr)) return hr;
// Set the window handle used to process graph events
hr = g_pME->SetNotifyWindow((OAHWND)hwnd, WM_GRAPHNOTIFY, 0);
// Attach the filter graph to the capture graph
hr = g_pCapture->SetFiltergraph(g_pGraph);
if (FAILED(hr)) return hr;
CComPtr<IMoniker> pMoniker = NULL;
ULONG cFetched;
// Create the system device enumerator
CComPtr<ICreateDevEnum> pDevEnum = NULL;
hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC,
IID_ICreateDevEnum, (void **)&pDevEnum);
if (FAILED(hr)) return hr;
// Create an enumerator for the video capture devices
CComPtr<IEnumMoniker> pClassEnum = NULL;
hr =
pDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory,
&pClassEnum, 0);
if (FAILED(hr)) return hr;
// If there are no enumerators pClassEnum will be NULL.
if (pClassEnum == NULL) return E_FAIL;
// Use the first video capture device on the device list.
if (S_OK == (pClassEnum->Next (1, &pMoniker, &cFetched)))
{
// Bind Moniker to a filter object
hr = pMoniker->BindToObject(0, 0, IID_IBaseFilter, (void
**)&pSrcFilter);
if (FAILED(hr)) return hr;
}
else return E_FAIL;
hr = g_pGraph->AddFilter(pSrcFilter, L"Video Capture");
if (FAILED(hr)) return hr;
IBaseFilter *pMux;
hr = g_pCapture->SetOutputFileName(
&MEDIASUBTYPE_Avi, // Specifies AVI for the target file.
L"C:\\dshowtest.avi", // File name.
&pMux, // Receives a pointer to the mux.
NULL); // (Optional) Receives a pointer to the file sink.
if (FAILED(hr)) return hr;
IBaseFilter *pVmr = NULL;
hr = g_pCapture->RenderStream(
&PIN_CATEGORY_CAPTURE, // Pin category.
&MEDIATYPE_Video, // Media type.
pSrcFilter, // Capture filter.
NULL, // Intermediate filter (optional).
pMux); // Mux or file sink filter.
if (FAILED(hr)) return hr;
hr = g_pCapture->RenderStream(
&PIN_CATEGORY_CAPTURE, // Pin category.
&MEDIATYPE_Audio, // Media type.
pSrcFilter, // Capture filter.
NULL, // Intermediate filter (optional).
pMux); // Mux or file sink filter.
if (FAILED(hr)) return hr;
IConfigAviMux *pConfigMux = NULL;
hr = pMux->QueryInterface(IID_IConfigAviMux, (void **)&pConfigMux);
if (SUCCEEDED(hr))
{
pConfigMux->SetMasterStream(1);
pConfigMux->Release();
}
IConfigInterleaving *pInterleave = NULL;
hr = pMux->QueryInterface(IID_IConfigInterleaving, (void
**)&pInterleave);
if (SUCCEEDED(hr))
{
pInterleave->put_Mode(INTERLEAVE_CAPTURE);
pInterleave->Release();
}
// Release the mux filter.
pMux->Release();
// Render the preview pin on the video capture filter
// Use this instead of g_pGraph->RenderFile
hr = g_pCapture->RenderStream(&PIN_CATEGORY_PREVIEW,
&MEDIATYPE_Video,
pSrcFilter, NULL, NULL);
if (FAILED(hr)) return hr;
// Set the video window to be a child of the main window
hr = g_pVW->put_Owner((OAHWND)hwnd);
if (FAILED(hr)) return hr;
// Set video window style
hr = g_pVW->put_WindowStyle(WS_CHILD | WS_CLIPCHILDREN);
if (FAILED(hr)) return hr;
ResizeVideoWindow(hwnd);
// Make the video window visible, now that it is properly
positioned
hr = g_pVW->put_Visible(OATRUE);
if (FAILED(hr)) return hr;
// Start previewing video data
hr = g_pMC->Run();
if (FAILED(hr)) return hr;
// Remember current state
g_psCurrent = Running;
.
- Follow-Ups:
- Re: directshow capture and preview
- From: The March Hare [MVP]
- Re: directshow capture and preview
- Prev by Date: dynamically adjusts to the available display area
- Next by Date: Re: Video network streaming
- Previous by thread: WMV9 settings for Network Source Filter
- Next by thread: Re: directshow capture and preview
- Index(es):
Relevant Pages
|