//===============================================================================
//		
//===============================================================================
HRESULT DetectionModule_touchLib::DetectionModuleInit(WCHAR* videoFilename, WCHAR* saveGraphFileName, WCHAR* loadGraphFilename)
{
	HRESULT hr = S_OK;

	GSGraphBase::CreateGraph();


	hr = AddSourceFilter(videoFilename);
	hr = CreateFilters(); //or using loading graph 
	//hr = LoadGraphFile(graphFilename);
	hr = GetFiltersAndInterfaces();
	hr = GetPins();
	hr = ConnectGraph();


	m_paramSet = GetDefaultParameters();

	// Set call back function in FindBlobFilter
	void* myDM[]={this};
	m_pIFindBlobFilter->SetCallbackFunction(DetectionModule_touchLib::FingerResultCallBack,1,myDM);

	//--- Save current graph ---
	if(saveGraphFileName != NULL)
	{
		hr = SaveGraphFile(saveGraphFileName);
	}


	return hr;
}
Exemple #2
0
HRESULT CaptureGraph::BuildGraph(CString subName)
{
	if(pGraph != NULL)
	{
		HRESULT hr;
		CComPtr<ICreateDevEnum> pSysVideoCaptureEnum = NULL;
		hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER, IID_ICreateDevEnum, (void **)&pSysVideoCaptureEnum);
		if(FAILED(hr)) return hr;

		CComPtr<IBaseFilter> pVideoCapture = NULL;
		CComPtr<IEnumMoniker> pEnumMoniker = NULL;
		hr = pSysVideoCaptureEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory, &pEnumMoniker, 0);
		if(FAILED(hr)) return hr;

		CComPtr<IMoniker> pMoniker = NULL;
		ULONG fetched;

		while(pEnumMoniker->Next(1, &pMoniker, &fetched) == S_OK)
		{
			CComPtr<IPropertyBag> pPropBag;
			hr = pMoniker->BindToStorage(0, 0, IID_IPropertyBag, (void **)&pPropBag);
			if(SUCCEEDED(hr))
			{
				VARIANT varName;
				VariantInit(&varName);
				hr = pPropBag->Read(L"FriendlyName", &varName, 0);
				if(SUCCEEDED(hr))
				{
					ASSERT(varName.vt == VT_BSTR);
					CString friendlyName(varName.bstrVal);

					if(friendlyName.Find(subName) != -1)
					{
						pMoniker->BindToObject(NULL, NULL, IID_IBaseFilter, (void **)&pVideoCapture);
						break;
					}

				}
			}
		}

		if(pVideoCapture != NULL)
		{
			hr = pGraph->AddFilter(pVideoCapture, L"Video Capture");
			if(FAILED(hr)) return hr;
		}
		//Replace this to add nullip filter.
		hr = pCaptureBuilder2->RenderStream(&PIN_CATEGORY_PREVIEW, &MEDIATYPE_Video, pVideoCapture, NULL, NULL);
		if(FAILED(hr)) return hr;

		hr = SaveGraphFile(pGraph, L"D:\\VideoCapture.grf");
		return hr;
	}
	return E_FAIL;
}
Exemple #3
0
BOOL CDShowCtrl::SaveGraph(LPCWSTR filePath)
{
	if( this->graph == NULL ){
		return FALSE;
	}
	BOOL ret = TRUE;

	HRESULT hr = SaveGraphFile(this->graph, filePath);
	if (FAILED(hr)){
		return FALSE;
	}

	return ret;
}
Exemple #4
0
HRESULT CTMReceiverGraph::BuildFilterGraph(const char* fileName, BOOL bDisplay)
{
	HRESULT hr = S_FALSE;
	if(m_pGraphBuilder != NULL)
	{
		m_bDisplay = bDisplay;

		CComPtr<IBaseFilter> pSrc;
		hr = CoCreateInstance(CLSID_TMReceiverSrc, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void **)&pSrc);
		if(FAILED(hr)) return hr;
		hr = pSrc->QueryInterface(IID_IRecordStream, (void **)&m_pRecordStream);
		if(FAILED(hr)) return hr;
		hr = pSrc->QueryInterface(IID_ISetCallBack, (void **)&m_pSetCallBack);
		if(FAILED(hr)) return hr;
		CComPtr<IFileSourceFilter> pFileSrc;
		hr = pSrc->QueryInterface(IID_IFileSourceFilter, (void **)&pFileSrc);
		if(FAILED(hr)) return hr;
		CString fileNameCStr(fileName);
		hr = pFileSrc->Load(fileNameCStr, NULL);
		if(FAILED(hr)) return hr;
		hr = m_pGraphBuilder->AddFilter(pSrc, L"Src Filter");
		if(FAILED(hr)) return hr;

		CComPtr<IBaseFilter> pRenderer;
		if(bDisplay)
		{
			hr = CoCreateInstance(CLSID_VideoRenderer, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void **)&pRenderer);
			if(FAILED(hr)) return hr;
		}
		else
		{
			hr = CoCreateInstance(CLSID_NullRenderer, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void **)&pRenderer);
			if(FAILED(hr)) return hr;
		}
		hr = m_pGraphBuilder->AddFilter(pRenderer, L"Renderer");
		if(FAILED(hr)) return hr;

		hr = ConnectFilters(m_pGraphBuilder, pSrc, pRenderer, MEDIATYPE_NULL);
		if(FAILED(hr)) return hr;

		hr = SaveGraphFile(m_pGraphBuilder, L"H:\\TMReceiver.grf");
		return S_OK;
	}
	return E_FAIL;
}
Exemple #5
0
HRESULT CDXGraph::RenderFile(CString mSourceFile)
{
	if(pGraph != NULL)
	{
		//pGraph->RenderFile(mSourceFile, NULL);
		//add grabber filter
		IBaseFilter *pGrabberF = NULL;
		this->AddGrabber(&pGrabberF);
		//add source filter
		IBaseFilter *pSrc;
		HRESULT hr = pGraph->AddSourceFilter(mSourceFile, L"Source", &pSrc);
		if(FAILED(hr)) return hr;
		/*IBaseFilter *pSrc;
		HRESULT hr = CoCreateInstance(CLSID_FFSrcFilter, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void **)&pSrc);
		if (FAILED(hr)) return hr;
		hr = pGraph->AddFilter(pSrc, L"SrcFilter");
		if (FAILED(hr)) return hr;*/
		hr = pSrc->QueryInterface(IID_INetDvr, (void **)&pNetDvr);
		if (FAILED(hr)) return hr;
		

		//add renderer filter
		IBaseFilter *pRender;
		hr = CoCreateInstance(CLSID_VideoRenderer, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void **)&pRender);
		if (FAILED(hr)) return hr;
		hr = pGraph->AddFilter(pRender, L"Renderer");
		if (FAILED(hr)) return hr;

		
		hr = ConnectFilters(pGraph, pSrc, pGrabberF, MEDIATYPE_NULL);
		hr = ConnectFilters(pGraph, pGrabberF, pRender, MEDIATYPE_NULL);
		pGrabberF->Release();
		pSrc->Release();
		pRender->Release();
		//test the graph
		SaveGraphFile(pGraph, L"D:\\SliderPlayer_264.grf");
		return hr;
	}
	return E_FAIL;
}
Exemple #6
0
HRESULT CaptureGraph::BuildGraphFromListBox(CListBox *captureFilterList, int selectedIndex)
{
	if(pGraph != NULL)
	{
		HRESULT hr;
		//dump the graph
		IMoniker *pSelectedCaptureMoniker = (IMoniker *)captureFilterList->GetItemDataPtr(selectedIndex);
		IBaseFilter *pCaptureFilter = NULL;
		hr = pSelectedCaptureMoniker->BindToObject(NULL, NULL, IID_IBaseFilter, (void **)&pCaptureFilter);
		if(FAILED(hr))
		{
			return hr;
		}
		pGraph->AddFilter(pCaptureFilter, L"Video Capture");
		hr = pCaptureBuilder2->RenderStream(&PIN_CATEGORY_PREVIEW, &MEDIATYPE_Video, pCaptureFilter, NULL, NULL);
		if(FAILED(hr))
		{
			return hr;
		}
		hr = SaveGraphFile(pGraph, L"D:\\VideoCapture.grf");
		return hr;
	}
	return E_FAIL;
}
Exemple #7
0
HRESULT RecordGraph::BuildGraph(CString recordFileName)
{
	HRESULT hr;
	ICreateDevEnum *pSysAudioCaptureEnum = NULL;
	hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER, IID_ICreateDevEnum, (void **)&pSysAudioCaptureEnum);
	if (FAILED(hr))
	{
		return hr;
	}

	IBaseFilter *pAudioCapture = NULL;
	IEnumMoniker *pEnumMoniker = NULL;
	hr = pSysAudioCaptureEnum->CreateClassEnumerator(CLSID_AudioInputDeviceCategory, &pEnumMoniker, 0);
	if (hr == S_OK)
	{
		IMoniker *pMoniker = NULL;
		ULONG fetched;
		BOOL findMicrophone = FALSE;
		while(pEnumMoniker->Next(1, &pMoniker, &fetched) == S_OK && !findMicrophone)
		{
			IPropertyBag *pPropBag;
			hr = pMoniker->BindToStorage(0, 0, IID_IPropertyBag, (void **)&pPropBag);
			if(SUCCEEDED(hr))
			{
				VARIANT varName;
				VariantInit(&varName);
				hr = pPropBag->Read(L"FriendlyName", &varName, 0);
				if(SUCCEEDED(hr))
				{
					ASSERT(varName.vt == VT_BSTR);
					CString friendlyName(varName.bstrVal);
					if(friendlyName.Find(L"Microphone") >= 0)
					{
						hr = pMoniker->BindToObject(NULL, NULL, IID_IBaseFilter, (void **)&pAudioCapture);
						findMicrophone = TRUE;
					}
					VariantClear(&varName);
					pPropBag->Release();
				}
			}
		}
		pEnumMoniker->Release();
	}
	pSysAudioCaptureEnum->Release();
	if(pAudioCapture == NULL)
	{
		return S_FALSE;
	}
	pBuilder->AddFilter(pAudioCapture, L"Audio Capture");

	IBaseFilter *pWaveDest = NULL;
	hr = CoCreateInstance(CLSID_WavDest, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void **)&pWaveDest);
	if(FAILED(hr))
	{
		return hr;
	}
	pBuilder->AddFilter(pWaveDest, L"Wave Dest");

	IBaseFilter *pFileWriter = NULL;
	hr = CoCreateInstance(CLSID_FileWriter, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void **)&pFileWriter);
	if(FAILED(hr))
	{
		return hr;
	}
	pBuilder->AddFilter(pFileWriter, L"File Writer");
	IFileSinkFilter *pFileSetter = NULL;
	hr = pFileWriter->QueryInterface(IID_IFileSinkFilter, (void **)&pFileSetter);
	if(FAILED(hr))
	{
		return hr;
	}
	AM_MEDIA_TYPE pmt;
	pmt.majortype = MEDIATYPE_Stream;
	pmt.subtype = MEDIASUBTYPE_WAVE;
	pmt.formattype = FORMAT_WaveFormatEx;
	hr = pFileSetter->SetFileName(recordFileName, &pmt);

	hr = ConnectFilters(pBuilder, pAudioCapture, pWaveDest, MEDIATYPE_NULL);if(FAILED(hr)) return hr;
	hr = ConnectFilters(pBuilder, pWaveDest, pFileWriter, MEDIATYPE_NULL);//if(FAILED(hr)) return hr;
	SaveGraphFile(pBuilder, L"D:\\Record.grf");

	pFileSetter->Release();
	pFileWriter->Release();
	pWaveDest->Release();
	pAudioCapture->Release();
}
bool DShowMoviePlayer::loadMovie (void)
{
	if (!_oleInitialized)
	{
		::CoInitialize (0);
	}

	char physicFileName[512];
	wchar_t physicFileNameW[512];
	ATOM_GetNativePathName (_fileName.c_str(), physicFileName);
	if (!convertCStringToWString (physicFileName, physicFileNameW, 512))
	{
		ATOM_LOGGER::error ("%s() %s\n", __FUNCTION__, "Error converting C string filename to UNICODE");
		return false;
	}

#if 1
	HRESULT hr = ::CoCreateInstance (CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, IID_IGraphBuilder, (void**)&_graphBuilder);
	if (FAILED(hr))
	{
		ATOM_LOGGER::error ("%s() %s\n", __FUNCTION__, "[DSHOW] Error creating graph");
		return false;
	}

	hr = ::CoCreateInstance (CLSID_SampleGrabber, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void**)&_grabberFilter);
	if (FAILED(hr))
	{
		ATOM_LOGGER::error ("%s() %s\n", __FUNCTION__, "[DSHOW] Error creating sample grabber");
		return false;
	}

	hr = _grabberFilter->QueryInterface (IID_ISampleGrabber, (void**)&_grabber);
	if (FAILED(hr))
	{
		ATOM_LOGGER::error ("%s() %s\n", __FUNCTION__, "[DSHOW] Error querying sample grabber");
		return false;
	}

	AM_MEDIA_TYPE mt;
	memset (&mt, 0, sizeof(AM_MEDIA_TYPE));
	mt.majortype = MEDIATYPE_Video;
	mt.subtype = MEDIASUBTYPE_RGB32;
	mt.formattype = FORMAT_VideoInfo;
	hr = _grabber->SetMediaType (&mt);
	if (FAILED(hr))
	{
		ATOM_LOGGER::error ("%s() %s\n", __FUNCTION__, "[DSHOW] Error setting smaple grabber media type");
		return false;
	}

	hr = _graphBuilder->AddFilter (_grabberFilter, L"Sample Grabber");
	if (FAILED(hr))
	{
		ATOM_LOGGER::error ("%s() %s\n", __FUNCTION__, "[DSHOW] Error adding filter");
		return false;
	}

	hr = _graphBuilder->QueryInterface (IID_IMediaControl, (void**)&_control);
	if (FAILED(hr))
	{
		ATOM_LOGGER::error ("%s() %s\n", __FUNCTION__, "[DSHOW] Error querying media control");
		return false;
	}

	IBaseFilter *render = 0;
	hr = ::CoCreateInstance (CLSID_NullRenderer, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void**)&render);
	if (FAILED(hr))
	{
		ATOM_LOGGER::error ("%s() %s\n", __FUNCTION__, "[DSHOW] Error creating render filter");
		return false;
	}

	hr = _graphBuilder->AddFilter (render, L"Null renderer");
	if (FAILED(hr))
	{
		ATOM_LOGGER::error ("%s() %s\n", __FUNCTION__, "[DSHOW] Error adding null-renderer filter");
		return false;
	}

	hr = _control->RenderFile (physicFileNameW);
	if (FAILED(hr))
	{
		ATOM_LOGGER::error ("%s() %s\n", __FUNCTION__, "[DSHOW] Error rendering file");
		return false;
	}
