Does anyone else have problems enumerating the pins on their video capture device using the pEnum->(next, &pPinOut, NULL)? I seem to have, and I cannot figure out why.
The usual preliminaries were done: COM was initialised and the device enumerator was instantiated. The friendly names and the CLSID of the filters were listed using Monikers and linked using arrays. The friendly name was displayed in a list box for user selection. From the selected friendly name, the CLSID was found. From this, and the source filter was instantiated and added to the filter graph.
Then the problems start. When I attempt to access the pins on the source filter, I find that pEnum->(next, &pPinOut, NULL) returns a S_FALSE message. (pEnum->reset() was performed immediately prior to start enumerating from the beginning.)
But it is probably not a problem with the functions, since using the same functions for another filter type (eg a video compressor), pEnum->(next, &pPinOut, NULL) returns a S_OK message.
I have tried different approaches to find the problem. I have rewritten a simplified program version in an attempt to isolate the problem. In vain. Upon running a “find unconnected pins” function, the function returns a “no unconnected pins” error, for the video capture device but not for other filter types. The ICaptureGraphBuilder2 interface, supposedly easier, failed to renderstream.
The most obvious possibility is the camera was in use. But it was not. The device enumerator and moniker were released after use and no other programs were running. Neither is the problem with the camera, for when I ran the sample DirectShow playcap project, the video camera was accessed and the image displayed.
I am sure I have missed something very simple, but I cannot think what it is. Could anyone tell me what I am doing wrong?
Many thanks in advance for your very needed help.
The most important code segment, with simple error-tracking, is shown below:
void Transform::renderFilter(const GUID &clsid, LPCWSTR wszName, IBaseFilter **ppFilter)
{
// COM initialised and pGraph instantiated at constructor level
// CLSID and wszName found via findFilterClsid() and enumFilters() function
// Add then render filter
*ppFilter = 0;
IBaseFilter *pFilter = 0;
IEnumPins *pEnum = 0;
IPin *pPinOut[2];
pPinOut[0] = pPinOut[1] = 0;
HRESULT hr = CoCreateInstance(clsid, 0, CLSCTX_INPROC_SERVER,
IID_IBaseFilter, reinterpret_cast<void**>(&pFilter));
if (hr == S_OK)
{
hr = pGraph->AddFilter(pFilter, wszName);
if (SUCCEEDED(hr))
{
*ppFilter = pFilter;
AfxMessageBox("Filter in place"
}
else
{
AfxMessageBox("No filter added"
pFilter->Release();
}
}
else
if (pFilter == 0)
AfxMessageBox("No filter instantiated"
pEnum->Reset();
// Enumerating pins
pFilter->EnumPins(&pEnum);
if (pFilter == 0)
AfxMessageBox("No filter found"
if (pEnum == 0)
AfxMessageBox("No pin enum"
if (pEnum->Next(1, &pPinOut[0], NULL) == S_FALSE)
AfxMessageBox("Error enumerating pins"
// This is where I keep getting the error message
while (pEnum->Next(1, &pPinOut[0], NULL) == S_OK) // hr
{
AfxMessageBox("Enumerating"
// Check the pin direction.
PIN_DIRECTION PinDir;
pPinOut[0]->QueryDirection(&PinDir);
if (PinDir == PINDIR_OUTPUT)
{
hr = pGraph->Render(pPinOut[0]);
AfxMessageBox("Output Pin rendered"
}
// pPinOut[0]->Release();
}
if (pPinOut[0] != 0)
{
pPinOut[0]->Release();
AfxMessageBox("Pin released"
}
pEnum->Release();
pFilter->Release();
// Media control interfaces
IMediaControl *pControl;
IMediaEvent *pEvent;
hr = pGraph->QueryInterface(IID_IMediaControl, (void **)&pControl);
hr = pGraph->QueryInterface(IID_IMediaEvent, (void **)&pEvent);
// control filter graph
hr = pControl->Run();
AfxMessageBox("Should have ran"
// long evCode = 0;
// pEvent->WaitForCompletion(10000, &evCode);
pControl->Release();
pEvent->Release();
}
The usual preliminaries were done: COM was initialised and the device enumerator was instantiated. The friendly names and the CLSID of the filters were listed using Monikers and linked using arrays. The friendly name was displayed in a list box for user selection. From the selected friendly name, the CLSID was found. From this, and the source filter was instantiated and added to the filter graph.
Then the problems start. When I attempt to access the pins on the source filter, I find that pEnum->(next, &pPinOut, NULL) returns a S_FALSE message. (pEnum->reset() was performed immediately prior to start enumerating from the beginning.)
But it is probably not a problem with the functions, since using the same functions for another filter type (eg a video compressor), pEnum->(next, &pPinOut, NULL) returns a S_OK message.
I have tried different approaches to find the problem. I have rewritten a simplified program version in an attempt to isolate the problem. In vain. Upon running a “find unconnected pins” function, the function returns a “no unconnected pins” error, for the video capture device but not for other filter types. The ICaptureGraphBuilder2 interface, supposedly easier, failed to renderstream.
The most obvious possibility is the camera was in use. But it was not. The device enumerator and moniker were released after use and no other programs were running. Neither is the problem with the camera, for when I ran the sample DirectShow playcap project, the video camera was accessed and the image displayed.
I am sure I have missed something very simple, but I cannot think what it is. Could anyone tell me what I am doing wrong?
Many thanks in advance for your very needed help.
The most important code segment, with simple error-tracking, is shown below:
void Transform::renderFilter(const GUID &clsid, LPCWSTR wszName, IBaseFilter **ppFilter)
{
// COM initialised and pGraph instantiated at constructor level
// CLSID and wszName found via findFilterClsid() and enumFilters() function
// Add then render filter
*ppFilter = 0;
IBaseFilter *pFilter = 0;
IEnumPins *pEnum = 0;
IPin *pPinOut[2];
pPinOut[0] = pPinOut[1] = 0;
HRESULT hr = CoCreateInstance(clsid, 0, CLSCTX_INPROC_SERVER,
IID_IBaseFilter, reinterpret_cast<void**>(&pFilter));
if (hr == S_OK)
{
hr = pGraph->AddFilter(pFilter, wszName);
if (SUCCEEDED(hr))
{
*ppFilter = pFilter;
AfxMessageBox("Filter in place"
}
else
{
AfxMessageBox("No filter added"
pFilter->Release();
}
}
else
if (pFilter == 0)
AfxMessageBox("No filter instantiated"
pEnum->Reset();
// Enumerating pins
pFilter->EnumPins(&pEnum);
if (pFilter == 0)
AfxMessageBox("No filter found"
if (pEnum == 0)
AfxMessageBox("No pin enum"
if (pEnum->Next(1, &pPinOut[0], NULL) == S_FALSE)
AfxMessageBox("Error enumerating pins"
// This is where I keep getting the error message
while (pEnum->Next(1, &pPinOut[0], NULL) == S_OK) // hr
{
AfxMessageBox("Enumerating"
// Check the pin direction.
PIN_DIRECTION PinDir;
pPinOut[0]->QueryDirection(&PinDir);
if (PinDir == PINDIR_OUTPUT)
{
hr = pGraph->Render(pPinOut[0]);
AfxMessageBox("Output Pin rendered"
}
// pPinOut[0]->Release();
}
if (pPinOut[0] != 0)
{
pPinOut[0]->Release();
AfxMessageBox("Pin released"
}
pEnum->Release();
pFilter->Release();
// Media control interfaces
IMediaControl *pControl;
IMediaEvent *pEvent;
hr = pGraph->QueryInterface(IID_IMediaControl, (void **)&pControl);
hr = pGraph->QueryInterface(IID_IMediaEvent, (void **)&pEvent);
// control filter graph
hr = pControl->Run();
AfxMessageBox("Should have ran"
// long evCode = 0;
// pEvent->WaitForCompletion(10000, &evCode);
pControl->Release();
pEvent->Release();
}