首页 > 代码库 > (原)Microsoft Source Reader的简单使用

(原)Microsoft Source Reader的简单使用

感觉Microsoft Source Reader还是比较坑的,只是由于需要,不得不使用。其实按照Microsoft提供的示例,基本上可以正常的调试出程序来。

下面的例子,简单的给出了Source Reader的代码。同时,HRESULT CreateVideoDeviceSource(IMFMediaSource **ppSource)函数中,使用了指针的指针,能正确的传出ppSource,不是NULL。之前调试时,使用HRESULT CreateVideoDeviceSource(IMFMediaSource *ppSource),出来后,ppSource依旧为NULL。后来直接把代码展开,没有继续深入考虑。感谢前两天@wuruifang  的建议,之后在网上搜了一下,指针的指针可以使得输入参数为NULL时输出正常。因而此处重新写成一个函数(以前不清楚为啥用指针的指针时出错,现在倒是没有)。

主要代码:

  1 int _tmain(int argc, _TCHAR* argv[])  2 {  3     IMFMediaSource *ppSource = NULL;  4     CreateVideoDeviceSource(&ppSource);  5   6 //     hr = EnumerateCaptureFormats(ppSource);  // This can show the formats the camera support.  7 //     if (FAILED(hr))  8 //         abort();  9     HRESULT hr; 10     IMFSourceReader *pReader; 11     hr = MFCreateSourceReaderFromMediaSource(ppSource, NULL, &pReader); 12     if (FAILED(hr)) 13         abort(); 14  15     hr = SetDeviceFormat(ppSource, 6);   //I need to configure the camera to format 6. 16     if (FAILED(hr)) 17         abort(); 18  19     ProcessSamples(pReader); 20  21     SafeRelease(&pReader); 22     SafeRelease(&ppSource); 23     MFShutdown(); 24     CoUninitialize(); 25 } 26  27 HRESULT ProcessSamples(IMFSourceReader *pReader) 28 { 29     HRESULT hr = S_OK; 30     IMFSample *pSample = NULL; 31     size_t  cSamples = 0; 32  33     _LARGE_INTEGER time_start;    /*begin time */ 34     _LARGE_INTEGER time_over;        /*end time*/ 35     double dqFreq;                /*timer frequence*/ 36     LARGE_INTEGER f;            /*timer frequence*/ 37     QueryPerformanceFrequency(&f); 38     dqFreq = (double)f.QuadPart; 39  40     QueryPerformanceCounter(&time_start); 41  42  43     bool quit = false; 44     while (!quit) 45     { 46         DWORD streamIndex, flags; 47         LONGLONG llTimeStamp; 48  49         hr = pReader->ReadSample( 50             MF_SOURCE_READER_ANY_STREAM,    // Stream index. 51             0,                              // Flags. 52             &streamIndex,                   // Receives the actual stream index.  53             &flags,                         // Receives status flags. 54             &llTimeStamp,                   // Receives the time stamp. 55             &pSample                        // Receives the sample or NULL. 56             ); 57  58         if (FAILED(hr)) 59             break; 60  61         if (flags & MF_SOURCE_READERF_ENDOFSTREAM) 62         { 63             wprintf(L"\tEnd of stream\n"); 64             quit = true; 65         } 66  67         if (pSample) 68         { 69             BYTE* data; 70             IMFMediaBuffer* buffer; 71             DWORD max, current; 72  73             //        printf(" cSamples = %d\n", cSamples); 74             ++cSamples; 75             pSample->GetBufferByIndex(0, &buffer); 76             buffer->Lock(&data, &max, &current); 77  78         //    saveBMP(data, cSamples, IMGWIDTH, IMGHEIGHT); 79  80             buffer->Unlock(); 81             SafeRelease(&buffer); 82          83             QueryPerformanceCounter(&time_over);          //In order to find the frames per second of the camera. 84             double usedtime = ((time_over.QuadPart - time_start.QuadPart) / dqFreq); 85             if (usedtime>1) 86             { 87                 printf(" cSamples = %d\n", cSamples); 88                 cSamples = 0; 89                 QueryPerformanceCounter(&time_start); 90             } 91         } 92         SafeRelease(&pSample); 93     } 94  95     SafeRelease(&pSample); 96     return hr; 97 } 98  99 HRESULT CreateVideoDeviceSource(IMFMediaSource **ppSource)100 {101     HRESULT hr;102     hr = CoInitialize(NULL);103     if (FAILED(hr))104         abort();105     hr = MFStartup(MF_VERSION, MFSTARTUP_NOSOCKET);106     if (FAILED(hr))107         abort();108         109     *ppSource = NULL;110 111     IMFMediaSource *pSource = NULL;112     IMFAttributes *pAttributes = NULL;113     IMFActivate **ppDevices = NULL;114 115     // Create an attribute store to specify the enumeration parameters.116     /*HRESULT*/ hr = MFCreateAttributes(&pAttributes, 1);117     if (FAILED(hr))118         abort();119 120     // Source type: video capture devices121     hr = pAttributes->SetGUID( MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE,122         MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_GUID );123     if (FAILED(hr))124         abort();125 126     // Enumerate devices.127     UINT32 count;128     hr = MFEnumDeviceSources(pAttributes, &ppDevices, &count);129     if (FAILED(hr))130         abort();131     if (count == 0)132     {133         hr = E_FAIL;134         return hr;135     }136 137     // Create the media source object.138     hr = ppDevices[0]->ActivateObject(IID_PPV_ARGS(&pSource));139     if (FAILED(hr))140         abort();141 142     *ppSource = pSource;143     (*ppSource)->AddRef();144 145     // release part146     SafeRelease(&pAttributes);147 148     for (DWORD i = 0; i < count; i++)149     {150         SafeRelease(&ppDevices[i]);151     }152     CoTaskMemFree(ppDevices);153     SafeRelease(&pSource);    //此处不确定,是否需要SafeRelease。154     return hr;155 }

 

得到的图片(程序中保存的是BMP图片,由于cnblogs不支持BMP,因而转成jpg):

 

完整代码(不会插入超链接,抱歉)见:https://github.com/darkknightzh/Microsoft-Source-Reader

 

参考(其他的记不清了,见谅):

Microsoft :http://msdn.microsoft.com/en-us/library/windows/desktop/dd389281(v=vs.85).aspx

指针的指针(详见4楼,14楼) :http://bbs.csdn.net/topics/210076970

(原)Microsoft Source Reader的简单使用