#if 0
	IPin *grabberOut = 0;
	FindPin (_grabberFilter, PINDIR_OUTPUT, 0, &grabberOut);
	if (grabberOut)
	{
		grabberOut->Disconnect ();
		grabberOut->Release ();
	}
#endif

	SaveGraphFile (_graphBuilder, L"C:\\test.grf");
	hr = _graphBuilder->QueryInterface (IID_IVideoWindow, (void**)&_window);
	if (FAILED(hr))
	{
		ATOM_LOGGER::error ("%s() %s\n", __FUNCTION__, "[DSHOW] Error querying video window");
		return false;
	}

	_window->put_AutoShow (OAFALSE);

#if 0
	if (!ConnectPins (_graphBuilder, _grabberFilter, 0, render, 0))
	{
		return false;
	}
	_control->RenderFile (physicFileNameW);
#endif

	memset(&mt, 0, sizeof(mt));
	mt.majortype = MEDIATYPE_Video;
	mt.subtype = MEDIASUBTYPE_RGB32;
	mt.formattype = FORMAT_VideoInfo;

	hr = _grabber->GetConnectedMediaType (&mt);
	if (FAILED(hr))
	{
		ATOM_LOGGER::error ("%s() %s\n", __FUNCTION__, "[DSHOW] Error getting connected media type");
		return false;
	}

	VIDEOINFOHEADER *vih = (VIDEOINFOHEADER*)mt.pbFormat;
	_videoWidth = vih->bmiHeader.biWidth;
	_videoHeight = vih->bmiHeader.biHeight;
	_bufferSize = mt.lSampleSize;
	if (mt.cbFormat != 0)
	{
		::CoTaskMemFree ((PVOID)mt.pbFormat);
		mt.cbFormat = 0;
		mt.pbFormat = 0;
	}
	if (mt.pUnk != NULL)
	{
		mt.pUnk->Release ();
		mt.pUnk = NULL;
	}

	_grabber->SetOneShot (FALSE);
	_grabber->SetBufferSamples (TRUE);

	hr = _graphBuilder->QueryInterface (IID_IMediaEvent, (void**)&_event);
	if (FAILED(hr))
	{
		ATOM_LOGGER::error ("%s() %s\n", __FUNCTION__, "[DSHOW] Error querying media event");
		return false;
	}

	hr = _graphBuilder->QueryInterface (IID_IMediaSeeking, (void**)&_seeking);
	if (FAILED(hr))
	{
		ATOM_LOGGER::error ("%s() %s\n", __FUNCTION__, "[DSHOW] Error querying media seeking");
		return false;
	}

