Simply WEIRD! Is this a directx/driver bug!

Tech-Archive recommends: Repair Windows Errors & Optimize Windows Performance



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;
}
.



Relevant Pages

  • Re: Threads and the OleDbDataReader Class
    ... on the COM component for the interface with IID '{0C733A7C-2A1C-11CE- ... apartment model when executing, and failures vary. ... reader to individual GUI elements as needed, either one at a time (i.e. ...  The program fails when I access the ...
    (microsoft.public.dotnet.languages.csharp)
  • Re: Catalyst 6500 [FWSM] [CSM]
    ... Actually, FWSM fails over when a monitored interface "fails", not when ... context, FWSM is not going to fail over; but if one of your monitored ... monitor-interface outside ... An interface "fail" means it did not pass one of the FWSM's regular ...
    (comp.dcom.sys.cisco)
  • Re: Threads and the OleDbDataReader Class
    ... on the COM component for the interface with IID '{0C733A7C-2A1C-11CE- ... you omitted exactly the part of the code where it actually fails. ... apartment model when executing, and failures vary. ... reader to individual GUI elements as needed, either one at a time (i.e. ...
    (microsoft.public.dotnet.languages.csharp)
  • Re: IS:: VOS Loopback interfaces
    ... >> I'd like to configure a loopback interface, additionaly to 127.0.0.1, ... > the IP layer (Can't remember when the primary fails if the secondary ... failover if the active adapter loses link or fails outright. ...
    (comp.sys.stratus)