1 /*M///////////////////////////////////////////////////////////////////////////////////////
3 // IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
5 // By downloading, copying, installing or using the software you agree to this license.
6 // If you do not agree to this license, do not download, install,
7 // copy or use the software.
10 // Intel License Agreement
11 // For Open Source Computer Vision Library
13 // Copyright (C) 2000, Intel Corporation, all rights reserved.
14 // Third party copyrights are property of their respective owners.
16 // Redistribution and use in source and binary forms, with or without modification,
17 // are permitted provided that the following conditions are met:
19 // * Redistribution's of source code must retain the above copyright notice,
20 // this list of conditions and the following disclaimer.
22 // * Redistribution's in binary form must reproduce the above copyright notice,
23 // this list of conditions and the following disclaimer in the documentation
24 // and/or other materials provided with the distribution.
26 // * The name of Intel Corporation may not be used to endorse or promote products
27 // derived from this software without specific prior written permission.
29 // This software is provided by the copyright holders and contributors "as is" and
30 // any express or implied warranties, including, but not limited to, the implied
31 // warranties of merchantability and fitness for a particular purpose are disclaimed.
32 // In no event shall the Intel Corporation or contributors be liable for any direct,
33 // indirect, incidental, special, exemplary, or consequential damages
34 // (including, but not limited to, procurement of substitute goods or services;
35 // loss of use, data, or profits; or business interruption) however caused
36 // and on any theory of liability, whether in contract, strict liability,
37 // or tort (including negligence or otherwise) arising in any way out of
38 // the use of this software, even if advised of the possibility of such damage.
41 #include "precomp.hpp"
42 #if defined _WIN32 && defined HAVE_MSMF
44 Media Foundation-based Video Capturing module is based on
45 videoInput library by Evgeny Pereguda:
46 http://www.codeproject.com/Articles/559437/Capturing-of-video-from-web-camera-on-Windows-7-an
47 Originally licensed under The Code Project Open License (CPOL) 1.02:
48 http://www.codeproject.com/info/cpol10.aspx
50 //require Windows 8 for some of the formats defined otherwise could baseline on lower version
51 #if WINVER < _WIN32_WINNT_WIN8
53 #define WINVER _WIN32_WINNT_WIN8
60 #include <mfobjects.h>
63 #include <Mfreadwrite.h>
78 #pragma warning(disable:4503)
79 #pragma comment(lib, "mfplat")
80 #pragma comment(lib, "mf")
81 #pragma comment(lib, "mfuuid")
82 #pragma comment(lib, "Strmiids")
83 #pragma comment(lib, "Mfreadwrite")
85 #pragma comment(lib, "d3d11")
87 #if (WINVER >= 0x0602) // Available since Win 8
88 #pragma comment(lib, "MinCore_Downlevel")
98 struct IMFMediaSource;
105 void DPOprintOut(const wchar_t *format, ...)
110 va_start(args, format);
111 if (::IsDebuggerPresent())
114 ::StringCchVPrintfW(szMsg, sizeof(szMsg) / sizeof(szMsg[0]), format, args);
115 ::OutputDebugStringW(szMsg);
119 if (wcscmp(format, L"%i"))
121 i = va_arg(args, int);
123 if (wcscmp(format, L"%s"))
125 p = va_arg(args, wchar_t *);
127 wprintf(format, i, p);
131 #define DebugPrintOut(...) DPOprintOut(__VA_ARGS__)
133 #define DebugPrintOut(...) void()
143 ComPtr(T* lp) throw()
147 ComPtr(_In_ const ComPtr<T>& lp) throw()
155 T** operator&() throw()
158 return p.operator&();
160 T* operator->() const throw()
163 return p.operator->();
165 bool operator!() const throw()
167 return p.operator==(NULL);
169 bool operator==(_In_opt_ T* pT) const throw()
171 return p.operator==(pT);
173 bool operator!=(_In_opt_ T* pT) const throw()
175 return p.operator!=(pT);
179 return p.operator!=(NULL);
182 T* const* GetAddressOf() const throw()
187 T** GetAddressOf() throw()
192 T** ReleaseAndGetAddressOf() throw()
198 T* Get() const throw()
203 // Attach to an existing interface (does not AddRef)
204 void Attach(_In_opt_ T* p2) throw()
208 // Detach the interface (does not Release)
213 _Check_return_ HRESULT CopyTo(_Deref_out_opt_ T** ppT) throw()
229 // query for U interface
231 HRESULT As(_Inout_ U** lp) const throw()
233 return p->QueryInterface(__uuidof(U), reinterpret_cast<void**>(lp));
235 // query for U interface
237 HRESULT As(_Out_ ComPtr<U>* lp) const throw()
239 return p->QueryInterface(__uuidof(U), reinterpret_cast<void**>(lp->ReleaseAndGetAddressOf()));
242 _COM_SMARTPTR_TYPEDEF(T, __uuidof(T));
246 #define _ComPtr ComPtr
248 // Structure for collecting info about types of video, which are supported by current video device
251 unsigned int MF_MT_FRAME_SIZE;
254 unsigned int MF_MT_YUV_MATRIX;
255 unsigned int MF_MT_VIDEO_LIGHTING;
256 int MF_MT_DEFAULT_STRIDE; // stride is negative if image is bottom-up
257 unsigned int MF_MT_VIDEO_CHROMA_SITING;
258 GUID MF_MT_AM_FORMAT_TYPE;
259 unsigned int MF_MT_FIXED_SIZE_SAMPLES;
260 unsigned int MF_MT_VIDEO_NOMINAL_RANGE;
261 UINT32 MF_MT_FRAME_RATE_NUMERATOR;
262 UINT32 MF_MT_FRAME_RATE_DENOMINATOR;
263 UINT32 MF_MT_PIXEL_ASPECT_RATIO_NUMERATOR;
264 UINT32 MF_MT_PIXEL_ASPECT_RATIO_DENOMINATOR;
265 unsigned int MF_MT_ALL_SAMPLES_INDEPENDENT;
266 UINT32 MF_MT_FRAME_RATE_RANGE_MIN_NUMERATOR;
267 UINT32 MF_MT_FRAME_RATE_RANGE_MIN_DENOMINATOR;
268 unsigned int MF_MT_SAMPLE_SIZE;
269 unsigned int MF_MT_VIDEO_PRIMARIES;
270 unsigned int MF_MT_INTERLACE_MODE;
271 UINT32 MF_MT_FRAME_RATE_RANGE_MAX_NUMERATOR;
272 UINT32 MF_MT_FRAME_RATE_RANGE_MAX_DENOMINATOR;
273 GUID MF_MT_MAJOR_TYPE;
275 LPCWSTR pMF_MT_MAJOR_TYPEName;
276 LPCWSTR pMF_MT_SUBTYPEName;
278 MediaType(IMFMediaType *pType);
283 // Class for creating of Media Foundation context
284 class Media_Foundation
287 ~Media_Foundation(void) { /*CV_Assert(SUCCEEDED(MFShutdown()));*/ CoUninitialize(); }
288 static Media_Foundation& getInstance()
290 static Media_Foundation instance;
294 Media_Foundation(void) { CoInitialize(0); CV_Assert(SUCCEEDED(MFStartup(MF_VERSION))); }
297 #ifndef IF_GUID_EQUAL_RETURN
298 #define IF_GUID_EQUAL_RETURN(val) if(val == guid) return L#val
300 LPCWSTR GetGUIDNameConstNew(const GUID& guid)
302 IF_GUID_EQUAL_RETURN(MF_MT_MAJOR_TYPE);
303 IF_GUID_EQUAL_RETURN(MF_MT_SUBTYPE);
304 IF_GUID_EQUAL_RETURN(MF_MT_ALL_SAMPLES_INDEPENDENT);
305 IF_GUID_EQUAL_RETURN(MF_MT_FIXED_SIZE_SAMPLES);
306 IF_GUID_EQUAL_RETURN(MF_MT_COMPRESSED);
307 IF_GUID_EQUAL_RETURN(MF_MT_SAMPLE_SIZE);
308 IF_GUID_EQUAL_RETURN(MF_MT_WRAPPED_TYPE);
309 IF_GUID_EQUAL_RETURN(MF_MT_AUDIO_NUM_CHANNELS);
310 IF_GUID_EQUAL_RETURN(MF_MT_AUDIO_SAMPLES_PER_SECOND);
311 IF_GUID_EQUAL_RETURN(MF_MT_AUDIO_FLOAT_SAMPLES_PER_SECOND);
312 IF_GUID_EQUAL_RETURN(MF_MT_AUDIO_AVG_BYTES_PER_SECOND);
313 IF_GUID_EQUAL_RETURN(MF_MT_AUDIO_BLOCK_ALIGNMENT);
314 IF_GUID_EQUAL_RETURN(MF_MT_AUDIO_BITS_PER_SAMPLE);
315 IF_GUID_EQUAL_RETURN(MF_MT_AUDIO_VALID_BITS_PER_SAMPLE);
316 IF_GUID_EQUAL_RETURN(MF_MT_AUDIO_SAMPLES_PER_BLOCK);
317 IF_GUID_EQUAL_RETURN(MF_MT_AUDIO_CHANNEL_MASK);
318 IF_GUID_EQUAL_RETURN(MF_MT_AUDIO_FOLDDOWN_MATRIX);
319 IF_GUID_EQUAL_RETURN(MF_MT_AUDIO_WMADRC_PEAKREF);
320 IF_GUID_EQUAL_RETURN(MF_MT_AUDIO_WMADRC_PEAKTARGET);
321 IF_GUID_EQUAL_RETURN(MF_MT_AUDIO_WMADRC_AVGREF);
322 IF_GUID_EQUAL_RETURN(MF_MT_AUDIO_WMADRC_AVGTARGET);
323 IF_GUID_EQUAL_RETURN(MF_MT_AUDIO_PREFER_WAVEFORMATEX);
324 IF_GUID_EQUAL_RETURN(MF_MT_AAC_PAYLOAD_TYPE);
325 IF_GUID_EQUAL_RETURN(MF_MT_AAC_AUDIO_PROFILE_LEVEL_INDICATION);
326 IF_GUID_EQUAL_RETURN(MF_MT_FRAME_SIZE);
327 IF_GUID_EQUAL_RETURN(MF_MT_FRAME_RATE);
328 IF_GUID_EQUAL_RETURN(MF_MT_FRAME_RATE_RANGE_MAX);
329 IF_GUID_EQUAL_RETURN(MF_MT_FRAME_RATE_RANGE_MIN);
330 IF_GUID_EQUAL_RETURN(MF_MT_PIXEL_ASPECT_RATIO);
331 IF_GUID_EQUAL_RETURN(MF_MT_DRM_FLAGS);
332 IF_GUID_EQUAL_RETURN(MF_MT_PAD_CONTROL_FLAGS);
333 IF_GUID_EQUAL_RETURN(MF_MT_SOURCE_CONTENT_HINT);
334 IF_GUID_EQUAL_RETURN(MF_MT_VIDEO_CHROMA_SITING);
335 IF_GUID_EQUAL_RETURN(MF_MT_INTERLACE_MODE);
336 IF_GUID_EQUAL_RETURN(MF_MT_TRANSFER_FUNCTION);
337 IF_GUID_EQUAL_RETURN(MF_MT_VIDEO_PRIMARIES);
338 IF_GUID_EQUAL_RETURN(MF_MT_CUSTOM_VIDEO_PRIMARIES);
339 IF_GUID_EQUAL_RETURN(MF_MT_YUV_MATRIX);
340 IF_GUID_EQUAL_RETURN(MF_MT_VIDEO_LIGHTING);
341 IF_GUID_EQUAL_RETURN(MF_MT_VIDEO_NOMINAL_RANGE);
342 IF_GUID_EQUAL_RETURN(MF_MT_GEOMETRIC_APERTURE);
343 IF_GUID_EQUAL_RETURN(MF_MT_MINIMUM_DISPLAY_APERTURE);
344 IF_GUID_EQUAL_RETURN(MF_MT_PAN_SCAN_APERTURE);
345 IF_GUID_EQUAL_RETURN(MF_MT_PAN_SCAN_ENABLED);
346 IF_GUID_EQUAL_RETURN(MF_MT_AVG_BITRATE);
347 IF_GUID_EQUAL_RETURN(MF_MT_AVG_BIT_ERROR_RATE);
348 IF_GUID_EQUAL_RETURN(MF_MT_MAX_KEYFRAME_SPACING);
349 IF_GUID_EQUAL_RETURN(MF_MT_DEFAULT_STRIDE);
350 IF_GUID_EQUAL_RETURN(MF_MT_PALETTE);
351 IF_GUID_EQUAL_RETURN(MF_MT_USER_DATA);
352 IF_GUID_EQUAL_RETURN(MF_MT_AM_FORMAT_TYPE);
353 IF_GUID_EQUAL_RETURN(MF_MT_MPEG_START_TIME_CODE);
354 IF_GUID_EQUAL_RETURN(MF_MT_MPEG2_PROFILE);
355 IF_GUID_EQUAL_RETURN(MF_MT_MPEG2_LEVEL);
356 IF_GUID_EQUAL_RETURN(MF_MT_MPEG2_FLAGS);
357 IF_GUID_EQUAL_RETURN(MF_MT_MPEG_SEQUENCE_HEADER);
358 IF_GUID_EQUAL_RETURN(MF_MT_DV_AAUX_SRC_PACK_0);
359 IF_GUID_EQUAL_RETURN(MF_MT_DV_AAUX_CTRL_PACK_0);
360 IF_GUID_EQUAL_RETURN(MF_MT_DV_AAUX_SRC_PACK_1);
361 IF_GUID_EQUAL_RETURN(MF_MT_DV_AAUX_CTRL_PACK_1);
362 IF_GUID_EQUAL_RETURN(MF_MT_DV_VAUX_SRC_PACK);
363 IF_GUID_EQUAL_RETURN(MF_MT_DV_VAUX_CTRL_PACK);
364 IF_GUID_EQUAL_RETURN(MF_MT_ARBITRARY_HEADER);
365 IF_GUID_EQUAL_RETURN(MF_MT_ARBITRARY_FORMAT);
366 IF_GUID_EQUAL_RETURN(MF_MT_IMAGE_LOSS_TOLERANT);
367 IF_GUID_EQUAL_RETURN(MF_MT_MPEG4_SAMPLE_DESCRIPTION);
368 IF_GUID_EQUAL_RETURN(MF_MT_MPEG4_CURRENT_SAMPLE_ENTRY);
369 IF_GUID_EQUAL_RETURN(MF_MT_ORIGINAL_4CC);
370 IF_GUID_EQUAL_RETURN(MF_MT_ORIGINAL_WAVE_FORMAT_TAG);
372 IF_GUID_EQUAL_RETURN(MFMediaType_Audio);
373 IF_GUID_EQUAL_RETURN(MFMediaType_Video);
374 IF_GUID_EQUAL_RETURN(MFMediaType_Protected);
375 #ifdef MFMediaType_Perception
376 IF_GUID_EQUAL_RETURN(MFMediaType_Perception);
378 IF_GUID_EQUAL_RETURN(MFMediaType_Stream);
379 IF_GUID_EQUAL_RETURN(MFMediaType_SAMI);
380 IF_GUID_EQUAL_RETURN(MFMediaType_Script);
381 IF_GUID_EQUAL_RETURN(MFMediaType_Image);
382 IF_GUID_EQUAL_RETURN(MFMediaType_HTML);
383 IF_GUID_EQUAL_RETURN(MFMediaType_Binary);
384 IF_GUID_EQUAL_RETURN(MFMediaType_FileTransfer);
385 IF_GUID_EQUAL_RETURN(MFVideoFormat_AI44); // FCC('AI44')
386 IF_GUID_EQUAL_RETURN(MFVideoFormat_ARGB32); // D3DFMT_A8R8G8B8
387 IF_GUID_EQUAL_RETURN(MFVideoFormat_AYUV); // FCC('AYUV')
388 IF_GUID_EQUAL_RETURN(MFVideoFormat_DV25); // FCC('dv25')
389 IF_GUID_EQUAL_RETURN(MFVideoFormat_DV50); // FCC('dv50')
390 IF_GUID_EQUAL_RETURN(MFVideoFormat_DVH1); // FCC('dvh1')
391 IF_GUID_EQUAL_RETURN(MFVideoFormat_DVC);
392 IF_GUID_EQUAL_RETURN(MFVideoFormat_DVHD);
393 IF_GUID_EQUAL_RETURN(MFVideoFormat_DVSD); // FCC('dvsd')
394 IF_GUID_EQUAL_RETURN(MFVideoFormat_DVSL); // FCC('dvsl')
395 IF_GUID_EQUAL_RETURN(MFVideoFormat_H264); // FCC('H264')
396 IF_GUID_EQUAL_RETURN(MFVideoFormat_I420); // FCC('I420')
397 IF_GUID_EQUAL_RETURN(MFVideoFormat_IYUV); // FCC('IYUV')
398 IF_GUID_EQUAL_RETURN(MFVideoFormat_M4S2); // FCC('M4S2')
399 IF_GUID_EQUAL_RETURN(MFVideoFormat_MJPG);
400 IF_GUID_EQUAL_RETURN(MFVideoFormat_MP43); // FCC('MP43')
401 IF_GUID_EQUAL_RETURN(MFVideoFormat_MP4S); // FCC('MP4S')
402 IF_GUID_EQUAL_RETURN(MFVideoFormat_MP4V); // FCC('MP4V')
403 IF_GUID_EQUAL_RETURN(MFVideoFormat_MPG1); // FCC('MPG1')
404 IF_GUID_EQUAL_RETURN(MFVideoFormat_MSS1); // FCC('MSS1')
405 IF_GUID_EQUAL_RETURN(MFVideoFormat_MSS2); // FCC('MSS2')
406 IF_GUID_EQUAL_RETURN(MFVideoFormat_NV11); // FCC('NV11')
407 IF_GUID_EQUAL_RETURN(MFVideoFormat_NV12); // FCC('NV12')
408 IF_GUID_EQUAL_RETURN(MFVideoFormat_P010); // FCC('P010')
409 IF_GUID_EQUAL_RETURN(MFVideoFormat_P016); // FCC('P016')
410 IF_GUID_EQUAL_RETURN(MFVideoFormat_P210); // FCC('P210')
411 IF_GUID_EQUAL_RETURN(MFVideoFormat_P216); // FCC('P216')
412 IF_GUID_EQUAL_RETURN(MFVideoFormat_RGB24); // D3DFMT_R8G8B8
413 IF_GUID_EQUAL_RETURN(MFVideoFormat_RGB32); // D3DFMT_X8R8G8B8
414 IF_GUID_EQUAL_RETURN(MFVideoFormat_RGB555); // D3DFMT_X1R5G5B5
415 IF_GUID_EQUAL_RETURN(MFVideoFormat_RGB565); // D3DFMT_R5G6B5
416 IF_GUID_EQUAL_RETURN(MFVideoFormat_RGB8);
417 IF_GUID_EQUAL_RETURN(MFVideoFormat_UYVY); // FCC('UYVY')
418 IF_GUID_EQUAL_RETURN(MFVideoFormat_v210); // FCC('v210')
419 IF_GUID_EQUAL_RETURN(MFVideoFormat_v410); // FCC('v410')
420 IF_GUID_EQUAL_RETURN(MFVideoFormat_WMV1); // FCC('WMV1')
421 IF_GUID_EQUAL_RETURN(MFVideoFormat_WMV2); // FCC('WMV2')
422 IF_GUID_EQUAL_RETURN(MFVideoFormat_WMV3); // FCC('WMV3')
423 IF_GUID_EQUAL_RETURN(MFVideoFormat_WVC1); // FCC('WVC1')
424 IF_GUID_EQUAL_RETURN(MFVideoFormat_Y210); // FCC('Y210')
425 IF_GUID_EQUAL_RETURN(MFVideoFormat_Y216); // FCC('Y216')
426 IF_GUID_EQUAL_RETURN(MFVideoFormat_Y410); // FCC('Y410')
427 IF_GUID_EQUAL_RETURN(MFVideoFormat_Y416); // FCC('Y416')
428 IF_GUID_EQUAL_RETURN(MFVideoFormat_Y41P);
429 IF_GUID_EQUAL_RETURN(MFVideoFormat_Y41T);
430 IF_GUID_EQUAL_RETURN(MFVideoFormat_YUY2); // FCC('YUY2')
431 IF_GUID_EQUAL_RETURN(MFVideoFormat_YV12); // FCC('YV12')
432 IF_GUID_EQUAL_RETURN(MFVideoFormat_YVYU);
433 #ifdef MFVideoFormat_H263
434 IF_GUID_EQUAL_RETURN(MFVideoFormat_H263);
436 #ifdef MFVideoFormat_H265
437 IF_GUID_EQUAL_RETURN(MFVideoFormat_H265);
439 #ifdef MFVideoFormat_H264_ES
440 IF_GUID_EQUAL_RETURN(MFVideoFormat_H264_ES);
442 #ifdef MFVideoFormat_HEVC
443 IF_GUID_EQUAL_RETURN(MFVideoFormat_HEVC);
445 #ifdef MFVideoFormat_HEVC_ES
446 IF_GUID_EQUAL_RETURN(MFVideoFormat_HEVC_ES);
448 #ifdef MFVideoFormat_MPEG2
449 IF_GUID_EQUAL_RETURN(MFVideoFormat_MPEG2);
451 #ifdef MFVideoFormat_VP80
452 IF_GUID_EQUAL_RETURN(MFVideoFormat_VP80);
454 #ifdef MFVideoFormat_VP90
455 IF_GUID_EQUAL_RETURN(MFVideoFormat_VP90);
457 #ifdef MFVideoFormat_420O
458 IF_GUID_EQUAL_RETURN(MFVideoFormat_420O);
460 #ifdef MFVideoFormat_Y42T
461 IF_GUID_EQUAL_RETURN(MFVideoFormat_Y42T);
463 #ifdef MFVideoFormat_YVU9
464 IF_GUID_EQUAL_RETURN(MFVideoFormat_YVU9);
466 #ifdef MFVideoFormat_v216
467 IF_GUID_EQUAL_RETURN(MFVideoFormat_v216);
469 #ifdef MFVideoFormat_L8
470 IF_GUID_EQUAL_RETURN(MFVideoFormat_L8);
472 #ifdef MFVideoFormat_L16
473 IF_GUID_EQUAL_RETURN(MFVideoFormat_L16);
475 #ifdef MFVideoFormat_D16
476 IF_GUID_EQUAL_RETURN(MFVideoFormat_D16);
478 #ifdef D3DFMT_X8R8G8B8
479 IF_GUID_EQUAL_RETURN(D3DFMT_X8R8G8B8);
481 #ifdef D3DFMT_A8R8G8B8
482 IF_GUID_EQUAL_RETURN(D3DFMT_A8R8G8B8);
485 IF_GUID_EQUAL_RETURN(D3DFMT_R8G8B8);
487 #ifdef D3DFMT_X1R5G5B5
488 IF_GUID_EQUAL_RETURN(D3DFMT_X1R5G5B5);
490 #ifdef D3DFMT_A4R4G4B4
491 IF_GUID_EQUAL_RETURN(D3DFMT_A4R4G4B4);
494 IF_GUID_EQUAL_RETURN(D3DFMT_R5G6B5);
497 IF_GUID_EQUAL_RETURN(D3DFMT_P8);
499 #ifdef D3DFMT_A2R10G10B10
500 IF_GUID_EQUAL_RETURN(D3DFMT_A2R10G10B10);
502 #ifdef D3DFMT_A2B10G10R10
503 IF_GUID_EQUAL_RETURN(D3DFMT_A2B10G10R10);
506 IF_GUID_EQUAL_RETURN(D3DFMT_L8);
509 IF_GUID_EQUAL_RETURN(D3DFMT_L16);
512 IF_GUID_EQUAL_RETURN(D3DFMT_D16);
514 #ifdef MFVideoFormat_A2R10G10B10
515 IF_GUID_EQUAL_RETURN(MFVideoFormat_A2R10G10B10);
517 #ifdef MFVideoFormat_A16B16G16R16F
518 IF_GUID_EQUAL_RETURN(MFVideoFormat_A16B16G16R16F);
520 IF_GUID_EQUAL_RETURN(MFAudioFormat_PCM); // WAVE_FORMAT_PCM
521 IF_GUID_EQUAL_RETURN(MFAudioFormat_Float); // WAVE_FORMAT_IEEE_FLOAT
522 IF_GUID_EQUAL_RETURN(MFAudioFormat_DTS); // WAVE_FORMAT_DTS
523 IF_GUID_EQUAL_RETURN(MFAudioFormat_Dolby_AC3_SPDIF); // WAVE_FORMAT_DOLBY_AC3_SPDIF
524 IF_GUID_EQUAL_RETURN(MFAudioFormat_DRM); // WAVE_FORMAT_DRM
525 IF_GUID_EQUAL_RETURN(MFAudioFormat_WMAudioV8); // WAVE_FORMAT_WMAUDIO2
526 IF_GUID_EQUAL_RETURN(MFAudioFormat_WMAudioV9); // WAVE_FORMAT_WMAUDIO3
527 IF_GUID_EQUAL_RETURN(MFAudioFormat_WMAudio_Lossless); // WAVE_FORMAT_WMAUDIO_LOSSLESS
528 IF_GUID_EQUAL_RETURN(MFAudioFormat_WMASPDIF); // WAVE_FORMAT_WMASPDIF
529 IF_GUID_EQUAL_RETURN(MFAudioFormat_MSP1); // WAVE_FORMAT_WMAVOICE9
530 IF_GUID_EQUAL_RETURN(MFAudioFormat_MP3); // WAVE_FORMAT_MPEGLAYER3
531 IF_GUID_EQUAL_RETURN(MFAudioFormat_MPEG); // WAVE_FORMAT_MPEG
532 IF_GUID_EQUAL_RETURN(MFAudioFormat_AAC); // WAVE_FORMAT_MPEG_HEAAC
533 IF_GUID_EQUAL_RETURN(MFAudioFormat_ADTS); // WAVE_FORMAT_MPEG_ADTS_AAC
534 #ifdef MFAudioFormat_ALAC
535 IF_GUID_EQUAL_RETURN(MFAudioFormat_ALAC);
537 #ifdef MFAudioFormat_AMR_NB
538 IF_GUID_EQUAL_RETURN(MFAudioFormat_AMR_NB);
540 #ifdef MFAudioFormat_AMR_WB
541 IF_GUID_EQUAL_RETURN(MFAudioFormat_AMR_WB);
543 #ifdef MFAudioFormat_AMR_WP
544 IF_GUID_EQUAL_RETURN(MFAudioFormat_AMR_WP);
546 #ifdef MFAudioFormat_Dolby_AC3
547 IF_GUID_EQUAL_RETURN(MFAudioFormat_Dolby_AC3);
549 #ifdef MFAudioFormat_Dolby_DDPlus
550 IF_GUID_EQUAL_RETURN(MFAudioFormat_Dolby_DDPlus);
552 #ifdef MFAudioFormat_FLAC
553 IF_GUID_EQUAL_RETURN(MFAudioFormat_FLAC);
555 #ifdef MFAudioFormat_Opus
556 IF_GUID_EQUAL_RETURN(MFAudioFormat_Opus);
558 #ifdef MEDIASUBTYPE_RAW_AAC1
559 IF_GUID_EQUAL_RETURN(MEDIASUBTYPE_RAW_AAC1);
561 #ifdef MFAudioFormat_Float_SpatialObjects
562 IF_GUID_EQUAL_RETURN(MFAudioFormat_Float_SpatialObjects);
564 #ifdef MFAudioFormat_QCELP
565 IF_GUID_EQUAL_RETURN(MFAudioFormat_QCELP);
571 bool LogAttributeValueByIndexNew(IMFAttributes *pAttr, DWORD index, MediaType &out)
574 PropVariantInit(&var);
576 if (SUCCEEDED(pAttr->GetItemByIndex(index, &guid, &var)))
578 if (guid == MF_MT_DEFAULT_STRIDE && var.vt == VT_INT)
579 out.MF_MT_DEFAULT_STRIDE = var.intVal;
580 else if (guid == MF_MT_FRAME_RATE && var.vt == VT_UI8)
581 Unpack2UINT32AsUINT64(var.uhVal.QuadPart, &out.MF_MT_FRAME_RATE_NUMERATOR, &out.MF_MT_FRAME_RATE_DENOMINATOR);
582 else if (guid == MF_MT_FRAME_RATE_RANGE_MAX && var.vt == VT_UI8)
583 Unpack2UINT32AsUINT64(var.uhVal.QuadPart, &out.MF_MT_FRAME_RATE_RANGE_MAX_NUMERATOR, &out.MF_MT_FRAME_RATE_RANGE_MAX_DENOMINATOR);
584 else if (guid == MF_MT_FRAME_RATE_RANGE_MIN && var.vt == VT_UI8)
585 Unpack2UINT32AsUINT64(var.uhVal.QuadPart, &out.MF_MT_FRAME_RATE_RANGE_MIN_NUMERATOR, &out.MF_MT_FRAME_RATE_RANGE_MIN_DENOMINATOR);
586 else if (guid == MF_MT_PIXEL_ASPECT_RATIO && var.vt == VT_UI8)
587 Unpack2UINT32AsUINT64(var.uhVal.QuadPart, &out.MF_MT_PIXEL_ASPECT_RATIO_NUMERATOR, &out.MF_MT_PIXEL_ASPECT_RATIO_DENOMINATOR);
588 else if (guid == MF_MT_YUV_MATRIX && var.vt == VT_UI4)
589 out.MF_MT_YUV_MATRIX = var.ulVal;
590 else if (guid == MF_MT_VIDEO_LIGHTING && var.vt == VT_UI4)
591 out.MF_MT_VIDEO_LIGHTING = var.ulVal;
592 else if (guid == MF_MT_DEFAULT_STRIDE && var.vt == VT_UI4)
593 out.MF_MT_DEFAULT_STRIDE = (int)var.ulVal;
594 else if (guid == MF_MT_VIDEO_CHROMA_SITING && var.vt == VT_UI4)
595 out.MF_MT_VIDEO_CHROMA_SITING = var.ulVal;
596 else if (guid == MF_MT_VIDEO_NOMINAL_RANGE && var.vt == VT_UI4)
597 out.MF_MT_VIDEO_NOMINAL_RANGE = var.ulVal;
598 else if (guid == MF_MT_ALL_SAMPLES_INDEPENDENT && var.vt == VT_UI4)
599 out.MF_MT_ALL_SAMPLES_INDEPENDENT = var.ulVal;
600 else if (guid == MF_MT_FIXED_SIZE_SAMPLES && var.vt == VT_UI4)
601 out.MF_MT_FIXED_SIZE_SAMPLES = var.ulVal;
602 else if (guid == MF_MT_SAMPLE_SIZE && var.vt == VT_UI4)
603 out.MF_MT_SAMPLE_SIZE = var.ulVal;
604 else if (guid == MF_MT_VIDEO_PRIMARIES && var.vt == VT_UI4)
605 out.MF_MT_VIDEO_PRIMARIES = var.ulVal;
606 else if (guid == MF_MT_INTERLACE_MODE && var.vt == VT_UI4)
607 out.MF_MT_INTERLACE_MODE = var.ulVal;
608 else if (guid == MF_MT_AM_FORMAT_TYPE && var.vt == VT_CLSID)
609 out.MF_MT_AM_FORMAT_TYPE = *var.puuid;
610 else if (guid == MF_MT_MAJOR_TYPE && var.vt == VT_CLSID)
611 out.pMF_MT_MAJOR_TYPEName = GetGUIDNameConstNew(out.MF_MT_MAJOR_TYPE = *var.puuid);
612 else if (guid == MF_MT_SUBTYPE && var.vt == VT_CLSID)
613 out.pMF_MT_SUBTYPEName = GetGUIDNameConstNew(out.MF_MT_SUBTYPE = *var.puuid);
614 else if (guid == MF_MT_FRAME_SIZE && var.vt == VT_UI8)
616 Unpack2UINT32AsUINT64(var.uhVal.QuadPart, &out.width, &out.height);
617 out.MF_MT_FRAME_SIZE = out.width * out.height;
619 PropVariantClear(&var);
625 MediaType::MediaType()
627 pMF_MT_MAJOR_TYPEName = NULL;
628 pMF_MT_SUBTYPEName = NULL;
632 MediaType::MediaType(IMFMediaType *pType)
634 pMF_MT_MAJOR_TYPEName = NULL;
635 pMF_MT_SUBTYPEName = NULL;
638 if (SUCCEEDED(pType->GetCount(&count)) &&
639 SUCCEEDED(pType->LockStore()))
641 for (UINT32 i = 0; i < count; i++)
642 if (!LogAttributeValueByIndexNew(pType, i, *this))
644 pType->UnlockStore();
648 MediaType::~MediaType()
653 void MediaType::Clear()
655 MF_MT_FRAME_SIZE = 0;
658 MF_MT_YUV_MATRIX = 0;
659 MF_MT_VIDEO_LIGHTING = 0;
660 MF_MT_DEFAULT_STRIDE = 0;
661 MF_MT_VIDEO_CHROMA_SITING = 0;
662 MF_MT_FIXED_SIZE_SAMPLES = 0;
663 MF_MT_VIDEO_NOMINAL_RANGE = 0;
664 MF_MT_FRAME_RATE_NUMERATOR = 0;
665 MF_MT_FRAME_RATE_DENOMINATOR = 0;
666 MF_MT_PIXEL_ASPECT_RATIO_NUMERATOR = 0;
667 MF_MT_PIXEL_ASPECT_RATIO_DENOMINATOR = 0;
668 MF_MT_ALL_SAMPLES_INDEPENDENT = 0;
669 MF_MT_FRAME_RATE_RANGE_MIN_NUMERATOR = 0;
670 MF_MT_FRAME_RATE_RANGE_MIN_DENOMINATOR = 0;
671 MF_MT_SAMPLE_SIZE = 0;
672 MF_MT_VIDEO_PRIMARIES = 0;
673 MF_MT_INTERLACE_MODE = 0;
674 MF_MT_FRAME_RATE_RANGE_MAX_NUMERATOR = 0;
675 MF_MT_FRAME_RATE_RANGE_MAX_DENOMINATOR = 0;
676 memset(&MF_MT_MAJOR_TYPE, 0, sizeof(GUID));
677 memset(&MF_MT_AM_FORMAT_TYPE, 0, sizeof(GUID));
678 memset(&MF_MT_SUBTYPE, 0, sizeof(GUID));
683 /******* Capturing video from camera or file via Microsoft Media Foundation **********/
684 class CvCapture_MSMF : public CvCapture
692 virtual ~CvCapture_MSMF();
693 virtual bool open(int index);
694 virtual bool open(const char* filename);
695 virtual void close();
696 virtual double getProperty(int) const CV_OVERRIDE;
697 virtual bool setProperty(int, double) CV_OVERRIDE;
698 virtual bool grabFrame() CV_OVERRIDE;
699 virtual IplImage* retrieveFrame(int) CV_OVERRIDE;
700 virtual int getCaptureDomain() CV_OVERRIDE { return CV_CAP_MSMF; } // Return the type of the capture object: CV_CAP_VFW, etc...
702 double getFramerate(MediaType MT) const;
703 bool configureOutput(UINT32 width, UINT32 height, double prefFramerate, UINT32 aspectRatioN, UINT32 aspectRatioD, int outFormat, bool convertToFormat);
704 bool setTime(double time, bool rough);
705 bool configureHW(bool enable);
707 Media_Foundation& MF;
710 MSMFCapture_Mode captureMode;
712 _ComPtr<ID3D11Device> D3DDev;
713 _ComPtr<IMFDXGIDeviceManager> D3DMgr;
715 _ComPtr<IMFSourceReader> videoFileSource;
717 MediaType nativeFormat;
718 MediaType captureFormat;
721 UINT32 aspectN, aspectD;
723 _ComPtr<IMFSample> videoSample;
729 CvCapture_MSMF::CvCapture_MSMF():
730 MF(Media_Foundation::getInstance()),
733 captureMode(MODE_SW),
738 videoFileSource(NULL),
740 outputFormat(CV_CAP_MODE_BGR),
750 CvCapture_MSMF::~CvCapture_MSMF()
755 void CvCapture_MSMF::close()
763 videoFileSource.Reset();
765 cvReleaseImage(&frame);
771 bool CvCapture_MSMF::configureHW(bool enable)
774 if ((enable && D3DMgr && D3DDev) || (!enable && !D3DMgr && !D3DDev))
777 bool reopen = isOpened;
779 cv::String prevfile = filename;
783 D3D_FEATURE_LEVEL levels[] = { D3D_FEATURE_LEVEL_11_1, D3D_FEATURE_LEVEL_11_0,
784 D3D_FEATURE_LEVEL_10_1, D3D_FEATURE_LEVEL_10_0,
785 D3D_FEATURE_LEVEL_9_3, D3D_FEATURE_LEVEL_9_2, D3D_FEATURE_LEVEL_9_1 };
786 if (SUCCEEDED(D3D11CreateDevice(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, D3D11_CREATE_DEVICE_BGRA_SUPPORT | D3D11_CREATE_DEVICE_VIDEO_SUPPORT,
787 levels, sizeof(levels) / sizeof(*levels), D3D11_SDK_VERSION, D3DDev.GetAddressOf(), NULL, NULL)))
789 // NOTE: Getting ready for multi-threaded operation
790 _ComPtr<ID3D11Multithread> D3DDevMT;
792 if (SUCCEEDED(D3DDev->QueryInterface(IID_PPV_ARGS(&D3DDevMT))))
794 D3DDevMT->SetMultithreadProtected(TRUE);
796 if (SUCCEEDED(MFCreateDXGIDeviceManager(&mgrRToken, D3DMgr.GetAddressOf())))
798 if (SUCCEEDED(D3DMgr->ResetDevice(D3DDev.Get(), mgrRToken)))
800 captureMode = MODE_HW;
801 return reopen ? camid >= 0 ? open(prevcam) : open(prevfile.c_str()) : true;
816 captureMode = MODE_SW;
817 return reopen ? camid >= 0 ? open(prevcam) : open(prevfile.c_str()) : true;
824 bool CvCapture_MSMF::configureOutput(UINT32 width, UINT32 height, double prefFramerate, UINT32 aspectRatioN, UINT32 aspectRatioD, int outFormat, bool convertToFormat)
826 if (width != 0 && height != 0 &&
827 width == captureFormat.width && height == captureFormat.height && prefFramerate == getFramerate(nativeFormat) &&
828 aspectRatioN == aspectN && aspectRatioD == aspectD && outFormat == outputFormat && convertToFormat == convertFormat)
832 int dwStreamFallback = -1;
833 MediaType MTFallback;
834 int dwStreamBest = -1;
837 DWORD dwMediaTypeTest = 0;
838 DWORD dwStreamTest = 0;
839 while (SUCCEEDED(hr))
841 _ComPtr<IMFMediaType> pType;
842 hr = videoFileSource->GetNativeMediaType(dwStreamTest, dwMediaTypeTest, &pType);
843 if (hr == MF_E_NO_MORE_TYPES)
849 else if (SUCCEEDED(hr))
851 MediaType MT(pType.Get());
852 if (MT.MF_MT_MAJOR_TYPE == MFMediaType_Video)
854 if (dwStreamFallback < 0 ||
855 ((MT.width * MT.height) > (MTFallback.width * MTFallback.height)) ||
856 (((MT.width * MT.height) == (MTFallback.width * MTFallback.height)) && getFramerate(MT) > getFramerate(MTFallback) && (prefFramerate == 0 || getFramerate(MT) <= prefFramerate)))
858 dwStreamFallback = (int)dwStreamTest;
861 if (MT.width == width && MT.height == height)
863 if (dwStreamBest < 0 ||
864 (getFramerate(MT) > getFramerate(MTBest) && (prefFramerate == 0 || getFramerate(MT) <= prefFramerate)))
866 dwStreamBest = (int)dwStreamTest;
874 if (dwStreamBest >= 0 || dwStreamFallback >= 0)
876 // Retrieved stream media type
877 DWORD tryStream = (DWORD)(dwStreamBest >= 0 ? dwStreamBest : dwStreamFallback);
878 MediaType tryMT = dwStreamBest >= 0 ? MTBest : MTFallback;
879 GUID outSubtype = GUID_NULL;
880 UINT32 outStride = 0;
885 case CV_CAP_MODE_BGR:
886 case CV_CAP_MODE_RGB:
887 outSubtype = captureMode == MODE_HW ? MFVideoFormat_RGB32 : MFVideoFormat_RGB24; // HW accelerated mode support only RGB32
888 outStride = (captureMode == MODE_HW ? 4 : 3) * tryMT.width;
889 outSize = outStride * tryMT.height;
891 case CV_CAP_MODE_GRAY:
892 outSubtype = MFVideoFormat_NV12;
893 outStride = tryMT.width;
894 outSize = outStride * tryMT.height * 3 / 2;
896 case CV_CAP_MODE_YUYV:
897 outSubtype = MFVideoFormat_YUY2;
898 outStride = 2 * tryMT.width;
899 outSize = outStride * tryMT.height;
904 _ComPtr<IMFMediaType> mediaTypeOut;
905 if (// Set the output media type.
906 SUCCEEDED(MFCreateMediaType(&mediaTypeOut)) &&
907 SUCCEEDED(mediaTypeOut->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Video)) &&
908 SUCCEEDED(mediaTypeOut->SetGUID(MF_MT_SUBTYPE, convertToFormat ? outSubtype : tryMT.MF_MT_SUBTYPE)) &&
909 SUCCEEDED(mediaTypeOut->SetUINT32(MF_MT_INTERLACE_MODE, convertToFormat ? MFVideoInterlace_Progressive : tryMT.MF_MT_INTERLACE_MODE)) &&
910 SUCCEEDED(MFSetAttributeRatio(mediaTypeOut.Get(), MF_MT_PIXEL_ASPECT_RATIO, aspectRatioN, aspectRatioD)) &&
911 SUCCEEDED(MFSetAttributeSize(mediaTypeOut.Get(), MF_MT_FRAME_SIZE, tryMT.width, tryMT.height)) &&
912 SUCCEEDED(mediaTypeOut->SetUINT32(MF_MT_FIXED_SIZE_SAMPLES, convertToFormat ? 1 : tryMT.MF_MT_FIXED_SIZE_SAMPLES)) &&
913 SUCCEEDED(mediaTypeOut->SetUINT32(MF_MT_SAMPLE_SIZE, convertToFormat ? outSize : tryMT.MF_MT_SAMPLE_SIZE)) &&
914 SUCCEEDED(mediaTypeOut->SetUINT32(MF_MT_DEFAULT_STRIDE, convertToFormat ? outStride : tryMT.MF_MT_DEFAULT_STRIDE)))//Assume BGR24 input
916 if (SUCCEEDED(videoFileSource->SetStreamSelection((DWORD)MF_SOURCE_READER_ALL_STREAMS, false)) &&
917 SUCCEEDED(videoFileSource->SetStreamSelection(tryStream, true)) &&
918 SUCCEEDED(videoFileSource->SetCurrentMediaType(tryStream, NULL, mediaTypeOut.Get()))
921 dwStreamIndex = tryStream;
922 nativeFormat = tryMT;
923 aspectN = aspectRatioN;
924 aspectD = aspectRatioD;
925 outputFormat = outFormat;
926 convertFormat = convertToFormat;
927 captureFormat = MediaType(mediaTypeOut.Get());
936 // Initialize camera input
937 bool CvCapture_MSMF::open(int _index)
941 _ComPtr<IMFAttributes> msAttr = NULL;
942 if (SUCCEEDED(MFCreateAttributes(msAttr.GetAddressOf(), 1)) &&
943 SUCCEEDED(msAttr->SetGUID(
944 MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE,
945 MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_GUID
948 IMFActivate **ppDevices = NULL;
950 if (SUCCEEDED(MFEnumDeviceSources(msAttr.Get(), &ppDevices, &count)))
954 _index = std::min(std::max(0, _index), (int)count - 1);
955 for (int ind = 0; ind < (int)count; ind++)
957 if (ind == _index && ppDevices[ind])
959 // Set source reader parameters
960 _ComPtr<IMFMediaSource> mSrc;
961 _ComPtr<IMFAttributes> srAttr;
962 if (SUCCEEDED(ppDevices[ind]->ActivateObject(__uuidof(IMFMediaSource), (void**)&mSrc)) && mSrc &&
963 SUCCEEDED(MFCreateAttributes(&srAttr, 10)) &&
964 SUCCEEDED(srAttr->SetUINT32(MF_READWRITE_ENABLE_HARDWARE_TRANSFORMS, true)) &&
965 SUCCEEDED(srAttr->SetUINT32(MF_SOURCE_READER_DISABLE_DXVA, false)) &&
966 SUCCEEDED(srAttr->SetUINT32(MF_SOURCE_READER_ENABLE_VIDEO_PROCESSING, false)) &&
967 SUCCEEDED(srAttr->SetUINT32(MF_SOURCE_READER_ENABLE_ADVANCED_VIDEO_PROCESSING, true)))
971 srAttr->SetUnknown(MF_SOURCE_READER_D3D_MANAGER, D3DMgr.Get());
973 if (SUCCEEDED(MFCreateSourceReaderFromMediaSource(mSrc.Get(), srAttr.Get(), &videoFileSource)))
977 if (configureOutput(0, 0, 0, aspectN, aspectD, outputFormat, convertFormat))
983 ppDevices[ind]->Release();
987 CoTaskMemFree(ppDevices);
993 bool CvCapture_MSMF::open(const char* _filename)
999 // Set source reader parameters
1000 _ComPtr<IMFAttributes> srAttr;
1001 if (SUCCEEDED(MFCreateAttributes(&srAttr, 10)) &&
1002 SUCCEEDED(srAttr->SetUINT32(MF_READWRITE_ENABLE_HARDWARE_TRANSFORMS, true)) &&
1003 SUCCEEDED(srAttr->SetUINT32(MF_SOURCE_READER_DISABLE_DXVA, false)) &&
1004 SUCCEEDED(srAttr->SetUINT32(MF_SOURCE_READER_ENABLE_VIDEO_PROCESSING, false)) &&
1005 SUCCEEDED(srAttr->SetUINT32(MF_SOURCE_READER_ENABLE_ADVANCED_VIDEO_PROCESSING, true))
1010 srAttr->SetUnknown(MF_SOURCE_READER_D3D_MANAGER, D3DMgr.Get());
1012 cv::AutoBuffer<wchar_t> unicodeFileName(strlen(_filename) + 1);
1013 MultiByteToWideChar(CP_ACP, 0, _filename, -1, unicodeFileName, (int)strlen(_filename) + 1);
1014 if (SUCCEEDED(MFCreateSourceReaderFromURL(unicodeFileName, srAttr.Get(), &videoFileSource)))
1018 if (configureOutput(0, 0, 0, aspectN, aspectD, outputFormat, convertFormat))
1020 filename = _filename;
1023 if (SUCCEEDED(hr = videoFileSource->GetPresentationAttribute((DWORD)MF_SOURCE_READER_MEDIASOURCE, MF_PD_DURATION, &var)) &&
1026 duration = var.uhVal.QuadPart;
1027 PropVariantClear(&var);
1038 bool CvCapture_MSMF::grabFrame()
1042 DWORD streamIndex, flags;
1044 videoSample.Reset();
1046 while(SUCCEEDED(hr = videoFileSource->ReadSample(
1047 dwStreamIndex, // Stream index.
1049 &streamIndex, // Receives the actual stream index.
1050 &flags, // Receives status flags.
1051 &sampleTime, // Receives the time stamp.
1052 &videoSample // Receives the sample or NULL.
1054 streamIndex == dwStreamIndex && !(flags & (MF_SOURCE_READERF_ERROR|MF_SOURCE_READERF_ALLEFFECTSREMOVED|MF_SOURCE_READERF_ENDOFSTREAM)) &&
1058 if (flags & MF_SOURCE_READERF_STREAMTICK)
1060 DebugPrintOut(L"\tStream tick detected. Retrying to grab the frame\n");
1066 if (streamIndex != dwStreamIndex)
1068 DebugPrintOut(L"\tWrong stream readed. Abort capturing\n");
1071 else if (flags & MF_SOURCE_READERF_ERROR)
1073 DebugPrintOut(L"\tStream reading error. Abort capturing\n");
1076 else if (flags & MF_SOURCE_READERF_ALLEFFECTSREMOVED)
1078 DebugPrintOut(L"\tStream decoding error. Abort capturing\n");
1081 else if (flags & MF_SOURCE_READERF_ENDOFSTREAM)
1083 DebugPrintOut(L"\tEnd of stream detected\n");
1087 if (flags & MF_SOURCE_READERF_NEWSTREAM)
1089 DebugPrintOut(L"\tNew stream detected\n");
1091 if (flags & MF_SOURCE_READERF_NATIVEMEDIATYPECHANGED)
1093 DebugPrintOut(L"\tStream native media type changed\n");
1095 if (flags & MF_SOURCE_READERF_CURRENTMEDIATYPECHANGED)
1097 DebugPrintOut(L"\tStream current media type changed\n");
1106 IplImage* CvCapture_MSMF::retrieveFrame(int)
1109 if (videoSample && SUCCEEDED(videoSample->GetBufferCount(&bcnt)) && bcnt > 0)
1111 _ComPtr<IMFMediaBuffer> buf = NULL;
1112 if (SUCCEEDED(videoSample->GetBufferByIndex(0, &buf)))
1114 DWORD maxsize, cursize;
1116 if (SUCCEEDED(buf->Lock(&ptr, &maxsize, &cursize)))
1120 if ((unsigned int)cursize == captureFormat.MF_MT_SAMPLE_SIZE)
1122 if (!frame || (int)captureFormat.width != frame->width || (int)captureFormat.height != frame->height)
1124 cvReleaseImage(&frame);
1125 unsigned int bytes = outputFormat == CV_CAP_MODE_GRAY || !convertFormat ? 1 : outputFormat == CV_CAP_MODE_YUYV ? 2 : 3;
1126 frame = cvCreateImage(cvSize(captureFormat.width, captureFormat.height), 8, bytes);
1128 switch (outputFormat)
1130 case CV_CAP_MODE_YUYV:
1131 memcpy(frame->imageData, ptr, cursize);
1133 case CV_CAP_MODE_BGR:
1134 if (captureMode == MODE_HW)
1135 cv::cvtColor(cv::Mat(captureFormat.height, captureFormat.width, CV_8UC4, ptr), cv::cvarrToMat(frame), cv::COLOR_BGRA2BGR);
1137 memcpy(frame->imageData, ptr, cursize);
1139 case CV_CAP_MODE_RGB:
1140 if (captureMode == MODE_HW)
1141 cv::cvtColor(cv::Mat(captureFormat.height, captureFormat.width, CV_8UC4, ptr), cv::cvarrToMat(frame), cv::COLOR_BGRA2BGR);
1143 cv::cvtColor(cv::Mat(captureFormat.height, captureFormat.width, CV_8UC3, ptr), cv::cvarrToMat(frame), cv::COLOR_BGR2RGB);
1145 case CV_CAP_MODE_GRAY:
1146 memcpy(frame->imageData, ptr, captureFormat.height*captureFormat.width);
1149 cvReleaseImage(&frame);
1154 cvReleaseImage(&frame);
1158 if (!frame || frame->width != (int)cursize || frame->height != 1)
1160 cvReleaseImage(&frame);
1161 frame = cvCreateImage(cvSize(cursize, 1), 8, 1);
1163 memcpy(frame->imageData, ptr, cursize);
1174 double CvCapture_MSMF::getFramerate(MediaType MT) const
1176 if (MT.MF_MT_SUBTYPE == MFVideoFormat_MP43) //Unable to estimate FPS for MP43
1178 return MT.MF_MT_FRAME_RATE_DENOMINATOR != 0 ? ((double)MT.MF_MT_FRAME_RATE_NUMERATOR) / ((double)MT.MF_MT_FRAME_RATE_DENOMINATOR) : 0;
1181 bool CvCapture_MSMF::setTime(double time, bool rough)
1184 if (SUCCEEDED(videoFileSource->GetPresentationAttribute((DWORD)MF_SOURCE_READER_MEDIASOURCE, MF_SOURCE_READER_MEDIASOURCE_CHARACTERISTICS, &var)) &&
1185 var.vt == VT_UI4 && (var.ulVal & MFMEDIASOURCE_CAN_SEEK && (rough || var.ulVal & MFMEDIASOURCE_HAS_SLOW_SEEK)))
1187 PropVariantClear(&var);
1188 sampleTime = (LONGLONG)floor(time + 0.5);
1190 var.hVal.QuadPart = sampleTime;
1191 HRESULT hr = videoFileSource->SetCurrentPosition(GUID_NULL, var);
1193 videoSample.Reset();
1194 PropVariantClear(&var);
1195 return SUCCEEDED(hr);
1200 double CvCapture_MSMF::getProperty( int property_id ) const
1202 IAMVideoProcAmp *pProcAmp = NULL;
1203 IAMCameraControl *pProcControl = NULL;
1204 // image format properties
1205 if (property_id == CV_CAP_PROP_FORMAT)
1206 return outputFormat;
1207 else if (property_id == CV_CAP_PROP_MODE)
1209 else if (property_id == CV_CAP_PROP_CONVERT_RGB)
1210 return convertFormat ? 1 : 0;
1211 else if (property_id == CV_CAP_PROP_SAR_NUM)
1213 else if (property_id == CV_CAP_PROP_SAR_DEN)
1216 switch (property_id)
1218 case CV_CAP_PROP_FRAME_WIDTH:
1219 return captureFormat.width;
1220 case CV_CAP_PROP_FRAME_HEIGHT:
1221 return captureFormat.height;
1222 case CV_CAP_PROP_FOURCC:
1223 return nativeFormat.MF_MT_SUBTYPE.Data1;
1224 case CV_CAP_PROP_FPS:
1225 return getFramerate(nativeFormat);
1226 case CV_CAP_PROP_FRAME_COUNT:
1228 return floor(((double)duration / 1e7)*getFramerate(nativeFormat) + 0.5);
1231 case CV_CAP_PROP_POS_FRAMES:
1232 return floor(((double)sampleTime / 1e7)*getFramerate(nativeFormat) + 0.5);
1233 case CV_CAP_PROP_POS_MSEC:
1234 return (double)sampleTime / 1e4;
1235 case CV_CAP_PROP_POS_AVI_RATIO:
1237 return (double)sampleTime / duration;
1240 case CV_CAP_PROP_BRIGHTNESS:
1241 if (SUCCEEDED(videoFileSource->GetServiceForStream((DWORD)MF_SOURCE_READER_MEDIASOURCE, GUID_NULL, IID_PPV_ARGS(&pProcAmp))))
1243 long paramVal, paramFlag;
1244 HRESULT hr = pProcAmp->Get(VideoProcAmp_Brightness, ¶mVal, ¶mFlag);
1245 long minVal, maxVal, stepVal;
1247 hr = pProcAmp->GetRange(VideoProcAmp_Brightness, &minVal, &maxVal, &stepVal, ¶mVal, ¶mFlag);//Unable to get the property, trying to return default value
1248 pProcAmp->Release();
1253 case CV_CAP_PROP_CONTRAST:
1254 if (SUCCEEDED(videoFileSource->GetServiceForStream((DWORD)MF_SOURCE_READER_MEDIASOURCE, GUID_NULL, IID_PPV_ARGS(&pProcAmp))))
1256 long paramVal, paramFlag;
1257 HRESULT hr = pProcAmp->Get(VideoProcAmp_Contrast, ¶mVal, ¶mFlag);
1258 long minVal, maxVal, stepVal;
1260 hr = pProcAmp->GetRange(VideoProcAmp_Contrast, &minVal, &maxVal, &stepVal, ¶mVal, ¶mFlag);//Unable to get the property, trying to return default value
1261 pProcAmp->Release();
1266 case CV_CAP_PROP_SATURATION:
1267 if (SUCCEEDED(videoFileSource->GetServiceForStream((DWORD)MF_SOURCE_READER_MEDIASOURCE, GUID_NULL, IID_PPV_ARGS(&pProcAmp))))
1269 long paramVal, paramFlag;
1270 HRESULT hr = pProcAmp->Get(VideoProcAmp_Saturation, ¶mVal, ¶mFlag);
1271 long minVal, maxVal, stepVal;
1273 hr = pProcAmp->GetRange(VideoProcAmp_Saturation, &minVal, &maxVal, &stepVal, ¶mVal, ¶mFlag);//Unable to get the property, trying to return default value
1274 pProcAmp->Release();
1279 case CV_CAP_PROP_HUE:
1280 if (SUCCEEDED(videoFileSource->GetServiceForStream((DWORD)MF_SOURCE_READER_MEDIASOURCE, GUID_NULL, IID_PPV_ARGS(&pProcAmp))))
1282 long paramVal, paramFlag;
1283 HRESULT hr = pProcAmp->Get(VideoProcAmp_Hue, ¶mVal, ¶mFlag);
1284 long minVal, maxVal, stepVal;
1286 hr = pProcAmp->GetRange(VideoProcAmp_Hue, &minVal, &maxVal, &stepVal, ¶mVal, ¶mFlag);//Unable to get the property, trying to return default value
1287 pProcAmp->Release();
1292 case CV_CAP_PROP_GAIN:
1293 if (SUCCEEDED(videoFileSource->GetServiceForStream((DWORD)MF_SOURCE_READER_MEDIASOURCE, GUID_NULL, IID_PPV_ARGS(&pProcAmp))))
1295 long paramVal, paramFlag;
1296 HRESULT hr = pProcAmp->Get(VideoProcAmp_Gain, ¶mVal, ¶mFlag);
1297 long minVal, maxVal, stepVal;
1299 hr = pProcAmp->GetRange(VideoProcAmp_Gain, &minVal, &maxVal, &stepVal, ¶mVal, ¶mFlag);//Unable to get the property, trying to return default value
1300 pProcAmp->Release();
1305 case CV_CAP_PROP_SHARPNESS:
1306 if (SUCCEEDED(videoFileSource->GetServiceForStream((DWORD)MF_SOURCE_READER_MEDIASOURCE, GUID_NULL, IID_PPV_ARGS(&pProcAmp))))
1308 long paramVal, paramFlag;
1309 HRESULT hr = pProcAmp->Get(VideoProcAmp_Sharpness, ¶mVal, ¶mFlag);
1310 long minVal, maxVal, stepVal;
1312 hr = pProcAmp->GetRange(VideoProcAmp_Sharpness, &minVal, &maxVal, &stepVal, ¶mVal, ¶mFlag);//Unable to get the property, trying to return default value
1313 pProcAmp->Release();
1318 case CV_CAP_PROP_GAMMA:
1319 if (SUCCEEDED(videoFileSource->GetServiceForStream((DWORD)MF_SOURCE_READER_MEDIASOURCE, GUID_NULL, IID_PPV_ARGS(&pProcAmp))))
1321 long paramVal, paramFlag;
1322 HRESULT hr = pProcAmp->Get(VideoProcAmp_Gamma, ¶mVal, ¶mFlag);
1323 long minVal, maxVal, stepVal;
1325 hr = pProcAmp->GetRange(VideoProcAmp_Gamma, &minVal, &maxVal, &stepVal, ¶mVal, ¶mFlag);//Unable to get the property, trying to return default value
1326 pProcAmp->Release();
1331 case CV_CAP_PROP_BACKLIGHT:
1332 if (SUCCEEDED(videoFileSource->GetServiceForStream((DWORD)MF_SOURCE_READER_MEDIASOURCE, GUID_NULL, IID_PPV_ARGS(&pProcAmp))))
1334 long paramVal, paramFlag;
1335 HRESULT hr = pProcAmp->Get(VideoProcAmp_BacklightCompensation, ¶mVal, ¶mFlag);
1336 long minVal, maxVal, stepVal;
1338 hr = pProcAmp->GetRange(VideoProcAmp_BacklightCompensation, &minVal, &maxVal, &stepVal, ¶mVal, ¶mFlag);//Unable to get the property, trying to return default value
1339 pProcAmp->Release();
1344 case CV_CAP_PROP_MONOCHROME:
1345 if (SUCCEEDED(videoFileSource->GetServiceForStream((DWORD)MF_SOURCE_READER_MEDIASOURCE, GUID_NULL, IID_PPV_ARGS(&pProcAmp))))
1347 long paramVal, paramFlag;
1348 HRESULT hr = pProcAmp->Get(VideoProcAmp_ColorEnable, ¶mVal, ¶mFlag);
1349 long minVal, maxVal, stepVal;
1351 hr = pProcAmp->GetRange(VideoProcAmp_ColorEnable, &minVal, &maxVal, &stepVal, ¶mVal, ¶mFlag);//Unable to get the property, trying to return default value
1352 pProcAmp->Release();
1354 return paramVal == 0 ? 1 : 0;
1357 case CV_CAP_PROP_TEMPERATURE:
1358 if (SUCCEEDED(videoFileSource->GetServiceForStream((DWORD)MF_SOURCE_READER_MEDIASOURCE, GUID_NULL, IID_PPV_ARGS(&pProcAmp))))
1360 long paramVal, paramFlag;
1361 HRESULT hr = pProcAmp->Get(VideoProcAmp_WhiteBalance, ¶mVal, ¶mFlag);
1362 long minVal, maxVal, stepVal;
1364 hr = pProcAmp->GetRange(VideoProcAmp_WhiteBalance, &minVal, &maxVal, &stepVal, ¶mVal, ¶mFlag);//Unable to get the property, trying to return default value
1365 pProcAmp->Release();
1369 case CV_CAP_PROP_WHITE_BALANCE_BLUE_U:
1370 case CV_CAP_PROP_WHITE_BALANCE_RED_V:
1372 case CV_CAP_PROP_PAN:
1373 if (SUCCEEDED(videoFileSource->GetServiceForStream((DWORD)MF_SOURCE_READER_MEDIASOURCE, GUID_NULL, IID_PPV_ARGS(&pProcControl))))
1375 long paramVal, paramFlag;
1376 HRESULT hr = pProcControl->Get(CameraControl_Pan, ¶mVal, ¶mFlag);
1377 long minVal, maxVal, stepVal;
1379 hr = pProcControl->GetRange(CameraControl_Pan, &minVal, &maxVal, &stepVal, ¶mVal, ¶mFlag);//Unable to get the property, trying to return default value
1380 pProcControl->Release();
1385 case CV_CAP_PROP_TILT:
1386 if (SUCCEEDED(videoFileSource->GetServiceForStream((DWORD)MF_SOURCE_READER_MEDIASOURCE, GUID_NULL, IID_PPV_ARGS(&pProcControl))))
1388 long paramVal, paramFlag;
1389 HRESULT hr = pProcControl->Get(CameraControl_Tilt, ¶mVal, ¶mFlag);
1390 long minVal, maxVal, stepVal;
1392 hr = pProcControl->GetRange(CameraControl_Tilt, &minVal, &maxVal, &stepVal, ¶mVal, ¶mFlag);//Unable to get the property, trying to return default value
1393 pProcControl->Release();
1398 case CV_CAP_PROP_ROLL:
1399 if (SUCCEEDED(videoFileSource->GetServiceForStream((DWORD)MF_SOURCE_READER_MEDIASOURCE, GUID_NULL, IID_PPV_ARGS(&pProcControl))))
1401 long paramVal, paramFlag;
1402 HRESULT hr = pProcControl->Get(CameraControl_Roll, ¶mVal, ¶mFlag);
1403 long minVal, maxVal, stepVal;
1405 hr = pProcControl->GetRange(CameraControl_Roll, &minVal, &maxVal, &stepVal, ¶mVal, ¶mFlag);//Unable to get the property, trying to return default value
1406 pProcControl->Release();
1411 case CV_CAP_PROP_IRIS:
1412 if (SUCCEEDED(videoFileSource->GetServiceForStream((DWORD)MF_SOURCE_READER_MEDIASOURCE, GUID_NULL, IID_PPV_ARGS(&pProcControl))))
1414 long paramVal, paramFlag;
1415 HRESULT hr = pProcControl->Get(CameraControl_Iris, ¶mVal, ¶mFlag);
1416 long minVal, maxVal, stepVal;
1418 hr = pProcControl->GetRange(CameraControl_Iris, &minVal, &maxVal, &stepVal, ¶mVal, ¶mFlag);//Unable to get the property, trying to return default value
1419 pProcControl->Release();
1424 case CV_CAP_PROP_EXPOSURE:
1425 if (SUCCEEDED(videoFileSource->GetServiceForStream((DWORD)MF_SOURCE_READER_MEDIASOURCE, GUID_NULL, IID_PPV_ARGS(&pProcControl))))
1427 long paramVal, paramFlag;
1428 HRESULT hr = pProcControl->Get(CameraControl_Exposure, ¶mVal, ¶mFlag);
1429 long minVal, maxVal, stepVal;
1431 hr = pProcControl->GetRange(CameraControl_Exposure, &minVal, &maxVal, &stepVal, ¶mVal, ¶mFlag);//Unable to get the property, trying to return default value
1432 pProcControl->Release();
1436 case CV_CAP_PROP_AUTO_EXPOSURE:
1437 if (SUCCEEDED(videoFileSource->GetServiceForStream((DWORD)MF_SOURCE_READER_MEDIASOURCE, GUID_NULL, IID_PPV_ARGS(&pProcControl))))
1439 long paramVal, paramFlag;
1440 HRESULT hr = pProcControl->Get(CameraControl_Exposure, ¶mVal, ¶mFlag);
1441 long minVal, maxVal, stepVal;
1443 hr = pProcControl->GetRange(CameraControl_Exposure, &minVal, &maxVal, &stepVal, ¶mVal, ¶mFlag);//Unable to get the property, trying to return default value
1444 pProcControl->Release();
1446 return paramFlag == VideoProcAmp_Flags_Auto;
1449 case CV_CAP_PROP_ZOOM:
1450 if (SUCCEEDED(videoFileSource->GetServiceForStream((DWORD)MF_SOURCE_READER_MEDIASOURCE, GUID_NULL, IID_PPV_ARGS(&pProcControl))))
1452 long paramVal, paramFlag;
1453 HRESULT hr = pProcControl->Get(CameraControl_Zoom, ¶mVal, ¶mFlag);
1454 long minVal, maxVal, stepVal;
1456 hr = pProcControl->GetRange(CameraControl_Zoom, &minVal, &maxVal, &stepVal, ¶mVal, ¶mFlag);//Unable to get the property, trying to return default value
1457 pProcControl->Release();
1462 case CV_CAP_PROP_FOCUS:
1463 if (SUCCEEDED(videoFileSource->GetServiceForStream((DWORD)MF_SOURCE_READER_MEDIASOURCE, GUID_NULL, IID_PPV_ARGS(&pProcControl))))
1465 long paramVal, paramFlag;
1466 HRESULT hr = pProcControl->Get(CameraControl_Focus, ¶mVal, ¶mFlag);
1467 long minVal, maxVal, stepVal;
1469 hr = pProcControl->GetRange(CameraControl_Focus, &minVal, &maxVal, &stepVal, ¶mVal, ¶mFlag);//Unable to get the property, trying to return default value
1470 pProcControl->Release();
1474 case CV_CAP_PROP_AUTOFOCUS:
1475 if (SUCCEEDED(videoFileSource->GetServiceForStream((DWORD)MF_SOURCE_READER_MEDIASOURCE, GUID_NULL, IID_PPV_ARGS(&pProcControl))))
1477 long paramVal, paramFlag;
1478 HRESULT hr = pProcControl->Get(CameraControl_Focus, ¶mVal, ¶mFlag);
1479 long minVal, maxVal, stepVal;
1481 hr = pProcControl->GetRange(CameraControl_Focus, &minVal, &maxVal, &stepVal, ¶mVal, ¶mFlag);//Unable to get the property, trying to return default value
1482 pProcControl->Release();
1484 return paramFlag == VideoProcAmp_Flags_Auto;
1488 case CV_CAP_PROP_RECTIFICATION:
1489 case CV_CAP_PROP_TRIGGER:
1490 case CV_CAP_PROP_TRIGGER_DELAY:
1491 case CV_CAP_PROP_GUID:
1492 case CV_CAP_PROP_ISO_SPEED:
1493 case CV_CAP_PROP_SETTINGS:
1494 case CV_CAP_PROP_BUFFERSIZE:
1502 bool CvCapture_MSMF::setProperty( int property_id, double value )
1504 IAMVideoProcAmp *pProcAmp = NULL;
1505 IAMCameraControl *pProcControl = NULL;
1506 // image capture properties
1507 if (property_id == CV_CAP_PROP_FORMAT)
1510 return configureOutput(captureFormat.width, captureFormat.height, getFramerate(nativeFormat), aspectN, aspectD, (int)cvRound(value), convertFormat);
1512 outputFormat = (int)cvRound(value);
1515 else if (property_id == CV_CAP_PROP_MODE)
1517 switch ((MSMFCapture_Mode)((int)value))
1520 return configureHW(false);
1522 return configureHW(true);
1527 else if (property_id == CV_CAP_PROP_CONVERT_RGB)
1530 return configureOutput(captureFormat.width, captureFormat.height, getFramerate(nativeFormat), aspectN, aspectD, outputFormat, value != 0);
1532 convertFormat = value != 0;
1535 else if (property_id == CV_CAP_PROP_SAR_NUM && value > 0)
1538 return configureOutput(captureFormat.width, captureFormat.height, getFramerate(nativeFormat), (UINT32)cvRound(value), aspectD, outputFormat, convertFormat);
1540 aspectN = (UINT32)cvRound(value);
1543 else if (property_id == CV_CAP_PROP_SAR_DEN && value > 0)
1546 return configureOutput(captureFormat.width, captureFormat.height, getFramerate(nativeFormat), aspectN, (UINT32)cvRound(value), outputFormat, convertFormat);
1548 aspectD = (UINT32)cvRound(value);
1552 switch (property_id)
1554 case CV_CAP_PROP_FRAME_WIDTH:
1556 return configureOutput((UINT32)cvRound(value), captureFormat.height, getFramerate(nativeFormat), aspectN, aspectD, outputFormat, convertFormat);
1558 case CV_CAP_PROP_FRAME_HEIGHT:
1560 return configureOutput(captureFormat.width, (UINT32)cvRound(value), getFramerate(nativeFormat), aspectN, aspectD, outputFormat, convertFormat);
1562 case CV_CAP_PROP_FPS:
1564 return configureOutput(captureFormat.width, captureFormat.height, value, aspectN, aspectD, outputFormat, convertFormat);
1566 case CV_CAP_PROP_FOURCC:
1568 case CV_CAP_PROP_FRAME_COUNT:
1570 case CV_CAP_PROP_POS_AVI_RATIO:
1572 return setTime(duration * value, true);
1574 case CV_CAP_PROP_POS_FRAMES:
1575 if (getFramerate(nativeFormat) != 0)
1576 return setTime(value * 1e7 / getFramerate(nativeFormat), false);
1578 case CV_CAP_PROP_POS_MSEC:
1579 return setTime(value * 1e4, true);
1580 case CV_CAP_PROP_BRIGHTNESS:
1581 if (SUCCEEDED(videoFileSource->GetServiceForStream((DWORD)MF_SOURCE_READER_MEDIASOURCE, GUID_NULL, IID_PPV_ARGS(&pProcAmp))))
1583 long paramVal = (long)value;
1584 HRESULT hr = pProcAmp->Set(VideoProcAmp_Brightness, paramVal, VideoProcAmp_Flags_Manual);
1585 pProcAmp->Release();
1586 return SUCCEEDED(hr);
1589 case CV_CAP_PROP_CONTRAST:
1590 if (SUCCEEDED(videoFileSource->GetServiceForStream((DWORD)MF_SOURCE_READER_MEDIASOURCE, GUID_NULL, IID_PPV_ARGS(&pProcAmp))))
1592 long paramVal = (long)value;
1593 HRESULT hr = pProcAmp->Set(VideoProcAmp_Contrast, paramVal, VideoProcAmp_Flags_Manual);
1594 pProcAmp->Release();
1595 return SUCCEEDED(hr);
1598 case CV_CAP_PROP_SATURATION:
1599 if (SUCCEEDED(videoFileSource->GetServiceForStream((DWORD)MF_SOURCE_READER_MEDIASOURCE, GUID_NULL, IID_PPV_ARGS(&pProcAmp))))
1601 long paramVal = (long)value;
1602 HRESULT hr = pProcAmp->Set(VideoProcAmp_Saturation, paramVal, VideoProcAmp_Flags_Manual);
1603 pProcAmp->Release();
1604 return SUCCEEDED(hr);
1607 case CV_CAP_PROP_HUE:
1608 if (SUCCEEDED(videoFileSource->GetServiceForStream((DWORD)MF_SOURCE_READER_MEDIASOURCE, GUID_NULL, IID_PPV_ARGS(&pProcAmp))))
1610 long paramVal = (long)value;
1611 HRESULT hr = pProcAmp->Set(VideoProcAmp_Hue, paramVal, VideoProcAmp_Flags_Manual);
1612 pProcAmp->Release();
1613 return SUCCEEDED(hr);
1616 case CV_CAP_PROP_GAIN:
1617 if (SUCCEEDED(videoFileSource->GetServiceForStream((DWORD)MF_SOURCE_READER_MEDIASOURCE, GUID_NULL, IID_PPV_ARGS(&pProcAmp))))
1619 long paramVal = (long)value;
1620 HRESULT hr = pProcAmp->Set(VideoProcAmp_Gain, paramVal, VideoProcAmp_Flags_Manual);
1621 pProcAmp->Release();
1622 return SUCCEEDED(hr);
1625 case CV_CAP_PROP_SHARPNESS:
1626 if (SUCCEEDED(videoFileSource->GetServiceForStream((DWORD)MF_SOURCE_READER_MEDIASOURCE, GUID_NULL, IID_PPV_ARGS(&pProcAmp))))
1628 long paramVal = (long)value;
1629 HRESULT hr = pProcAmp->Set(VideoProcAmp_Sharpness, paramVal, VideoProcAmp_Flags_Manual);
1630 pProcAmp->Release();
1631 return SUCCEEDED(hr);
1634 case CV_CAP_PROP_GAMMA:
1635 if (SUCCEEDED(videoFileSource->GetServiceForStream((DWORD)MF_SOURCE_READER_MEDIASOURCE, GUID_NULL, IID_PPV_ARGS(&pProcAmp))))
1637 long paramVal = (long)value;
1638 HRESULT hr = pProcAmp->Set(VideoProcAmp_Gamma, paramVal, VideoProcAmp_Flags_Manual);
1639 pProcAmp->Release();
1640 return SUCCEEDED(hr);
1643 case CV_CAP_PROP_BACKLIGHT:
1644 if (SUCCEEDED(videoFileSource->GetServiceForStream((DWORD)MF_SOURCE_READER_MEDIASOURCE, GUID_NULL, IID_PPV_ARGS(&pProcAmp))))
1646 long paramVal = (long)value;
1647 HRESULT hr = pProcAmp->Set(VideoProcAmp_BacklightCompensation, paramVal, VideoProcAmp_Flags_Manual);
1648 pProcAmp->Release();
1649 return SUCCEEDED(hr);
1652 case CV_CAP_PROP_MONOCHROME:
1653 if (SUCCEEDED(videoFileSource->GetServiceForStream((DWORD)MF_SOURCE_READER_MEDIASOURCE, GUID_NULL, IID_PPV_ARGS(&pProcAmp))))
1655 long paramVal = value != 0 ? 0 : 1;
1656 HRESULT hr = pProcAmp->Set(VideoProcAmp_ColorEnable, paramVal, VideoProcAmp_Flags_Manual);
1657 pProcAmp->Release();
1658 return SUCCEEDED(hr);
1661 case CV_CAP_PROP_TEMPERATURE:
1662 if (SUCCEEDED(videoFileSource->GetServiceForStream((DWORD)MF_SOURCE_READER_MEDIASOURCE, GUID_NULL, IID_PPV_ARGS(&pProcAmp))))
1664 long paramVal = (long)value;
1665 HRESULT hr = pProcAmp->Set(VideoProcAmp_WhiteBalance, paramVal, VideoProcAmp_Flags_Manual);
1666 pProcAmp->Release();
1667 return SUCCEEDED(hr);
1669 case CV_CAP_PROP_WHITE_BALANCE_BLUE_U:
1670 case CV_CAP_PROP_WHITE_BALANCE_RED_V:
1672 case CV_CAP_PROP_PAN:
1673 if (SUCCEEDED(videoFileSource->GetServiceForStream((DWORD)MF_SOURCE_READER_MEDIASOURCE, GUID_NULL, IID_PPV_ARGS(&pProcControl))))
1675 long paramVal = (long)value;
1676 HRESULT hr = pProcControl->Set(CameraControl_Pan, paramVal, VideoProcAmp_Flags_Manual);
1677 pProcControl->Release();
1678 return SUCCEEDED(hr);
1681 case CV_CAP_PROP_TILT:
1682 if (SUCCEEDED(videoFileSource->GetServiceForStream((DWORD)MF_SOURCE_READER_MEDIASOURCE, GUID_NULL, IID_PPV_ARGS(&pProcControl))))
1684 long paramVal = (long)value;
1685 HRESULT hr = pProcControl->Set(CameraControl_Tilt, paramVal, VideoProcAmp_Flags_Manual);
1686 pProcControl->Release();
1687 return SUCCEEDED(hr);
1690 case CV_CAP_PROP_ROLL:
1691 if (SUCCEEDED(videoFileSource->GetServiceForStream((DWORD)MF_SOURCE_READER_MEDIASOURCE, GUID_NULL, IID_PPV_ARGS(&pProcControl))))
1693 long paramVal = (long)value;
1694 HRESULT hr = pProcControl->Set(CameraControl_Roll, paramVal, VideoProcAmp_Flags_Manual);
1695 pProcControl->Release();
1696 return SUCCEEDED(hr);
1699 case CV_CAP_PROP_IRIS:
1700 if (SUCCEEDED(videoFileSource->GetServiceForStream((DWORD)MF_SOURCE_READER_MEDIASOURCE, GUID_NULL, IID_PPV_ARGS(&pProcControl))))
1702 long paramVal = (long)value;
1703 HRESULT hr = pProcControl->Set(CameraControl_Iris, paramVal, VideoProcAmp_Flags_Manual);
1704 pProcControl->Release();
1705 return SUCCEEDED(hr);
1708 case CV_CAP_PROP_EXPOSURE:
1709 if (SUCCEEDED(videoFileSource->GetServiceForStream((DWORD)MF_SOURCE_READER_MEDIASOURCE, GUID_NULL, IID_PPV_ARGS(&pProcControl))))
1711 long paramVal = (long)value;
1712 HRESULT hr = pProcControl->Set(CameraControl_Exposure, paramVal, VideoProcAmp_Flags_Manual);
1713 pProcControl->Release();
1714 return SUCCEEDED(hr);
1716 case CV_CAP_PROP_AUTO_EXPOSURE:
1717 if (SUCCEEDED(videoFileSource->GetServiceForStream((DWORD)MF_SOURCE_READER_MEDIASOURCE, GUID_NULL, IID_PPV_ARGS(&pProcControl))))
1720 HRESULT hr = pProcControl->Set(CameraControl_Exposure, paramVal, value != 0 ? VideoProcAmp_Flags_Auto : VideoProcAmp_Flags_Manual);
1721 pProcControl->Release();
1722 return SUCCEEDED(hr);
1725 case CV_CAP_PROP_ZOOM:
1726 if (SUCCEEDED(videoFileSource->GetServiceForStream((DWORD)MF_SOURCE_READER_MEDIASOURCE, GUID_NULL, IID_PPV_ARGS(&pProcControl))))
1728 long paramVal = (long)value;
1729 HRESULT hr = pProcControl->Set(CameraControl_Zoom, paramVal, VideoProcAmp_Flags_Manual);
1730 pProcControl->Release();
1731 return SUCCEEDED(hr);
1734 case CV_CAP_PROP_FOCUS:
1735 if (SUCCEEDED(videoFileSource->GetServiceForStream((DWORD)MF_SOURCE_READER_MEDIASOURCE, GUID_NULL, IID_PPV_ARGS(&pProcControl))))
1737 long paramVal = (long)value;
1738 HRESULT hr = pProcControl->Set(CameraControl_Focus, paramVal, VideoProcAmp_Flags_Manual);
1739 pProcControl->Release();
1740 return SUCCEEDED(hr);
1742 case CV_CAP_PROP_AUTOFOCUS:
1743 if (SUCCEEDED(videoFileSource->GetServiceForStream((DWORD)MF_SOURCE_READER_MEDIASOURCE, GUID_NULL, IID_PPV_ARGS(&pProcControl))))
1746 HRESULT hr = pProcControl->Set(CameraControl_Focus, paramVal, value != 0 ? VideoProcAmp_Flags_Auto : VideoProcAmp_Flags_Manual);
1747 pProcControl->Release();
1748 return SUCCEEDED(hr);
1752 case CV_CAP_PROP_RECTIFICATION:
1753 case CV_CAP_PROP_TRIGGER:
1754 case CV_CAP_PROP_TRIGGER_DELAY:
1755 case CV_CAP_PROP_GUID:
1756 case CV_CAP_PROP_ISO_SPEED:
1757 case CV_CAP_PROP_SETTINGS:
1758 case CV_CAP_PROP_BUFFERSIZE:
1766 CvCapture* cvCreateCameraCapture_MSMF( int index )
1768 CvCapture_MSMF* capture = new CvCapture_MSMF;
1771 if( capture->open( index ))
1783 CvCapture* cvCreateFileCapture_MSMF (const char* filename)
1785 CvCapture_MSMF* capture = new CvCapture_MSMF;
1788 if( capture->open(filename) )
1805 // Media Foundation-based Video Writer
1809 class CvVideoWriter_MSMF : public CvVideoWriter
1812 CvVideoWriter_MSMF();
1813 virtual ~CvVideoWriter_MSMF();
1814 virtual bool open(const char* filename, int fourcc,
1815 double fps, CvSize frameSize, bool isColor);
1816 virtual void close();
1817 virtual bool writeFrame(const IplImage* img);
1820 Media_Foundation& MF;
1826 GUID encodingFormat;
1830 _ComPtr<IMFSinkWriter> sinkWriter;
1837 static const GUID FourCC2GUID(int fourcc);
1840 CvVideoWriter_MSMF::CvVideoWriter_MSMF():
1841 MF(Media_Foundation::getInstance()),
1846 CvVideoWriter_MSMF::~CvVideoWriter_MSMF()
1851 const GUID CvVideoWriter_MSMF::FourCC2GUID(int fourcc)
1855 case CV_FOURCC_MACRO('d', 'v', '2', '5'):
1856 return MFVideoFormat_DV25; break;
1857 case CV_FOURCC_MACRO('d', 'v', '5', '0'):
1858 return MFVideoFormat_DV50; break;
1859 case CV_FOURCC_MACRO('d', 'v', 'c', ' '):
1860 return MFVideoFormat_DVC; break;
1861 case CV_FOURCC_MACRO('d', 'v', 'h', '1'):
1862 return MFVideoFormat_DVH1; break;
1863 case CV_FOURCC_MACRO('d', 'v', 'h', 'd'):
1864 return MFVideoFormat_DVHD; break;
1865 case CV_FOURCC_MACRO('d', 'v', 's', 'd'):
1866 return MFVideoFormat_DVSD; break;
1867 case CV_FOURCC_MACRO('d', 'v', 's', 'l'):
1868 return MFVideoFormat_DVSL; break;
1869 #if (WINVER >= 0x0602)
1870 case CV_FOURCC_MACRO('H', '2', '6', '3'): // Available only for Win 8 target.
1871 return MFVideoFormat_H263; break;
1873 case CV_FOURCC_MACRO('H', '2', '6', '4'):
1874 return MFVideoFormat_H264; break;
1875 case CV_FOURCC_MACRO('M', '4', 'S', '2'):
1876 return MFVideoFormat_M4S2; break;
1877 case CV_FOURCC_MACRO('M', 'J', 'P', 'G'):
1878 return MFVideoFormat_MJPG; break;
1879 case CV_FOURCC_MACRO('M', 'P', '4', '3'):
1880 return MFVideoFormat_MP43; break;
1881 case CV_FOURCC_MACRO('M', 'P', '4', 'S'):
1882 return MFVideoFormat_MP4S; break;
1883 case CV_FOURCC_MACRO('M', 'P', '4', 'V'):
1884 return MFVideoFormat_MP4V; break;
1885 case CV_FOURCC_MACRO('M', 'P', 'G', '1'):
1886 return MFVideoFormat_MPG1; break;
1887 case CV_FOURCC_MACRO('M', 'S', 'S', '1'):
1888 return MFVideoFormat_MSS1; break;
1889 case CV_FOURCC_MACRO('M', 'S', 'S', '2'):
1890 return MFVideoFormat_MSS2; break;
1891 case CV_FOURCC_MACRO('W', 'M', 'V', '1'):
1892 return MFVideoFormat_WMV1; break;
1893 case CV_FOURCC_MACRO('W', 'M', 'V', '2'):
1894 return MFVideoFormat_WMV2; break;
1895 case CV_FOURCC_MACRO('W', 'M', 'V', '3'):
1896 return MFVideoFormat_WMV3; break;
1897 case CV_FOURCC_MACRO('W', 'V', 'C', '1'):
1898 return MFVideoFormat_WVC1; break;
1900 return MFVideoFormat_H264;
1904 bool CvVideoWriter_MSMF::open( const char* filename, int fourcc,
1905 double _fps, CvSize _frameSize, bool /*isColor*/ )
1909 videoWidth = _frameSize.width;
1910 videoHeight = _frameSize.height;
1912 bitRate = (UINT32)fps*videoWidth*videoHeight; // 1-bit per pixel
1913 encodingFormat = FourCC2GUID(fourcc);
1914 inputFormat = MFVideoFormat_RGB32;
1916 _ComPtr<IMFMediaType> mediaTypeOut;
1917 _ComPtr<IMFMediaType> mediaTypeIn;
1918 _ComPtr<IMFAttributes> spAttr;
1919 if (// Set the output media type.
1920 SUCCEEDED(MFCreateMediaType(&mediaTypeOut)) &&
1921 SUCCEEDED(mediaTypeOut->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Video)) &&
1922 SUCCEEDED(mediaTypeOut->SetGUID(MF_MT_SUBTYPE, encodingFormat)) &&
1923 SUCCEEDED(mediaTypeOut->SetUINT32(MF_MT_AVG_BITRATE, bitRate)) &&
1924 SUCCEEDED(mediaTypeOut->SetUINT32(MF_MT_INTERLACE_MODE, MFVideoInterlace_Progressive)) &&
1925 SUCCEEDED(MFSetAttributeSize(mediaTypeOut.Get(), MF_MT_FRAME_SIZE, videoWidth, videoHeight)) &&
1926 SUCCEEDED(MFSetAttributeRatio(mediaTypeOut.Get(), MF_MT_FRAME_RATE, (UINT32)fps, 1)) &&
1927 SUCCEEDED(MFSetAttributeRatio(mediaTypeOut.Get(), MF_MT_PIXEL_ASPECT_RATIO, 1, 1)) &&
1928 // Set the input media type.
1929 SUCCEEDED(MFCreateMediaType(&mediaTypeIn)) &&
1930 SUCCEEDED(mediaTypeIn->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Video)) &&
1931 SUCCEEDED(mediaTypeIn->SetGUID(MF_MT_SUBTYPE, inputFormat)) &&
1932 SUCCEEDED(mediaTypeIn->SetUINT32(MF_MT_INTERLACE_MODE, MFVideoInterlace_Progressive)) &&
1933 SUCCEEDED(mediaTypeIn->SetUINT32(MF_MT_DEFAULT_STRIDE, 4 * videoWidth)) && //Assume BGR32 input
1934 SUCCEEDED(MFSetAttributeSize(mediaTypeIn.Get(), MF_MT_FRAME_SIZE, videoWidth, videoHeight)) &&
1935 SUCCEEDED(MFSetAttributeRatio(mediaTypeIn.Get(), MF_MT_FRAME_RATE, (UINT32)fps, 1)) &&
1936 SUCCEEDED(MFSetAttributeRatio(mediaTypeIn.Get(), MF_MT_PIXEL_ASPECT_RATIO, 1, 1)) &&
1937 // Set sink writer parameters
1938 SUCCEEDED(MFCreateAttributes(&spAttr, 10)) &&
1939 SUCCEEDED(spAttr->SetUINT32(MF_READWRITE_ENABLE_HARDWARE_TRANSFORMS, true)) &&
1940 SUCCEEDED(spAttr->SetUINT32(MF_SINK_WRITER_DISABLE_THROTTLING, true))
1943 // Create the sink writer
1944 cv::AutoBuffer<wchar_t> unicodeFileName(strlen(filename) + 1);
1945 MultiByteToWideChar(CP_ACP, 0, filename, -1, unicodeFileName, (int)strlen(filename) + 1);
1946 HRESULT hr = MFCreateSinkWriterFromURL(unicodeFileName, NULL, spAttr.Get(), &sinkWriter);
1949 // Configure the sink writer and tell it start to start accepting data
1950 if (SUCCEEDED(sinkWriter->AddStream(mediaTypeOut.Get(), &streamIndex)) &&
1951 SUCCEEDED(sinkWriter->SetInputMediaType(streamIndex, mediaTypeIn.Get(), NULL)) &&
1952 SUCCEEDED(sinkWriter->BeginWriting()))
1956 MFFrameRateToAverageTimePerFrame((UINT32)fps, 1, &rtDuration);
1965 void CvVideoWriter_MSMF::close()
1970 sinkWriter->Finalize();
1975 bool CvVideoWriter_MSMF::writeFrame(const IplImage* img)
1978 (img->nChannels != 1 && img->nChannels != 3 && img->nChannels != 4) ||
1979 (UINT32)img->width != videoWidth || (UINT32)img->height != videoHeight)
1982 const LONG cbWidth = 4 * videoWidth;
1983 const DWORD cbBuffer = cbWidth * videoHeight;
1984 _ComPtr<IMFSample> sample;
1985 _ComPtr<IMFMediaBuffer> buffer;
1987 // Prepare a media sample.
1988 if (SUCCEEDED(MFCreateSample(&sample)) &&
1989 // Set sample time stamp and duration.
1990 SUCCEEDED(sample->SetSampleTime(rtStart)) &&
1991 SUCCEEDED(sample->SetSampleDuration(rtDuration)) &&
1992 // Create a memory buffer.
1993 SUCCEEDED(MFCreateMemoryBuffer(cbBuffer, &buffer)) &&
1994 // Set the data length of the buffer.
1995 SUCCEEDED(buffer->SetCurrentLength(cbBuffer)) &&
1996 // Add the buffer to the sample.
1997 SUCCEEDED(sample->AddBuffer(buffer.Get())) &&
1999 SUCCEEDED(buffer->Lock(&pData, NULL, NULL)))
2001 // Copy the video frame to the buffer.
2002 cv::cvtColor(cv::cvarrToMat(img), cv::Mat(videoHeight, videoWidth, CV_8UC4, pData, cbWidth), img->nChannels > 1 ? cv::COLOR_BGR2BGRA : cv::COLOR_GRAY2BGRA);
2004 // Send media sample to the Sink Writer.
2005 if (SUCCEEDED(sinkWriter->WriteSample(streamIndex, sample.Get())))
2007 rtStart += rtDuration;
2015 CvVideoWriter* cvCreateVideoWriter_MSMF( const char* filename, int fourcc,
2016 double fps, CvSize frameSize, int isColor )
2018 CvVideoWriter_MSMF* writer = new CvVideoWriter_MSMF;
2019 if( writer->open( filename, fourcc, fps, frameSize, isColor != 0 ))