(原)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. Notice that output window of visual studio shows the infomation.
  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"	End of stream
");
 64             quit = true;
 65         }
 66 
 67         if (pSample)
 68         {
 69             BYTE* data;
 70             IMFMediaBuffer* buffer;
 71             DWORD max, current;
 72 
 73             //        printf(" cSamples = %d
", 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
", 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 devices
121     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 part
146     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

原文地址:https://www.cnblogs.com/darkknightzh/p/4072398.html