Processing video from a webcam

Hi, I wrote oone app that captures video from a webcam (it's the one in Mark Pesce's book of DirectShow). It works perfectly but it only
records around 7-8 seconds. I want to make this modifications but I
don't know how so I ask you to help me:

1. I want the app not to stop recording at 8 seconds, I want me to stop
it when I want.
2. I don't want sound.

The app shows a window with the video it is recording and writes it
into a file. I want it to filter those frames with another kind of
filter (a Sobel one for example).

3. In order to make this I think I have to connect the output file of
the Smart Tee Filter (Capture or Preview, which is faster ) to another
new filter (a Sobel one in the example) instead than to a Video
Renderer,don't I If that is not correct please tell me what should I
do and if that's the solution please tell me how should I make that
connection and how should I create a new filter (the Sobel one).

I put my code for you to see what my app is doing and where should add
or remove code:

void main(){

ICaptureGraphBuilder2 *pCaptureGraph = NULL;
IGraphBuilder *pGraph = NULL;
IMediaControl *pControl = NULL;
IFileSinkFilter *pSink = NULL;
IBaseFilter *pAudioInputFilter = NULL;
IBaseFilter *pVideoInputFilter = NULL;
IBaseFilter *pASFWriter = NULL;

HRESULT hr = CoInitialize(NULL);

if (FAILED(hr)){
printf("ERROR inicializando libreria COM");

}

hr = CoCreateInstance(CLSID_CaptureGraphBuilder2, NULL,
CLSCTX_INPROC_SERVER,
IID_ICaptureGraphBuilder2, (void**)&pCaptureGraph);
if (FAILED(hr)){
printf("ERROR no se puede crear el Filter Graph Manager");
}

hr =
pCaptureGraph->SetOutputFileName(&MEDIASUBTYPE_Asf,L"C:\\MyWebcam.ASF",&pAS
FWriter,&pSink);

hr = ShowFilterPropertyPages(pASFWriter); //Funcion que hare mas abajo

hr = pCaptureGraph->GetFiltergraph(&pGraph);

hr = pGraph->QueryInterface(IID_IMediaControl,(void**)&pControl);

if (FAILED(hr)){
printf("Error al crear el Media Control object");
CoUninitialize();

}

hr = GetAudioInputFilter(&pAudioInputFilter); // Es casi = q la funcion
EnumerateAudioInputFilters
//que esta en el capitulo anterior del libro

if (SUCCEEDED(hr)){
hr = pGraph->AddFilter(pAudioInputFilter,L"WebCam Audio Capture");

}

hr = GetVideoInputFilter(&pVideoInputFilter);//Parecida la de
GetAudio...

if (SUCCEEDED(hr)){
hr = pGraph->AddFilter(pVideoInputFilter,L"WebCam Video Capture");

}

IBaseFilter *pIntermediate = NULL;

hr =
pCaptureGraph->RenderStream(&PIN_CATEGORY_PREVIEW,&MEDIATYPE_Video,
pVideoInputFilter,
NULL,NULL);

hr =
pCaptureGraph->RenderStream(&PIN_CATEGORY_CAPTURE,&MEDIATYPE_Video,
pVideoInputFilter,
NULL,pASFWriter);

hr =
pCaptureGraph->RenderStream(&PIN_CATEGORY_CAPTURE,&MEDIATYPE_Audio,
pAudioInputFilter,
NULL,pASFWriter);

if(SUCCEEDED(hr)){
hr = pControl->Run();
if(SUCCEEDED(hr)){
wprintf(L"Started Recording...Press Enter to stop,\n");
char ch;
ch = getchar();
}

}

hr = pControl->Stop();

wprintf(L"Stopped recording.\n");

SaveGraphFile(pGraph,L"C:\\Mygraph.GRF");

pSink->Release();
pASFWriter->Release();
pVideoInputFilter->Release(),
pAudioInputFilter->Release();
pControl->Release();
pGraph->Release();
pCaptureGraph->Release();
CoUninitialize();

}

And this are the functions that main calls:

