000 自己接pin

Post date: 2015/4/20 上午 02:20:17

#include <windows.h> #include <iostream> #include <assert.h> #include <tchar.h> #include <DShow.h> #include <atlbase.h> #include <InitGuid.h> #include <dvdmedia.h> #pragma comment(lib,"amstrmid.lib") #pragma comment( lib, "Strmiids.lib" ) // for DirectShow library #pragma comment( lib, "Quartz.lib" ) // for AMGetErrorText 顯示 Error 字串使用 #define CHECK_ERROR(tsz,hr) \ { if( S_OK != hr) \ return hr; \ } #define SAFE_RELEASE(pObject) if(pObject){ pObject->Release(); pObject = NULL;} /*------------------------------------------------------------------------- Routine: DV_SaveGraph Purpose: Save the filter graph into a *.grf file Arguments: FileName Returns: HRESULT as appropriate Notes: ------------------------------------------------------------------------*/ HRESULT SaveGraphToFile(TCHAR* sGraphFile,IGraphBuilder *m_pGraph) { IStorage * pStorage = NULL; IStream * pStream = NULL; IPersistStream * pPersistStream = NULL; HRESULT hr = S_OK; if(sGraphFile == NULL) return E_FAIL; USES_CONVERSION; // Either Open or Create the *.GRF file hr = StgOpenStorage( T2W (sGraphFile), NULL, STGM_TRANSACTED | STGM_READWRITE | STGM_SHARE_DENY_WRITE, NULL, NULL, &pStorage ); if ( STG_E_FILENOTFOUND == hr ) hr = StgCreateDocfile( T2W (sGraphFile), STGM_CREATE | STGM_TRANSACTED | STGM_READWRITE | STGM_SHARE_EXCLUSIVE , NULL , &pStorage); CHECK_ERROR( TEXT(" StgCreateDocfile failed."), hr); hr = pStorage->CreateStream( L"ActiveMovieGraph", STGM_WRITE | STGM_CREATE | STGM_SHARE_EXCLUSIVE, NULL, NULL, &pStream ); CHECK_ERROR( TEXT(" CreateStream failed."), hr); // Persist the stream, save & commit to disk hr = m_pGraph->QueryInterface( IID_IPersistStream, (void **) &pPersistStream ); CHECK_ERROR( TEXT(" QI IPersistStream failed."), hr); hr = pPersistStream->Save(pStream, TRUE); CHECK_ERROR( TEXT(" pPersistStream->Save() failed."), hr); hr = pStorage->Commit( STGC_DEFAULT ); CHECK_ERROR( TEXT(" Save GRF file failed."), hr); SAFE_RELEASE(pStorage); SAFE_RELEASE(pStream); SAFE_RELEASE(pPersistStream); return hr; } BOOL hrcheck(HRESULT hr, TCHAR* errtext) { if (hr >= S_OK) return FALSE; TCHAR szErr[MAX_ERROR_TEXT_LEN]; DWORD res = AMGetErrorText(hr, szErr, MAX_ERROR_TEXT_LEN); if(res) printf("Error %x: %s\n%s\n",hr,errtext,szErr); else printf("Error %x: %s\n",hr,errtext); return TRUE; } #define CHECK_HR(hr,msg) if(hrcheck(hr,msg)) return hr; CComPtr<IPin> GetPin(IBaseFilter *pFilter, LPCOLESTR pinname) { CComPtr<IEnumPins> pEnum; CComPtr<IPin> pPin; HRESULT hr = pFilter->EnumPins(&pEnum); if(hrcheck(hr, L"Can't enumerate pins.")) return NULL; while(pEnum->Next(1,&pPin,0) == S_OK) { PIN_INFO pinfo; pPin->QueryPinInfo(&pinfo); BOOL found = !wcsicmp(pinname, pinfo.achName); if(pinfo.pFilter) pinfo.pFilter->Release(); if(found) return pPin; pPin.Release(); } printf("Pin not found!\n"); return NULL; } // {D05CDBE3-B4A3-4E98-838D-4C19A1092806} DEFINE_GUID(CLSID_SampleFileSourceAsync ,0xD05CDBE3,0xB4A3, 0x4E98, 0x83, 0x8D, 0x4C, 0x19, 0xA1, 0x09, 0x28, 0x06); //FT_MediaProtector_R4Smart.ax // {171252A0-8820-4AFE-9DF8-5C92B2D66B04} DEFINE_GUID(CLSID_LAVSplitter ,0x171252A0,0x8820, 0x4AFE, 0x9D, 0xF8, 0x5C, 0x92, 0xB2, 0xD6, 0x6B, 0x04); //LAVSplitter.ax // {EE30215D-164F-4A92-A4EB-9D4C13390F9F} DEFINE_GUID(CLSID_LAVVideoDecoder ,0xEE30215D,0x164F, 0x4A92, 0xA4, 0xEB, 0x9D, 0x4C, 0x13, 0x39, 0x0F, 0x9F); //LAVVideo.ax // {B87BEB7B-8D29-423F-AE4D-6582C10175AC} DEFINE_GUID(CLSID_VideoRenderer ,0xB87BEB7B,0x8D29, 0x423F, 0xAE, 0x4D, 0x65, 0x82, 0xC1, 0x01, 0x75, 0xAC); //quartz.dll // {E8E73B6B-4CB3-44A4-BE99-4F7BCB96E491} DEFINE_GUID(CLSID_LAVAudioDecoder ,0xE8E73B6B,0x4CB3, 0x44A4, 0xBE, 0x99, 0x4F, 0x7B, 0xCB, 0x96, 0xE4, 0x91); //LAVAudio.ax // {5811086B-1D07-4CE9-A398-8DEC9A2DBD89} DEFINE_GUID(CLSID_MainMediaAudioPitchFilter ,0x5811086B,0x1D07, 0x4CE9, 0xA3, 0x98, 0x8D, 0xEC, 0x9A, 0x2D, 0xBD, 0x89); //mainmediaaudiopitch.dll // {C1F400A0-3F08-11d3-9F0B-006008039E37} DEFINE_GUID(CLSID_SampleGrabber ,0xC1F400A0,0x3F08, 0x11d3, 0x9F, 0x0B, 0x00, 0x60, 0x08, 0x03, 0x9E, 0x37); //mainmediaaudiopitch.dll DECLARE_INTERFACE_(IAudioPitch,IUnknown) { //1000 is original pitch, >1000 is lower pitch and <1000 is higher pitch STDMETHOD(setPitchValue)(THIS_ double nVal) PURE; STDMETHOD(getPitchValue)(THIS_ double *nVal) PURE; STDMETHOD(setTempoValue)(THIS_ float nVal) PURE; STDMETHOD(getTempoValue)(THIS_ float *nVal) PURE; STDMETHOD(setLicenseKey)(THIS_ int nVal) PURE; }; DEFINE_GUID(IID_IAudioPitch ,0xa878a55, 0xa929, 0x4f68, 0xbf, 0x81, 0xe1, 0xb7, 0xb4, 0xa9, 0xbd, 0xef); HRESULT BuildGraph(IGraphBuilder *pGraph, LPCOLESTR srcFile1) { HRESULT hr = S_OK; //graph builder CComPtr<ICaptureGraphBuilder2> pBuilder; hr = pBuilder.CoCreateInstance(CLSID_CaptureGraphBuilder2); CHECK_HR(hr, L"Can't create Capture Graph Builder"); hr = pBuilder->SetFiltergraph(pGraph); CHECK_HR(hr, L"Can't SetFiltergraph"); //add Sample FIle Source (Async.) CComPtr<IBaseFilter> pSampleFileSourceAsync; hr = pSampleFileSourceAsync.CoCreateInstance(CLSID_SampleFileSourceAsync); CHECK_HR(hr, L"Can't create Sample File Source (Async.)"); hr = pGraph->AddFilter(pSampleFileSourceAsync, L"Sample File Source (Async.)"); CHECK_HR(hr, L"can't add Sample File Source (Async.) to graph"); //set source filename CComQIPtr<IFileSourceFilter, &IID_IFileSourceFilter> pSampleFileSourceAsync_src(pSampleFileSourceAsync); if (!pSampleFileSourceAsync_src) CHECK_HR(E_NOINTERFACE, L"Can't get IFileSourceFilter"); hr = pSampleFileSourceAsync_src->Load(srcFile1, NULL); CHECK_HR(hr, L"Can't load file"); //add LAV Splitter CComPtr<IBaseFilter> pLAVSplitter; hr = pLAVSplitter.CoCreateInstance(CLSID_LAVSplitter); CHECK_HR(hr,L"Can't create LAV Splitter"); hr = pGraph->AddFilter(pLAVSplitter,L"LAV Splitter"); CHECK_HR(hr, L"Can't add LAV Splitter to graph"); //connect Sample FIle Source (Async.) and add LAV Splitter hr = pGraph->ConnectDirect(GetPin(pSampleFileSourceAsync, L"Output"), GetPin(pLAVSplitter, L"Input"), NULL); CHECK_HR(hr, L"Can't connect Sample FIle Source (Async.) and add LAV Splitter"); //add LAV Video Decoder CComPtr<IBaseFilter> pLAVVideoDecoder; hr = pLAVVideoDecoder.CoCreateInstance(CLSID_LAVVideoDecoder); CHECK_HR(hr,L"Can't create LAV Video Decoder"); hr = pGraph->AddFilter(pLAVVideoDecoder,L"LAV Video Decoder"); CHECK_HR(hr, L"Can't add LAV Video Decoder to graph"); //connect LAV Splitter and LAV Video Decoder hr = pGraph->ConnectDirect(GetPin(pLAVSplitter, L"Video"), GetPin(pLAVVideoDecoder, L"Input"), NULL); CHECK_HR(hr, L"Can't connect LAV Splitter and LAV Video Decoder"); //add Video Renderer CComPtr<IBaseFilter> pVideoRenderer; hr = pVideoRenderer.CoCreateInstance(CLSID_VideoRenderer); CHECK_HR(hr, L"Can't create Video Renderer"); hr = pGraph->AddFilter(pVideoRenderer, L"Video Renderer"); CHECK_HR(hr, L"Can't add Video Renderer to graph"); //add Default DirectSound Device CComPtr<IBaseFilter> pDefaultDirectSoundDevice; hr = pDefaultDirectSoundDevice.CoCreateInstance(CLSID_DSoundRender); CHECK_HR(hr,L"Can't create Default DirectSound Device"); hr = pGraph->AddFilter(pDefaultDirectSoundDevice,L"Defult DirectSound Device"); CHECK_HR(hr, L"Can't add Default DirectSound Device to graph"); //connect LAV Video Decoder and Video Renderer hr = pGraph->ConnectDirect(GetPin(pLAVVideoDecoder, L"Output"), GetPin(pVideoRenderer, L"VMR Input0"), NULL); CHECK_HR(hr, L"Can't connect LAV Video Decoder and Video Renderer"); //add LAV Audio Decoder CComPtr<IBaseFilter> pLAVAudioDecoder; hr = pLAVAudioDecoder.CoCreateInstance(CLSID_LAVAudioDecoder); CHECK_HR(hr,L"Can't create LAV Audio Decoder"); hr = pGraph->AddFilter(pLAVAudioDecoder,L"LAV Audio Decoder"); CHECK_HR(hr, L"Can't add LAV Audio Decoder to graph"); //connect LAV Splitter and LAV Audio Decoder hr = pGraph->ConnectDirect(GetPin(pLAVSplitter, L"Audio"), GetPin(pLAVAudioDecoder, L"Input"), NULL); CHECK_HR(hr, L"Can't connect LAV Splitter and LAV Audio Decoder"); //add MainMedia Audio Pitch Filter CComPtr<IBaseFilter> pMainMediaAudioPitchFilter; hr = pMainMediaAudioPitchFilter.CoCreateInstance(CLSID_MainMediaAudioPitchFilter); CHECK_HR(hr, L"Can't create MainMedia Audio Pitch Filter"); hr = pGraph->AddFilter(pMainMediaAudioPitchFilter,L"MainMedia Audio Pitch Filter"); CHECK_HR(hr, L"Can't add MainMedia Audio Pitch Filter to graph"); //connect LAV Audio Decoder and MainMedia Audio Pitch Filter hr = pGraph->ConnectDirect(GetPin(pLAVAudioDecoder, L"Output"), GetPin(pMainMediaAudioPitchFilter, L"XForm In"), NULL); CHECK_HR(hr, L"Can't connect LAV Audio Decoder and MainMedia Audio Pitch Filter"); //connect MainMedia Audio Pitch Filter and Default DirectSound Device hr = pGraph->ConnectDirect(GetPin(pMainMediaAudioPitchFilter, L"XForm Out"), GetPin(pDefaultDirectSoundDevice, L"Audio Input pin (rendered)"), NULL); CHECK_HR(hr, L"Can't connect MainMedia Audio Pitch Filter and Default DirectSound Device"); CComQIPtr<IAudioPitch, &IID_IAudioPitch> pProp(pMainMediaAudioPitchFilter); if(pProp) { pProp->setTempoValue(100); } return S_OK; } int Test2() { CoInitialize(NULL); CComPtr<IGraphBuilder> graph; graph.CoCreateInstance(CLSID_FilterGraph); printf("Building graph...\n"); HRESULT hr = BuildGraph(graph, L"D:\\debug\\s50001_0.mp4"); if(hr == S_OK) { printf("Running"); CComQIPtr<IMediaControl,&IID_IMediaControl> mediaControl(graph); hr = mediaControl->Run(); CHECK_HR(hr, L"Can't run the graph"); CComQIPtr<IMediaEvent, &IID_IMediaEvent> mediaEvent(graph); BOOL stop = FALSE; MSG msg; while(!stop) { long ev=0,p1=0,p2=0; Sleep(500); printf("."); while(PeekMessage(&msg, NULL,0,0,PM_REMOVE)) DispatchMessage(&msg); while(mediaEvent->GetEvent(&ev,&p1,&p2,0)==S_OK) { if(ev == EC_COMPLETE || ev == EC_USERABORT) { printf("Done!\n"); stop = TRUE; } else if (ev == EC_ERRORABORT) { printf("An error occured: HRESULT=%x\n",p1); mediaControl->Stop(); stop=TRUE; } mediaEvent->FreeEventParams(ev,p1,p2); } } } CoUninitialize(); } //sample int main() { Test2(); system("pause"); return 0; }