#else
	HRESULT hr = ::CoCreateInstance (CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, IID_IGraphBuilder, (void**)&_graphBuilder);
	if (FAILED(hr))
	{
		ATOM_LOGGER::error ("%s() %s\n", __FUNCTION__, "[DSHOW] Error creating graph");
		return false;
	}

	hr = _graphBuilder->QueryInterface (IID_IMediaControl, (void**)&_control);
	if (FAILED(hr))
	{
		ATOM_LOGGER::error ("%s() %s\n", __FUNCTION__, "[DSHOW] Error querying media control");
		return false;
	}

	hr = _graphBuilder->QueryInterface (IID_IMediaEvent, (void**)&_event);
	if (FAILED(hr))
	{
		ATOM_LOGGER::error ("%s() %s\n", __FUNCTION__, "[DSHOW] Error querying media event");
		return false;
	}

	hr = _graphBuilder->QueryInterface (IID_IMediaSeeking, (void**)&_seeking);
	if (FAILED(hr))
	{
		ATOM_LOGGER::error ("%s() %s\n", __FUNCTION__, "[DSHOW] Error querying media seeking");
		return false;
	}

	hr = ::CoCreateInstance (CLSID_SampleGrabber, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void**)&_grabberFilter);
	if (FAILED(hr))
	{
		ATOM_LOGGER::error ("%s() %s\n", __FUNCTION__, "[DSHOW] Error creating sample grabber");
		return false;
	}

	hr = _graphBuilder->AddFilter (_grabberFilter, L"Sample Grabber");
	if (FAILED(hr))
	{
		ATOM_LOGGER::error ("%s() %s\n", __FUNCTION__, "[DSHOW] Error adding filter");
		return false;
	}

	hr = _grabberFilter->QueryInterface (IID_ISampleGrabber, (void**)&_grabber);
	if (FAILED(hr))
	{
		ATOM_LOGGER::error ("%s() %s\n", __FUNCTION__, "[DSHOW] Error querying sample grabber");
		return false;
	}

	AM_MEDIA_TYPE mt;
	memset (&mt, 0, sizeof(AM_MEDIA_TYPE));
	mt.majortype = MEDIATYPE_Video;
	mt.subtype = MEDIASUBTYPE_RGB24;
	mt.formattype = FORMAT_VideoInfo;
	hr = _grabber->SetMediaType (&mt);
	if (FAILED(hr))
	{
		ATOM_LOGGER::error ("%s() %s\n", __FUNCTION__, "[DSHOW] Error setting smaple grabber media type");
		return false;
	}

	IBaseFilter *srcFilter = 0;
	hr = _graphBuilder->AddSourceFilter (physicFileNameW, L"Source", &srcFilter);
	if (FAILED(hr))
	{
		ATOM_LOGGER::error ("%s() %s\n", __FUNCTION__, "[DSHOW] Error adding source filter");
		return false;
	}

	hr = connectFilters (_graphBuilder, srcFilter, _grabberFilter);
	if (FAILED(hr))
	{
		ATOM_LOGGER::error ("%s() %s\n", __FUNCTION__, "[DSHOW] Error connecting filters");
		return false;
	}

	IBaseFilter *render = 0;
	hr = ::CoCreateInstance (CLSID_NullRenderer, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void**)&render);
	if (FAILED(hr))
	{
		ATOM_LOGGER::error ("%s() %s\n", __FUNCTION__, "[DSHOW] Error creating render filter");
		return false;
	}

	_graphBuilder->AddFilter (render, L"Render");

	hr = connectFilters (_graphBuilder, _grabberFilter, render);
	if (FAILED(hr))
	{
		ATOM_LOGGER::error ("%s() %s\n", __FUNCTION__, "[DSHOW] Error connect filters");
		return false;
	}

	hr = _graphBuilder->RenderFile (physicFileNameW, NULL);
	if (FAILED(hr))
	{
		ATOM_LOGGER::error ("%s() %s\n", __FUNCTION__, "[DSHOW] Error rendering file");
		return false;
	}

	hr = _graphBuilder->QueryInterface (IID_IVideoWindow, (void**)&_window);
	if (FAILED(hr))
	{
		ATOM_LOGGER::error ("%s() %s\n", __FUNCTION__, "[DSHOW] Error querying video window");
		return false;
	}

	_window->put_AutoShow (OAFALSE);

	AM_MEDIA_TYPE mtt;
	hr = _grabber->GetConnectedMediaType (&mtt);
	if (FAILED(hr))
	{
		ATOM_LOGGER::error ("%s() %s\n", __FUNCTION__, "[DSHOW] Error getting connected media type info");
		return false;
	}
	
	VIDEOINFOHEADER *vih = (VIDEOINFOHEADER*)mtt.pbFormat;
	_videoWidth = vih->bmiHeader.biWidth;
	_videoHeight = vih->bmiHeader.biHeight;
	if (mtt.cbFormat != 0)
	{
		::CoTaskMemFree ((PVOID)mtt.pbFormat);
		mtt.cbFormat = 0;
		mtt.pbFormat = 0;
	}
	if (mtt.pUnk != NULL)
	{
		mtt.pUnk->Release ();
		mtt.pUnk = NULL;
	}

	_grabber->SetOneShot (FALSE);
	_grabber->SetBufferSamples (TRUE);