HRESULT SaveGraphFile(IGraphBuilder *pGraph, WCHAR *wszPath){

const WCHAR wszStreamName[] = L"ActiveMovieGraph";
HRESULT hr;
IStorage *pStorage = NULL;

hr = StgCreateDocfile(wszPath,
STGM_CREATE|STGM_TRANSACTED|STGM_READWRITE|STGM_SHARE_EXCLUSIVE,
0,&pStorage);

if (FAILED(hr)){
return (hr);
}

IStream *pStream;

hr =
pStorage->CreateStream(wszStreamName,STGM_WRITE|STGM_CREATE|STGM_SHARE_EXCLUSIVE,
0,0,&pStream);

if (FAILED(hr)){
pStorage->Release();
return (hr);
}

IPersistStream *pPersist = NULL;

pGraph->QueryInterface(IID_IPersistStream,reinterpret_cast<void**>(&pPersist));

hr = pPersist->Save(pStream, TRUE);

pStream->Release();
pPersist->Release();

if(SUCCEEDED(hr)){
hr = pStorage->Commit(STGC_DEFAULT);
}
pStorage->Release();

return hr;

}

HRESULT ShowFilterPropertyPages(IBaseFilter *pFilter){

ISpecifyPropertyPages *pProp;
HRESULT hr =
pFilter->QueryInterface(IID_ISpecifyPropertyPages,(void**)&pProp);

if(SUCCEEDED(hr)){
FILTER_INFO FilterInfo;
hr = pFilter->QueryFilterInfo(&FilterInfo);
IUnknown *pFilterUnk;
pFilter->QueryInterface(IID_IUnknown,(void**)&pFilterUnk);
CAUUID caGUID;
pProp->GetPages(&caGUID);
pProp->Release();

OleCreatePropertyFrame(NULL,0,0,FilterInfo.achName,1,&pFilterUnk,caGUID.cElems,
caGUID.pElems,0,0,NULL);

pFilterUnk->Release();
FilterInfo.pGraph->Release();
CoTaskMemFree(caGUID.pElems);

}
return hr;

}

HRESULT GetAudioInputFilter(IBaseFilter** gottaFilter){

ICreateDevEnum *pSysDevEnum = NULL;
HRESULT hr =
CoCreateInstance(CLSID_SystemDeviceEnum,NULL,CLSCTX_INPROC_SERVER,
IID_ICreateDevEnum,(void**)&pSysDevEnum);

if(FAILED(hr)){
return hr;
}

IEnumMoniker *pEnumCat = NULL;
hr =
pSysDevEnum->CreateClassEnumerator(CLSID_AudioInputDeviceCategory,&pEnumCat,0);

if(hr == S_OK){
IMoniker *pMoniker = NULL;
ULONG cFetched;
if(pEnumCat->Next(1,&pMoniker,&cFetched)==S_OK){
IPropertyBag *pPropBag;
hr =
pMoniker->BindToStorage(0,0,IID_IPropertyBag,(void**)&pPropBag);
if(SUCCEEDED(hr)){
VARIANT varName;
VariantInit(&varName);
hr = pPropBag->Read(L"Labtec",&varName,0);
if(SUCCEEDED(hr)){
wprintf(L"Selecting Audio Input Device: %s\n",varName.bstrVal);
}
VariantClear(&varName);

hr =
pMoniker->BindToObject(NULL,NULL,IID_IBaseFilter,(void**)gottaFilter);
pPropBag->Release();
}
pMoniker->Release();
}
pEnumCat->Release();
}
pSysDevEnum->Release();
return hr;

}

HRESULT GetVideoInputFilter(IBaseFilter** gottaFilter){

ICreateDevEnum *pSysDevEnum = NULL;
HRESULT hr =
CoCreateInstance(CLSID_SystemDeviceEnum,NULL,CLSCTX_INPROC_SERVER,
IID_ICreateDevEnum,(void**)&pSysDevEnum);

if(FAILED(hr)){
return hr;
}

IEnumMoniker *pEnumCat = NULL;
hr =
pSysDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory,&pEnumCat,0);

if(hr == S_OK){
IMoniker *pMoniker = NULL;
ULONG cFetched;
if(pEnumCat->Next(1,&pMoniker,&cFetched)==S_OK){
IPropertyBag *pPropBag;
hr =
pMoniker->BindToStorage(0,0,IID_IPropertyBag,(void**)&pPropBag);
if(SUCCEEDED(hr)){
VARIANT varName;
VariantInit(&varName);
hr = pPropBag->Read(L"Labtec",&varName,0);
if(SUCCEEDED(hr)){
wprintf(L"Selecting Video Input Device: %s\n",varName.bstrVal);
}
VariantClear(&varName);

hr =
pMoniker->BindToObject(NULL,NULL,IID_IBaseFilter,(void**)gottaFilter);
pPropBag->Release();
}
pMoniker->Release();
}
pEnumCat->Release();
}
pSysDevEnum->Release();
return hr;



Answer this question

Processing video from a webcam