首页 > 代码库 > (原)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, ¤t); 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的简单使用