Simply WEIRD! Is this a directx/driver bug!
- From: Jesper <Jesper@xxxxxxxxxxxxxxxxxxxxxxxxx>
- Date: Fri, 6 May 2005 06:04:02 -0700
Hi!
I'm writing a tv tuner application, and I have run into the weirdest thing.
I'm sorry for the lengthy post, but I don't know how to explain it without
supplying a stripped version of the code (see below).
As you can see, my WinMain makes an instance of the StripedTestTuner class
and then calls the init() method on the new instance. The init() method
simply calls to other methods: initGraph() and then buildGraph().
The initGraph() method sets up the capture graph and inserts the needed
filters, but does not connect them. Connecting the filters is done in
buildGraph(), though that is not in the supplyed code, because it fails
eventhough the filters are not connected.
Actually it does not fail until the init method of the StripedTestTuner
finishes (without errors) and the StripedTestTuner object is destroyed in
WinMain. Destroying the object results in the method releaseFilters() being
called from the destructor, which releases all the COM interfaces.
As you can see in the code of releaseFilters(), releasing the second
interface fails, and with this striped down code, it is always releasing the
second interface that fails no matter the order of the 'release blocks'.
The funny thing is, if the variable captureDeviceType (int) is not set, as
it is in the method initGraph(), it will not fail either...! Neither will it
if the block of code in the method buildGraph() is commented out!
I realy hope you can help me out here...
-------------------- code ----------------------
// constructor
CStripedTestTuner::CStripedTestTuner()
{
pWc9 = NULL;
pVCapDevFilter = NULL;
pMpeg2Demuxer = NULL;
pGrphBld = NULL;
pCapGrphBld = NULL;
pMediaCtrl = NULL;
pSConfig = NULL;
pTVTuner = NULL;
pAnalogVideoDecoder = NULL;
pAudioPin = NULL;
pVideoPin = NULL;
runState = RS_OFF;
}
// destructor
CStripedTestTuner::~CStripedTestTuner()
{
releaseFilters();
}
bool CStripedTestTuner::init(IBaseFilter* pVmr9)
{
HRESULT hr;
this->pVmr9 = pVmr9;
hr = initGraph();
if (FAILED(hr)) {
releaseFilters();
setError(hr);
return SUCCEEDED(hr);
}
hr = buildGraph();
if (FAILED(hr)) {
setError(hr);
releaseFilters();
return SUCCEEDED(hr);
}
return true;
}
HRESULT CStripedTestTuner::initGraph()
{
HRESULT hr;
// create Capture Graph Builder
hr = CoCreateInstance((REFCLSID)CLSID_CaptureGraphBuilder2, NULL,
CLSCTX_INPROC,
(REFIID)IID_ICaptureGraphBuilder2, (void**)&pCapGrphBld);
if (FAILED(hr)) {
return hr;
}
// create Filter Graph Builder
hr = CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC,
IID_IGraphBuilder, (LPVOID*)&pGrphBld);
if (FAILED(hr)) {
return hr;
}
// Attach the filter graph to the capture graph
hr = pCapGrphBld->SetFiltergraph(pGrphBld);
if (FAILED(hr)) {
return hr;
}
// Use the system device enumerator and class enumerator to find
// a video capture/preview device.
hr = findCaptureDevice(&pVCapDevFilter);
if (FAILED(hr)) {
return hr;
}
// Add Capture filter to the graph
hr = pGrphBld->AddFilter(pVCapDevFilter, L"Video Capture");
if (FAILED(hr)) {
return hr;
}
captureDeviceType = 2; //***** IF THIS int IS NOT SET (OR SET TO 0 (ZERO))
IT DOES NOT FAIL...!
return S_OK;
}
HRESULT CStripedTestTuner::findCaptureDevice(IBaseFilter** ppSrcFilter)
{
HRESULT hr;
*ppSrcFilter = NULL;
IMoniker* pMoniker = NULL;
ULONG cFetched;
// Create the system device enumerator
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
IEnumMoniker* pClassEnum = NULL;
hr = pDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory,
&pClassEnum, 0);
if (FAILED(hr)) {
pDevEnum->Release();
return hr;
}
pDevEnum->Release();
// If there are no enumerators for the requested type, then
// CreateClassEnumerator will succeed, but pClassEnum will be NULL.
if (pClassEnum == NULL) {
return E_FAIL;
}
// Use the first video capture device on the device list.
if (pClassEnum->Next(1, &pMoniker, &cFetched) == S_OK) {
// Bind Moniker to a filter object
hr = pMoniker->BindToObject(NULL, NULL, IID_IBaseFilter,
(void**)ppSrcFilter);
pMoniker->Release();
pMoniker = NULL;
if (FAILED(hr)) {
pClassEnum->Release();
pMoniker->Release();
return hr;
}
}
else {
pClassEnum->Release();
return E_FAIL;
}
pClassEnum->Release();
return S_OK;
}
HRESULT CStripedTestTuner::buildGraph()
{
HRESULT hr;
// get the capture pin of the capture filter
IPin* pCapPin;
hr = pCapGrphBld->FindPin(pVCapDevFilter, PINDIR_OUTPUT,
&PIN_CATEGORY_CAPTURE, NULL, FALSE, 0, &pCapPin);
if (FAILED(hr)) {
return hr;
}
switch (captureDeviceType) {
case YUY2:
//**************** IF THIS SECTION IS COMMENTED OUT IT WILL NOT FAIL
EITHER...!
hr = pCapGrphBld->FindInterface(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video,
pVCapDevFilter, IID_IAMStreamConfig, (void**)&pSConfig);
if (FAILED(hr)) {
pCapPin->Release();
return hr;
}
pCapPin->Release();
pSConfig->Release();
//*********************************
break;
}
pCapPin->Release();
return S_OK;
}
void CStripedTestTuner::releaseFilters()
{
if (pVCapDevFilter != NULL) {
pVCapDevFilter->Release();
pVCapDevFilter = NULL;
}
if (pSConfig != NULL) {
pSConfig->Release(); //******** FAILS ON RELEASING THE SECOND COM
INTERFACE, NO MATTER WHICH ONE THAT IS...!
pSConfig = NULL;
}
if (pMediaCtrl != NULL) {
pMediaCtrl->Release();
pMediaCtrl = NULL;
}
if (pWc9 != NULL) {
pWc9->Release();
pWc9 = NULL;
}
if (pAnalogVideoDecoder != NULL) {
pAnalogVideoDecoder->Release();
pAnalogVideoDecoder = NULL;
}
if (pMpeg2Demuxer != NULL) {
pMpeg2Demuxer->Release();
pMpeg2Demuxer = NULL;
}
if (pTVTuner != NULL) {
pTVTuner->Release();
pTVTuner = NULL;
}
if (pVideoPin != NULL) {
pVideoPin->Release();
pVideoPin = NULL;
}
if (pAudioPin != NULL) {
pAudioPin->Release();
pAudioPin = NULL;
}
if (pGrphBld != NULL) {
pGrphBld->Release();
pGrphBld = NULL;
}
if (pCapGrphBld != NULL) {
ULONG refCount = pCapGrphBld->Release();
pCapGrphBld = NULL;
}
}
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR
lpCmdLine, int nCmdShow) {
if (!createWindow(AppWndProc, width, height)) {
// could not create window...
return 3;
}
if (FAILED(CoInitializeEx(NULL, COINIT_MULTITHREADED))) {
return 1;
}
IBaseFilter* pVmr9 = NULL;
if (!createVmr9(&pVmr9)) {
CoUninitialize();
return 7;
}
tuner = new CStripedTestTuner();
if (!tuner->init(pVmr9)) {
pVmr9->Release();
delete tuner;
CoUninitialize();
return 4;
}
ShowWindow(ghAppWnd, SW_SHOWNORMAL);
MSG msg;
while (GetMessage(&msg, NULL, 0, 0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
pVmr9->Release();
delete tuner;
CoUninitialize();
return 0;
}
.
- Follow-Ups:
- Re: Simply WEIRD! Is this a directx/driver bug!
- From: Sarat Venugopal
- Re: Simply WEIRD! Is this a directx/driver bug!
- From: The March Hare [MVP]
- Re: Simply WEIRD! Is this a directx/driver bug!
- Prev by Date: RE: VMR-9 & video capture
- Next by Date: Re: VMR-9 & video capture
- Previous by thread: VMR-9 & video capture
- Next by thread: Re: Simply WEIRD! Is this a directx/driver bug!
- Index(es):
Relevant Pages
|