#endif

	return true;
}
Exemple #9
0
HRESULT CDXGraph::RenderAVIFile(CString mSourceFile)
{
	if(pGraph != NULL)
	{
		//Add Grabber Filter
		IBaseFilter *pGrabberF = NULL;
		this->AddGrabber(&pGrabberF);
		//Add src filter
		IBaseFilter *pSrc;
		HRESULT hr = pGraph->AddSourceFilter(mSourceFile, L"Source", &pSrc);
		if(FAILED(hr)) return hr;
		//Add Avi splitter filter
		IBaseFilter *pAviSplitter = NULL;
		hr = CoCreateInstance(CLSID_AviSplitter, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void **)&pAviSplitter);
		hr = pGraph->AddFilter(pAviSplitter, L"AVI Splitter");
		//Add Mpeg4s decoder dmo filter
		IBaseFilter *pMp4Decoder = NULL;
		hr = CoCreateInstance(CLSID_MPEG4SDecoder, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void **)&pMp4Decoder);
		hr = pGraph->AddFilter(pMp4Decoder, L"Mp4 Decoder");

		//Audio
		//add mp3 decoder
		IBaseFilter *pMP3Decoder = NULL;
		hr = CoCreateInstance(CLSID_MP3Decoder, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void **)&pMP3Decoder);
		hr = pGraph->AddFilter(pMP3Decoder, L"MP3 Decoder");

		//add direct sound device
		IBaseFilter *pDSoundDevice = NULL;
		hr = CoCreateInstance(CLSID_DSoundRender,NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void **)&pDSoundDevice);
		hr = pGraph->AddFilter(pDSoundDevice, L"Sound Renderer");

		//connect filters via pins
		hr = ConnectFilters(pGraph, pSrc, pAviSplitter, MEDIATYPE_NULL);
		//Split to audio and video
		IEnumPins *pEnum = 0;
		IPin *pPin = 0;
		IEnumMediaTypes *pEnumMediaType = 0;
		hr = pAviSplitter->EnumPins(&pEnum);
		bool audio_connected = false, video_connected = false;
		while(pEnum->Next(1, &pPin, NULL) == S_OK)
		{
			hr = pPin->EnumMediaTypes(&pEnumMediaType);
			//if this is video output pin
			if(SUCCEEDED(this->CheckMediaType(pEnumMediaType, MEDIATYPE_Video)))
			{
				IPin *pMP4DecoderInput = NULL;
				hr = this->GetUnconnectedPin(pMp4Decoder, PINDIR_INPUT, &pMP4DecoderInput, MEDIATYPE_NULL);
				hr = pGraph->Connect(pPin, pMP4DecoderInput);
				PIN_INFO pInfo;
				pPin->QueryPinInfo(&pInfo);
				pMP4DecoderInput->QueryPinInfo(&pInfo);
				pMP4DecoderInput->Release();
				video_connected = true;
			}
			//if this is audio output pin
			else if (SUCCEEDED(this->CheckMediaType(pEnumMediaType, MEDIATYPE_Audio)))
			{
				IPin *pMP3DecoderInput = NULL;
				hr = this->GetUnconnectedPin(pMP3Decoder, PINDIR_INPUT, &pMP3DecoderInput, MEDIATYPE_NULL);
				hr = pGraph->Connect(pPin, pMP3DecoderInput);
				pMP3DecoderInput->Release();
				audio_connected = true;
			}
			
			pPin->Release();
			pEnumMediaType->Release();
			if (audio_connected && video_connected)
				break;
		}
		pEnum->Release();
		//Connect Audio Renderer
		hr = this->ConnectFilters(pGraph, pMP3Decoder, pDSoundDevice, MEDIATYPE_Audio);

		//Connect the Mp4Decoder to Sample Grabber
		hr = this->ConnectFilters(pGraph, pMp4Decoder, pGrabberF, MEDIATYPE_NULL);

		//get the output pin of grabber, then render pin
		IPin *pOutPin = NULL;
		this->GetUnconnectedPin(pGrabberF, PINDIR_OUTPUT, &pOutPin, MEDIATYPE_NULL);
		hr = pGraph->Render(pOutPin);

		pGrabberF->Release();
		pSrc->Release();
		pAviSplitter->Release();
		pMp4Decoder->Release();
		pMP3Decoder->Release();
		pDSoundDevice->Release();
		IEnumFilters *pEnumFilter;
		IBaseFilter *pRenderFilter;
		hr = pGraph->EnumFilters(&pEnumFilter);
		//test the graph
		SaveGraphFile(pGraph, L"D:\\SliderPlayer_264.grf");
		return S_OK;
	}
	return E_FAIL;
}
// A very simple program to capture a webcam & audio to a file using DirectShow
//
int main(int argc, char* argv[])
{
    ICaptureGraphBuilder2 *pCaptureGraph = NULL;	// Capture graph builder object
	IGraphBuilder *pGraph = NULL;	// Graph builder object
    IMediaControl *pControl = NULL;	// Media control object
	IFileSinkFilter *pSink = NULL;	// File sink object
	IBaseFilter *pAudioInputFilter = NULL; // Audio Capture filter
	IBaseFilter *pVideoInputFilter = NULL; // Video Capture filter
	IBaseFilter *pASFWriter = NULL;	// WM ASF File config interface

    // Initialize the COM library.
    HRESULT hr = CoInitialize(NULL);
    if (FAILED(hr))
    {
	     // We’ll send our error messages to the console.
        printf("ERROR - Could not initialize COM library");
        return hr;
    }

    // Create the filter graph manager and query for interfaces.
    hr = CoCreateInstance(CLSID_CaptureGraphBuilder2, NULL, CLSCTX_INPROC_SERVER,
                          IID_ICaptureGraphBuilder2, (void **)&pCaptureGraph);
    if (FAILED(hr))	// FAILED is a macro that tests the return value
    {
        printf("ERROR - Could not create the Filter Graph Manager.");
        return hr;
    }

	// Use a method of the capture graph builder
	// To create an output path for the stream 
	hr = pCaptureGraph->SetOutputFileName(&MEDIASUBTYPE_Asf, 
		L"C:\\MyWebcam.ASF", &pASFWriter, &pSink);

	// Now configure the ASF Writer
	// Present the property pages for this filter
	hr = ShowFilterPropertyPages(pASFWriter);

	// Now get the filter graph manager
	// That's part of the capture graph builder
	hr = pCaptureGraph->GetFiltergraph(&pGraph);

	 // Using QueryInterface on the graph builder, 
    // Get the Media Control object.
    hr = pGraph->QueryInterface(IID_IMediaControl, (void **)&pControl);
    if (FAILED(hr))
    {
        printf("ERROR - Could not create the Media Control object.");
        pGraph->Release();	// Clean up after ourselves.
		CoUninitialize();  // And uninitalize COM
        return hr;
    }

	// Get an AudioCapture filter.
	// But there are several to choose from
	// So we need to enumerate them, and pick one.
	// Then add the audio capture filter to the filter graph. 
	hr = GetAudioInputFilter(&pAudioInputFilter, L"Logitech");
	if (SUCCEEDED(hr)) {
		hr = pGraph->AddFilter(pAudioInputFilter, L"Webcam Audio Capture");
	}

	// Now create the video input filter from the webcam
	hr = GetVideoInputFilter(&pVideoInputFilter, L"Logitech");
	if (SUCCEEDED(hr)) {
		hr = pGraph->AddFilter(pVideoInputFilter, L"Webcam Video Capture");
	}

	// Add a video renderer
	//IBaseFilter *pVideoRenderer = NULL;
	//hr = AddFilterByCLSID(pGraph, CLSID_VideoRenderer, L"Video Renderer", &pVideoRenderer);

	// Use another method of the capture graph builder
	// To provide a render path for video preview
	IBaseFilter *pIntermediate = NULL;
	hr = pCaptureGraph->RenderStream(&PIN_CATEGORY_PREVIEW, &MEDIATYPE_Video,
		pVideoInputFilter, NULL, NULL);

	// Now add the video capture to the output file
	hr = pCaptureGraph->RenderStream(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video,
		pVideoInputFilter, NULL, pASFWriter);
	
	// And do the same for the audio
	hr = pCaptureGraph->RenderStream(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Audio,
		pAudioInputFilter, NULL, pASFWriter);

    if (SUCCEEDED(hr))
    {
        // Run the graph.
        hr = pControl->Run();
        if (SUCCEEDED(hr))
        {
			// Wait patiently for completion of the recording
			wprintf(L"Started recording...press Enter to stop recording.\n");

            // Wait for completion.
			char ch;
			ch = getchar();		// We wait for keyboard input
        }

		// And let's stop the filter graph
		hr = pControl->Stop();

		wprintf(L"Stopped recording.\n");	// To the console

		// Before we finish up, save the filter graph to a file.
		SaveGraphFile(pGraph, L"C:\\MyGraph.GRF");
    }

	// Now release everything, and clean up.
	pSink->Release();
	pASFWriter->Release();
	pVideoInputFilter->Release();
	pAudioInputFilter->Release();
    pControl->Release();
    pGraph->Release();
	pCaptureGraph->Release();
    CoUninitialize();

	return 0;
}