2013-04-03 09:01:20 +08:00
|
|
|
/*M///////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
//
|
|
|
|
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
|
|
|
|
//
|
|
|
|
// By downloading, copying, installing or using the software you agree to this license.
|
|
|
|
// If you do not agree to this license, do not download, install,
|
|
|
|
// copy or use the software.
|
|
|
|
//
|
|
|
|
//
|
|
|
|
// Intel License Agreement
|
|
|
|
// For Open Source Computer Vision Library
|
|
|
|
//
|
|
|
|
// Copyright (C) 2000, Intel Corporation, all rights reserved.
|
|
|
|
// Third party copyrights are property of their respective owners.
|
|
|
|
//
|
|
|
|
// Redistribution and use in source and binary forms, with or without modification,
|
|
|
|
// are permitted provided that the following conditions are met:
|
|
|
|
//
|
|
|
|
// * Redistribution's of source code must retain the above copyright notice,
|
|
|
|
// this list of conditions and the following disclaimer.
|
|
|
|
//
|
|
|
|
// * Redistribution's in binary form must reproduce the above copyright notice,
|
|
|
|
// this list of conditions and the following disclaimer in the documentation
|
|
|
|
// and/or other materials provided with the distribution.
|
|
|
|
//
|
|
|
|
// * The name of Intel Corporation may not be used to endorse or promote products
|
|
|
|
// derived from this software without specific prior written permission.
|
|
|
|
//
|
|
|
|
// This software is provided by the copyright holders and contributors "as is" and
|
|
|
|
// any express or implied warranties, including, but not limited to, the implied
|
|
|
|
// warranties of merchantability and fitness for a particular purpose are disclaimed.
|
|
|
|
// In no event shall the Intel Corporation or contributors be liable for any direct,
|
|
|
|
// indirect, incidental, special, exemplary, or consequential damages
|
|
|
|
// (including, but not limited to, procurement of substitute goods or services;
|
|
|
|
// loss of use, data, or profits; or business interruption) however caused
|
|
|
|
// and on any theory of liability, whether in contract, strict liability,
|
|
|
|
// or tort (including negligence or otherwise) arising in any way out of
|
|
|
|
// the use of this software, even if advised of the possibility of such damage.
|
|
|
|
//
|
|
|
|
//M*/
|
|
|
|
#include "precomp.hpp"
|
|
|
|
#if (defined WIN32 || defined _WIN32) && defined HAVE_MSMF
|
|
|
|
/*
|
|
|
|
Media Foundation-based Video Capturing module is based on
|
|
|
|
videoInput library by Evgeny Pereguda:
|
|
|
|
http://www.codeproject.com/Articles/559437/Capturing-of-video-from-web-camera-on-Windows-7-an
|
|
|
|
Originaly licensed under The Code Project Open License (CPOL) 1.02:
|
|
|
|
http://www.codeproject.com/info/cpol10.aspx
|
|
|
|
*/
|
|
|
|
#include <windows.h>
|
|
|
|
#include <guiddef.h>
|
|
|
|
#include <mfidl.h>
|
|
|
|
#include <Mfapi.h>
|
|
|
|
#include <mfplay.h>
|
|
|
|
#include <mfobjects.h>
|
2013-05-15 21:09:03 +08:00
|
|
|
#include <strsafe.h>
|
2013-05-06 18:36:51 +08:00
|
|
|
#include <Mfreadwrite.h>
|
2013-04-03 09:01:20 +08:00
|
|
|
#include <new>
|
|
|
|
#include <map>
|
|
|
|
#include <vector>
|
|
|
|
#include <string>
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdarg.h>
|
|
|
|
#include <string.h>
|
2013-04-16 21:25:10 +08:00
|
|
|
|
2013-04-03 09:01:20 +08:00
|
|
|
#pragma warning(disable:4503)
|
|
|
|
#pragma comment(lib, "mfplat")
|
|
|
|
#pragma comment(lib, "mf")
|
|
|
|
#pragma comment(lib, "mfuuid")
|
|
|
|
#pragma comment(lib, "Strmiids")
|
2013-05-06 18:36:51 +08:00
|
|
|
#pragma comment(lib, "Mfreadwrite")
|
2013-04-03 09:01:20 +08:00
|
|
|
#pragma comment(lib, "MinCore_Downlevel")
|
2013-04-16 21:25:10 +08:00
|
|
|
|
2013-05-19 04:04:31 +08:00
|
|
|
// for ComPtr usage
|
|
|
|
#include <wrl/client.h>
|
2013-05-15 21:09:03 +08:00
|
|
|
using namespace Microsoft::WRL;
|
|
|
|
|
Update cap_msmf.cpp
Add support for WinRT in the MF capture framework by removing the disallowed calls to enumerate devices and create a sample grabber sink and adding framework for the MediaCapture interface and a custom sink which interfaces with the sample grabber callback interface. The change requires discussion for making it completely functional as redundancy is required given that if the source is a video file, the old code pathways must be used. Otherwise all IMFMediaSession, IMFMediaSource, and IMFActivate code must use a MediaCapture code path and all sink code must use the CMediaSink custom sink.
Support for the custom sink is extended to non-WinRT not for compatibility as Windows Vista client is a minimum regardless, but because it offers more flexibility, could be faster and is able to be used as an optionally different code path during sink creation based on a future configuration parameter.
My discussion and proposal to finish this change:
Devices are so easily enumerated through WinRT Windows.Devices namespace that wrapping the calls in a library is quite a chore for little benefit though to get the various modes and formats could still be a worthwhile project. For now conditional compilation to remove videodevices and any offending non-video file related activity in videodevice. In my opinion, this is a different , far less fundamental and important change which can possibly be done as a future project and also much more easily implemented in C++/CX.
ImageGrabber has the IMFSampleGrabberSinkCallback replaced with a base class (SharedSampleGrabber) which also be is base class for ImageGrabberRT. This change is necessary as the custom sink does not require a thread to pump events which is done through MediaCapture already. IMFSampleGrabberSinkCallback is the common element between both models and that piece can be shared. Initializing the new ImageGrabberRT is as simple as passing an already initialized MediaCapture object and any video format/encoding parameters.
The concurrency event is necessary to wait for completion and is the way the underlying, IAsyncAction wrappers in the task library work as well. Native WIN32 event objects would be an option if HAVE_CONCURRENCY is not defined. I could even imagine doing it with sleep/thread yield and InterlockedCompareExchange yet I am not enthusiastic about that approach either. Since there is a specific compiler HAVE_ for concurrency, I do not like pulling it in though I think for WinRT it is safe to say we will always have it available though should probably conditionally compile with the Interlocked option as WIN32 events would require HAVE_WIN32.
It looks like C++/CX cannot be used for the IMediaExtension sink (which should not be a problem) as using COM objects requires WRL and though deriving from IMediaExtension can be done, there is little purpose without COM. Objects from C++/CX can be swapped to interact with objects from native C++ as Inspectable* can reinterpret_cast to the ref object IInspectable^ and vice-versa. A solution to the COM class with C++/CX would be great so we could have dual support. Also without #define for every WRL object in use, the code will get quite muddy given that the */^ would need to be ifdef'd everywhere.
Update cap_msmf.cpp
Fixed bugs and completed the change. I believe the new classes need to be moved to a header file as the file has become to large and more classes need to be added for handling all the asynchronous problems (one wrapping IAsyncAction in a task and another for making a task out of IAsyncAction). Unfortunately, blocking on the UI thread is not an option in WinRT so a synchronous architecture is considered "illegal" by Microsoft's standards even if implementable (C++/CX ppltasks library throws errors if you try it). Worse, either by design or a bug in the MF MediaCapture class with Custom Sinks causes a crash if stop/start previewing without reinitializing (spPreferredPreviewMediaType is fatally nulled). After decompiling Windows.Media.dll, I worked around this in my own projects by using an activate-able custom sink ID which strangely assigns 1 to this pointer allowing it to be reinitialized in what can only be described as a hack by Microsoft. This would add additional overhead to the project to implement especially for static libraries as it requires IDL/DLL exporting followed by manifest declaration. Better to document that it is not supported.
Furthermore, an additional class for IMFAttributes should be implemented to make clean architecture for passing around attributes as opposed to directly calling non-COM interface calls on the objects and making use of SetProperties which would also be a set up for an object that uses the RuntimeClass activation ID.
The remaining changes are not difficult and will be complete soon along with debug tracing messages.
Update cap_msmf.cpp
Create cap_msmf.h
Update cap_msmf.cpp
Update cap_msmf.h
Update cap_msmf.cpp
Update cap_msmf.h
Update and rename cap_msmf.h to cap_msmf.hpp
Update cap_msmf.cpp
Update CMakeLists.txt
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.cpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Successful test - samples are grabbed
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Create ppltasks_winrt.h
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update ppltasks_winrt.h
Library updated and cleaned up with comments, marshaling, exceptions and linker settings
Update ppltasks_winrt.h
Fixed trailing whitespace
2013-12-14 16:53:30 +08:00
|
|
|
#include <mferror.h>
|
|
|
|
|
|
|
|
#ifdef HAVE_WINRT
|
|
|
|
#ifdef __cplusplus_winrt
|
|
|
|
#include <agile.h>
|
|
|
|
#include <vccorlib.h>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#include <wrl\async.h>
|
|
|
|
#include <wrl\implements.h>
|
|
|
|
#include <wrl\module.h>
|
|
|
|
#include <wrl\wrappers\corewrappers.h>
|
|
|
|
#include <windows.media.capture.h>
|
|
|
|
#include <windows.devices.enumeration.h>
|
|
|
|
#include <concrt.h>
|
|
|
|
#include <ppltasks.h>
|
|
|
|
|
|
|
|
using namespace Microsoft::WRL::Wrappers;
|
|
|
|
#endif
|
|
|
|
|
2013-04-03 09:01:20 +08:00
|
|
|
struct IMFMediaType;
|
Update cap_msmf.cpp
Add support for WinRT in the MF capture framework by removing the disallowed calls to enumerate devices and create a sample grabber sink and adding framework for the MediaCapture interface and a custom sink which interfaces with the sample grabber callback interface. The change requires discussion for making it completely functional as redundancy is required given that if the source is a video file, the old code pathways must be used. Otherwise all IMFMediaSession, IMFMediaSource, and IMFActivate code must use a MediaCapture code path and all sink code must use the CMediaSink custom sink.
Support for the custom sink is extended to non-WinRT not for compatibility as Windows Vista client is a minimum regardless, but because it offers more flexibility, could be faster and is able to be used as an optionally different code path during sink creation based on a future configuration parameter.
My discussion and proposal to finish this change:
Devices are so easily enumerated through WinRT Windows.Devices namespace that wrapping the calls in a library is quite a chore for little benefit though to get the various modes and formats could still be a worthwhile project. For now conditional compilation to remove videodevices and any offending non-video file related activity in videodevice. In my opinion, this is a different , far less fundamental and important change which can possibly be done as a future project and also much more easily implemented in C++/CX.
ImageGrabber has the IMFSampleGrabberSinkCallback replaced with a base class (SharedSampleGrabber) which also be is base class for ImageGrabberRT. This change is necessary as the custom sink does not require a thread to pump events which is done through MediaCapture already. IMFSampleGrabberSinkCallback is the common element between both models and that piece can be shared. Initializing the new ImageGrabberRT is as simple as passing an already initialized MediaCapture object and any video format/encoding parameters.
The concurrency event is necessary to wait for completion and is the way the underlying, IAsyncAction wrappers in the task library work as well. Native WIN32 event objects would be an option if HAVE_CONCURRENCY is not defined. I could even imagine doing it with sleep/thread yield and InterlockedCompareExchange yet I am not enthusiastic about that approach either. Since there is a specific compiler HAVE_ for concurrency, I do not like pulling it in though I think for WinRT it is safe to say we will always have it available though should probably conditionally compile with the Interlocked option as WIN32 events would require HAVE_WIN32.
It looks like C++/CX cannot be used for the IMediaExtension sink (which should not be a problem) as using COM objects requires WRL and though deriving from IMediaExtension can be done, there is little purpose without COM. Objects from C++/CX can be swapped to interact with objects from native C++ as Inspectable* can reinterpret_cast to the ref object IInspectable^ and vice-versa. A solution to the COM class with C++/CX would be great so we could have dual support. Also without #define for every WRL object in use, the code will get quite muddy given that the */^ would need to be ifdef'd everywhere.
Update cap_msmf.cpp
Fixed bugs and completed the change. I believe the new classes need to be moved to a header file as the file has become to large and more classes need to be added for handling all the asynchronous problems (one wrapping IAsyncAction in a task and another for making a task out of IAsyncAction). Unfortunately, blocking on the UI thread is not an option in WinRT so a synchronous architecture is considered "illegal" by Microsoft's standards even if implementable (C++/CX ppltasks library throws errors if you try it). Worse, either by design or a bug in the MF MediaCapture class with Custom Sinks causes a crash if stop/start previewing without reinitializing (spPreferredPreviewMediaType is fatally nulled). After decompiling Windows.Media.dll, I worked around this in my own projects by using an activate-able custom sink ID which strangely assigns 1 to this pointer allowing it to be reinitialized in what can only be described as a hack by Microsoft. This would add additional overhead to the project to implement especially for static libraries as it requires IDL/DLL exporting followed by manifest declaration. Better to document that it is not supported.
Furthermore, an additional class for IMFAttributes should be implemented to make clean architecture for passing around attributes as opposed to directly calling non-COM interface calls on the objects and making use of SetProperties which would also be a set up for an object that uses the RuntimeClass activation ID.
The remaining changes are not difficult and will be complete soon along with debug tracing messages.
Update cap_msmf.cpp
Create cap_msmf.h
Update cap_msmf.cpp
Update cap_msmf.h
Update cap_msmf.cpp
Update cap_msmf.h
Update and rename cap_msmf.h to cap_msmf.hpp
Update cap_msmf.cpp
Update CMakeLists.txt
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.cpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Successful test - samples are grabbed
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Create ppltasks_winrt.h
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update ppltasks_winrt.h
Library updated and cleaned up with comments, marshaling, exceptions and linker settings
Update ppltasks_winrt.h
Fixed trailing whitespace
2013-12-14 16:53:30 +08:00
|
|
|
#ifndef HAVE_WINRT
|
2013-04-03 09:01:20 +08:00
|
|
|
struct IMFActivate;
|
|
|
|
struct IMFMediaSource;
|
Update cap_msmf.cpp
Add support for WinRT in the MF capture framework by removing the disallowed calls to enumerate devices and create a sample grabber sink and adding framework for the MediaCapture interface and a custom sink which interfaces with the sample grabber callback interface. The change requires discussion for making it completely functional as redundancy is required given that if the source is a video file, the old code pathways must be used. Otherwise all IMFMediaSession, IMFMediaSource, and IMFActivate code must use a MediaCapture code path and all sink code must use the CMediaSink custom sink.
Support for the custom sink is extended to non-WinRT not for compatibility as Windows Vista client is a minimum regardless, but because it offers more flexibility, could be faster and is able to be used as an optionally different code path during sink creation based on a future configuration parameter.
My discussion and proposal to finish this change:
Devices are so easily enumerated through WinRT Windows.Devices namespace that wrapping the calls in a library is quite a chore for little benefit though to get the various modes and formats could still be a worthwhile project. For now conditional compilation to remove videodevices and any offending non-video file related activity in videodevice. In my opinion, this is a different , far less fundamental and important change which can possibly be done as a future project and also much more easily implemented in C++/CX.
ImageGrabber has the IMFSampleGrabberSinkCallback replaced with a base class (SharedSampleGrabber) which also be is base class for ImageGrabberRT. This change is necessary as the custom sink does not require a thread to pump events which is done through MediaCapture already. IMFSampleGrabberSinkCallback is the common element between both models and that piece can be shared. Initializing the new ImageGrabberRT is as simple as passing an already initialized MediaCapture object and any video format/encoding parameters.
The concurrency event is necessary to wait for completion and is the way the underlying, IAsyncAction wrappers in the task library work as well. Native WIN32 event objects would be an option if HAVE_CONCURRENCY is not defined. I could even imagine doing it with sleep/thread yield and InterlockedCompareExchange yet I am not enthusiastic about that approach either. Since there is a specific compiler HAVE_ for concurrency, I do not like pulling it in though I think for WinRT it is safe to say we will always have it available though should probably conditionally compile with the Interlocked option as WIN32 events would require HAVE_WIN32.
It looks like C++/CX cannot be used for the IMediaExtension sink (which should not be a problem) as using COM objects requires WRL and though deriving from IMediaExtension can be done, there is little purpose without COM. Objects from C++/CX can be swapped to interact with objects from native C++ as Inspectable* can reinterpret_cast to the ref object IInspectable^ and vice-versa. A solution to the COM class with C++/CX would be great so we could have dual support. Also without #define for every WRL object in use, the code will get quite muddy given that the */^ would need to be ifdef'd everywhere.
Update cap_msmf.cpp
Fixed bugs and completed the change. I believe the new classes need to be moved to a header file as the file has become to large and more classes need to be added for handling all the asynchronous problems (one wrapping IAsyncAction in a task and another for making a task out of IAsyncAction). Unfortunately, blocking on the UI thread is not an option in WinRT so a synchronous architecture is considered "illegal" by Microsoft's standards even if implementable (C++/CX ppltasks library throws errors if you try it). Worse, either by design or a bug in the MF MediaCapture class with Custom Sinks causes a crash if stop/start previewing without reinitializing (spPreferredPreviewMediaType is fatally nulled). After decompiling Windows.Media.dll, I worked around this in my own projects by using an activate-able custom sink ID which strangely assigns 1 to this pointer allowing it to be reinitialized in what can only be described as a hack by Microsoft. This would add additional overhead to the project to implement especially for static libraries as it requires IDL/DLL exporting followed by manifest declaration. Better to document that it is not supported.
Furthermore, an additional class for IMFAttributes should be implemented to make clean architecture for passing around attributes as opposed to directly calling non-COM interface calls on the objects and making use of SetProperties which would also be a set up for an object that uses the RuntimeClass activation ID.
The remaining changes are not difficult and will be complete soon along with debug tracing messages.
Update cap_msmf.cpp
Create cap_msmf.h
Update cap_msmf.cpp
Update cap_msmf.h
Update cap_msmf.cpp
Update cap_msmf.h
Update and rename cap_msmf.h to cap_msmf.hpp
Update cap_msmf.cpp
Update CMakeLists.txt
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.cpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Successful test - samples are grabbed
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Create ppltasks_winrt.h
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update ppltasks_winrt.h
Library updated and cleaned up with comments, marshaling, exceptions and linker settings
Update ppltasks_winrt.h
Fixed trailing whitespace
2013-12-14 16:53:30 +08:00
|
|
|
#endif
|
2013-04-03 09:01:20 +08:00
|
|
|
struct IMFAttributes;
|
2013-04-16 21:25:10 +08:00
|
|
|
|
2013-04-03 09:01:20 +08:00
|
|
|
namespace
|
|
|
|
{
|
2013-04-16 21:25:10 +08:00
|
|
|
|
2013-04-03 09:01:20 +08:00
|
|
|
template <class T> void SafeRelease(T **ppT)
|
|
|
|
{
|
|
|
|
if (*ppT)
|
|
|
|
{
|
|
|
|
(*ppT)->Release();
|
|
|
|
*ppT = NULL;
|
|
|
|
}
|
|
|
|
}
|
2013-04-16 21:25:10 +08:00
|
|
|
|
|
|
|
/// Class for printing info into consol
|
2013-04-03 09:01:20 +08:00
|
|
|
class DebugPrintOut
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
~DebugPrintOut(void);
|
|
|
|
static DebugPrintOut& getInstance();
|
|
|
|
void printOut(const wchar_t *format, ...);
|
|
|
|
void setVerbose(bool state);
|
|
|
|
bool verbose;
|
2013-04-03 18:48:23 +08:00
|
|
|
private:
|
|
|
|
DebugPrintOut(void);
|
2013-04-03 09:01:20 +08:00
|
|
|
};
|
2013-04-16 21:25:10 +08:00
|
|
|
|
Update cap_msmf.cpp
Add support for WinRT in the MF capture framework by removing the disallowed calls to enumerate devices and create a sample grabber sink and adding framework for the MediaCapture interface and a custom sink which interfaces with the sample grabber callback interface. The change requires discussion for making it completely functional as redundancy is required given that if the source is a video file, the old code pathways must be used. Otherwise all IMFMediaSession, IMFMediaSource, and IMFActivate code must use a MediaCapture code path and all sink code must use the CMediaSink custom sink.
Support for the custom sink is extended to non-WinRT not for compatibility as Windows Vista client is a minimum regardless, but because it offers more flexibility, could be faster and is able to be used as an optionally different code path during sink creation based on a future configuration parameter.
My discussion and proposal to finish this change:
Devices are so easily enumerated through WinRT Windows.Devices namespace that wrapping the calls in a library is quite a chore for little benefit though to get the various modes and formats could still be a worthwhile project. For now conditional compilation to remove videodevices and any offending non-video file related activity in videodevice. In my opinion, this is a different , far less fundamental and important change which can possibly be done as a future project and also much more easily implemented in C++/CX.
ImageGrabber has the IMFSampleGrabberSinkCallback replaced with a base class (SharedSampleGrabber) which also be is base class for ImageGrabberRT. This change is necessary as the custom sink does not require a thread to pump events which is done through MediaCapture already. IMFSampleGrabberSinkCallback is the common element between both models and that piece can be shared. Initializing the new ImageGrabberRT is as simple as passing an already initialized MediaCapture object and any video format/encoding parameters.
The concurrency event is necessary to wait for completion and is the way the underlying, IAsyncAction wrappers in the task library work as well. Native WIN32 event objects would be an option if HAVE_CONCURRENCY is not defined. I could even imagine doing it with sleep/thread yield and InterlockedCompareExchange yet I am not enthusiastic about that approach either. Since there is a specific compiler HAVE_ for concurrency, I do not like pulling it in though I think for WinRT it is safe to say we will always have it available though should probably conditionally compile with the Interlocked option as WIN32 events would require HAVE_WIN32.
It looks like C++/CX cannot be used for the IMediaExtension sink (which should not be a problem) as using COM objects requires WRL and though deriving from IMediaExtension can be done, there is little purpose without COM. Objects from C++/CX can be swapped to interact with objects from native C++ as Inspectable* can reinterpret_cast to the ref object IInspectable^ and vice-versa. A solution to the COM class with C++/CX would be great so we could have dual support. Also without #define for every WRL object in use, the code will get quite muddy given that the */^ would need to be ifdef'd everywhere.
Update cap_msmf.cpp
Fixed bugs and completed the change. I believe the new classes need to be moved to a header file as the file has become to large and more classes need to be added for handling all the asynchronous problems (one wrapping IAsyncAction in a task and another for making a task out of IAsyncAction). Unfortunately, blocking on the UI thread is not an option in WinRT so a synchronous architecture is considered "illegal" by Microsoft's standards even if implementable (C++/CX ppltasks library throws errors if you try it). Worse, either by design or a bug in the MF MediaCapture class with Custom Sinks causes a crash if stop/start previewing without reinitializing (spPreferredPreviewMediaType is fatally nulled). After decompiling Windows.Media.dll, I worked around this in my own projects by using an activate-able custom sink ID which strangely assigns 1 to this pointer allowing it to be reinitialized in what can only be described as a hack by Microsoft. This would add additional overhead to the project to implement especially for static libraries as it requires IDL/DLL exporting followed by manifest declaration. Better to document that it is not supported.
Furthermore, an additional class for IMFAttributes should be implemented to make clean architecture for passing around attributes as opposed to directly calling non-COM interface calls on the objects and making use of SetProperties which would also be a set up for an object that uses the RuntimeClass activation ID.
The remaining changes are not difficult and will be complete soon along with debug tracing messages.
Update cap_msmf.cpp
Create cap_msmf.h
Update cap_msmf.cpp
Update cap_msmf.h
Update cap_msmf.cpp
Update cap_msmf.h
Update and rename cap_msmf.h to cap_msmf.hpp
Update cap_msmf.cpp
Update CMakeLists.txt
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.cpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Successful test - samples are grabbed
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Create ppltasks_winrt.h
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update ppltasks_winrt.h
Library updated and cleaned up with comments, marshaling, exceptions and linker settings
Update ppltasks_winrt.h
Fixed trailing whitespace
2013-12-14 16:53:30 +08:00
|
|
|
#include "cap_msmf.hpp"
|
|
|
|
|
2013-04-03 09:01:20 +08:00
|
|
|
// Structure for collecting info about types of video, which are supported by current video device
|
|
|
|
struct MediaType
|
|
|
|
{
|
|
|
|
unsigned int MF_MT_FRAME_SIZE;
|
|
|
|
unsigned int height;
|
|
|
|
unsigned int width;
|
|
|
|
unsigned int MF_MT_YUV_MATRIX;
|
|
|
|
unsigned int MF_MT_VIDEO_LIGHTING;
|
2013-05-19 04:04:31 +08:00
|
|
|
int MF_MT_DEFAULT_STRIDE; // stride is negative if image is bottom-up
|
2013-04-03 09:01:20 +08:00
|
|
|
unsigned int MF_MT_VIDEO_CHROMA_SITING;
|
|
|
|
GUID MF_MT_AM_FORMAT_TYPE;
|
|
|
|
wchar_t *pMF_MT_AM_FORMAT_TYPEName;
|
|
|
|
unsigned int MF_MT_FIXED_SIZE_SAMPLES;
|
|
|
|
unsigned int MF_MT_VIDEO_NOMINAL_RANGE;
|
2013-05-23 00:50:54 +08:00
|
|
|
unsigned int MF_MT_FRAME_RATE_NUMERATOR;
|
|
|
|
unsigned int MF_MT_FRAME_RATE_DENOMINATOR;
|
2013-04-03 09:01:20 +08:00
|
|
|
unsigned int MF_MT_PIXEL_ASPECT_RATIO;
|
|
|
|
unsigned int MF_MT_PIXEL_ASPECT_RATIO_low;
|
|
|
|
unsigned int MF_MT_ALL_SAMPLES_INDEPENDENT;
|
|
|
|
unsigned int MF_MT_FRAME_RATE_RANGE_MIN;
|
|
|
|
unsigned int MF_MT_FRAME_RATE_RANGE_MIN_low;
|
|
|
|
unsigned int MF_MT_SAMPLE_SIZE;
|
|
|
|
unsigned int MF_MT_VIDEO_PRIMARIES;
|
|
|
|
unsigned int MF_MT_INTERLACE_MODE;
|
|
|
|
unsigned int MF_MT_FRAME_RATE_RANGE_MAX;
|
|
|
|
unsigned int MF_MT_FRAME_RATE_RANGE_MAX_low;
|
|
|
|
GUID MF_MT_MAJOR_TYPE;
|
|
|
|
GUID MF_MT_SUBTYPE;
|
|
|
|
wchar_t *pMF_MT_MAJOR_TYPEName;
|
|
|
|
wchar_t *pMF_MT_SUBTYPEName;
|
|
|
|
MediaType();
|
|
|
|
~MediaType();
|
|
|
|
void Clear();
|
|
|
|
};
|
2013-04-16 21:25:10 +08:00
|
|
|
|
2013-04-03 09:01:20 +08:00
|
|
|
/// Class for parsing info from IMFMediaType into the local MediaType
|
|
|
|
class FormatReader
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
static MediaType Read(IMFMediaType *pType);
|
|
|
|
~FormatReader(void);
|
|
|
|
private:
|
|
|
|
FormatReader(void);
|
|
|
|
};
|
2013-04-16 21:25:10 +08:00
|
|
|
|
2013-04-03 09:01:20 +08:00
|
|
|
DWORD WINAPI MainThreadFunction( LPVOID lpParam );
|
|
|
|
typedef void(*emergensyStopEventCallback)(int, void *);
|
2013-04-16 21:25:10 +08:00
|
|
|
|
2013-04-03 09:01:20 +08:00
|
|
|
class RawImage
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
~RawImage(void);
|
|
|
|
// Function of creation of the instance of the class
|
|
|
|
static long CreateInstance(RawImage **ppRImage,unsigned int size);
|
|
|
|
void setCopy(const BYTE * pSampleBuffer);
|
|
|
|
void fastCopy(const BYTE * pSampleBuffer);
|
|
|
|
unsigned char * getpPixels();
|
|
|
|
bool isNew();
|
|
|
|
unsigned int getSize();
|
|
|
|
private:
|
|
|
|
bool ri_new;
|
|
|
|
unsigned int ri_size;
|
|
|
|
unsigned char *ri_pixels;
|
|
|
|
RawImage(unsigned int size);
|
|
|
|
};
|
2013-04-16 21:25:10 +08:00
|
|
|
|
Update cap_msmf.cpp
Add support for WinRT in the MF capture framework by removing the disallowed calls to enumerate devices and create a sample grabber sink and adding framework for the MediaCapture interface and a custom sink which interfaces with the sample grabber callback interface. The change requires discussion for making it completely functional as redundancy is required given that if the source is a video file, the old code pathways must be used. Otherwise all IMFMediaSession, IMFMediaSource, and IMFActivate code must use a MediaCapture code path and all sink code must use the CMediaSink custom sink.
Support for the custom sink is extended to non-WinRT not for compatibility as Windows Vista client is a minimum regardless, but because it offers more flexibility, could be faster and is able to be used as an optionally different code path during sink creation based on a future configuration parameter.
My discussion and proposal to finish this change:
Devices are so easily enumerated through WinRT Windows.Devices namespace that wrapping the calls in a library is quite a chore for little benefit though to get the various modes and formats could still be a worthwhile project. For now conditional compilation to remove videodevices and any offending non-video file related activity in videodevice. In my opinion, this is a different , far less fundamental and important change which can possibly be done as a future project and also much more easily implemented in C++/CX.
ImageGrabber has the IMFSampleGrabberSinkCallback replaced with a base class (SharedSampleGrabber) which also be is base class for ImageGrabberRT. This change is necessary as the custom sink does not require a thread to pump events which is done through MediaCapture already. IMFSampleGrabberSinkCallback is the common element between both models and that piece can be shared. Initializing the new ImageGrabberRT is as simple as passing an already initialized MediaCapture object and any video format/encoding parameters.
The concurrency event is necessary to wait for completion and is the way the underlying, IAsyncAction wrappers in the task library work as well. Native WIN32 event objects would be an option if HAVE_CONCURRENCY is not defined. I could even imagine doing it with sleep/thread yield and InterlockedCompareExchange yet I am not enthusiastic about that approach either. Since there is a specific compiler HAVE_ for concurrency, I do not like pulling it in though I think for WinRT it is safe to say we will always have it available though should probably conditionally compile with the Interlocked option as WIN32 events would require HAVE_WIN32.
It looks like C++/CX cannot be used for the IMediaExtension sink (which should not be a problem) as using COM objects requires WRL and though deriving from IMediaExtension can be done, there is little purpose without COM. Objects from C++/CX can be swapped to interact with objects from native C++ as Inspectable* can reinterpret_cast to the ref object IInspectable^ and vice-versa. A solution to the COM class with C++/CX would be great so we could have dual support. Also without #define for every WRL object in use, the code will get quite muddy given that the */^ would need to be ifdef'd everywhere.
Update cap_msmf.cpp
Fixed bugs and completed the change. I believe the new classes need to be moved to a header file as the file has become to large and more classes need to be added for handling all the asynchronous problems (one wrapping IAsyncAction in a task and another for making a task out of IAsyncAction). Unfortunately, blocking on the UI thread is not an option in WinRT so a synchronous architecture is considered "illegal" by Microsoft's standards even if implementable (C++/CX ppltasks library throws errors if you try it). Worse, either by design or a bug in the MF MediaCapture class with Custom Sinks causes a crash if stop/start previewing without reinitializing (spPreferredPreviewMediaType is fatally nulled). After decompiling Windows.Media.dll, I worked around this in my own projects by using an activate-able custom sink ID which strangely assigns 1 to this pointer allowing it to be reinitialized in what can only be described as a hack by Microsoft. This would add additional overhead to the project to implement especially for static libraries as it requires IDL/DLL exporting followed by manifest declaration. Better to document that it is not supported.
Furthermore, an additional class for IMFAttributes should be implemented to make clean architecture for passing around attributes as opposed to directly calling non-COM interface calls on the objects and making use of SetProperties which would also be a set up for an object that uses the RuntimeClass activation ID.
The remaining changes are not difficult and will be complete soon along with debug tracing messages.
Update cap_msmf.cpp
Create cap_msmf.h
Update cap_msmf.cpp
Update cap_msmf.h
Update cap_msmf.cpp
Update cap_msmf.h
Update and rename cap_msmf.h to cap_msmf.hpp
Update cap_msmf.cpp
Update CMakeLists.txt
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.cpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Successful test - samples are grabbed
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Create ppltasks_winrt.h
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update ppltasks_winrt.h
Library updated and cleaned up with comments, marshaling, exceptions and linker settings
Update ppltasks_winrt.h
Fixed trailing whitespace
2013-12-14 16:53:30 +08:00
|
|
|
class ImageGrabberCallback : public IMFSampleGrabberSinkCallback
|
2013-04-03 09:01:20 +08:00
|
|
|
{
|
|
|
|
public:
|
2013-05-14 20:17:34 +08:00
|
|
|
void pauseGrabbing();
|
|
|
|
void resumeGrabbing();
|
2013-04-03 09:01:20 +08:00
|
|
|
RawImage *getRawImage();
|
Update cap_msmf.cpp
Add support for WinRT in the MF capture framework by removing the disallowed calls to enumerate devices and create a sample grabber sink and adding framework for the MediaCapture interface and a custom sink which interfaces with the sample grabber callback interface. The change requires discussion for making it completely functional as redundancy is required given that if the source is a video file, the old code pathways must be used. Otherwise all IMFMediaSession, IMFMediaSource, and IMFActivate code must use a MediaCapture code path and all sink code must use the CMediaSink custom sink.
Support for the custom sink is extended to non-WinRT not for compatibility as Windows Vista client is a minimum regardless, but because it offers more flexibility, could be faster and is able to be used as an optionally different code path during sink creation based on a future configuration parameter.
My discussion and proposal to finish this change:
Devices are so easily enumerated through WinRT Windows.Devices namespace that wrapping the calls in a library is quite a chore for little benefit though to get the various modes and formats could still be a worthwhile project. For now conditional compilation to remove videodevices and any offending non-video file related activity in videodevice. In my opinion, this is a different , far less fundamental and important change which can possibly be done as a future project and also much more easily implemented in C++/CX.
ImageGrabber has the IMFSampleGrabberSinkCallback replaced with a base class (SharedSampleGrabber) which also be is base class for ImageGrabberRT. This change is necessary as the custom sink does not require a thread to pump events which is done through MediaCapture already. IMFSampleGrabberSinkCallback is the common element between both models and that piece can be shared. Initializing the new ImageGrabberRT is as simple as passing an already initialized MediaCapture object and any video format/encoding parameters.
The concurrency event is necessary to wait for completion and is the way the underlying, IAsyncAction wrappers in the task library work as well. Native WIN32 event objects would be an option if HAVE_CONCURRENCY is not defined. I could even imagine doing it with sleep/thread yield and InterlockedCompareExchange yet I am not enthusiastic about that approach either. Since there is a specific compiler HAVE_ for concurrency, I do not like pulling it in though I think for WinRT it is safe to say we will always have it available though should probably conditionally compile with the Interlocked option as WIN32 events would require HAVE_WIN32.
It looks like C++/CX cannot be used for the IMediaExtension sink (which should not be a problem) as using COM objects requires WRL and though deriving from IMediaExtension can be done, there is little purpose without COM. Objects from C++/CX can be swapped to interact with objects from native C++ as Inspectable* can reinterpret_cast to the ref object IInspectable^ and vice-versa. A solution to the COM class with C++/CX would be great so we could have dual support. Also without #define for every WRL object in use, the code will get quite muddy given that the */^ would need to be ifdef'd everywhere.
Update cap_msmf.cpp
Fixed bugs and completed the change. I believe the new classes need to be moved to a header file as the file has become to large and more classes need to be added for handling all the asynchronous problems (one wrapping IAsyncAction in a task and another for making a task out of IAsyncAction). Unfortunately, blocking on the UI thread is not an option in WinRT so a synchronous architecture is considered "illegal" by Microsoft's standards even if implementable (C++/CX ppltasks library throws errors if you try it). Worse, either by design or a bug in the MF MediaCapture class with Custom Sinks causes a crash if stop/start previewing without reinitializing (spPreferredPreviewMediaType is fatally nulled). After decompiling Windows.Media.dll, I worked around this in my own projects by using an activate-able custom sink ID which strangely assigns 1 to this pointer allowing it to be reinitialized in what can only be described as a hack by Microsoft. This would add additional overhead to the project to implement especially for static libraries as it requires IDL/DLL exporting followed by manifest declaration. Better to document that it is not supported.
Furthermore, an additional class for IMFAttributes should be implemented to make clean architecture for passing around attributes as opposed to directly calling non-COM interface calls on the objects and making use of SetProperties which would also be a set up for an object that uses the RuntimeClass activation ID.
The remaining changes are not difficult and will be complete soon along with debug tracing messages.
Update cap_msmf.cpp
Create cap_msmf.h
Update cap_msmf.cpp
Update cap_msmf.h
Update cap_msmf.cpp
Update cap_msmf.h
Update and rename cap_msmf.h to cap_msmf.hpp
Update cap_msmf.cpp
Update CMakeLists.txt
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.cpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Successful test - samples are grabbed
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Create ppltasks_winrt.h
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update ppltasks_winrt.h
Library updated and cleaned up with comments, marshaling, exceptions and linker settings
Update ppltasks_winrt.h
Fixed trailing whitespace
2013-12-14 16:53:30 +08:00
|
|
|
// IMFClockStateSink methods
|
|
|
|
STDMETHODIMP OnClockStart(MFTIME hnsSystemTime, LONGLONG llClockStartOffset);
|
|
|
|
STDMETHODIMP OnClockStop(MFTIME hnsSystemTime);
|
|
|
|
STDMETHODIMP OnClockPause(MFTIME hnsSystemTime);
|
|
|
|
STDMETHODIMP OnClockRestart(MFTIME hnsSystemTime);
|
|
|
|
STDMETHODIMP OnClockSetRate(MFTIME hnsSystemTime, float flRate);
|
|
|
|
// IMFSampleGrabberSinkCallback methods
|
|
|
|
STDMETHODIMP OnSetPresentationClock(IMFPresentationClock* pClock);
|
|
|
|
STDMETHODIMP OnProcessSample(REFGUID guidMajorMediaType, DWORD dwSampleFlags,
|
|
|
|
LONGLONG llSampleTime, LONGLONG llSampleDuration, const BYTE * pSampleBuffer,
|
|
|
|
DWORD dwSampleSize);
|
|
|
|
STDMETHODIMP OnShutdown();
|
2013-05-14 20:17:34 +08:00
|
|
|
|
2013-05-15 20:12:25 +08:00
|
|
|
const HANDLE ig_hFrameReady;
|
|
|
|
const HANDLE ig_hFrameGrabbed;
|
|
|
|
const HANDLE ig_hFinish;
|
Update cap_msmf.cpp
Add support for WinRT in the MF capture framework by removing the disallowed calls to enumerate devices and create a sample grabber sink and adding framework for the MediaCapture interface and a custom sink which interfaces with the sample grabber callback interface. The change requires discussion for making it completely functional as redundancy is required given that if the source is a video file, the old code pathways must be used. Otherwise all IMFMediaSession, IMFMediaSource, and IMFActivate code must use a MediaCapture code path and all sink code must use the CMediaSink custom sink.
Support for the custom sink is extended to non-WinRT not for compatibility as Windows Vista client is a minimum regardless, but because it offers more flexibility, could be faster and is able to be used as an optionally different code path during sink creation based on a future configuration parameter.
My discussion and proposal to finish this change:
Devices are so easily enumerated through WinRT Windows.Devices namespace that wrapping the calls in a library is quite a chore for little benefit though to get the various modes and formats could still be a worthwhile project. For now conditional compilation to remove videodevices and any offending non-video file related activity in videodevice. In my opinion, this is a different , far less fundamental and important change which can possibly be done as a future project and also much more easily implemented in C++/CX.
ImageGrabber has the IMFSampleGrabberSinkCallback replaced with a base class (SharedSampleGrabber) which also be is base class for ImageGrabberRT. This change is necessary as the custom sink does not require a thread to pump events which is done through MediaCapture already. IMFSampleGrabberSinkCallback is the common element between both models and that piece can be shared. Initializing the new ImageGrabberRT is as simple as passing an already initialized MediaCapture object and any video format/encoding parameters.
The concurrency event is necessary to wait for completion and is the way the underlying, IAsyncAction wrappers in the task library work as well. Native WIN32 event objects would be an option if HAVE_CONCURRENCY is not defined. I could even imagine doing it with sleep/thread yield and InterlockedCompareExchange yet I am not enthusiastic about that approach either. Since there is a specific compiler HAVE_ for concurrency, I do not like pulling it in though I think for WinRT it is safe to say we will always have it available though should probably conditionally compile with the Interlocked option as WIN32 events would require HAVE_WIN32.
It looks like C++/CX cannot be used for the IMediaExtension sink (which should not be a problem) as using COM objects requires WRL and though deriving from IMediaExtension can be done, there is little purpose without COM. Objects from C++/CX can be swapped to interact with objects from native C++ as Inspectable* can reinterpret_cast to the ref object IInspectable^ and vice-versa. A solution to the COM class with C++/CX would be great so we could have dual support. Also without #define for every WRL object in use, the code will get quite muddy given that the */^ would need to be ifdef'd everywhere.
Update cap_msmf.cpp
Fixed bugs and completed the change. I believe the new classes need to be moved to a header file as the file has become to large and more classes need to be added for handling all the asynchronous problems (one wrapping IAsyncAction in a task and another for making a task out of IAsyncAction). Unfortunately, blocking on the UI thread is not an option in WinRT so a synchronous architecture is considered "illegal" by Microsoft's standards even if implementable (C++/CX ppltasks library throws errors if you try it). Worse, either by design or a bug in the MF MediaCapture class with Custom Sinks causes a crash if stop/start previewing without reinitializing (spPreferredPreviewMediaType is fatally nulled). After decompiling Windows.Media.dll, I worked around this in my own projects by using an activate-able custom sink ID which strangely assigns 1 to this pointer allowing it to be reinitialized in what can only be described as a hack by Microsoft. This would add additional overhead to the project to implement especially for static libraries as it requires IDL/DLL exporting followed by manifest declaration. Better to document that it is not supported.
Furthermore, an additional class for IMFAttributes should be implemented to make clean architecture for passing around attributes as opposed to directly calling non-COM interface calls on the objects and making use of SetProperties which would also be a set up for an object that uses the RuntimeClass activation ID.
The remaining changes are not difficult and will be complete soon along with debug tracing messages.
Update cap_msmf.cpp
Create cap_msmf.h
Update cap_msmf.cpp
Update cap_msmf.h
Update cap_msmf.cpp
Update cap_msmf.h
Update and rename cap_msmf.h to cap_msmf.hpp
Update cap_msmf.cpp
Update CMakeLists.txt
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.cpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Successful test - samples are grabbed
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Create ppltasks_winrt.h
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update ppltasks_winrt.h
Library updated and cleaned up with comments, marshaling, exceptions and linker settings
Update ppltasks_winrt.h
Fixed trailing whitespace
2013-12-14 16:53:30 +08:00
|
|
|
protected:
|
|
|
|
ImageGrabberCallback(bool synchronous);
|
2013-04-03 09:01:20 +08:00
|
|
|
bool ig_RIE;
|
|
|
|
bool ig_Close;
|
2013-05-15 20:12:25 +08:00
|
|
|
bool ig_Synchronous;
|
2013-04-03 09:01:20 +08:00
|
|
|
long m_cRef;
|
Update cap_msmf.cpp
Add support for WinRT in the MF capture framework by removing the disallowed calls to enumerate devices and create a sample grabber sink and adding framework for the MediaCapture interface and a custom sink which interfaces with the sample grabber callback interface. The change requires discussion for making it completely functional as redundancy is required given that if the source is a video file, the old code pathways must be used. Otherwise all IMFMediaSession, IMFMediaSource, and IMFActivate code must use a MediaCapture code path and all sink code must use the CMediaSink custom sink.
Support for the custom sink is extended to non-WinRT not for compatibility as Windows Vista client is a minimum regardless, but because it offers more flexibility, could be faster and is able to be used as an optionally different code path during sink creation based on a future configuration parameter.
My discussion and proposal to finish this change:
Devices are so easily enumerated through WinRT Windows.Devices namespace that wrapping the calls in a library is quite a chore for little benefit though to get the various modes and formats could still be a worthwhile project. For now conditional compilation to remove videodevices and any offending non-video file related activity in videodevice. In my opinion, this is a different , far less fundamental and important change which can possibly be done as a future project and also much more easily implemented in C++/CX.
ImageGrabber has the IMFSampleGrabberSinkCallback replaced with a base class (SharedSampleGrabber) which also be is base class for ImageGrabberRT. This change is necessary as the custom sink does not require a thread to pump events which is done through MediaCapture already. IMFSampleGrabberSinkCallback is the common element between both models and that piece can be shared. Initializing the new ImageGrabberRT is as simple as passing an already initialized MediaCapture object and any video format/encoding parameters.
The concurrency event is necessary to wait for completion and is the way the underlying, IAsyncAction wrappers in the task library work as well. Native WIN32 event objects would be an option if HAVE_CONCURRENCY is not defined. I could even imagine doing it with sleep/thread yield and InterlockedCompareExchange yet I am not enthusiastic about that approach either. Since there is a specific compiler HAVE_ for concurrency, I do not like pulling it in though I think for WinRT it is safe to say we will always have it available though should probably conditionally compile with the Interlocked option as WIN32 events would require HAVE_WIN32.
It looks like C++/CX cannot be used for the IMediaExtension sink (which should not be a problem) as using COM objects requires WRL and though deriving from IMediaExtension can be done, there is little purpose without COM. Objects from C++/CX can be swapped to interact with objects from native C++ as Inspectable* can reinterpret_cast to the ref object IInspectable^ and vice-versa. A solution to the COM class with C++/CX would be great so we could have dual support. Also without #define for every WRL object in use, the code will get quite muddy given that the */^ would need to be ifdef'd everywhere.
Update cap_msmf.cpp
Fixed bugs and completed the change. I believe the new classes need to be moved to a header file as the file has become to large and more classes need to be added for handling all the asynchronous problems (one wrapping IAsyncAction in a task and another for making a task out of IAsyncAction). Unfortunately, blocking on the UI thread is not an option in WinRT so a synchronous architecture is considered "illegal" by Microsoft's standards even if implementable (C++/CX ppltasks library throws errors if you try it). Worse, either by design or a bug in the MF MediaCapture class with Custom Sinks causes a crash if stop/start previewing without reinitializing (spPreferredPreviewMediaType is fatally nulled). After decompiling Windows.Media.dll, I worked around this in my own projects by using an activate-able custom sink ID which strangely assigns 1 to this pointer allowing it to be reinitialized in what can only be described as a hack by Microsoft. This would add additional overhead to the project to implement especially for static libraries as it requires IDL/DLL exporting followed by manifest declaration. Better to document that it is not supported.
Furthermore, an additional class for IMFAttributes should be implemented to make clean architecture for passing around attributes as opposed to directly calling non-COM interface calls on the objects and making use of SetProperties which would also be a set up for an object that uses the RuntimeClass activation ID.
The remaining changes are not difficult and will be complete soon along with debug tracing messages.
Update cap_msmf.cpp
Create cap_msmf.h
Update cap_msmf.cpp
Update cap_msmf.h
Update cap_msmf.cpp
Update cap_msmf.h
Update and rename cap_msmf.h to cap_msmf.hpp
Update cap_msmf.cpp
Update CMakeLists.txt
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.cpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Successful test - samples are grabbed
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Create ppltasks_winrt.h
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update ppltasks_winrt.h
Library updated and cleaned up with comments, marshaling, exceptions and linker settings
Update ppltasks_winrt.h
Fixed trailing whitespace
2013-12-14 16:53:30 +08:00
|
|
|
|
|
|
|
RawImage *ig_RIFirst;
|
|
|
|
RawImage *ig_RISecond;
|
|
|
|
RawImage *ig_RIOut;
|
|
|
|
};
|
|
|
|
|
|
|
|
#ifdef HAVE_WINRT
|
|
|
|
extern const __declspec(selectany) WCHAR RuntimeClass_CV_ImageGrabberWinRT[] = L"cv.ImageGrabberWinRT";
|
|
|
|
|
|
|
|
class ImageGrabberWinRT :
|
|
|
|
public Microsoft::WRL::RuntimeClass<
|
|
|
|
Microsoft::WRL::RuntimeClassFlags< Microsoft::WRL::RuntimeClassType::WinRtClassicComMix>,
|
|
|
|
IMFSampleGrabberSinkCallback>, public ImageGrabberCallback
|
|
|
|
{
|
|
|
|
InspectableClass(RuntimeClass_CV_ImageGrabberWinRT, BaseTrust)
|
|
|
|
public:
|
|
|
|
ImageGrabberWinRT(bool synchronous);
|
|
|
|
~ImageGrabberWinRT(void);
|
|
|
|
|
|
|
|
HRESULT initImageGrabber(MAKE_WRL_REF(_MediaCapture) pSource,
|
|
|
|
GUID VideoFormat);
|
|
|
|
HRESULT startGrabbing(MAKE_WRL_REF(_AsyncAction)* action);
|
|
|
|
HRESULT stopGrabbing(MAKE_WRL_REF(_AsyncAction)* action);
|
|
|
|
// IMFClockStateSink methods
|
|
|
|
STDMETHODIMP OnClockStart(MFTIME hnsSystemTime, LONGLONG llClockStartOffset) { return ImageGrabberCallback::OnClockStart(hnsSystemTime, llClockStartOffset); }
|
|
|
|
STDMETHODIMP OnClockStop(MFTIME hnsSystemTime) { return ImageGrabberCallback::OnClockStop(hnsSystemTime); }
|
|
|
|
STDMETHODIMP OnClockPause(MFTIME hnsSystemTime) { return ImageGrabberCallback::OnClockPause(hnsSystemTime); }
|
|
|
|
STDMETHODIMP OnClockRestart(MFTIME hnsSystemTime) { return ImageGrabberCallback::OnClockRestart(hnsSystemTime); }
|
|
|
|
STDMETHODIMP OnClockSetRate(MFTIME hnsSystemTime, float flRate) { return ImageGrabberCallback::OnClockSetRate(hnsSystemTime, flRate); }
|
|
|
|
// IMFSampleGrabberSinkCallback methods
|
|
|
|
STDMETHODIMP OnSetPresentationClock(IMFPresentationClock* pClock) { return ImageGrabberCallback::OnSetPresentationClock(pClock); }
|
|
|
|
STDMETHODIMP OnProcessSample(REFGUID guidMajorMediaType, DWORD dwSampleFlags,
|
|
|
|
LONGLONG llSampleTime, LONGLONG llSampleDuration, const BYTE * pSampleBuffer,
|
|
|
|
DWORD dwSampleSize) { return ImageGrabberCallback::OnProcessSample(guidMajorMediaType, dwSampleFlags, llSampleTime, llSampleDuration, pSampleBuffer, dwSampleSize); }
|
|
|
|
STDMETHODIMP OnShutdown() { return ImageGrabberCallback::OnShutdown(); }
|
|
|
|
// Function of creation of the instance of the class
|
|
|
|
static HRESULT CreateInstance(ImageGrabberWinRT **ppIG, bool synchronous = false);
|
|
|
|
private:
|
|
|
|
MAKE_WRL_AGILE_REF(_MediaCapture) ig_pMedCapSource;
|
|
|
|
MediaSink* ig_pMediaSink;
|
|
|
|
};
|
|
|
|
#endif
|
|
|
|
|
|
|
|
// Class for grabbing image from video stream
|
|
|
|
class ImageGrabber : public ImageGrabberCallback
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
~ImageGrabber(void);
|
|
|
|
HRESULT initImageGrabber(IMFMediaSource *pSource, GUID VideoFormat);
|
|
|
|
HRESULT startGrabbing(void);
|
|
|
|
void stopGrabbing();
|
|
|
|
// IUnknown methods
|
|
|
|
STDMETHODIMP QueryInterface(REFIID iid, void** ppv);
|
|
|
|
STDMETHODIMP_(ULONG) AddRef();
|
|
|
|
STDMETHODIMP_(ULONG) Release();
|
|
|
|
// Function of creation of the instance of the class
|
|
|
|
static HRESULT CreateInstance(ImageGrabber **ppIG, unsigned int deviceID, bool synchronous = false);
|
|
|
|
|
|
|
|
private:
|
2013-04-03 09:01:20 +08:00
|
|
|
unsigned int ig_DeviceID;
|
Update cap_msmf.cpp
Add support for WinRT in the MF capture framework by removing the disallowed calls to enumerate devices and create a sample grabber sink and adding framework for the MediaCapture interface and a custom sink which interfaces with the sample grabber callback interface. The change requires discussion for making it completely functional as redundancy is required given that if the source is a video file, the old code pathways must be used. Otherwise all IMFMediaSession, IMFMediaSource, and IMFActivate code must use a MediaCapture code path and all sink code must use the CMediaSink custom sink.
Support for the custom sink is extended to non-WinRT not for compatibility as Windows Vista client is a minimum regardless, but because it offers more flexibility, could be faster and is able to be used as an optionally different code path during sink creation based on a future configuration parameter.
My discussion and proposal to finish this change:
Devices are so easily enumerated through WinRT Windows.Devices namespace that wrapping the calls in a library is quite a chore for little benefit though to get the various modes and formats could still be a worthwhile project. For now conditional compilation to remove videodevices and any offending non-video file related activity in videodevice. In my opinion, this is a different , far less fundamental and important change which can possibly be done as a future project and also much more easily implemented in C++/CX.
ImageGrabber has the IMFSampleGrabberSinkCallback replaced with a base class (SharedSampleGrabber) which also be is base class for ImageGrabberRT. This change is necessary as the custom sink does not require a thread to pump events which is done through MediaCapture already. IMFSampleGrabberSinkCallback is the common element between both models and that piece can be shared. Initializing the new ImageGrabberRT is as simple as passing an already initialized MediaCapture object and any video format/encoding parameters.
The concurrency event is necessary to wait for completion and is the way the underlying, IAsyncAction wrappers in the task library work as well. Native WIN32 event objects would be an option if HAVE_CONCURRENCY is not defined. I could even imagine doing it with sleep/thread yield and InterlockedCompareExchange yet I am not enthusiastic about that approach either. Since there is a specific compiler HAVE_ for concurrency, I do not like pulling it in though I think for WinRT it is safe to say we will always have it available though should probably conditionally compile with the Interlocked option as WIN32 events would require HAVE_WIN32.
It looks like C++/CX cannot be used for the IMediaExtension sink (which should not be a problem) as using COM objects requires WRL and though deriving from IMediaExtension can be done, there is little purpose without COM. Objects from C++/CX can be swapped to interact with objects from native C++ as Inspectable* can reinterpret_cast to the ref object IInspectable^ and vice-versa. A solution to the COM class with C++/CX would be great so we could have dual support. Also without #define for every WRL object in use, the code will get quite muddy given that the */^ would need to be ifdef'd everywhere.
Update cap_msmf.cpp
Fixed bugs and completed the change. I believe the new classes need to be moved to a header file as the file has become to large and more classes need to be added for handling all the asynchronous problems (one wrapping IAsyncAction in a task and another for making a task out of IAsyncAction). Unfortunately, blocking on the UI thread is not an option in WinRT so a synchronous architecture is considered "illegal" by Microsoft's standards even if implementable (C++/CX ppltasks library throws errors if you try it). Worse, either by design or a bug in the MF MediaCapture class with Custom Sinks causes a crash if stop/start previewing without reinitializing (spPreferredPreviewMediaType is fatally nulled). After decompiling Windows.Media.dll, I worked around this in my own projects by using an activate-able custom sink ID which strangely assigns 1 to this pointer allowing it to be reinitialized in what can only be described as a hack by Microsoft. This would add additional overhead to the project to implement especially for static libraries as it requires IDL/DLL exporting followed by manifest declaration. Better to document that it is not supported.
Furthermore, an additional class for IMFAttributes should be implemented to make clean architecture for passing around attributes as opposed to directly calling non-COM interface calls on the objects and making use of SetProperties which would also be a set up for an object that uses the RuntimeClass activation ID.
The remaining changes are not difficult and will be complete soon along with debug tracing messages.
Update cap_msmf.cpp
Create cap_msmf.h
Update cap_msmf.cpp
Update cap_msmf.h
Update cap_msmf.cpp
Update cap_msmf.h
Update and rename cap_msmf.h to cap_msmf.hpp
Update cap_msmf.cpp
Update CMakeLists.txt
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.cpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Successful test - samples are grabbed
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Create ppltasks_winrt.h
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update ppltasks_winrt.h
Library updated and cleaned up with comments, marshaling, exceptions and linker settings
Update ppltasks_winrt.h
Fixed trailing whitespace
2013-12-14 16:53:30 +08:00
|
|
|
|
2013-04-03 09:01:20 +08:00
|
|
|
IMFMediaSource *ig_pSource;
|
|
|
|
IMFMediaSession *ig_pSession;
|
|
|
|
IMFTopology *ig_pTopology;
|
2013-05-15 20:12:25 +08:00
|
|
|
ImageGrabber(unsigned int deviceID, bool synchronous);
|
2013-04-03 09:01:20 +08:00
|
|
|
HRESULT CreateTopology(IMFMediaSource *pSource, IMFActivate *pSinkActivate, IMFTopology **ppTopo);
|
2013-06-24 16:10:18 +08:00
|
|
|
HRESULT AddSourceNode(IMFTopology *pTopology, IMFMediaSource *pSource,
|
|
|
|
IMFPresentationDescriptor *pPD, IMFStreamDescriptor *pSD, IMFTopologyNode **ppNode);
|
2013-05-14 20:17:34 +08:00
|
|
|
HRESULT AddOutputNode(IMFTopology *pTopology, IMFActivate *pActivate, DWORD dwId, IMFTopologyNode **ppNode);
|
2013-04-03 09:01:20 +08:00
|
|
|
};
|
2013-05-19 04:04:31 +08:00
|
|
|
|
2013-04-03 09:01:20 +08:00
|
|
|
/// Class for controlling of thread of the grabbing raw data from video device
|
|
|
|
class ImageGrabberThread
|
|
|
|
{
|
|
|
|
friend DWORD WINAPI MainThreadFunction( LPVOID lpParam );
|
|
|
|
public:
|
|
|
|
~ImageGrabberThread(void);
|
2013-05-15 20:12:25 +08:00
|
|
|
static HRESULT CreateInstance(ImageGrabberThread **ppIGT, IMFMediaSource *pSource, unsigned int deviceID, bool synchronious = false);
|
2013-04-03 09:01:20 +08:00
|
|
|
void start();
|
|
|
|
void stop();
|
|
|
|
void setEmergencyStopEvent(void *userData, void(*func)(int, void *));
|
|
|
|
ImageGrabber *getImageGrabber();
|
|
|
|
protected:
|
|
|
|
virtual void run();
|
|
|
|
private:
|
2013-05-15 20:12:25 +08:00
|
|
|
ImageGrabberThread(IMFMediaSource *pSource, unsigned int deviceID, bool synchronious);
|
2013-04-03 09:01:20 +08:00
|
|
|
HANDLE igt_Handle;
|
|
|
|
DWORD igt_ThreadIdArray;
|
|
|
|
ImageGrabber *igt_pImageGrabber;
|
|
|
|
emergensyStopEventCallback igt_func;
|
|
|
|
void *igt_userData;
|
|
|
|
bool igt_stop;
|
|
|
|
unsigned int igt_DeviceID;
|
|
|
|
};
|
2013-05-19 04:04:31 +08:00
|
|
|
|
2013-04-03 09:01:20 +08:00
|
|
|
// Structure for collecting info about one parametr of current video device
|
|
|
|
struct Parametr
|
|
|
|
{
|
|
|
|
long CurrentValue;
|
|
|
|
long Min;
|
|
|
|
long Max;
|
|
|
|
long Step;
|
|
|
|
long Default;
|
|
|
|
long Flag;
|
|
|
|
Parametr();
|
|
|
|
};
|
2013-05-19 04:04:31 +08:00
|
|
|
|
2013-04-03 09:01:20 +08:00
|
|
|
// Structure for collecting info about 17 parametrs of current video device
|
|
|
|
struct CamParametrs
|
|
|
|
{
|
|
|
|
Parametr Brightness;
|
|
|
|
Parametr Contrast;
|
|
|
|
Parametr Hue;
|
|
|
|
Parametr Saturation;
|
|
|
|
Parametr Sharpness;
|
|
|
|
Parametr Gamma;
|
|
|
|
Parametr ColorEnable;
|
|
|
|
Parametr WhiteBalance;
|
|
|
|
Parametr BacklightCompensation;
|
|
|
|
Parametr Gain;
|
|
|
|
Parametr Pan;
|
|
|
|
Parametr Tilt;
|
|
|
|
Parametr Roll;
|
|
|
|
Parametr Zoom;
|
|
|
|
Parametr Exposure;
|
|
|
|
Parametr Iris;
|
|
|
|
Parametr Focus;
|
|
|
|
};
|
2013-05-19 04:04:31 +08:00
|
|
|
|
2013-04-03 09:01:20 +08:00
|
|
|
typedef std::wstring String;
|
|
|
|
typedef std::vector<int> vectorNum;
|
|
|
|
typedef std::map<String, vectorNum> SUBTYPEMap;
|
|
|
|
typedef std::map<UINT64, SUBTYPEMap> FrameRateMap;
|
|
|
|
typedef void(*emergensyStopEventCallback)(int, void *);
|
2013-05-19 04:04:31 +08:00
|
|
|
|
2013-04-03 09:01:20 +08:00
|
|
|
/// Class for controlling of video device
|
|
|
|
class videoDevice
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
videoDevice(void);
|
|
|
|
~videoDevice(void);
|
|
|
|
void closeDevice();
|
|
|
|
CamParametrs getParametrs();
|
|
|
|
void setParametrs(CamParametrs parametrs);
|
|
|
|
void setEmergencyStopEvent(void *userData, void(*func)(int, void *));
|
Update cap_msmf.cpp
Add support for WinRT in the MF capture framework by removing the disallowed calls to enumerate devices and create a sample grabber sink and adding framework for the MediaCapture interface and a custom sink which interfaces with the sample grabber callback interface. The change requires discussion for making it completely functional as redundancy is required given that if the source is a video file, the old code pathways must be used. Otherwise all IMFMediaSession, IMFMediaSource, and IMFActivate code must use a MediaCapture code path and all sink code must use the CMediaSink custom sink.
Support for the custom sink is extended to non-WinRT not for compatibility as Windows Vista client is a minimum regardless, but because it offers more flexibility, could be faster and is able to be used as an optionally different code path during sink creation based on a future configuration parameter.
My discussion and proposal to finish this change:
Devices are so easily enumerated through WinRT Windows.Devices namespace that wrapping the calls in a library is quite a chore for little benefit though to get the various modes and formats could still be a worthwhile project. For now conditional compilation to remove videodevices and any offending non-video file related activity in videodevice. In my opinion, this is a different , far less fundamental and important change which can possibly be done as a future project and also much more easily implemented in C++/CX.
ImageGrabber has the IMFSampleGrabberSinkCallback replaced with a base class (SharedSampleGrabber) which also be is base class for ImageGrabberRT. This change is necessary as the custom sink does not require a thread to pump events which is done through MediaCapture already. IMFSampleGrabberSinkCallback is the common element between both models and that piece can be shared. Initializing the new ImageGrabberRT is as simple as passing an already initialized MediaCapture object and any video format/encoding parameters.
The concurrency event is necessary to wait for completion and is the way the underlying, IAsyncAction wrappers in the task library work as well. Native WIN32 event objects would be an option if HAVE_CONCURRENCY is not defined. I could even imagine doing it with sleep/thread yield and InterlockedCompareExchange yet I am not enthusiastic about that approach either. Since there is a specific compiler HAVE_ for concurrency, I do not like pulling it in though I think for WinRT it is safe to say we will always have it available though should probably conditionally compile with the Interlocked option as WIN32 events would require HAVE_WIN32.
It looks like C++/CX cannot be used for the IMediaExtension sink (which should not be a problem) as using COM objects requires WRL and though deriving from IMediaExtension can be done, there is little purpose without COM. Objects from C++/CX can be swapped to interact with objects from native C++ as Inspectable* can reinterpret_cast to the ref object IInspectable^ and vice-versa. A solution to the COM class with C++/CX would be great so we could have dual support. Also without #define for every WRL object in use, the code will get quite muddy given that the */^ would need to be ifdef'd everywhere.
Update cap_msmf.cpp
Fixed bugs and completed the change. I believe the new classes need to be moved to a header file as the file has become to large and more classes need to be added for handling all the asynchronous problems (one wrapping IAsyncAction in a task and another for making a task out of IAsyncAction). Unfortunately, blocking on the UI thread is not an option in WinRT so a synchronous architecture is considered "illegal" by Microsoft's standards even if implementable (C++/CX ppltasks library throws errors if you try it). Worse, either by design or a bug in the MF MediaCapture class with Custom Sinks causes a crash if stop/start previewing without reinitializing (spPreferredPreviewMediaType is fatally nulled). After decompiling Windows.Media.dll, I worked around this in my own projects by using an activate-able custom sink ID which strangely assigns 1 to this pointer allowing it to be reinitialized in what can only be described as a hack by Microsoft. This would add additional overhead to the project to implement especially for static libraries as it requires IDL/DLL exporting followed by manifest declaration. Better to document that it is not supported.
Furthermore, an additional class for IMFAttributes should be implemented to make clean architecture for passing around attributes as opposed to directly calling non-COM interface calls on the objects and making use of SetProperties which would also be a set up for an object that uses the RuntimeClass activation ID.
The remaining changes are not difficult and will be complete soon along with debug tracing messages.
Update cap_msmf.cpp
Create cap_msmf.h
Update cap_msmf.cpp
Update cap_msmf.h
Update cap_msmf.cpp
Update cap_msmf.h
Update and rename cap_msmf.h to cap_msmf.hpp
Update cap_msmf.cpp
Update CMakeLists.txt
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.cpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Successful test - samples are grabbed
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Create ppltasks_winrt.h
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update ppltasks_winrt.h
Library updated and cleaned up with comments, marshaling, exceptions and linker settings
Update ppltasks_winrt.h
Fixed trailing whitespace
2013-12-14 16:53:30 +08:00
|
|
|
#ifdef HAVE_WINRT
|
|
|
|
long readInfoOfDevice(MAKE_WRL_REF(_IDeviceInformation) pDevice, unsigned int Num);
|
|
|
|
void waitForDevice()
|
|
|
|
{
|
|
|
|
if (vd_pAction) {
|
|
|
|
HRESULT hr;
|
|
|
|
DO_ACTION_SYNCHRONOUSLY(hr, vd_pAction, GET_CURRENT_CONTEXT);
|
|
|
|
vd_pAction = nullptr;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#else
|
2013-04-03 09:01:20 +08:00
|
|
|
long readInfoOfDevice(IMFActivate *pActivate, unsigned int Num);
|
Update cap_msmf.cpp
Add support for WinRT in the MF capture framework by removing the disallowed calls to enumerate devices and create a sample grabber sink and adding framework for the MediaCapture interface and a custom sink which interfaces with the sample grabber callback interface. The change requires discussion for making it completely functional as redundancy is required given that if the source is a video file, the old code pathways must be used. Otherwise all IMFMediaSession, IMFMediaSource, and IMFActivate code must use a MediaCapture code path and all sink code must use the CMediaSink custom sink.
Support for the custom sink is extended to non-WinRT not for compatibility as Windows Vista client is a minimum regardless, but because it offers more flexibility, could be faster and is able to be used as an optionally different code path during sink creation based on a future configuration parameter.
My discussion and proposal to finish this change:
Devices are so easily enumerated through WinRT Windows.Devices namespace that wrapping the calls in a library is quite a chore for little benefit though to get the various modes and formats could still be a worthwhile project. For now conditional compilation to remove videodevices and any offending non-video file related activity in videodevice. In my opinion, this is a different , far less fundamental and important change which can possibly be done as a future project and also much more easily implemented in C++/CX.
ImageGrabber has the IMFSampleGrabberSinkCallback replaced with a base class (SharedSampleGrabber) which also be is base class for ImageGrabberRT. This change is necessary as the custom sink does not require a thread to pump events which is done through MediaCapture already. IMFSampleGrabberSinkCallback is the common element between both models and that piece can be shared. Initializing the new ImageGrabberRT is as simple as passing an already initialized MediaCapture object and any video format/encoding parameters.
The concurrency event is necessary to wait for completion and is the way the underlying, IAsyncAction wrappers in the task library work as well. Native WIN32 event objects would be an option if HAVE_CONCURRENCY is not defined. I could even imagine doing it with sleep/thread yield and InterlockedCompareExchange yet I am not enthusiastic about that approach either. Since there is a specific compiler HAVE_ for concurrency, I do not like pulling it in though I think for WinRT it is safe to say we will always have it available though should probably conditionally compile with the Interlocked option as WIN32 events would require HAVE_WIN32.
It looks like C++/CX cannot be used for the IMediaExtension sink (which should not be a problem) as using COM objects requires WRL and though deriving from IMediaExtension can be done, there is little purpose without COM. Objects from C++/CX can be swapped to interact with objects from native C++ as Inspectable* can reinterpret_cast to the ref object IInspectable^ and vice-versa. A solution to the COM class with C++/CX would be great so we could have dual support. Also without #define for every WRL object in use, the code will get quite muddy given that the */^ would need to be ifdef'd everywhere.
Update cap_msmf.cpp
Fixed bugs and completed the change. I believe the new classes need to be moved to a header file as the file has become to large and more classes need to be added for handling all the asynchronous problems (one wrapping IAsyncAction in a task and another for making a task out of IAsyncAction). Unfortunately, blocking on the UI thread is not an option in WinRT so a synchronous architecture is considered "illegal" by Microsoft's standards even if implementable (C++/CX ppltasks library throws errors if you try it). Worse, either by design or a bug in the MF MediaCapture class with Custom Sinks causes a crash if stop/start previewing without reinitializing (spPreferredPreviewMediaType is fatally nulled). After decompiling Windows.Media.dll, I worked around this in my own projects by using an activate-able custom sink ID which strangely assigns 1 to this pointer allowing it to be reinitialized in what can only be described as a hack by Microsoft. This would add additional overhead to the project to implement especially for static libraries as it requires IDL/DLL exporting followed by manifest declaration. Better to document that it is not supported.
Furthermore, an additional class for IMFAttributes should be implemented to make clean architecture for passing around attributes as opposed to directly calling non-COM interface calls on the objects and making use of SetProperties which would also be a set up for an object that uses the RuntimeClass activation ID.
The remaining changes are not difficult and will be complete soon along with debug tracing messages.
Update cap_msmf.cpp
Create cap_msmf.h
Update cap_msmf.cpp
Update cap_msmf.h
Update cap_msmf.cpp
Update cap_msmf.h
Update and rename cap_msmf.h to cap_msmf.hpp
Update cap_msmf.cpp
Update CMakeLists.txt
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.cpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Successful test - samples are grabbed
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Create ppltasks_winrt.h
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update ppltasks_winrt.h
Library updated and cleaned up with comments, marshaling, exceptions and linker settings
Update ppltasks_winrt.h
Fixed trailing whitespace
2013-12-14 16:53:30 +08:00
|
|
|
#endif
|
2013-04-03 09:01:20 +08:00
|
|
|
wchar_t *getName();
|
|
|
|
int getCountFormats();
|
|
|
|
unsigned int getWidth();
|
|
|
|
unsigned int getHeight();
|
|
|
|
MediaType getFormat(unsigned int id);
|
|
|
|
bool setupDevice(unsigned int w, unsigned int h, unsigned int idealFramerate = 0);
|
|
|
|
bool setupDevice(unsigned int id);
|
|
|
|
bool isDeviceSetup();
|
|
|
|
bool isDeviceMediaSource();
|
|
|
|
bool isDeviceRawDataSource();
|
|
|
|
bool isFrameNew();
|
|
|
|
IMFMediaSource *getMediaSource();
|
|
|
|
RawImage *getRawImageOut();
|
|
|
|
private:
|
|
|
|
enum typeLock
|
|
|
|
{
|
|
|
|
MediaSourceLock,
|
|
|
|
RawDataLock,
|
|
|
|
OpenLock
|
|
|
|
} vd_LockOut;
|
|
|
|
wchar_t *vd_pFriendlyName;
|
|
|
|
ImageGrabberThread *vd_pImGrTh;
|
|
|
|
CamParametrs vd_PrevParametrs;
|
|
|
|
unsigned int vd_Width;
|
|
|
|
unsigned int vd_Height;
|
|
|
|
unsigned int vd_CurrentNumber;
|
|
|
|
bool vd_IsSetuped;
|
|
|
|
std::map<UINT64, FrameRateMap> vd_CaptureFormats;
|
|
|
|
std::vector<MediaType> vd_CurrentFormats;
|
|
|
|
IMFMediaSource *vd_pSource;
|
Update cap_msmf.cpp
Add support for WinRT in the MF capture framework by removing the disallowed calls to enumerate devices and create a sample grabber sink and adding framework for the MediaCapture interface and a custom sink which interfaces with the sample grabber callback interface. The change requires discussion for making it completely functional as redundancy is required given that if the source is a video file, the old code pathways must be used. Otherwise all IMFMediaSession, IMFMediaSource, and IMFActivate code must use a MediaCapture code path and all sink code must use the CMediaSink custom sink.
Support for the custom sink is extended to non-WinRT not for compatibility as Windows Vista client is a minimum regardless, but because it offers more flexibility, could be faster and is able to be used as an optionally different code path during sink creation based on a future configuration parameter.
My discussion and proposal to finish this change:
Devices are so easily enumerated through WinRT Windows.Devices namespace that wrapping the calls in a library is quite a chore for little benefit though to get the various modes and formats could still be a worthwhile project. For now conditional compilation to remove videodevices and any offending non-video file related activity in videodevice. In my opinion, this is a different , far less fundamental and important change which can possibly be done as a future project and also much more easily implemented in C++/CX.
ImageGrabber has the IMFSampleGrabberSinkCallback replaced with a base class (SharedSampleGrabber) which also be is base class for ImageGrabberRT. This change is necessary as the custom sink does not require a thread to pump events which is done through MediaCapture already. IMFSampleGrabberSinkCallback is the common element between both models and that piece can be shared. Initializing the new ImageGrabberRT is as simple as passing an already initialized MediaCapture object and any video format/encoding parameters.
The concurrency event is necessary to wait for completion and is the way the underlying, IAsyncAction wrappers in the task library work as well. Native WIN32 event objects would be an option if HAVE_CONCURRENCY is not defined. I could even imagine doing it with sleep/thread yield and InterlockedCompareExchange yet I am not enthusiastic about that approach either. Since there is a specific compiler HAVE_ for concurrency, I do not like pulling it in though I think for WinRT it is safe to say we will always have it available though should probably conditionally compile with the Interlocked option as WIN32 events would require HAVE_WIN32.
It looks like C++/CX cannot be used for the IMediaExtension sink (which should not be a problem) as using COM objects requires WRL and though deriving from IMediaExtension can be done, there is little purpose without COM. Objects from C++/CX can be swapped to interact with objects from native C++ as Inspectable* can reinterpret_cast to the ref object IInspectable^ and vice-versa. A solution to the COM class with C++/CX would be great so we could have dual support. Also without #define for every WRL object in use, the code will get quite muddy given that the */^ would need to be ifdef'd everywhere.
Update cap_msmf.cpp
Fixed bugs and completed the change. I believe the new classes need to be moved to a header file as the file has become to large and more classes need to be added for handling all the asynchronous problems (one wrapping IAsyncAction in a task and another for making a task out of IAsyncAction). Unfortunately, blocking on the UI thread is not an option in WinRT so a synchronous architecture is considered "illegal" by Microsoft's standards even if implementable (C++/CX ppltasks library throws errors if you try it). Worse, either by design or a bug in the MF MediaCapture class with Custom Sinks causes a crash if stop/start previewing without reinitializing (spPreferredPreviewMediaType is fatally nulled). After decompiling Windows.Media.dll, I worked around this in my own projects by using an activate-able custom sink ID which strangely assigns 1 to this pointer allowing it to be reinitialized in what can only be described as a hack by Microsoft. This would add additional overhead to the project to implement especially for static libraries as it requires IDL/DLL exporting followed by manifest declaration. Better to document that it is not supported.
Furthermore, an additional class for IMFAttributes should be implemented to make clean architecture for passing around attributes as opposed to directly calling non-COM interface calls on the objects and making use of SetProperties which would also be a set up for an object that uses the RuntimeClass activation ID.
The remaining changes are not difficult and will be complete soon along with debug tracing messages.
Update cap_msmf.cpp
Create cap_msmf.h
Update cap_msmf.cpp
Update cap_msmf.h
Update cap_msmf.cpp
Update cap_msmf.h
Update and rename cap_msmf.h to cap_msmf.hpp
Update cap_msmf.cpp
Update CMakeLists.txt
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.cpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Successful test - samples are grabbed
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Create ppltasks_winrt.h
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update ppltasks_winrt.h
Library updated and cleaned up with comments, marshaling, exceptions and linker settings
Update ppltasks_winrt.h
Fixed trailing whitespace
2013-12-14 16:53:30 +08:00
|
|
|
#ifdef HAVE_WINRT
|
|
|
|
MAKE_WRL_AGILE_REF(_MediaCapture) vd_pMedCap;
|
|
|
|
IMedCapFailHandler* vd_pMedCapFail;
|
|
|
|
ImageGrabberWinRT *vd_pImGr;
|
|
|
|
MAKE_WRL_REF(_AsyncAction) vd_pAction;
|
|
|
|
Concurrency::critical_section vd_lock;
|
|
|
|
#endif
|
2013-04-03 09:01:20 +08:00
|
|
|
emergensyStopEventCallback vd_func;
|
|
|
|
void *vd_userData;
|
2013-05-19 04:04:31 +08:00
|
|
|
HRESULT enumerateCaptureFormats(IMFMediaSource *pSource);
|
2013-04-03 09:01:20 +08:00
|
|
|
long setDeviceFormat(IMFMediaSource *pSource, unsigned long dwFormatIndex);
|
|
|
|
void buildLibraryofTypes();
|
|
|
|
int findType(unsigned int size, unsigned int frameRate = 0);
|
Update cap_msmf.cpp
Add support for WinRT in the MF capture framework by removing the disallowed calls to enumerate devices and create a sample grabber sink and adding framework for the MediaCapture interface and a custom sink which interfaces with the sample grabber callback interface. The change requires discussion for making it completely functional as redundancy is required given that if the source is a video file, the old code pathways must be used. Otherwise all IMFMediaSession, IMFMediaSource, and IMFActivate code must use a MediaCapture code path and all sink code must use the CMediaSink custom sink.
Support for the custom sink is extended to non-WinRT not for compatibility as Windows Vista client is a minimum regardless, but because it offers more flexibility, could be faster and is able to be used as an optionally different code path during sink creation based on a future configuration parameter.
My discussion and proposal to finish this change:
Devices are so easily enumerated through WinRT Windows.Devices namespace that wrapping the calls in a library is quite a chore for little benefit though to get the various modes and formats could still be a worthwhile project. For now conditional compilation to remove videodevices and any offending non-video file related activity in videodevice. In my opinion, this is a different , far less fundamental and important change which can possibly be done as a future project and also much more easily implemented in C++/CX.
ImageGrabber has the IMFSampleGrabberSinkCallback replaced with a base class (SharedSampleGrabber) which also be is base class for ImageGrabberRT. This change is necessary as the custom sink does not require a thread to pump events which is done through MediaCapture already. IMFSampleGrabberSinkCallback is the common element between both models and that piece can be shared. Initializing the new ImageGrabberRT is as simple as passing an already initialized MediaCapture object and any video format/encoding parameters.
The concurrency event is necessary to wait for completion and is the way the underlying, IAsyncAction wrappers in the task library work as well. Native WIN32 event objects would be an option if HAVE_CONCURRENCY is not defined. I could even imagine doing it with sleep/thread yield and InterlockedCompareExchange yet I am not enthusiastic about that approach either. Since there is a specific compiler HAVE_ for concurrency, I do not like pulling it in though I think for WinRT it is safe to say we will always have it available though should probably conditionally compile with the Interlocked option as WIN32 events would require HAVE_WIN32.
It looks like C++/CX cannot be used for the IMediaExtension sink (which should not be a problem) as using COM objects requires WRL and though deriving from IMediaExtension can be done, there is little purpose without COM. Objects from C++/CX can be swapped to interact with objects from native C++ as Inspectable* can reinterpret_cast to the ref object IInspectable^ and vice-versa. A solution to the COM class with C++/CX would be great so we could have dual support. Also without #define for every WRL object in use, the code will get quite muddy given that the */^ would need to be ifdef'd everywhere.
Update cap_msmf.cpp
Fixed bugs and completed the change. I believe the new classes need to be moved to a header file as the file has become to large and more classes need to be added for handling all the asynchronous problems (one wrapping IAsyncAction in a task and another for making a task out of IAsyncAction). Unfortunately, blocking on the UI thread is not an option in WinRT so a synchronous architecture is considered "illegal" by Microsoft's standards even if implementable (C++/CX ppltasks library throws errors if you try it). Worse, either by design or a bug in the MF MediaCapture class with Custom Sinks causes a crash if stop/start previewing without reinitializing (spPreferredPreviewMediaType is fatally nulled). After decompiling Windows.Media.dll, I worked around this in my own projects by using an activate-able custom sink ID which strangely assigns 1 to this pointer allowing it to be reinitialized in what can only be described as a hack by Microsoft. This would add additional overhead to the project to implement especially for static libraries as it requires IDL/DLL exporting followed by manifest declaration. Better to document that it is not supported.
Furthermore, an additional class for IMFAttributes should be implemented to make clean architecture for passing around attributes as opposed to directly calling non-COM interface calls on the objects and making use of SetProperties which would also be a set up for an object that uses the RuntimeClass activation ID.
The remaining changes are not difficult and will be complete soon along with debug tracing messages.
Update cap_msmf.cpp
Create cap_msmf.h
Update cap_msmf.cpp
Update cap_msmf.h
Update cap_msmf.cpp
Update cap_msmf.h
Update and rename cap_msmf.h to cap_msmf.hpp
Update cap_msmf.cpp
Update CMakeLists.txt
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.cpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Successful test - samples are grabbed
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Create ppltasks_winrt.h
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update ppltasks_winrt.h
Library updated and cleaned up with comments, marshaling, exceptions and linker settings
Update ppltasks_winrt.h
Fixed trailing whitespace
2013-12-14 16:53:30 +08:00
|
|
|
#ifdef HAVE_WINRT
|
|
|
|
HRESULT enumerateCaptureFormats(MAKE_WRL_REF(_MediaCapture) pSource);
|
|
|
|
long setDeviceFormat(MAKE_WRL_REF(_MediaCapture) pSource, unsigned long dwFormatIndex, MAKE_WRL_REF(_AsyncAction)* pAction);
|
|
|
|
long resetDevice(MAKE_WRL_REF(_IDeviceInformation) pDevice);
|
|
|
|
long checkDevice(_DeviceClass devClass, DEFINE_TASK<HRESULT>* pTask, MAKE_WRL_REF(_IDeviceInformation)* ppDevice);
|
|
|
|
#else
|
2013-04-03 09:01:20 +08:00
|
|
|
long resetDevice(IMFActivate *pActivate);
|
|
|
|
long checkDevice(IMFAttributes *pAttributes, IMFActivate **pDevice);
|
Update cap_msmf.cpp
Add support for WinRT in the MF capture framework by removing the disallowed calls to enumerate devices and create a sample grabber sink and adding framework for the MediaCapture interface and a custom sink which interfaces with the sample grabber callback interface. The change requires discussion for making it completely functional as redundancy is required given that if the source is a video file, the old code pathways must be used. Otherwise all IMFMediaSession, IMFMediaSource, and IMFActivate code must use a MediaCapture code path and all sink code must use the CMediaSink custom sink.
Support for the custom sink is extended to non-WinRT not for compatibility as Windows Vista client is a minimum regardless, but because it offers more flexibility, could be faster and is able to be used as an optionally different code path during sink creation based on a future configuration parameter.
My discussion and proposal to finish this change:
Devices are so easily enumerated through WinRT Windows.Devices namespace that wrapping the calls in a library is quite a chore for little benefit though to get the various modes and formats could still be a worthwhile project. For now conditional compilation to remove videodevices and any offending non-video file related activity in videodevice. In my opinion, this is a different , far less fundamental and important change which can possibly be done as a future project and also much more easily implemented in C++/CX.
ImageGrabber has the IMFSampleGrabberSinkCallback replaced with a base class (SharedSampleGrabber) which also be is base class for ImageGrabberRT. This change is necessary as the custom sink does not require a thread to pump events which is done through MediaCapture already. IMFSampleGrabberSinkCallback is the common element between both models and that piece can be shared. Initializing the new ImageGrabberRT is as simple as passing an already initialized MediaCapture object and any video format/encoding parameters.
The concurrency event is necessary to wait for completion and is the way the underlying, IAsyncAction wrappers in the task library work as well. Native WIN32 event objects would be an option if HAVE_CONCURRENCY is not defined. I could even imagine doing it with sleep/thread yield and InterlockedCompareExchange yet I am not enthusiastic about that approach either. Since there is a specific compiler HAVE_ for concurrency, I do not like pulling it in though I think for WinRT it is safe to say we will always have it available though should probably conditionally compile with the Interlocked option as WIN32 events would require HAVE_WIN32.
It looks like C++/CX cannot be used for the IMediaExtension sink (which should not be a problem) as using COM objects requires WRL and though deriving from IMediaExtension can be done, there is little purpose without COM. Objects from C++/CX can be swapped to interact with objects from native C++ as Inspectable* can reinterpret_cast to the ref object IInspectable^ and vice-versa. A solution to the COM class with C++/CX would be great so we could have dual support. Also without #define for every WRL object in use, the code will get quite muddy given that the */^ would need to be ifdef'd everywhere.
Update cap_msmf.cpp
Fixed bugs and completed the change. I believe the new classes need to be moved to a header file as the file has become to large and more classes need to be added for handling all the asynchronous problems (one wrapping IAsyncAction in a task and another for making a task out of IAsyncAction). Unfortunately, blocking on the UI thread is not an option in WinRT so a synchronous architecture is considered "illegal" by Microsoft's standards even if implementable (C++/CX ppltasks library throws errors if you try it). Worse, either by design or a bug in the MF MediaCapture class with Custom Sinks causes a crash if stop/start previewing without reinitializing (spPreferredPreviewMediaType is fatally nulled). After decompiling Windows.Media.dll, I worked around this in my own projects by using an activate-able custom sink ID which strangely assigns 1 to this pointer allowing it to be reinitialized in what can only be described as a hack by Microsoft. This would add additional overhead to the project to implement especially for static libraries as it requires IDL/DLL exporting followed by manifest declaration. Better to document that it is not supported.
Furthermore, an additional class for IMFAttributes should be implemented to make clean architecture for passing around attributes as opposed to directly calling non-COM interface calls on the objects and making use of SetProperties which would also be a set up for an object that uses the RuntimeClass activation ID.
The remaining changes are not difficult and will be complete soon along with debug tracing messages.
Update cap_msmf.cpp
Create cap_msmf.h
Update cap_msmf.cpp
Update cap_msmf.h
Update cap_msmf.cpp
Update cap_msmf.h
Update and rename cap_msmf.h to cap_msmf.hpp
Update cap_msmf.cpp
Update CMakeLists.txt
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.cpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Successful test - samples are grabbed
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Create ppltasks_winrt.h
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update ppltasks_winrt.h
Library updated and cleaned up with comments, marshaling, exceptions and linker settings
Update ppltasks_winrt.h
Fixed trailing whitespace
2013-12-14 16:53:30 +08:00
|
|
|
#endif
|
|
|
|
long initDevice();
|
2013-04-03 09:01:20 +08:00
|
|
|
};
|
2013-05-19 04:04:31 +08:00
|
|
|
|
2013-04-03 09:01:20 +08:00
|
|
|
/// Class for managing of list of video devices
|
|
|
|
class videoDevices
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
~videoDevices(void);
|
Update cap_msmf.cpp
Add support for WinRT in the MF capture framework by removing the disallowed calls to enumerate devices and create a sample grabber sink and adding framework for the MediaCapture interface and a custom sink which interfaces with the sample grabber callback interface. The change requires discussion for making it completely functional as redundancy is required given that if the source is a video file, the old code pathways must be used. Otherwise all IMFMediaSession, IMFMediaSource, and IMFActivate code must use a MediaCapture code path and all sink code must use the CMediaSink custom sink.
Support for the custom sink is extended to non-WinRT not for compatibility as Windows Vista client is a minimum regardless, but because it offers more flexibility, could be faster and is able to be used as an optionally different code path during sink creation based on a future configuration parameter.
My discussion and proposal to finish this change:
Devices are so easily enumerated through WinRT Windows.Devices namespace that wrapping the calls in a library is quite a chore for little benefit though to get the various modes and formats could still be a worthwhile project. For now conditional compilation to remove videodevices and any offending non-video file related activity in videodevice. In my opinion, this is a different , far less fundamental and important change which can possibly be done as a future project and also much more easily implemented in C++/CX.
ImageGrabber has the IMFSampleGrabberSinkCallback replaced with a base class (SharedSampleGrabber) which also be is base class for ImageGrabberRT. This change is necessary as the custom sink does not require a thread to pump events which is done through MediaCapture already. IMFSampleGrabberSinkCallback is the common element between both models and that piece can be shared. Initializing the new ImageGrabberRT is as simple as passing an already initialized MediaCapture object and any video format/encoding parameters.
The concurrency event is necessary to wait for completion and is the way the underlying, IAsyncAction wrappers in the task library work as well. Native WIN32 event objects would be an option if HAVE_CONCURRENCY is not defined. I could even imagine doing it with sleep/thread yield and InterlockedCompareExchange yet I am not enthusiastic about that approach either. Since there is a specific compiler HAVE_ for concurrency, I do not like pulling it in though I think for WinRT it is safe to say we will always have it available though should probably conditionally compile with the Interlocked option as WIN32 events would require HAVE_WIN32.
It looks like C++/CX cannot be used for the IMediaExtension sink (which should not be a problem) as using COM objects requires WRL and though deriving from IMediaExtension can be done, there is little purpose without COM. Objects from C++/CX can be swapped to interact with objects from native C++ as Inspectable* can reinterpret_cast to the ref object IInspectable^ and vice-versa. A solution to the COM class with C++/CX would be great so we could have dual support. Also without #define for every WRL object in use, the code will get quite muddy given that the */^ would need to be ifdef'd everywhere.
Update cap_msmf.cpp
Fixed bugs and completed the change. I believe the new classes need to be moved to a header file as the file has become to large and more classes need to be added for handling all the asynchronous problems (one wrapping IAsyncAction in a task and another for making a task out of IAsyncAction). Unfortunately, blocking on the UI thread is not an option in WinRT so a synchronous architecture is considered "illegal" by Microsoft's standards even if implementable (C++/CX ppltasks library throws errors if you try it). Worse, either by design or a bug in the MF MediaCapture class with Custom Sinks causes a crash if stop/start previewing without reinitializing (spPreferredPreviewMediaType is fatally nulled). After decompiling Windows.Media.dll, I worked around this in my own projects by using an activate-able custom sink ID which strangely assigns 1 to this pointer allowing it to be reinitialized in what can only be described as a hack by Microsoft. This would add additional overhead to the project to implement especially for static libraries as it requires IDL/DLL exporting followed by manifest declaration. Better to document that it is not supported.
Furthermore, an additional class for IMFAttributes should be implemented to make clean architecture for passing around attributes as opposed to directly calling non-COM interface calls on the objects and making use of SetProperties which would also be a set up for an object that uses the RuntimeClass activation ID.
The remaining changes are not difficult and will be complete soon along with debug tracing messages.
Update cap_msmf.cpp
Create cap_msmf.h
Update cap_msmf.cpp
Update cap_msmf.h
Update cap_msmf.cpp
Update cap_msmf.h
Update and rename cap_msmf.h to cap_msmf.hpp
Update cap_msmf.cpp
Update CMakeLists.txt
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.cpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Successful test - samples are grabbed
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Create ppltasks_winrt.h
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update ppltasks_winrt.h
Library updated and cleaned up with comments, marshaling, exceptions and linker settings
Update ppltasks_winrt.h
Fixed trailing whitespace
2013-12-14 16:53:30 +08:00
|
|
|
#ifdef HAVE_WINRT
|
|
|
|
long initDevices(_DeviceClass devClass);
|
|
|
|
void waitInit() {
|
|
|
|
if (vds_enumTask) {
|
|
|
|
HRESULT hr;
|
|
|
|
DO_ACTION_SYNCHRONOUSLY(hr, vds_enumTask, GET_CURRENT_CONTEXT);
|
|
|
|
vds_enumTask = nullptr;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#else
|
2013-04-03 09:01:20 +08:00
|
|
|
long initDevices(IMFAttributes *pAttributes);
|
Update cap_msmf.cpp
Add support for WinRT in the MF capture framework by removing the disallowed calls to enumerate devices and create a sample grabber sink and adding framework for the MediaCapture interface and a custom sink which interfaces with the sample grabber callback interface. The change requires discussion for making it completely functional as redundancy is required given that if the source is a video file, the old code pathways must be used. Otherwise all IMFMediaSession, IMFMediaSource, and IMFActivate code must use a MediaCapture code path and all sink code must use the CMediaSink custom sink.
Support for the custom sink is extended to non-WinRT not for compatibility as Windows Vista client is a minimum regardless, but because it offers more flexibility, could be faster and is able to be used as an optionally different code path during sink creation based on a future configuration parameter.
My discussion and proposal to finish this change:
Devices are so easily enumerated through WinRT Windows.Devices namespace that wrapping the calls in a library is quite a chore for little benefit though to get the various modes and formats could still be a worthwhile project. For now conditional compilation to remove videodevices and any offending non-video file related activity in videodevice. In my opinion, this is a different , far less fundamental and important change which can possibly be done as a future project and also much more easily implemented in C++/CX.
ImageGrabber has the IMFSampleGrabberSinkCallback replaced with a base class (SharedSampleGrabber) which also be is base class for ImageGrabberRT. This change is necessary as the custom sink does not require a thread to pump events which is done through MediaCapture already. IMFSampleGrabberSinkCallback is the common element between both models and that piece can be shared. Initializing the new ImageGrabberRT is as simple as passing an already initialized MediaCapture object and any video format/encoding parameters.
The concurrency event is necessary to wait for completion and is the way the underlying, IAsyncAction wrappers in the task library work as well. Native WIN32 event objects would be an option if HAVE_CONCURRENCY is not defined. I could even imagine doing it with sleep/thread yield and InterlockedCompareExchange yet I am not enthusiastic about that approach either. Since there is a specific compiler HAVE_ for concurrency, I do not like pulling it in though I think for WinRT it is safe to say we will always have it available though should probably conditionally compile with the Interlocked option as WIN32 events would require HAVE_WIN32.
It looks like C++/CX cannot be used for the IMediaExtension sink (which should not be a problem) as using COM objects requires WRL and though deriving from IMediaExtension can be done, there is little purpose without COM. Objects from C++/CX can be swapped to interact with objects from native C++ as Inspectable* can reinterpret_cast to the ref object IInspectable^ and vice-versa. A solution to the COM class with C++/CX would be great so we could have dual support. Also without #define for every WRL object in use, the code will get quite muddy given that the */^ would need to be ifdef'd everywhere.
Update cap_msmf.cpp
Fixed bugs and completed the change. I believe the new classes need to be moved to a header file as the file has become to large and more classes need to be added for handling all the asynchronous problems (one wrapping IAsyncAction in a task and another for making a task out of IAsyncAction). Unfortunately, blocking on the UI thread is not an option in WinRT so a synchronous architecture is considered "illegal" by Microsoft's standards even if implementable (C++/CX ppltasks library throws errors if you try it). Worse, either by design or a bug in the MF MediaCapture class with Custom Sinks causes a crash if stop/start previewing without reinitializing (spPreferredPreviewMediaType is fatally nulled). After decompiling Windows.Media.dll, I worked around this in my own projects by using an activate-able custom sink ID which strangely assigns 1 to this pointer allowing it to be reinitialized in what can only be described as a hack by Microsoft. This would add additional overhead to the project to implement especially for static libraries as it requires IDL/DLL exporting followed by manifest declaration. Better to document that it is not supported.
Furthermore, an additional class for IMFAttributes should be implemented to make clean architecture for passing around attributes as opposed to directly calling non-COM interface calls on the objects and making use of SetProperties which would also be a set up for an object that uses the RuntimeClass activation ID.
The remaining changes are not difficult and will be complete soon along with debug tracing messages.
Update cap_msmf.cpp
Create cap_msmf.h
Update cap_msmf.cpp
Update cap_msmf.h
Update cap_msmf.cpp
Update cap_msmf.h
Update and rename cap_msmf.h to cap_msmf.hpp
Update cap_msmf.cpp
Update CMakeLists.txt
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.cpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Successful test - samples are grabbed
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Create ppltasks_winrt.h
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update ppltasks_winrt.h
Library updated and cleaned up with comments, marshaling, exceptions and linker settings
Update ppltasks_winrt.h
Fixed trailing whitespace
2013-12-14 16:53:30 +08:00
|
|
|
#endif
|
2013-04-03 09:01:20 +08:00
|
|
|
static videoDevices& getInstance();
|
|
|
|
videoDevice *getDevice(unsigned int i);
|
|
|
|
unsigned int getCount();
|
|
|
|
void clearDevices();
|
|
|
|
private:
|
|
|
|
UINT32 count;
|
Update cap_msmf.cpp
Add support for WinRT in the MF capture framework by removing the disallowed calls to enumerate devices and create a sample grabber sink and adding framework for the MediaCapture interface and a custom sink which interfaces with the sample grabber callback interface. The change requires discussion for making it completely functional as redundancy is required given that if the source is a video file, the old code pathways must be used. Otherwise all IMFMediaSession, IMFMediaSource, and IMFActivate code must use a MediaCapture code path and all sink code must use the CMediaSink custom sink.
Support for the custom sink is extended to non-WinRT not for compatibility as Windows Vista client is a minimum regardless, but because it offers more flexibility, could be faster and is able to be used as an optionally different code path during sink creation based on a future configuration parameter.
My discussion and proposal to finish this change:
Devices are so easily enumerated through WinRT Windows.Devices namespace that wrapping the calls in a library is quite a chore for little benefit though to get the various modes and formats could still be a worthwhile project. For now conditional compilation to remove videodevices and any offending non-video file related activity in videodevice. In my opinion, this is a different , far less fundamental and important change which can possibly be done as a future project and also much more easily implemented in C++/CX.
ImageGrabber has the IMFSampleGrabberSinkCallback replaced with a base class (SharedSampleGrabber) which also be is base class for ImageGrabberRT. This change is necessary as the custom sink does not require a thread to pump events which is done through MediaCapture already. IMFSampleGrabberSinkCallback is the common element between both models and that piece can be shared. Initializing the new ImageGrabberRT is as simple as passing an already initialized MediaCapture object and any video format/encoding parameters.
The concurrency event is necessary to wait for completion and is the way the underlying, IAsyncAction wrappers in the task library work as well. Native WIN32 event objects would be an option if HAVE_CONCURRENCY is not defined. I could even imagine doing it with sleep/thread yield and InterlockedCompareExchange yet I am not enthusiastic about that approach either. Since there is a specific compiler HAVE_ for concurrency, I do not like pulling it in though I think for WinRT it is safe to say we will always have it available though should probably conditionally compile with the Interlocked option as WIN32 events would require HAVE_WIN32.
It looks like C++/CX cannot be used for the IMediaExtension sink (which should not be a problem) as using COM objects requires WRL and though deriving from IMediaExtension can be done, there is little purpose without COM. Objects from C++/CX can be swapped to interact with objects from native C++ as Inspectable* can reinterpret_cast to the ref object IInspectable^ and vice-versa. A solution to the COM class with C++/CX would be great so we could have dual support. Also without #define for every WRL object in use, the code will get quite muddy given that the */^ would need to be ifdef'd everywhere.
Update cap_msmf.cpp
Fixed bugs and completed the change. I believe the new classes need to be moved to a header file as the file has become to large and more classes need to be added for handling all the asynchronous problems (one wrapping IAsyncAction in a task and another for making a task out of IAsyncAction). Unfortunately, blocking on the UI thread is not an option in WinRT so a synchronous architecture is considered "illegal" by Microsoft's standards even if implementable (C++/CX ppltasks library throws errors if you try it). Worse, either by design or a bug in the MF MediaCapture class with Custom Sinks causes a crash if stop/start previewing without reinitializing (spPreferredPreviewMediaType is fatally nulled). After decompiling Windows.Media.dll, I worked around this in my own projects by using an activate-able custom sink ID which strangely assigns 1 to this pointer allowing it to be reinitialized in what can only be described as a hack by Microsoft. This would add additional overhead to the project to implement especially for static libraries as it requires IDL/DLL exporting followed by manifest declaration. Better to document that it is not supported.
Furthermore, an additional class for IMFAttributes should be implemented to make clean architecture for passing around attributes as opposed to directly calling non-COM interface calls on the objects and making use of SetProperties which would also be a set up for an object that uses the RuntimeClass activation ID.
The remaining changes are not difficult and will be complete soon along with debug tracing messages.
Update cap_msmf.cpp
Create cap_msmf.h
Update cap_msmf.cpp
Update cap_msmf.h
Update cap_msmf.cpp
Update cap_msmf.h
Update and rename cap_msmf.h to cap_msmf.hpp
Update cap_msmf.cpp
Update CMakeLists.txt
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.cpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Successful test - samples are grabbed
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Create ppltasks_winrt.h
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update ppltasks_winrt.h
Library updated and cleaned up with comments, marshaling, exceptions and linker settings
Update ppltasks_winrt.h
Fixed trailing whitespace
2013-12-14 16:53:30 +08:00
|
|
|
#ifdef HAVE_WINRT
|
|
|
|
MAKE_WRL_REF(_AsyncAction) vds_enumTask;
|
|
|
|
#endif
|
2013-04-03 09:01:20 +08:00
|
|
|
std::vector<videoDevice *> vds_Devices;
|
|
|
|
videoDevices(void);
|
|
|
|
};
|
2013-05-19 04:04:31 +08:00
|
|
|
|
2013-04-03 09:01:20 +08:00
|
|
|
// Class for creating of Media Foundation context
|
|
|
|
class Media_Foundation
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
virtual ~Media_Foundation(void);
|
|
|
|
static Media_Foundation& getInstance();
|
|
|
|
bool buildListOfDevices();
|
|
|
|
private:
|
|
|
|
Media_Foundation(void);
|
|
|
|
};
|
2013-05-19 04:04:31 +08:00
|
|
|
|
2013-04-03 09:01:20 +08:00
|
|
|
/// The only visiable class for controlling of video devices in format singelton
|
|
|
|
class videoInput
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
virtual ~videoInput(void);
|
|
|
|
// Getting of static instance of videoInput class
|
|
|
|
static videoInput& getInstance();
|
|
|
|
// Closing video device with deviceID
|
|
|
|
void closeDevice(int deviceID);
|
|
|
|
// Setting callback function for emergency events(for example: removing video device with deviceID) with userData
|
|
|
|
void setEmergencyStopEvent(int deviceID, void *userData, void(*func)(int, void *));
|
|
|
|
// Closing all devices
|
|
|
|
void closeAllDevices();
|
|
|
|
// Getting of parametrs of video device with deviceID
|
|
|
|
CamParametrs getParametrs(int deviceID);
|
|
|
|
// Setting of parametrs of video device with deviceID
|
|
|
|
void setParametrs(int deviceID, CamParametrs parametrs);
|
|
|
|
// Getting numbers of existence videodevices with listing in consol
|
|
|
|
unsigned int listDevices(bool silent = false);
|
|
|
|
// Getting numbers of formats, which are supported by videodevice with deviceID
|
|
|
|
unsigned int getCountFormats(int deviceID);
|
|
|
|
// Getting width of image, which is getting from videodevice with deviceID
|
|
|
|
unsigned int getWidth(int deviceID);
|
|
|
|
// Getting height of image, which is getting from videodevice with deviceID
|
|
|
|
unsigned int getHeight(int deviceID);
|
|
|
|
// Getting name of videodevice with deviceID
|
|
|
|
wchar_t *getNameVideoDevice(int deviceID);
|
|
|
|
// Getting interface MediaSource for Media Foundation from videodevice with deviceID
|
|
|
|
IMFMediaSource *getMediaSource(int deviceID);
|
2013-04-03 18:48:23 +08:00
|
|
|
// Getting format with id, which is supported by videodevice with deviceID
|
2013-04-03 09:01:20 +08:00
|
|
|
MediaType getFormat(int deviceID, int unsigned id);
|
|
|
|
// Checking of existence of the suitable video devices
|
|
|
|
bool isDevicesAcceable();
|
|
|
|
// Checking of using the videodevice with deviceID
|
|
|
|
bool isDeviceSetup(int deviceID);
|
|
|
|
// Checking of using MediaSource from videodevice with deviceID
|
|
|
|
bool isDeviceMediaSource(int deviceID);
|
|
|
|
// Checking of using Raw Data of pixels from videodevice with deviceID
|
|
|
|
bool isDeviceRawDataSource(int deviceID);
|
|
|
|
// Setting of the state of outprinting info in console
|
|
|
|
static void setVerbose(bool state);
|
|
|
|
// Initialization of video device with deviceID by media type with id
|
|
|
|
bool setupDevice(int deviceID, unsigned int id = 0);
|
|
|
|
// Initialization of video device with deviceID by wisth w, height h and fps idealFramerate
|
|
|
|
bool setupDevice(int deviceID, unsigned int w, unsigned int h, unsigned int idealFramerate = 30);
|
2013-04-03 18:48:23 +08:00
|
|
|
// Checking of recivig of new frame from video device with deviceID
|
2013-04-03 09:01:20 +08:00
|
|
|
bool isFrameNew(int deviceID);
|
Update cap_msmf.cpp
Add support for WinRT in the MF capture framework by removing the disallowed calls to enumerate devices and create a sample grabber sink and adding framework for the MediaCapture interface and a custom sink which interfaces with the sample grabber callback interface. The change requires discussion for making it completely functional as redundancy is required given that if the source is a video file, the old code pathways must be used. Otherwise all IMFMediaSession, IMFMediaSource, and IMFActivate code must use a MediaCapture code path and all sink code must use the CMediaSink custom sink.
Support for the custom sink is extended to non-WinRT not for compatibility as Windows Vista client is a minimum regardless, but because it offers more flexibility, could be faster and is able to be used as an optionally different code path during sink creation based on a future configuration parameter.
My discussion and proposal to finish this change:
Devices are so easily enumerated through WinRT Windows.Devices namespace that wrapping the calls in a library is quite a chore for little benefit though to get the various modes and formats could still be a worthwhile project. For now conditional compilation to remove videodevices and any offending non-video file related activity in videodevice. In my opinion, this is a different , far less fundamental and important change which can possibly be done as a future project and also much more easily implemented in C++/CX.
ImageGrabber has the IMFSampleGrabberSinkCallback replaced with a base class (SharedSampleGrabber) which also be is base class for ImageGrabberRT. This change is necessary as the custom sink does not require a thread to pump events which is done through MediaCapture already. IMFSampleGrabberSinkCallback is the common element between both models and that piece can be shared. Initializing the new ImageGrabberRT is as simple as passing an already initialized MediaCapture object and any video format/encoding parameters.
The concurrency event is necessary to wait for completion and is the way the underlying, IAsyncAction wrappers in the task library work as well. Native WIN32 event objects would be an option if HAVE_CONCURRENCY is not defined. I could even imagine doing it with sleep/thread yield and InterlockedCompareExchange yet I am not enthusiastic about that approach either. Since there is a specific compiler HAVE_ for concurrency, I do not like pulling it in though I think for WinRT it is safe to say we will always have it available though should probably conditionally compile with the Interlocked option as WIN32 events would require HAVE_WIN32.
It looks like C++/CX cannot be used for the IMediaExtension sink (which should not be a problem) as using COM objects requires WRL and though deriving from IMediaExtension can be done, there is little purpose without COM. Objects from C++/CX can be swapped to interact with objects from native C++ as Inspectable* can reinterpret_cast to the ref object IInspectable^ and vice-versa. A solution to the COM class with C++/CX would be great so we could have dual support. Also without #define for every WRL object in use, the code will get quite muddy given that the */^ would need to be ifdef'd everywhere.
Update cap_msmf.cpp
Fixed bugs and completed the change. I believe the new classes need to be moved to a header file as the file has become to large and more classes need to be added for handling all the asynchronous problems (one wrapping IAsyncAction in a task and another for making a task out of IAsyncAction). Unfortunately, blocking on the UI thread is not an option in WinRT so a synchronous architecture is considered "illegal" by Microsoft's standards even if implementable (C++/CX ppltasks library throws errors if you try it). Worse, either by design or a bug in the MF MediaCapture class with Custom Sinks causes a crash if stop/start previewing without reinitializing (spPreferredPreviewMediaType is fatally nulled). After decompiling Windows.Media.dll, I worked around this in my own projects by using an activate-able custom sink ID which strangely assigns 1 to this pointer allowing it to be reinitialized in what can only be described as a hack by Microsoft. This would add additional overhead to the project to implement especially for static libraries as it requires IDL/DLL exporting followed by manifest declaration. Better to document that it is not supported.
Furthermore, an additional class for IMFAttributes should be implemented to make clean architecture for passing around attributes as opposed to directly calling non-COM interface calls on the objects and making use of SetProperties which would also be a set up for an object that uses the RuntimeClass activation ID.
The remaining changes are not difficult and will be complete soon along with debug tracing messages.
Update cap_msmf.cpp
Create cap_msmf.h
Update cap_msmf.cpp
Update cap_msmf.h
Update cap_msmf.cpp
Update cap_msmf.h
Update and rename cap_msmf.h to cap_msmf.hpp
Update cap_msmf.cpp
Update CMakeLists.txt
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.cpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Successful test - samples are grabbed
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Create ppltasks_winrt.h
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update ppltasks_winrt.h
Library updated and cleaned up with comments, marshaling, exceptions and linker settings
Update ppltasks_winrt.h
Fixed trailing whitespace
2013-12-14 16:53:30 +08:00
|
|
|
#ifdef HAVE_WINRT
|
|
|
|
void waitForDevice(int deviceID);
|
|
|
|
#endif
|
2013-04-03 09:01:20 +08:00
|
|
|
// Writing of Raw Data pixels from video device with deviceID with correction of RedAndBlue flipping flipRedAndBlue and vertical flipping flipImage
|
|
|
|
bool getPixels(int deviceID, unsigned char * pixels, bool flipRedAndBlue = false, bool flipImage = false);
|
2013-05-19 04:04:31 +08:00
|
|
|
static void processPixels(unsigned char * src, unsigned char * dst, unsigned int width, unsigned int height, unsigned int bpp, bool bRGB, bool bFlip);
|
2013-04-03 18:48:23 +08:00
|
|
|
private:
|
2013-04-03 09:01:20 +08:00
|
|
|
bool accessToDevices;
|
|
|
|
videoInput(void);
|
|
|
|
void updateListOfDevices();
|
|
|
|
};
|
2013-05-19 04:04:31 +08:00
|
|
|
|
2013-04-03 09:01:20 +08:00
|
|
|
DebugPrintOut::DebugPrintOut(void):verbose(true)
|
|
|
|
{
|
|
|
|
}
|
2013-05-19 04:04:31 +08:00
|
|
|
|
2013-04-03 09:01:20 +08:00
|
|
|
DebugPrintOut::~DebugPrintOut(void)
|
|
|
|
{
|
|
|
|
}
|
2013-05-19 04:04:31 +08:00
|
|
|
|
2013-04-03 09:01:20 +08:00
|
|
|
DebugPrintOut& DebugPrintOut::getInstance()
|
|
|
|
{
|
|
|
|
static DebugPrintOut instance;
|
|
|
|
return instance;
|
|
|
|
}
|
2013-05-19 04:04:31 +08:00
|
|
|
|
2013-04-03 09:01:20 +08:00
|
|
|
void DebugPrintOut::printOut(const wchar_t *format, ...)
|
|
|
|
{
|
|
|
|
if(verbose)
|
|
|
|
{
|
|
|
|
int i = 0;
|
|
|
|
wchar_t *p = NULL;
|
|
|
|
va_list args;
|
|
|
|
va_start(args, format);
|
|
|
|
if(wcscmp(format, L"%i"))
|
|
|
|
{
|
|
|
|
i = va_arg (args, int);
|
|
|
|
}
|
|
|
|
if(wcscmp(format, L"%s"))
|
|
|
|
{
|
|
|
|
p = va_arg (args, wchar_t *);
|
|
|
|
}
|
|
|
|
wprintf(format, i,p);
|
|
|
|
va_end (args);
|
|
|
|
}
|
|
|
|
}
|
2013-05-19 04:04:31 +08:00
|
|
|
|
2013-04-03 09:01:20 +08:00
|
|
|
void DebugPrintOut::setVerbose(bool state)
|
|
|
|
{
|
|
|
|
verbose = state;
|
|
|
|
}
|
2013-05-19 04:04:31 +08:00
|
|
|
|
2013-04-03 09:01:20 +08:00
|
|
|
LPCWSTR GetGUIDNameConstNew(const GUID& guid);
|
|
|
|
HRESULT GetGUIDNameNew(const GUID& guid, WCHAR **ppwsz);
|
|
|
|
HRESULT LogAttributeValueByIndexNew(IMFAttributes *pAttr, DWORD index);
|
|
|
|
HRESULT SpecialCaseAttributeValueNew(GUID guid, const PROPVARIANT& var, MediaType &out);
|
2013-05-19 04:04:31 +08:00
|
|
|
|
2013-04-03 09:01:20 +08:00
|
|
|
unsigned int *GetParametr(GUID guid, MediaType &out)
|
|
|
|
{
|
2013-04-03 18:48:23 +08:00
|
|
|
if(guid == MF_MT_YUV_MATRIX)
|
2013-04-03 09:01:20 +08:00
|
|
|
return &(out.MF_MT_YUV_MATRIX);
|
2013-04-03 18:48:23 +08:00
|
|
|
if(guid == MF_MT_VIDEO_LIGHTING)
|
2013-04-03 09:01:20 +08:00
|
|
|
return &(out.MF_MT_VIDEO_LIGHTING);
|
2013-04-03 18:48:23 +08:00
|
|
|
if(guid == MF_MT_DEFAULT_STRIDE)
|
2013-05-19 04:04:31 +08:00
|
|
|
return (unsigned int*)&(out.MF_MT_DEFAULT_STRIDE);
|
2013-04-03 18:48:23 +08:00
|
|
|
if(guid == MF_MT_VIDEO_CHROMA_SITING)
|
2013-04-03 09:01:20 +08:00
|
|
|
return &(out.MF_MT_VIDEO_CHROMA_SITING);
|
2013-04-03 18:48:23 +08:00
|
|
|
if(guid == MF_MT_VIDEO_NOMINAL_RANGE)
|
2013-04-03 09:01:20 +08:00
|
|
|
return &(out.MF_MT_VIDEO_NOMINAL_RANGE);
|
2013-04-03 18:48:23 +08:00
|
|
|
if(guid == MF_MT_ALL_SAMPLES_INDEPENDENT)
|
2013-04-03 09:01:20 +08:00
|
|
|
return &(out.MF_MT_ALL_SAMPLES_INDEPENDENT);
|
2013-04-03 18:48:23 +08:00
|
|
|
if(guid == MF_MT_FIXED_SIZE_SAMPLES)
|
2013-04-03 09:01:20 +08:00
|
|
|
return &(out.MF_MT_FIXED_SIZE_SAMPLES);
|
2013-04-03 18:48:23 +08:00
|
|
|
if(guid == MF_MT_SAMPLE_SIZE)
|
2013-04-03 09:01:20 +08:00
|
|
|
return &(out.MF_MT_SAMPLE_SIZE);
|
2013-04-03 18:48:23 +08:00
|
|
|
if(guid == MF_MT_VIDEO_PRIMARIES)
|
2013-04-03 09:01:20 +08:00
|
|
|
return &(out.MF_MT_VIDEO_PRIMARIES);
|
2013-04-03 18:48:23 +08:00
|
|
|
if(guid == MF_MT_INTERLACE_MODE)
|
2013-04-03 09:01:20 +08:00
|
|
|
return &(out.MF_MT_INTERLACE_MODE);
|
|
|
|
return NULL;
|
|
|
|
}
|
2013-05-19 04:04:31 +08:00
|
|
|
|
2013-04-03 09:01:20 +08:00
|
|
|
HRESULT LogAttributeValueByIndexNew(IMFAttributes *pAttr, DWORD index, MediaType &out)
|
|
|
|
{
|
|
|
|
WCHAR *pGuidName = NULL;
|
|
|
|
WCHAR *pGuidValName = NULL;
|
|
|
|
GUID guid = { 0 };
|
|
|
|
PROPVARIANT var;
|
|
|
|
PropVariantInit(&var);
|
|
|
|
HRESULT hr = pAttr->GetItemByIndex(index, &guid, &var);
|
|
|
|
if (FAILED(hr))
|
|
|
|
{
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
hr = GetGUIDNameNew(guid, &pGuidName);
|
|
|
|
if (FAILED(hr))
|
|
|
|
{
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
hr = SpecialCaseAttributeValueNew(guid, var, out);
|
|
|
|
unsigned int *p;
|
|
|
|
if (FAILED(hr))
|
|
|
|
{
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
if (hr == S_FALSE)
|
|
|
|
{
|
|
|
|
switch (var.vt)
|
|
|
|
{
|
|
|
|
case VT_UI4:
|
|
|
|
p = GetParametr(guid, out);
|
2013-04-03 18:48:23 +08:00
|
|
|
if(p)
|
2013-04-03 09:01:20 +08:00
|
|
|
{
|
|
|
|
*p = var.ulVal;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case VT_UI8:
|
|
|
|
break;
|
|
|
|
case VT_R8:
|
|
|
|
break;
|
|
|
|
case VT_CLSID:
|
|
|
|
if(guid == MF_MT_AM_FORMAT_TYPE)
|
|
|
|
{
|
|
|
|
hr = GetGUIDNameNew(*var.puuid, &pGuidValName);
|
|
|
|
if (SUCCEEDED(hr))
|
|
|
|
{
|
|
|
|
out.MF_MT_AM_FORMAT_TYPE = MF_MT_AM_FORMAT_TYPE;
|
|
|
|
out.pMF_MT_AM_FORMAT_TYPEName = pGuidValName;
|
|
|
|
pGuidValName = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if(guid == MF_MT_MAJOR_TYPE)
|
|
|
|
{
|
|
|
|
hr = GetGUIDNameNew(*var.puuid, &pGuidValName);
|
|
|
|
if (SUCCEEDED(hr))
|
|
|
|
{
|
|
|
|
out.MF_MT_MAJOR_TYPE = MF_MT_MAJOR_TYPE;
|
|
|
|
out.pMF_MT_MAJOR_TYPEName = pGuidValName;
|
|
|
|
pGuidValName = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if(guid == MF_MT_SUBTYPE)
|
|
|
|
{
|
|
|
|
hr = GetGUIDNameNew(*var.puuid, &pGuidValName);
|
|
|
|
if (SUCCEEDED(hr))
|
|
|
|
{
|
|
|
|
out.MF_MT_SUBTYPE = MF_MT_SUBTYPE;
|
|
|
|
out.pMF_MT_SUBTYPEName = pGuidValName;
|
|
|
|
pGuidValName = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case VT_LPWSTR:
|
|
|
|
break;
|
|
|
|
case VT_VECTOR | VT_UI1:
|
|
|
|
break;
|
|
|
|
case VT_UNKNOWN:
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
done:
|
|
|
|
CoTaskMemFree(pGuidName);
|
|
|
|
CoTaskMemFree(pGuidValName);
|
|
|
|
PropVariantClear(&var);
|
|
|
|
return hr;
|
|
|
|
}
|
2013-05-19 04:04:31 +08:00
|
|
|
|
2013-04-03 09:01:20 +08:00
|
|
|
HRESULT GetGUIDNameNew(const GUID& guid, WCHAR **ppwsz)
|
|
|
|
{
|
|
|
|
HRESULT hr = S_OK;
|
|
|
|
WCHAR *pName = NULL;
|
|
|
|
LPCWSTR pcwsz = GetGUIDNameConstNew(guid);
|
|
|
|
if (pcwsz)
|
|
|
|
{
|
|
|
|
size_t cchLength = 0;
|
|
|
|
hr = StringCchLengthW(pcwsz, STRSAFE_MAX_CCH, &cchLength);
|
|
|
|
if (FAILED(hr))
|
|
|
|
{
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
pName = (WCHAR*)CoTaskMemAlloc((cchLength + 1) * sizeof(WCHAR));
|
|
|
|
if (pName == NULL)
|
|
|
|
{
|
|
|
|
hr = E_OUTOFMEMORY;
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
hr = StringCchCopyW(pName, cchLength + 1, pcwsz);
|
|
|
|
if (FAILED(hr))
|
|
|
|
{
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
hr = StringFromCLSID(guid, &pName);
|
|
|
|
}
|
|
|
|
done:
|
|
|
|
if (FAILED(hr))
|
|
|
|
{
|
|
|
|
*ppwsz = NULL;
|
|
|
|
CoTaskMemFree(pName);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
*ppwsz = pName;
|
|
|
|
}
|
|
|
|
return hr;
|
|
|
|
}
|
2013-05-23 00:50:54 +08:00
|
|
|
|
2013-04-03 09:01:20 +08:00
|
|
|
void LogUINT32AsUINT64New(const PROPVARIANT& var, UINT32 &uHigh, UINT32 &uLow)
|
|
|
|
{
|
|
|
|
Unpack2UINT32AsUINT64(var.uhVal.QuadPart, &uHigh, &uLow);
|
|
|
|
}
|
2013-05-23 00:50:54 +08:00
|
|
|
|
2013-04-03 09:01:20 +08:00
|
|
|
float OffsetToFloatNew(const MFOffset& offset)
|
|
|
|
{
|
|
|
|
return offset.value + (static_cast<float>(offset.fract) / 65536.0f);
|
|
|
|
}
|
2013-05-23 00:50:54 +08:00
|
|
|
|
2013-04-03 09:01:20 +08:00
|
|
|
HRESULT LogVideoAreaNew(const PROPVARIANT& var)
|
|
|
|
{
|
|
|
|
if (var.caub.cElems < sizeof(MFVideoArea))
|
|
|
|
{
|
|
|
|
return S_OK;
|
|
|
|
}
|
|
|
|
return S_OK;
|
|
|
|
}
|
2013-05-23 00:50:54 +08:00
|
|
|
|
2013-04-03 09:01:20 +08:00
|
|
|
HRESULT SpecialCaseAttributeValueNew(GUID guid, const PROPVARIANT& var, MediaType &out)
|
|
|
|
{
|
2013-05-19 04:04:31 +08:00
|
|
|
if (guid == MF_MT_DEFAULT_STRIDE)
|
|
|
|
{
|
|
|
|
out.MF_MT_DEFAULT_STRIDE = var.intVal;
|
|
|
|
} else
|
2013-04-03 09:01:20 +08:00
|
|
|
if (guid == MF_MT_FRAME_SIZE)
|
|
|
|
{
|
|
|
|
UINT32 uHigh = 0, uLow = 0;
|
|
|
|
LogUINT32AsUINT64New(var, uHigh, uLow);
|
|
|
|
out.width = uHigh;
|
|
|
|
out.height = uLow;
|
|
|
|
out.MF_MT_FRAME_SIZE = out.width * out.height;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
if (guid == MF_MT_FRAME_RATE)
|
|
|
|
{
|
|
|
|
UINT32 uHigh = 0, uLow = 0;
|
|
|
|
LogUINT32AsUINT64New(var, uHigh, uLow);
|
2013-05-23 00:50:54 +08:00
|
|
|
out.MF_MT_FRAME_RATE_NUMERATOR = uHigh;
|
|
|
|
out.MF_MT_FRAME_RATE_DENOMINATOR = uLow;
|
2013-04-03 09:01:20 +08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
if (guid == MF_MT_FRAME_RATE_RANGE_MAX)
|
|
|
|
{
|
|
|
|
UINT32 uHigh = 0, uLow = 0;
|
|
|
|
LogUINT32AsUINT64New(var, uHigh, uLow);
|
|
|
|
out.MF_MT_FRAME_RATE_RANGE_MAX = uHigh;
|
|
|
|
out.MF_MT_FRAME_RATE_RANGE_MAX_low = uLow;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
if (guid == MF_MT_FRAME_RATE_RANGE_MIN)
|
|
|
|
{
|
|
|
|
UINT32 uHigh = 0, uLow = 0;
|
|
|
|
LogUINT32AsUINT64New(var, uHigh, uLow);
|
|
|
|
out.MF_MT_FRAME_RATE_RANGE_MIN = uHigh;
|
|
|
|
out.MF_MT_FRAME_RATE_RANGE_MIN_low = uLow;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
if (guid == MF_MT_PIXEL_ASPECT_RATIO)
|
|
|
|
{
|
|
|
|
UINT32 uHigh = 0, uLow = 0;
|
|
|
|
LogUINT32AsUINT64New(var, uHigh, uLow);
|
|
|
|
out.MF_MT_PIXEL_ASPECT_RATIO = uHigh;
|
|
|
|
out.MF_MT_PIXEL_ASPECT_RATIO_low = uLow;
|
2013-04-03 18:48:23 +08:00
|
|
|
}
|
2013-04-03 09:01:20 +08:00
|
|
|
else
|
|
|
|
{
|
|
|
|
return S_FALSE;
|
|
|
|
}
|
|
|
|
return S_OK;
|
|
|
|
}
|
2013-05-23 00:50:54 +08:00
|
|
|
|
2013-04-03 09:01:20 +08:00
|
|
|
#ifndef IF_EQUAL_RETURN
|
|
|
|
#define IF_EQUAL_RETURN(param, val) if(val == param) return L#val
|
|
|
|
#endif
|
2013-05-23 00:50:54 +08:00
|
|
|
|
2013-04-03 09:01:20 +08:00
|
|
|
LPCWSTR GetGUIDNameConstNew(const GUID& guid)
|
|
|
|
{
|
|
|
|
IF_EQUAL_RETURN(guid, MF_MT_MAJOR_TYPE);
|
|
|
|
IF_EQUAL_RETURN(guid, MF_MT_MAJOR_TYPE);
|
|
|
|
IF_EQUAL_RETURN(guid, MF_MT_SUBTYPE);
|
|
|
|
IF_EQUAL_RETURN(guid, MF_MT_ALL_SAMPLES_INDEPENDENT);
|
|
|
|
IF_EQUAL_RETURN(guid, MF_MT_FIXED_SIZE_SAMPLES);
|
|
|
|
IF_EQUAL_RETURN(guid, MF_MT_COMPRESSED);
|
|
|
|
IF_EQUAL_RETURN(guid, MF_MT_SAMPLE_SIZE);
|
|
|
|
IF_EQUAL_RETURN(guid, MF_MT_WRAPPED_TYPE);
|
|
|
|
IF_EQUAL_RETURN(guid, MF_MT_AUDIO_NUM_CHANNELS);
|
|
|
|
IF_EQUAL_RETURN(guid, MF_MT_AUDIO_SAMPLES_PER_SECOND);
|
|
|
|
IF_EQUAL_RETURN(guid, MF_MT_AUDIO_FLOAT_SAMPLES_PER_SECOND);
|
|
|
|
IF_EQUAL_RETURN(guid, MF_MT_AUDIO_AVG_BYTES_PER_SECOND);
|
|
|
|
IF_EQUAL_RETURN(guid, MF_MT_AUDIO_BLOCK_ALIGNMENT);
|
|
|
|
IF_EQUAL_RETURN(guid, MF_MT_AUDIO_BITS_PER_SAMPLE);
|
|
|
|
IF_EQUAL_RETURN(guid, MF_MT_AUDIO_VALID_BITS_PER_SAMPLE);
|
|
|
|
IF_EQUAL_RETURN(guid, MF_MT_AUDIO_SAMPLES_PER_BLOCK);
|
|
|
|
IF_EQUAL_RETURN(guid, MF_MT_AUDIO_CHANNEL_MASK);
|
|
|
|
IF_EQUAL_RETURN(guid, MF_MT_AUDIO_FOLDDOWN_MATRIX);
|
|
|
|
IF_EQUAL_RETURN(guid, MF_MT_AUDIO_WMADRC_PEAKREF);
|
|
|
|
IF_EQUAL_RETURN(guid, MF_MT_AUDIO_WMADRC_PEAKTARGET);
|
|
|
|
IF_EQUAL_RETURN(guid, MF_MT_AUDIO_WMADRC_AVGREF);
|
|
|
|
IF_EQUAL_RETURN(guid, MF_MT_AUDIO_WMADRC_AVGTARGET);
|
|
|
|
IF_EQUAL_RETURN(guid, MF_MT_AUDIO_PREFER_WAVEFORMATEX);
|
|
|
|
IF_EQUAL_RETURN(guid, MF_MT_AAC_PAYLOAD_TYPE);
|
|
|
|
IF_EQUAL_RETURN(guid, MF_MT_AAC_AUDIO_PROFILE_LEVEL_INDICATION);
|
|
|
|
IF_EQUAL_RETURN(guid, MF_MT_FRAME_SIZE);
|
|
|
|
IF_EQUAL_RETURN(guid, MF_MT_FRAME_RATE);
|
|
|
|
IF_EQUAL_RETURN(guid, MF_MT_FRAME_RATE_RANGE_MAX);
|
|
|
|
IF_EQUAL_RETURN(guid, MF_MT_FRAME_RATE_RANGE_MIN);
|
|
|
|
IF_EQUAL_RETURN(guid, MF_MT_PIXEL_ASPECT_RATIO);
|
|
|
|
IF_EQUAL_RETURN(guid, MF_MT_DRM_FLAGS);
|
|
|
|
IF_EQUAL_RETURN(guid, MF_MT_PAD_CONTROL_FLAGS);
|
|
|
|
IF_EQUAL_RETURN(guid, MF_MT_SOURCE_CONTENT_HINT);
|
|
|
|
IF_EQUAL_RETURN(guid, MF_MT_VIDEO_CHROMA_SITING);
|
|
|
|
IF_EQUAL_RETURN(guid, MF_MT_INTERLACE_MODE);
|
|
|
|
IF_EQUAL_RETURN(guid, MF_MT_TRANSFER_FUNCTION);
|
|
|
|
IF_EQUAL_RETURN(guid, MF_MT_VIDEO_PRIMARIES);
|
|
|
|
IF_EQUAL_RETURN(guid, MF_MT_CUSTOM_VIDEO_PRIMARIES);
|
|
|
|
IF_EQUAL_RETURN(guid, MF_MT_YUV_MATRIX);
|
|
|
|
IF_EQUAL_RETURN(guid, MF_MT_VIDEO_LIGHTING);
|
|
|
|
IF_EQUAL_RETURN(guid, MF_MT_VIDEO_NOMINAL_RANGE);
|
|
|
|
IF_EQUAL_RETURN(guid, MF_MT_GEOMETRIC_APERTURE);
|
|
|
|
IF_EQUAL_RETURN(guid, MF_MT_MINIMUM_DISPLAY_APERTURE);
|
|
|
|
IF_EQUAL_RETURN(guid, MF_MT_PAN_SCAN_APERTURE);
|
|
|
|
IF_EQUAL_RETURN(guid, MF_MT_PAN_SCAN_ENABLED);
|
|
|
|
IF_EQUAL_RETURN(guid, MF_MT_AVG_BITRATE);
|
|
|
|
IF_EQUAL_RETURN(guid, MF_MT_AVG_BIT_ERROR_RATE);
|
|
|
|
IF_EQUAL_RETURN(guid, MF_MT_MAX_KEYFRAME_SPACING);
|
|
|
|
IF_EQUAL_RETURN(guid, MF_MT_DEFAULT_STRIDE);
|
|
|
|
IF_EQUAL_RETURN(guid, MF_MT_PALETTE);
|
|
|
|
IF_EQUAL_RETURN(guid, MF_MT_USER_DATA);
|
|
|
|
IF_EQUAL_RETURN(guid, MF_MT_AM_FORMAT_TYPE);
|
|
|
|
IF_EQUAL_RETURN(guid, MF_MT_MPEG_START_TIME_CODE);
|
|
|
|
IF_EQUAL_RETURN(guid, MF_MT_MPEG2_PROFILE);
|
|
|
|
IF_EQUAL_RETURN(guid, MF_MT_MPEG2_LEVEL);
|
|
|
|
IF_EQUAL_RETURN(guid, MF_MT_MPEG2_FLAGS);
|
|
|
|
IF_EQUAL_RETURN(guid, MF_MT_MPEG_SEQUENCE_HEADER);
|
|
|
|
IF_EQUAL_RETURN(guid, MF_MT_DV_AAUX_SRC_PACK_0);
|
|
|
|
IF_EQUAL_RETURN(guid, MF_MT_DV_AAUX_CTRL_PACK_0);
|
|
|
|
IF_EQUAL_RETURN(guid, MF_MT_DV_AAUX_SRC_PACK_1);
|
|
|
|
IF_EQUAL_RETURN(guid, MF_MT_DV_AAUX_CTRL_PACK_1);
|
|
|
|
IF_EQUAL_RETURN(guid, MF_MT_DV_VAUX_SRC_PACK);
|
|
|
|
IF_EQUAL_RETURN(guid, MF_MT_DV_VAUX_CTRL_PACK);
|
|
|
|
IF_EQUAL_RETURN(guid, MF_MT_ARBITRARY_HEADER);
|
|
|
|
IF_EQUAL_RETURN(guid, MF_MT_ARBITRARY_FORMAT);
|
2013-04-03 18:48:23 +08:00
|
|
|
IF_EQUAL_RETURN(guid, MF_MT_IMAGE_LOSS_TOLERANT);
|
2013-04-03 09:01:20 +08:00
|
|
|
IF_EQUAL_RETURN(guid, MF_MT_MPEG4_SAMPLE_DESCRIPTION);
|
|
|
|
IF_EQUAL_RETURN(guid, MF_MT_MPEG4_CURRENT_SAMPLE_ENTRY);
|
2013-04-03 18:48:23 +08:00
|
|
|
IF_EQUAL_RETURN(guid, MF_MT_ORIGINAL_4CC);
|
2013-04-03 09:01:20 +08:00
|
|
|
IF_EQUAL_RETURN(guid, MF_MT_ORIGINAL_WAVE_FORMAT_TAG);
|
|
|
|
// Media types
|
|
|
|
IF_EQUAL_RETURN(guid, MFMediaType_Audio);
|
|
|
|
IF_EQUAL_RETURN(guid, MFMediaType_Video);
|
|
|
|
IF_EQUAL_RETURN(guid, MFMediaType_Protected);
|
|
|
|
IF_EQUAL_RETURN(guid, MFMediaType_SAMI);
|
|
|
|
IF_EQUAL_RETURN(guid, MFMediaType_Script);
|
|
|
|
IF_EQUAL_RETURN(guid, MFMediaType_Image);
|
|
|
|
IF_EQUAL_RETURN(guid, MFMediaType_HTML);
|
|
|
|
IF_EQUAL_RETURN(guid, MFMediaType_Binary);
|
|
|
|
IF_EQUAL_RETURN(guid, MFMediaType_FileTransfer);
|
|
|
|
IF_EQUAL_RETURN(guid, MFVideoFormat_AI44); // FCC('AI44')
|
2013-04-03 18:48:23 +08:00
|
|
|
IF_EQUAL_RETURN(guid, MFVideoFormat_ARGB32); // D3DFMT_A8R8G8B8
|
2013-04-03 09:01:20 +08:00
|
|
|
IF_EQUAL_RETURN(guid, MFVideoFormat_AYUV); // FCC('AYUV')
|
|
|
|
IF_EQUAL_RETURN(guid, MFVideoFormat_DV25); // FCC('dv25')
|
|
|
|
IF_EQUAL_RETURN(guid, MFVideoFormat_DV50); // FCC('dv50')
|
|
|
|
IF_EQUAL_RETURN(guid, MFVideoFormat_DVH1); // FCC('dvh1')
|
|
|
|
IF_EQUAL_RETURN(guid, MFVideoFormat_DVSD); // FCC('dvsd')
|
|
|
|
IF_EQUAL_RETURN(guid, MFVideoFormat_DVSL); // FCC('dvsl')
|
|
|
|
IF_EQUAL_RETURN(guid, MFVideoFormat_H264); // FCC('H264')
|
|
|
|
IF_EQUAL_RETURN(guid, MFVideoFormat_I420); // FCC('I420')
|
|
|
|
IF_EQUAL_RETURN(guid, MFVideoFormat_IYUV); // FCC('IYUV')
|
|
|
|
IF_EQUAL_RETURN(guid, MFVideoFormat_M4S2); // FCC('M4S2')
|
|
|
|
IF_EQUAL_RETURN(guid, MFVideoFormat_MJPG);
|
|
|
|
IF_EQUAL_RETURN(guid, MFVideoFormat_MP43); // FCC('MP43')
|
|
|
|
IF_EQUAL_RETURN(guid, MFVideoFormat_MP4S); // FCC('MP4S')
|
|
|
|
IF_EQUAL_RETURN(guid, MFVideoFormat_MP4V); // FCC('MP4V')
|
|
|
|
IF_EQUAL_RETURN(guid, MFVideoFormat_MPG1); // FCC('MPG1')
|
|
|
|
IF_EQUAL_RETURN(guid, MFVideoFormat_MSS1); // FCC('MSS1')
|
|
|
|
IF_EQUAL_RETURN(guid, MFVideoFormat_MSS2); // FCC('MSS2')
|
|
|
|
IF_EQUAL_RETURN(guid, MFVideoFormat_NV11); // FCC('NV11')
|
|
|
|
IF_EQUAL_RETURN(guid, MFVideoFormat_NV12); // FCC('NV12')
|
|
|
|
IF_EQUAL_RETURN(guid, MFVideoFormat_P010); // FCC('P010')
|
|
|
|
IF_EQUAL_RETURN(guid, MFVideoFormat_P016); // FCC('P016')
|
|
|
|
IF_EQUAL_RETURN(guid, MFVideoFormat_P210); // FCC('P210')
|
|
|
|
IF_EQUAL_RETURN(guid, MFVideoFormat_P216); // FCC('P216')
|
2013-04-03 18:48:23 +08:00
|
|
|
IF_EQUAL_RETURN(guid, MFVideoFormat_RGB24); // D3DFMT_R8G8B8
|
|
|
|
IF_EQUAL_RETURN(guid, MFVideoFormat_RGB32); // D3DFMT_X8R8G8B8
|
|
|
|
IF_EQUAL_RETURN(guid, MFVideoFormat_RGB555); // D3DFMT_X1R5G5B5
|
|
|
|
IF_EQUAL_RETURN(guid, MFVideoFormat_RGB565); // D3DFMT_R5G6B5
|
2013-04-03 09:01:20 +08:00
|
|
|
IF_EQUAL_RETURN(guid, MFVideoFormat_RGB8);
|
|
|
|
IF_EQUAL_RETURN(guid, MFVideoFormat_UYVY); // FCC('UYVY')
|
|
|
|
IF_EQUAL_RETURN(guid, MFVideoFormat_v210); // FCC('v210')
|
|
|
|
IF_EQUAL_RETURN(guid, MFVideoFormat_v410); // FCC('v410')
|
|
|
|
IF_EQUAL_RETURN(guid, MFVideoFormat_WMV1); // FCC('WMV1')
|
|
|
|
IF_EQUAL_RETURN(guid, MFVideoFormat_WMV2); // FCC('WMV2')
|
|
|
|
IF_EQUAL_RETURN(guid, MFVideoFormat_WMV3); // FCC('WMV3')
|
|
|
|
IF_EQUAL_RETURN(guid, MFVideoFormat_WVC1); // FCC('WVC1')
|
|
|
|
IF_EQUAL_RETURN(guid, MFVideoFormat_Y210); // FCC('Y210')
|
|
|
|
IF_EQUAL_RETURN(guid, MFVideoFormat_Y216); // FCC('Y216')
|
|
|
|
IF_EQUAL_RETURN(guid, MFVideoFormat_Y410); // FCC('Y410')
|
|
|
|
IF_EQUAL_RETURN(guid, MFVideoFormat_Y416); // FCC('Y416')
|
|
|
|
IF_EQUAL_RETURN(guid, MFVideoFormat_Y41P);
|
|
|
|
IF_EQUAL_RETURN(guid, MFVideoFormat_Y41T);
|
|
|
|
IF_EQUAL_RETURN(guid, MFVideoFormat_YUY2); // FCC('YUY2')
|
|
|
|
IF_EQUAL_RETURN(guid, MFVideoFormat_YV12); // FCC('YV12')
|
|
|
|
IF_EQUAL_RETURN(guid, MFVideoFormat_YVYU);
|
2013-04-03 18:48:23 +08:00
|
|
|
IF_EQUAL_RETURN(guid, MFAudioFormat_PCM); // WAVE_FORMAT_PCM
|
|
|
|
IF_EQUAL_RETURN(guid, MFAudioFormat_Float); // WAVE_FORMAT_IEEE_FLOAT
|
|
|
|
IF_EQUAL_RETURN(guid, MFAudioFormat_DTS); // WAVE_FORMAT_DTS
|
|
|
|
IF_EQUAL_RETURN(guid, MFAudioFormat_Dolby_AC3_SPDIF); // WAVE_FORMAT_DOLBY_AC3_SPDIF
|
|
|
|
IF_EQUAL_RETURN(guid, MFAudioFormat_DRM); // WAVE_FORMAT_DRM
|
|
|
|
IF_EQUAL_RETURN(guid, MFAudioFormat_WMAudioV8); // WAVE_FORMAT_WMAUDIO2
|
|
|
|
IF_EQUAL_RETURN(guid, MFAudioFormat_WMAudioV9); // WAVE_FORMAT_WMAUDIO3
|
|
|
|
IF_EQUAL_RETURN(guid, MFAudioFormat_WMAudio_Lossless); // WAVE_FORMAT_WMAUDIO_LOSSLESS
|
|
|
|
IF_EQUAL_RETURN(guid, MFAudioFormat_WMASPDIF); // WAVE_FORMAT_WMASPDIF
|
|
|
|
IF_EQUAL_RETURN(guid, MFAudioFormat_MSP1); // WAVE_FORMAT_WMAVOICE9
|
|
|
|
IF_EQUAL_RETURN(guid, MFAudioFormat_MP3); // WAVE_FORMAT_MPEGLAYER3
|
|
|
|
IF_EQUAL_RETURN(guid, MFAudioFormat_MPEG); // WAVE_FORMAT_MPEG
|
|
|
|
IF_EQUAL_RETURN(guid, MFAudioFormat_AAC); // WAVE_FORMAT_MPEG_HEAAC
|
|
|
|
IF_EQUAL_RETURN(guid, MFAudioFormat_ADTS); // WAVE_FORMAT_MPEG_ADTS_AAC
|
2013-04-03 09:01:20 +08:00
|
|
|
return NULL;
|
|
|
|
}
|
2013-05-22 19:21:23 +08:00
|
|
|
|
2013-04-03 09:01:20 +08:00
|
|
|
FormatReader::FormatReader(void)
|
|
|
|
{
|
|
|
|
}
|
2013-05-22 19:21:23 +08:00
|
|
|
|
2013-04-03 09:01:20 +08:00
|
|
|
MediaType FormatReader::Read(IMFMediaType *pType)
|
|
|
|
{
|
|
|
|
UINT32 count = 0;
|
|
|
|
HRESULT hr = S_OK;
|
|
|
|
MediaType out;
|
|
|
|
hr = pType->LockStore();
|
|
|
|
if (FAILED(hr))
|
|
|
|
{
|
|
|
|
return out;
|
|
|
|
}
|
|
|
|
hr = pType->GetCount(&count);
|
|
|
|
if (FAILED(hr))
|
|
|
|
{
|
|
|
|
return out;
|
|
|
|
}
|
|
|
|
for (UINT32 i = 0; i < count; i++)
|
|
|
|
{
|
|
|
|
hr = LogAttributeValueByIndexNew(pType, i, out);
|
|
|
|
if (FAILED(hr))
|
|
|
|
{
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
hr = pType->UnlockStore();
|
|
|
|
if (FAILED(hr))
|
|
|
|
{
|
|
|
|
return out;
|
|
|
|
}
|
|
|
|
return out;
|
|
|
|
}
|
2013-05-23 00:50:54 +08:00
|
|
|
|
2013-04-03 09:01:20 +08:00
|
|
|
FormatReader::~FormatReader(void)
|
|
|
|
{
|
|
|
|
}
|
2013-04-16 21:25:10 +08:00
|
|
|
|
2013-06-24 16:10:18 +08:00
|
|
|
#define CHECK_HR(x) if (FAILED(x)) { goto done; }
|
2013-04-16 21:25:10 +08:00
|
|
|
|
Update cap_msmf.cpp
Add support for WinRT in the MF capture framework by removing the disallowed calls to enumerate devices and create a sample grabber sink and adding framework for the MediaCapture interface and a custom sink which interfaces with the sample grabber callback interface. The change requires discussion for making it completely functional as redundancy is required given that if the source is a video file, the old code pathways must be used. Otherwise all IMFMediaSession, IMFMediaSource, and IMFActivate code must use a MediaCapture code path and all sink code must use the CMediaSink custom sink.
Support for the custom sink is extended to non-WinRT not for compatibility as Windows Vista client is a minimum regardless, but because it offers more flexibility, could be faster and is able to be used as an optionally different code path during sink creation based on a future configuration parameter.
My discussion and proposal to finish this change:
Devices are so easily enumerated through WinRT Windows.Devices namespace that wrapping the calls in a library is quite a chore for little benefit though to get the various modes and formats could still be a worthwhile project. For now conditional compilation to remove videodevices and any offending non-video file related activity in videodevice. In my opinion, this is a different , far less fundamental and important change which can possibly be done as a future project and also much more easily implemented in C++/CX.
ImageGrabber has the IMFSampleGrabberSinkCallback replaced with a base class (SharedSampleGrabber) which also be is base class for ImageGrabberRT. This change is necessary as the custom sink does not require a thread to pump events which is done through MediaCapture already. IMFSampleGrabberSinkCallback is the common element between both models and that piece can be shared. Initializing the new ImageGrabberRT is as simple as passing an already initialized MediaCapture object and any video format/encoding parameters.
The concurrency event is necessary to wait for completion and is the way the underlying, IAsyncAction wrappers in the task library work as well. Native WIN32 event objects would be an option if HAVE_CONCURRENCY is not defined. I could even imagine doing it with sleep/thread yield and InterlockedCompareExchange yet I am not enthusiastic about that approach either. Since there is a specific compiler HAVE_ for concurrency, I do not like pulling it in though I think for WinRT it is safe to say we will always have it available though should probably conditionally compile with the Interlocked option as WIN32 events would require HAVE_WIN32.
It looks like C++/CX cannot be used for the IMediaExtension sink (which should not be a problem) as using COM objects requires WRL and though deriving from IMediaExtension can be done, there is little purpose without COM. Objects from C++/CX can be swapped to interact with objects from native C++ as Inspectable* can reinterpret_cast to the ref object IInspectable^ and vice-versa. A solution to the COM class with C++/CX would be great so we could have dual support. Also without #define for every WRL object in use, the code will get quite muddy given that the */^ would need to be ifdef'd everywhere.
Update cap_msmf.cpp
Fixed bugs and completed the change. I believe the new classes need to be moved to a header file as the file has become to large and more classes need to be added for handling all the asynchronous problems (one wrapping IAsyncAction in a task and another for making a task out of IAsyncAction). Unfortunately, blocking on the UI thread is not an option in WinRT so a synchronous architecture is considered "illegal" by Microsoft's standards even if implementable (C++/CX ppltasks library throws errors if you try it). Worse, either by design or a bug in the MF MediaCapture class with Custom Sinks causes a crash if stop/start previewing without reinitializing (spPreferredPreviewMediaType is fatally nulled). After decompiling Windows.Media.dll, I worked around this in my own projects by using an activate-able custom sink ID which strangely assigns 1 to this pointer allowing it to be reinitialized in what can only be described as a hack by Microsoft. This would add additional overhead to the project to implement especially for static libraries as it requires IDL/DLL exporting followed by manifest declaration. Better to document that it is not supported.
Furthermore, an additional class for IMFAttributes should be implemented to make clean architecture for passing around attributes as opposed to directly calling non-COM interface calls on the objects and making use of SetProperties which would also be a set up for an object that uses the RuntimeClass activation ID.
The remaining changes are not difficult and will be complete soon along with debug tracing messages.
Update cap_msmf.cpp
Create cap_msmf.h
Update cap_msmf.cpp
Update cap_msmf.h
Update cap_msmf.cpp
Update cap_msmf.h
Update and rename cap_msmf.h to cap_msmf.hpp
Update cap_msmf.cpp
Update CMakeLists.txt
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.cpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Successful test - samples are grabbed
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Create ppltasks_winrt.h
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update ppltasks_winrt.h
Library updated and cleaned up with comments, marshaling, exceptions and linker settings
Update ppltasks_winrt.h
Fixed trailing whitespace
2013-12-14 16:53:30 +08:00
|
|
|
ImageGrabberCallback::ImageGrabberCallback(bool synchronous):
|
2013-05-14 20:17:34 +08:00
|
|
|
m_cRef(1),
|
|
|
|
ig_RIE(true),
|
|
|
|
ig_Close(false),
|
2013-05-15 20:12:25 +08:00
|
|
|
ig_Synchronous(synchronous),
|
2013-05-22 19:21:23 +08:00
|
|
|
ig_hFrameReady(synchronous ? CreateEvent(NULL, FALSE, FALSE, NULL): 0),
|
|
|
|
ig_hFrameGrabbed(synchronous ? CreateEvent(NULL, FALSE, TRUE, NULL): 0),
|
|
|
|
ig_hFinish(CreateEvent(NULL, TRUE, FALSE, NULL))
|
2013-05-14 20:17:34 +08:00
|
|
|
{}
|
2013-04-16 21:25:10 +08:00
|
|
|
|
Update cap_msmf.cpp
Add support for WinRT in the MF capture framework by removing the disallowed calls to enumerate devices and create a sample grabber sink and adding framework for the MediaCapture interface and a custom sink which interfaces with the sample grabber callback interface. The change requires discussion for making it completely functional as redundancy is required given that if the source is a video file, the old code pathways must be used. Otherwise all IMFMediaSession, IMFMediaSource, and IMFActivate code must use a MediaCapture code path and all sink code must use the CMediaSink custom sink.
Support for the custom sink is extended to non-WinRT not for compatibility as Windows Vista client is a minimum regardless, but because it offers more flexibility, could be faster and is able to be used as an optionally different code path during sink creation based on a future configuration parameter.
My discussion and proposal to finish this change:
Devices are so easily enumerated through WinRT Windows.Devices namespace that wrapping the calls in a library is quite a chore for little benefit though to get the various modes and formats could still be a worthwhile project. For now conditional compilation to remove videodevices and any offending non-video file related activity in videodevice. In my opinion, this is a different , far less fundamental and important change which can possibly be done as a future project and also much more easily implemented in C++/CX.
ImageGrabber has the IMFSampleGrabberSinkCallback replaced with a base class (SharedSampleGrabber) which also be is base class for ImageGrabberRT. This change is necessary as the custom sink does not require a thread to pump events which is done through MediaCapture already. IMFSampleGrabberSinkCallback is the common element between both models and that piece can be shared. Initializing the new ImageGrabberRT is as simple as passing an already initialized MediaCapture object and any video format/encoding parameters.
The concurrency event is necessary to wait for completion and is the way the underlying, IAsyncAction wrappers in the task library work as well. Native WIN32 event objects would be an option if HAVE_CONCURRENCY is not defined. I could even imagine doing it with sleep/thread yield and InterlockedCompareExchange yet I am not enthusiastic about that approach either. Since there is a specific compiler HAVE_ for concurrency, I do not like pulling it in though I think for WinRT it is safe to say we will always have it available though should probably conditionally compile with the Interlocked option as WIN32 events would require HAVE_WIN32.
It looks like C++/CX cannot be used for the IMediaExtension sink (which should not be a problem) as using COM objects requires WRL and though deriving from IMediaExtension can be done, there is little purpose without COM. Objects from C++/CX can be swapped to interact with objects from native C++ as Inspectable* can reinterpret_cast to the ref object IInspectable^ and vice-versa. A solution to the COM class with C++/CX would be great so we could have dual support. Also without #define for every WRL object in use, the code will get quite muddy given that the */^ would need to be ifdef'd everywhere.
Update cap_msmf.cpp
Fixed bugs and completed the change. I believe the new classes need to be moved to a header file as the file has become to large and more classes need to be added for handling all the asynchronous problems (one wrapping IAsyncAction in a task and another for making a task out of IAsyncAction). Unfortunately, blocking on the UI thread is not an option in WinRT so a synchronous architecture is considered "illegal" by Microsoft's standards even if implementable (C++/CX ppltasks library throws errors if you try it). Worse, either by design or a bug in the MF MediaCapture class with Custom Sinks causes a crash if stop/start previewing without reinitializing (spPreferredPreviewMediaType is fatally nulled). After decompiling Windows.Media.dll, I worked around this in my own projects by using an activate-able custom sink ID which strangely assigns 1 to this pointer allowing it to be reinitialized in what can only be described as a hack by Microsoft. This would add additional overhead to the project to implement especially for static libraries as it requires IDL/DLL exporting followed by manifest declaration. Better to document that it is not supported.
Furthermore, an additional class for IMFAttributes should be implemented to make clean architecture for passing around attributes as opposed to directly calling non-COM interface calls on the objects and making use of SetProperties which would also be a set up for an object that uses the RuntimeClass activation ID.
The remaining changes are not difficult and will be complete soon along with debug tracing messages.
Update cap_msmf.cpp
Create cap_msmf.h
Update cap_msmf.cpp
Update cap_msmf.h
Update cap_msmf.cpp
Update cap_msmf.h
Update and rename cap_msmf.h to cap_msmf.hpp
Update cap_msmf.cpp
Update CMakeLists.txt
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.cpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Successful test - samples are grabbed
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Create ppltasks_winrt.h
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update ppltasks_winrt.h
Library updated and cleaned up with comments, marshaling, exceptions and linker settings
Update ppltasks_winrt.h
Fixed trailing whitespace
2013-12-14 16:53:30 +08:00
|
|
|
ImageGrabber::ImageGrabber(unsigned int deviceID, bool synchronous):
|
|
|
|
ImageGrabberCallback(synchronous),
|
|
|
|
ig_DeviceID(deviceID),
|
|
|
|
ig_pSource(NULL),
|
|
|
|
ig_pSession(NULL),
|
|
|
|
ig_pTopology(NULL)
|
|
|
|
{}
|
|
|
|
|
2013-04-03 09:01:20 +08:00
|
|
|
ImageGrabber::~ImageGrabber(void)
|
|
|
|
{
|
|
|
|
if (ig_pSession)
|
|
|
|
{
|
|
|
|
ig_pSession->Shutdown();
|
|
|
|
}
|
2013-05-14 20:17:34 +08:00
|
|
|
|
2013-05-22 19:21:23 +08:00
|
|
|
CloseHandle(ig_hFinish);
|
|
|
|
|
2013-05-15 20:12:25 +08:00
|
|
|
if (ig_Synchronous)
|
|
|
|
{
|
|
|
|
CloseHandle(ig_hFrameReady);
|
|
|
|
CloseHandle(ig_hFrameGrabbed);
|
|
|
|
}
|
2013-05-14 20:17:34 +08:00
|
|
|
|
|
|
|
SafeRelease(&ig_pSession);
|
|
|
|
SafeRelease(&ig_pTopology);
|
2013-04-03 09:01:20 +08:00
|
|
|
DebugPrintOut *DPO = &DebugPrintOut::getInstance();
|
2013-05-14 20:17:34 +08:00
|
|
|
|
Update cap_msmf.cpp
Add support for WinRT in the MF capture framework by removing the disallowed calls to enumerate devices and create a sample grabber sink and adding framework for the MediaCapture interface and a custom sink which interfaces with the sample grabber callback interface. The change requires discussion for making it completely functional as redundancy is required given that if the source is a video file, the old code pathways must be used. Otherwise all IMFMediaSession, IMFMediaSource, and IMFActivate code must use a MediaCapture code path and all sink code must use the CMediaSink custom sink.
Support for the custom sink is extended to non-WinRT not for compatibility as Windows Vista client is a minimum regardless, but because it offers more flexibility, could be faster and is able to be used as an optionally different code path during sink creation based on a future configuration parameter.
My discussion and proposal to finish this change:
Devices are so easily enumerated through WinRT Windows.Devices namespace that wrapping the calls in a library is quite a chore for little benefit though to get the various modes and formats could still be a worthwhile project. For now conditional compilation to remove videodevices and any offending non-video file related activity in videodevice. In my opinion, this is a different , far less fundamental and important change which can possibly be done as a future project and also much more easily implemented in C++/CX.
ImageGrabber has the IMFSampleGrabberSinkCallback replaced with a base class (SharedSampleGrabber) which also be is base class for ImageGrabberRT. This change is necessary as the custom sink does not require a thread to pump events which is done through MediaCapture already. IMFSampleGrabberSinkCallback is the common element between both models and that piece can be shared. Initializing the new ImageGrabberRT is as simple as passing an already initialized MediaCapture object and any video format/encoding parameters.
The concurrency event is necessary to wait for completion and is the way the underlying, IAsyncAction wrappers in the task library work as well. Native WIN32 event objects would be an option if HAVE_CONCURRENCY is not defined. I could even imagine doing it with sleep/thread yield and InterlockedCompareExchange yet I am not enthusiastic about that approach either. Since there is a specific compiler HAVE_ for concurrency, I do not like pulling it in though I think for WinRT it is safe to say we will always have it available though should probably conditionally compile with the Interlocked option as WIN32 events would require HAVE_WIN32.
It looks like C++/CX cannot be used for the IMediaExtension sink (which should not be a problem) as using COM objects requires WRL and though deriving from IMediaExtension can be done, there is little purpose without COM. Objects from C++/CX can be swapped to interact with objects from native C++ as Inspectable* can reinterpret_cast to the ref object IInspectable^ and vice-versa. A solution to the COM class with C++/CX would be great so we could have dual support. Also without #define for every WRL object in use, the code will get quite muddy given that the */^ would need to be ifdef'd everywhere.
Update cap_msmf.cpp
Fixed bugs and completed the change. I believe the new classes need to be moved to a header file as the file has become to large and more classes need to be added for handling all the asynchronous problems (one wrapping IAsyncAction in a task and another for making a task out of IAsyncAction). Unfortunately, blocking on the UI thread is not an option in WinRT so a synchronous architecture is considered "illegal" by Microsoft's standards even if implementable (C++/CX ppltasks library throws errors if you try it). Worse, either by design or a bug in the MF MediaCapture class with Custom Sinks causes a crash if stop/start previewing without reinitializing (spPreferredPreviewMediaType is fatally nulled). After decompiling Windows.Media.dll, I worked around this in my own projects by using an activate-able custom sink ID which strangely assigns 1 to this pointer allowing it to be reinitialized in what can only be described as a hack by Microsoft. This would add additional overhead to the project to implement especially for static libraries as it requires IDL/DLL exporting followed by manifest declaration. Better to document that it is not supported.
Furthermore, an additional class for IMFAttributes should be implemented to make clean architecture for passing around attributes as opposed to directly calling non-COM interface calls on the objects and making use of SetProperties which would also be a set up for an object that uses the RuntimeClass activation ID.
The remaining changes are not difficult and will be complete soon along with debug tracing messages.
Update cap_msmf.cpp
Create cap_msmf.h
Update cap_msmf.cpp
Update cap_msmf.h
Update cap_msmf.cpp
Update cap_msmf.h
Update and rename cap_msmf.h to cap_msmf.hpp
Update cap_msmf.cpp
Update CMakeLists.txt
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.cpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Successful test - samples are grabbed
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Create ppltasks_winrt.h
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update ppltasks_winrt.h
Library updated and cleaned up with comments, marshaling, exceptions and linker settings
Update ppltasks_winrt.h
Fixed trailing whitespace
2013-12-14 16:53:30 +08:00
|
|
|
DPO->printOut(L"IMAGEGRABBER VIDEODEVICE %i: Destroying instance of the ImageGrabber class\n", ig_DeviceID);
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef HAVE_WINRT
|
|
|
|
|
|
|
|
ImageGrabberWinRT::ImageGrabberWinRT(bool synchronous):
|
|
|
|
ImageGrabberCallback(synchronous),
|
|
|
|
ig_pMediaSink(NULL)
|
|
|
|
{
|
|
|
|
ig_pMedCapSource = nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
ImageGrabberWinRT::~ImageGrabberWinRT(void)
|
|
|
|
{
|
|
|
|
//stop must already be performed and complete by object owner
|
|
|
|
if (ig_pMediaSink != NULL) {
|
|
|
|
((IMFMediaSink*)ig_pMediaSink)->Shutdown();
|
|
|
|
}
|
|
|
|
SafeRelease(&ig_pMediaSink);
|
|
|
|
RELEASE_AGILE_WRL(ig_pMedCapSource)
|
|
|
|
|
|
|
|
CloseHandle(ig_hFinish);
|
|
|
|
|
|
|
|
if (ig_Synchronous)
|
|
|
|
{
|
|
|
|
CloseHandle(ig_hFrameReady);
|
|
|
|
CloseHandle(ig_hFrameGrabbed);
|
|
|
|
}
|
|
|
|
|
|
|
|
DebugPrintOut *DPO = &DebugPrintOut::getInstance();
|
|
|
|
|
|
|
|
DPO->printOut(L"IMAGEGRABBER VIDEODEVICE: Destroying instance of the ImageGrabberWinRT class\n");
|
|
|
|
}
|
|
|
|
|
|
|
|
HRESULT ImageGrabberWinRT::initImageGrabber(MAKE_WRL_REF(_MediaCapture) pSource,
|
|
|
|
GUID VideoFormat)
|
|
|
|
{
|
|
|
|
HRESULT hr;
|
|
|
|
MAKE_WRL_OBJ(_VideoDeviceController) pDevCont;
|
|
|
|
WRL_PROP_GET(pSource, VideoDeviceController, pDevCont, hr)
|
|
|
|
if (FAILED(hr)) return hr;
|
|
|
|
GET_WRL_MEDIA_DEVICE_CONTROLLER(pDevCont, pMedDevCont, hr)
|
|
|
|
if (FAILED(hr)) return hr;
|
|
|
|
MAKE_WRL_OBJ(_MediaEncodingProperties) pMedEncProps;
|
|
|
|
WRL_METHOD(pMedDevCont, GetMediaStreamProperties, pMedEncProps, hr, _VideoPreview)
|
|
|
|
if (FAILED(hr)) return hr;
|
|
|
|
GET_WRL_VIDEO_ENCODING_PROPERTIES(pMedEncProps, pVidProps, hr);
|
|
|
|
if (FAILED(hr)) return hr;
|
|
|
|
ComPtr<IMFMediaType> pType = NULL;
|
|
|
|
hr = MediaSink::ConvertPropertiesToMediaType(DEREF_AS_NATIVE_WRL_OBJ(ABI::Windows::Media::MediaProperties::IMediaEncodingProperties, pMedEncProps), &pType);
|
|
|
|
if (FAILED(hr)) return hr;
|
|
|
|
MediaType MT = FormatReader::Read(pType.Get());
|
|
|
|
unsigned int sizeRawImage = 0;
|
|
|
|
if(VideoFormat == MFVideoFormat_RGB24)
|
|
|
|
{
|
|
|
|
sizeRawImage = MT.MF_MT_FRAME_SIZE * 3;
|
|
|
|
}
|
|
|
|
else if(VideoFormat == MFVideoFormat_RGB32)
|
|
|
|
{
|
|
|
|
sizeRawImage = MT.MF_MT_FRAME_SIZE * 4;
|
|
|
|
}
|
|
|
|
sizeRawImage = MT.MF_MT_SAMPLE_SIZE;
|
|
|
|
CHECK_HR(hr = RawImage::CreateInstance(&ig_RIFirst, sizeRawImage));
|
|
|
|
CHECK_HR(hr = RawImage::CreateInstance(&ig_RISecond, sizeRawImage));
|
|
|
|
ig_RIOut = ig_RISecond;
|
|
|
|
ig_pMedCapSource = pSource;
|
|
|
|
done:
|
|
|
|
return hr;
|
|
|
|
}
|
|
|
|
|
|
|
|
HRESULT ImageGrabberWinRT::stopGrabbing(MAKE_WRL_REF(_AsyncAction)* action)
|
|
|
|
{
|
|
|
|
HRESULT hr = S_OK;
|
|
|
|
if (ig_pMedCapSource != nullptr) {
|
|
|
|
GET_WRL_VIDEO_PREVIEW(DEREF_AGILE_WRL_OBJ(ig_pMedCapSource), imedPrevCap, hr);
|
|
|
|
if (FAILED(hr)) return hr;
|
|
|
|
MAKE_WRL_REF(_AsyncAction) pAction;
|
|
|
|
WRL_METHOD_BASE(imedPrevCap, StopPreviewAsync, pAction, hr)
|
|
|
|
if (SUCCEEDED(hr)) {
|
|
|
|
SAVE_CURRENT_CONTEXT(context);
|
|
|
|
*action = reinterpret_cast<MAKE_WRL_REF(_AsyncAction)>(BEGIN_CREATE_ASYNC(pAction, context, this)
|
|
|
|
HRESULT hr;
|
|
|
|
DO_ACTION_SYNCHRONOUSLY(hr, pAction, context);
|
|
|
|
SafeRelease(&ig_pMediaSink);
|
|
|
|
SetEvent(ig_hFinish);
|
|
|
|
END_CREATE_ASYNC(hr));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return hr;
|
|
|
|
}
|
|
|
|
|
|
|
|
HRESULT ImageGrabberWinRT::startGrabbing(MAKE_WRL_REF(_AsyncAction)* action)
|
|
|
|
{
|
|
|
|
HRESULT hr = S_OK;
|
|
|
|
GET_WRL_VIDEO_PREVIEW(DEREF_AGILE_WRL_OBJ(ig_pMedCapSource), imedPrevCap, hr);
|
|
|
|
if (FAILED(hr)) return hr;
|
|
|
|
ACTIVATE_OBJ(RuntimeClass_Windows_Foundation_Collections_PropertySet, MAKE_WRL_OBJ(_PropertySet), pSet, hr)
|
|
|
|
if (FAILED(hr)) return hr;
|
|
|
|
GET_WRL_MAP(pSet, spSetting, hr)
|
|
|
|
if (FAILED(hr)) return hr;
|
|
|
|
ACTIVATE_STATIC_OBJ(RuntimeClass_Windows_Foundation_PropertyValue, MAKE_WRL_OBJ(_PropertyValueStatics), spPropVal, hr)
|
|
|
|
if (FAILED(hr)) return hr;
|
|
|
|
_ObjectObj pVal;
|
|
|
|
boolean bReplaced;
|
|
|
|
WRL_METHOD(spPropVal, CreateUInt32, pVal, hr, (unsigned int)_VideoPreview)
|
|
|
|
if (FAILED(hr)) return hr;
|
|
|
|
WRL_METHOD(spSetting, Insert, bReplaced, hr, DEREF_WRL_OBJ(_StringReference(MF_PROP_VIDTYPE)), DEREF_WRL_OBJ(pVal))
|
|
|
|
if (FAILED(hr)) return hr;
|
|
|
|
WRL_METHOD(spSetting, Insert, bReplaced, hr, DEREF_WRL_OBJ(_StringReference(MF_PROP_SAMPLEGRABBERCALLBACK)), reinterpret_cast<_Object>(this))
|
|
|
|
if (FAILED(hr)) return hr;
|
|
|
|
MAKE_WRL_OBJ(_VideoDeviceController) pDevCont;
|
|
|
|
WRL_PROP_GET(ig_pMedCapSource, VideoDeviceController, pDevCont, hr)
|
|
|
|
if (FAILED(hr)) return hr;
|
|
|
|
GET_WRL_MEDIA_DEVICE_CONTROLLER(pDevCont, pMedDevCont, hr)
|
|
|
|
if (FAILED(hr)) return hr;
|
|
|
|
MAKE_WRL_OBJ(_MediaEncodingProperties) pMedEncProps;
|
|
|
|
WRL_METHOD(pMedDevCont, GetMediaStreamProperties, pMedEncProps, hr, _VideoPreview)
|
|
|
|
if (FAILED(hr)) return hr;
|
|
|
|
GET_WRL_VIDEO_ENCODING_PROPERTIES(pMedEncProps, pVidProps, hr);
|
|
|
|
if (FAILED(hr)) return hr;
|
|
|
|
ACTIVATE_OBJ(RuntimeClass_Windows_Media_MediaProperties_MediaEncodingProfile, MAKE_WRL_OBJ(_MediaEncodingProfile), pEncProps, hr)
|
|
|
|
if (FAILED(hr)) return hr;
|
|
|
|
WRL_PROP_PUT(pEncProps, Video, DEREF_WRL_OBJ(pVidProps), hr)
|
|
|
|
if (FAILED(hr)) return hr;
|
|
|
|
WRL_METHOD(spSetting, Insert, bReplaced, hr, DEREF_WRL_OBJ(_StringReference(MF_PROP_VIDENCPROPS)), DEREF_WRL_OBJ(pVidProps))
|
|
|
|
if (SUCCEEDED(hr)) {
|
|
|
|
//can start/stop multiple times with same MediaCapture object if using activatable class
|
|
|
|
WRL_METHOD(imedPrevCap, _StartPreviewToCustomSinkIdAsync, *action, hr, DEREF_WRL_OBJ(pEncProps), DEREF_WRL_OBJ(_StringReference(RuntimeClass_CV_MediaSink)), DEREF_WRL_OBJ(pSet))
|
|
|
|
if (FAILED(hr) && hr == REGDB_E_CLASSNOTREG) {
|
|
|
|
hr = Microsoft::WRL::Make<MediaSink>().CopyTo(&ig_pMediaSink);
|
|
|
|
if (FAILED(hr)) return hr;
|
|
|
|
hr = ((ABI::Windows::Media::IMediaExtension*)ig_pMediaSink)->SetProperties(DEREF_AS_NATIVE_WRL_OBJ(ABI::Windows::Foundation::Collections::IPropertySet, pSet));
|
|
|
|
if (FAILED(hr)) return hr;
|
|
|
|
WRL_METHOD(imedPrevCap, StartPreviewToCustomSinkAsync, *action, hr, DEREF_WRL_OBJ(pEncProps), reinterpret_cast<MAKE_WRL_REF(_MediaExtension)>(ig_pMediaSink))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return hr;
|
|
|
|
}
|
|
|
|
|
|
|
|
HRESULT ImageGrabberWinRT::CreateInstance(ImageGrabberWinRT **ppIG, bool synchronous)
|
|
|
|
{
|
|
|
|
*ppIG = Microsoft::WRL::Make<ImageGrabberWinRT>(synchronous).Detach();
|
|
|
|
if (ppIG == NULL)
|
|
|
|
{
|
|
|
|
return E_OUTOFMEMORY;
|
|
|
|
}
|
|
|
|
DebugPrintOut *DPO = &DebugPrintOut::getInstance();
|
|
|
|
DPO->printOut(L"IMAGEGRABBER VIDEODEVICE: Creating instance of ImageGrabberWinRT\n");
|
|
|
|
return S_OK;
|
2013-04-03 09:01:20 +08:00
|
|
|
}
|
Update cap_msmf.cpp
Add support for WinRT in the MF capture framework by removing the disallowed calls to enumerate devices and create a sample grabber sink and adding framework for the MediaCapture interface and a custom sink which interfaces with the sample grabber callback interface. The change requires discussion for making it completely functional as redundancy is required given that if the source is a video file, the old code pathways must be used. Otherwise all IMFMediaSession, IMFMediaSource, and IMFActivate code must use a MediaCapture code path and all sink code must use the CMediaSink custom sink.
Support for the custom sink is extended to non-WinRT not for compatibility as Windows Vista client is a minimum regardless, but because it offers more flexibility, could be faster and is able to be used as an optionally different code path during sink creation based on a future configuration parameter.
My discussion and proposal to finish this change:
Devices are so easily enumerated through WinRT Windows.Devices namespace that wrapping the calls in a library is quite a chore for little benefit though to get the various modes and formats could still be a worthwhile project. For now conditional compilation to remove videodevices and any offending non-video file related activity in videodevice. In my opinion, this is a different , far less fundamental and important change which can possibly be done as a future project and also much more easily implemented in C++/CX.
ImageGrabber has the IMFSampleGrabberSinkCallback replaced with a base class (SharedSampleGrabber) which also be is base class for ImageGrabberRT. This change is necessary as the custom sink does not require a thread to pump events which is done through MediaCapture already. IMFSampleGrabberSinkCallback is the common element between both models and that piece can be shared. Initializing the new ImageGrabberRT is as simple as passing an already initialized MediaCapture object and any video format/encoding parameters.
The concurrency event is necessary to wait for completion and is the way the underlying, IAsyncAction wrappers in the task library work as well. Native WIN32 event objects would be an option if HAVE_CONCURRENCY is not defined. I could even imagine doing it with sleep/thread yield and InterlockedCompareExchange yet I am not enthusiastic about that approach either. Since there is a specific compiler HAVE_ for concurrency, I do not like pulling it in though I think for WinRT it is safe to say we will always have it available though should probably conditionally compile with the Interlocked option as WIN32 events would require HAVE_WIN32.
It looks like C++/CX cannot be used for the IMediaExtension sink (which should not be a problem) as using COM objects requires WRL and though deriving from IMediaExtension can be done, there is little purpose without COM. Objects from C++/CX can be swapped to interact with objects from native C++ as Inspectable* can reinterpret_cast to the ref object IInspectable^ and vice-versa. A solution to the COM class with C++/CX would be great so we could have dual support. Also without #define for every WRL object in use, the code will get quite muddy given that the */^ would need to be ifdef'd everywhere.
Update cap_msmf.cpp
Fixed bugs and completed the change. I believe the new classes need to be moved to a header file as the file has become to large and more classes need to be added for handling all the asynchronous problems (one wrapping IAsyncAction in a task and another for making a task out of IAsyncAction). Unfortunately, blocking on the UI thread is not an option in WinRT so a synchronous architecture is considered "illegal" by Microsoft's standards even if implementable (C++/CX ppltasks library throws errors if you try it). Worse, either by design or a bug in the MF MediaCapture class with Custom Sinks causes a crash if stop/start previewing without reinitializing (spPreferredPreviewMediaType is fatally nulled). After decompiling Windows.Media.dll, I worked around this in my own projects by using an activate-able custom sink ID which strangely assigns 1 to this pointer allowing it to be reinitialized in what can only be described as a hack by Microsoft. This would add additional overhead to the project to implement especially for static libraries as it requires IDL/DLL exporting followed by manifest declaration. Better to document that it is not supported.
Furthermore, an additional class for IMFAttributes should be implemented to make clean architecture for passing around attributes as opposed to directly calling non-COM interface calls on the objects and making use of SetProperties which would also be a set up for an object that uses the RuntimeClass activation ID.
The remaining changes are not difficult and will be complete soon along with debug tracing messages.
Update cap_msmf.cpp
Create cap_msmf.h
Update cap_msmf.cpp
Update cap_msmf.h
Update cap_msmf.cpp
Update cap_msmf.h
Update and rename cap_msmf.h to cap_msmf.hpp
Update cap_msmf.cpp
Update CMakeLists.txt
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.cpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Successful test - samples are grabbed
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Create ppltasks_winrt.h
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update ppltasks_winrt.h
Library updated and cleaned up with comments, marshaling, exceptions and linker settings
Update ppltasks_winrt.h
Fixed trailing whitespace
2013-12-14 16:53:30 +08:00
|
|
|
#endif
|
2013-04-16 21:25:10 +08:00
|
|
|
|
2013-04-03 09:01:20 +08:00
|
|
|
HRESULT ImageGrabber::initImageGrabber(IMFMediaSource *pSource, GUID VideoFormat)
|
|
|
|
{
|
2013-05-15 21:09:03 +08:00
|
|
|
ComPtr<IMFActivate> pSinkActivate = NULL;
|
|
|
|
ComPtr<IMFMediaType> pType = NULL;
|
|
|
|
ComPtr<IMFPresentationDescriptor> pPD = NULL;
|
|
|
|
ComPtr<IMFStreamDescriptor> pSD = NULL;
|
|
|
|
ComPtr<IMFMediaTypeHandler> pHandler = NULL;
|
|
|
|
ComPtr<IMFMediaType> pCurrentType = NULL;
|
2013-04-03 09:01:20 +08:00
|
|
|
HRESULT hr = S_OK;
|
|
|
|
MediaType MT;
|
|
|
|
// Clean up.
|
|
|
|
if (ig_pSession)
|
|
|
|
{
|
|
|
|
ig_pSession->Shutdown();
|
|
|
|
}
|
|
|
|
SafeRelease(&ig_pSession);
|
|
|
|
SafeRelease(&ig_pTopology);
|
|
|
|
ig_pSource = pSource;
|
|
|
|
hr = pSource->CreatePresentationDescriptor(&pPD);
|
|
|
|
if (FAILED(hr))
|
2013-04-16 21:25:10 +08:00
|
|
|
{
|
2013-04-03 09:01:20 +08:00
|
|
|
goto err;
|
2013-04-16 21:25:10 +08:00
|
|
|
}
|
2013-04-03 09:01:20 +08:00
|
|
|
BOOL fSelected;
|
|
|
|
hr = pPD->GetStreamDescriptorByIndex(0, &fSelected, &pSD);
|
2013-04-16 21:25:10 +08:00
|
|
|
if (FAILED(hr)) {
|
2013-04-03 09:01:20 +08:00
|
|
|
goto err;
|
2013-04-16 21:25:10 +08:00
|
|
|
}
|
2013-04-03 09:01:20 +08:00
|
|
|
hr = pSD->GetMediaTypeHandler(&pHandler);
|
2013-04-16 21:25:10 +08:00
|
|
|
if (FAILED(hr)) {
|
2013-04-03 09:01:20 +08:00
|
|
|
goto err;
|
2013-04-16 21:25:10 +08:00
|
|
|
}
|
2013-04-03 09:01:20 +08:00
|
|
|
DWORD cTypes = 0;
|
|
|
|
hr = pHandler->GetMediaTypeCount(&cTypes);
|
2013-04-16 21:25:10 +08:00
|
|
|
if (FAILED(hr)) {
|
2013-04-03 09:01:20 +08:00
|
|
|
goto err;
|
2013-04-16 21:25:10 +08:00
|
|
|
}
|
2013-04-03 09:01:20 +08:00
|
|
|
if(cTypes > 0)
|
|
|
|
{
|
|
|
|
hr = pHandler->GetCurrentMediaType(&pCurrentType);
|
2013-04-16 21:25:10 +08:00
|
|
|
if (FAILED(hr)) {
|
2013-04-03 09:01:20 +08:00
|
|
|
goto err;
|
2013-04-16 21:25:10 +08:00
|
|
|
}
|
2013-05-15 21:09:03 +08:00
|
|
|
MT = FormatReader::Read(pCurrentType.Get());
|
2013-04-03 09:01:20 +08:00
|
|
|
}
|
|
|
|
err:
|
|
|
|
unsigned int sizeRawImage = 0;
|
|
|
|
if(VideoFormat == MFVideoFormat_RGB24)
|
|
|
|
{
|
|
|
|
sizeRawImage = MT.MF_MT_FRAME_SIZE * 3;
|
|
|
|
}
|
|
|
|
else if(VideoFormat == MFVideoFormat_RGB32)
|
|
|
|
{
|
|
|
|
sizeRawImage = MT.MF_MT_FRAME_SIZE * 4;
|
|
|
|
}
|
Update cap_msmf.cpp
Add support for WinRT in the MF capture framework by removing the disallowed calls to enumerate devices and create a sample grabber sink and adding framework for the MediaCapture interface and a custom sink which interfaces with the sample grabber callback interface. The change requires discussion for making it completely functional as redundancy is required given that if the source is a video file, the old code pathways must be used. Otherwise all IMFMediaSession, IMFMediaSource, and IMFActivate code must use a MediaCapture code path and all sink code must use the CMediaSink custom sink.
Support for the custom sink is extended to non-WinRT not for compatibility as Windows Vista client is a minimum regardless, but because it offers more flexibility, could be faster and is able to be used as an optionally different code path during sink creation based on a future configuration parameter.
My discussion and proposal to finish this change:
Devices are so easily enumerated through WinRT Windows.Devices namespace that wrapping the calls in a library is quite a chore for little benefit though to get the various modes and formats could still be a worthwhile project. For now conditional compilation to remove videodevices and any offending non-video file related activity in videodevice. In my opinion, this is a different , far less fundamental and important change which can possibly be done as a future project and also much more easily implemented in C++/CX.
ImageGrabber has the IMFSampleGrabberSinkCallback replaced with a base class (SharedSampleGrabber) which also be is base class for ImageGrabberRT. This change is necessary as the custom sink does not require a thread to pump events which is done through MediaCapture already. IMFSampleGrabberSinkCallback is the common element between both models and that piece can be shared. Initializing the new ImageGrabberRT is as simple as passing an already initialized MediaCapture object and any video format/encoding parameters.
The concurrency event is necessary to wait for completion and is the way the underlying, IAsyncAction wrappers in the task library work as well. Native WIN32 event objects would be an option if HAVE_CONCURRENCY is not defined. I could even imagine doing it with sleep/thread yield and InterlockedCompareExchange yet I am not enthusiastic about that approach either. Since there is a specific compiler HAVE_ for concurrency, I do not like pulling it in though I think for WinRT it is safe to say we will always have it available though should probably conditionally compile with the Interlocked option as WIN32 events would require HAVE_WIN32.
It looks like C++/CX cannot be used for the IMediaExtension sink (which should not be a problem) as using COM objects requires WRL and though deriving from IMediaExtension can be done, there is little purpose without COM. Objects from C++/CX can be swapped to interact with objects from native C++ as Inspectable* can reinterpret_cast to the ref object IInspectable^ and vice-versa. A solution to the COM class with C++/CX would be great so we could have dual support. Also without #define for every WRL object in use, the code will get quite muddy given that the */^ would need to be ifdef'd everywhere.
Update cap_msmf.cpp
Fixed bugs and completed the change. I believe the new classes need to be moved to a header file as the file has become to large and more classes need to be added for handling all the asynchronous problems (one wrapping IAsyncAction in a task and another for making a task out of IAsyncAction). Unfortunately, blocking on the UI thread is not an option in WinRT so a synchronous architecture is considered "illegal" by Microsoft's standards even if implementable (C++/CX ppltasks library throws errors if you try it). Worse, either by design or a bug in the MF MediaCapture class with Custom Sinks causes a crash if stop/start previewing without reinitializing (spPreferredPreviewMediaType is fatally nulled). After decompiling Windows.Media.dll, I worked around this in my own projects by using an activate-able custom sink ID which strangely assigns 1 to this pointer allowing it to be reinitialized in what can only be described as a hack by Microsoft. This would add additional overhead to the project to implement especially for static libraries as it requires IDL/DLL exporting followed by manifest declaration. Better to document that it is not supported.
Furthermore, an additional class for IMFAttributes should be implemented to make clean architecture for passing around attributes as opposed to directly calling non-COM interface calls on the objects and making use of SetProperties which would also be a set up for an object that uses the RuntimeClass activation ID.
The remaining changes are not difficult and will be complete soon along with debug tracing messages.
Update cap_msmf.cpp
Create cap_msmf.h
Update cap_msmf.cpp
Update cap_msmf.h
Update cap_msmf.cpp
Update cap_msmf.h
Update and rename cap_msmf.h to cap_msmf.hpp
Update cap_msmf.cpp
Update CMakeLists.txt
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.cpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Successful test - samples are grabbed
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Create ppltasks_winrt.h
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update ppltasks_winrt.h
Library updated and cleaned up with comments, marshaling, exceptions and linker settings
Update ppltasks_winrt.h
Fixed trailing whitespace
2013-12-14 16:53:30 +08:00
|
|
|
//sizeRawImage = MT.MF_MT_SAMPLE_SIZE;
|
2013-04-03 09:01:20 +08:00
|
|
|
CHECK_HR(hr = RawImage::CreateInstance(&ig_RIFirst, sizeRawImage));
|
|
|
|
CHECK_HR(hr = RawImage::CreateInstance(&ig_RISecond, sizeRawImage));
|
|
|
|
ig_RIOut = ig_RISecond;
|
|
|
|
// Configure the media type that the Sample Grabber will receive.
|
|
|
|
// Setting the major and subtype is usually enough for the topology loader
|
|
|
|
// to resolve the topology.
|
2013-05-15 21:09:03 +08:00
|
|
|
CHECK_HR(hr = MFCreateMediaType(pType.GetAddressOf()));
|
2013-04-03 09:01:20 +08:00
|
|
|
CHECK_HR(hr = pType->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Video));
|
|
|
|
CHECK_HR(hr = pType->SetGUID(MF_MT_SUBTYPE, VideoFormat));
|
|
|
|
// Create the sample grabber sink.
|
2013-05-15 21:09:03 +08:00
|
|
|
CHECK_HR(hr = MFCreateSampleGrabberSinkActivate(pType.Get(), this, pSinkActivate.GetAddressOf()));
|
2013-04-03 09:01:20 +08:00
|
|
|
// To run as fast as possible, set this attribute (requires Windows 7):
|
|
|
|
CHECK_HR(hr = pSinkActivate->SetUINT32(MF_SAMPLEGRABBERSINK_IGNORE_CLOCK, TRUE));
|
|
|
|
// Create the Media Session.
|
|
|
|
CHECK_HR(hr = MFCreateMediaSession(NULL, &ig_pSession));
|
|
|
|
// Create the topology.
|
2013-05-15 21:09:03 +08:00
|
|
|
CHECK_HR(hr = CreateTopology(pSource, pSinkActivate.Get(), &ig_pTopology));
|
2013-04-03 09:01:20 +08:00
|
|
|
done:
|
|
|
|
// Clean up.
|
|
|
|
if (FAILED(hr))
|
2013-04-03 18:48:23 +08:00
|
|
|
{
|
2013-04-03 09:01:20 +08:00
|
|
|
if (ig_pSession)
|
|
|
|
{
|
|
|
|
ig_pSession->Shutdown();
|
|
|
|
}
|
|
|
|
SafeRelease(&ig_pSession);
|
|
|
|
SafeRelease(&ig_pTopology);
|
|
|
|
}
|
|
|
|
return hr;
|
|
|
|
}
|
2013-04-16 21:25:10 +08:00
|
|
|
|
2013-04-03 09:01:20 +08:00
|
|
|
void ImageGrabber::stopGrabbing()
|
|
|
|
{
|
|
|
|
if(ig_pSession)
|
|
|
|
ig_pSession->Stop();
|
|
|
|
DebugPrintOut *DPO = &DebugPrintOut::getInstance();
|
|
|
|
DPO->printOut(L"IMAGEGRABBER VIDEODEVICE %i: Stopping of of grabbing of images\n", ig_DeviceID);
|
|
|
|
}
|
2013-04-16 21:25:10 +08:00
|
|
|
|
2013-04-03 09:01:20 +08:00
|
|
|
HRESULT ImageGrabber::startGrabbing(void)
|
|
|
|
{
|
Update cap_msmf.cpp
Add support for WinRT in the MF capture framework by removing the disallowed calls to enumerate devices and create a sample grabber sink and adding framework for the MediaCapture interface and a custom sink which interfaces with the sample grabber callback interface. The change requires discussion for making it completely functional as redundancy is required given that if the source is a video file, the old code pathways must be used. Otherwise all IMFMediaSession, IMFMediaSource, and IMFActivate code must use a MediaCapture code path and all sink code must use the CMediaSink custom sink.
Support for the custom sink is extended to non-WinRT not for compatibility as Windows Vista client is a minimum regardless, but because it offers more flexibility, could be faster and is able to be used as an optionally different code path during sink creation based on a future configuration parameter.
My discussion and proposal to finish this change:
Devices are so easily enumerated through WinRT Windows.Devices namespace that wrapping the calls in a library is quite a chore for little benefit though to get the various modes and formats could still be a worthwhile project. For now conditional compilation to remove videodevices and any offending non-video file related activity in videodevice. In my opinion, this is a different , far less fundamental and important change which can possibly be done as a future project and also much more easily implemented in C++/CX.
ImageGrabber has the IMFSampleGrabberSinkCallback replaced with a base class (SharedSampleGrabber) which also be is base class for ImageGrabberRT. This change is necessary as the custom sink does not require a thread to pump events which is done through MediaCapture already. IMFSampleGrabberSinkCallback is the common element between both models and that piece can be shared. Initializing the new ImageGrabberRT is as simple as passing an already initialized MediaCapture object and any video format/encoding parameters.
The concurrency event is necessary to wait for completion and is the way the underlying, IAsyncAction wrappers in the task library work as well. Native WIN32 event objects would be an option if HAVE_CONCURRENCY is not defined. I could even imagine doing it with sleep/thread yield and InterlockedCompareExchange yet I am not enthusiastic about that approach either. Since there is a specific compiler HAVE_ for concurrency, I do not like pulling it in though I think for WinRT it is safe to say we will always have it available though should probably conditionally compile with the Interlocked option as WIN32 events would require HAVE_WIN32.
It looks like C++/CX cannot be used for the IMediaExtension sink (which should not be a problem) as using COM objects requires WRL and though deriving from IMediaExtension can be done, there is little purpose without COM. Objects from C++/CX can be swapped to interact with objects from native C++ as Inspectable* can reinterpret_cast to the ref object IInspectable^ and vice-versa. A solution to the COM class with C++/CX would be great so we could have dual support. Also without #define for every WRL object in use, the code will get quite muddy given that the */^ would need to be ifdef'd everywhere.
Update cap_msmf.cpp
Fixed bugs and completed the change. I believe the new classes need to be moved to a header file as the file has become to large and more classes need to be added for handling all the asynchronous problems (one wrapping IAsyncAction in a task and another for making a task out of IAsyncAction). Unfortunately, blocking on the UI thread is not an option in WinRT so a synchronous architecture is considered "illegal" by Microsoft's standards even if implementable (C++/CX ppltasks library throws errors if you try it). Worse, either by design or a bug in the MF MediaCapture class with Custom Sinks causes a crash if stop/start previewing without reinitializing (spPreferredPreviewMediaType is fatally nulled). After decompiling Windows.Media.dll, I worked around this in my own projects by using an activate-able custom sink ID which strangely assigns 1 to this pointer allowing it to be reinitialized in what can only be described as a hack by Microsoft. This would add additional overhead to the project to implement especially for static libraries as it requires IDL/DLL exporting followed by manifest declaration. Better to document that it is not supported.
Furthermore, an additional class for IMFAttributes should be implemented to make clean architecture for passing around attributes as opposed to directly calling non-COM interface calls on the objects and making use of SetProperties which would also be a set up for an object that uses the RuntimeClass activation ID.
The remaining changes are not difficult and will be complete soon along with debug tracing messages.
Update cap_msmf.cpp
Create cap_msmf.h
Update cap_msmf.cpp
Update cap_msmf.h
Update cap_msmf.cpp
Update cap_msmf.h
Update and rename cap_msmf.h to cap_msmf.hpp
Update cap_msmf.cpp
Update CMakeLists.txt
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.cpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Successful test - samples are grabbed
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Create ppltasks_winrt.h
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update ppltasks_winrt.h
Library updated and cleaned up with comments, marshaling, exceptions and linker settings
Update ppltasks_winrt.h
Fixed trailing whitespace
2013-12-14 16:53:30 +08:00
|
|
|
HRESULT hr = S_OK;
|
2013-04-03 09:01:20 +08:00
|
|
|
DebugPrintOut *DPO = &DebugPrintOut::getInstance();
|
2013-05-15 21:09:03 +08:00
|
|
|
ComPtr<IMFMediaEvent> pEvent = NULL;
|
2013-04-03 09:01:20 +08:00
|
|
|
PROPVARIANT var;
|
|
|
|
PropVariantInit(&var);
|
2013-05-14 20:17:34 +08:00
|
|
|
hr = ig_pSession->SetTopology(0, ig_pTopology);
|
2013-04-03 09:01:20 +08:00
|
|
|
DPO->printOut(L"IMAGEGRABBER VIDEODEVICE %i: Start Grabbing of the images\n", ig_DeviceID);
|
2013-05-14 20:17:34 +08:00
|
|
|
hr = ig_pSession->Start(&GUID_NULL, &var);
|
2013-04-03 09:01:20 +08:00
|
|
|
for(;;)
|
|
|
|
{
|
|
|
|
HRESULT hrStatus = S_OK;
|
|
|
|
MediaEventType met;
|
|
|
|
if(!ig_pSession) break;
|
|
|
|
hr = ig_pSession->GetEvent(0, &pEvent);
|
|
|
|
if(!SUCCEEDED(hr))
|
|
|
|
{
|
|
|
|
hr = S_OK;
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
hr = pEvent->GetStatus(&hrStatus);
|
|
|
|
if(!SUCCEEDED(hr))
|
|
|
|
{
|
|
|
|
hr = S_OK;
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
hr = pEvent->GetType(&met);
|
|
|
|
if(!SUCCEEDED(hr))
|
|
|
|
{
|
|
|
|
hr = S_OK;
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
if (met == MESessionEnded)
|
2013-04-03 18:48:23 +08:00
|
|
|
{
|
2013-04-03 09:01:20 +08:00
|
|
|
DPO->printOut(L"IMAGEGRABBER VIDEODEVICE %i: MESessionEnded \n", ig_DeviceID);
|
|
|
|
ig_pSession->Stop();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (met == MESessionStopped)
|
|
|
|
{
|
|
|
|
DPO->printOut(L"IMAGEGRABBER VIDEODEVICE %i: MESessionStopped \n", ig_DeviceID);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (met == MEVideoCaptureDeviceRemoved)
|
|
|
|
{
|
|
|
|
DPO->printOut(L"IMAGEGRABBER VIDEODEVICE %i: MEVideoCaptureDeviceRemoved \n", ig_DeviceID);
|
2013-04-03 18:48:23 +08:00
|
|
|
break;
|
2013-04-03 09:01:20 +08:00
|
|
|
}
|
2013-05-19 04:04:31 +08:00
|
|
|
if ((met == MEError) || (met == MENonFatalError))
|
|
|
|
{
|
|
|
|
pEvent->GetStatus(&hrStatus);
|
|
|
|
DPO->printOut(L"IMAGEGRABBER VIDEODEVICE %i: MEError | MENonFatalError: %u\n", ig_DeviceID, hrStatus);
|
|
|
|
break;
|
|
|
|
}
|
2013-04-03 09:01:20 +08:00
|
|
|
}
|
2013-05-19 04:04:31 +08:00
|
|
|
DPO->printOut(L"IMAGEGRABBER VIDEODEVICE %i: Finish startGrabbing \n", ig_DeviceID);
|
2013-05-14 20:17:34 +08:00
|
|
|
|
2013-05-19 04:04:31 +08:00
|
|
|
done:
|
2013-05-22 19:21:23 +08:00
|
|
|
SetEvent(ig_hFinish);
|
2013-05-06 18:36:51 +08:00
|
|
|
|
2013-04-03 09:01:20 +08:00
|
|
|
return hr;
|
|
|
|
}
|
2013-04-16 21:25:10 +08:00
|
|
|
|
Update cap_msmf.cpp
Add support for WinRT in the MF capture framework by removing the disallowed calls to enumerate devices and create a sample grabber sink and adding framework for the MediaCapture interface and a custom sink which interfaces with the sample grabber callback interface. The change requires discussion for making it completely functional as redundancy is required given that if the source is a video file, the old code pathways must be used. Otherwise all IMFMediaSession, IMFMediaSource, and IMFActivate code must use a MediaCapture code path and all sink code must use the CMediaSink custom sink.
Support for the custom sink is extended to non-WinRT not for compatibility as Windows Vista client is a minimum regardless, but because it offers more flexibility, could be faster and is able to be used as an optionally different code path during sink creation based on a future configuration parameter.
My discussion and proposal to finish this change:
Devices are so easily enumerated through WinRT Windows.Devices namespace that wrapping the calls in a library is quite a chore for little benefit though to get the various modes and formats could still be a worthwhile project. For now conditional compilation to remove videodevices and any offending non-video file related activity in videodevice. In my opinion, this is a different , far less fundamental and important change which can possibly be done as a future project and also much more easily implemented in C++/CX.
ImageGrabber has the IMFSampleGrabberSinkCallback replaced with a base class (SharedSampleGrabber) which also be is base class for ImageGrabberRT. This change is necessary as the custom sink does not require a thread to pump events which is done through MediaCapture already. IMFSampleGrabberSinkCallback is the common element between both models and that piece can be shared. Initializing the new ImageGrabberRT is as simple as passing an already initialized MediaCapture object and any video format/encoding parameters.
The concurrency event is necessary to wait for completion and is the way the underlying, IAsyncAction wrappers in the task library work as well. Native WIN32 event objects would be an option if HAVE_CONCURRENCY is not defined. I could even imagine doing it with sleep/thread yield and InterlockedCompareExchange yet I am not enthusiastic about that approach either. Since there is a specific compiler HAVE_ for concurrency, I do not like pulling it in though I think for WinRT it is safe to say we will always have it available though should probably conditionally compile with the Interlocked option as WIN32 events would require HAVE_WIN32.
It looks like C++/CX cannot be used for the IMediaExtension sink (which should not be a problem) as using COM objects requires WRL and though deriving from IMediaExtension can be done, there is little purpose without COM. Objects from C++/CX can be swapped to interact with objects from native C++ as Inspectable* can reinterpret_cast to the ref object IInspectable^ and vice-versa. A solution to the COM class with C++/CX would be great so we could have dual support. Also without #define for every WRL object in use, the code will get quite muddy given that the */^ would need to be ifdef'd everywhere.
Update cap_msmf.cpp
Fixed bugs and completed the change. I believe the new classes need to be moved to a header file as the file has become to large and more classes need to be added for handling all the asynchronous problems (one wrapping IAsyncAction in a task and another for making a task out of IAsyncAction). Unfortunately, blocking on the UI thread is not an option in WinRT so a synchronous architecture is considered "illegal" by Microsoft's standards even if implementable (C++/CX ppltasks library throws errors if you try it). Worse, either by design or a bug in the MF MediaCapture class with Custom Sinks causes a crash if stop/start previewing without reinitializing (spPreferredPreviewMediaType is fatally nulled). After decompiling Windows.Media.dll, I worked around this in my own projects by using an activate-able custom sink ID which strangely assigns 1 to this pointer allowing it to be reinitialized in what can only be described as a hack by Microsoft. This would add additional overhead to the project to implement especially for static libraries as it requires IDL/DLL exporting followed by manifest declaration. Better to document that it is not supported.
Furthermore, an additional class for IMFAttributes should be implemented to make clean architecture for passing around attributes as opposed to directly calling non-COM interface calls on the objects and making use of SetProperties which would also be a set up for an object that uses the RuntimeClass activation ID.
The remaining changes are not difficult and will be complete soon along with debug tracing messages.
Update cap_msmf.cpp
Create cap_msmf.h
Update cap_msmf.cpp
Update cap_msmf.h
Update cap_msmf.cpp
Update cap_msmf.h
Update and rename cap_msmf.h to cap_msmf.hpp
Update cap_msmf.cpp
Update CMakeLists.txt
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.cpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Successful test - samples are grabbed
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Create ppltasks_winrt.h
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update ppltasks_winrt.h
Library updated and cleaned up with comments, marshaling, exceptions and linker settings
Update ppltasks_winrt.h
Fixed trailing whitespace
2013-12-14 16:53:30 +08:00
|
|
|
void ImageGrabberCallback::pauseGrabbing()
|
2013-05-14 20:17:34 +08:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
Update cap_msmf.cpp
Add support for WinRT in the MF capture framework by removing the disallowed calls to enumerate devices and create a sample grabber sink and adding framework for the MediaCapture interface and a custom sink which interfaces with the sample grabber callback interface. The change requires discussion for making it completely functional as redundancy is required given that if the source is a video file, the old code pathways must be used. Otherwise all IMFMediaSession, IMFMediaSource, and IMFActivate code must use a MediaCapture code path and all sink code must use the CMediaSink custom sink.
Support for the custom sink is extended to non-WinRT not for compatibility as Windows Vista client is a minimum regardless, but because it offers more flexibility, could be faster and is able to be used as an optionally different code path during sink creation based on a future configuration parameter.
My discussion and proposal to finish this change:
Devices are so easily enumerated through WinRT Windows.Devices namespace that wrapping the calls in a library is quite a chore for little benefit though to get the various modes and formats could still be a worthwhile project. For now conditional compilation to remove videodevices and any offending non-video file related activity in videodevice. In my opinion, this is a different , far less fundamental and important change which can possibly be done as a future project and also much more easily implemented in C++/CX.
ImageGrabber has the IMFSampleGrabberSinkCallback replaced with a base class (SharedSampleGrabber) which also be is base class for ImageGrabberRT. This change is necessary as the custom sink does not require a thread to pump events which is done through MediaCapture already. IMFSampleGrabberSinkCallback is the common element between both models and that piece can be shared. Initializing the new ImageGrabberRT is as simple as passing an already initialized MediaCapture object and any video format/encoding parameters.
The concurrency event is necessary to wait for completion and is the way the underlying, IAsyncAction wrappers in the task library work as well. Native WIN32 event objects would be an option if HAVE_CONCURRENCY is not defined. I could even imagine doing it with sleep/thread yield and InterlockedCompareExchange yet I am not enthusiastic about that approach either. Since there is a specific compiler HAVE_ for concurrency, I do not like pulling it in though I think for WinRT it is safe to say we will always have it available though should probably conditionally compile with the Interlocked option as WIN32 events would require HAVE_WIN32.
It looks like C++/CX cannot be used for the IMediaExtension sink (which should not be a problem) as using COM objects requires WRL and though deriving from IMediaExtension can be done, there is little purpose without COM. Objects from C++/CX can be swapped to interact with objects from native C++ as Inspectable* can reinterpret_cast to the ref object IInspectable^ and vice-versa. A solution to the COM class with C++/CX would be great so we could have dual support. Also without #define for every WRL object in use, the code will get quite muddy given that the */^ would need to be ifdef'd everywhere.
Update cap_msmf.cpp
Fixed bugs and completed the change. I believe the new classes need to be moved to a header file as the file has become to large and more classes need to be added for handling all the asynchronous problems (one wrapping IAsyncAction in a task and another for making a task out of IAsyncAction). Unfortunately, blocking on the UI thread is not an option in WinRT so a synchronous architecture is considered "illegal" by Microsoft's standards even if implementable (C++/CX ppltasks library throws errors if you try it). Worse, either by design or a bug in the MF MediaCapture class with Custom Sinks causes a crash if stop/start previewing without reinitializing (spPreferredPreviewMediaType is fatally nulled). After decompiling Windows.Media.dll, I worked around this in my own projects by using an activate-able custom sink ID which strangely assigns 1 to this pointer allowing it to be reinitialized in what can only be described as a hack by Microsoft. This would add additional overhead to the project to implement especially for static libraries as it requires IDL/DLL exporting followed by manifest declaration. Better to document that it is not supported.
Furthermore, an additional class for IMFAttributes should be implemented to make clean architecture for passing around attributes as opposed to directly calling non-COM interface calls on the objects and making use of SetProperties which would also be a set up for an object that uses the RuntimeClass activation ID.
The remaining changes are not difficult and will be complete soon along with debug tracing messages.
Update cap_msmf.cpp
Create cap_msmf.h
Update cap_msmf.cpp
Update cap_msmf.h
Update cap_msmf.cpp
Update cap_msmf.h
Update and rename cap_msmf.h to cap_msmf.hpp
Update cap_msmf.cpp
Update CMakeLists.txt
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.cpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Successful test - samples are grabbed
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Create ppltasks_winrt.h
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update ppltasks_winrt.h
Library updated and cleaned up with comments, marshaling, exceptions and linker settings
Update ppltasks_winrt.h
Fixed trailing whitespace
2013-12-14 16:53:30 +08:00
|
|
|
void ImageGrabberCallback::resumeGrabbing()
|
2013-05-14 20:17:34 +08:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2013-04-03 09:01:20 +08:00
|
|
|
HRESULT ImageGrabber::CreateTopology(IMFMediaSource *pSource, IMFActivate *pSinkActivate, IMFTopology **ppTopo)
|
|
|
|
{
|
2013-05-22 19:21:23 +08:00
|
|
|
IMFTopology* pTopology = NULL;
|
2013-05-15 21:09:03 +08:00
|
|
|
ComPtr<IMFPresentationDescriptor> pPD = NULL;
|
|
|
|
ComPtr<IMFStreamDescriptor> pSD = NULL;
|
|
|
|
ComPtr<IMFMediaTypeHandler> pHandler = NULL;
|
|
|
|
ComPtr<IMFTopologyNode> pNode1 = NULL;
|
|
|
|
ComPtr<IMFTopologyNode> pNode2 = NULL;
|
2013-04-03 09:01:20 +08:00
|
|
|
HRESULT hr = S_OK;
|
|
|
|
DWORD cStreams = 0;
|
2013-05-22 19:21:23 +08:00
|
|
|
CHECK_HR(hr = MFCreateTopology(&pTopology));
|
2013-05-15 21:09:03 +08:00
|
|
|
CHECK_HR(hr = pSource->CreatePresentationDescriptor(pPD.GetAddressOf()));
|
2013-04-03 09:01:20 +08:00
|
|
|
CHECK_HR(hr = pPD->GetStreamDescriptorCount(&cStreams));
|
|
|
|
for (DWORD i = 0; i < cStreams; i++)
|
|
|
|
{
|
|
|
|
// In this example, we look for audio streams and connect them to the sink.
|
|
|
|
BOOL fSelected = FALSE;
|
|
|
|
GUID majorType;
|
|
|
|
CHECK_HR(hr = pPD->GetStreamDescriptorByIndex(i, &fSelected, &pSD));
|
|
|
|
CHECK_HR(hr = pSD->GetMediaTypeHandler(&pHandler));
|
|
|
|
CHECK_HR(hr = pHandler->GetMajorType(&majorType));
|
|
|
|
if (majorType == MFMediaType_Video && fSelected)
|
|
|
|
{
|
2013-05-22 19:21:23 +08:00
|
|
|
CHECK_HR(hr = AddSourceNode(pTopology, pSource, pPD.Get(), pSD.Get(), pNode1.GetAddressOf()));
|
|
|
|
CHECK_HR(hr = AddOutputNode(pTopology, pSinkActivate, 0, pNode2.GetAddressOf()));
|
2013-05-15 21:09:03 +08:00
|
|
|
CHECK_HR(hr = pNode1->ConnectOutput(0, pNode2.Get(), 0));
|
2013-04-03 09:01:20 +08:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
CHECK_HR(hr = pPD->DeselectStream(i));
|
|
|
|
}
|
|
|
|
}
|
2013-05-22 19:21:23 +08:00
|
|
|
*ppTopo = pTopology;
|
2013-04-03 09:01:20 +08:00
|
|
|
(*ppTopo)->AddRef();
|
2013-04-16 21:25:10 +08:00
|
|
|
|
2013-04-03 09:01:20 +08:00
|
|
|
done:
|
|
|
|
return hr;
|
|
|
|
}
|
2013-04-16 21:25:10 +08:00
|
|
|
|
2013-04-03 09:01:20 +08:00
|
|
|
HRESULT ImageGrabber::AddSourceNode(
|
|
|
|
IMFTopology *pTopology, // Topology.
|
|
|
|
IMFMediaSource *pSource, // Media source.
|
|
|
|
IMFPresentationDescriptor *pPD, // Presentation descriptor.
|
|
|
|
IMFStreamDescriptor *pSD, // Stream descriptor.
|
|
|
|
IMFTopologyNode **ppNode) // Receives the node pointer.
|
|
|
|
{
|
2013-05-15 21:09:03 +08:00
|
|
|
ComPtr<IMFTopologyNode> pNode = NULL;
|
2013-04-03 09:01:20 +08:00
|
|
|
HRESULT hr = S_OK;
|
2013-05-15 21:09:03 +08:00
|
|
|
CHECK_HR(hr = MFCreateTopologyNode(MF_TOPOLOGY_SOURCESTREAM_NODE, pNode.GetAddressOf()));
|
2013-04-03 09:01:20 +08:00
|
|
|
CHECK_HR(hr = pNode->SetUnknown(MF_TOPONODE_SOURCE, pSource));
|
|
|
|
CHECK_HR(hr = pNode->SetUnknown(MF_TOPONODE_PRESENTATION_DESCRIPTOR, pPD));
|
|
|
|
CHECK_HR(hr = pNode->SetUnknown(MF_TOPONODE_STREAM_DESCRIPTOR, pSD));
|
2013-05-15 21:09:03 +08:00
|
|
|
CHECK_HR(hr = pTopology->AddNode(pNode.Get()));
|
2013-04-03 09:01:20 +08:00
|
|
|
// Return the pointer to the caller.
|
2013-05-15 21:09:03 +08:00
|
|
|
*ppNode = pNode.Get();
|
2013-04-03 09:01:20 +08:00
|
|
|
(*ppNode)->AddRef();
|
2013-04-16 21:25:10 +08:00
|
|
|
|
2013-04-03 09:01:20 +08:00
|
|
|
done:
|
|
|
|
return hr;
|
|
|
|
}
|
2013-04-16 21:25:10 +08:00
|
|
|
|
2013-04-03 09:01:20 +08:00
|
|
|
HRESULT ImageGrabber::AddOutputNode(
|
|
|
|
IMFTopology *pTopology, // Topology.
|
|
|
|
IMFActivate *pActivate, // Media sink activation object.
|
|
|
|
DWORD dwId, // Identifier of the stream sink.
|
|
|
|
IMFTopologyNode **ppNode) // Receives the node pointer.
|
|
|
|
{
|
2013-05-15 21:09:03 +08:00
|
|
|
ComPtr<IMFTopologyNode> pNode = NULL;
|
2013-04-03 09:01:20 +08:00
|
|
|
HRESULT hr = S_OK;
|
2013-05-15 21:09:03 +08:00
|
|
|
CHECK_HR(hr = MFCreateTopologyNode(MF_TOPOLOGY_OUTPUT_NODE, pNode.GetAddressOf()));
|
2013-04-03 09:01:20 +08:00
|
|
|
CHECK_HR(hr = pNode->SetObject(pActivate));
|
|
|
|
CHECK_HR(hr = pNode->SetUINT32(MF_TOPONODE_STREAMID, dwId));
|
|
|
|
CHECK_HR(hr = pNode->SetUINT32(MF_TOPONODE_NOSHUTDOWN_ON_REMOVE, FALSE));
|
2013-05-15 21:09:03 +08:00
|
|
|
CHECK_HR(hr = pTopology->AddNode(pNode.Get()));
|
2013-04-03 09:01:20 +08:00
|
|
|
// Return the pointer to the caller.
|
2013-05-15 21:09:03 +08:00
|
|
|
*ppNode = pNode.Get();
|
2013-04-03 09:01:20 +08:00
|
|
|
(*ppNode)->AddRef();
|
2013-04-16 21:25:10 +08:00
|
|
|
|
2013-04-03 09:01:20 +08:00
|
|
|
done:
|
|
|
|
return hr;
|
|
|
|
}
|
2013-04-16 21:25:10 +08:00
|
|
|
|
2013-05-15 20:12:25 +08:00
|
|
|
HRESULT ImageGrabber::CreateInstance(ImageGrabber **ppIG, unsigned int deviceID, bool synchronious)
|
2013-04-03 09:01:20 +08:00
|
|
|
{
|
2013-05-15 20:12:25 +08:00
|
|
|
*ppIG = new (std::nothrow) ImageGrabber(deviceID, synchronious);
|
2013-04-03 09:01:20 +08:00
|
|
|
if (ppIG == NULL)
|
|
|
|
{
|
|
|
|
return E_OUTOFMEMORY;
|
|
|
|
}
|
|
|
|
DebugPrintOut *DPO = &DebugPrintOut::getInstance();
|
|
|
|
DPO->printOut(L"IMAGEGRABBER VIDEODEVICE %i: Creating instance of ImageGrabber\n", deviceID);
|
|
|
|
return S_OK;
|
|
|
|
}
|
2013-04-16 21:25:10 +08:00
|
|
|
|
2013-04-03 09:01:20 +08:00
|
|
|
STDMETHODIMP ImageGrabber::QueryInterface(REFIID riid, void** ppv)
|
|
|
|
{
|
|
|
|
HRESULT hr = E_NOINTERFACE;
|
|
|
|
*ppv = NULL;
|
|
|
|
if(riid == IID_IUnknown || riid == IID_IMFSampleGrabberSinkCallback)
|
|
|
|
{
|
|
|
|
*ppv = static_cast<IMFSampleGrabberSinkCallback *>(this);
|
|
|
|
hr = S_OK;
|
|
|
|
}
|
|
|
|
if(riid == IID_IMFClockStateSink)
|
|
|
|
{
|
|
|
|
*ppv = static_cast<IMFClockStateSink *>(this);
|
|
|
|
hr = S_OK;
|
|
|
|
}
|
|
|
|
if(SUCCEEDED(hr))
|
|
|
|
{
|
|
|
|
reinterpret_cast<IUnknown *>(*ppv)->AddRef();
|
|
|
|
}
|
|
|
|
return hr;
|
|
|
|
}
|
2013-04-16 21:25:10 +08:00
|
|
|
|
2013-04-03 09:01:20 +08:00
|
|
|
STDMETHODIMP_(ULONG) ImageGrabber::AddRef()
|
|
|
|
{
|
|
|
|
return InterlockedIncrement(&m_cRef);
|
|
|
|
}
|
2013-04-16 21:25:10 +08:00
|
|
|
|
2013-04-03 09:01:20 +08:00
|
|
|
STDMETHODIMP_(ULONG) ImageGrabber::Release()
|
|
|
|
{
|
|
|
|
ULONG cRef = InterlockedDecrement(&m_cRef);
|
|
|
|
if (cRef == 0)
|
|
|
|
{
|
|
|
|
delete this;
|
|
|
|
}
|
|
|
|
return cRef;
|
|
|
|
}
|
2013-04-16 21:25:10 +08:00
|
|
|
|
Update cap_msmf.cpp
Add support for WinRT in the MF capture framework by removing the disallowed calls to enumerate devices and create a sample grabber sink and adding framework for the MediaCapture interface and a custom sink which interfaces with the sample grabber callback interface. The change requires discussion for making it completely functional as redundancy is required given that if the source is a video file, the old code pathways must be used. Otherwise all IMFMediaSession, IMFMediaSource, and IMFActivate code must use a MediaCapture code path and all sink code must use the CMediaSink custom sink.
Support for the custom sink is extended to non-WinRT not for compatibility as Windows Vista client is a minimum regardless, but because it offers more flexibility, could be faster and is able to be used as an optionally different code path during sink creation based on a future configuration parameter.
My discussion and proposal to finish this change:
Devices are so easily enumerated through WinRT Windows.Devices namespace that wrapping the calls in a library is quite a chore for little benefit though to get the various modes and formats could still be a worthwhile project. For now conditional compilation to remove videodevices and any offending non-video file related activity in videodevice. In my opinion, this is a different , far less fundamental and important change which can possibly be done as a future project and also much more easily implemented in C++/CX.
ImageGrabber has the IMFSampleGrabberSinkCallback replaced with a base class (SharedSampleGrabber) which also be is base class for ImageGrabberRT. This change is necessary as the custom sink does not require a thread to pump events which is done through MediaCapture already. IMFSampleGrabberSinkCallback is the common element between both models and that piece can be shared. Initializing the new ImageGrabberRT is as simple as passing an already initialized MediaCapture object and any video format/encoding parameters.
The concurrency event is necessary to wait for completion and is the way the underlying, IAsyncAction wrappers in the task library work as well. Native WIN32 event objects would be an option if HAVE_CONCURRENCY is not defined. I could even imagine doing it with sleep/thread yield and InterlockedCompareExchange yet I am not enthusiastic about that approach either. Since there is a specific compiler HAVE_ for concurrency, I do not like pulling it in though I think for WinRT it is safe to say we will always have it available though should probably conditionally compile with the Interlocked option as WIN32 events would require HAVE_WIN32.
It looks like C++/CX cannot be used for the IMediaExtension sink (which should not be a problem) as using COM objects requires WRL and though deriving from IMediaExtension can be done, there is little purpose without COM. Objects from C++/CX can be swapped to interact with objects from native C++ as Inspectable* can reinterpret_cast to the ref object IInspectable^ and vice-versa. A solution to the COM class with C++/CX would be great so we could have dual support. Also without #define for every WRL object in use, the code will get quite muddy given that the */^ would need to be ifdef'd everywhere.
Update cap_msmf.cpp
Fixed bugs and completed the change. I believe the new classes need to be moved to a header file as the file has become to large and more classes need to be added for handling all the asynchronous problems (one wrapping IAsyncAction in a task and another for making a task out of IAsyncAction). Unfortunately, blocking on the UI thread is not an option in WinRT so a synchronous architecture is considered "illegal" by Microsoft's standards even if implementable (C++/CX ppltasks library throws errors if you try it). Worse, either by design or a bug in the MF MediaCapture class with Custom Sinks causes a crash if stop/start previewing without reinitializing (spPreferredPreviewMediaType is fatally nulled). After decompiling Windows.Media.dll, I worked around this in my own projects by using an activate-able custom sink ID which strangely assigns 1 to this pointer allowing it to be reinitialized in what can only be described as a hack by Microsoft. This would add additional overhead to the project to implement especially for static libraries as it requires IDL/DLL exporting followed by manifest declaration. Better to document that it is not supported.
Furthermore, an additional class for IMFAttributes should be implemented to make clean architecture for passing around attributes as opposed to directly calling non-COM interface calls on the objects and making use of SetProperties which would also be a set up for an object that uses the RuntimeClass activation ID.
The remaining changes are not difficult and will be complete soon along with debug tracing messages.
Update cap_msmf.cpp
Create cap_msmf.h
Update cap_msmf.cpp
Update cap_msmf.h
Update cap_msmf.cpp
Update cap_msmf.h
Update and rename cap_msmf.h to cap_msmf.hpp
Update cap_msmf.cpp
Update CMakeLists.txt
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.cpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Successful test - samples are grabbed
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Create ppltasks_winrt.h
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update ppltasks_winrt.h
Library updated and cleaned up with comments, marshaling, exceptions and linker settings
Update ppltasks_winrt.h
Fixed trailing whitespace
2013-12-14 16:53:30 +08:00
|
|
|
STDMETHODIMP ImageGrabberCallback::OnClockStart(MFTIME hnsSystemTime, LONGLONG llClockStartOffset)
|
2013-04-03 09:01:20 +08:00
|
|
|
{
|
|
|
|
(void)hnsSystemTime;
|
|
|
|
(void)llClockStartOffset;
|
|
|
|
return S_OK;
|
|
|
|
}
|
2013-04-16 21:25:10 +08:00
|
|
|
|
Update cap_msmf.cpp
Add support for WinRT in the MF capture framework by removing the disallowed calls to enumerate devices and create a sample grabber sink and adding framework for the MediaCapture interface and a custom sink which interfaces with the sample grabber callback interface. The change requires discussion for making it completely functional as redundancy is required given that if the source is a video file, the old code pathways must be used. Otherwise all IMFMediaSession, IMFMediaSource, and IMFActivate code must use a MediaCapture code path and all sink code must use the CMediaSink custom sink.
Support for the custom sink is extended to non-WinRT not for compatibility as Windows Vista client is a minimum regardless, but because it offers more flexibility, could be faster and is able to be used as an optionally different code path during sink creation based on a future configuration parameter.
My discussion and proposal to finish this change:
Devices are so easily enumerated through WinRT Windows.Devices namespace that wrapping the calls in a library is quite a chore for little benefit though to get the various modes and formats could still be a worthwhile project. For now conditional compilation to remove videodevices and any offending non-video file related activity in videodevice. In my opinion, this is a different , far less fundamental and important change which can possibly be done as a future project and also much more easily implemented in C++/CX.
ImageGrabber has the IMFSampleGrabberSinkCallback replaced with a base class (SharedSampleGrabber) which also be is base class for ImageGrabberRT. This change is necessary as the custom sink does not require a thread to pump events which is done through MediaCapture already. IMFSampleGrabberSinkCallback is the common element between both models and that piece can be shared. Initializing the new ImageGrabberRT is as simple as passing an already initialized MediaCapture object and any video format/encoding parameters.
The concurrency event is necessary to wait for completion and is the way the underlying, IAsyncAction wrappers in the task library work as well. Native WIN32 event objects would be an option if HAVE_CONCURRENCY is not defined. I could even imagine doing it with sleep/thread yield and InterlockedCompareExchange yet I am not enthusiastic about that approach either. Since there is a specific compiler HAVE_ for concurrency, I do not like pulling it in though I think for WinRT it is safe to say we will always have it available though should probably conditionally compile with the Interlocked option as WIN32 events would require HAVE_WIN32.
It looks like C++/CX cannot be used for the IMediaExtension sink (which should not be a problem) as using COM objects requires WRL and though deriving from IMediaExtension can be done, there is little purpose without COM. Objects from C++/CX can be swapped to interact with objects from native C++ as Inspectable* can reinterpret_cast to the ref object IInspectable^ and vice-versa. A solution to the COM class with C++/CX would be great so we could have dual support. Also without #define for every WRL object in use, the code will get quite muddy given that the */^ would need to be ifdef'd everywhere.
Update cap_msmf.cpp
Fixed bugs and completed the change. I believe the new classes need to be moved to a header file as the file has become to large and more classes need to be added for handling all the asynchronous problems (one wrapping IAsyncAction in a task and another for making a task out of IAsyncAction). Unfortunately, blocking on the UI thread is not an option in WinRT so a synchronous architecture is considered "illegal" by Microsoft's standards even if implementable (C++/CX ppltasks library throws errors if you try it). Worse, either by design or a bug in the MF MediaCapture class with Custom Sinks causes a crash if stop/start previewing without reinitializing (spPreferredPreviewMediaType is fatally nulled). After decompiling Windows.Media.dll, I worked around this in my own projects by using an activate-able custom sink ID which strangely assigns 1 to this pointer allowing it to be reinitialized in what can only be described as a hack by Microsoft. This would add additional overhead to the project to implement especially for static libraries as it requires IDL/DLL exporting followed by manifest declaration. Better to document that it is not supported.
Furthermore, an additional class for IMFAttributes should be implemented to make clean architecture for passing around attributes as opposed to directly calling non-COM interface calls on the objects and making use of SetProperties which would also be a set up for an object that uses the RuntimeClass activation ID.
The remaining changes are not difficult and will be complete soon along with debug tracing messages.
Update cap_msmf.cpp
Create cap_msmf.h
Update cap_msmf.cpp
Update cap_msmf.h
Update cap_msmf.cpp
Update cap_msmf.h
Update and rename cap_msmf.h to cap_msmf.hpp
Update cap_msmf.cpp
Update CMakeLists.txt
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.cpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Successful test - samples are grabbed
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Create ppltasks_winrt.h
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update ppltasks_winrt.h
Library updated and cleaned up with comments, marshaling, exceptions and linker settings
Update ppltasks_winrt.h
Fixed trailing whitespace
2013-12-14 16:53:30 +08:00
|
|
|
STDMETHODIMP ImageGrabberCallback::OnClockStop(MFTIME hnsSystemTime)
|
2013-04-03 09:01:20 +08:00
|
|
|
{
|
|
|
|
(void)hnsSystemTime;
|
|
|
|
return S_OK;
|
|
|
|
}
|
2013-04-16 21:25:10 +08:00
|
|
|
|
Update cap_msmf.cpp
Add support for WinRT in the MF capture framework by removing the disallowed calls to enumerate devices and create a sample grabber sink and adding framework for the MediaCapture interface and a custom sink which interfaces with the sample grabber callback interface. The change requires discussion for making it completely functional as redundancy is required given that if the source is a video file, the old code pathways must be used. Otherwise all IMFMediaSession, IMFMediaSource, and IMFActivate code must use a MediaCapture code path and all sink code must use the CMediaSink custom sink.
Support for the custom sink is extended to non-WinRT not for compatibility as Windows Vista client is a minimum regardless, but because it offers more flexibility, could be faster and is able to be used as an optionally different code path during sink creation based on a future configuration parameter.
My discussion and proposal to finish this change:
Devices are so easily enumerated through WinRT Windows.Devices namespace that wrapping the calls in a library is quite a chore for little benefit though to get the various modes and formats could still be a worthwhile project. For now conditional compilation to remove videodevices and any offending non-video file related activity in videodevice. In my opinion, this is a different , far less fundamental and important change which can possibly be done as a future project and also much more easily implemented in C++/CX.
ImageGrabber has the IMFSampleGrabberSinkCallback replaced with a base class (SharedSampleGrabber) which also be is base class for ImageGrabberRT. This change is necessary as the custom sink does not require a thread to pump events which is done through MediaCapture already. IMFSampleGrabberSinkCallback is the common element between both models and that piece can be shared. Initializing the new ImageGrabberRT is as simple as passing an already initialized MediaCapture object and any video format/encoding parameters.
The concurrency event is necessary to wait for completion and is the way the underlying, IAsyncAction wrappers in the task library work as well. Native WIN32 event objects would be an option if HAVE_CONCURRENCY is not defined. I could even imagine doing it with sleep/thread yield and InterlockedCompareExchange yet I am not enthusiastic about that approach either. Since there is a specific compiler HAVE_ for concurrency, I do not like pulling it in though I think for WinRT it is safe to say we will always have it available though should probably conditionally compile with the Interlocked option as WIN32 events would require HAVE_WIN32.
It looks like C++/CX cannot be used for the IMediaExtension sink (which should not be a problem) as using COM objects requires WRL and though deriving from IMediaExtension can be done, there is little purpose without COM. Objects from C++/CX can be swapped to interact with objects from native C++ as Inspectable* can reinterpret_cast to the ref object IInspectable^ and vice-versa. A solution to the COM class with C++/CX would be great so we could have dual support. Also without #define for every WRL object in use, the code will get quite muddy given that the */^ would need to be ifdef'd everywhere.
Update cap_msmf.cpp
Fixed bugs and completed the change. I believe the new classes need to be moved to a header file as the file has become to large and more classes need to be added for handling all the asynchronous problems (one wrapping IAsyncAction in a task and another for making a task out of IAsyncAction). Unfortunately, blocking on the UI thread is not an option in WinRT so a synchronous architecture is considered "illegal" by Microsoft's standards even if implementable (C++/CX ppltasks library throws errors if you try it). Worse, either by design or a bug in the MF MediaCapture class with Custom Sinks causes a crash if stop/start previewing without reinitializing (spPreferredPreviewMediaType is fatally nulled). After decompiling Windows.Media.dll, I worked around this in my own projects by using an activate-able custom sink ID which strangely assigns 1 to this pointer allowing it to be reinitialized in what can only be described as a hack by Microsoft. This would add additional overhead to the project to implement especially for static libraries as it requires IDL/DLL exporting followed by manifest declaration. Better to document that it is not supported.
Furthermore, an additional class for IMFAttributes should be implemented to make clean architecture for passing around attributes as opposed to directly calling non-COM interface calls on the objects and making use of SetProperties which would also be a set up for an object that uses the RuntimeClass activation ID.
The remaining changes are not difficult and will be complete soon along with debug tracing messages.
Update cap_msmf.cpp
Create cap_msmf.h
Update cap_msmf.cpp
Update cap_msmf.h
Update cap_msmf.cpp
Update cap_msmf.h
Update and rename cap_msmf.h to cap_msmf.hpp
Update cap_msmf.cpp
Update CMakeLists.txt
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.cpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Successful test - samples are grabbed
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Create ppltasks_winrt.h
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update ppltasks_winrt.h
Library updated and cleaned up with comments, marshaling, exceptions and linker settings
Update ppltasks_winrt.h
Fixed trailing whitespace
2013-12-14 16:53:30 +08:00
|
|
|
STDMETHODIMP ImageGrabberCallback::OnClockPause(MFTIME hnsSystemTime)
|
2013-04-03 09:01:20 +08:00
|
|
|
{
|
|
|
|
(void)hnsSystemTime;
|
|
|
|
return S_OK;
|
|
|
|
}
|
2013-04-16 21:25:10 +08:00
|
|
|
|
Update cap_msmf.cpp
Add support for WinRT in the MF capture framework by removing the disallowed calls to enumerate devices and create a sample grabber sink and adding framework for the MediaCapture interface and a custom sink which interfaces with the sample grabber callback interface. The change requires discussion for making it completely functional as redundancy is required given that if the source is a video file, the old code pathways must be used. Otherwise all IMFMediaSession, IMFMediaSource, and IMFActivate code must use a MediaCapture code path and all sink code must use the CMediaSink custom sink.
Support for the custom sink is extended to non-WinRT not for compatibility as Windows Vista client is a minimum regardless, but because it offers more flexibility, could be faster and is able to be used as an optionally different code path during sink creation based on a future configuration parameter.
My discussion and proposal to finish this change:
Devices are so easily enumerated through WinRT Windows.Devices namespace that wrapping the calls in a library is quite a chore for little benefit though to get the various modes and formats could still be a worthwhile project. For now conditional compilation to remove videodevices and any offending non-video file related activity in videodevice. In my opinion, this is a different , far less fundamental and important change which can possibly be done as a future project and also much more easily implemented in C++/CX.
ImageGrabber has the IMFSampleGrabberSinkCallback replaced with a base class (SharedSampleGrabber) which also be is base class for ImageGrabberRT. This change is necessary as the custom sink does not require a thread to pump events which is done through MediaCapture already. IMFSampleGrabberSinkCallback is the common element between both models and that piece can be shared. Initializing the new ImageGrabberRT is as simple as passing an already initialized MediaCapture object and any video format/encoding parameters.
The concurrency event is necessary to wait for completion and is the way the underlying, IAsyncAction wrappers in the task library work as well. Native WIN32 event objects would be an option if HAVE_CONCURRENCY is not defined. I could even imagine doing it with sleep/thread yield and InterlockedCompareExchange yet I am not enthusiastic about that approach either. Since there is a specific compiler HAVE_ for concurrency, I do not like pulling it in though I think for WinRT it is safe to say we will always have it available though should probably conditionally compile with the Interlocked option as WIN32 events would require HAVE_WIN32.
It looks like C++/CX cannot be used for the IMediaExtension sink (which should not be a problem) as using COM objects requires WRL and though deriving from IMediaExtension can be done, there is little purpose without COM. Objects from C++/CX can be swapped to interact with objects from native C++ as Inspectable* can reinterpret_cast to the ref object IInspectable^ and vice-versa. A solution to the COM class with C++/CX would be great so we could have dual support. Also without #define for every WRL object in use, the code will get quite muddy given that the */^ would need to be ifdef'd everywhere.
Update cap_msmf.cpp
Fixed bugs and completed the change. I believe the new classes need to be moved to a header file as the file has become to large and more classes need to be added for handling all the asynchronous problems (one wrapping IAsyncAction in a task and another for making a task out of IAsyncAction). Unfortunately, blocking on the UI thread is not an option in WinRT so a synchronous architecture is considered "illegal" by Microsoft's standards even if implementable (C++/CX ppltasks library throws errors if you try it). Worse, either by design or a bug in the MF MediaCapture class with Custom Sinks causes a crash if stop/start previewing without reinitializing (spPreferredPreviewMediaType is fatally nulled). After decompiling Windows.Media.dll, I worked around this in my own projects by using an activate-able custom sink ID which strangely assigns 1 to this pointer allowing it to be reinitialized in what can only be described as a hack by Microsoft. This would add additional overhead to the project to implement especially for static libraries as it requires IDL/DLL exporting followed by manifest declaration. Better to document that it is not supported.
Furthermore, an additional class for IMFAttributes should be implemented to make clean architecture for passing around attributes as opposed to directly calling non-COM interface calls on the objects and making use of SetProperties which would also be a set up for an object that uses the RuntimeClass activation ID.
The remaining changes are not difficult and will be complete soon along with debug tracing messages.
Update cap_msmf.cpp
Create cap_msmf.h
Update cap_msmf.cpp
Update cap_msmf.h
Update cap_msmf.cpp
Update cap_msmf.h
Update and rename cap_msmf.h to cap_msmf.hpp
Update cap_msmf.cpp
Update CMakeLists.txt
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.cpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Successful test - samples are grabbed
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Create ppltasks_winrt.h
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update ppltasks_winrt.h
Library updated and cleaned up with comments, marshaling, exceptions and linker settings
Update ppltasks_winrt.h
Fixed trailing whitespace
2013-12-14 16:53:30 +08:00
|
|
|
STDMETHODIMP ImageGrabberCallback::OnClockRestart(MFTIME hnsSystemTime)
|
2013-04-03 09:01:20 +08:00
|
|
|
{
|
|
|
|
(void)hnsSystemTime;
|
|
|
|
return S_OK;
|
|
|
|
}
|
2013-04-16 21:25:10 +08:00
|
|
|
|
Update cap_msmf.cpp
Add support for WinRT in the MF capture framework by removing the disallowed calls to enumerate devices and create a sample grabber sink and adding framework for the MediaCapture interface and a custom sink which interfaces with the sample grabber callback interface. The change requires discussion for making it completely functional as redundancy is required given that if the source is a video file, the old code pathways must be used. Otherwise all IMFMediaSession, IMFMediaSource, and IMFActivate code must use a MediaCapture code path and all sink code must use the CMediaSink custom sink.
Support for the custom sink is extended to non-WinRT not for compatibility as Windows Vista client is a minimum regardless, but because it offers more flexibility, could be faster and is able to be used as an optionally different code path during sink creation based on a future configuration parameter.
My discussion and proposal to finish this change:
Devices are so easily enumerated through WinRT Windows.Devices namespace that wrapping the calls in a library is quite a chore for little benefit though to get the various modes and formats could still be a worthwhile project. For now conditional compilation to remove videodevices and any offending non-video file related activity in videodevice. In my opinion, this is a different , far less fundamental and important change which can possibly be done as a future project and also much more easily implemented in C++/CX.
ImageGrabber has the IMFSampleGrabberSinkCallback replaced with a base class (SharedSampleGrabber) which also be is base class for ImageGrabberRT. This change is necessary as the custom sink does not require a thread to pump events which is done through MediaCapture already. IMFSampleGrabberSinkCallback is the common element between both models and that piece can be shared. Initializing the new ImageGrabberRT is as simple as passing an already initialized MediaCapture object and any video format/encoding parameters.
The concurrency event is necessary to wait for completion and is the way the underlying, IAsyncAction wrappers in the task library work as well. Native WIN32 event objects would be an option if HAVE_CONCURRENCY is not defined. I could even imagine doing it with sleep/thread yield and InterlockedCompareExchange yet I am not enthusiastic about that approach either. Since there is a specific compiler HAVE_ for concurrency, I do not like pulling it in though I think for WinRT it is safe to say we will always have it available though should probably conditionally compile with the Interlocked option as WIN32 events would require HAVE_WIN32.
It looks like C++/CX cannot be used for the IMediaExtension sink (which should not be a problem) as using COM objects requires WRL and though deriving from IMediaExtension can be done, there is little purpose without COM. Objects from C++/CX can be swapped to interact with objects from native C++ as Inspectable* can reinterpret_cast to the ref object IInspectable^ and vice-versa. A solution to the COM class with C++/CX would be great so we could have dual support. Also without #define for every WRL object in use, the code will get quite muddy given that the */^ would need to be ifdef'd everywhere.
Update cap_msmf.cpp
Fixed bugs and completed the change. I believe the new classes need to be moved to a header file as the file has become to large and more classes need to be added for handling all the asynchronous problems (one wrapping IAsyncAction in a task and another for making a task out of IAsyncAction). Unfortunately, blocking on the UI thread is not an option in WinRT so a synchronous architecture is considered "illegal" by Microsoft's standards even if implementable (C++/CX ppltasks library throws errors if you try it). Worse, either by design or a bug in the MF MediaCapture class with Custom Sinks causes a crash if stop/start previewing without reinitializing (spPreferredPreviewMediaType is fatally nulled). After decompiling Windows.Media.dll, I worked around this in my own projects by using an activate-able custom sink ID which strangely assigns 1 to this pointer allowing it to be reinitialized in what can only be described as a hack by Microsoft. This would add additional overhead to the project to implement especially for static libraries as it requires IDL/DLL exporting followed by manifest declaration. Better to document that it is not supported.
Furthermore, an additional class for IMFAttributes should be implemented to make clean architecture for passing around attributes as opposed to directly calling non-COM interface calls on the objects and making use of SetProperties which would also be a set up for an object that uses the RuntimeClass activation ID.
The remaining changes are not difficult and will be complete soon along with debug tracing messages.
Update cap_msmf.cpp
Create cap_msmf.h
Update cap_msmf.cpp
Update cap_msmf.h
Update cap_msmf.cpp
Update cap_msmf.h
Update and rename cap_msmf.h to cap_msmf.hpp
Update cap_msmf.cpp
Update CMakeLists.txt
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.cpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Successful test - samples are grabbed
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Create ppltasks_winrt.h
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update ppltasks_winrt.h
Library updated and cleaned up with comments, marshaling, exceptions and linker settings
Update ppltasks_winrt.h
Fixed trailing whitespace
2013-12-14 16:53:30 +08:00
|
|
|
STDMETHODIMP ImageGrabberCallback::OnClockSetRate(MFTIME hnsSystemTime, float flRate)
|
2013-04-03 09:01:20 +08:00
|
|
|
{
|
|
|
|
(void)flRate;
|
|
|
|
(void)hnsSystemTime;
|
|
|
|
return S_OK;
|
|
|
|
}
|
2013-04-16 21:25:10 +08:00
|
|
|
|
Update cap_msmf.cpp
Add support for WinRT in the MF capture framework by removing the disallowed calls to enumerate devices and create a sample grabber sink and adding framework for the MediaCapture interface and a custom sink which interfaces with the sample grabber callback interface. The change requires discussion for making it completely functional as redundancy is required given that if the source is a video file, the old code pathways must be used. Otherwise all IMFMediaSession, IMFMediaSource, and IMFActivate code must use a MediaCapture code path and all sink code must use the CMediaSink custom sink.
Support for the custom sink is extended to non-WinRT not for compatibility as Windows Vista client is a minimum regardless, but because it offers more flexibility, could be faster and is able to be used as an optionally different code path during sink creation based on a future configuration parameter.
My discussion and proposal to finish this change:
Devices are so easily enumerated through WinRT Windows.Devices namespace that wrapping the calls in a library is quite a chore for little benefit though to get the various modes and formats could still be a worthwhile project. For now conditional compilation to remove videodevices and any offending non-video file related activity in videodevice. In my opinion, this is a different , far less fundamental and important change which can possibly be done as a future project and also much more easily implemented in C++/CX.
ImageGrabber has the IMFSampleGrabberSinkCallback replaced with a base class (SharedSampleGrabber) which also be is base class for ImageGrabberRT. This change is necessary as the custom sink does not require a thread to pump events which is done through MediaCapture already. IMFSampleGrabberSinkCallback is the common element between both models and that piece can be shared. Initializing the new ImageGrabberRT is as simple as passing an already initialized MediaCapture object and any video format/encoding parameters.
The concurrency event is necessary to wait for completion and is the way the underlying, IAsyncAction wrappers in the task library work as well. Native WIN32 event objects would be an option if HAVE_CONCURRENCY is not defined. I could even imagine doing it with sleep/thread yield and InterlockedCompareExchange yet I am not enthusiastic about that approach either. Since there is a specific compiler HAVE_ for concurrency, I do not like pulling it in though I think for WinRT it is safe to say we will always have it available though should probably conditionally compile with the Interlocked option as WIN32 events would require HAVE_WIN32.
It looks like C++/CX cannot be used for the IMediaExtension sink (which should not be a problem) as using COM objects requires WRL and though deriving from IMediaExtension can be done, there is little purpose without COM. Objects from C++/CX can be swapped to interact with objects from native C++ as Inspectable* can reinterpret_cast to the ref object IInspectable^ and vice-versa. A solution to the COM class with C++/CX would be great so we could have dual support. Also without #define for every WRL object in use, the code will get quite muddy given that the */^ would need to be ifdef'd everywhere.
Update cap_msmf.cpp
Fixed bugs and completed the change. I believe the new classes need to be moved to a header file as the file has become to large and more classes need to be added for handling all the asynchronous problems (one wrapping IAsyncAction in a task and another for making a task out of IAsyncAction). Unfortunately, blocking on the UI thread is not an option in WinRT so a synchronous architecture is considered "illegal" by Microsoft's standards even if implementable (C++/CX ppltasks library throws errors if you try it). Worse, either by design or a bug in the MF MediaCapture class with Custom Sinks causes a crash if stop/start previewing without reinitializing (spPreferredPreviewMediaType is fatally nulled). After decompiling Windows.Media.dll, I worked around this in my own projects by using an activate-able custom sink ID which strangely assigns 1 to this pointer allowing it to be reinitialized in what can only be described as a hack by Microsoft. This would add additional overhead to the project to implement especially for static libraries as it requires IDL/DLL exporting followed by manifest declaration. Better to document that it is not supported.
Furthermore, an additional class for IMFAttributes should be implemented to make clean architecture for passing around attributes as opposed to directly calling non-COM interface calls on the objects and making use of SetProperties which would also be a set up for an object that uses the RuntimeClass activation ID.
The remaining changes are not difficult and will be complete soon along with debug tracing messages.
Update cap_msmf.cpp
Create cap_msmf.h
Update cap_msmf.cpp
Update cap_msmf.h
Update cap_msmf.cpp
Update cap_msmf.h
Update and rename cap_msmf.h to cap_msmf.hpp
Update cap_msmf.cpp
Update CMakeLists.txt
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.cpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Successful test - samples are grabbed
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Create ppltasks_winrt.h
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update ppltasks_winrt.h
Library updated and cleaned up with comments, marshaling, exceptions and linker settings
Update ppltasks_winrt.h
Fixed trailing whitespace
2013-12-14 16:53:30 +08:00
|
|
|
STDMETHODIMP ImageGrabberCallback::OnSetPresentationClock(IMFPresentationClock* pClock)
|
2013-04-03 09:01:20 +08:00
|
|
|
{
|
|
|
|
(void)pClock;
|
|
|
|
return S_OK;
|
|
|
|
}
|
2013-04-16 21:25:10 +08:00
|
|
|
|
Update cap_msmf.cpp
Add support for WinRT in the MF capture framework by removing the disallowed calls to enumerate devices and create a sample grabber sink and adding framework for the MediaCapture interface and a custom sink which interfaces with the sample grabber callback interface. The change requires discussion for making it completely functional as redundancy is required given that if the source is a video file, the old code pathways must be used. Otherwise all IMFMediaSession, IMFMediaSource, and IMFActivate code must use a MediaCapture code path and all sink code must use the CMediaSink custom sink.
Support for the custom sink is extended to non-WinRT not for compatibility as Windows Vista client is a minimum regardless, but because it offers more flexibility, could be faster and is able to be used as an optionally different code path during sink creation based on a future configuration parameter.
My discussion and proposal to finish this change:
Devices are so easily enumerated through WinRT Windows.Devices namespace that wrapping the calls in a library is quite a chore for little benefit though to get the various modes and formats could still be a worthwhile project. For now conditional compilation to remove videodevices and any offending non-video file related activity in videodevice. In my opinion, this is a different , far less fundamental and important change which can possibly be done as a future project and also much more easily implemented in C++/CX.
ImageGrabber has the IMFSampleGrabberSinkCallback replaced with a base class (SharedSampleGrabber) which also be is base class for ImageGrabberRT. This change is necessary as the custom sink does not require a thread to pump events which is done through MediaCapture already. IMFSampleGrabberSinkCallback is the common element between both models and that piece can be shared. Initializing the new ImageGrabberRT is as simple as passing an already initialized MediaCapture object and any video format/encoding parameters.
The concurrency event is necessary to wait for completion and is the way the underlying, IAsyncAction wrappers in the task library work as well. Native WIN32 event objects would be an option if HAVE_CONCURRENCY is not defined. I could even imagine doing it with sleep/thread yield and InterlockedCompareExchange yet I am not enthusiastic about that approach either. Since there is a specific compiler HAVE_ for concurrency, I do not like pulling it in though I think for WinRT it is safe to say we will always have it available though should probably conditionally compile with the Interlocked option as WIN32 events would require HAVE_WIN32.
It looks like C++/CX cannot be used for the IMediaExtension sink (which should not be a problem) as using COM objects requires WRL and though deriving from IMediaExtension can be done, there is little purpose without COM. Objects from C++/CX can be swapped to interact with objects from native C++ as Inspectable* can reinterpret_cast to the ref object IInspectable^ and vice-versa. A solution to the COM class with C++/CX would be great so we could have dual support. Also without #define for every WRL object in use, the code will get quite muddy given that the */^ would need to be ifdef'd everywhere.
Update cap_msmf.cpp
Fixed bugs and completed the change. I believe the new classes need to be moved to a header file as the file has become to large and more classes need to be added for handling all the asynchronous problems (one wrapping IAsyncAction in a task and another for making a task out of IAsyncAction). Unfortunately, blocking on the UI thread is not an option in WinRT so a synchronous architecture is considered "illegal" by Microsoft's standards even if implementable (C++/CX ppltasks library throws errors if you try it). Worse, either by design or a bug in the MF MediaCapture class with Custom Sinks causes a crash if stop/start previewing without reinitializing (spPreferredPreviewMediaType is fatally nulled). After decompiling Windows.Media.dll, I worked around this in my own projects by using an activate-able custom sink ID which strangely assigns 1 to this pointer allowing it to be reinitialized in what can only be described as a hack by Microsoft. This would add additional overhead to the project to implement especially for static libraries as it requires IDL/DLL exporting followed by manifest declaration. Better to document that it is not supported.
Furthermore, an additional class for IMFAttributes should be implemented to make clean architecture for passing around attributes as opposed to directly calling non-COM interface calls on the objects and making use of SetProperties which would also be a set up for an object that uses the RuntimeClass activation ID.
The remaining changes are not difficult and will be complete soon along with debug tracing messages.
Update cap_msmf.cpp
Create cap_msmf.h
Update cap_msmf.cpp
Update cap_msmf.h
Update cap_msmf.cpp
Update cap_msmf.h
Update and rename cap_msmf.h to cap_msmf.hpp
Update cap_msmf.cpp
Update CMakeLists.txt
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.cpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Successful test - samples are grabbed
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Create ppltasks_winrt.h
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update ppltasks_winrt.h
Library updated and cleaned up with comments, marshaling, exceptions and linker settings
Update ppltasks_winrt.h
Fixed trailing whitespace
2013-12-14 16:53:30 +08:00
|
|
|
STDMETHODIMP ImageGrabberCallback::OnProcessSample(REFGUID guidMajorMediaType, DWORD dwSampleFlags,
|
2013-04-03 09:01:20 +08:00
|
|
|
LONGLONG llSampleTime, LONGLONG llSampleDuration, const BYTE * pSampleBuffer,
|
|
|
|
DWORD dwSampleSize)
|
|
|
|
{
|
|
|
|
(void)guidMajorMediaType;
|
|
|
|
(void)llSampleTime;
|
|
|
|
(void)dwSampleFlags;
|
|
|
|
(void)llSampleDuration;
|
|
|
|
(void)dwSampleSize;
|
2013-04-16 21:25:10 +08:00
|
|
|
|
2013-05-22 19:21:23 +08:00
|
|
|
HANDLE tmp[] = {ig_hFinish, ig_hFrameGrabbed, NULL};
|
2013-05-14 20:17:34 +08:00
|
|
|
|
2013-05-22 19:21:23 +08:00
|
|
|
DWORD status = WaitForMultipleObjects(2, tmp, FALSE, INFINITE);
|
|
|
|
if (status == WAIT_OBJECT_0)
|
|
|
|
{
|
|
|
|
printf("OnProcessFrame called after ig_hFinish event\n");
|
|
|
|
return S_OK;
|
|
|
|
}
|
2013-04-16 21:25:10 +08:00
|
|
|
|
2013-04-03 09:01:20 +08:00
|
|
|
if(ig_RIE)
|
|
|
|
{
|
|
|
|
ig_RIFirst->fastCopy(pSampleBuffer);
|
|
|
|
ig_RIOut = ig_RIFirst;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
ig_RISecond->fastCopy(pSampleBuffer);
|
|
|
|
ig_RIOut = ig_RISecond;
|
|
|
|
}
|
2013-04-16 21:25:10 +08:00
|
|
|
|
2013-05-15 20:12:25 +08:00
|
|
|
if (ig_Synchronous)
|
|
|
|
{
|
|
|
|
SetEvent(ig_hFrameReady);
|
|
|
|
}
|
2013-05-22 19:21:23 +08:00
|
|
|
else
|
|
|
|
{
|
|
|
|
ig_RIE = !ig_RIE;
|
|
|
|
}
|
2013-05-14 20:17:34 +08:00
|
|
|
|
2013-04-03 09:01:20 +08:00
|
|
|
return S_OK;
|
|
|
|
}
|
2013-04-16 21:25:10 +08:00
|
|
|
|
Update cap_msmf.cpp
Add support for WinRT in the MF capture framework by removing the disallowed calls to enumerate devices and create a sample grabber sink and adding framework for the MediaCapture interface and a custom sink which interfaces with the sample grabber callback interface. The change requires discussion for making it completely functional as redundancy is required given that if the source is a video file, the old code pathways must be used. Otherwise all IMFMediaSession, IMFMediaSource, and IMFActivate code must use a MediaCapture code path and all sink code must use the CMediaSink custom sink.
Support for the custom sink is extended to non-WinRT not for compatibility as Windows Vista client is a minimum regardless, but because it offers more flexibility, could be faster and is able to be used as an optionally different code path during sink creation based on a future configuration parameter.
My discussion and proposal to finish this change:
Devices are so easily enumerated through WinRT Windows.Devices namespace that wrapping the calls in a library is quite a chore for little benefit though to get the various modes and formats could still be a worthwhile project. For now conditional compilation to remove videodevices and any offending non-video file related activity in videodevice. In my opinion, this is a different , far less fundamental and important change which can possibly be done as a future project and also much more easily implemented in C++/CX.
ImageGrabber has the IMFSampleGrabberSinkCallback replaced with a base class (SharedSampleGrabber) which also be is base class for ImageGrabberRT. This change is necessary as the custom sink does not require a thread to pump events which is done through MediaCapture already. IMFSampleGrabberSinkCallback is the common element between both models and that piece can be shared. Initializing the new ImageGrabberRT is as simple as passing an already initialized MediaCapture object and any video format/encoding parameters.
The concurrency event is necessary to wait for completion and is the way the underlying, IAsyncAction wrappers in the task library work as well. Native WIN32 event objects would be an option if HAVE_CONCURRENCY is not defined. I could even imagine doing it with sleep/thread yield and InterlockedCompareExchange yet I am not enthusiastic about that approach either. Since there is a specific compiler HAVE_ for concurrency, I do not like pulling it in though I think for WinRT it is safe to say we will always have it available though should probably conditionally compile with the Interlocked option as WIN32 events would require HAVE_WIN32.
It looks like C++/CX cannot be used for the IMediaExtension sink (which should not be a problem) as using COM objects requires WRL and though deriving from IMediaExtension can be done, there is little purpose without COM. Objects from C++/CX can be swapped to interact with objects from native C++ as Inspectable* can reinterpret_cast to the ref object IInspectable^ and vice-versa. A solution to the COM class with C++/CX would be great so we could have dual support. Also without #define for every WRL object in use, the code will get quite muddy given that the */^ would need to be ifdef'd everywhere.
Update cap_msmf.cpp
Fixed bugs and completed the change. I believe the new classes need to be moved to a header file as the file has become to large and more classes need to be added for handling all the asynchronous problems (one wrapping IAsyncAction in a task and another for making a task out of IAsyncAction). Unfortunately, blocking on the UI thread is not an option in WinRT so a synchronous architecture is considered "illegal" by Microsoft's standards even if implementable (C++/CX ppltasks library throws errors if you try it). Worse, either by design or a bug in the MF MediaCapture class with Custom Sinks causes a crash if stop/start previewing without reinitializing (spPreferredPreviewMediaType is fatally nulled). After decompiling Windows.Media.dll, I worked around this in my own projects by using an activate-able custom sink ID which strangely assigns 1 to this pointer allowing it to be reinitialized in what can only be described as a hack by Microsoft. This would add additional overhead to the project to implement especially for static libraries as it requires IDL/DLL exporting followed by manifest declaration. Better to document that it is not supported.
Furthermore, an additional class for IMFAttributes should be implemented to make clean architecture for passing around attributes as opposed to directly calling non-COM interface calls on the objects and making use of SetProperties which would also be a set up for an object that uses the RuntimeClass activation ID.
The remaining changes are not difficult and will be complete soon along with debug tracing messages.
Update cap_msmf.cpp
Create cap_msmf.h
Update cap_msmf.cpp
Update cap_msmf.h
Update cap_msmf.cpp
Update cap_msmf.h
Update and rename cap_msmf.h to cap_msmf.hpp
Update cap_msmf.cpp
Update CMakeLists.txt
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.cpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Successful test - samples are grabbed
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Create ppltasks_winrt.h
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update ppltasks_winrt.h
Library updated and cleaned up with comments, marshaling, exceptions and linker settings
Update ppltasks_winrt.h
Fixed trailing whitespace
2013-12-14 16:53:30 +08:00
|
|
|
STDMETHODIMP ImageGrabberCallback::OnShutdown()
|
2013-04-03 09:01:20 +08:00
|
|
|
{
|
2013-05-22 19:21:23 +08:00
|
|
|
SetEvent(ig_hFinish);
|
2013-04-03 09:01:20 +08:00
|
|
|
return S_OK;
|
|
|
|
}
|
2013-04-16 21:25:10 +08:00
|
|
|
|
Update cap_msmf.cpp
Add support for WinRT in the MF capture framework by removing the disallowed calls to enumerate devices and create a sample grabber sink and adding framework for the MediaCapture interface and a custom sink which interfaces with the sample grabber callback interface. The change requires discussion for making it completely functional as redundancy is required given that if the source is a video file, the old code pathways must be used. Otherwise all IMFMediaSession, IMFMediaSource, and IMFActivate code must use a MediaCapture code path and all sink code must use the CMediaSink custom sink.
Support for the custom sink is extended to non-WinRT not for compatibility as Windows Vista client is a minimum regardless, but because it offers more flexibility, could be faster and is able to be used as an optionally different code path during sink creation based on a future configuration parameter.
My discussion and proposal to finish this change:
Devices are so easily enumerated through WinRT Windows.Devices namespace that wrapping the calls in a library is quite a chore for little benefit though to get the various modes and formats could still be a worthwhile project. For now conditional compilation to remove videodevices and any offending non-video file related activity in videodevice. In my opinion, this is a different , far less fundamental and important change which can possibly be done as a future project and also much more easily implemented in C++/CX.
ImageGrabber has the IMFSampleGrabberSinkCallback replaced with a base class (SharedSampleGrabber) which also be is base class for ImageGrabberRT. This change is necessary as the custom sink does not require a thread to pump events which is done through MediaCapture already. IMFSampleGrabberSinkCallback is the common element between both models and that piece can be shared. Initializing the new ImageGrabberRT is as simple as passing an already initialized MediaCapture object and any video format/encoding parameters.
The concurrency event is necessary to wait for completion and is the way the underlying, IAsyncAction wrappers in the task library work as well. Native WIN32 event objects would be an option if HAVE_CONCURRENCY is not defined. I could even imagine doing it with sleep/thread yield and InterlockedCompareExchange yet I am not enthusiastic about that approach either. Since there is a specific compiler HAVE_ for concurrency, I do not like pulling it in though I think for WinRT it is safe to say we will always have it available though should probably conditionally compile with the Interlocked option as WIN32 events would require HAVE_WIN32.
It looks like C++/CX cannot be used for the IMediaExtension sink (which should not be a problem) as using COM objects requires WRL and though deriving from IMediaExtension can be done, there is little purpose without COM. Objects from C++/CX can be swapped to interact with objects from native C++ as Inspectable* can reinterpret_cast to the ref object IInspectable^ and vice-versa. A solution to the COM class with C++/CX would be great so we could have dual support. Also without #define for every WRL object in use, the code will get quite muddy given that the */^ would need to be ifdef'd everywhere.
Update cap_msmf.cpp
Fixed bugs and completed the change. I believe the new classes need to be moved to a header file as the file has become to large and more classes need to be added for handling all the asynchronous problems (one wrapping IAsyncAction in a task and another for making a task out of IAsyncAction). Unfortunately, blocking on the UI thread is not an option in WinRT so a synchronous architecture is considered "illegal" by Microsoft's standards even if implementable (C++/CX ppltasks library throws errors if you try it). Worse, either by design or a bug in the MF MediaCapture class with Custom Sinks causes a crash if stop/start previewing without reinitializing (spPreferredPreviewMediaType is fatally nulled). After decompiling Windows.Media.dll, I worked around this in my own projects by using an activate-able custom sink ID which strangely assigns 1 to this pointer allowing it to be reinitialized in what can only be described as a hack by Microsoft. This would add additional overhead to the project to implement especially for static libraries as it requires IDL/DLL exporting followed by manifest declaration. Better to document that it is not supported.
Furthermore, an additional class for IMFAttributes should be implemented to make clean architecture for passing around attributes as opposed to directly calling non-COM interface calls on the objects and making use of SetProperties which would also be a set up for an object that uses the RuntimeClass activation ID.
The remaining changes are not difficult and will be complete soon along with debug tracing messages.
Update cap_msmf.cpp
Create cap_msmf.h
Update cap_msmf.cpp
Update cap_msmf.h
Update cap_msmf.cpp
Update cap_msmf.h
Update and rename cap_msmf.h to cap_msmf.hpp
Update cap_msmf.cpp
Update CMakeLists.txt
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.cpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Successful test - samples are grabbed
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Create ppltasks_winrt.h
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update ppltasks_winrt.h
Library updated and cleaned up with comments, marshaling, exceptions and linker settings
Update ppltasks_winrt.h
Fixed trailing whitespace
2013-12-14 16:53:30 +08:00
|
|
|
RawImage *ImageGrabberCallback::getRawImage()
|
2013-04-03 09:01:20 +08:00
|
|
|
{
|
|
|
|
return ig_RIOut;
|
|
|
|
}
|
2013-04-16 21:25:10 +08:00
|
|
|
|
2013-04-03 09:01:20 +08:00
|
|
|
DWORD WINAPI MainThreadFunction( LPVOID lpParam )
|
|
|
|
{
|
|
|
|
ImageGrabberThread *pIGT = (ImageGrabberThread *)lpParam;
|
|
|
|
pIGT->run();
|
2013-04-03 18:48:23 +08:00
|
|
|
return 0;
|
2013-04-03 09:01:20 +08:00
|
|
|
}
|
2013-04-16 21:25:10 +08:00
|
|
|
|
2013-05-15 20:12:25 +08:00
|
|
|
HRESULT ImageGrabberThread::CreateInstance(ImageGrabberThread **ppIGT, IMFMediaSource *pSource, unsigned int deviceID, bool synchronious)
|
2013-04-03 09:01:20 +08:00
|
|
|
{
|
|
|
|
DebugPrintOut *DPO = &DebugPrintOut::getInstance();
|
2013-05-15 20:12:25 +08:00
|
|
|
*ppIGT = new (std::nothrow) ImageGrabberThread(pSource, deviceID, synchronious);
|
2013-04-03 09:01:20 +08:00
|
|
|
if (ppIGT == NULL)
|
|
|
|
{
|
|
|
|
DPO->printOut(L"IMAGEGRABBERTHREAD VIDEODEVICE %i: Memory cannot be allocated\n", deviceID);
|
|
|
|
return E_OUTOFMEMORY;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
DPO->printOut(L"IMAGEGRABBERTHREAD VIDEODEVICE %i: Creating of the instance of ImageGrabberThread\n", deviceID);
|
|
|
|
return S_OK;
|
|
|
|
}
|
2013-04-16 21:25:10 +08:00
|
|
|
|
Update cap_msmf.cpp
Add support for WinRT in the MF capture framework by removing the disallowed calls to enumerate devices and create a sample grabber sink and adding framework for the MediaCapture interface and a custom sink which interfaces with the sample grabber callback interface. The change requires discussion for making it completely functional as redundancy is required given that if the source is a video file, the old code pathways must be used. Otherwise all IMFMediaSession, IMFMediaSource, and IMFActivate code must use a MediaCapture code path and all sink code must use the CMediaSink custom sink.
Support for the custom sink is extended to non-WinRT not for compatibility as Windows Vista client is a minimum regardless, but because it offers more flexibility, could be faster and is able to be used as an optionally different code path during sink creation based on a future configuration parameter.
My discussion and proposal to finish this change:
Devices are so easily enumerated through WinRT Windows.Devices namespace that wrapping the calls in a library is quite a chore for little benefit though to get the various modes and formats could still be a worthwhile project. For now conditional compilation to remove videodevices and any offending non-video file related activity in videodevice. In my opinion, this is a different , far less fundamental and important change which can possibly be done as a future project and also much more easily implemented in C++/CX.
ImageGrabber has the IMFSampleGrabberSinkCallback replaced with a base class (SharedSampleGrabber) which also be is base class for ImageGrabberRT. This change is necessary as the custom sink does not require a thread to pump events which is done through MediaCapture already. IMFSampleGrabberSinkCallback is the common element between both models and that piece can be shared. Initializing the new ImageGrabberRT is as simple as passing an already initialized MediaCapture object and any video format/encoding parameters.
The concurrency event is necessary to wait for completion and is the way the underlying, IAsyncAction wrappers in the task library work as well. Native WIN32 event objects would be an option if HAVE_CONCURRENCY is not defined. I could even imagine doing it with sleep/thread yield and InterlockedCompareExchange yet I am not enthusiastic about that approach either. Since there is a specific compiler HAVE_ for concurrency, I do not like pulling it in though I think for WinRT it is safe to say we will always have it available though should probably conditionally compile with the Interlocked option as WIN32 events would require HAVE_WIN32.
It looks like C++/CX cannot be used for the IMediaExtension sink (which should not be a problem) as using COM objects requires WRL and though deriving from IMediaExtension can be done, there is little purpose without COM. Objects from C++/CX can be swapped to interact with objects from native C++ as Inspectable* can reinterpret_cast to the ref object IInspectable^ and vice-versa. A solution to the COM class with C++/CX would be great so we could have dual support. Also without #define for every WRL object in use, the code will get quite muddy given that the */^ would need to be ifdef'd everywhere.
Update cap_msmf.cpp
Fixed bugs and completed the change. I believe the new classes need to be moved to a header file as the file has become to large and more classes need to be added for handling all the asynchronous problems (one wrapping IAsyncAction in a task and another for making a task out of IAsyncAction). Unfortunately, blocking on the UI thread is not an option in WinRT so a synchronous architecture is considered "illegal" by Microsoft's standards even if implementable (C++/CX ppltasks library throws errors if you try it). Worse, either by design or a bug in the MF MediaCapture class with Custom Sinks causes a crash if stop/start previewing without reinitializing (spPreferredPreviewMediaType is fatally nulled). After decompiling Windows.Media.dll, I worked around this in my own projects by using an activate-able custom sink ID which strangely assigns 1 to this pointer allowing it to be reinitialized in what can only be described as a hack by Microsoft. This would add additional overhead to the project to implement especially for static libraries as it requires IDL/DLL exporting followed by manifest declaration. Better to document that it is not supported.
Furthermore, an additional class for IMFAttributes should be implemented to make clean architecture for passing around attributes as opposed to directly calling non-COM interface calls on the objects and making use of SetProperties which would also be a set up for an object that uses the RuntimeClass activation ID.
The remaining changes are not difficult and will be complete soon along with debug tracing messages.
Update cap_msmf.cpp
Create cap_msmf.h
Update cap_msmf.cpp
Update cap_msmf.h
Update cap_msmf.cpp
Update cap_msmf.h
Update and rename cap_msmf.h to cap_msmf.hpp
Update cap_msmf.cpp
Update CMakeLists.txt
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.cpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Successful test - samples are grabbed
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Create ppltasks_winrt.h
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update ppltasks_winrt.h
Library updated and cleaned up with comments, marshaling, exceptions and linker settings
Update ppltasks_winrt.h
Fixed trailing whitespace
2013-12-14 16:53:30 +08:00
|
|
|
ImageGrabberThread::ImageGrabberThread(IMFMediaSource *pSource, unsigned int deviceID, bool synchronious) :
|
2013-05-15 20:12:25 +08:00
|
|
|
igt_func(NULL),
|
|
|
|
igt_Handle(NULL),
|
|
|
|
igt_stop(false)
|
2013-04-03 09:01:20 +08:00
|
|
|
{
|
|
|
|
DebugPrintOut *DPO = &DebugPrintOut::getInstance();
|
2013-05-15 20:12:25 +08:00
|
|
|
HRESULT hr = ImageGrabber::CreateInstance(&igt_pImageGrabber, deviceID, synchronious);
|
2013-04-03 09:01:20 +08:00
|
|
|
igt_DeviceID = deviceID;
|
|
|
|
if(SUCCEEDED(hr))
|
|
|
|
{
|
|
|
|
hr = igt_pImageGrabber->initImageGrabber(pSource, MFVideoFormat_RGB24);
|
|
|
|
if(!SUCCEEDED(hr))
|
|
|
|
{
|
|
|
|
DPO->printOut(L"IMAGEGRABBERTHREAD VIDEODEVICE %i: There is a problem with initialization of the instance of the ImageGrabber class\n", deviceID);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
DPO->printOut(L"IMAGEGRABBERTHREAD VIDEODEVICE %i: Initialization of instance of the ImageGrabber class\n", deviceID);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
Update cap_msmf.cpp
Add support for WinRT in the MF capture framework by removing the disallowed calls to enumerate devices and create a sample grabber sink and adding framework for the MediaCapture interface and a custom sink which interfaces with the sample grabber callback interface. The change requires discussion for making it completely functional as redundancy is required given that if the source is a video file, the old code pathways must be used. Otherwise all IMFMediaSession, IMFMediaSource, and IMFActivate code must use a MediaCapture code path and all sink code must use the CMediaSink custom sink.
Support for the custom sink is extended to non-WinRT not for compatibility as Windows Vista client is a minimum regardless, but because it offers more flexibility, could be faster and is able to be used as an optionally different code path during sink creation based on a future configuration parameter.
My discussion and proposal to finish this change:
Devices are so easily enumerated through WinRT Windows.Devices namespace that wrapping the calls in a library is quite a chore for little benefit though to get the various modes and formats could still be a worthwhile project. For now conditional compilation to remove videodevices and any offending non-video file related activity in videodevice. In my opinion, this is a different , far less fundamental and important change which can possibly be done as a future project and also much more easily implemented in C++/CX.
ImageGrabber has the IMFSampleGrabberSinkCallback replaced with a base class (SharedSampleGrabber) which also be is base class for ImageGrabberRT. This change is necessary as the custom sink does not require a thread to pump events which is done through MediaCapture already. IMFSampleGrabberSinkCallback is the common element between both models and that piece can be shared. Initializing the new ImageGrabberRT is as simple as passing an already initialized MediaCapture object and any video format/encoding parameters.
The concurrency event is necessary to wait for completion and is the way the underlying, IAsyncAction wrappers in the task library work as well. Native WIN32 event objects would be an option if HAVE_CONCURRENCY is not defined. I could even imagine doing it with sleep/thread yield and InterlockedCompareExchange yet I am not enthusiastic about that approach either. Since there is a specific compiler HAVE_ for concurrency, I do not like pulling it in though I think for WinRT it is safe to say we will always have it available though should probably conditionally compile with the Interlocked option as WIN32 events would require HAVE_WIN32.
It looks like C++/CX cannot be used for the IMediaExtension sink (which should not be a problem) as using COM objects requires WRL and though deriving from IMediaExtension can be done, there is little purpose without COM. Objects from C++/CX can be swapped to interact with objects from native C++ as Inspectable* can reinterpret_cast to the ref object IInspectable^ and vice-versa. A solution to the COM class with C++/CX would be great so we could have dual support. Also without #define for every WRL object in use, the code will get quite muddy given that the */^ would need to be ifdef'd everywhere.
Update cap_msmf.cpp
Fixed bugs and completed the change. I believe the new classes need to be moved to a header file as the file has become to large and more classes need to be added for handling all the asynchronous problems (one wrapping IAsyncAction in a task and another for making a task out of IAsyncAction). Unfortunately, blocking on the UI thread is not an option in WinRT so a synchronous architecture is considered "illegal" by Microsoft's standards even if implementable (C++/CX ppltasks library throws errors if you try it). Worse, either by design or a bug in the MF MediaCapture class with Custom Sinks causes a crash if stop/start previewing without reinitializing (spPreferredPreviewMediaType is fatally nulled). After decompiling Windows.Media.dll, I worked around this in my own projects by using an activate-able custom sink ID which strangely assigns 1 to this pointer allowing it to be reinitialized in what can only be described as a hack by Microsoft. This would add additional overhead to the project to implement especially for static libraries as it requires IDL/DLL exporting followed by manifest declaration. Better to document that it is not supported.
Furthermore, an additional class for IMFAttributes should be implemented to make clean architecture for passing around attributes as opposed to directly calling non-COM interface calls on the objects and making use of SetProperties which would also be a set up for an object that uses the RuntimeClass activation ID.
The remaining changes are not difficult and will be complete soon along with debug tracing messages.
Update cap_msmf.cpp
Create cap_msmf.h
Update cap_msmf.cpp
Update cap_msmf.h
Update cap_msmf.cpp
Update cap_msmf.h
Update and rename cap_msmf.h to cap_msmf.hpp
Update cap_msmf.cpp
Update CMakeLists.txt
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.cpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Successful test - samples are grabbed
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Create ppltasks_winrt.h
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update ppltasks_winrt.h
Library updated and cleaned up with comments, marshaling, exceptions and linker settings
Update ppltasks_winrt.h
Fixed trailing whitespace
2013-12-14 16:53:30 +08:00
|
|
|
DPO->printOut(L"IMAGEGRABBERTHREAD VIDEODEVICE %i: There is a problem with creation of the instance of the ImageGrabber class\n", deviceID);
|
2013-04-03 09:01:20 +08:00
|
|
|
}
|
|
|
|
}
|
2013-04-16 21:25:10 +08:00
|
|
|
|
2013-04-03 09:01:20 +08:00
|
|
|
void ImageGrabberThread::setEmergencyStopEvent(void *userData, void(*func)(int, void *))
|
|
|
|
{
|
|
|
|
if(func)
|
|
|
|
{
|
|
|
|
igt_func = func;
|
|
|
|
igt_userData = userData;
|
|
|
|
}
|
|
|
|
}
|
2013-04-16 21:25:10 +08:00
|
|
|
|
2013-04-03 09:01:20 +08:00
|
|
|
ImageGrabberThread::~ImageGrabberThread(void)
|
|
|
|
{
|
|
|
|
DebugPrintOut *DPO = &DebugPrintOut::getInstance();
|
|
|
|
DPO->printOut(L"IMAGEGRABBERTHREAD VIDEODEVICE %i: Destroing ImageGrabberThread\n", igt_DeviceID);
|
2013-05-22 19:21:23 +08:00
|
|
|
if (igt_Handle)
|
|
|
|
WaitForSingleObject(igt_Handle, INFINITE);
|
2013-04-03 09:01:20 +08:00
|
|
|
delete igt_pImageGrabber;
|
|
|
|
}
|
2013-04-16 21:25:10 +08:00
|
|
|
|
2013-04-03 09:01:20 +08:00
|
|
|
void ImageGrabberThread::stop()
|
|
|
|
{
|
|
|
|
igt_stop = true;
|
|
|
|
if(igt_pImageGrabber)
|
|
|
|
{
|
|
|
|
igt_pImageGrabber->stopGrabbing();
|
|
|
|
}
|
|
|
|
}
|
2013-04-16 21:25:10 +08:00
|
|
|
|
2013-04-03 09:01:20 +08:00
|
|
|
void ImageGrabberThread::start()
|
|
|
|
{
|
2013-04-03 18:48:23 +08:00
|
|
|
igt_Handle = CreateThread(
|
2013-05-14 20:17:34 +08:00
|
|
|
NULL, // default security attributes
|
|
|
|
0, // use default stack size
|
|
|
|
MainThreadFunction, // thread function name
|
|
|
|
this, // argument to thread function
|
|
|
|
0, // use default creation flags
|
2013-04-03 18:48:23 +08:00
|
|
|
&igt_ThreadIdArray); // returns the thread identifier
|
2013-04-03 09:01:20 +08:00
|
|
|
}
|
2013-04-16 21:25:10 +08:00
|
|
|
|
2013-04-03 09:01:20 +08:00
|
|
|
void ImageGrabberThread::run()
|
|
|
|
{
|
|
|
|
DebugPrintOut *DPO = &DebugPrintOut::getInstance();
|
|
|
|
if(igt_pImageGrabber)
|
|
|
|
{
|
|
|
|
DPO->printOut(L"IMAGEGRABBERTHREAD VIDEODEVICE %i: Thread for grabbing images is started\n", igt_DeviceID);
|
|
|
|
HRESULT hr = igt_pImageGrabber->startGrabbing();
|
2013-04-03 18:48:23 +08:00
|
|
|
if(!SUCCEEDED(hr))
|
2013-04-03 09:01:20 +08:00
|
|
|
{
|
|
|
|
DPO->printOut(L"IMAGEGRABBERTHREAD VIDEODEVICE %i: There is a problem with starting the process of grabbing\n", igt_DeviceID);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
DPO->printOut(L"IMAGEGRABBERTHREAD VIDEODEVICE %i The thread is finished without execution of grabbing\n", igt_DeviceID);
|
|
|
|
}
|
|
|
|
if(!igt_stop)
|
|
|
|
{
|
|
|
|
DPO->printOut(L"IMAGEGRABBERTHREAD VIDEODEVICE %i: Emergency Stop thread\n", igt_DeviceID);
|
|
|
|
if(igt_func)
|
|
|
|
{
|
|
|
|
igt_func(igt_DeviceID, igt_userData);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
DPO->printOut(L"IMAGEGRABBERTHREAD VIDEODEVICE %i: Finish thread\n", igt_DeviceID);
|
|
|
|
}
|
2013-04-16 21:25:10 +08:00
|
|
|
|
2013-04-03 09:01:20 +08:00
|
|
|
ImageGrabber *ImageGrabberThread::getImageGrabber()
|
|
|
|
{
|
|
|
|
return igt_pImageGrabber;
|
|
|
|
}
|
2013-04-16 21:25:10 +08:00
|
|
|
|
2013-04-03 09:01:20 +08:00
|
|
|
Media_Foundation::Media_Foundation(void)
|
|
|
|
{
|
|
|
|
HRESULT hr = MFStartup(MF_VERSION);
|
|
|
|
if(!SUCCEEDED(hr))
|
|
|
|
{
|
|
|
|
DebugPrintOut *DPO = &DebugPrintOut::getInstance();
|
|
|
|
DPO->printOut(L"MEDIA FOUNDATION: It cannot be created!!!\n");
|
|
|
|
}
|
|
|
|
}
|
2013-04-16 21:25:10 +08:00
|
|
|
|
2013-04-03 09:01:20 +08:00
|
|
|
Media_Foundation::~Media_Foundation(void)
|
|
|
|
{
|
|
|
|
HRESULT hr = MFShutdown();
|
|
|
|
if(!SUCCEEDED(hr))
|
|
|
|
{
|
|
|
|
DebugPrintOut *DPO = &DebugPrintOut::getInstance();
|
|
|
|
DPO->printOut(L"MEDIA FOUNDATION: Resources cannot be released\n");
|
|
|
|
}
|
|
|
|
}
|
2013-04-16 21:25:10 +08:00
|
|
|
|
2013-04-03 09:01:20 +08:00
|
|
|
bool Media_Foundation::buildListOfDevices()
|
|
|
|
{
|
|
|
|
HRESULT hr = S_OK;
|
Update cap_msmf.cpp
Add support for WinRT in the MF capture framework by removing the disallowed calls to enumerate devices and create a sample grabber sink and adding framework for the MediaCapture interface and a custom sink which interfaces with the sample grabber callback interface. The change requires discussion for making it completely functional as redundancy is required given that if the source is a video file, the old code pathways must be used. Otherwise all IMFMediaSession, IMFMediaSource, and IMFActivate code must use a MediaCapture code path and all sink code must use the CMediaSink custom sink.
Support for the custom sink is extended to non-WinRT not for compatibility as Windows Vista client is a minimum regardless, but because it offers more flexibility, could be faster and is able to be used as an optionally different code path during sink creation based on a future configuration parameter.
My discussion and proposal to finish this change:
Devices are so easily enumerated through WinRT Windows.Devices namespace that wrapping the calls in a library is quite a chore for little benefit though to get the various modes and formats could still be a worthwhile project. For now conditional compilation to remove videodevices and any offending non-video file related activity in videodevice. In my opinion, this is a different , far less fundamental and important change which can possibly be done as a future project and also much more easily implemented in C++/CX.
ImageGrabber has the IMFSampleGrabberSinkCallback replaced with a base class (SharedSampleGrabber) which also be is base class for ImageGrabberRT. This change is necessary as the custom sink does not require a thread to pump events which is done through MediaCapture already. IMFSampleGrabberSinkCallback is the common element between both models and that piece can be shared. Initializing the new ImageGrabberRT is as simple as passing an already initialized MediaCapture object and any video format/encoding parameters.
The concurrency event is necessary to wait for completion and is the way the underlying, IAsyncAction wrappers in the task library work as well. Native WIN32 event objects would be an option if HAVE_CONCURRENCY is not defined. I could even imagine doing it with sleep/thread yield and InterlockedCompareExchange yet I am not enthusiastic about that approach either. Since there is a specific compiler HAVE_ for concurrency, I do not like pulling it in though I think for WinRT it is safe to say we will always have it available though should probably conditionally compile with the Interlocked option as WIN32 events would require HAVE_WIN32.
It looks like C++/CX cannot be used for the IMediaExtension sink (which should not be a problem) as using COM objects requires WRL and though deriving from IMediaExtension can be done, there is little purpose without COM. Objects from C++/CX can be swapped to interact with objects from native C++ as Inspectable* can reinterpret_cast to the ref object IInspectable^ and vice-versa. A solution to the COM class with C++/CX would be great so we could have dual support. Also without #define for every WRL object in use, the code will get quite muddy given that the */^ would need to be ifdef'd everywhere.
Update cap_msmf.cpp
Fixed bugs and completed the change. I believe the new classes need to be moved to a header file as the file has become to large and more classes need to be added for handling all the asynchronous problems (one wrapping IAsyncAction in a task and another for making a task out of IAsyncAction). Unfortunately, blocking on the UI thread is not an option in WinRT so a synchronous architecture is considered "illegal" by Microsoft's standards even if implementable (C++/CX ppltasks library throws errors if you try it). Worse, either by design or a bug in the MF MediaCapture class with Custom Sinks causes a crash if stop/start previewing without reinitializing (spPreferredPreviewMediaType is fatally nulled). After decompiling Windows.Media.dll, I worked around this in my own projects by using an activate-able custom sink ID which strangely assigns 1 to this pointer allowing it to be reinitialized in what can only be described as a hack by Microsoft. This would add additional overhead to the project to implement especially for static libraries as it requires IDL/DLL exporting followed by manifest declaration. Better to document that it is not supported.
Furthermore, an additional class for IMFAttributes should be implemented to make clean architecture for passing around attributes as opposed to directly calling non-COM interface calls on the objects and making use of SetProperties which would also be a set up for an object that uses the RuntimeClass activation ID.
The remaining changes are not difficult and will be complete soon along with debug tracing messages.
Update cap_msmf.cpp
Create cap_msmf.h
Update cap_msmf.cpp
Update cap_msmf.h
Update cap_msmf.cpp
Update cap_msmf.h
Update and rename cap_msmf.h to cap_msmf.hpp
Update cap_msmf.cpp
Update CMakeLists.txt
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.cpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Successful test - samples are grabbed
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Create ppltasks_winrt.h
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update ppltasks_winrt.h
Library updated and cleaned up with comments, marshaling, exceptions and linker settings
Update ppltasks_winrt.h
Fixed trailing whitespace
2013-12-14 16:53:30 +08:00
|
|
|
#ifdef HAVE_WINRT
|
|
|
|
videoDevices *vDs = &videoDevices::getInstance();
|
|
|
|
hr = vDs->initDevices(_VideoCapture);
|
|
|
|
#else
|
2013-05-15 21:09:03 +08:00
|
|
|
ComPtr<IMFAttributes> pAttributes = NULL;
|
2013-04-03 09:01:20 +08:00
|
|
|
CoInitialize(NULL);
|
2013-05-15 21:09:03 +08:00
|
|
|
hr = MFCreateAttributes(pAttributes.GetAddressOf(), 1);
|
2013-04-03 09:01:20 +08:00
|
|
|
if (SUCCEEDED(hr))
|
|
|
|
{
|
|
|
|
hr = pAttributes->SetGUID(
|
|
|
|
MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE,
|
|
|
|
MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_GUID
|
|
|
|
);
|
|
|
|
}
|
|
|
|
if (SUCCEEDED(hr))
|
|
|
|
{
|
|
|
|
videoDevices *vDs = &videoDevices::getInstance();
|
2013-05-15 21:09:03 +08:00
|
|
|
hr = vDs->initDevices(pAttributes.Get());
|
2013-04-03 09:01:20 +08:00
|
|
|
}
|
Update cap_msmf.cpp
Add support for WinRT in the MF capture framework by removing the disallowed calls to enumerate devices and create a sample grabber sink and adding framework for the MediaCapture interface and a custom sink which interfaces with the sample grabber callback interface. The change requires discussion for making it completely functional as redundancy is required given that if the source is a video file, the old code pathways must be used. Otherwise all IMFMediaSession, IMFMediaSource, and IMFActivate code must use a MediaCapture code path and all sink code must use the CMediaSink custom sink.
Support for the custom sink is extended to non-WinRT not for compatibility as Windows Vista client is a minimum regardless, but because it offers more flexibility, could be faster and is able to be used as an optionally different code path during sink creation based on a future configuration parameter.
My discussion and proposal to finish this change:
Devices are so easily enumerated through WinRT Windows.Devices namespace that wrapping the calls in a library is quite a chore for little benefit though to get the various modes and formats could still be a worthwhile project. For now conditional compilation to remove videodevices and any offending non-video file related activity in videodevice. In my opinion, this is a different , far less fundamental and important change which can possibly be done as a future project and also much more easily implemented in C++/CX.
ImageGrabber has the IMFSampleGrabberSinkCallback replaced with a base class (SharedSampleGrabber) which also be is base class for ImageGrabberRT. This change is necessary as the custom sink does not require a thread to pump events which is done through MediaCapture already. IMFSampleGrabberSinkCallback is the common element between both models and that piece can be shared. Initializing the new ImageGrabberRT is as simple as passing an already initialized MediaCapture object and any video format/encoding parameters.
The concurrency event is necessary to wait for completion and is the way the underlying, IAsyncAction wrappers in the task library work as well. Native WIN32 event objects would be an option if HAVE_CONCURRENCY is not defined. I could even imagine doing it with sleep/thread yield and InterlockedCompareExchange yet I am not enthusiastic about that approach either. Since there is a specific compiler HAVE_ for concurrency, I do not like pulling it in though I think for WinRT it is safe to say we will always have it available though should probably conditionally compile with the Interlocked option as WIN32 events would require HAVE_WIN32.
It looks like C++/CX cannot be used for the IMediaExtension sink (which should not be a problem) as using COM objects requires WRL and though deriving from IMediaExtension can be done, there is little purpose without COM. Objects from C++/CX can be swapped to interact with objects from native C++ as Inspectable* can reinterpret_cast to the ref object IInspectable^ and vice-versa. A solution to the COM class with C++/CX would be great so we could have dual support. Also without #define for every WRL object in use, the code will get quite muddy given that the */^ would need to be ifdef'd everywhere.
Update cap_msmf.cpp
Fixed bugs and completed the change. I believe the new classes need to be moved to a header file as the file has become to large and more classes need to be added for handling all the asynchronous problems (one wrapping IAsyncAction in a task and another for making a task out of IAsyncAction). Unfortunately, blocking on the UI thread is not an option in WinRT so a synchronous architecture is considered "illegal" by Microsoft's standards even if implementable (C++/CX ppltasks library throws errors if you try it). Worse, either by design or a bug in the MF MediaCapture class with Custom Sinks causes a crash if stop/start previewing without reinitializing (spPreferredPreviewMediaType is fatally nulled). After decompiling Windows.Media.dll, I worked around this in my own projects by using an activate-able custom sink ID which strangely assigns 1 to this pointer allowing it to be reinitialized in what can only be described as a hack by Microsoft. This would add additional overhead to the project to implement especially for static libraries as it requires IDL/DLL exporting followed by manifest declaration. Better to document that it is not supported.
Furthermore, an additional class for IMFAttributes should be implemented to make clean architecture for passing around attributes as opposed to directly calling non-COM interface calls on the objects and making use of SetProperties which would also be a set up for an object that uses the RuntimeClass activation ID.
The remaining changes are not difficult and will be complete soon along with debug tracing messages.
Update cap_msmf.cpp
Create cap_msmf.h
Update cap_msmf.cpp
Update cap_msmf.h
Update cap_msmf.cpp
Update cap_msmf.h
Update and rename cap_msmf.h to cap_msmf.hpp
Update cap_msmf.cpp
Update CMakeLists.txt
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.cpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Successful test - samples are grabbed
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Create ppltasks_winrt.h
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update ppltasks_winrt.h
Library updated and cleaned up with comments, marshaling, exceptions and linker settings
Update ppltasks_winrt.h
Fixed trailing whitespace
2013-12-14 16:53:30 +08:00
|
|
|
#endif
|
|
|
|
if (FAILED(hr))
|
2013-04-03 09:01:20 +08:00
|
|
|
{
|
|
|
|
DebugPrintOut *DPO = &DebugPrintOut::getInstance();
|
|
|
|
DPO->printOut(L"MEDIA FOUNDATION: The access to the video cameras denied\n");
|
|
|
|
}
|
2013-05-15 21:09:03 +08:00
|
|
|
|
2013-04-03 09:01:20 +08:00
|
|
|
return (SUCCEEDED(hr));
|
|
|
|
}
|
2013-04-16 21:25:10 +08:00
|
|
|
|
2013-04-03 09:01:20 +08:00
|
|
|
Media_Foundation& Media_Foundation::getInstance()
|
|
|
|
{
|
|
|
|
static Media_Foundation instance;
|
|
|
|
return instance;
|
|
|
|
}
|
2013-04-16 21:25:10 +08:00
|
|
|
|
2013-04-03 09:01:20 +08:00
|
|
|
RawImage::RawImage(unsigned int size): ri_new(false), ri_pixels(NULL)
|
|
|
|
{
|
|
|
|
ri_size = size;
|
|
|
|
ri_pixels = new unsigned char[size];
|
|
|
|
memset((void *)ri_pixels,0,ri_size);
|
|
|
|
}
|
2013-04-16 21:25:10 +08:00
|
|
|
|
2013-04-03 09:01:20 +08:00
|
|
|
bool RawImage::isNew()
|
|
|
|
{
|
|
|
|
return ri_new;
|
|
|
|
}
|
2013-04-16 21:25:10 +08:00
|
|
|
|
2013-04-03 09:01:20 +08:00
|
|
|
unsigned int RawImage::getSize()
|
|
|
|
{
|
|
|
|
return ri_size;
|
|
|
|
}
|
2013-04-16 21:25:10 +08:00
|
|
|
|
2013-04-03 09:01:20 +08:00
|
|
|
RawImage::~RawImage(void)
|
|
|
|
{
|
|
|
|
delete []ri_pixels;
|
|
|
|
ri_pixels = NULL;
|
|
|
|
}
|
2013-04-16 21:25:10 +08:00
|
|
|
|
2013-04-03 09:01:20 +08:00
|
|
|
long RawImage::CreateInstance(RawImage **ppRImage,unsigned int size)
|
|
|
|
{
|
|
|
|
*ppRImage = new (std::nothrow) RawImage(size);
|
|
|
|
if (ppRImage == NULL)
|
|
|
|
{
|
|
|
|
return E_OUTOFMEMORY;
|
|
|
|
}
|
|
|
|
return S_OK;
|
|
|
|
}
|
2013-04-16 21:25:10 +08:00
|
|
|
|
2013-04-03 09:01:20 +08:00
|
|
|
void RawImage::setCopy(const BYTE * pSampleBuffer)
|
|
|
|
{
|
|
|
|
memcpy(ri_pixels, pSampleBuffer, ri_size);
|
|
|
|
ri_new = true;
|
|
|
|
}
|
2013-04-16 21:25:10 +08:00
|
|
|
|
2013-04-03 09:01:20 +08:00
|
|
|
void RawImage::fastCopy(const BYTE * pSampleBuffer)
|
|
|
|
{
|
|
|
|
memcpy(ri_pixels, pSampleBuffer, ri_size);
|
|
|
|
ri_new = true;
|
|
|
|
}
|
2013-04-16 21:25:10 +08:00
|
|
|
|
2013-04-03 09:01:20 +08:00
|
|
|
unsigned char * RawImage::getpPixels()
|
|
|
|
{
|
|
|
|
ri_new = false;
|
|
|
|
return ri_pixels;
|
|
|
|
}
|
2013-04-16 21:25:10 +08:00
|
|
|
|
2013-04-03 09:01:20 +08:00
|
|
|
videoDevice::videoDevice(void): vd_IsSetuped(false), vd_LockOut(OpenLock), vd_pFriendlyName(NULL),
|
Update cap_msmf.cpp
Add support for WinRT in the MF capture framework by removing the disallowed calls to enumerate devices and create a sample grabber sink and adding framework for the MediaCapture interface and a custom sink which interfaces with the sample grabber callback interface. The change requires discussion for making it completely functional as redundancy is required given that if the source is a video file, the old code pathways must be used. Otherwise all IMFMediaSession, IMFMediaSource, and IMFActivate code must use a MediaCapture code path and all sink code must use the CMediaSink custom sink.
Support for the custom sink is extended to non-WinRT not for compatibility as Windows Vista client is a minimum regardless, but because it offers more flexibility, could be faster and is able to be used as an optionally different code path during sink creation based on a future configuration parameter.
My discussion and proposal to finish this change:
Devices are so easily enumerated through WinRT Windows.Devices namespace that wrapping the calls in a library is quite a chore for little benefit though to get the various modes and formats could still be a worthwhile project. For now conditional compilation to remove videodevices and any offending non-video file related activity in videodevice. In my opinion, this is a different , far less fundamental and important change which can possibly be done as a future project and also much more easily implemented in C++/CX.
ImageGrabber has the IMFSampleGrabberSinkCallback replaced with a base class (SharedSampleGrabber) which also be is base class for ImageGrabberRT. This change is necessary as the custom sink does not require a thread to pump events which is done through MediaCapture already. IMFSampleGrabberSinkCallback is the common element between both models and that piece can be shared. Initializing the new ImageGrabberRT is as simple as passing an already initialized MediaCapture object and any video format/encoding parameters.
The concurrency event is necessary to wait for completion and is the way the underlying, IAsyncAction wrappers in the task library work as well. Native WIN32 event objects would be an option if HAVE_CONCURRENCY is not defined. I could even imagine doing it with sleep/thread yield and InterlockedCompareExchange yet I am not enthusiastic about that approach either. Since there is a specific compiler HAVE_ for concurrency, I do not like pulling it in though I think for WinRT it is safe to say we will always have it available though should probably conditionally compile with the Interlocked option as WIN32 events would require HAVE_WIN32.
It looks like C++/CX cannot be used for the IMediaExtension sink (which should not be a problem) as using COM objects requires WRL and though deriving from IMediaExtension can be done, there is little purpose without COM. Objects from C++/CX can be swapped to interact with objects from native C++ as Inspectable* can reinterpret_cast to the ref object IInspectable^ and vice-versa. A solution to the COM class with C++/CX would be great so we could have dual support. Also without #define for every WRL object in use, the code will get quite muddy given that the */^ would need to be ifdef'd everywhere.
Update cap_msmf.cpp
Fixed bugs and completed the change. I believe the new classes need to be moved to a header file as the file has become to large and more classes need to be added for handling all the asynchronous problems (one wrapping IAsyncAction in a task and another for making a task out of IAsyncAction). Unfortunately, blocking on the UI thread is not an option in WinRT so a synchronous architecture is considered "illegal" by Microsoft's standards even if implementable (C++/CX ppltasks library throws errors if you try it). Worse, either by design or a bug in the MF MediaCapture class with Custom Sinks causes a crash if stop/start previewing without reinitializing (spPreferredPreviewMediaType is fatally nulled). After decompiling Windows.Media.dll, I worked around this in my own projects by using an activate-able custom sink ID which strangely assigns 1 to this pointer allowing it to be reinitialized in what can only be described as a hack by Microsoft. This would add additional overhead to the project to implement especially for static libraries as it requires IDL/DLL exporting followed by manifest declaration. Better to document that it is not supported.
Furthermore, an additional class for IMFAttributes should be implemented to make clean architecture for passing around attributes as opposed to directly calling non-COM interface calls on the objects and making use of SetProperties which would also be a set up for an object that uses the RuntimeClass activation ID.
The remaining changes are not difficult and will be complete soon along with debug tracing messages.
Update cap_msmf.cpp
Create cap_msmf.h
Update cap_msmf.cpp
Update cap_msmf.h
Update cap_msmf.cpp
Update cap_msmf.h
Update and rename cap_msmf.h to cap_msmf.hpp
Update cap_msmf.cpp
Update CMakeLists.txt
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.cpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Successful test - samples are grabbed
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Create ppltasks_winrt.h
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update ppltasks_winrt.h
Library updated and cleaned up with comments, marshaling, exceptions and linker settings
Update ppltasks_winrt.h
Fixed trailing whitespace
2013-12-14 16:53:30 +08:00
|
|
|
vd_Width(0), vd_Height(0), vd_pSource(NULL), vd_pImGrTh(NULL), vd_func(NULL), vd_userData(NULL)
|
2013-04-03 09:01:20 +08:00
|
|
|
{
|
Update cap_msmf.cpp
Add support for WinRT in the MF capture framework by removing the disallowed calls to enumerate devices and create a sample grabber sink and adding framework for the MediaCapture interface and a custom sink which interfaces with the sample grabber callback interface. The change requires discussion for making it completely functional as redundancy is required given that if the source is a video file, the old code pathways must be used. Otherwise all IMFMediaSession, IMFMediaSource, and IMFActivate code must use a MediaCapture code path and all sink code must use the CMediaSink custom sink.
Support for the custom sink is extended to non-WinRT not for compatibility as Windows Vista client is a minimum regardless, but because it offers more flexibility, could be faster and is able to be used as an optionally different code path during sink creation based on a future configuration parameter.
My discussion and proposal to finish this change:
Devices are so easily enumerated through WinRT Windows.Devices namespace that wrapping the calls in a library is quite a chore for little benefit though to get the various modes and formats could still be a worthwhile project. For now conditional compilation to remove videodevices and any offending non-video file related activity in videodevice. In my opinion, this is a different , far less fundamental and important change which can possibly be done as a future project and also much more easily implemented in C++/CX.
ImageGrabber has the IMFSampleGrabberSinkCallback replaced with a base class (SharedSampleGrabber) which also be is base class for ImageGrabberRT. This change is necessary as the custom sink does not require a thread to pump events which is done through MediaCapture already. IMFSampleGrabberSinkCallback is the common element between both models and that piece can be shared. Initializing the new ImageGrabberRT is as simple as passing an already initialized MediaCapture object and any video format/encoding parameters.
The concurrency event is necessary to wait for completion and is the way the underlying, IAsyncAction wrappers in the task library work as well. Native WIN32 event objects would be an option if HAVE_CONCURRENCY is not defined. I could even imagine doing it with sleep/thread yield and InterlockedCompareExchange yet I am not enthusiastic about that approach either. Since there is a specific compiler HAVE_ for concurrency, I do not like pulling it in though I think for WinRT it is safe to say we will always have it available though should probably conditionally compile with the Interlocked option as WIN32 events would require HAVE_WIN32.
It looks like C++/CX cannot be used for the IMediaExtension sink (which should not be a problem) as using COM objects requires WRL and though deriving from IMediaExtension can be done, there is little purpose without COM. Objects from C++/CX can be swapped to interact with objects from native C++ as Inspectable* can reinterpret_cast to the ref object IInspectable^ and vice-versa. A solution to the COM class with C++/CX would be great so we could have dual support. Also without #define for every WRL object in use, the code will get quite muddy given that the */^ would need to be ifdef'd everywhere.
Update cap_msmf.cpp
Fixed bugs and completed the change. I believe the new classes need to be moved to a header file as the file has become to large and more classes need to be added for handling all the asynchronous problems (one wrapping IAsyncAction in a task and another for making a task out of IAsyncAction). Unfortunately, blocking on the UI thread is not an option in WinRT so a synchronous architecture is considered "illegal" by Microsoft's standards even if implementable (C++/CX ppltasks library throws errors if you try it). Worse, either by design or a bug in the MF MediaCapture class with Custom Sinks causes a crash if stop/start previewing without reinitializing (spPreferredPreviewMediaType is fatally nulled). After decompiling Windows.Media.dll, I worked around this in my own projects by using an activate-able custom sink ID which strangely assigns 1 to this pointer allowing it to be reinitialized in what can only be described as a hack by Microsoft. This would add additional overhead to the project to implement especially for static libraries as it requires IDL/DLL exporting followed by manifest declaration. Better to document that it is not supported.
Furthermore, an additional class for IMFAttributes should be implemented to make clean architecture for passing around attributes as opposed to directly calling non-COM interface calls on the objects and making use of SetProperties which would also be a set up for an object that uses the RuntimeClass activation ID.
The remaining changes are not difficult and will be complete soon along with debug tracing messages.
Update cap_msmf.cpp
Create cap_msmf.h
Update cap_msmf.cpp
Update cap_msmf.h
Update cap_msmf.cpp
Update cap_msmf.h
Update and rename cap_msmf.h to cap_msmf.hpp
Update cap_msmf.cpp
Update CMakeLists.txt
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.cpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Successful test - samples are grabbed
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Create ppltasks_winrt.h
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update ppltasks_winrt.h
Library updated and cleaned up with comments, marshaling, exceptions and linker settings
Update ppltasks_winrt.h
Fixed trailing whitespace
2013-12-14 16:53:30 +08:00
|
|
|
#ifdef HAVE_WINRT
|
|
|
|
vd_pMedCap = nullptr;
|
|
|
|
vd_pMedCapFail = NULL;
|
|
|
|
vd_pImGr = NULL;
|
|
|
|
vd_pAction = nullptr;
|
|
|
|
#endif
|
2013-04-03 09:01:20 +08:00
|
|
|
}
|
2013-04-16 21:25:10 +08:00
|
|
|
|
2013-04-03 09:01:20 +08:00
|
|
|
void videoDevice::setParametrs(CamParametrs parametrs)
|
|
|
|
{
|
|
|
|
if(vd_IsSetuped)
|
|
|
|
{
|
|
|
|
if(vd_pSource)
|
|
|
|
{
|
|
|
|
Parametr *pParametr = (Parametr *)(¶metrs);
|
|
|
|
Parametr *pPrevParametr = (Parametr *)(&vd_PrevParametrs);
|
|
|
|
IAMVideoProcAmp *pProcAmp = NULL;
|
|
|
|
HRESULT hr = vd_pSource->QueryInterface(IID_PPV_ARGS(&pProcAmp));
|
|
|
|
if (SUCCEEDED(hr))
|
|
|
|
{
|
|
|
|
for(unsigned int i = 0; i < 10; i++)
|
|
|
|
{
|
|
|
|
if(pPrevParametr[i].CurrentValue != pParametr[i].CurrentValue || pPrevParametr[i].Flag != pParametr[i].Flag)
|
|
|
|
hr = pProcAmp->Set(VideoProcAmp_Brightness + i, pParametr[i].CurrentValue, pParametr[i].Flag);
|
|
|
|
}
|
|
|
|
pProcAmp->Release();
|
|
|
|
}
|
|
|
|
IAMCameraControl *pProcControl = NULL;
|
|
|
|
hr = vd_pSource->QueryInterface(IID_PPV_ARGS(&pProcControl));
|
|
|
|
if (SUCCEEDED(hr))
|
|
|
|
{
|
|
|
|
for(unsigned int i = 0; i < 7; i++)
|
|
|
|
{
|
|
|
|
if(pPrevParametr[10 + i].CurrentValue != pParametr[10 + i].CurrentValue || pPrevParametr[10 + i].Flag != pParametr[10 + i].Flag)
|
2013-04-03 18:48:23 +08:00
|
|
|
hr = pProcControl->Set(CameraControl_Pan+i, pParametr[10 + i].CurrentValue, pParametr[10 + i].Flag);
|
2013-04-03 09:01:20 +08:00
|
|
|
}
|
|
|
|
pProcControl->Release();
|
|
|
|
}
|
|
|
|
vd_PrevParametrs = parametrs;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2013-04-16 21:25:10 +08:00
|
|
|
|
2013-04-03 09:01:20 +08:00
|
|
|
CamParametrs videoDevice::getParametrs()
|
|
|
|
{
|
|
|
|
CamParametrs out;
|
|
|
|
if(vd_IsSetuped)
|
|
|
|
{
|
|
|
|
if(vd_pSource)
|
|
|
|
{
|
|
|
|
Parametr *pParametr = (Parametr *)(&out);
|
|
|
|
IAMVideoProcAmp *pProcAmp = NULL;
|
|
|
|
HRESULT hr = vd_pSource->QueryInterface(IID_PPV_ARGS(&pProcAmp));
|
|
|
|
if (SUCCEEDED(hr))
|
|
|
|
{
|
|
|
|
for(unsigned int i = 0; i < 10; i++)
|
|
|
|
{
|
|
|
|
Parametr temp;
|
|
|
|
hr = pProcAmp->GetRange(VideoProcAmp_Brightness+i, &temp.Min, &temp.Max, &temp.Step, &temp.Default, &temp.Flag);
|
|
|
|
if (SUCCEEDED(hr))
|
|
|
|
{
|
|
|
|
temp.CurrentValue = temp.Default;
|
|
|
|
pParametr[i] = temp;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
pProcAmp->Release();
|
|
|
|
}
|
|
|
|
IAMCameraControl *pProcControl = NULL;
|
|
|
|
hr = vd_pSource->QueryInterface(IID_PPV_ARGS(&pProcControl));
|
|
|
|
if (SUCCEEDED(hr))
|
|
|
|
{
|
|
|
|
for(unsigned int i = 0; i < 7; i++)
|
|
|
|
{
|
|
|
|
Parametr temp;
|
|
|
|
hr = pProcControl->GetRange(CameraControl_Pan+i, &temp.Min, &temp.Max, &temp.Step, &temp.Default, &temp.Flag);
|
|
|
|
if (SUCCEEDED(hr))
|
|
|
|
{
|
|
|
|
temp.CurrentValue = temp.Default;
|
|
|
|
pParametr[10 + i] = temp;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
pProcControl->Release();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return out;
|
|
|
|
}
|
2013-04-16 21:25:10 +08:00
|
|
|
|
Update cap_msmf.cpp
Add support for WinRT in the MF capture framework by removing the disallowed calls to enumerate devices and create a sample grabber sink and adding framework for the MediaCapture interface and a custom sink which interfaces with the sample grabber callback interface. The change requires discussion for making it completely functional as redundancy is required given that if the source is a video file, the old code pathways must be used. Otherwise all IMFMediaSession, IMFMediaSource, and IMFActivate code must use a MediaCapture code path and all sink code must use the CMediaSink custom sink.
Support for the custom sink is extended to non-WinRT not for compatibility as Windows Vista client is a minimum regardless, but because it offers more flexibility, could be faster and is able to be used as an optionally different code path during sink creation based on a future configuration parameter.
My discussion and proposal to finish this change:
Devices are so easily enumerated through WinRT Windows.Devices namespace that wrapping the calls in a library is quite a chore for little benefit though to get the various modes and formats could still be a worthwhile project. For now conditional compilation to remove videodevices and any offending non-video file related activity in videodevice. In my opinion, this is a different , far less fundamental and important change which can possibly be done as a future project and also much more easily implemented in C++/CX.
ImageGrabber has the IMFSampleGrabberSinkCallback replaced with a base class (SharedSampleGrabber) which also be is base class for ImageGrabberRT. This change is necessary as the custom sink does not require a thread to pump events which is done through MediaCapture already. IMFSampleGrabberSinkCallback is the common element between both models and that piece can be shared. Initializing the new ImageGrabberRT is as simple as passing an already initialized MediaCapture object and any video format/encoding parameters.
The concurrency event is necessary to wait for completion and is the way the underlying, IAsyncAction wrappers in the task library work as well. Native WIN32 event objects would be an option if HAVE_CONCURRENCY is not defined. I could even imagine doing it with sleep/thread yield and InterlockedCompareExchange yet I am not enthusiastic about that approach either. Since there is a specific compiler HAVE_ for concurrency, I do not like pulling it in though I think for WinRT it is safe to say we will always have it available though should probably conditionally compile with the Interlocked option as WIN32 events would require HAVE_WIN32.
It looks like C++/CX cannot be used for the IMediaExtension sink (which should not be a problem) as using COM objects requires WRL and though deriving from IMediaExtension can be done, there is little purpose without COM. Objects from C++/CX can be swapped to interact with objects from native C++ as Inspectable* can reinterpret_cast to the ref object IInspectable^ and vice-versa. A solution to the COM class with C++/CX would be great so we could have dual support. Also without #define for every WRL object in use, the code will get quite muddy given that the */^ would need to be ifdef'd everywhere.
Update cap_msmf.cpp
Fixed bugs and completed the change. I believe the new classes need to be moved to a header file as the file has become to large and more classes need to be added for handling all the asynchronous problems (one wrapping IAsyncAction in a task and another for making a task out of IAsyncAction). Unfortunately, blocking on the UI thread is not an option in WinRT so a synchronous architecture is considered "illegal" by Microsoft's standards even if implementable (C++/CX ppltasks library throws errors if you try it). Worse, either by design or a bug in the MF MediaCapture class with Custom Sinks causes a crash if stop/start previewing without reinitializing (spPreferredPreviewMediaType is fatally nulled). After decompiling Windows.Media.dll, I worked around this in my own projects by using an activate-able custom sink ID which strangely assigns 1 to this pointer allowing it to be reinitialized in what can only be described as a hack by Microsoft. This would add additional overhead to the project to implement especially for static libraries as it requires IDL/DLL exporting followed by manifest declaration. Better to document that it is not supported.
Furthermore, an additional class for IMFAttributes should be implemented to make clean architecture for passing around attributes as opposed to directly calling non-COM interface calls on the objects and making use of SetProperties which would also be a set up for an object that uses the RuntimeClass activation ID.
The remaining changes are not difficult and will be complete soon along with debug tracing messages.
Update cap_msmf.cpp
Create cap_msmf.h
Update cap_msmf.cpp
Update cap_msmf.h
Update cap_msmf.cpp
Update cap_msmf.h
Update and rename cap_msmf.h to cap_msmf.hpp
Update cap_msmf.cpp
Update CMakeLists.txt
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.cpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Successful test - samples are grabbed
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Create ppltasks_winrt.h
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update ppltasks_winrt.h
Library updated and cleaned up with comments, marshaling, exceptions and linker settings
Update ppltasks_winrt.h
Fixed trailing whitespace
2013-12-14 16:53:30 +08:00
|
|
|
#ifdef HAVE_WINRT
|
|
|
|
long videoDevice::resetDevice(MAKE_WRL_REF(_IDeviceInformation) pDevice)
|
|
|
|
#else
|
2013-04-03 09:01:20 +08:00
|
|
|
long videoDevice::resetDevice(IMFActivate *pActivate)
|
Update cap_msmf.cpp
Add support for WinRT in the MF capture framework by removing the disallowed calls to enumerate devices and create a sample grabber sink and adding framework for the MediaCapture interface and a custom sink which interfaces with the sample grabber callback interface. The change requires discussion for making it completely functional as redundancy is required given that if the source is a video file, the old code pathways must be used. Otherwise all IMFMediaSession, IMFMediaSource, and IMFActivate code must use a MediaCapture code path and all sink code must use the CMediaSink custom sink.
Support for the custom sink is extended to non-WinRT not for compatibility as Windows Vista client is a minimum regardless, but because it offers more flexibility, could be faster and is able to be used as an optionally different code path during sink creation based on a future configuration parameter.
My discussion and proposal to finish this change:
Devices are so easily enumerated through WinRT Windows.Devices namespace that wrapping the calls in a library is quite a chore for little benefit though to get the various modes and formats could still be a worthwhile project. For now conditional compilation to remove videodevices and any offending non-video file related activity in videodevice. In my opinion, this is a different , far less fundamental and important change which can possibly be done as a future project and also much more easily implemented in C++/CX.
ImageGrabber has the IMFSampleGrabberSinkCallback replaced with a base class (SharedSampleGrabber) which also be is base class for ImageGrabberRT. This change is necessary as the custom sink does not require a thread to pump events which is done through MediaCapture already. IMFSampleGrabberSinkCallback is the common element between both models and that piece can be shared. Initializing the new ImageGrabberRT is as simple as passing an already initialized MediaCapture object and any video format/encoding parameters.
The concurrency event is necessary to wait for completion and is the way the underlying, IAsyncAction wrappers in the task library work as well. Native WIN32 event objects would be an option if HAVE_CONCURRENCY is not defined. I could even imagine doing it with sleep/thread yield and InterlockedCompareExchange yet I am not enthusiastic about that approach either. Since there is a specific compiler HAVE_ for concurrency, I do not like pulling it in though I think for WinRT it is safe to say we will always have it available though should probably conditionally compile with the Interlocked option as WIN32 events would require HAVE_WIN32.
It looks like C++/CX cannot be used for the IMediaExtension sink (which should not be a problem) as using COM objects requires WRL and though deriving from IMediaExtension can be done, there is little purpose without COM. Objects from C++/CX can be swapped to interact with objects from native C++ as Inspectable* can reinterpret_cast to the ref object IInspectable^ and vice-versa. A solution to the COM class with C++/CX would be great so we could have dual support. Also without #define for every WRL object in use, the code will get quite muddy given that the */^ would need to be ifdef'd everywhere.
Update cap_msmf.cpp
Fixed bugs and completed the change. I believe the new classes need to be moved to a header file as the file has become to large and more classes need to be added for handling all the asynchronous problems (one wrapping IAsyncAction in a task and another for making a task out of IAsyncAction). Unfortunately, blocking on the UI thread is not an option in WinRT so a synchronous architecture is considered "illegal" by Microsoft's standards even if implementable (C++/CX ppltasks library throws errors if you try it). Worse, either by design or a bug in the MF MediaCapture class with Custom Sinks causes a crash if stop/start previewing without reinitializing (spPreferredPreviewMediaType is fatally nulled). After decompiling Windows.Media.dll, I worked around this in my own projects by using an activate-able custom sink ID which strangely assigns 1 to this pointer allowing it to be reinitialized in what can only be described as a hack by Microsoft. This would add additional overhead to the project to implement especially for static libraries as it requires IDL/DLL exporting followed by manifest declaration. Better to document that it is not supported.
Furthermore, an additional class for IMFAttributes should be implemented to make clean architecture for passing around attributes as opposed to directly calling non-COM interface calls on the objects and making use of SetProperties which would also be a set up for an object that uses the RuntimeClass activation ID.
The remaining changes are not difficult and will be complete soon along with debug tracing messages.
Update cap_msmf.cpp
Create cap_msmf.h
Update cap_msmf.cpp
Update cap_msmf.h
Update cap_msmf.cpp
Update cap_msmf.h
Update and rename cap_msmf.h to cap_msmf.hpp
Update cap_msmf.cpp
Update CMakeLists.txt
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.cpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Successful test - samples are grabbed
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Create ppltasks_winrt.h
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update ppltasks_winrt.h
Library updated and cleaned up with comments, marshaling, exceptions and linker settings
Update ppltasks_winrt.h
Fixed trailing whitespace
2013-12-14 16:53:30 +08:00
|
|
|
#endif
|
2013-04-03 09:01:20 +08:00
|
|
|
{
|
|
|
|
HRESULT hr = -1;
|
|
|
|
vd_CurrentFormats.clear();
|
|
|
|
if(vd_pFriendlyName)
|
|
|
|
CoTaskMemFree(vd_pFriendlyName);
|
|
|
|
vd_pFriendlyName = NULL;
|
Update cap_msmf.cpp
Add support for WinRT in the MF capture framework by removing the disallowed calls to enumerate devices and create a sample grabber sink and adding framework for the MediaCapture interface and a custom sink which interfaces with the sample grabber callback interface. The change requires discussion for making it completely functional as redundancy is required given that if the source is a video file, the old code pathways must be used. Otherwise all IMFMediaSession, IMFMediaSource, and IMFActivate code must use a MediaCapture code path and all sink code must use the CMediaSink custom sink.
Support for the custom sink is extended to non-WinRT not for compatibility as Windows Vista client is a minimum regardless, but because it offers more flexibility, could be faster and is able to be used as an optionally different code path during sink creation based on a future configuration parameter.
My discussion and proposal to finish this change:
Devices are so easily enumerated through WinRT Windows.Devices namespace that wrapping the calls in a library is quite a chore for little benefit though to get the various modes and formats could still be a worthwhile project. For now conditional compilation to remove videodevices and any offending non-video file related activity in videodevice. In my opinion, this is a different , far less fundamental and important change which can possibly be done as a future project and also much more easily implemented in C++/CX.
ImageGrabber has the IMFSampleGrabberSinkCallback replaced with a base class (SharedSampleGrabber) which also be is base class for ImageGrabberRT. This change is necessary as the custom sink does not require a thread to pump events which is done through MediaCapture already. IMFSampleGrabberSinkCallback is the common element between both models and that piece can be shared. Initializing the new ImageGrabberRT is as simple as passing an already initialized MediaCapture object and any video format/encoding parameters.
The concurrency event is necessary to wait for completion and is the way the underlying, IAsyncAction wrappers in the task library work as well. Native WIN32 event objects would be an option if HAVE_CONCURRENCY is not defined. I could even imagine doing it with sleep/thread yield and InterlockedCompareExchange yet I am not enthusiastic about that approach either. Since there is a specific compiler HAVE_ for concurrency, I do not like pulling it in though I think for WinRT it is safe to say we will always have it available though should probably conditionally compile with the Interlocked option as WIN32 events would require HAVE_WIN32.
It looks like C++/CX cannot be used for the IMediaExtension sink (which should not be a problem) as using COM objects requires WRL and though deriving from IMediaExtension can be done, there is little purpose without COM. Objects from C++/CX can be swapped to interact with objects from native C++ as Inspectable* can reinterpret_cast to the ref object IInspectable^ and vice-versa. A solution to the COM class with C++/CX would be great so we could have dual support. Also without #define for every WRL object in use, the code will get quite muddy given that the */^ would need to be ifdef'd everywhere.
Update cap_msmf.cpp
Fixed bugs and completed the change. I believe the new classes need to be moved to a header file as the file has become to large and more classes need to be added for handling all the asynchronous problems (one wrapping IAsyncAction in a task and another for making a task out of IAsyncAction). Unfortunately, blocking on the UI thread is not an option in WinRT so a synchronous architecture is considered "illegal" by Microsoft's standards even if implementable (C++/CX ppltasks library throws errors if you try it). Worse, either by design or a bug in the MF MediaCapture class with Custom Sinks causes a crash if stop/start previewing without reinitializing (spPreferredPreviewMediaType is fatally nulled). After decompiling Windows.Media.dll, I worked around this in my own projects by using an activate-able custom sink ID which strangely assigns 1 to this pointer allowing it to be reinitialized in what can only be described as a hack by Microsoft. This would add additional overhead to the project to implement especially for static libraries as it requires IDL/DLL exporting followed by manifest declaration. Better to document that it is not supported.
Furthermore, an additional class for IMFAttributes should be implemented to make clean architecture for passing around attributes as opposed to directly calling non-COM interface calls on the objects and making use of SetProperties which would also be a set up for an object that uses the RuntimeClass activation ID.
The remaining changes are not difficult and will be complete soon along with debug tracing messages.
Update cap_msmf.cpp
Create cap_msmf.h
Update cap_msmf.cpp
Update cap_msmf.h
Update cap_msmf.cpp
Update cap_msmf.h
Update and rename cap_msmf.h to cap_msmf.hpp
Update cap_msmf.cpp
Update CMakeLists.txt
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.cpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Successful test - samples are grabbed
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Create ppltasks_winrt.h
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update ppltasks_winrt.h
Library updated and cleaned up with comments, marshaling, exceptions and linker settings
Update ppltasks_winrt.h
Fixed trailing whitespace
2013-12-14 16:53:30 +08:00
|
|
|
#ifdef HAVE_WINRT
|
|
|
|
if (pDevice)
|
|
|
|
{
|
|
|
|
ACTIVATE_OBJ(RuntimeClass_Windows_Media_Capture_MediaCapture, MAKE_WRL_OBJ(_MediaCapture), pIMedCap, hr)
|
|
|
|
if (FAILED(hr)) return hr;
|
|
|
|
ACTIVATE_OBJ(RuntimeClass_Windows_Media_Capture_MediaCaptureInitializationSettings, MAKE_WRL_OBJ(_MediaCaptureInitializationSettings), pCapInitSet, hr)
|
|
|
|
if (FAILED(hr)) return hr;
|
|
|
|
_StringObj str;
|
|
|
|
WRL_PROP_GET(pDevice, Name, *REF_WRL_OBJ(str), hr)
|
|
|
|
if (FAILED(hr)) return hr;
|
|
|
|
unsigned int length = 0;
|
|
|
|
PCWSTR wstr = WindowsGetStringRawBuffer(reinterpret_cast<HSTRING>(DEREF_WRL_OBJ(str)), &length);
|
|
|
|
vd_pFriendlyName = (wchar_t*)CoTaskMemAlloc((length + 1) * sizeof(wchar_t));
|
|
|
|
wcscpy(vd_pFriendlyName, wstr);
|
|
|
|
WRL_PROP_GET(pDevice, Id, *REF_WRL_OBJ(str), hr)
|
|
|
|
if (FAILED(hr)) return hr;
|
|
|
|
WRL_PROP_PUT(pCapInitSet, VideoDeviceId, DEREF_WRL_OBJ(str), hr)
|
|
|
|
if (FAILED(hr)) return hr;
|
|
|
|
WRL_PROP_PUT(pCapInitSet, StreamingCaptureMode, _Video, hr)
|
|
|
|
if (FAILED(hr)) return hr;
|
|
|
|
MAKE_WRL_REF(_AsyncAction) pAction;
|
|
|
|
WRL_METHOD(DEREF_WRL_OBJ(pIMedCap), _InitializeWithSettingsAsync, pAction, hr, DEREF_WRL_OBJ(pCapInitSet))
|
|
|
|
if (FAILED(hr)) return hr;
|
|
|
|
MAKE_WRL_AGILE_REF(_MediaCapture) pAgileMedCap;
|
|
|
|
pAgileMedCap = PREPARE_TRANSFER_WRL_OBJ(pIMedCap);
|
|
|
|
Concurrency::critical_section::scoped_lock _LockHolder(vd_lock);
|
|
|
|
MAKE_WRL_REF(_AsyncAction) pOldAction = vd_pAction;
|
|
|
|
SAVE_CURRENT_CONTEXT(context);
|
|
|
|
vd_pAction = reinterpret_cast<MAKE_WRL_REF(_AsyncAction)>(BEGIN_CREATE_ASYNC(pAction, pOldAction, context, &pAgileMedCap, this)
|
|
|
|
HRESULT hr;
|
|
|
|
if (pOldAction) DO_ACTION_SYNCHRONOUSLY(hr, pOldAction, GET_CURRENT_CONTEXT);
|
|
|
|
DO_ACTION_SYNCHRONOUSLY(hr, pAction, context);
|
|
|
|
if (SUCCEEDED(hr)) {
|
|
|
|
//all camera capture calls only in original context
|
|
|
|
BEGIN_CALL_IN_CONTEXT(hr, context, pAgileMedCap, this)
|
|
|
|
enumerateCaptureFormats(DEREF_AGILE_WRL_OBJ(pAgileMedCap));
|
|
|
|
END_CALL_IN_CONTEXT(S_OK)
|
|
|
|
}
|
|
|
|
buildLibraryofTypes();
|
|
|
|
RELEASE_AGILE_WRL(pAgileMedCap)
|
|
|
|
END_CREATE_ASYNC(hr));
|
|
|
|
}
|
|
|
|
#else
|
2013-04-03 09:01:20 +08:00
|
|
|
if(pActivate)
|
2013-04-03 18:48:23 +08:00
|
|
|
{
|
2013-04-03 09:01:20 +08:00
|
|
|
IMFMediaSource *pSource = NULL;
|
|
|
|
hr = pActivate->GetAllocatedString(
|
|
|
|
MF_DEVSOURCE_ATTRIBUTE_FRIENDLY_NAME,
|
|
|
|
&vd_pFriendlyName,
|
|
|
|
NULL
|
|
|
|
);
|
|
|
|
hr = pActivate->ActivateObject(
|
|
|
|
__uuidof(IMFMediaSource),
|
|
|
|
(void**)&pSource
|
|
|
|
);
|
|
|
|
enumerateCaptureFormats(pSource);
|
|
|
|
buildLibraryofTypes();
|
|
|
|
SafeRelease(&pSource);
|
2013-04-03 18:48:23 +08:00
|
|
|
if(FAILED(hr))
|
|
|
|
{
|
2013-04-03 09:01:20 +08:00
|
|
|
vd_pFriendlyName = NULL;
|
|
|
|
DebugPrintOut *DPO = &DebugPrintOut::getInstance();
|
|
|
|
DPO->printOut(L"VIDEODEVICE %i: IMFMediaSource interface cannot be created \n", vd_CurrentNumber);
|
|
|
|
}
|
|
|
|
}
|
Update cap_msmf.cpp
Add support for WinRT in the MF capture framework by removing the disallowed calls to enumerate devices and create a sample grabber sink and adding framework for the MediaCapture interface and a custom sink which interfaces with the sample grabber callback interface. The change requires discussion for making it completely functional as redundancy is required given that if the source is a video file, the old code pathways must be used. Otherwise all IMFMediaSession, IMFMediaSource, and IMFActivate code must use a MediaCapture code path and all sink code must use the CMediaSink custom sink.
Support for the custom sink is extended to non-WinRT not for compatibility as Windows Vista client is a minimum regardless, but because it offers more flexibility, could be faster and is able to be used as an optionally different code path during sink creation based on a future configuration parameter.
My discussion and proposal to finish this change:
Devices are so easily enumerated through WinRT Windows.Devices namespace that wrapping the calls in a library is quite a chore for little benefit though to get the various modes and formats could still be a worthwhile project. For now conditional compilation to remove videodevices and any offending non-video file related activity in videodevice. In my opinion, this is a different , far less fundamental and important change which can possibly be done as a future project and also much more easily implemented in C++/CX.
ImageGrabber has the IMFSampleGrabberSinkCallback replaced with a base class (SharedSampleGrabber) which also be is base class for ImageGrabberRT. This change is necessary as the custom sink does not require a thread to pump events which is done through MediaCapture already. IMFSampleGrabberSinkCallback is the common element between both models and that piece can be shared. Initializing the new ImageGrabberRT is as simple as passing an already initialized MediaCapture object and any video format/encoding parameters.
The concurrency event is necessary to wait for completion and is the way the underlying, IAsyncAction wrappers in the task library work as well. Native WIN32 event objects would be an option if HAVE_CONCURRENCY is not defined. I could even imagine doing it with sleep/thread yield and InterlockedCompareExchange yet I am not enthusiastic about that approach either. Since there is a specific compiler HAVE_ for concurrency, I do not like pulling it in though I think for WinRT it is safe to say we will always have it available though should probably conditionally compile with the Interlocked option as WIN32 events would require HAVE_WIN32.
It looks like C++/CX cannot be used for the IMediaExtension sink (which should not be a problem) as using COM objects requires WRL and though deriving from IMediaExtension can be done, there is little purpose without COM. Objects from C++/CX can be swapped to interact with objects from native C++ as Inspectable* can reinterpret_cast to the ref object IInspectable^ and vice-versa. A solution to the COM class with C++/CX would be great so we could have dual support. Also without #define for every WRL object in use, the code will get quite muddy given that the */^ would need to be ifdef'd everywhere.
Update cap_msmf.cpp
Fixed bugs and completed the change. I believe the new classes need to be moved to a header file as the file has become to large and more classes need to be added for handling all the asynchronous problems (one wrapping IAsyncAction in a task and another for making a task out of IAsyncAction). Unfortunately, blocking on the UI thread is not an option in WinRT so a synchronous architecture is considered "illegal" by Microsoft's standards even if implementable (C++/CX ppltasks library throws errors if you try it). Worse, either by design or a bug in the MF MediaCapture class with Custom Sinks causes a crash if stop/start previewing without reinitializing (spPreferredPreviewMediaType is fatally nulled). After decompiling Windows.Media.dll, I worked around this in my own projects by using an activate-able custom sink ID which strangely assigns 1 to this pointer allowing it to be reinitialized in what can only be described as a hack by Microsoft. This would add additional overhead to the project to implement especially for static libraries as it requires IDL/DLL exporting followed by manifest declaration. Better to document that it is not supported.
Furthermore, an additional class for IMFAttributes should be implemented to make clean architecture for passing around attributes as opposed to directly calling non-COM interface calls on the objects and making use of SetProperties which would also be a set up for an object that uses the RuntimeClass activation ID.
The remaining changes are not difficult and will be complete soon along with debug tracing messages.
Update cap_msmf.cpp
Create cap_msmf.h
Update cap_msmf.cpp
Update cap_msmf.h
Update cap_msmf.cpp
Update cap_msmf.h
Update and rename cap_msmf.h to cap_msmf.hpp
Update cap_msmf.cpp
Update CMakeLists.txt
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.cpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Successful test - samples are grabbed
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Create ppltasks_winrt.h
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update ppltasks_winrt.h
Library updated and cleaned up with comments, marshaling, exceptions and linker settings
Update ppltasks_winrt.h
Fixed trailing whitespace
2013-12-14 16:53:30 +08:00
|
|
|
#endif
|
2013-04-03 09:01:20 +08:00
|
|
|
return hr;
|
|
|
|
}
|
2013-04-16 21:25:10 +08:00
|
|
|
|
Update cap_msmf.cpp
Add support for WinRT in the MF capture framework by removing the disallowed calls to enumerate devices and create a sample grabber sink and adding framework for the MediaCapture interface and a custom sink which interfaces with the sample grabber callback interface. The change requires discussion for making it completely functional as redundancy is required given that if the source is a video file, the old code pathways must be used. Otherwise all IMFMediaSession, IMFMediaSource, and IMFActivate code must use a MediaCapture code path and all sink code must use the CMediaSink custom sink.
Support for the custom sink is extended to non-WinRT not for compatibility as Windows Vista client is a minimum regardless, but because it offers more flexibility, could be faster and is able to be used as an optionally different code path during sink creation based on a future configuration parameter.
My discussion and proposal to finish this change:
Devices are so easily enumerated through WinRT Windows.Devices namespace that wrapping the calls in a library is quite a chore for little benefit though to get the various modes and formats could still be a worthwhile project. For now conditional compilation to remove videodevices and any offending non-video file related activity in videodevice. In my opinion, this is a different , far less fundamental and important change which can possibly be done as a future project and also much more easily implemented in C++/CX.
ImageGrabber has the IMFSampleGrabberSinkCallback replaced with a base class (SharedSampleGrabber) which also be is base class for ImageGrabberRT. This change is necessary as the custom sink does not require a thread to pump events which is done through MediaCapture already. IMFSampleGrabberSinkCallback is the common element between both models and that piece can be shared. Initializing the new ImageGrabberRT is as simple as passing an already initialized MediaCapture object and any video format/encoding parameters.
The concurrency event is necessary to wait for completion and is the way the underlying, IAsyncAction wrappers in the task library work as well. Native WIN32 event objects would be an option if HAVE_CONCURRENCY is not defined. I could even imagine doing it with sleep/thread yield and InterlockedCompareExchange yet I am not enthusiastic about that approach either. Since there is a specific compiler HAVE_ for concurrency, I do not like pulling it in though I think for WinRT it is safe to say we will always have it available though should probably conditionally compile with the Interlocked option as WIN32 events would require HAVE_WIN32.
It looks like C++/CX cannot be used for the IMediaExtension sink (which should not be a problem) as using COM objects requires WRL and though deriving from IMediaExtension can be done, there is little purpose without COM. Objects from C++/CX can be swapped to interact with objects from native C++ as Inspectable* can reinterpret_cast to the ref object IInspectable^ and vice-versa. A solution to the COM class with C++/CX would be great so we could have dual support. Also without #define for every WRL object in use, the code will get quite muddy given that the */^ would need to be ifdef'd everywhere.
Update cap_msmf.cpp
Fixed bugs and completed the change. I believe the new classes need to be moved to a header file as the file has become to large and more classes need to be added for handling all the asynchronous problems (one wrapping IAsyncAction in a task and another for making a task out of IAsyncAction). Unfortunately, blocking on the UI thread is not an option in WinRT so a synchronous architecture is considered "illegal" by Microsoft's standards even if implementable (C++/CX ppltasks library throws errors if you try it). Worse, either by design or a bug in the MF MediaCapture class with Custom Sinks causes a crash if stop/start previewing without reinitializing (spPreferredPreviewMediaType is fatally nulled). After decompiling Windows.Media.dll, I worked around this in my own projects by using an activate-able custom sink ID which strangely assigns 1 to this pointer allowing it to be reinitialized in what can only be described as a hack by Microsoft. This would add additional overhead to the project to implement especially for static libraries as it requires IDL/DLL exporting followed by manifest declaration. Better to document that it is not supported.
Furthermore, an additional class for IMFAttributes should be implemented to make clean architecture for passing around attributes as opposed to directly calling non-COM interface calls on the objects and making use of SetProperties which would also be a set up for an object that uses the RuntimeClass activation ID.
The remaining changes are not difficult and will be complete soon along with debug tracing messages.
Update cap_msmf.cpp
Create cap_msmf.h
Update cap_msmf.cpp
Update cap_msmf.h
Update cap_msmf.cpp
Update cap_msmf.h
Update and rename cap_msmf.h to cap_msmf.hpp
Update cap_msmf.cpp
Update CMakeLists.txt
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.cpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Successful test - samples are grabbed
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Create ppltasks_winrt.h
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update ppltasks_winrt.h
Library updated and cleaned up with comments, marshaling, exceptions and linker settings
Update ppltasks_winrt.h
Fixed trailing whitespace
2013-12-14 16:53:30 +08:00
|
|
|
#ifdef HAVE_WINRT
|
|
|
|
long videoDevice::readInfoOfDevice(MAKE_WRL_REF(_IDeviceInformation) pDevice, unsigned int Num)
|
|
|
|
{
|
|
|
|
HRESULT hr = -1;
|
|
|
|
vd_CurrentNumber = Num;
|
|
|
|
hr = resetDevice(pDevice);
|
|
|
|
return hr;
|
|
|
|
}
|
|
|
|
#else
|
2013-04-03 09:01:20 +08:00
|
|
|
long videoDevice::readInfoOfDevice(IMFActivate *pActivate, unsigned int Num)
|
|
|
|
{
|
|
|
|
HRESULT hr = -1;
|
|
|
|
vd_CurrentNumber = Num;
|
|
|
|
hr = resetDevice(pActivate);
|
|
|
|
return hr;
|
|
|
|
}
|
Update cap_msmf.cpp
Add support for WinRT in the MF capture framework by removing the disallowed calls to enumerate devices and create a sample grabber sink and adding framework for the MediaCapture interface and a custom sink which interfaces with the sample grabber callback interface. The change requires discussion for making it completely functional as redundancy is required given that if the source is a video file, the old code pathways must be used. Otherwise all IMFMediaSession, IMFMediaSource, and IMFActivate code must use a MediaCapture code path and all sink code must use the CMediaSink custom sink.
Support for the custom sink is extended to non-WinRT not for compatibility as Windows Vista client is a minimum regardless, but because it offers more flexibility, could be faster and is able to be used as an optionally different code path during sink creation based on a future configuration parameter.
My discussion and proposal to finish this change:
Devices are so easily enumerated through WinRT Windows.Devices namespace that wrapping the calls in a library is quite a chore for little benefit though to get the various modes and formats could still be a worthwhile project. For now conditional compilation to remove videodevices and any offending non-video file related activity in videodevice. In my opinion, this is a different , far less fundamental and important change which can possibly be done as a future project and also much more easily implemented in C++/CX.
ImageGrabber has the IMFSampleGrabberSinkCallback replaced with a base class (SharedSampleGrabber) which also be is base class for ImageGrabberRT. This change is necessary as the custom sink does not require a thread to pump events which is done through MediaCapture already. IMFSampleGrabberSinkCallback is the common element between both models and that piece can be shared. Initializing the new ImageGrabberRT is as simple as passing an already initialized MediaCapture object and any video format/encoding parameters.
The concurrency event is necessary to wait for completion and is the way the underlying, IAsyncAction wrappers in the task library work as well. Native WIN32 event objects would be an option if HAVE_CONCURRENCY is not defined. I could even imagine doing it with sleep/thread yield and InterlockedCompareExchange yet I am not enthusiastic about that approach either. Since there is a specific compiler HAVE_ for concurrency, I do not like pulling it in though I think for WinRT it is safe to say we will always have it available though should probably conditionally compile with the Interlocked option as WIN32 events would require HAVE_WIN32.
It looks like C++/CX cannot be used for the IMediaExtension sink (which should not be a problem) as using COM objects requires WRL and though deriving from IMediaExtension can be done, there is little purpose without COM. Objects from C++/CX can be swapped to interact with objects from native C++ as Inspectable* can reinterpret_cast to the ref object IInspectable^ and vice-versa. A solution to the COM class with C++/CX would be great so we could have dual support. Also without #define for every WRL object in use, the code will get quite muddy given that the */^ would need to be ifdef'd everywhere.
Update cap_msmf.cpp
Fixed bugs and completed the change. I believe the new classes need to be moved to a header file as the file has become to large and more classes need to be added for handling all the asynchronous problems (one wrapping IAsyncAction in a task and another for making a task out of IAsyncAction). Unfortunately, blocking on the UI thread is not an option in WinRT so a synchronous architecture is considered "illegal" by Microsoft's standards even if implementable (C++/CX ppltasks library throws errors if you try it). Worse, either by design or a bug in the MF MediaCapture class with Custom Sinks causes a crash if stop/start previewing without reinitializing (spPreferredPreviewMediaType is fatally nulled). After decompiling Windows.Media.dll, I worked around this in my own projects by using an activate-able custom sink ID which strangely assigns 1 to this pointer allowing it to be reinitialized in what can only be described as a hack by Microsoft. This would add additional overhead to the project to implement especially for static libraries as it requires IDL/DLL exporting followed by manifest declaration. Better to document that it is not supported.
Furthermore, an additional class for IMFAttributes should be implemented to make clean architecture for passing around attributes as opposed to directly calling non-COM interface calls on the objects and making use of SetProperties which would also be a set up for an object that uses the RuntimeClass activation ID.
The remaining changes are not difficult and will be complete soon along with debug tracing messages.
Update cap_msmf.cpp
Create cap_msmf.h
Update cap_msmf.cpp
Update cap_msmf.h
Update cap_msmf.cpp
Update cap_msmf.h
Update and rename cap_msmf.h to cap_msmf.hpp
Update cap_msmf.cpp
Update CMakeLists.txt
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.cpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Successful test - samples are grabbed
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Create ppltasks_winrt.h
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update ppltasks_winrt.h
Library updated and cleaned up with comments, marshaling, exceptions and linker settings
Update ppltasks_winrt.h
Fixed trailing whitespace
2013-12-14 16:53:30 +08:00
|
|
|
#endif
|
2013-04-16 21:25:10 +08:00
|
|
|
|
Update cap_msmf.cpp
Add support for WinRT in the MF capture framework by removing the disallowed calls to enumerate devices and create a sample grabber sink and adding framework for the MediaCapture interface and a custom sink which interfaces with the sample grabber callback interface. The change requires discussion for making it completely functional as redundancy is required given that if the source is a video file, the old code pathways must be used. Otherwise all IMFMediaSession, IMFMediaSource, and IMFActivate code must use a MediaCapture code path and all sink code must use the CMediaSink custom sink.
Support for the custom sink is extended to non-WinRT not for compatibility as Windows Vista client is a minimum regardless, but because it offers more flexibility, could be faster and is able to be used as an optionally different code path during sink creation based on a future configuration parameter.
My discussion and proposal to finish this change:
Devices are so easily enumerated through WinRT Windows.Devices namespace that wrapping the calls in a library is quite a chore for little benefit though to get the various modes and formats could still be a worthwhile project. For now conditional compilation to remove videodevices and any offending non-video file related activity in videodevice. In my opinion, this is a different , far less fundamental and important change which can possibly be done as a future project and also much more easily implemented in C++/CX.
ImageGrabber has the IMFSampleGrabberSinkCallback replaced with a base class (SharedSampleGrabber) which also be is base class for ImageGrabberRT. This change is necessary as the custom sink does not require a thread to pump events which is done through MediaCapture already. IMFSampleGrabberSinkCallback is the common element between both models and that piece can be shared. Initializing the new ImageGrabberRT is as simple as passing an already initialized MediaCapture object and any video format/encoding parameters.
The concurrency event is necessary to wait for completion and is the way the underlying, IAsyncAction wrappers in the task library work as well. Native WIN32 event objects would be an option if HAVE_CONCURRENCY is not defined. I could even imagine doing it with sleep/thread yield and InterlockedCompareExchange yet I am not enthusiastic about that approach either. Since there is a specific compiler HAVE_ for concurrency, I do not like pulling it in though I think for WinRT it is safe to say we will always have it available though should probably conditionally compile with the Interlocked option as WIN32 events would require HAVE_WIN32.
It looks like C++/CX cannot be used for the IMediaExtension sink (which should not be a problem) as using COM objects requires WRL and though deriving from IMediaExtension can be done, there is little purpose without COM. Objects from C++/CX can be swapped to interact with objects from native C++ as Inspectable* can reinterpret_cast to the ref object IInspectable^ and vice-versa. A solution to the COM class with C++/CX would be great so we could have dual support. Also without #define for every WRL object in use, the code will get quite muddy given that the */^ would need to be ifdef'd everywhere.
Update cap_msmf.cpp
Fixed bugs and completed the change. I believe the new classes need to be moved to a header file as the file has become to large and more classes need to be added for handling all the asynchronous problems (one wrapping IAsyncAction in a task and another for making a task out of IAsyncAction). Unfortunately, blocking on the UI thread is not an option in WinRT so a synchronous architecture is considered "illegal" by Microsoft's standards even if implementable (C++/CX ppltasks library throws errors if you try it). Worse, either by design or a bug in the MF MediaCapture class with Custom Sinks causes a crash if stop/start previewing without reinitializing (spPreferredPreviewMediaType is fatally nulled). After decompiling Windows.Media.dll, I worked around this in my own projects by using an activate-able custom sink ID which strangely assigns 1 to this pointer allowing it to be reinitialized in what can only be described as a hack by Microsoft. This would add additional overhead to the project to implement especially for static libraries as it requires IDL/DLL exporting followed by manifest declaration. Better to document that it is not supported.
Furthermore, an additional class for IMFAttributes should be implemented to make clean architecture for passing around attributes as opposed to directly calling non-COM interface calls on the objects and making use of SetProperties which would also be a set up for an object that uses the RuntimeClass activation ID.
The remaining changes are not difficult and will be complete soon along with debug tracing messages.
Update cap_msmf.cpp
Create cap_msmf.h
Update cap_msmf.cpp
Update cap_msmf.h
Update cap_msmf.cpp
Update cap_msmf.h
Update and rename cap_msmf.h to cap_msmf.hpp
Update cap_msmf.cpp
Update CMakeLists.txt
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.cpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Successful test - samples are grabbed
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Create ppltasks_winrt.h
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update ppltasks_winrt.h
Library updated and cleaned up with comments, marshaling, exceptions and linker settings
Update ppltasks_winrt.h
Fixed trailing whitespace
2013-12-14 16:53:30 +08:00
|
|
|
#ifdef HAVE_WINRT
|
|
|
|
long videoDevice::checkDevice(_DeviceClass devClass, DEFINE_TASK<HRESULT>* pTask, MAKE_WRL_REF(_IDeviceInformation)* ppDevice)
|
|
|
|
{
|
|
|
|
HRESULT hr = S_OK;
|
|
|
|
ACTIVATE_STATIC_OBJ(RuntimeClass_Windows_Devices_Enumeration_DeviceInformation, MAKE_WRL_OBJ(_DeviceInformationStatics), pDevStat, hr)
|
|
|
|
if (FAILED(hr)) return hr;
|
|
|
|
MAKE_WRL_REF(_AsyncOperation<MAKE_WRL_REF(_DeviceInformationCollection)>) pAction;
|
|
|
|
WRL_METHOD(pDevStat, _FindAllAsyncDeviceClass, pAction, hr, devClass)
|
|
|
|
if (SUCCEEDED(hr)) {
|
|
|
|
*pTask = CREATE_TASK([pAction, &ppDevice, this]() -> HRESULT {
|
|
|
|
HRESULT hr;
|
|
|
|
MAKE_WRL_OBJ(_VectorView<MAKE_WRL_REF(_DeviceInformation)>) pVector;
|
|
|
|
DO_OPERATION_SYNCHRONOUSLY_VECTOR(hr, pAction, GET_CURRENT_CONTEXT, pVector, _VectorView, _DeviceInformation, _DeviceInformationCollection);
|
|
|
|
UINT32 count = 0;
|
|
|
|
if (SUCCEEDED(hr)) WRL_PROP_GET(pVector, Size, count, hr)
|
|
|
|
if (SUCCEEDED(hr) && count > 0) {
|
|
|
|
for (UINT32 i = 0; i < count; i++) {
|
|
|
|
MAKE_WRL_OBJ(_IDeviceInformation) pDevice;
|
|
|
|
WRL_METHOD(pVector, GetAt, pDevice, hr, i)
|
|
|
|
if (SUCCEEDED(hr)) {
|
|
|
|
_StringObj str;
|
|
|
|
unsigned int length = 0;
|
|
|
|
WRL_PROP_GET(pDevice, Name, *REF_WRL_OBJ(str), hr)
|
|
|
|
PCWSTR wstr = WindowsGetStringRawBuffer(reinterpret_cast<HSTRING>(DEREF_WRL_OBJ(str)), &length);
|
|
|
|
if (wcscmp(wstr, vd_pFriendlyName) == 0) {
|
|
|
|
*ppDevice = PREPARE_TRANSFER_WRL_OBJ(pDevice);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return hr;
|
|
|
|
});
|
|
|
|
}
|
|
|
|
return hr;
|
|
|
|
}
|
|
|
|
#else
|
2013-04-03 09:01:20 +08:00
|
|
|
long videoDevice::checkDevice(IMFAttributes *pAttributes, IMFActivate **pDevice)
|
|
|
|
{
|
|
|
|
HRESULT hr = S_OK;
|
|
|
|
IMFActivate **ppDevices = NULL;
|
|
|
|
DebugPrintOut *DPO = &DebugPrintOut::getInstance();
|
|
|
|
UINT32 count;
|
|
|
|
wchar_t *newFriendlyName = NULL;
|
|
|
|
hr = MFEnumDeviceSources(pAttributes, &ppDevices, &count);
|
|
|
|
if (SUCCEEDED(hr))
|
|
|
|
{
|
|
|
|
if(count > 0)
|
|
|
|
{
|
|
|
|
if(count > vd_CurrentNumber)
|
2013-04-03 18:48:23 +08:00
|
|
|
{
|
2013-04-03 09:01:20 +08:00
|
|
|
hr = ppDevices[vd_CurrentNumber]->GetAllocatedString(
|
|
|
|
MF_DEVSOURCE_ATTRIBUTE_FRIENDLY_NAME,
|
|
|
|
&newFriendlyName,
|
|
|
|
NULL
|
|
|
|
);
|
|
|
|
if (SUCCEEDED(hr))
|
|
|
|
{
|
|
|
|
if(wcscmp(newFriendlyName, vd_pFriendlyName) != 0)
|
|
|
|
{
|
|
|
|
DPO->printOut(L"VIDEODEVICE %i: Chosen device cannot be found \n", vd_CurrentNumber);
|
|
|
|
hr = -1;
|
|
|
|
pDevice = NULL;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
*pDevice = ppDevices[vd_CurrentNumber];
|
|
|
|
(*pDevice)->AddRef();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
DPO->printOut(L"VIDEODEVICE %i: Name of device cannot be gotten \n", vd_CurrentNumber);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
DPO->printOut(L"VIDEODEVICE %i: Number of devices more than corrent number of the device \n", vd_CurrentNumber);
|
|
|
|
hr = -1;
|
|
|
|
}
|
|
|
|
for(UINT32 i = 0; i < count; i++)
|
|
|
|
{
|
|
|
|
SafeRelease(&ppDevices[i]);
|
|
|
|
}
|
|
|
|
SafeRelease(ppDevices);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
hr = -1;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
DPO->printOut(L"VIDEODEVICE %i: List of DeviceSources cannot be enumerated \n", vd_CurrentNumber);
|
|
|
|
}
|
|
|
|
return hr;
|
|
|
|
}
|
Update cap_msmf.cpp
Add support for WinRT in the MF capture framework by removing the disallowed calls to enumerate devices and create a sample grabber sink and adding framework for the MediaCapture interface and a custom sink which interfaces with the sample grabber callback interface. The change requires discussion for making it completely functional as redundancy is required given that if the source is a video file, the old code pathways must be used. Otherwise all IMFMediaSession, IMFMediaSource, and IMFActivate code must use a MediaCapture code path and all sink code must use the CMediaSink custom sink.
Support for the custom sink is extended to non-WinRT not for compatibility as Windows Vista client is a minimum regardless, but because it offers more flexibility, could be faster and is able to be used as an optionally different code path during sink creation based on a future configuration parameter.
My discussion and proposal to finish this change:
Devices are so easily enumerated through WinRT Windows.Devices namespace that wrapping the calls in a library is quite a chore for little benefit though to get the various modes and formats could still be a worthwhile project. For now conditional compilation to remove videodevices and any offending non-video file related activity in videodevice. In my opinion, this is a different , far less fundamental and important change which can possibly be done as a future project and also much more easily implemented in C++/CX.
ImageGrabber has the IMFSampleGrabberSinkCallback replaced with a base class (SharedSampleGrabber) which also be is base class for ImageGrabberRT. This change is necessary as the custom sink does not require a thread to pump events which is done through MediaCapture already. IMFSampleGrabberSinkCallback is the common element between both models and that piece can be shared. Initializing the new ImageGrabberRT is as simple as passing an already initialized MediaCapture object and any video format/encoding parameters.
The concurrency event is necessary to wait for completion and is the way the underlying, IAsyncAction wrappers in the task library work as well. Native WIN32 event objects would be an option if HAVE_CONCURRENCY is not defined. I could even imagine doing it with sleep/thread yield and InterlockedCompareExchange yet I am not enthusiastic about that approach either. Since there is a specific compiler HAVE_ for concurrency, I do not like pulling it in though I think for WinRT it is safe to say we will always have it available though should probably conditionally compile with the Interlocked option as WIN32 events would require HAVE_WIN32.
It looks like C++/CX cannot be used for the IMediaExtension sink (which should not be a problem) as using COM objects requires WRL and though deriving from IMediaExtension can be done, there is little purpose without COM. Objects from C++/CX can be swapped to interact with objects from native C++ as Inspectable* can reinterpret_cast to the ref object IInspectable^ and vice-versa. A solution to the COM class with C++/CX would be great so we could have dual support. Also without #define for every WRL object in use, the code will get quite muddy given that the */^ would need to be ifdef'd everywhere.
Update cap_msmf.cpp
Fixed bugs and completed the change. I believe the new classes need to be moved to a header file as the file has become to large and more classes need to be added for handling all the asynchronous problems (one wrapping IAsyncAction in a task and another for making a task out of IAsyncAction). Unfortunately, blocking on the UI thread is not an option in WinRT so a synchronous architecture is considered "illegal" by Microsoft's standards even if implementable (C++/CX ppltasks library throws errors if you try it). Worse, either by design or a bug in the MF MediaCapture class with Custom Sinks causes a crash if stop/start previewing without reinitializing (spPreferredPreviewMediaType is fatally nulled). After decompiling Windows.Media.dll, I worked around this in my own projects by using an activate-able custom sink ID which strangely assigns 1 to this pointer allowing it to be reinitialized in what can only be described as a hack by Microsoft. This would add additional overhead to the project to implement especially for static libraries as it requires IDL/DLL exporting followed by manifest declaration. Better to document that it is not supported.
Furthermore, an additional class for IMFAttributes should be implemented to make clean architecture for passing around attributes as opposed to directly calling non-COM interface calls on the objects and making use of SetProperties which would also be a set up for an object that uses the RuntimeClass activation ID.
The remaining changes are not difficult and will be complete soon along with debug tracing messages.
Update cap_msmf.cpp
Create cap_msmf.h
Update cap_msmf.cpp
Update cap_msmf.h
Update cap_msmf.cpp
Update cap_msmf.h
Update and rename cap_msmf.h to cap_msmf.hpp
Update cap_msmf.cpp
Update CMakeLists.txt
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.cpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Successful test - samples are grabbed
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Create ppltasks_winrt.h
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update ppltasks_winrt.h
Library updated and cleaned up with comments, marshaling, exceptions and linker settings
Update ppltasks_winrt.h
Fixed trailing whitespace
2013-12-14 16:53:30 +08:00
|
|
|
#endif
|
2013-05-15 21:09:03 +08:00
|
|
|
|
2013-04-03 09:01:20 +08:00
|
|
|
long videoDevice::initDevice()
|
|
|
|
{
|
Update cap_msmf.cpp
Add support for WinRT in the MF capture framework by removing the disallowed calls to enumerate devices and create a sample grabber sink and adding framework for the MediaCapture interface and a custom sink which interfaces with the sample grabber callback interface. The change requires discussion for making it completely functional as redundancy is required given that if the source is a video file, the old code pathways must be used. Otherwise all IMFMediaSession, IMFMediaSource, and IMFActivate code must use a MediaCapture code path and all sink code must use the CMediaSink custom sink.
Support for the custom sink is extended to non-WinRT not for compatibility as Windows Vista client is a minimum regardless, but because it offers more flexibility, could be faster and is able to be used as an optionally different code path during sink creation based on a future configuration parameter.
My discussion and proposal to finish this change:
Devices are so easily enumerated through WinRT Windows.Devices namespace that wrapping the calls in a library is quite a chore for little benefit though to get the various modes and formats could still be a worthwhile project. For now conditional compilation to remove videodevices and any offending non-video file related activity in videodevice. In my opinion, this is a different , far less fundamental and important change which can possibly be done as a future project and also much more easily implemented in C++/CX.
ImageGrabber has the IMFSampleGrabberSinkCallback replaced with a base class (SharedSampleGrabber) which also be is base class for ImageGrabberRT. This change is necessary as the custom sink does not require a thread to pump events which is done through MediaCapture already. IMFSampleGrabberSinkCallback is the common element between both models and that piece can be shared. Initializing the new ImageGrabberRT is as simple as passing an already initialized MediaCapture object and any video format/encoding parameters.
The concurrency event is necessary to wait for completion and is the way the underlying, IAsyncAction wrappers in the task library work as well. Native WIN32 event objects would be an option if HAVE_CONCURRENCY is not defined. I could even imagine doing it with sleep/thread yield and InterlockedCompareExchange yet I am not enthusiastic about that approach either. Since there is a specific compiler HAVE_ for concurrency, I do not like pulling it in though I think for WinRT it is safe to say we will always have it available though should probably conditionally compile with the Interlocked option as WIN32 events would require HAVE_WIN32.
It looks like C++/CX cannot be used for the IMediaExtension sink (which should not be a problem) as using COM objects requires WRL and though deriving from IMediaExtension can be done, there is little purpose without COM. Objects from C++/CX can be swapped to interact with objects from native C++ as Inspectable* can reinterpret_cast to the ref object IInspectable^ and vice-versa. A solution to the COM class with C++/CX would be great so we could have dual support. Also without #define for every WRL object in use, the code will get quite muddy given that the */^ would need to be ifdef'd everywhere.
Update cap_msmf.cpp
Fixed bugs and completed the change. I believe the new classes need to be moved to a header file as the file has become to large and more classes need to be added for handling all the asynchronous problems (one wrapping IAsyncAction in a task and another for making a task out of IAsyncAction). Unfortunately, blocking on the UI thread is not an option in WinRT so a synchronous architecture is considered "illegal" by Microsoft's standards even if implementable (C++/CX ppltasks library throws errors if you try it). Worse, either by design or a bug in the MF MediaCapture class with Custom Sinks causes a crash if stop/start previewing without reinitializing (spPreferredPreviewMediaType is fatally nulled). After decompiling Windows.Media.dll, I worked around this in my own projects by using an activate-able custom sink ID which strangely assigns 1 to this pointer allowing it to be reinitialized in what can only be described as a hack by Microsoft. This would add additional overhead to the project to implement especially for static libraries as it requires IDL/DLL exporting followed by manifest declaration. Better to document that it is not supported.
Furthermore, an additional class for IMFAttributes should be implemented to make clean architecture for passing around attributes as opposed to directly calling non-COM interface calls on the objects and making use of SetProperties which would also be a set up for an object that uses the RuntimeClass activation ID.
The remaining changes are not difficult and will be complete soon along with debug tracing messages.
Update cap_msmf.cpp
Create cap_msmf.h
Update cap_msmf.cpp
Update cap_msmf.h
Update cap_msmf.cpp
Update cap_msmf.h
Update and rename cap_msmf.h to cap_msmf.hpp
Update cap_msmf.cpp
Update CMakeLists.txt
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.cpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Successful test - samples are grabbed
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Create ppltasks_winrt.h
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update ppltasks_winrt.h
Library updated and cleaned up with comments, marshaling, exceptions and linker settings
Update ppltasks_winrt.h
Fixed trailing whitespace
2013-12-14 16:53:30 +08:00
|
|
|
HRESULT hr = S_OK;
|
|
|
|
CoInitialize(NULL);
|
|
|
|
#ifdef HAVE_WINRT
|
|
|
|
Concurrency::critical_section::scoped_lock _LockHolder(vd_lock);
|
|
|
|
MAKE_WRL_REF(_AsyncAction) pOldAction = vd_pAction;
|
|
|
|
SAVE_CURRENT_CONTEXT(context);
|
|
|
|
vd_pAction = reinterpret_cast<MAKE_WRL_REF(_AsyncAction)>(BEGIN_CREATE_ASYNC(pOldAction, context, this)
|
|
|
|
HRESULT hr;
|
|
|
|
if (pOldAction) DO_ACTION_SYNCHRONOUSLY(hr, pOldAction, GET_CURRENT_CONTEXT);
|
|
|
|
DEFINE_TASK<HRESULT> pTask;
|
|
|
|
MAKE_WRL_OBJ(_IDeviceInformation) pDevInfo;
|
|
|
|
hr = checkDevice(_VideoCapture, &pTask, REF_WRL_OBJ(pDevInfo));
|
|
|
|
if (SUCCEEDED(hr)) hr = pTask.get();
|
|
|
|
if (SUCCEEDED(hr)) {
|
|
|
|
MAKE_WRL_REF(_AsyncAction) pAction;
|
|
|
|
BEGIN_CALL_IN_CONTEXT(hr, context, pDevInfo, &pAction, context, this)
|
|
|
|
HRESULT hr;
|
|
|
|
ACTIVATE_OBJ(RuntimeClass_Windows_Media_Capture_MediaCapture, MAKE_WRL_OBJ(_MediaCapture), pIMedCap, hr)
|
|
|
|
if (SUCCEEDED(hr)) {
|
|
|
|
RELEASE_WRL(vd_pMedCap);
|
|
|
|
vd_pMedCap = PREPARE_TRANSFER_WRL_OBJ(pIMedCap);
|
|
|
|
ACTIVATE_OBJ(RuntimeClass_Windows_Media_Capture_MediaCaptureInitializationSettings, MAKE_WRL_OBJ(_MediaCaptureInitializationSettings), pCapInitSet, hr)
|
|
|
|
_StringObj str;
|
|
|
|
if (SUCCEEDED(hr)) {
|
|
|
|
WRL_PROP_GET(pDevInfo, Id, *REF_WRL_OBJ(str), hr)
|
|
|
|
if (SUCCEEDED(hr)) {
|
|
|
|
WRL_PROP_PUT(pCapInitSet, VideoDeviceId, DEREF_WRL_OBJ(str), hr)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (SUCCEEDED(hr))
|
|
|
|
WRL_PROP_PUT(pCapInitSet, StreamingCaptureMode, _Video, hr)
|
|
|
|
if (SUCCEEDED(hr)) {
|
|
|
|
vd_pMedCapFail = create_medcapfailedhandler([this, context](){
|
|
|
|
HRESULT hr;
|
|
|
|
BEGIN_CALL_IN_CONTEXT(hr, context, this)
|
|
|
|
closeDevice();
|
|
|
|
END_CALL_IN_CONTEXT(S_OK)
|
|
|
|
});
|
|
|
|
}
|
|
|
|
if (SUCCEEDED(hr)) hr = vd_pMedCapFail->AddHandler(reinterpret_cast<ABI::Windows::Media::Capture::IMediaCapture*>(DEREF_AGILE_WRL_OBJ(vd_pMedCap)));
|
|
|
|
if (SUCCEEDED(hr)) WRL_METHOD(vd_pMedCap, _InitializeWithSettingsAsync, pAction, hr, DEREF_WRL_OBJ(pCapInitSet))
|
|
|
|
}
|
|
|
|
END_CALL_IN_CONTEXT(hr)
|
|
|
|
DO_ACTION_SYNCHRONOUSLY(hr, pAction, context);
|
|
|
|
}
|
|
|
|
END_CREATE_ASYNC(hr));
|
|
|
|
#else
|
|
|
|
DebugPrintOut *DPO = &DebugPrintOut::getInstance();
|
2013-05-15 21:09:03 +08:00
|
|
|
ComPtr<IMFAttributes> pAttributes = NULL;
|
|
|
|
IMFActivate *vd_pActivate = NULL;
|
|
|
|
hr = MFCreateAttributes(pAttributes.GetAddressOf(), 1);
|
2013-04-03 09:01:20 +08:00
|
|
|
if (SUCCEEDED(hr))
|
|
|
|
{
|
|
|
|
hr = pAttributes->SetGUID(
|
|
|
|
MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE,
|
|
|
|
MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_GUID
|
|
|
|
);
|
2013-04-03 18:48:23 +08:00
|
|
|
}
|
2013-04-03 09:01:20 +08:00
|
|
|
if (SUCCEEDED(hr))
|
|
|
|
{
|
2013-05-15 21:09:03 +08:00
|
|
|
hr = checkDevice(pAttributes.Get(), &vd_pActivate);
|
2013-04-03 09:01:20 +08:00
|
|
|
if (SUCCEEDED(hr) && vd_pActivate)
|
|
|
|
{
|
|
|
|
SafeRelease(&vd_pSource);
|
|
|
|
hr = vd_pActivate->ActivateObject(
|
|
|
|
__uuidof(IMFMediaSource),
|
|
|
|
(void**)&vd_pSource
|
|
|
|
);
|
|
|
|
if (SUCCEEDED(hr))
|
|
|
|
{
|
|
|
|
}
|
|
|
|
SafeRelease(&vd_pActivate);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
DPO->printOut(L"VIDEODEVICE %i: Device there is not \n", vd_CurrentNumber);
|
|
|
|
}
|
2013-04-03 18:48:23 +08:00
|
|
|
}
|
2013-04-03 09:01:20 +08:00
|
|
|
else
|
|
|
|
{
|
|
|
|
DPO->printOut(L"VIDEODEVICE %i: The attribute of video cameras cannot be getting \n", vd_CurrentNumber);
|
|
|
|
}
|
Update cap_msmf.cpp
Add support for WinRT in the MF capture framework by removing the disallowed calls to enumerate devices and create a sample grabber sink and adding framework for the MediaCapture interface and a custom sink which interfaces with the sample grabber callback interface. The change requires discussion for making it completely functional as redundancy is required given that if the source is a video file, the old code pathways must be used. Otherwise all IMFMediaSession, IMFMediaSource, and IMFActivate code must use a MediaCapture code path and all sink code must use the CMediaSink custom sink.
Support for the custom sink is extended to non-WinRT not for compatibility as Windows Vista client is a minimum regardless, but because it offers more flexibility, could be faster and is able to be used as an optionally different code path during sink creation based on a future configuration parameter.
My discussion and proposal to finish this change:
Devices are so easily enumerated through WinRT Windows.Devices namespace that wrapping the calls in a library is quite a chore for little benefit though to get the various modes and formats could still be a worthwhile project. For now conditional compilation to remove videodevices and any offending non-video file related activity in videodevice. In my opinion, this is a different , far less fundamental and important change which can possibly be done as a future project and also much more easily implemented in C++/CX.
ImageGrabber has the IMFSampleGrabberSinkCallback replaced with a base class (SharedSampleGrabber) which also be is base class for ImageGrabberRT. This change is necessary as the custom sink does not require a thread to pump events which is done through MediaCapture already. IMFSampleGrabberSinkCallback is the common element between both models and that piece can be shared. Initializing the new ImageGrabberRT is as simple as passing an already initialized MediaCapture object and any video format/encoding parameters.
The concurrency event is necessary to wait for completion and is the way the underlying, IAsyncAction wrappers in the task library work as well. Native WIN32 event objects would be an option if HAVE_CONCURRENCY is not defined. I could even imagine doing it with sleep/thread yield and InterlockedCompareExchange yet I am not enthusiastic about that approach either. Since there is a specific compiler HAVE_ for concurrency, I do not like pulling it in though I think for WinRT it is safe to say we will always have it available though should probably conditionally compile with the Interlocked option as WIN32 events would require HAVE_WIN32.
It looks like C++/CX cannot be used for the IMediaExtension sink (which should not be a problem) as using COM objects requires WRL and though deriving from IMediaExtension can be done, there is little purpose without COM. Objects from C++/CX can be swapped to interact with objects from native C++ as Inspectable* can reinterpret_cast to the ref object IInspectable^ and vice-versa. A solution to the COM class with C++/CX would be great so we could have dual support. Also without #define for every WRL object in use, the code will get quite muddy given that the */^ would need to be ifdef'd everywhere.
Update cap_msmf.cpp
Fixed bugs and completed the change. I believe the new classes need to be moved to a header file as the file has become to large and more classes need to be added for handling all the asynchronous problems (one wrapping IAsyncAction in a task and another for making a task out of IAsyncAction). Unfortunately, blocking on the UI thread is not an option in WinRT so a synchronous architecture is considered "illegal" by Microsoft's standards even if implementable (C++/CX ppltasks library throws errors if you try it). Worse, either by design or a bug in the MF MediaCapture class with Custom Sinks causes a crash if stop/start previewing without reinitializing (spPreferredPreviewMediaType is fatally nulled). After decompiling Windows.Media.dll, I worked around this in my own projects by using an activate-able custom sink ID which strangely assigns 1 to this pointer allowing it to be reinitialized in what can only be described as a hack by Microsoft. This would add additional overhead to the project to implement especially for static libraries as it requires IDL/DLL exporting followed by manifest declaration. Better to document that it is not supported.
Furthermore, an additional class for IMFAttributes should be implemented to make clean architecture for passing around attributes as opposed to directly calling non-COM interface calls on the objects and making use of SetProperties which would also be a set up for an object that uses the RuntimeClass activation ID.
The remaining changes are not difficult and will be complete soon along with debug tracing messages.
Update cap_msmf.cpp
Create cap_msmf.h
Update cap_msmf.cpp
Update cap_msmf.h
Update cap_msmf.cpp
Update cap_msmf.h
Update and rename cap_msmf.h to cap_msmf.hpp
Update cap_msmf.cpp
Update CMakeLists.txt
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.cpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Successful test - samples are grabbed
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Create ppltasks_winrt.h
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update ppltasks_winrt.h
Library updated and cleaned up with comments, marshaling, exceptions and linker settings
Update ppltasks_winrt.h
Fixed trailing whitespace
2013-12-14 16:53:30 +08:00
|
|
|
#endif
|
2013-04-03 09:01:20 +08:00
|
|
|
return hr;
|
|
|
|
}
|
2013-05-15 21:09:03 +08:00
|
|
|
|
2013-04-03 09:01:20 +08:00
|
|
|
MediaType videoDevice::getFormat(unsigned int id)
|
|
|
|
{
|
|
|
|
if(id < vd_CurrentFormats.size())
|
|
|
|
{
|
|
|
|
return vd_CurrentFormats[id];
|
|
|
|
}
|
|
|
|
else return MediaType();
|
|
|
|
}
|
|
|
|
int videoDevice::getCountFormats()
|
|
|
|
{
|
Update cap_msmf.cpp
Add support for WinRT in the MF capture framework by removing the disallowed calls to enumerate devices and create a sample grabber sink and adding framework for the MediaCapture interface and a custom sink which interfaces with the sample grabber callback interface. The change requires discussion for making it completely functional as redundancy is required given that if the source is a video file, the old code pathways must be used. Otherwise all IMFMediaSession, IMFMediaSource, and IMFActivate code must use a MediaCapture code path and all sink code must use the CMediaSink custom sink.
Support for the custom sink is extended to non-WinRT not for compatibility as Windows Vista client is a minimum regardless, but because it offers more flexibility, could be faster and is able to be used as an optionally different code path during sink creation based on a future configuration parameter.
My discussion and proposal to finish this change:
Devices are so easily enumerated through WinRT Windows.Devices namespace that wrapping the calls in a library is quite a chore for little benefit though to get the various modes and formats could still be a worthwhile project. For now conditional compilation to remove videodevices and any offending non-video file related activity in videodevice. In my opinion, this is a different , far less fundamental and important change which can possibly be done as a future project and also much more easily implemented in C++/CX.
ImageGrabber has the IMFSampleGrabberSinkCallback replaced with a base class (SharedSampleGrabber) which also be is base class for ImageGrabberRT. This change is necessary as the custom sink does not require a thread to pump events which is done through MediaCapture already. IMFSampleGrabberSinkCallback is the common element between both models and that piece can be shared. Initializing the new ImageGrabberRT is as simple as passing an already initialized MediaCapture object and any video format/encoding parameters.
The concurrency event is necessary to wait for completion and is the way the underlying, IAsyncAction wrappers in the task library work as well. Native WIN32 event objects would be an option if HAVE_CONCURRENCY is not defined. I could even imagine doing it with sleep/thread yield and InterlockedCompareExchange yet I am not enthusiastic about that approach either. Since there is a specific compiler HAVE_ for concurrency, I do not like pulling it in though I think for WinRT it is safe to say we will always have it available though should probably conditionally compile with the Interlocked option as WIN32 events would require HAVE_WIN32.
It looks like C++/CX cannot be used for the IMediaExtension sink (which should not be a problem) as using COM objects requires WRL and though deriving from IMediaExtension can be done, there is little purpose without COM. Objects from C++/CX can be swapped to interact with objects from native C++ as Inspectable* can reinterpret_cast to the ref object IInspectable^ and vice-versa. A solution to the COM class with C++/CX would be great so we could have dual support. Also without #define for every WRL object in use, the code will get quite muddy given that the */^ would need to be ifdef'd everywhere.
Update cap_msmf.cpp
Fixed bugs and completed the change. I believe the new classes need to be moved to a header file as the file has become to large and more classes need to be added for handling all the asynchronous problems (one wrapping IAsyncAction in a task and another for making a task out of IAsyncAction). Unfortunately, blocking on the UI thread is not an option in WinRT so a synchronous architecture is considered "illegal" by Microsoft's standards even if implementable (C++/CX ppltasks library throws errors if you try it). Worse, either by design or a bug in the MF MediaCapture class with Custom Sinks causes a crash if stop/start previewing without reinitializing (spPreferredPreviewMediaType is fatally nulled). After decompiling Windows.Media.dll, I worked around this in my own projects by using an activate-able custom sink ID which strangely assigns 1 to this pointer allowing it to be reinitialized in what can only be described as a hack by Microsoft. This would add additional overhead to the project to implement especially for static libraries as it requires IDL/DLL exporting followed by manifest declaration. Better to document that it is not supported.
Furthermore, an additional class for IMFAttributes should be implemented to make clean architecture for passing around attributes as opposed to directly calling non-COM interface calls on the objects and making use of SetProperties which would also be a set up for an object that uses the RuntimeClass activation ID.
The remaining changes are not difficult and will be complete soon along with debug tracing messages.
Update cap_msmf.cpp
Create cap_msmf.h
Update cap_msmf.cpp
Update cap_msmf.h
Update cap_msmf.cpp
Update cap_msmf.h
Update and rename cap_msmf.h to cap_msmf.hpp
Update cap_msmf.cpp
Update CMakeLists.txt
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.cpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Successful test - samples are grabbed
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Create ppltasks_winrt.h
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update ppltasks_winrt.h
Library updated and cleaned up with comments, marshaling, exceptions and linker settings
Update ppltasks_winrt.h
Fixed trailing whitespace
2013-12-14 16:53:30 +08:00
|
|
|
return (int)vd_CurrentFormats.size();
|
2013-04-03 09:01:20 +08:00
|
|
|
}
|
|
|
|
void videoDevice::setEmergencyStopEvent(void *userData, void(*func)(int, void *))
|
|
|
|
{
|
|
|
|
vd_func = func;
|
|
|
|
vd_userData = userData;
|
|
|
|
}
|
|
|
|
void videoDevice::closeDevice()
|
2013-04-03 18:48:23 +08:00
|
|
|
{
|
2013-04-03 09:01:20 +08:00
|
|
|
if(vd_IsSetuped)
|
|
|
|
{
|
|
|
|
vd_IsSetuped = false;
|
Update cap_msmf.cpp
Add support for WinRT in the MF capture framework by removing the disallowed calls to enumerate devices and create a sample grabber sink and adding framework for the MediaCapture interface and a custom sink which interfaces with the sample grabber callback interface. The change requires discussion for making it completely functional as redundancy is required given that if the source is a video file, the old code pathways must be used. Otherwise all IMFMediaSession, IMFMediaSource, and IMFActivate code must use a MediaCapture code path and all sink code must use the CMediaSink custom sink.
Support for the custom sink is extended to non-WinRT not for compatibility as Windows Vista client is a minimum regardless, but because it offers more flexibility, could be faster and is able to be used as an optionally different code path during sink creation based on a future configuration parameter.
My discussion and proposal to finish this change:
Devices are so easily enumerated through WinRT Windows.Devices namespace that wrapping the calls in a library is quite a chore for little benefit though to get the various modes and formats could still be a worthwhile project. For now conditional compilation to remove videodevices and any offending non-video file related activity in videodevice. In my opinion, this is a different , far less fundamental and important change which can possibly be done as a future project and also much more easily implemented in C++/CX.
ImageGrabber has the IMFSampleGrabberSinkCallback replaced with a base class (SharedSampleGrabber) which also be is base class for ImageGrabberRT. This change is necessary as the custom sink does not require a thread to pump events which is done through MediaCapture already. IMFSampleGrabberSinkCallback is the common element between both models and that piece can be shared. Initializing the new ImageGrabberRT is as simple as passing an already initialized MediaCapture object and any video format/encoding parameters.
The concurrency event is necessary to wait for completion and is the way the underlying, IAsyncAction wrappers in the task library work as well. Native WIN32 event objects would be an option if HAVE_CONCURRENCY is not defined. I could even imagine doing it with sleep/thread yield and InterlockedCompareExchange yet I am not enthusiastic about that approach either. Since there is a specific compiler HAVE_ for concurrency, I do not like pulling it in though I think for WinRT it is safe to say we will always have it available though should probably conditionally compile with the Interlocked option as WIN32 events would require HAVE_WIN32.
It looks like C++/CX cannot be used for the IMediaExtension sink (which should not be a problem) as using COM objects requires WRL and though deriving from IMediaExtension can be done, there is little purpose without COM. Objects from C++/CX can be swapped to interact with objects from native C++ as Inspectable* can reinterpret_cast to the ref object IInspectable^ and vice-versa. A solution to the COM class with C++/CX would be great so we could have dual support. Also without #define for every WRL object in use, the code will get quite muddy given that the */^ would need to be ifdef'd everywhere.
Update cap_msmf.cpp
Fixed bugs and completed the change. I believe the new classes need to be moved to a header file as the file has become to large and more classes need to be added for handling all the asynchronous problems (one wrapping IAsyncAction in a task and another for making a task out of IAsyncAction). Unfortunately, blocking on the UI thread is not an option in WinRT so a synchronous architecture is considered "illegal" by Microsoft's standards even if implementable (C++/CX ppltasks library throws errors if you try it). Worse, either by design or a bug in the MF MediaCapture class with Custom Sinks causes a crash if stop/start previewing without reinitializing (spPreferredPreviewMediaType is fatally nulled). After decompiling Windows.Media.dll, I worked around this in my own projects by using an activate-able custom sink ID which strangely assigns 1 to this pointer allowing it to be reinitialized in what can only be described as a hack by Microsoft. This would add additional overhead to the project to implement especially for static libraries as it requires IDL/DLL exporting followed by manifest declaration. Better to document that it is not supported.
Furthermore, an additional class for IMFAttributes should be implemented to make clean architecture for passing around attributes as opposed to directly calling non-COM interface calls on the objects and making use of SetProperties which would also be a set up for an object that uses the RuntimeClass activation ID.
The remaining changes are not difficult and will be complete soon along with debug tracing messages.
Update cap_msmf.cpp
Create cap_msmf.h
Update cap_msmf.cpp
Update cap_msmf.h
Update cap_msmf.cpp
Update cap_msmf.h
Update and rename cap_msmf.h to cap_msmf.hpp
Update cap_msmf.cpp
Update CMakeLists.txt
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.cpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Successful test - samples are grabbed
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Create ppltasks_winrt.h
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update ppltasks_winrt.h
Library updated and cleaned up with comments, marshaling, exceptions and linker settings
Update ppltasks_winrt.h
Fixed trailing whitespace
2013-12-14 16:53:30 +08:00
|
|
|
|
|
|
|
#ifdef HAVE_WINRT
|
|
|
|
if (DEREF_AGILE_WRL_OBJ(vd_pMedCap)) {
|
|
|
|
MAKE_WRL_REF(_AsyncAction) action;
|
|
|
|
Concurrency::critical_section::scoped_lock _LockHolder(vd_lock);
|
|
|
|
MAKE_WRL_REF(_AsyncAction) pOldAction = vd_pAction;
|
|
|
|
vd_pImGr->stopGrabbing(&action);
|
|
|
|
vd_pMedCapFail->RemoveHandler(reinterpret_cast<ABI::Windows::Media::Capture::IMediaCapture*>(DEREF_AGILE_WRL_OBJ(vd_pMedCap)));
|
|
|
|
SafeRelease(&vd_pMedCapFail);
|
|
|
|
vd_pAction = reinterpret_cast<MAKE_WRL_REF(_AsyncAction)>(BEGIN_CREATE_ASYNC(action, pOldAction, this)
|
|
|
|
HRESULT hr;
|
|
|
|
if (pOldAction) DO_ACTION_SYNCHRONOUSLY(hr, pOldAction, GET_CURRENT_CONTEXT);
|
|
|
|
DO_ACTION_SYNCHRONOUSLY(hr, action, GET_CURRENT_CONTEXT);
|
|
|
|
RELEASE_WRL(vd_pMedCap)
|
|
|
|
if(vd_LockOut == RawDataLock) {
|
|
|
|
delete vd_pImGr;
|
|
|
|
}
|
|
|
|
vd_pImGr = NULL;
|
|
|
|
vd_LockOut = OpenLock;
|
|
|
|
END_CREATE_ASYNC(hr));
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2013-04-03 09:01:20 +08:00
|
|
|
vd_pSource->Stop();
|
|
|
|
SafeRelease(&vd_pSource);
|
|
|
|
if(vd_LockOut == RawDataLock)
|
|
|
|
{
|
|
|
|
vd_pImGrTh->stop();
|
|
|
|
Sleep(500);
|
|
|
|
delete vd_pImGrTh;
|
|
|
|
}
|
|
|
|
vd_pImGrTh = NULL;
|
2013-04-03 18:48:23 +08:00
|
|
|
vd_LockOut = OpenLock;
|
2013-04-03 09:01:20 +08:00
|
|
|
DebugPrintOut *DPO = &DebugPrintOut::getInstance();
|
|
|
|
DPO->printOut(L"VIDEODEVICE %i: Device is stopped \n", vd_CurrentNumber);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
unsigned int videoDevice::getWidth()
|
|
|
|
{
|
|
|
|
if(vd_IsSetuped)
|
|
|
|
return vd_Width;
|
|
|
|
else
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
unsigned int videoDevice::getHeight()
|
|
|
|
{
|
|
|
|
if(vd_IsSetuped)
|
|
|
|
return vd_Height;
|
2013-04-03 18:48:23 +08:00
|
|
|
else
|
2013-04-03 09:01:20 +08:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
IMFMediaSource *videoDevice::getMediaSource()
|
|
|
|
{
|
|
|
|
IMFMediaSource *out = NULL;
|
|
|
|
if(vd_LockOut == OpenLock)
|
|
|
|
{
|
2013-04-03 18:48:23 +08:00
|
|
|
vd_LockOut = MediaSourceLock;
|
2013-04-03 09:01:20 +08:00
|
|
|
out = vd_pSource;
|
|
|
|
}
|
|
|
|
return out;
|
|
|
|
}
|
|
|
|
int videoDevice::findType(unsigned int size, unsigned int frameRate)
|
2013-04-03 18:48:23 +08:00
|
|
|
{
|
2013-04-03 09:01:20 +08:00
|
|
|
if(vd_CaptureFormats.size() == 0)
|
|
|
|
return 0;
|
|
|
|
FrameRateMap FRM = vd_CaptureFormats[size];
|
|
|
|
if(FRM.size() == 0)
|
|
|
|
return 0;
|
|
|
|
UINT64 frameRateMax = 0; SUBTYPEMap STMMax;
|
|
|
|
if(frameRate == 0)
|
|
|
|
{
|
|
|
|
std::map<UINT64, SUBTYPEMap>::iterator f = FRM.begin();
|
|
|
|
for(; f != FRM.end(); f++)
|
|
|
|
{
|
|
|
|
if((*f).first >= frameRateMax)
|
|
|
|
{
|
|
|
|
frameRateMax = (*f).first;
|
|
|
|
STMMax = (*f).second;
|
|
|
|
}
|
2013-04-03 18:48:23 +08:00
|
|
|
}
|
2013-04-03 09:01:20 +08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
std::map<UINT64, SUBTYPEMap>::iterator f = FRM.begin();
|
|
|
|
for(; f != FRM.end(); f++)
|
|
|
|
{
|
|
|
|
if((*f).first >= frameRateMax)
|
|
|
|
{
|
|
|
|
if(frameRate > (*f).first)
|
|
|
|
{
|
|
|
|
frameRateMax = (*f).first;
|
|
|
|
STMMax = (*f).second;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if(STMMax.size() == 0)
|
|
|
|
return 0;
|
|
|
|
std::map<String, vectorNum>::iterator S = STMMax.begin();
|
|
|
|
vectorNum VN = (*S).second;
|
|
|
|
if(VN.size() == 0)
|
|
|
|
return 0;
|
|
|
|
return VN[0];
|
|
|
|
}
|
2013-05-23 00:50:54 +08:00
|
|
|
|
2013-04-03 09:01:20 +08:00
|
|
|
void videoDevice::buildLibraryofTypes()
|
|
|
|
{
|
|
|
|
unsigned int size;
|
|
|
|
unsigned int framerate;
|
|
|
|
std::vector<MediaType>::iterator i = vd_CurrentFormats.begin();
|
|
|
|
int count = 0;
|
|
|
|
for(; i != vd_CurrentFormats.end(); i++)
|
|
|
|
{
|
|
|
|
size = (*i).MF_MT_FRAME_SIZE;
|
2013-05-23 00:50:54 +08:00
|
|
|
framerate = (*i).MF_MT_FRAME_RATE_NUMERATOR;
|
2013-04-03 09:01:20 +08:00
|
|
|
FrameRateMap FRM = vd_CaptureFormats[size];
|
|
|
|
SUBTYPEMap STM = FRM[framerate];
|
|
|
|
String subType((*i).pMF_MT_SUBTYPEName);
|
|
|
|
vectorNum VN = STM[subType];
|
|
|
|
VN.push_back(count);
|
|
|
|
STM[subType] = VN;
|
|
|
|
FRM[framerate] = STM;
|
|
|
|
vd_CaptureFormats[size] = FRM;
|
|
|
|
count++;
|
|
|
|
}
|
|
|
|
}
|
2013-05-15 21:09:03 +08:00
|
|
|
|
Update cap_msmf.cpp
Add support for WinRT in the MF capture framework by removing the disallowed calls to enumerate devices and create a sample grabber sink and adding framework for the MediaCapture interface and a custom sink which interfaces with the sample grabber callback interface. The change requires discussion for making it completely functional as redundancy is required given that if the source is a video file, the old code pathways must be used. Otherwise all IMFMediaSession, IMFMediaSource, and IMFActivate code must use a MediaCapture code path and all sink code must use the CMediaSink custom sink.
Support for the custom sink is extended to non-WinRT not for compatibility as Windows Vista client is a minimum regardless, but because it offers more flexibility, could be faster and is able to be used as an optionally different code path during sink creation based on a future configuration parameter.
My discussion and proposal to finish this change:
Devices are so easily enumerated through WinRT Windows.Devices namespace that wrapping the calls in a library is quite a chore for little benefit though to get the various modes and formats could still be a worthwhile project. For now conditional compilation to remove videodevices and any offending non-video file related activity in videodevice. In my opinion, this is a different , far less fundamental and important change which can possibly be done as a future project and also much more easily implemented in C++/CX.
ImageGrabber has the IMFSampleGrabberSinkCallback replaced with a base class (SharedSampleGrabber) which also be is base class for ImageGrabberRT. This change is necessary as the custom sink does not require a thread to pump events which is done through MediaCapture already. IMFSampleGrabberSinkCallback is the common element between both models and that piece can be shared. Initializing the new ImageGrabberRT is as simple as passing an already initialized MediaCapture object and any video format/encoding parameters.
The concurrency event is necessary to wait for completion and is the way the underlying, IAsyncAction wrappers in the task library work as well. Native WIN32 event objects would be an option if HAVE_CONCURRENCY is not defined. I could even imagine doing it with sleep/thread yield and InterlockedCompareExchange yet I am not enthusiastic about that approach either. Since there is a specific compiler HAVE_ for concurrency, I do not like pulling it in though I think for WinRT it is safe to say we will always have it available though should probably conditionally compile with the Interlocked option as WIN32 events would require HAVE_WIN32.
It looks like C++/CX cannot be used for the IMediaExtension sink (which should not be a problem) as using COM objects requires WRL and though deriving from IMediaExtension can be done, there is little purpose without COM. Objects from C++/CX can be swapped to interact with objects from native C++ as Inspectable* can reinterpret_cast to the ref object IInspectable^ and vice-versa. A solution to the COM class with C++/CX would be great so we could have dual support. Also without #define for every WRL object in use, the code will get quite muddy given that the */^ would need to be ifdef'd everywhere.
Update cap_msmf.cpp
Fixed bugs and completed the change. I believe the new classes need to be moved to a header file as the file has become to large and more classes need to be added for handling all the asynchronous problems (one wrapping IAsyncAction in a task and another for making a task out of IAsyncAction). Unfortunately, blocking on the UI thread is not an option in WinRT so a synchronous architecture is considered "illegal" by Microsoft's standards even if implementable (C++/CX ppltasks library throws errors if you try it). Worse, either by design or a bug in the MF MediaCapture class with Custom Sinks causes a crash if stop/start previewing without reinitializing (spPreferredPreviewMediaType is fatally nulled). After decompiling Windows.Media.dll, I worked around this in my own projects by using an activate-able custom sink ID which strangely assigns 1 to this pointer allowing it to be reinitialized in what can only be described as a hack by Microsoft. This would add additional overhead to the project to implement especially for static libraries as it requires IDL/DLL exporting followed by manifest declaration. Better to document that it is not supported.
Furthermore, an additional class for IMFAttributes should be implemented to make clean architecture for passing around attributes as opposed to directly calling non-COM interface calls on the objects and making use of SetProperties which would also be a set up for an object that uses the RuntimeClass activation ID.
The remaining changes are not difficult and will be complete soon along with debug tracing messages.
Update cap_msmf.cpp
Create cap_msmf.h
Update cap_msmf.cpp
Update cap_msmf.h
Update cap_msmf.cpp
Update cap_msmf.h
Update and rename cap_msmf.h to cap_msmf.hpp
Update cap_msmf.cpp
Update CMakeLists.txt
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.cpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Successful test - samples are grabbed
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Create ppltasks_winrt.h
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update ppltasks_winrt.h
Library updated and cleaned up with comments, marshaling, exceptions and linker settings
Update ppltasks_winrt.h
Fixed trailing whitespace
2013-12-14 16:53:30 +08:00
|
|
|
#ifdef HAVE_WINRT
|
|
|
|
long videoDevice::setDeviceFormat(MAKE_WRL_REF(_MediaCapture) pSource, unsigned long dwFormatIndex, MAKE_WRL_REF(_AsyncAction)* pAction)
|
|
|
|
{
|
|
|
|
HRESULT hr;
|
|
|
|
MAKE_WRL_OBJ(_VideoDeviceController) pDevCont;
|
|
|
|
WRL_PROP_GET(pSource, VideoDeviceController, pDevCont, hr)
|
|
|
|
if (FAILED(hr)) return hr;
|
|
|
|
GET_WRL_MEDIA_DEVICE_CONTROLLER(pDevCont, pMedDevCont, hr)
|
|
|
|
if (FAILED(hr)) return hr;
|
|
|
|
MAKE_WRL_OBJ(_VectorView<MAKE_WRL_REF(_MediaEncodingProperties)>) pVector;
|
|
|
|
WRL_METHOD(pMedDevCont, GetAvailableMediaStreamProperties, pVector, hr, _VideoPreview)
|
|
|
|
if (FAILED(hr)) return hr;
|
|
|
|
MAKE_WRL_OBJ(_MediaEncodingProperties) pMedEncProps;
|
|
|
|
WRL_METHOD(pVector, GetAt, pMedEncProps, hr, dwFormatIndex)
|
|
|
|
if (FAILED(hr)) return hr;
|
|
|
|
WRL_METHOD(pMedDevCont, SetMediaStreamPropertiesAsync, *pAction, hr, _VideoPreview, DEREF_WRL_OBJ(pMedEncProps))
|
|
|
|
return hr;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2013-04-03 09:01:20 +08:00
|
|
|
long videoDevice::setDeviceFormat(IMFMediaSource *pSource, unsigned long dwFormatIndex)
|
|
|
|
{
|
2013-05-15 21:09:03 +08:00
|
|
|
ComPtr<IMFPresentationDescriptor> pPD = NULL;
|
|
|
|
ComPtr<IMFStreamDescriptor> pSD = NULL;
|
|
|
|
ComPtr<IMFMediaTypeHandler> pHandler = NULL;
|
|
|
|
ComPtr<IMFMediaType> pType = NULL;
|
|
|
|
HRESULT hr = pSource->CreatePresentationDescriptor(pPD.GetAddressOf());
|
2013-04-03 09:01:20 +08:00
|
|
|
if (FAILED(hr))
|
|
|
|
{
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
BOOL fSelected;
|
2013-05-15 21:09:03 +08:00
|
|
|
hr = pPD->GetStreamDescriptorByIndex(0, &fSelected, pSD.GetAddressOf());
|
2013-04-03 09:01:20 +08:00
|
|
|
if (FAILED(hr))
|
|
|
|
{
|
|
|
|
goto done;
|
|
|
|
}
|
2013-05-15 21:09:03 +08:00
|
|
|
hr = pSD->GetMediaTypeHandler(pHandler.GetAddressOf());
|
2013-04-03 09:01:20 +08:00
|
|
|
if (FAILED(hr))
|
|
|
|
{
|
|
|
|
goto done;
|
|
|
|
}
|
2013-05-15 21:09:03 +08:00
|
|
|
hr = pHandler->GetMediaTypeByIndex((DWORD)dwFormatIndex, pType.GetAddressOf());
|
2013-04-03 09:01:20 +08:00
|
|
|
if (FAILED(hr))
|
|
|
|
{
|
|
|
|
goto done;
|
|
|
|
}
|
2013-05-15 21:09:03 +08:00
|
|
|
hr = pHandler->SetCurrentMediaType(pType.Get());
|
|
|
|
|
2013-04-03 09:01:20 +08:00
|
|
|
done:
|
|
|
|
return hr;
|
|
|
|
}
|
2013-05-15 21:09:03 +08:00
|
|
|
|
2013-04-03 09:01:20 +08:00
|
|
|
bool videoDevice::isDeviceSetup()
|
|
|
|
{
|
|
|
|
return vd_IsSetuped;
|
|
|
|
}
|
2013-05-15 21:09:03 +08:00
|
|
|
|
2013-04-03 09:01:20 +08:00
|
|
|
RawImage * videoDevice::getRawImageOut()
|
|
|
|
{
|
|
|
|
if(!vd_IsSetuped) return NULL;
|
Update cap_msmf.cpp
Add support for WinRT in the MF capture framework by removing the disallowed calls to enumerate devices and create a sample grabber sink and adding framework for the MediaCapture interface and a custom sink which interfaces with the sample grabber callback interface. The change requires discussion for making it completely functional as redundancy is required given that if the source is a video file, the old code pathways must be used. Otherwise all IMFMediaSession, IMFMediaSource, and IMFActivate code must use a MediaCapture code path and all sink code must use the CMediaSink custom sink.
Support for the custom sink is extended to non-WinRT not for compatibility as Windows Vista client is a minimum regardless, but because it offers more flexibility, could be faster and is able to be used as an optionally different code path during sink creation based on a future configuration parameter.
My discussion and proposal to finish this change:
Devices are so easily enumerated through WinRT Windows.Devices namespace that wrapping the calls in a library is quite a chore for little benefit though to get the various modes and formats could still be a worthwhile project. For now conditional compilation to remove videodevices and any offending non-video file related activity in videodevice. In my opinion, this is a different , far less fundamental and important change which can possibly be done as a future project and also much more easily implemented in C++/CX.
ImageGrabber has the IMFSampleGrabberSinkCallback replaced with a base class (SharedSampleGrabber) which also be is base class for ImageGrabberRT. This change is necessary as the custom sink does not require a thread to pump events which is done through MediaCapture already. IMFSampleGrabberSinkCallback is the common element between both models and that piece can be shared. Initializing the new ImageGrabberRT is as simple as passing an already initialized MediaCapture object and any video format/encoding parameters.
The concurrency event is necessary to wait for completion and is the way the underlying, IAsyncAction wrappers in the task library work as well. Native WIN32 event objects would be an option if HAVE_CONCURRENCY is not defined. I could even imagine doing it with sleep/thread yield and InterlockedCompareExchange yet I am not enthusiastic about that approach either. Since there is a specific compiler HAVE_ for concurrency, I do not like pulling it in though I think for WinRT it is safe to say we will always have it available though should probably conditionally compile with the Interlocked option as WIN32 events would require HAVE_WIN32.
It looks like C++/CX cannot be used for the IMediaExtension sink (which should not be a problem) as using COM objects requires WRL and though deriving from IMediaExtension can be done, there is little purpose without COM. Objects from C++/CX can be swapped to interact with objects from native C++ as Inspectable* can reinterpret_cast to the ref object IInspectable^ and vice-versa. A solution to the COM class with C++/CX would be great so we could have dual support. Also without #define for every WRL object in use, the code will get quite muddy given that the */^ would need to be ifdef'd everywhere.
Update cap_msmf.cpp
Fixed bugs and completed the change. I believe the new classes need to be moved to a header file as the file has become to large and more classes need to be added for handling all the asynchronous problems (one wrapping IAsyncAction in a task and another for making a task out of IAsyncAction). Unfortunately, blocking on the UI thread is not an option in WinRT so a synchronous architecture is considered "illegal" by Microsoft's standards even if implementable (C++/CX ppltasks library throws errors if you try it). Worse, either by design or a bug in the MF MediaCapture class with Custom Sinks causes a crash if stop/start previewing without reinitializing (spPreferredPreviewMediaType is fatally nulled). After decompiling Windows.Media.dll, I worked around this in my own projects by using an activate-able custom sink ID which strangely assigns 1 to this pointer allowing it to be reinitialized in what can only be described as a hack by Microsoft. This would add additional overhead to the project to implement especially for static libraries as it requires IDL/DLL exporting followed by manifest declaration. Better to document that it is not supported.
Furthermore, an additional class for IMFAttributes should be implemented to make clean architecture for passing around attributes as opposed to directly calling non-COM interface calls on the objects and making use of SetProperties which would also be a set up for an object that uses the RuntimeClass activation ID.
The remaining changes are not difficult and will be complete soon along with debug tracing messages.
Update cap_msmf.cpp
Create cap_msmf.h
Update cap_msmf.cpp
Update cap_msmf.h
Update cap_msmf.cpp
Update cap_msmf.h
Update and rename cap_msmf.h to cap_msmf.hpp
Update cap_msmf.cpp
Update CMakeLists.txt
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.cpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Successful test - samples are grabbed
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Create ppltasks_winrt.h
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update ppltasks_winrt.h
Library updated and cleaned up with comments, marshaling, exceptions and linker settings
Update ppltasks_winrt.h
Fixed trailing whitespace
2013-12-14 16:53:30 +08:00
|
|
|
#ifdef HAVE_WINRT
|
|
|
|
if(vd_pImGr) return vd_pImGr->getRawImage();
|
|
|
|
#endif
|
2013-04-03 09:01:20 +08:00
|
|
|
if(vd_pImGrTh)
|
2013-04-03 18:48:23 +08:00
|
|
|
return vd_pImGrTh->getImageGrabber()->getRawImage();
|
2013-04-03 09:01:20 +08:00
|
|
|
else
|
|
|
|
{
|
|
|
|
DebugPrintOut *DPO = &DebugPrintOut::getInstance();
|
|
|
|
DPO->printOut(L"VIDEODEVICE %i: The instance of ImageGrabberThread class does not exist \n", vd_CurrentNumber);
|
|
|
|
}
|
|
|
|
return NULL;
|
|
|
|
}
|
2013-05-15 21:09:03 +08:00
|
|
|
|
2013-04-03 09:01:20 +08:00
|
|
|
bool videoDevice::isFrameNew()
|
|
|
|
{
|
|
|
|
if(!vd_IsSetuped) return false;
|
2013-04-03 18:48:23 +08:00
|
|
|
if(vd_LockOut == RawDataLock || vd_LockOut == OpenLock)
|
2013-04-03 09:01:20 +08:00
|
|
|
{
|
|
|
|
if(vd_LockOut == OpenLock)
|
|
|
|
{
|
|
|
|
vd_LockOut = RawDataLock;
|
Update cap_msmf.cpp
Add support for WinRT in the MF capture framework by removing the disallowed calls to enumerate devices and create a sample grabber sink and adding framework for the MediaCapture interface and a custom sink which interfaces with the sample grabber callback interface. The change requires discussion for making it completely functional as redundancy is required given that if the source is a video file, the old code pathways must be used. Otherwise all IMFMediaSession, IMFMediaSource, and IMFActivate code must use a MediaCapture code path and all sink code must use the CMediaSink custom sink.
Support for the custom sink is extended to non-WinRT not for compatibility as Windows Vista client is a minimum regardless, but because it offers more flexibility, could be faster and is able to be used as an optionally different code path during sink creation based on a future configuration parameter.
My discussion and proposal to finish this change:
Devices are so easily enumerated through WinRT Windows.Devices namespace that wrapping the calls in a library is quite a chore for little benefit though to get the various modes and formats could still be a worthwhile project. For now conditional compilation to remove videodevices and any offending non-video file related activity in videodevice. In my opinion, this is a different , far less fundamental and important change which can possibly be done as a future project and also much more easily implemented in C++/CX.
ImageGrabber has the IMFSampleGrabberSinkCallback replaced with a base class (SharedSampleGrabber) which also be is base class for ImageGrabberRT. This change is necessary as the custom sink does not require a thread to pump events which is done through MediaCapture already. IMFSampleGrabberSinkCallback is the common element between both models and that piece can be shared. Initializing the new ImageGrabberRT is as simple as passing an already initialized MediaCapture object and any video format/encoding parameters.
The concurrency event is necessary to wait for completion and is the way the underlying, IAsyncAction wrappers in the task library work as well. Native WIN32 event objects would be an option if HAVE_CONCURRENCY is not defined. I could even imagine doing it with sleep/thread yield and InterlockedCompareExchange yet I am not enthusiastic about that approach either. Since there is a specific compiler HAVE_ for concurrency, I do not like pulling it in though I think for WinRT it is safe to say we will always have it available though should probably conditionally compile with the Interlocked option as WIN32 events would require HAVE_WIN32.
It looks like C++/CX cannot be used for the IMediaExtension sink (which should not be a problem) as using COM objects requires WRL and though deriving from IMediaExtension can be done, there is little purpose without COM. Objects from C++/CX can be swapped to interact with objects from native C++ as Inspectable* can reinterpret_cast to the ref object IInspectable^ and vice-versa. A solution to the COM class with C++/CX would be great so we could have dual support. Also without #define for every WRL object in use, the code will get quite muddy given that the */^ would need to be ifdef'd everywhere.
Update cap_msmf.cpp
Fixed bugs and completed the change. I believe the new classes need to be moved to a header file as the file has become to large and more classes need to be added for handling all the asynchronous problems (one wrapping IAsyncAction in a task and another for making a task out of IAsyncAction). Unfortunately, blocking on the UI thread is not an option in WinRT so a synchronous architecture is considered "illegal" by Microsoft's standards even if implementable (C++/CX ppltasks library throws errors if you try it). Worse, either by design or a bug in the MF MediaCapture class with Custom Sinks causes a crash if stop/start previewing without reinitializing (spPreferredPreviewMediaType is fatally nulled). After decompiling Windows.Media.dll, I worked around this in my own projects by using an activate-able custom sink ID which strangely assigns 1 to this pointer allowing it to be reinitialized in what can only be described as a hack by Microsoft. This would add additional overhead to the project to implement especially for static libraries as it requires IDL/DLL exporting followed by manifest declaration. Better to document that it is not supported.
Furthermore, an additional class for IMFAttributes should be implemented to make clean architecture for passing around attributes as opposed to directly calling non-COM interface calls on the objects and making use of SetProperties which would also be a set up for an object that uses the RuntimeClass activation ID.
The remaining changes are not difficult and will be complete soon along with debug tracing messages.
Update cap_msmf.cpp
Create cap_msmf.h
Update cap_msmf.cpp
Update cap_msmf.h
Update cap_msmf.cpp
Update cap_msmf.h
Update and rename cap_msmf.h to cap_msmf.hpp
Update cap_msmf.cpp
Update CMakeLists.txt
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.cpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Successful test - samples are grabbed
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Create ppltasks_winrt.h
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update ppltasks_winrt.h
Library updated and cleaned up with comments, marshaling, exceptions and linker settings
Update ppltasks_winrt.h
Fixed trailing whitespace
2013-12-14 16:53:30 +08:00
|
|
|
|
|
|
|
//must already be closed
|
|
|
|
#ifdef HAVE_WINRT
|
|
|
|
if (DEREF_AGILE_WRL_OBJ(vd_pMedCap)) {
|
|
|
|
MAKE_WRL_REF(_AsyncAction) action;
|
|
|
|
if (FAILED(ImageGrabberWinRT::CreateInstance(&vd_pImGr))) return false;
|
|
|
|
if (FAILED(vd_pImGr->initImageGrabber(DEREF_AGILE_WRL_OBJ(vd_pMedCap), MFVideoFormat_RGB24)) || FAILED(vd_pImGr->startGrabbing(&action))) {
|
|
|
|
delete vd_pImGr;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
Concurrency::critical_section::scoped_lock _LockHolder(vd_lock);
|
|
|
|
MAKE_WRL_REF(_AsyncAction) pOldAction = vd_pAction;
|
|
|
|
SAVE_CURRENT_CONTEXT(context);
|
|
|
|
vd_pAction = reinterpret_cast<MAKE_WRL_REF(_AsyncAction)>(BEGIN_CREATE_ASYNC(action, pOldAction, context, this)
|
|
|
|
HRESULT hr;
|
|
|
|
if (pOldAction) DO_ACTION_SYNCHRONOUSLY(hr, pOldAction, GET_CURRENT_CONTEXT);
|
|
|
|
DO_ACTION_SYNCHRONOUSLY(hr, action, context);
|
|
|
|
END_CREATE_ASYNC(hr));
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
#endif
|
2013-04-03 09:01:20 +08:00
|
|
|
HRESULT hr = ImageGrabberThread::CreateInstance(&vd_pImGrTh, vd_pSource, vd_CurrentNumber);
|
|
|
|
if(FAILED(hr))
|
|
|
|
{
|
|
|
|
DebugPrintOut *DPO = &DebugPrintOut::getInstance();
|
|
|
|
DPO->printOut(L"VIDEODEVICE %i: The instance of ImageGrabberThread class cannot be created.\n", vd_CurrentNumber);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
vd_pImGrTh->setEmergencyStopEvent(vd_userData, vd_func);
|
|
|
|
vd_pImGrTh->start();
|
|
|
|
return true;
|
|
|
|
}
|
Update cap_msmf.cpp
Add support for WinRT in the MF capture framework by removing the disallowed calls to enumerate devices and create a sample grabber sink and adding framework for the MediaCapture interface and a custom sink which interfaces with the sample grabber callback interface. The change requires discussion for making it completely functional as redundancy is required given that if the source is a video file, the old code pathways must be used. Otherwise all IMFMediaSession, IMFMediaSource, and IMFActivate code must use a MediaCapture code path and all sink code must use the CMediaSink custom sink.
Support for the custom sink is extended to non-WinRT not for compatibility as Windows Vista client is a minimum regardless, but because it offers more flexibility, could be faster and is able to be used as an optionally different code path during sink creation based on a future configuration parameter.
My discussion and proposal to finish this change:
Devices are so easily enumerated through WinRT Windows.Devices namespace that wrapping the calls in a library is quite a chore for little benefit though to get the various modes and formats could still be a worthwhile project. For now conditional compilation to remove videodevices and any offending non-video file related activity in videodevice. In my opinion, this is a different , far less fundamental and important change which can possibly be done as a future project and also much more easily implemented in C++/CX.
ImageGrabber has the IMFSampleGrabberSinkCallback replaced with a base class (SharedSampleGrabber) which also be is base class for ImageGrabberRT. This change is necessary as the custom sink does not require a thread to pump events which is done through MediaCapture already. IMFSampleGrabberSinkCallback is the common element between both models and that piece can be shared. Initializing the new ImageGrabberRT is as simple as passing an already initialized MediaCapture object and any video format/encoding parameters.
The concurrency event is necessary to wait for completion and is the way the underlying, IAsyncAction wrappers in the task library work as well. Native WIN32 event objects would be an option if HAVE_CONCURRENCY is not defined. I could even imagine doing it with sleep/thread yield and InterlockedCompareExchange yet I am not enthusiastic about that approach either. Since there is a specific compiler HAVE_ for concurrency, I do not like pulling it in though I think for WinRT it is safe to say we will always have it available though should probably conditionally compile with the Interlocked option as WIN32 events would require HAVE_WIN32.
It looks like C++/CX cannot be used for the IMediaExtension sink (which should not be a problem) as using COM objects requires WRL and though deriving from IMediaExtension can be done, there is little purpose without COM. Objects from C++/CX can be swapped to interact with objects from native C++ as Inspectable* can reinterpret_cast to the ref object IInspectable^ and vice-versa. A solution to the COM class with C++/CX would be great so we could have dual support. Also without #define for every WRL object in use, the code will get quite muddy given that the */^ would need to be ifdef'd everywhere.
Update cap_msmf.cpp
Fixed bugs and completed the change. I believe the new classes need to be moved to a header file as the file has become to large and more classes need to be added for handling all the asynchronous problems (one wrapping IAsyncAction in a task and another for making a task out of IAsyncAction). Unfortunately, blocking on the UI thread is not an option in WinRT so a synchronous architecture is considered "illegal" by Microsoft's standards even if implementable (C++/CX ppltasks library throws errors if you try it). Worse, either by design or a bug in the MF MediaCapture class with Custom Sinks causes a crash if stop/start previewing without reinitializing (spPreferredPreviewMediaType is fatally nulled). After decompiling Windows.Media.dll, I worked around this in my own projects by using an activate-able custom sink ID which strangely assigns 1 to this pointer allowing it to be reinitialized in what can only be described as a hack by Microsoft. This would add additional overhead to the project to implement especially for static libraries as it requires IDL/DLL exporting followed by manifest declaration. Better to document that it is not supported.
Furthermore, an additional class for IMFAttributes should be implemented to make clean architecture for passing around attributes as opposed to directly calling non-COM interface calls on the objects and making use of SetProperties which would also be a set up for an object that uses the RuntimeClass activation ID.
The remaining changes are not difficult and will be complete soon along with debug tracing messages.
Update cap_msmf.cpp
Create cap_msmf.h
Update cap_msmf.cpp
Update cap_msmf.h
Update cap_msmf.cpp
Update cap_msmf.h
Update and rename cap_msmf.h to cap_msmf.hpp
Update cap_msmf.cpp
Update CMakeLists.txt
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.cpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Successful test - samples are grabbed
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Create ppltasks_winrt.h
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update ppltasks_winrt.h
Library updated and cleaned up with comments, marshaling, exceptions and linker settings
Update ppltasks_winrt.h
Fixed trailing whitespace
2013-12-14 16:53:30 +08:00
|
|
|
#ifdef HAVE_WINRT
|
|
|
|
if(vd_pImGr)
|
|
|
|
return vd_pImGr->getRawImage()->isNew();
|
|
|
|
#endif
|
2013-04-03 09:01:20 +08:00
|
|
|
if(vd_pImGrTh)
|
2013-04-03 18:48:23 +08:00
|
|
|
return vd_pImGrTh->getImageGrabber()->getRawImage()->isNew();
|
2013-04-03 09:01:20 +08:00
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
2013-05-15 21:09:03 +08:00
|
|
|
|
2013-04-03 09:01:20 +08:00
|
|
|
bool videoDevice::isDeviceMediaSource()
|
|
|
|
{
|
|
|
|
if(vd_LockOut == MediaSourceLock) return true;
|
|
|
|
return false;
|
|
|
|
}
|
2013-05-15 21:09:03 +08:00
|
|
|
|
2013-04-03 09:01:20 +08:00
|
|
|
bool videoDevice::isDeviceRawDataSource()
|
|
|
|
{
|
|
|
|
if(vd_LockOut == RawDataLock) return true;
|
|
|
|
return false;
|
|
|
|
}
|
2013-05-15 21:09:03 +08:00
|
|
|
|
2013-04-03 09:01:20 +08:00
|
|
|
bool videoDevice::setupDevice(unsigned int id)
|
2013-04-03 18:48:23 +08:00
|
|
|
{
|
2013-04-03 09:01:20 +08:00
|
|
|
DebugPrintOut *DPO = &DebugPrintOut::getInstance();
|
|
|
|
if(!vd_IsSetuped)
|
|
|
|
{
|
|
|
|
HRESULT hr = -1;
|
|
|
|
hr = initDevice();
|
|
|
|
if(SUCCEEDED(hr))
|
2013-04-03 18:48:23 +08:00
|
|
|
{
|
Update cap_msmf.cpp
Add support for WinRT in the MF capture framework by removing the disallowed calls to enumerate devices and create a sample grabber sink and adding framework for the MediaCapture interface and a custom sink which interfaces with the sample grabber callback interface. The change requires discussion for making it completely functional as redundancy is required given that if the source is a video file, the old code pathways must be used. Otherwise all IMFMediaSession, IMFMediaSource, and IMFActivate code must use a MediaCapture code path and all sink code must use the CMediaSink custom sink.
Support for the custom sink is extended to non-WinRT not for compatibility as Windows Vista client is a minimum regardless, but because it offers more flexibility, could be faster and is able to be used as an optionally different code path during sink creation based on a future configuration parameter.
My discussion and proposal to finish this change:
Devices are so easily enumerated through WinRT Windows.Devices namespace that wrapping the calls in a library is quite a chore for little benefit though to get the various modes and formats could still be a worthwhile project. For now conditional compilation to remove videodevices and any offending non-video file related activity in videodevice. In my opinion, this is a different , far less fundamental and important change which can possibly be done as a future project and also much more easily implemented in C++/CX.
ImageGrabber has the IMFSampleGrabberSinkCallback replaced with a base class (SharedSampleGrabber) which also be is base class for ImageGrabberRT. This change is necessary as the custom sink does not require a thread to pump events which is done through MediaCapture already. IMFSampleGrabberSinkCallback is the common element between both models and that piece can be shared. Initializing the new ImageGrabberRT is as simple as passing an already initialized MediaCapture object and any video format/encoding parameters.
The concurrency event is necessary to wait for completion and is the way the underlying, IAsyncAction wrappers in the task library work as well. Native WIN32 event objects would be an option if HAVE_CONCURRENCY is not defined. I could even imagine doing it with sleep/thread yield and InterlockedCompareExchange yet I am not enthusiastic about that approach either. Since there is a specific compiler HAVE_ for concurrency, I do not like pulling it in though I think for WinRT it is safe to say we will always have it available though should probably conditionally compile with the Interlocked option as WIN32 events would require HAVE_WIN32.
It looks like C++/CX cannot be used for the IMediaExtension sink (which should not be a problem) as using COM objects requires WRL and though deriving from IMediaExtension can be done, there is little purpose without COM. Objects from C++/CX can be swapped to interact with objects from native C++ as Inspectable* can reinterpret_cast to the ref object IInspectable^ and vice-versa. A solution to the COM class with C++/CX would be great so we could have dual support. Also without #define for every WRL object in use, the code will get quite muddy given that the */^ would need to be ifdef'd everywhere.
Update cap_msmf.cpp
Fixed bugs and completed the change. I believe the new classes need to be moved to a header file as the file has become to large and more classes need to be added for handling all the asynchronous problems (one wrapping IAsyncAction in a task and another for making a task out of IAsyncAction). Unfortunately, blocking on the UI thread is not an option in WinRT so a synchronous architecture is considered "illegal" by Microsoft's standards even if implementable (C++/CX ppltasks library throws errors if you try it). Worse, either by design or a bug in the MF MediaCapture class with Custom Sinks causes a crash if stop/start previewing without reinitializing (spPreferredPreviewMediaType is fatally nulled). After decompiling Windows.Media.dll, I worked around this in my own projects by using an activate-able custom sink ID which strangely assigns 1 to this pointer allowing it to be reinitialized in what can only be described as a hack by Microsoft. This would add additional overhead to the project to implement especially for static libraries as it requires IDL/DLL exporting followed by manifest declaration. Better to document that it is not supported.
Furthermore, an additional class for IMFAttributes should be implemented to make clean architecture for passing around attributes as opposed to directly calling non-COM interface calls on the objects and making use of SetProperties which would also be a set up for an object that uses the RuntimeClass activation ID.
The remaining changes are not difficult and will be complete soon along with debug tracing messages.
Update cap_msmf.cpp
Create cap_msmf.h
Update cap_msmf.cpp
Update cap_msmf.h
Update cap_msmf.cpp
Update cap_msmf.h
Update and rename cap_msmf.h to cap_msmf.hpp
Update cap_msmf.cpp
Update CMakeLists.txt
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.cpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Successful test - samples are grabbed
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Create ppltasks_winrt.h
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update ppltasks_winrt.h
Library updated and cleaned up with comments, marshaling, exceptions and linker settings
Update ppltasks_winrt.h
Fixed trailing whitespace
2013-12-14 16:53:30 +08:00
|
|
|
#ifdef HAVE_WINRT
|
|
|
|
Concurrency::critical_section::scoped_lock _LockHolder(vd_lock);
|
|
|
|
MAKE_WRL_REF(_AsyncAction) pOldAction = vd_pAction;
|
|
|
|
SAVE_CURRENT_CONTEXT(context);
|
|
|
|
vd_pAction = reinterpret_cast<MAKE_WRL_REF(_AsyncAction)>(BEGIN_CREATE_ASYNC(pOldAction, context, id, DPO, this)
|
|
|
|
HRESULT hr;
|
|
|
|
if (pOldAction) DO_ACTION_SYNCHRONOUSLY(hr, pOldAction, GET_CURRENT_CONTEXT);
|
|
|
|
#endif
|
2013-04-03 18:48:23 +08:00
|
|
|
vd_Width = vd_CurrentFormats[id].width;
|
2013-04-03 09:01:20 +08:00
|
|
|
vd_Height = vd_CurrentFormats[id].height;
|
Update cap_msmf.cpp
Add support for WinRT in the MF capture framework by removing the disallowed calls to enumerate devices and create a sample grabber sink and adding framework for the MediaCapture interface and a custom sink which interfaces with the sample grabber callback interface. The change requires discussion for making it completely functional as redundancy is required given that if the source is a video file, the old code pathways must be used. Otherwise all IMFMediaSession, IMFMediaSource, and IMFActivate code must use a MediaCapture code path and all sink code must use the CMediaSink custom sink.
Support for the custom sink is extended to non-WinRT not for compatibility as Windows Vista client is a minimum regardless, but because it offers more flexibility, could be faster and is able to be used as an optionally different code path during sink creation based on a future configuration parameter.
My discussion and proposal to finish this change:
Devices are so easily enumerated through WinRT Windows.Devices namespace that wrapping the calls in a library is quite a chore for little benefit though to get the various modes and formats could still be a worthwhile project. For now conditional compilation to remove videodevices and any offending non-video file related activity in videodevice. In my opinion, this is a different , far less fundamental and important change which can possibly be done as a future project and also much more easily implemented in C++/CX.
ImageGrabber has the IMFSampleGrabberSinkCallback replaced with a base class (SharedSampleGrabber) which also be is base class for ImageGrabberRT. This change is necessary as the custom sink does not require a thread to pump events which is done through MediaCapture already. IMFSampleGrabberSinkCallback is the common element between both models and that piece can be shared. Initializing the new ImageGrabberRT is as simple as passing an already initialized MediaCapture object and any video format/encoding parameters.
The concurrency event is necessary to wait for completion and is the way the underlying, IAsyncAction wrappers in the task library work as well. Native WIN32 event objects would be an option if HAVE_CONCURRENCY is not defined. I could even imagine doing it with sleep/thread yield and InterlockedCompareExchange yet I am not enthusiastic about that approach either. Since there is a specific compiler HAVE_ for concurrency, I do not like pulling it in though I think for WinRT it is safe to say we will always have it available though should probably conditionally compile with the Interlocked option as WIN32 events would require HAVE_WIN32.
It looks like C++/CX cannot be used for the IMediaExtension sink (which should not be a problem) as using COM objects requires WRL and though deriving from IMediaExtension can be done, there is little purpose without COM. Objects from C++/CX can be swapped to interact with objects from native C++ as Inspectable* can reinterpret_cast to the ref object IInspectable^ and vice-versa. A solution to the COM class with C++/CX would be great so we could have dual support. Also without #define for every WRL object in use, the code will get quite muddy given that the */^ would need to be ifdef'd everywhere.
Update cap_msmf.cpp
Fixed bugs and completed the change. I believe the new classes need to be moved to a header file as the file has become to large and more classes need to be added for handling all the asynchronous problems (one wrapping IAsyncAction in a task and another for making a task out of IAsyncAction). Unfortunately, blocking on the UI thread is not an option in WinRT so a synchronous architecture is considered "illegal" by Microsoft's standards even if implementable (C++/CX ppltasks library throws errors if you try it). Worse, either by design or a bug in the MF MediaCapture class with Custom Sinks causes a crash if stop/start previewing without reinitializing (spPreferredPreviewMediaType is fatally nulled). After decompiling Windows.Media.dll, I worked around this in my own projects by using an activate-able custom sink ID which strangely assigns 1 to this pointer allowing it to be reinitialized in what can only be described as a hack by Microsoft. This would add additional overhead to the project to implement especially for static libraries as it requires IDL/DLL exporting followed by manifest declaration. Better to document that it is not supported.
Furthermore, an additional class for IMFAttributes should be implemented to make clean architecture for passing around attributes as opposed to directly calling non-COM interface calls on the objects and making use of SetProperties which would also be a set up for an object that uses the RuntimeClass activation ID.
The remaining changes are not difficult and will be complete soon along with debug tracing messages.
Update cap_msmf.cpp
Create cap_msmf.h
Update cap_msmf.cpp
Update cap_msmf.h
Update cap_msmf.cpp
Update cap_msmf.h
Update and rename cap_msmf.h to cap_msmf.hpp
Update cap_msmf.cpp
Update CMakeLists.txt
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.cpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Successful test - samples are grabbed
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Create ppltasks_winrt.h
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update ppltasks_winrt.h
Library updated and cleaned up with comments, marshaling, exceptions and linker settings
Update ppltasks_winrt.h
Fixed trailing whitespace
2013-12-14 16:53:30 +08:00
|
|
|
#ifdef HAVE_WINRT
|
|
|
|
if (DEREF_AGILE_WRL_OBJ(vd_pMedCap)) {
|
|
|
|
MAKE_WRL_REF(_AsyncAction) pAction;
|
|
|
|
BEGIN_CALL_IN_CONTEXT(hr, context, id, &pAction, this)
|
|
|
|
END_CALL_IN_CONTEXT(setDeviceFormat(DEREF_AGILE_WRL_OBJ(vd_pMedCap), (DWORD) id, &pAction))
|
|
|
|
if (SUCCEEDED(hr)) DO_ACTION_SYNCHRONOUSLY(hr, pAction, context);
|
|
|
|
} else
|
|
|
|
#endif
|
2013-04-03 09:01:20 +08:00
|
|
|
hr = setDeviceFormat(vd_pSource, (DWORD) id);
|
|
|
|
vd_IsSetuped = (SUCCEEDED(hr));
|
|
|
|
if(vd_IsSetuped)
|
|
|
|
DPO->printOut(L"\n\nVIDEODEVICE %i: Device is setuped \n", vd_CurrentNumber);
|
|
|
|
vd_PrevParametrs = getParametrs();
|
Update cap_msmf.cpp
Add support for WinRT in the MF capture framework by removing the disallowed calls to enumerate devices and create a sample grabber sink and adding framework for the MediaCapture interface and a custom sink which interfaces with the sample grabber callback interface. The change requires discussion for making it completely functional as redundancy is required given that if the source is a video file, the old code pathways must be used. Otherwise all IMFMediaSession, IMFMediaSource, and IMFActivate code must use a MediaCapture code path and all sink code must use the CMediaSink custom sink.
Support for the custom sink is extended to non-WinRT not for compatibility as Windows Vista client is a minimum regardless, but because it offers more flexibility, could be faster and is able to be used as an optionally different code path during sink creation based on a future configuration parameter.
My discussion and proposal to finish this change:
Devices are so easily enumerated through WinRT Windows.Devices namespace that wrapping the calls in a library is quite a chore for little benefit though to get the various modes and formats could still be a worthwhile project. For now conditional compilation to remove videodevices and any offending non-video file related activity in videodevice. In my opinion, this is a different , far less fundamental and important change which can possibly be done as a future project and also much more easily implemented in C++/CX.
ImageGrabber has the IMFSampleGrabberSinkCallback replaced with a base class (SharedSampleGrabber) which also be is base class for ImageGrabberRT. This change is necessary as the custom sink does not require a thread to pump events which is done through MediaCapture already. IMFSampleGrabberSinkCallback is the common element between both models and that piece can be shared. Initializing the new ImageGrabberRT is as simple as passing an already initialized MediaCapture object and any video format/encoding parameters.
The concurrency event is necessary to wait for completion and is the way the underlying, IAsyncAction wrappers in the task library work as well. Native WIN32 event objects would be an option if HAVE_CONCURRENCY is not defined. I could even imagine doing it with sleep/thread yield and InterlockedCompareExchange yet I am not enthusiastic about that approach either. Since there is a specific compiler HAVE_ for concurrency, I do not like pulling it in though I think for WinRT it is safe to say we will always have it available though should probably conditionally compile with the Interlocked option as WIN32 events would require HAVE_WIN32.
It looks like C++/CX cannot be used for the IMediaExtension sink (which should not be a problem) as using COM objects requires WRL and though deriving from IMediaExtension can be done, there is little purpose without COM. Objects from C++/CX can be swapped to interact with objects from native C++ as Inspectable* can reinterpret_cast to the ref object IInspectable^ and vice-versa. A solution to the COM class with C++/CX would be great so we could have dual support. Also without #define for every WRL object in use, the code will get quite muddy given that the */^ would need to be ifdef'd everywhere.
Update cap_msmf.cpp
Fixed bugs and completed the change. I believe the new classes need to be moved to a header file as the file has become to large and more classes need to be added for handling all the asynchronous problems (one wrapping IAsyncAction in a task and another for making a task out of IAsyncAction). Unfortunately, blocking on the UI thread is not an option in WinRT so a synchronous architecture is considered "illegal" by Microsoft's standards even if implementable (C++/CX ppltasks library throws errors if you try it). Worse, either by design or a bug in the MF MediaCapture class with Custom Sinks causes a crash if stop/start previewing without reinitializing (spPreferredPreviewMediaType is fatally nulled). After decompiling Windows.Media.dll, I worked around this in my own projects by using an activate-able custom sink ID which strangely assigns 1 to this pointer allowing it to be reinitialized in what can only be described as a hack by Microsoft. This would add additional overhead to the project to implement especially for static libraries as it requires IDL/DLL exporting followed by manifest declaration. Better to document that it is not supported.
Furthermore, an additional class for IMFAttributes should be implemented to make clean architecture for passing around attributes as opposed to directly calling non-COM interface calls on the objects and making use of SetProperties which would also be a set up for an object that uses the RuntimeClass activation ID.
The remaining changes are not difficult and will be complete soon along with debug tracing messages.
Update cap_msmf.cpp
Create cap_msmf.h
Update cap_msmf.cpp
Update cap_msmf.h
Update cap_msmf.cpp
Update cap_msmf.h
Update and rename cap_msmf.h to cap_msmf.hpp
Update cap_msmf.cpp
Update CMakeLists.txt
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.cpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Successful test - samples are grabbed
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Create ppltasks_winrt.h
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update ppltasks_winrt.h
Library updated and cleaned up with comments, marshaling, exceptions and linker settings
Update ppltasks_winrt.h
Fixed trailing whitespace
2013-12-14 16:53:30 +08:00
|
|
|
#ifdef HAVE_WINRT
|
|
|
|
END_CREATE_ASYNC(hr));
|
|
|
|
return true;
|
|
|
|
#else
|
2013-04-03 09:01:20 +08:00
|
|
|
return vd_IsSetuped;
|
Update cap_msmf.cpp
Add support for WinRT in the MF capture framework by removing the disallowed calls to enumerate devices and create a sample grabber sink and adding framework for the MediaCapture interface and a custom sink which interfaces with the sample grabber callback interface. The change requires discussion for making it completely functional as redundancy is required given that if the source is a video file, the old code pathways must be used. Otherwise all IMFMediaSession, IMFMediaSource, and IMFActivate code must use a MediaCapture code path and all sink code must use the CMediaSink custom sink.
Support for the custom sink is extended to non-WinRT not for compatibility as Windows Vista client is a minimum regardless, but because it offers more flexibility, could be faster and is able to be used as an optionally different code path during sink creation based on a future configuration parameter.
My discussion and proposal to finish this change:
Devices are so easily enumerated through WinRT Windows.Devices namespace that wrapping the calls in a library is quite a chore for little benefit though to get the various modes and formats could still be a worthwhile project. For now conditional compilation to remove videodevices and any offending non-video file related activity in videodevice. In my opinion, this is a different , far less fundamental and important change which can possibly be done as a future project and also much more easily implemented in C++/CX.
ImageGrabber has the IMFSampleGrabberSinkCallback replaced with a base class (SharedSampleGrabber) which also be is base class for ImageGrabberRT. This change is necessary as the custom sink does not require a thread to pump events which is done through MediaCapture already. IMFSampleGrabberSinkCallback is the common element between both models and that piece can be shared. Initializing the new ImageGrabberRT is as simple as passing an already initialized MediaCapture object and any video format/encoding parameters.
The concurrency event is necessary to wait for completion and is the way the underlying, IAsyncAction wrappers in the task library work as well. Native WIN32 event objects would be an option if HAVE_CONCURRENCY is not defined. I could even imagine doing it with sleep/thread yield and InterlockedCompareExchange yet I am not enthusiastic about that approach either. Since there is a specific compiler HAVE_ for concurrency, I do not like pulling it in though I think for WinRT it is safe to say we will always have it available though should probably conditionally compile with the Interlocked option as WIN32 events would require HAVE_WIN32.
It looks like C++/CX cannot be used for the IMediaExtension sink (which should not be a problem) as using COM objects requires WRL and though deriving from IMediaExtension can be done, there is little purpose without COM. Objects from C++/CX can be swapped to interact with objects from native C++ as Inspectable* can reinterpret_cast to the ref object IInspectable^ and vice-versa. A solution to the COM class with C++/CX would be great so we could have dual support. Also without #define for every WRL object in use, the code will get quite muddy given that the */^ would need to be ifdef'd everywhere.
Update cap_msmf.cpp
Fixed bugs and completed the change. I believe the new classes need to be moved to a header file as the file has become to large and more classes need to be added for handling all the asynchronous problems (one wrapping IAsyncAction in a task and another for making a task out of IAsyncAction). Unfortunately, blocking on the UI thread is not an option in WinRT so a synchronous architecture is considered "illegal" by Microsoft's standards even if implementable (C++/CX ppltasks library throws errors if you try it). Worse, either by design or a bug in the MF MediaCapture class with Custom Sinks causes a crash if stop/start previewing without reinitializing (spPreferredPreviewMediaType is fatally nulled). After decompiling Windows.Media.dll, I worked around this in my own projects by using an activate-able custom sink ID which strangely assigns 1 to this pointer allowing it to be reinitialized in what can only be described as a hack by Microsoft. This would add additional overhead to the project to implement especially for static libraries as it requires IDL/DLL exporting followed by manifest declaration. Better to document that it is not supported.
Furthermore, an additional class for IMFAttributes should be implemented to make clean architecture for passing around attributes as opposed to directly calling non-COM interface calls on the objects and making use of SetProperties which would also be a set up for an object that uses the RuntimeClass activation ID.
The remaining changes are not difficult and will be complete soon along with debug tracing messages.
Update cap_msmf.cpp
Create cap_msmf.h
Update cap_msmf.cpp
Update cap_msmf.h
Update cap_msmf.cpp
Update cap_msmf.h
Update and rename cap_msmf.h to cap_msmf.hpp
Update cap_msmf.cpp
Update CMakeLists.txt
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.cpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Successful test - samples are grabbed
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Create ppltasks_winrt.h
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update ppltasks_winrt.h
Library updated and cleaned up with comments, marshaling, exceptions and linker settings
Update ppltasks_winrt.h
Fixed trailing whitespace
2013-12-14 16:53:30 +08:00
|
|
|
#endif
|
2013-04-03 09:01:20 +08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
DPO->printOut(L"VIDEODEVICE %i: Interface IMFMediaSource cannot be got \n", vd_CurrentNumber);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
DPO->printOut(L"VIDEODEVICE %i: Device is setuped already \n", vd_CurrentNumber);
|
|
|
|
return false;
|
2013-04-03 18:48:23 +08:00
|
|
|
}
|
2013-04-03 09:01:20 +08:00
|
|
|
}
|
2013-05-15 21:09:03 +08:00
|
|
|
|
2013-04-03 09:01:20 +08:00
|
|
|
bool videoDevice::setupDevice(unsigned int w, unsigned int h, unsigned int idealFramerate)
|
2013-04-03 18:48:23 +08:00
|
|
|
{
|
2013-04-03 09:01:20 +08:00
|
|
|
unsigned int id = findType(w * h, idealFramerate);
|
|
|
|
return setupDevice(id);
|
|
|
|
}
|
2013-05-15 21:09:03 +08:00
|
|
|
|
2013-04-03 09:01:20 +08:00
|
|
|
wchar_t *videoDevice::getName()
|
|
|
|
{
|
|
|
|
return vd_pFriendlyName;
|
|
|
|
}
|
2013-05-15 21:09:03 +08:00
|
|
|
|
2013-04-03 09:01:20 +08:00
|
|
|
videoDevice::~videoDevice(void)
|
2013-04-03 18:48:23 +08:00
|
|
|
{
|
2013-04-03 09:01:20 +08:00
|
|
|
closeDevice();
|
Update cap_msmf.cpp
Add support for WinRT in the MF capture framework by removing the disallowed calls to enumerate devices and create a sample grabber sink and adding framework for the MediaCapture interface and a custom sink which interfaces with the sample grabber callback interface. The change requires discussion for making it completely functional as redundancy is required given that if the source is a video file, the old code pathways must be used. Otherwise all IMFMediaSession, IMFMediaSource, and IMFActivate code must use a MediaCapture code path and all sink code must use the CMediaSink custom sink.
Support for the custom sink is extended to non-WinRT not for compatibility as Windows Vista client is a minimum regardless, but because it offers more flexibility, could be faster and is able to be used as an optionally different code path during sink creation based on a future configuration parameter.
My discussion and proposal to finish this change:
Devices are so easily enumerated through WinRT Windows.Devices namespace that wrapping the calls in a library is quite a chore for little benefit though to get the various modes and formats could still be a worthwhile project. For now conditional compilation to remove videodevices and any offending non-video file related activity in videodevice. In my opinion, this is a different , far less fundamental and important change which can possibly be done as a future project and also much more easily implemented in C++/CX.
ImageGrabber has the IMFSampleGrabberSinkCallback replaced with a base class (SharedSampleGrabber) which also be is base class for ImageGrabberRT. This change is necessary as the custom sink does not require a thread to pump events which is done through MediaCapture already. IMFSampleGrabberSinkCallback is the common element between both models and that piece can be shared. Initializing the new ImageGrabberRT is as simple as passing an already initialized MediaCapture object and any video format/encoding parameters.
The concurrency event is necessary to wait for completion and is the way the underlying, IAsyncAction wrappers in the task library work as well. Native WIN32 event objects would be an option if HAVE_CONCURRENCY is not defined. I could even imagine doing it with sleep/thread yield and InterlockedCompareExchange yet I am not enthusiastic about that approach either. Since there is a specific compiler HAVE_ for concurrency, I do not like pulling it in though I think for WinRT it is safe to say we will always have it available though should probably conditionally compile with the Interlocked option as WIN32 events would require HAVE_WIN32.
It looks like C++/CX cannot be used for the IMediaExtension sink (which should not be a problem) as using COM objects requires WRL and though deriving from IMediaExtension can be done, there is little purpose without COM. Objects from C++/CX can be swapped to interact with objects from native C++ as Inspectable* can reinterpret_cast to the ref object IInspectable^ and vice-versa. A solution to the COM class with C++/CX would be great so we could have dual support. Also without #define for every WRL object in use, the code will get quite muddy given that the */^ would need to be ifdef'd everywhere.
Update cap_msmf.cpp
Fixed bugs and completed the change. I believe the new classes need to be moved to a header file as the file has become to large and more classes need to be added for handling all the asynchronous problems (one wrapping IAsyncAction in a task and another for making a task out of IAsyncAction). Unfortunately, blocking on the UI thread is not an option in WinRT so a synchronous architecture is considered "illegal" by Microsoft's standards even if implementable (C++/CX ppltasks library throws errors if you try it). Worse, either by design or a bug in the MF MediaCapture class with Custom Sinks causes a crash if stop/start previewing without reinitializing (spPreferredPreviewMediaType is fatally nulled). After decompiling Windows.Media.dll, I worked around this in my own projects by using an activate-able custom sink ID which strangely assigns 1 to this pointer allowing it to be reinitialized in what can only be described as a hack by Microsoft. This would add additional overhead to the project to implement especially for static libraries as it requires IDL/DLL exporting followed by manifest declaration. Better to document that it is not supported.
Furthermore, an additional class for IMFAttributes should be implemented to make clean architecture for passing around attributes as opposed to directly calling non-COM interface calls on the objects and making use of SetProperties which would also be a set up for an object that uses the RuntimeClass activation ID.
The remaining changes are not difficult and will be complete soon along with debug tracing messages.
Update cap_msmf.cpp
Create cap_msmf.h
Update cap_msmf.cpp
Update cap_msmf.h
Update cap_msmf.cpp
Update cap_msmf.h
Update and rename cap_msmf.h to cap_msmf.hpp
Update cap_msmf.cpp
Update CMakeLists.txt
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.cpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Successful test - samples are grabbed
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Create ppltasks_winrt.h
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update ppltasks_winrt.h
Library updated and cleaned up with comments, marshaling, exceptions and linker settings
Update ppltasks_winrt.h
Fixed trailing whitespace
2013-12-14 16:53:30 +08:00
|
|
|
#ifdef HAVE_WINRT
|
|
|
|
RELEASE_WRL(vd_pMedCap)
|
|
|
|
#endif
|
2013-04-03 09:01:20 +08:00
|
|
|
SafeRelease(&vd_pSource);
|
|
|
|
if(vd_pFriendlyName)
|
|
|
|
CoTaskMemFree(vd_pFriendlyName);
|
|
|
|
}
|
2013-05-15 21:09:03 +08:00
|
|
|
|
Update cap_msmf.cpp
Add support for WinRT in the MF capture framework by removing the disallowed calls to enumerate devices and create a sample grabber sink and adding framework for the MediaCapture interface and a custom sink which interfaces with the sample grabber callback interface. The change requires discussion for making it completely functional as redundancy is required given that if the source is a video file, the old code pathways must be used. Otherwise all IMFMediaSession, IMFMediaSource, and IMFActivate code must use a MediaCapture code path and all sink code must use the CMediaSink custom sink.
Support for the custom sink is extended to non-WinRT not for compatibility as Windows Vista client is a minimum regardless, but because it offers more flexibility, could be faster and is able to be used as an optionally different code path during sink creation based on a future configuration parameter.
My discussion and proposal to finish this change:
Devices are so easily enumerated through WinRT Windows.Devices namespace that wrapping the calls in a library is quite a chore for little benefit though to get the various modes and formats could still be a worthwhile project. For now conditional compilation to remove videodevices and any offending non-video file related activity in videodevice. In my opinion, this is a different , far less fundamental and important change which can possibly be done as a future project and also much more easily implemented in C++/CX.
ImageGrabber has the IMFSampleGrabberSinkCallback replaced with a base class (SharedSampleGrabber) which also be is base class for ImageGrabberRT. This change is necessary as the custom sink does not require a thread to pump events which is done through MediaCapture already. IMFSampleGrabberSinkCallback is the common element between both models and that piece can be shared. Initializing the new ImageGrabberRT is as simple as passing an already initialized MediaCapture object and any video format/encoding parameters.
The concurrency event is necessary to wait for completion and is the way the underlying, IAsyncAction wrappers in the task library work as well. Native WIN32 event objects would be an option if HAVE_CONCURRENCY is not defined. I could even imagine doing it with sleep/thread yield and InterlockedCompareExchange yet I am not enthusiastic about that approach either. Since there is a specific compiler HAVE_ for concurrency, I do not like pulling it in though I think for WinRT it is safe to say we will always have it available though should probably conditionally compile with the Interlocked option as WIN32 events would require HAVE_WIN32.
It looks like C++/CX cannot be used for the IMediaExtension sink (which should not be a problem) as using COM objects requires WRL and though deriving from IMediaExtension can be done, there is little purpose without COM. Objects from C++/CX can be swapped to interact with objects from native C++ as Inspectable* can reinterpret_cast to the ref object IInspectable^ and vice-versa. A solution to the COM class with C++/CX would be great so we could have dual support. Also without #define for every WRL object in use, the code will get quite muddy given that the */^ would need to be ifdef'd everywhere.
Update cap_msmf.cpp
Fixed bugs and completed the change. I believe the new classes need to be moved to a header file as the file has become to large and more classes need to be added for handling all the asynchronous problems (one wrapping IAsyncAction in a task and another for making a task out of IAsyncAction). Unfortunately, blocking on the UI thread is not an option in WinRT so a synchronous architecture is considered "illegal" by Microsoft's standards even if implementable (C++/CX ppltasks library throws errors if you try it). Worse, either by design or a bug in the MF MediaCapture class with Custom Sinks causes a crash if stop/start previewing without reinitializing (spPreferredPreviewMediaType is fatally nulled). After decompiling Windows.Media.dll, I worked around this in my own projects by using an activate-able custom sink ID which strangely assigns 1 to this pointer allowing it to be reinitialized in what can only be described as a hack by Microsoft. This would add additional overhead to the project to implement especially for static libraries as it requires IDL/DLL exporting followed by manifest declaration. Better to document that it is not supported.
Furthermore, an additional class for IMFAttributes should be implemented to make clean architecture for passing around attributes as opposed to directly calling non-COM interface calls on the objects and making use of SetProperties which would also be a set up for an object that uses the RuntimeClass activation ID.
The remaining changes are not difficult and will be complete soon along with debug tracing messages.
Update cap_msmf.cpp
Create cap_msmf.h
Update cap_msmf.cpp
Update cap_msmf.h
Update cap_msmf.cpp
Update cap_msmf.h
Update and rename cap_msmf.h to cap_msmf.hpp
Update cap_msmf.cpp
Update CMakeLists.txt
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.cpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Successful test - samples are grabbed
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Create ppltasks_winrt.h
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update ppltasks_winrt.h
Library updated and cleaned up with comments, marshaling, exceptions and linker settings
Update ppltasks_winrt.h
Fixed trailing whitespace
2013-12-14 16:53:30 +08:00
|
|
|
#ifdef HAVE_WINRT
|
|
|
|
HRESULT videoDevice::enumerateCaptureFormats(MAKE_WRL_REF(_MediaCapture) pSource)
|
|
|
|
{
|
|
|
|
HRESULT hr;
|
|
|
|
MAKE_WRL_OBJ(_VideoDeviceController) pDevCont;
|
|
|
|
WRL_PROP_GET(pSource, VideoDeviceController, pDevCont, hr)
|
|
|
|
if (FAILED(hr)) return hr;
|
|
|
|
GET_WRL_MEDIA_DEVICE_CONTROLLER(pDevCont, pMedDevCont, hr)
|
|
|
|
if (FAILED(hr)) return hr;
|
|
|
|
MAKE_WRL_OBJ(_VectorView<MAKE_WRL_REF(_MediaEncodingProperties)>) pVector;
|
|
|
|
WRL_METHOD(pMedDevCont, GetAvailableMediaStreamProperties, pVector, hr, _VideoPreview)
|
|
|
|
if (FAILED(hr)) return hr;
|
|
|
|
UINT32 count;
|
|
|
|
WRL_PROP_GET(pVector, Size, count, hr)
|
|
|
|
if (FAILED(hr)) return hr;
|
|
|
|
for (UINT32 i = 0; i < count; i++) {
|
|
|
|
MAKE_WRL_OBJ(_MediaEncodingProperties) pMedEncProps;
|
|
|
|
WRL_METHOD(pVector, GetAt, pMedEncProps, hr, i)
|
|
|
|
if (FAILED(hr)) return hr;
|
|
|
|
ComPtr<IMFMediaType> pType = NULL;
|
|
|
|
hr = MediaSink::ConvertPropertiesToMediaType(DEREF_AS_NATIVE_WRL_OBJ(ABI::Windows::Media::MediaProperties::IMediaEncodingProperties, pMedEncProps), &pType);
|
|
|
|
if (FAILED(hr)) return hr;
|
|
|
|
MediaType MT = FormatReader::Read(pType.Get());
|
|
|
|
vd_CurrentFormats.push_back(MT);
|
|
|
|
}
|
|
|
|
return hr;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2013-05-19 04:04:31 +08:00
|
|
|
HRESULT videoDevice::enumerateCaptureFormats(IMFMediaSource *pSource)
|
2013-04-03 09:01:20 +08:00
|
|
|
{
|
2013-05-15 21:09:03 +08:00
|
|
|
ComPtr<IMFPresentationDescriptor> pPD = NULL;
|
|
|
|
ComPtr<IMFStreamDescriptor> pSD = NULL;
|
|
|
|
ComPtr<IMFMediaTypeHandler> pHandler = NULL;
|
|
|
|
ComPtr<IMFMediaType> pType = NULL;
|
|
|
|
HRESULT hr = pSource->CreatePresentationDescriptor(pPD.GetAddressOf());
|
2013-04-03 09:01:20 +08:00
|
|
|
if (FAILED(hr))
|
|
|
|
{
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
BOOL fSelected;
|
2013-05-15 21:09:03 +08:00
|
|
|
hr = pPD->GetStreamDescriptorByIndex(0, &fSelected, pSD.GetAddressOf());
|
2013-04-03 09:01:20 +08:00
|
|
|
if (FAILED(hr))
|
|
|
|
{
|
|
|
|
goto done;
|
|
|
|
}
|
2013-05-15 21:09:03 +08:00
|
|
|
hr = pSD->GetMediaTypeHandler(pHandler.GetAddressOf());
|
2013-04-03 09:01:20 +08:00
|
|
|
if (FAILED(hr))
|
|
|
|
{
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
DWORD cTypes = 0;
|
|
|
|
hr = pHandler->GetMediaTypeCount(&cTypes);
|
|
|
|
if (FAILED(hr))
|
|
|
|
{
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
for (DWORD i = 0; i < cTypes; i++)
|
|
|
|
{
|
2013-05-15 21:09:03 +08:00
|
|
|
hr = pHandler->GetMediaTypeByIndex(i, pType.GetAddressOf());
|
2013-04-03 09:01:20 +08:00
|
|
|
if (FAILED(hr))
|
|
|
|
{
|
|
|
|
goto done;
|
|
|
|
}
|
2013-05-15 21:09:03 +08:00
|
|
|
MediaType MT = FormatReader::Read(pType.Get());
|
2013-04-03 09:01:20 +08:00
|
|
|
vd_CurrentFormats.push_back(MT);
|
|
|
|
}
|
2013-05-15 21:09:03 +08:00
|
|
|
|
2013-04-03 09:01:20 +08:00
|
|
|
done:
|
|
|
|
return hr;
|
|
|
|
}
|
2013-04-16 21:25:10 +08:00
|
|
|
|
2013-04-03 09:01:20 +08:00
|
|
|
videoDevices::videoDevices(void): count(0)
|
Update cap_msmf.cpp
Add support for WinRT in the MF capture framework by removing the disallowed calls to enumerate devices and create a sample grabber sink and adding framework for the MediaCapture interface and a custom sink which interfaces with the sample grabber callback interface. The change requires discussion for making it completely functional as redundancy is required given that if the source is a video file, the old code pathways must be used. Otherwise all IMFMediaSession, IMFMediaSource, and IMFActivate code must use a MediaCapture code path and all sink code must use the CMediaSink custom sink.
Support for the custom sink is extended to non-WinRT not for compatibility as Windows Vista client is a minimum regardless, but because it offers more flexibility, could be faster and is able to be used as an optionally different code path during sink creation based on a future configuration parameter.
My discussion and proposal to finish this change:
Devices are so easily enumerated through WinRT Windows.Devices namespace that wrapping the calls in a library is quite a chore for little benefit though to get the various modes and formats could still be a worthwhile project. For now conditional compilation to remove videodevices and any offending non-video file related activity in videodevice. In my opinion, this is a different , far less fundamental and important change which can possibly be done as a future project and also much more easily implemented in C++/CX.
ImageGrabber has the IMFSampleGrabberSinkCallback replaced with a base class (SharedSampleGrabber) which also be is base class for ImageGrabberRT. This change is necessary as the custom sink does not require a thread to pump events which is done through MediaCapture already. IMFSampleGrabberSinkCallback is the common element between both models and that piece can be shared. Initializing the new ImageGrabberRT is as simple as passing an already initialized MediaCapture object and any video format/encoding parameters.
The concurrency event is necessary to wait for completion and is the way the underlying, IAsyncAction wrappers in the task library work as well. Native WIN32 event objects would be an option if HAVE_CONCURRENCY is not defined. I could even imagine doing it with sleep/thread yield and InterlockedCompareExchange yet I am not enthusiastic about that approach either. Since there is a specific compiler HAVE_ for concurrency, I do not like pulling it in though I think for WinRT it is safe to say we will always have it available though should probably conditionally compile with the Interlocked option as WIN32 events would require HAVE_WIN32.
It looks like C++/CX cannot be used for the IMediaExtension sink (which should not be a problem) as using COM objects requires WRL and though deriving from IMediaExtension can be done, there is little purpose without COM. Objects from C++/CX can be swapped to interact with objects from native C++ as Inspectable* can reinterpret_cast to the ref object IInspectable^ and vice-versa. A solution to the COM class with C++/CX would be great so we could have dual support. Also without #define for every WRL object in use, the code will get quite muddy given that the */^ would need to be ifdef'd everywhere.
Update cap_msmf.cpp
Fixed bugs and completed the change. I believe the new classes need to be moved to a header file as the file has become to large and more classes need to be added for handling all the asynchronous problems (one wrapping IAsyncAction in a task and another for making a task out of IAsyncAction). Unfortunately, blocking on the UI thread is not an option in WinRT so a synchronous architecture is considered "illegal" by Microsoft's standards even if implementable (C++/CX ppltasks library throws errors if you try it). Worse, either by design or a bug in the MF MediaCapture class with Custom Sinks causes a crash if stop/start previewing without reinitializing (spPreferredPreviewMediaType is fatally nulled). After decompiling Windows.Media.dll, I worked around this in my own projects by using an activate-able custom sink ID which strangely assigns 1 to this pointer allowing it to be reinitialized in what can only be described as a hack by Microsoft. This would add additional overhead to the project to implement especially for static libraries as it requires IDL/DLL exporting followed by manifest declaration. Better to document that it is not supported.
Furthermore, an additional class for IMFAttributes should be implemented to make clean architecture for passing around attributes as opposed to directly calling non-COM interface calls on the objects and making use of SetProperties which would also be a set up for an object that uses the RuntimeClass activation ID.
The remaining changes are not difficult and will be complete soon along with debug tracing messages.
Update cap_msmf.cpp
Create cap_msmf.h
Update cap_msmf.cpp
Update cap_msmf.h
Update cap_msmf.cpp
Update cap_msmf.h
Update and rename cap_msmf.h to cap_msmf.hpp
Update cap_msmf.cpp
Update CMakeLists.txt
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.cpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Successful test - samples are grabbed
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Create ppltasks_winrt.h
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update ppltasks_winrt.h
Library updated and cleaned up with comments, marshaling, exceptions and linker settings
Update ppltasks_winrt.h
Fixed trailing whitespace
2013-12-14 16:53:30 +08:00
|
|
|
{
|
|
|
|
#ifdef HAVE_WINRT
|
|
|
|
vds_enumTask = nullptr;
|
|
|
|
#endif
|
|
|
|
}
|
2013-04-16 21:25:10 +08:00
|
|
|
|
2013-04-03 09:01:20 +08:00
|
|
|
void videoDevices::clearDevices()
|
|
|
|
{
|
|
|
|
std::vector<videoDevice *>::iterator i = vds_Devices.begin();
|
|
|
|
for(; i != vds_Devices.end(); ++i)
|
|
|
|
delete (*i);
|
|
|
|
vds_Devices.clear();
|
|
|
|
}
|
2013-04-16 21:25:10 +08:00
|
|
|
|
2013-04-03 09:01:20 +08:00
|
|
|
videoDevices::~videoDevices(void)
|
2013-04-03 18:48:23 +08:00
|
|
|
{
|
2013-04-03 09:01:20 +08:00
|
|
|
clearDevices();
|
|
|
|
}
|
2013-04-16 21:25:10 +08:00
|
|
|
|
2013-04-03 09:01:20 +08:00
|
|
|
videoDevice * videoDevices::getDevice(unsigned int i)
|
|
|
|
{
|
|
|
|
if(i >= vds_Devices.size())
|
|
|
|
{
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
if(i < 0)
|
|
|
|
{
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
return vds_Devices[i];
|
|
|
|
}
|
2013-04-16 21:25:10 +08:00
|
|
|
|
Update cap_msmf.cpp
Add support for WinRT in the MF capture framework by removing the disallowed calls to enumerate devices and create a sample grabber sink and adding framework for the MediaCapture interface and a custom sink which interfaces with the sample grabber callback interface. The change requires discussion for making it completely functional as redundancy is required given that if the source is a video file, the old code pathways must be used. Otherwise all IMFMediaSession, IMFMediaSource, and IMFActivate code must use a MediaCapture code path and all sink code must use the CMediaSink custom sink.
Support for the custom sink is extended to non-WinRT not for compatibility as Windows Vista client is a minimum regardless, but because it offers more flexibility, could be faster and is able to be used as an optionally different code path during sink creation based on a future configuration parameter.
My discussion and proposal to finish this change:
Devices are so easily enumerated through WinRT Windows.Devices namespace that wrapping the calls in a library is quite a chore for little benefit though to get the various modes and formats could still be a worthwhile project. For now conditional compilation to remove videodevices and any offending non-video file related activity in videodevice. In my opinion, this is a different , far less fundamental and important change which can possibly be done as a future project and also much more easily implemented in C++/CX.
ImageGrabber has the IMFSampleGrabberSinkCallback replaced with a base class (SharedSampleGrabber) which also be is base class for ImageGrabberRT. This change is necessary as the custom sink does not require a thread to pump events which is done through MediaCapture already. IMFSampleGrabberSinkCallback is the common element between both models and that piece can be shared. Initializing the new ImageGrabberRT is as simple as passing an already initialized MediaCapture object and any video format/encoding parameters.
The concurrency event is necessary to wait for completion and is the way the underlying, IAsyncAction wrappers in the task library work as well. Native WIN32 event objects would be an option if HAVE_CONCURRENCY is not defined. I could even imagine doing it with sleep/thread yield and InterlockedCompareExchange yet I am not enthusiastic about that approach either. Since there is a specific compiler HAVE_ for concurrency, I do not like pulling it in though I think for WinRT it is safe to say we will always have it available though should probably conditionally compile with the Interlocked option as WIN32 events would require HAVE_WIN32.
It looks like C++/CX cannot be used for the IMediaExtension sink (which should not be a problem) as using COM objects requires WRL and though deriving from IMediaExtension can be done, there is little purpose without COM. Objects from C++/CX can be swapped to interact with objects from native C++ as Inspectable* can reinterpret_cast to the ref object IInspectable^ and vice-versa. A solution to the COM class with C++/CX would be great so we could have dual support. Also without #define for every WRL object in use, the code will get quite muddy given that the */^ would need to be ifdef'd everywhere.
Update cap_msmf.cpp
Fixed bugs and completed the change. I believe the new classes need to be moved to a header file as the file has become to large and more classes need to be added for handling all the asynchronous problems (one wrapping IAsyncAction in a task and another for making a task out of IAsyncAction). Unfortunately, blocking on the UI thread is not an option in WinRT so a synchronous architecture is considered "illegal" by Microsoft's standards even if implementable (C++/CX ppltasks library throws errors if you try it). Worse, either by design or a bug in the MF MediaCapture class with Custom Sinks causes a crash if stop/start previewing without reinitializing (spPreferredPreviewMediaType is fatally nulled). After decompiling Windows.Media.dll, I worked around this in my own projects by using an activate-able custom sink ID which strangely assigns 1 to this pointer allowing it to be reinitialized in what can only be described as a hack by Microsoft. This would add additional overhead to the project to implement especially for static libraries as it requires IDL/DLL exporting followed by manifest declaration. Better to document that it is not supported.
Furthermore, an additional class for IMFAttributes should be implemented to make clean architecture for passing around attributes as opposed to directly calling non-COM interface calls on the objects and making use of SetProperties which would also be a set up for an object that uses the RuntimeClass activation ID.
The remaining changes are not difficult and will be complete soon along with debug tracing messages.
Update cap_msmf.cpp
Create cap_msmf.h
Update cap_msmf.cpp
Update cap_msmf.h
Update cap_msmf.cpp
Update cap_msmf.h
Update and rename cap_msmf.h to cap_msmf.hpp
Update cap_msmf.cpp
Update CMakeLists.txt
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.cpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Successful test - samples are grabbed
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Create ppltasks_winrt.h
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update ppltasks_winrt.h
Library updated and cleaned up with comments, marshaling, exceptions and linker settings
Update ppltasks_winrt.h
Fixed trailing whitespace
2013-12-14 16:53:30 +08:00
|
|
|
#ifdef HAVE_WINRT
|
|
|
|
long videoDevices::initDevices(_DeviceClass devClass)
|
|
|
|
{
|
|
|
|
HRESULT hr = S_OK;
|
|
|
|
ACTIVATE_STATIC_OBJ(RuntimeClass_Windows_Devices_Enumeration_DeviceInformation, MAKE_WRL_OBJ(_DeviceInformationStatics), pDevStat, hr)
|
|
|
|
if (FAILED(hr)) return hr;
|
|
|
|
MAKE_WRL_REF(_AsyncOperation<MAKE_WRL_REF(_DeviceInformationCollection)>) pAction;
|
|
|
|
WRL_METHOD(pDevStat, _FindAllAsyncDeviceClass, pAction, hr, devClass)
|
|
|
|
if (SUCCEEDED(hr)) {
|
|
|
|
SAVE_CURRENT_CONTEXT(context);
|
|
|
|
vds_enumTask = reinterpret_cast<MAKE_WRL_REF(_AsyncAction)>(BEGIN_CREATE_ASYNC(pAction, context, this)
|
|
|
|
HRESULT hr;
|
|
|
|
MAKE_WRL_OBJ(_VectorView<MAKE_WRL_REF(_DeviceInformation)>) pVector;
|
|
|
|
DO_OPERATION_SYNCHRONOUSLY_VECTOR(hr, pAction, GET_CURRENT_CONTEXT, pVector, _VectorView, _DeviceInformation, _DeviceInformationCollection);
|
|
|
|
if (SUCCEEDED(hr)) WRL_PROP_GET(pVector, Size, count, hr)
|
|
|
|
if (SUCCEEDED(hr) && count > 0) {
|
|
|
|
for (UINT32 i = 0; i < count; i++) {
|
|
|
|
videoDevice *vd = new videoDevice;
|
|
|
|
MAKE_WRL_OBJ(_IDeviceInformation) pDevice;
|
|
|
|
WRL_METHOD(pVector, GetAt, pDevice, hr, i)
|
|
|
|
if (SUCCEEDED(hr)) {
|
|
|
|
BEGIN_CALL_IN_CONTEXT(hr, context, vd, pDevice, i)
|
|
|
|
vd->readInfoOfDevice(DEREF_WRL_OBJ(pDevice), i);
|
|
|
|
END_CALL_IN_CONTEXT(S_OK)
|
|
|
|
vds_Devices.push_back(vd);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
END_CREATE_ASYNC(hr));
|
|
|
|
}
|
|
|
|
return hr;
|
|
|
|
}
|
|
|
|
#else
|
2013-04-03 09:01:20 +08:00
|
|
|
long videoDevices::initDevices(IMFAttributes *pAttributes)
|
|
|
|
{
|
|
|
|
HRESULT hr = S_OK;
|
|
|
|
clearDevices();
|
Update cap_msmf.cpp
Add support for WinRT in the MF capture framework by removing the disallowed calls to enumerate devices and create a sample grabber sink and adding framework for the MediaCapture interface and a custom sink which interfaces with the sample grabber callback interface. The change requires discussion for making it completely functional as redundancy is required given that if the source is a video file, the old code pathways must be used. Otherwise all IMFMediaSession, IMFMediaSource, and IMFActivate code must use a MediaCapture code path and all sink code must use the CMediaSink custom sink.
Support for the custom sink is extended to non-WinRT not for compatibility as Windows Vista client is a minimum regardless, but because it offers more flexibility, could be faster and is able to be used as an optionally different code path during sink creation based on a future configuration parameter.
My discussion and proposal to finish this change:
Devices are so easily enumerated through WinRT Windows.Devices namespace that wrapping the calls in a library is quite a chore for little benefit though to get the various modes and formats could still be a worthwhile project. For now conditional compilation to remove videodevices and any offending non-video file related activity in videodevice. In my opinion, this is a different , far less fundamental and important change which can possibly be done as a future project and also much more easily implemented in C++/CX.
ImageGrabber has the IMFSampleGrabberSinkCallback replaced with a base class (SharedSampleGrabber) which also be is base class for ImageGrabberRT. This change is necessary as the custom sink does not require a thread to pump events which is done through MediaCapture already. IMFSampleGrabberSinkCallback is the common element between both models and that piece can be shared. Initializing the new ImageGrabberRT is as simple as passing an already initialized MediaCapture object and any video format/encoding parameters.
The concurrency event is necessary to wait for completion and is the way the underlying, IAsyncAction wrappers in the task library work as well. Native WIN32 event objects would be an option if HAVE_CONCURRENCY is not defined. I could even imagine doing it with sleep/thread yield and InterlockedCompareExchange yet I am not enthusiastic about that approach either. Since there is a specific compiler HAVE_ for concurrency, I do not like pulling it in though I think for WinRT it is safe to say we will always have it available though should probably conditionally compile with the Interlocked option as WIN32 events would require HAVE_WIN32.
It looks like C++/CX cannot be used for the IMediaExtension sink (which should not be a problem) as using COM objects requires WRL and though deriving from IMediaExtension can be done, there is little purpose without COM. Objects from C++/CX can be swapped to interact with objects from native C++ as Inspectable* can reinterpret_cast to the ref object IInspectable^ and vice-versa. A solution to the COM class with C++/CX would be great so we could have dual support. Also without #define for every WRL object in use, the code will get quite muddy given that the */^ would need to be ifdef'd everywhere.
Update cap_msmf.cpp
Fixed bugs and completed the change. I believe the new classes need to be moved to a header file as the file has become to large and more classes need to be added for handling all the asynchronous problems (one wrapping IAsyncAction in a task and another for making a task out of IAsyncAction). Unfortunately, blocking on the UI thread is not an option in WinRT so a synchronous architecture is considered "illegal" by Microsoft's standards even if implementable (C++/CX ppltasks library throws errors if you try it). Worse, either by design or a bug in the MF MediaCapture class with Custom Sinks causes a crash if stop/start previewing without reinitializing (spPreferredPreviewMediaType is fatally nulled). After decompiling Windows.Media.dll, I worked around this in my own projects by using an activate-able custom sink ID which strangely assigns 1 to this pointer allowing it to be reinitialized in what can only be described as a hack by Microsoft. This would add additional overhead to the project to implement especially for static libraries as it requires IDL/DLL exporting followed by manifest declaration. Better to document that it is not supported.
Furthermore, an additional class for IMFAttributes should be implemented to make clean architecture for passing around attributes as opposed to directly calling non-COM interface calls on the objects and making use of SetProperties which would also be a set up for an object that uses the RuntimeClass activation ID.
The remaining changes are not difficult and will be complete soon along with debug tracing messages.
Update cap_msmf.cpp
Create cap_msmf.h
Update cap_msmf.cpp
Update cap_msmf.h
Update cap_msmf.cpp
Update cap_msmf.h
Update and rename cap_msmf.h to cap_msmf.hpp
Update cap_msmf.cpp
Update CMakeLists.txt
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.cpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Successful test - samples are grabbed
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Create ppltasks_winrt.h
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update ppltasks_winrt.h
Library updated and cleaned up with comments, marshaling, exceptions and linker settings
Update ppltasks_winrt.h
Fixed trailing whitespace
2013-12-14 16:53:30 +08:00
|
|
|
IMFActivate **ppDevices = NULL;
|
2013-04-03 09:01:20 +08:00
|
|
|
hr = MFEnumDeviceSources(pAttributes, &ppDevices, &count);
|
|
|
|
if (SUCCEEDED(hr))
|
|
|
|
{
|
|
|
|
if(count > 0)
|
|
|
|
{
|
|
|
|
for(UINT32 i = 0; i < count; i++)
|
|
|
|
{
|
|
|
|
videoDevice *vd = new videoDevice;
|
|
|
|
vd->readInfoOfDevice(ppDevices[i], i);
|
|
|
|
vds_Devices.push_back(vd);
|
|
|
|
SafeRelease(&ppDevices[i]);
|
|
|
|
}
|
|
|
|
SafeRelease(ppDevices);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
hr = -1;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
DebugPrintOut *DPO = &DebugPrintOut::getInstance();
|
|
|
|
DPO->printOut(L"VIDEODEVICES: The instances of the videoDevice class cannot be created\n");
|
|
|
|
}
|
|
|
|
return hr;
|
|
|
|
}
|
Update cap_msmf.cpp
Add support for WinRT in the MF capture framework by removing the disallowed calls to enumerate devices and create a sample grabber sink and adding framework for the MediaCapture interface and a custom sink which interfaces with the sample grabber callback interface. The change requires discussion for making it completely functional as redundancy is required given that if the source is a video file, the old code pathways must be used. Otherwise all IMFMediaSession, IMFMediaSource, and IMFActivate code must use a MediaCapture code path and all sink code must use the CMediaSink custom sink.
Support for the custom sink is extended to non-WinRT not for compatibility as Windows Vista client is a minimum regardless, but because it offers more flexibility, could be faster and is able to be used as an optionally different code path during sink creation based on a future configuration parameter.
My discussion and proposal to finish this change:
Devices are so easily enumerated through WinRT Windows.Devices namespace that wrapping the calls in a library is quite a chore for little benefit though to get the various modes and formats could still be a worthwhile project. For now conditional compilation to remove videodevices and any offending non-video file related activity in videodevice. In my opinion, this is a different , far less fundamental and important change which can possibly be done as a future project and also much more easily implemented in C++/CX.
ImageGrabber has the IMFSampleGrabberSinkCallback replaced with a base class (SharedSampleGrabber) which also be is base class for ImageGrabberRT. This change is necessary as the custom sink does not require a thread to pump events which is done through MediaCapture already. IMFSampleGrabberSinkCallback is the common element between both models and that piece can be shared. Initializing the new ImageGrabberRT is as simple as passing an already initialized MediaCapture object and any video format/encoding parameters.
The concurrency event is necessary to wait for completion and is the way the underlying, IAsyncAction wrappers in the task library work as well. Native WIN32 event objects would be an option if HAVE_CONCURRENCY is not defined. I could even imagine doing it with sleep/thread yield and InterlockedCompareExchange yet I am not enthusiastic about that approach either. Since there is a specific compiler HAVE_ for concurrency, I do not like pulling it in though I think for WinRT it is safe to say we will always have it available though should probably conditionally compile with the Interlocked option as WIN32 events would require HAVE_WIN32.
It looks like C++/CX cannot be used for the IMediaExtension sink (which should not be a problem) as using COM objects requires WRL and though deriving from IMediaExtension can be done, there is little purpose without COM. Objects from C++/CX can be swapped to interact with objects from native C++ as Inspectable* can reinterpret_cast to the ref object IInspectable^ and vice-versa. A solution to the COM class with C++/CX would be great so we could have dual support. Also without #define for every WRL object in use, the code will get quite muddy given that the */^ would need to be ifdef'd everywhere.
Update cap_msmf.cpp
Fixed bugs and completed the change. I believe the new classes need to be moved to a header file as the file has become to large and more classes need to be added for handling all the asynchronous problems (one wrapping IAsyncAction in a task and another for making a task out of IAsyncAction). Unfortunately, blocking on the UI thread is not an option in WinRT so a synchronous architecture is considered "illegal" by Microsoft's standards even if implementable (C++/CX ppltasks library throws errors if you try it). Worse, either by design or a bug in the MF MediaCapture class with Custom Sinks causes a crash if stop/start previewing without reinitializing (spPreferredPreviewMediaType is fatally nulled). After decompiling Windows.Media.dll, I worked around this in my own projects by using an activate-able custom sink ID which strangely assigns 1 to this pointer allowing it to be reinitialized in what can only be described as a hack by Microsoft. This would add additional overhead to the project to implement especially for static libraries as it requires IDL/DLL exporting followed by manifest declaration. Better to document that it is not supported.
Furthermore, an additional class for IMFAttributes should be implemented to make clean architecture for passing around attributes as opposed to directly calling non-COM interface calls on the objects and making use of SetProperties which would also be a set up for an object that uses the RuntimeClass activation ID.
The remaining changes are not difficult and will be complete soon along with debug tracing messages.
Update cap_msmf.cpp
Create cap_msmf.h
Update cap_msmf.cpp
Update cap_msmf.h
Update cap_msmf.cpp
Update cap_msmf.h
Update and rename cap_msmf.h to cap_msmf.hpp
Update cap_msmf.cpp
Update CMakeLists.txt
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.cpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Successful test - samples are grabbed
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Create ppltasks_winrt.h
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update ppltasks_winrt.h
Library updated and cleaned up with comments, marshaling, exceptions and linker settings
Update ppltasks_winrt.h
Fixed trailing whitespace
2013-12-14 16:53:30 +08:00
|
|
|
#endif
|
2013-04-16 21:25:10 +08:00
|
|
|
|
2013-08-05 02:34:36 +08:00
|
|
|
unsigned int videoDevices::getCount()
|
2013-04-03 09:01:20 +08:00
|
|
|
{
|
Update cap_msmf.cpp
Add support for WinRT in the MF capture framework by removing the disallowed calls to enumerate devices and create a sample grabber sink and adding framework for the MediaCapture interface and a custom sink which interfaces with the sample grabber callback interface. The change requires discussion for making it completely functional as redundancy is required given that if the source is a video file, the old code pathways must be used. Otherwise all IMFMediaSession, IMFMediaSource, and IMFActivate code must use a MediaCapture code path and all sink code must use the CMediaSink custom sink.
Support for the custom sink is extended to non-WinRT not for compatibility as Windows Vista client is a minimum regardless, but because it offers more flexibility, could be faster and is able to be used as an optionally different code path during sink creation based on a future configuration parameter.
My discussion and proposal to finish this change:
Devices are so easily enumerated through WinRT Windows.Devices namespace that wrapping the calls in a library is quite a chore for little benefit though to get the various modes and formats could still be a worthwhile project. For now conditional compilation to remove videodevices and any offending non-video file related activity in videodevice. In my opinion, this is a different , far less fundamental and important change which can possibly be done as a future project and also much more easily implemented in C++/CX.
ImageGrabber has the IMFSampleGrabberSinkCallback replaced with a base class (SharedSampleGrabber) which also be is base class for ImageGrabberRT. This change is necessary as the custom sink does not require a thread to pump events which is done through MediaCapture already. IMFSampleGrabberSinkCallback is the common element between both models and that piece can be shared. Initializing the new ImageGrabberRT is as simple as passing an already initialized MediaCapture object and any video format/encoding parameters.
The concurrency event is necessary to wait for completion and is the way the underlying, IAsyncAction wrappers in the task library work as well. Native WIN32 event objects would be an option if HAVE_CONCURRENCY is not defined. I could even imagine doing it with sleep/thread yield and InterlockedCompareExchange yet I am not enthusiastic about that approach either. Since there is a specific compiler HAVE_ for concurrency, I do not like pulling it in though I think for WinRT it is safe to say we will always have it available though should probably conditionally compile with the Interlocked option as WIN32 events would require HAVE_WIN32.
It looks like C++/CX cannot be used for the IMediaExtension sink (which should not be a problem) as using COM objects requires WRL and though deriving from IMediaExtension can be done, there is little purpose without COM. Objects from C++/CX can be swapped to interact with objects from native C++ as Inspectable* can reinterpret_cast to the ref object IInspectable^ and vice-versa. A solution to the COM class with C++/CX would be great so we could have dual support. Also without #define for every WRL object in use, the code will get quite muddy given that the */^ would need to be ifdef'd everywhere.
Update cap_msmf.cpp
Fixed bugs and completed the change. I believe the new classes need to be moved to a header file as the file has become to large and more classes need to be added for handling all the asynchronous problems (one wrapping IAsyncAction in a task and another for making a task out of IAsyncAction). Unfortunately, blocking on the UI thread is not an option in WinRT so a synchronous architecture is considered "illegal" by Microsoft's standards even if implementable (C++/CX ppltasks library throws errors if you try it). Worse, either by design or a bug in the MF MediaCapture class with Custom Sinks causes a crash if stop/start previewing without reinitializing (spPreferredPreviewMediaType is fatally nulled). After decompiling Windows.Media.dll, I worked around this in my own projects by using an activate-able custom sink ID which strangely assigns 1 to this pointer allowing it to be reinitialized in what can only be described as a hack by Microsoft. This would add additional overhead to the project to implement especially for static libraries as it requires IDL/DLL exporting followed by manifest declaration. Better to document that it is not supported.
Furthermore, an additional class for IMFAttributes should be implemented to make clean architecture for passing around attributes as opposed to directly calling non-COM interface calls on the objects and making use of SetProperties which would also be a set up for an object that uses the RuntimeClass activation ID.
The remaining changes are not difficult and will be complete soon along with debug tracing messages.
Update cap_msmf.cpp
Create cap_msmf.h
Update cap_msmf.cpp
Update cap_msmf.h
Update cap_msmf.cpp
Update cap_msmf.h
Update and rename cap_msmf.h to cap_msmf.hpp
Update cap_msmf.cpp
Update CMakeLists.txt
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.cpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Successful test - samples are grabbed
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Create ppltasks_winrt.h
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update ppltasks_winrt.h
Library updated and cleaned up with comments, marshaling, exceptions and linker settings
Update ppltasks_winrt.h
Fixed trailing whitespace
2013-12-14 16:53:30 +08:00
|
|
|
return (unsigned int)vds_Devices.size();
|
2013-04-03 09:01:20 +08:00
|
|
|
}
|
2013-04-16 21:25:10 +08:00
|
|
|
|
2013-04-03 18:48:23 +08:00
|
|
|
videoDevices& videoDevices::getInstance()
|
2013-04-03 09:01:20 +08:00
|
|
|
{
|
|
|
|
static videoDevices instance;
|
|
|
|
return instance;
|
|
|
|
}
|
2013-04-16 21:25:10 +08:00
|
|
|
|
2013-04-03 09:01:20 +08:00
|
|
|
Parametr::Parametr()
|
|
|
|
{
|
|
|
|
CurrentValue = 0;
|
|
|
|
Min = 0;
|
|
|
|
Max = 0;
|
|
|
|
Step = 0;
|
2013-04-03 18:48:23 +08:00
|
|
|
Default = 0;
|
2013-04-03 09:01:20 +08:00
|
|
|
Flag = 0;
|
|
|
|
}
|
2013-04-16 21:25:10 +08:00
|
|
|
|
2013-04-03 09:01:20 +08:00
|
|
|
MediaType::MediaType()
|
|
|
|
{
|
|
|
|
pMF_MT_AM_FORMAT_TYPEName = NULL;
|
|
|
|
pMF_MT_MAJOR_TYPEName = NULL;
|
|
|
|
pMF_MT_SUBTYPEName = NULL;
|
|
|
|
Clear();
|
|
|
|
}
|
2013-04-16 21:25:10 +08:00
|
|
|
|
2013-04-03 09:01:20 +08:00
|
|
|
MediaType::~MediaType()
|
|
|
|
{
|
|
|
|
Clear();
|
|
|
|
}
|
2013-04-16 21:25:10 +08:00
|
|
|
|
2013-04-03 09:01:20 +08:00
|
|
|
void MediaType::Clear()
|
|
|
|
{
|
|
|
|
MF_MT_FRAME_SIZE = 0;
|
|
|
|
height = 0;
|
|
|
|
width = 0;
|
|
|
|
MF_MT_YUV_MATRIX = 0;
|
|
|
|
MF_MT_VIDEO_LIGHTING = 0;
|
|
|
|
MF_MT_DEFAULT_STRIDE = 0;
|
|
|
|
MF_MT_VIDEO_CHROMA_SITING = 0;
|
|
|
|
MF_MT_FIXED_SIZE_SAMPLES = 0;
|
|
|
|
MF_MT_VIDEO_NOMINAL_RANGE = 0;
|
2013-05-23 00:50:54 +08:00
|
|
|
MF_MT_FRAME_RATE_NUMERATOR = 0;
|
|
|
|
MF_MT_FRAME_RATE_DENOMINATOR = 0;
|
2013-04-03 09:01:20 +08:00
|
|
|
MF_MT_PIXEL_ASPECT_RATIO = 0;
|
|
|
|
MF_MT_PIXEL_ASPECT_RATIO_low = 0;
|
|
|
|
MF_MT_ALL_SAMPLES_INDEPENDENT = 0;
|
|
|
|
MF_MT_FRAME_RATE_RANGE_MIN = 0;
|
|
|
|
MF_MT_FRAME_RATE_RANGE_MIN_low = 0;
|
|
|
|
MF_MT_SAMPLE_SIZE = 0;
|
|
|
|
MF_MT_VIDEO_PRIMARIES = 0;
|
|
|
|
MF_MT_INTERLACE_MODE = 0;
|
|
|
|
MF_MT_FRAME_RATE_RANGE_MAX = 0;
|
|
|
|
MF_MT_FRAME_RATE_RANGE_MAX_low = 0;
|
|
|
|
memset(&MF_MT_MAJOR_TYPE, 0, sizeof(GUID));
|
|
|
|
memset(&MF_MT_AM_FORMAT_TYPE, 0, sizeof(GUID));
|
|
|
|
memset(&MF_MT_SUBTYPE, 0, sizeof(GUID));
|
|
|
|
}
|
2013-04-16 21:25:10 +08:00
|
|
|
|
2013-04-03 09:01:20 +08:00
|
|
|
videoInput::videoInput(void): accessToDevices(false)
|
|
|
|
{
|
|
|
|
DebugPrintOut *DPO = &DebugPrintOut::getInstance();
|
|
|
|
DPO->printOut(L"\n***** VIDEOINPUT LIBRARY - 2013 (Author: Evgeny Pereguda) *****\n\n");
|
|
|
|
updateListOfDevices();
|
|
|
|
if(!accessToDevices)
|
Update cap_msmf.cpp
Add support for WinRT in the MF capture framework by removing the disallowed calls to enumerate devices and create a sample grabber sink and adding framework for the MediaCapture interface and a custom sink which interfaces with the sample grabber callback interface. The change requires discussion for making it completely functional as redundancy is required given that if the source is a video file, the old code pathways must be used. Otherwise all IMFMediaSession, IMFMediaSource, and IMFActivate code must use a MediaCapture code path and all sink code must use the CMediaSink custom sink.
Support for the custom sink is extended to non-WinRT not for compatibility as Windows Vista client is a minimum regardless, but because it offers more flexibility, could be faster and is able to be used as an optionally different code path during sink creation based on a future configuration parameter.
My discussion and proposal to finish this change:
Devices are so easily enumerated through WinRT Windows.Devices namespace that wrapping the calls in a library is quite a chore for little benefit though to get the various modes and formats could still be a worthwhile project. For now conditional compilation to remove videodevices and any offending non-video file related activity in videodevice. In my opinion, this is a different , far less fundamental and important change which can possibly be done as a future project and also much more easily implemented in C++/CX.
ImageGrabber has the IMFSampleGrabberSinkCallback replaced with a base class (SharedSampleGrabber) which also be is base class for ImageGrabberRT. This change is necessary as the custom sink does not require a thread to pump events which is done through MediaCapture already. IMFSampleGrabberSinkCallback is the common element between both models and that piece can be shared. Initializing the new ImageGrabberRT is as simple as passing an already initialized MediaCapture object and any video format/encoding parameters.
The concurrency event is necessary to wait for completion and is the way the underlying, IAsyncAction wrappers in the task library work as well. Native WIN32 event objects would be an option if HAVE_CONCURRENCY is not defined. I could even imagine doing it with sleep/thread yield and InterlockedCompareExchange yet I am not enthusiastic about that approach either. Since there is a specific compiler HAVE_ for concurrency, I do not like pulling it in though I think for WinRT it is safe to say we will always have it available though should probably conditionally compile with the Interlocked option as WIN32 events would require HAVE_WIN32.
It looks like C++/CX cannot be used for the IMediaExtension sink (which should not be a problem) as using COM objects requires WRL and though deriving from IMediaExtension can be done, there is little purpose without COM. Objects from C++/CX can be swapped to interact with objects from native C++ as Inspectable* can reinterpret_cast to the ref object IInspectable^ and vice-versa. A solution to the COM class with C++/CX would be great so we could have dual support. Also without #define for every WRL object in use, the code will get quite muddy given that the */^ would need to be ifdef'd everywhere.
Update cap_msmf.cpp
Fixed bugs and completed the change. I believe the new classes need to be moved to a header file as the file has become to large and more classes need to be added for handling all the asynchronous problems (one wrapping IAsyncAction in a task and another for making a task out of IAsyncAction). Unfortunately, blocking on the UI thread is not an option in WinRT so a synchronous architecture is considered "illegal" by Microsoft's standards even if implementable (C++/CX ppltasks library throws errors if you try it). Worse, either by design or a bug in the MF MediaCapture class with Custom Sinks causes a crash if stop/start previewing without reinitializing (spPreferredPreviewMediaType is fatally nulled). After decompiling Windows.Media.dll, I worked around this in my own projects by using an activate-able custom sink ID which strangely assigns 1 to this pointer allowing it to be reinitialized in what can only be described as a hack by Microsoft. This would add additional overhead to the project to implement especially for static libraries as it requires IDL/DLL exporting followed by manifest declaration. Better to document that it is not supported.
Furthermore, an additional class for IMFAttributes should be implemented to make clean architecture for passing around attributes as opposed to directly calling non-COM interface calls on the objects and making use of SetProperties which would also be a set up for an object that uses the RuntimeClass activation ID.
The remaining changes are not difficult and will be complete soon along with debug tracing messages.
Update cap_msmf.cpp
Create cap_msmf.h
Update cap_msmf.cpp
Update cap_msmf.h
Update cap_msmf.cpp
Update cap_msmf.h
Update and rename cap_msmf.h to cap_msmf.hpp
Update cap_msmf.cpp
Update CMakeLists.txt
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.cpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Successful test - samples are grabbed
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Create ppltasks_winrt.h
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update ppltasks_winrt.h
Library updated and cleaned up with comments, marshaling, exceptions and linker settings
Update ppltasks_winrt.h
Fixed trailing whitespace
2013-12-14 16:53:30 +08:00
|
|
|
DPO->printOut(L"INITIALIZATION: There is not any suitable video device\n");
|
2013-04-03 09:01:20 +08:00
|
|
|
}
|
2013-04-16 21:25:10 +08:00
|
|
|
|
2013-04-03 09:01:20 +08:00
|
|
|
void videoInput::updateListOfDevices()
|
|
|
|
{
|
|
|
|
DebugPrintOut *DPO = &DebugPrintOut::getInstance();
|
|
|
|
Media_Foundation *MF = &Media_Foundation::getInstance();
|
|
|
|
accessToDevices = MF->buildListOfDevices();
|
|
|
|
if(!accessToDevices)
|
Update cap_msmf.cpp
Add support for WinRT in the MF capture framework by removing the disallowed calls to enumerate devices and create a sample grabber sink and adding framework for the MediaCapture interface and a custom sink which interfaces with the sample grabber callback interface. The change requires discussion for making it completely functional as redundancy is required given that if the source is a video file, the old code pathways must be used. Otherwise all IMFMediaSession, IMFMediaSource, and IMFActivate code must use a MediaCapture code path and all sink code must use the CMediaSink custom sink.
Support for the custom sink is extended to non-WinRT not for compatibility as Windows Vista client is a minimum regardless, but because it offers more flexibility, could be faster and is able to be used as an optionally different code path during sink creation based on a future configuration parameter.
My discussion and proposal to finish this change:
Devices are so easily enumerated through WinRT Windows.Devices namespace that wrapping the calls in a library is quite a chore for little benefit though to get the various modes and formats could still be a worthwhile project. For now conditional compilation to remove videodevices and any offending non-video file related activity in videodevice. In my opinion, this is a different , far less fundamental and important change which can possibly be done as a future project and also much more easily implemented in C++/CX.
ImageGrabber has the IMFSampleGrabberSinkCallback replaced with a base class (SharedSampleGrabber) which also be is base class for ImageGrabberRT. This change is necessary as the custom sink does not require a thread to pump events which is done through MediaCapture already. IMFSampleGrabberSinkCallback is the common element between both models and that piece can be shared. Initializing the new ImageGrabberRT is as simple as passing an already initialized MediaCapture object and any video format/encoding parameters.
The concurrency event is necessary to wait for completion and is the way the underlying, IAsyncAction wrappers in the task library work as well. Native WIN32 event objects would be an option if HAVE_CONCURRENCY is not defined. I could even imagine doing it with sleep/thread yield and InterlockedCompareExchange yet I am not enthusiastic about that approach either. Since there is a specific compiler HAVE_ for concurrency, I do not like pulling it in though I think for WinRT it is safe to say we will always have it available though should probably conditionally compile with the Interlocked option as WIN32 events would require HAVE_WIN32.
It looks like C++/CX cannot be used for the IMediaExtension sink (which should not be a problem) as using COM objects requires WRL and though deriving from IMediaExtension can be done, there is little purpose without COM. Objects from C++/CX can be swapped to interact with objects from native C++ as Inspectable* can reinterpret_cast to the ref object IInspectable^ and vice-versa. A solution to the COM class with C++/CX would be great so we could have dual support. Also without #define for every WRL object in use, the code will get quite muddy given that the */^ would need to be ifdef'd everywhere.
Update cap_msmf.cpp
Fixed bugs and completed the change. I believe the new classes need to be moved to a header file as the file has become to large and more classes need to be added for handling all the asynchronous problems (one wrapping IAsyncAction in a task and another for making a task out of IAsyncAction). Unfortunately, blocking on the UI thread is not an option in WinRT so a synchronous architecture is considered "illegal" by Microsoft's standards even if implementable (C++/CX ppltasks library throws errors if you try it). Worse, either by design or a bug in the MF MediaCapture class with Custom Sinks causes a crash if stop/start previewing without reinitializing (spPreferredPreviewMediaType is fatally nulled). After decompiling Windows.Media.dll, I worked around this in my own projects by using an activate-able custom sink ID which strangely assigns 1 to this pointer allowing it to be reinitialized in what can only be described as a hack by Microsoft. This would add additional overhead to the project to implement especially for static libraries as it requires IDL/DLL exporting followed by manifest declaration. Better to document that it is not supported.
Furthermore, an additional class for IMFAttributes should be implemented to make clean architecture for passing around attributes as opposed to directly calling non-COM interface calls on the objects and making use of SetProperties which would also be a set up for an object that uses the RuntimeClass activation ID.
The remaining changes are not difficult and will be complete soon along with debug tracing messages.
Update cap_msmf.cpp
Create cap_msmf.h
Update cap_msmf.cpp
Update cap_msmf.h
Update cap_msmf.cpp
Update cap_msmf.h
Update and rename cap_msmf.h to cap_msmf.hpp
Update cap_msmf.cpp
Update CMakeLists.txt
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.cpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Successful test - samples are grabbed
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Create ppltasks_winrt.h
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update ppltasks_winrt.h
Library updated and cleaned up with comments, marshaling, exceptions and linker settings
Update ppltasks_winrt.h
Fixed trailing whitespace
2013-12-14 16:53:30 +08:00
|
|
|
DPO->printOut(L"UPDATING: There is not any suitable video device\n");
|
2013-04-03 09:01:20 +08:00
|
|
|
}
|
2013-04-16 21:25:10 +08:00
|
|
|
|
2013-04-03 09:01:20 +08:00
|
|
|
videoInput::~videoInput(void)
|
|
|
|
{
|
|
|
|
DebugPrintOut *DPO = &DebugPrintOut::getInstance();
|
|
|
|
DPO->printOut(L"\n***** CLOSE VIDEOINPUT LIBRARY - 2013 *****\n\n");
|
|
|
|
}
|
2013-04-16 21:25:10 +08:00
|
|
|
|
2013-04-03 09:01:20 +08:00
|
|
|
IMFMediaSource *videoInput::getMediaSource(int deviceID)
|
|
|
|
{
|
|
|
|
DebugPrintOut *DPO = &DebugPrintOut::getInstance();
|
|
|
|
if(accessToDevices)
|
|
|
|
{
|
|
|
|
videoDevices *VDS = &videoDevices::getInstance();
|
|
|
|
videoDevice * VD = VDS->getDevice(deviceID);
|
|
|
|
if(VD)
|
|
|
|
{
|
|
|
|
IMFMediaSource *out = VD->getMediaSource();
|
|
|
|
if(!out)
|
|
|
|
DPO->printOut(L"VideoDevice %i: There is not any suitable IMFMediaSource interface\n", deviceID);
|
|
|
|
return out;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
DPO->printOut(L"VIDEODEVICE(s): There is not any suitable video device\n");
|
|
|
|
}
|
|
|
|
return NULL;
|
|
|
|
}
|
2013-04-16 21:25:10 +08:00
|
|
|
|
2013-04-03 09:01:20 +08:00
|
|
|
bool videoInput::setupDevice(int deviceID, unsigned int id)
|
|
|
|
{
|
|
|
|
DebugPrintOut *DPO = &DebugPrintOut::getInstance();
|
|
|
|
if (deviceID < 0 )
|
|
|
|
{
|
|
|
|
DPO->printOut(L"VIDEODEVICE %i: Invalid device ID\n", deviceID);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
if(accessToDevices)
|
|
|
|
{
|
|
|
|
videoDevices *VDS = &videoDevices::getInstance();
|
|
|
|
videoDevice * VD = VDS->getDevice(deviceID);
|
|
|
|
if(VD)
|
|
|
|
{
|
|
|
|
bool out = VD->setupDevice(id);
|
|
|
|
if(!out)
|
|
|
|
DPO->printOut(L"VIDEODEVICE %i: This device cannot be started\n", deviceID);
|
|
|
|
return out;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
DPO->printOut(L"VIDEODEVICE(s): There is not any suitable video device\n");
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
2013-04-16 21:25:10 +08:00
|
|
|
|
2013-04-03 09:01:20 +08:00
|
|
|
bool videoInput::setupDevice(int deviceID, unsigned int w, unsigned int h, unsigned int idealFramerate)
|
|
|
|
{
|
|
|
|
DebugPrintOut *DPO = &DebugPrintOut::getInstance();
|
|
|
|
if (deviceID < 0 )
|
|
|
|
{
|
|
|
|
DPO->printOut(L"VIDEODEVICE %i: Invalid device ID\n", deviceID);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
if(accessToDevices)
|
|
|
|
{
|
|
|
|
videoDevices *VDS = &videoDevices::getInstance();
|
|
|
|
videoDevice * VD = VDS->getDevice(deviceID);
|
|
|
|
if(VD)
|
|
|
|
{
|
|
|
|
bool out = VD->setupDevice(w, h, idealFramerate);
|
|
|
|
if(!out)
|
|
|
|
DPO->printOut(L"VIDEODEVICE %i: this device cannot be started\n", deviceID);
|
|
|
|
return out;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
DPO->printOut(L"VIDEODEVICE(s): There is not any suitable video device\n", deviceID);
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
2013-04-16 21:25:10 +08:00
|
|
|
|
2013-04-03 09:01:20 +08:00
|
|
|
MediaType videoInput::getFormat(int deviceID, unsigned int id)
|
|
|
|
{
|
|
|
|
DebugPrintOut *DPO = &DebugPrintOut::getInstance();
|
|
|
|
if (deviceID < 0)
|
|
|
|
{
|
|
|
|
DPO->printOut(L"VIDEODEVICE %i: Invalid device ID\n", deviceID);
|
|
|
|
return MediaType();
|
|
|
|
}
|
|
|
|
if(accessToDevices)
|
|
|
|
{
|
|
|
|
videoDevices *VDS = &videoDevices::getInstance();
|
|
|
|
videoDevice * VD = VDS->getDevice(deviceID);
|
2013-04-03 18:48:23 +08:00
|
|
|
if(VD)
|
2013-04-03 09:01:20 +08:00
|
|
|
return VD->getFormat(id);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
DPO->printOut(L"VIDEODEVICE(s): There is not any suitable video device\n");
|
|
|
|
}
|
|
|
|
return MediaType();
|
|
|
|
}
|
2013-04-16 21:25:10 +08:00
|
|
|
|
2013-04-03 09:01:20 +08:00
|
|
|
bool videoInput::isDeviceSetup(int deviceID)
|
|
|
|
{
|
|
|
|
DebugPrintOut *DPO = &DebugPrintOut::getInstance();
|
|
|
|
if (deviceID < 0)
|
|
|
|
{
|
|
|
|
DPO->printOut(L"VIDEODEVICE %i: Invalid device ID\n", deviceID);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
if(accessToDevices)
|
|
|
|
{
|
|
|
|
videoDevices *VDS = &videoDevices::getInstance();
|
|
|
|
videoDevice * VD = VDS->getDevice(deviceID);
|
|
|
|
if(VD)
|
|
|
|
return VD->isDeviceSetup();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
DPO->printOut(L"VIDEODEVICE(s): There is not any suitable video device\n");
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
2013-04-16 21:25:10 +08:00
|
|
|
|
2013-04-03 09:01:20 +08:00
|
|
|
bool videoInput::isDeviceMediaSource(int deviceID)
|
|
|
|
{
|
|
|
|
DebugPrintOut *DPO = &DebugPrintOut::getInstance();
|
|
|
|
if (deviceID < 0)
|
|
|
|
{
|
|
|
|
DPO->printOut(L"VIDEODEVICE %i: Invalid device ID\n", deviceID);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
if(accessToDevices)
|
|
|
|
{
|
|
|
|
videoDevices *VDS = &videoDevices::getInstance();
|
|
|
|
videoDevice * VD = VDS->getDevice(deviceID);
|
|
|
|
if(VD)
|
|
|
|
return VD->isDeviceMediaSource();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
DPO->printOut(L"Device(s): There is not any suitable video device\n");
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
2013-04-16 21:25:10 +08:00
|
|
|
|
2013-04-03 09:01:20 +08:00
|
|
|
bool videoInput::isDeviceRawDataSource(int deviceID)
|
|
|
|
{
|
|
|
|
DebugPrintOut *DPO = &DebugPrintOut::getInstance();
|
|
|
|
if (deviceID < 0)
|
|
|
|
{
|
|
|
|
DPO->printOut(L"VIDEODEVICE %i: Invalid device ID\n", deviceID);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
if(accessToDevices)
|
|
|
|
{
|
|
|
|
videoDevices *VDS = &videoDevices::getInstance();
|
|
|
|
videoDevice * VD = VDS->getDevice(deviceID);
|
|
|
|
if(VD)
|
|
|
|
{
|
|
|
|
bool isRaw = VD->isDeviceRawDataSource();
|
|
|
|
return isRaw;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
DPO->printOut(L"VIDEODEVICE(s): There is not any suitable video device\n");
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
2013-04-16 21:25:10 +08:00
|
|
|
|
2013-04-03 09:01:20 +08:00
|
|
|
bool videoInput::isFrameNew(int deviceID)
|
2013-04-03 18:48:23 +08:00
|
|
|
{
|
2013-04-03 09:01:20 +08:00
|
|
|
DebugPrintOut *DPO = &DebugPrintOut::getInstance();
|
|
|
|
if (deviceID < 0)
|
|
|
|
{
|
|
|
|
DPO->printOut(L"VIDEODEVICE %i: Invalid device ID\n", deviceID);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
if(accessToDevices)
|
|
|
|
{
|
|
|
|
if(!isDeviceSetup(deviceID))
|
|
|
|
{
|
|
|
|
if(isDeviceMediaSource(deviceID))
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
videoDevices *VDS = &videoDevices::getInstance();
|
|
|
|
videoDevice * VD = VDS->getDevice(deviceID);
|
|
|
|
if(VD)
|
|
|
|
{
|
|
|
|
return VD->isFrameNew();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
DPO->printOut(L"VIDEODEVICE(s): There is not any suitable video device\n");
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
2013-04-16 21:25:10 +08:00
|
|
|
|
Update cap_msmf.cpp
Add support for WinRT in the MF capture framework by removing the disallowed calls to enumerate devices and create a sample grabber sink and adding framework for the MediaCapture interface and a custom sink which interfaces with the sample grabber callback interface. The change requires discussion for making it completely functional as redundancy is required given that if the source is a video file, the old code pathways must be used. Otherwise all IMFMediaSession, IMFMediaSource, and IMFActivate code must use a MediaCapture code path and all sink code must use the CMediaSink custom sink.
Support for the custom sink is extended to non-WinRT not for compatibility as Windows Vista client is a minimum regardless, but because it offers more flexibility, could be faster and is able to be used as an optionally different code path during sink creation based on a future configuration parameter.
My discussion and proposal to finish this change:
Devices are so easily enumerated through WinRT Windows.Devices namespace that wrapping the calls in a library is quite a chore for little benefit though to get the various modes and formats could still be a worthwhile project. For now conditional compilation to remove videodevices and any offending non-video file related activity in videodevice. In my opinion, this is a different , far less fundamental and important change which can possibly be done as a future project and also much more easily implemented in C++/CX.
ImageGrabber has the IMFSampleGrabberSinkCallback replaced with a base class (SharedSampleGrabber) which also be is base class for ImageGrabberRT. This change is necessary as the custom sink does not require a thread to pump events which is done through MediaCapture already. IMFSampleGrabberSinkCallback is the common element between both models and that piece can be shared. Initializing the new ImageGrabberRT is as simple as passing an already initialized MediaCapture object and any video format/encoding parameters.
The concurrency event is necessary to wait for completion and is the way the underlying, IAsyncAction wrappers in the task library work as well. Native WIN32 event objects would be an option if HAVE_CONCURRENCY is not defined. I could even imagine doing it with sleep/thread yield and InterlockedCompareExchange yet I am not enthusiastic about that approach either. Since there is a specific compiler HAVE_ for concurrency, I do not like pulling it in though I think for WinRT it is safe to say we will always have it available though should probably conditionally compile with the Interlocked option as WIN32 events would require HAVE_WIN32.
It looks like C++/CX cannot be used for the IMediaExtension sink (which should not be a problem) as using COM objects requires WRL and though deriving from IMediaExtension can be done, there is little purpose without COM. Objects from C++/CX can be swapped to interact with objects from native C++ as Inspectable* can reinterpret_cast to the ref object IInspectable^ and vice-versa. A solution to the COM class with C++/CX would be great so we could have dual support. Also without #define for every WRL object in use, the code will get quite muddy given that the */^ would need to be ifdef'd everywhere.
Update cap_msmf.cpp
Fixed bugs and completed the change. I believe the new classes need to be moved to a header file as the file has become to large and more classes need to be added for handling all the asynchronous problems (one wrapping IAsyncAction in a task and another for making a task out of IAsyncAction). Unfortunately, blocking on the UI thread is not an option in WinRT so a synchronous architecture is considered "illegal" by Microsoft's standards even if implementable (C++/CX ppltasks library throws errors if you try it). Worse, either by design or a bug in the MF MediaCapture class with Custom Sinks causes a crash if stop/start previewing without reinitializing (spPreferredPreviewMediaType is fatally nulled). After decompiling Windows.Media.dll, I worked around this in my own projects by using an activate-able custom sink ID which strangely assigns 1 to this pointer allowing it to be reinitialized in what can only be described as a hack by Microsoft. This would add additional overhead to the project to implement especially for static libraries as it requires IDL/DLL exporting followed by manifest declaration. Better to document that it is not supported.
Furthermore, an additional class for IMFAttributes should be implemented to make clean architecture for passing around attributes as opposed to directly calling non-COM interface calls on the objects and making use of SetProperties which would also be a set up for an object that uses the RuntimeClass activation ID.
The remaining changes are not difficult and will be complete soon along with debug tracing messages.
Update cap_msmf.cpp
Create cap_msmf.h
Update cap_msmf.cpp
Update cap_msmf.h
Update cap_msmf.cpp
Update cap_msmf.h
Update and rename cap_msmf.h to cap_msmf.hpp
Update cap_msmf.cpp
Update CMakeLists.txt
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.cpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Successful test - samples are grabbed
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Create ppltasks_winrt.h
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update ppltasks_winrt.h
Library updated and cleaned up with comments, marshaling, exceptions and linker settings
Update ppltasks_winrt.h
Fixed trailing whitespace
2013-12-14 16:53:30 +08:00
|
|
|
#ifdef HAVE_WINRT
|
|
|
|
void videoInput::waitForDevice(int deviceID)
|
|
|
|
{
|
|
|
|
DebugPrintOut *DPO = &DebugPrintOut::getInstance();
|
|
|
|
if (deviceID < 0)
|
|
|
|
{
|
|
|
|
DPO->printOut(L"VIDEODEVICE %i: Invalid device ID\n", deviceID);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if(accessToDevices)
|
|
|
|
{
|
|
|
|
if(!isDeviceSetup(deviceID))
|
|
|
|
{
|
|
|
|
if(isDeviceMediaSource(deviceID))
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
videoDevices *VDS = &videoDevices::getInstance();
|
|
|
|
videoDevice * VD = VDS->getDevice(deviceID);
|
|
|
|
if(VD)
|
|
|
|
{
|
|
|
|
VD->waitForDevice();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
DPO->printOut(L"VIDEODEVICE(s): There is not any suitable video device\n");
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2013-04-03 09:01:20 +08:00
|
|
|
unsigned int videoInput::getCountFormats(int deviceID)
|
|
|
|
{
|
|
|
|
DebugPrintOut *DPO = &DebugPrintOut::getInstance();
|
|
|
|
if (deviceID < 0)
|
|
|
|
{
|
|
|
|
DPO->printOut(L"VIDEODEVICE %i: Invalid device ID\n", deviceID);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
if(accessToDevices)
|
|
|
|
{
|
|
|
|
videoDevices *VDS = &videoDevices::getInstance();
|
|
|
|
videoDevice * VD = VDS->getDevice(deviceID);
|
|
|
|
if(VD)
|
|
|
|
return VD->getCountFormats();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
DPO->printOut(L"VIDEODEVICE(s): There is not any suitable video device\n");
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
2013-04-16 21:25:10 +08:00
|
|
|
|
2013-04-03 09:01:20 +08:00
|
|
|
void videoInput::closeAllDevices()
|
|
|
|
{
|
|
|
|
videoDevices *VDS = &videoDevices::getInstance();
|
|
|
|
for(unsigned int i = 0; i < VDS->getCount(); i++)
|
|
|
|
closeDevice(i);
|
|
|
|
}
|
2013-04-16 21:25:10 +08:00
|
|
|
|
2013-04-03 09:01:20 +08:00
|
|
|
void videoInput::setParametrs(int deviceID, CamParametrs parametrs)
|
|
|
|
{
|
|
|
|
DebugPrintOut *DPO = &DebugPrintOut::getInstance();
|
|
|
|
if (deviceID < 0)
|
|
|
|
{
|
|
|
|
DPO->printOut(L"VIDEODEVICE %i: Invalid device ID\n", deviceID);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if(accessToDevices)
|
|
|
|
{
|
|
|
|
videoDevices *VDS = &videoDevices::getInstance();
|
|
|
|
videoDevice *VD = VDS->getDevice(deviceID);
|
|
|
|
if(VD)
|
|
|
|
VD->setParametrs(parametrs);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
DPO->printOut(L"VIDEODEVICE(s): There is not any suitable video device\n");
|
|
|
|
}
|
|
|
|
}
|
2013-04-16 21:25:10 +08:00
|
|
|
|
2013-04-03 09:01:20 +08:00
|
|
|
CamParametrs videoInput::getParametrs(int deviceID)
|
|
|
|
{
|
|
|
|
DebugPrintOut *DPO = &DebugPrintOut::getInstance();
|
|
|
|
CamParametrs out;
|
|
|
|
if (deviceID < 0)
|
|
|
|
{
|
|
|
|
DPO->printOut(L"VIDEODEVICE %i: Invalid device ID\n", deviceID);
|
|
|
|
return out;
|
|
|
|
}
|
|
|
|
if(accessToDevices)
|
|
|
|
{
|
|
|
|
videoDevices *VDS = &videoDevices::getInstance();
|
|
|
|
videoDevice *VD = VDS->getDevice(deviceID);
|
|
|
|
if(VD)
|
|
|
|
out = VD->getParametrs();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
DPO->printOut(L"VIDEODEVICE(s): There is not any suitable video device\n");
|
|
|
|
}
|
|
|
|
return out;
|
|
|
|
}
|
2013-04-16 21:25:10 +08:00
|
|
|
|
2013-04-03 09:01:20 +08:00
|
|
|
void videoInput::closeDevice(int deviceID)
|
|
|
|
{
|
|
|
|
DebugPrintOut *DPO = &DebugPrintOut::getInstance();
|
|
|
|
if (deviceID < 0)
|
|
|
|
{
|
|
|
|
DPO->printOut(L"VIDEODEVICE %i: Invalid device ID\n", deviceID);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if(accessToDevices)
|
|
|
|
{
|
|
|
|
videoDevices *VDS = &videoDevices::getInstance();
|
|
|
|
videoDevice *VD = VDS->getDevice(deviceID);
|
|
|
|
if(VD)
|
|
|
|
VD->closeDevice();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
DPO->printOut(L"VIDEODEVICE(s): There is not any suitable video device\n");
|
|
|
|
}
|
|
|
|
}
|
2013-04-16 21:25:10 +08:00
|
|
|
|
2013-04-03 09:01:20 +08:00
|
|
|
unsigned int videoInput::getWidth(int deviceID)
|
|
|
|
{
|
|
|
|
DebugPrintOut *DPO = &DebugPrintOut::getInstance();
|
|
|
|
if (deviceID < 0)
|
|
|
|
{
|
|
|
|
DPO->printOut(L"VIDEODEVICE %i: Invalid device ID\n", deviceID);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
if(accessToDevices)
|
|
|
|
{
|
|
|
|
videoDevices *VDS = &videoDevices::getInstance();
|
|
|
|
videoDevice * VD = VDS->getDevice(deviceID);
|
2013-04-03 18:48:23 +08:00
|
|
|
if(VD)
|
2013-04-03 09:01:20 +08:00
|
|
|
return VD->getWidth();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
DPO->printOut(L"VIDEODEVICE(s): There is not any suitable video device\n");
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
2013-04-16 21:25:10 +08:00
|
|
|
|
2013-04-03 09:01:20 +08:00
|
|
|
unsigned int videoInput::getHeight(int deviceID)
|
|
|
|
{
|
|
|
|
DebugPrintOut *DPO = &DebugPrintOut::getInstance();
|
|
|
|
if (deviceID < 0)
|
|
|
|
{
|
|
|
|
DPO->printOut(L"VIDEODEVICE %i: Invalid device ID\n", deviceID);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
if(accessToDevices)
|
|
|
|
{
|
|
|
|
videoDevices *VDS = &videoDevices::getInstance();
|
|
|
|
videoDevice * VD = VDS->getDevice(deviceID);
|
|
|
|
if(VD)
|
|
|
|
return VD->getHeight();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
DPO->printOut(L"VIDEODEVICE(s): There is not any suitable video device\n");
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
2013-04-16 21:25:10 +08:00
|
|
|
|
2013-04-03 09:01:20 +08:00
|
|
|
wchar_t *videoInput::getNameVideoDevice(int deviceID)
|
|
|
|
{
|
|
|
|
DebugPrintOut *DPO = &DebugPrintOut::getInstance();
|
|
|
|
if (deviceID < 0)
|
|
|
|
{
|
|
|
|
DPO->printOut(L"VIDEODEVICE %i: Invalid device ID\n", deviceID);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
if(accessToDevices)
|
|
|
|
{
|
|
|
|
videoDevices *VDS = &videoDevices::getInstance();
|
|
|
|
videoDevice * VD = VDS->getDevice(deviceID);
|
|
|
|
if(VD)
|
|
|
|
return VD->getName();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
DPO->printOut(L"VIDEODEVICE(s): There is not any suitable video device\n");
|
|
|
|
}
|
|
|
|
return L"Empty";
|
|
|
|
}
|
2013-04-16 21:25:10 +08:00
|
|
|
|
2013-04-03 09:01:20 +08:00
|
|
|
unsigned int videoInput::listDevices(bool silent)
|
|
|
|
{
|
|
|
|
DebugPrintOut *DPO = &DebugPrintOut::getInstance();
|
|
|
|
int out = 0;
|
|
|
|
if(accessToDevices)
|
|
|
|
{
|
|
|
|
videoDevices *VDS = &videoDevices::getInstance();
|
Update cap_msmf.cpp
Add support for WinRT in the MF capture framework by removing the disallowed calls to enumerate devices and create a sample grabber sink and adding framework for the MediaCapture interface and a custom sink which interfaces with the sample grabber callback interface. The change requires discussion for making it completely functional as redundancy is required given that if the source is a video file, the old code pathways must be used. Otherwise all IMFMediaSession, IMFMediaSource, and IMFActivate code must use a MediaCapture code path and all sink code must use the CMediaSink custom sink.
Support for the custom sink is extended to non-WinRT not for compatibility as Windows Vista client is a minimum regardless, but because it offers more flexibility, could be faster and is able to be used as an optionally different code path during sink creation based on a future configuration parameter.
My discussion and proposal to finish this change:
Devices are so easily enumerated through WinRT Windows.Devices namespace that wrapping the calls in a library is quite a chore for little benefit though to get the various modes and formats could still be a worthwhile project. For now conditional compilation to remove videodevices and any offending non-video file related activity in videodevice. In my opinion, this is a different , far less fundamental and important change which can possibly be done as a future project and also much more easily implemented in C++/CX.
ImageGrabber has the IMFSampleGrabberSinkCallback replaced with a base class (SharedSampleGrabber) which also be is base class for ImageGrabberRT. This change is necessary as the custom sink does not require a thread to pump events which is done through MediaCapture already. IMFSampleGrabberSinkCallback is the common element between both models and that piece can be shared. Initializing the new ImageGrabberRT is as simple as passing an already initialized MediaCapture object and any video format/encoding parameters.
The concurrency event is necessary to wait for completion and is the way the underlying, IAsyncAction wrappers in the task library work as well. Native WIN32 event objects would be an option if HAVE_CONCURRENCY is not defined. I could even imagine doing it with sleep/thread yield and InterlockedCompareExchange yet I am not enthusiastic about that approach either. Since there is a specific compiler HAVE_ for concurrency, I do not like pulling it in though I think for WinRT it is safe to say we will always have it available though should probably conditionally compile with the Interlocked option as WIN32 events would require HAVE_WIN32.
It looks like C++/CX cannot be used for the IMediaExtension sink (which should not be a problem) as using COM objects requires WRL and though deriving from IMediaExtension can be done, there is little purpose without COM. Objects from C++/CX can be swapped to interact with objects from native C++ as Inspectable* can reinterpret_cast to the ref object IInspectable^ and vice-versa. A solution to the COM class with C++/CX would be great so we could have dual support. Also without #define for every WRL object in use, the code will get quite muddy given that the */^ would need to be ifdef'd everywhere.
Update cap_msmf.cpp
Fixed bugs and completed the change. I believe the new classes need to be moved to a header file as the file has become to large and more classes need to be added for handling all the asynchronous problems (one wrapping IAsyncAction in a task and another for making a task out of IAsyncAction). Unfortunately, blocking on the UI thread is not an option in WinRT so a synchronous architecture is considered "illegal" by Microsoft's standards even if implementable (C++/CX ppltasks library throws errors if you try it). Worse, either by design or a bug in the MF MediaCapture class with Custom Sinks causes a crash if stop/start previewing without reinitializing (spPreferredPreviewMediaType is fatally nulled). After decompiling Windows.Media.dll, I worked around this in my own projects by using an activate-able custom sink ID which strangely assigns 1 to this pointer allowing it to be reinitialized in what can only be described as a hack by Microsoft. This would add additional overhead to the project to implement especially for static libraries as it requires IDL/DLL exporting followed by manifest declaration. Better to document that it is not supported.
Furthermore, an additional class for IMFAttributes should be implemented to make clean architecture for passing around attributes as opposed to directly calling non-COM interface calls on the objects and making use of SetProperties which would also be a set up for an object that uses the RuntimeClass activation ID.
The remaining changes are not difficult and will be complete soon along with debug tracing messages.
Update cap_msmf.cpp
Create cap_msmf.h
Update cap_msmf.cpp
Update cap_msmf.h
Update cap_msmf.cpp
Update cap_msmf.h
Update and rename cap_msmf.h to cap_msmf.hpp
Update cap_msmf.cpp
Update CMakeLists.txt
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.cpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Successful test - samples are grabbed
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Create ppltasks_winrt.h
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update ppltasks_winrt.h
Library updated and cleaned up with comments, marshaling, exceptions and linker settings
Update ppltasks_winrt.h
Fixed trailing whitespace
2013-12-14 16:53:30 +08:00
|
|
|
#ifdef HAVE_WINRT
|
|
|
|
VDS->waitInit();
|
|
|
|
#endif
|
2013-04-03 09:01:20 +08:00
|
|
|
out = VDS->getCount();
|
|
|
|
DebugPrintOut *DPO = &DebugPrintOut::getInstance();
|
|
|
|
if(!silent)DPO->printOut(L"\nVIDEOINPUT SPY MODE!\n\n");
|
|
|
|
if(!silent)DPO->printOut(L"SETUP: Looking For Capture Devices\n");
|
|
|
|
for(int i = 0; i < out; i++)
|
|
|
|
{
|
|
|
|
if(!silent)DPO->printOut(L"SETUP: %i) %s \n",i, getNameVideoDevice(i));
|
|
|
|
}
|
|
|
|
if(!silent)DPO->printOut(L"SETUP: %i Device(s) found\n\n", out);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
DPO->printOut(L"VIDEODEVICE(s): There is not any suitable video device\n");
|
|
|
|
}
|
|
|
|
return out;
|
|
|
|
}
|
2013-04-16 21:25:10 +08:00
|
|
|
|
2013-04-03 18:48:23 +08:00
|
|
|
videoInput& videoInput::getInstance()
|
2013-04-03 09:01:20 +08:00
|
|
|
{
|
|
|
|
static videoInput instance;
|
|
|
|
return instance;
|
|
|
|
}
|
2013-04-16 21:25:10 +08:00
|
|
|
|
2013-04-03 09:01:20 +08:00
|
|
|
bool videoInput::isDevicesAcceable()
|
|
|
|
{
|
|
|
|
return accessToDevices;
|
|
|
|
}
|
2013-04-16 21:25:10 +08:00
|
|
|
|
2013-04-03 09:01:20 +08:00
|
|
|
void videoInput::setVerbose(bool state)
|
|
|
|
{
|
|
|
|
DebugPrintOut *DPO = &DebugPrintOut::getInstance();
|
2013-04-03 18:48:23 +08:00
|
|
|
DPO->setVerbose(state);
|
2013-04-03 09:01:20 +08:00
|
|
|
}
|
2013-04-16 21:25:10 +08:00
|
|
|
|
2013-04-03 09:01:20 +08:00
|
|
|
void videoInput::setEmergencyStopEvent(int deviceID, void *userData, void(*func)(int, void *))
|
|
|
|
{
|
|
|
|
DebugPrintOut *DPO = &DebugPrintOut::getInstance();
|
|
|
|
if (deviceID < 0)
|
|
|
|
{
|
|
|
|
DPO->printOut(L"VIDEODEVICE %i: Invalid device ID\n", deviceID);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if(accessToDevices)
|
|
|
|
{
|
|
|
|
if(func)
|
|
|
|
{
|
|
|
|
videoDevices *VDS = &videoDevices::getInstance();
|
|
|
|
videoDevice * VD = VDS->getDevice(deviceID);
|
2013-04-03 18:48:23 +08:00
|
|
|
if(VD)
|
2013-04-03 09:01:20 +08:00
|
|
|
VD->setEmergencyStopEvent(userData, func);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
DPO->printOut(L"VIDEODEVICE(s): There is not any suitable video device\n");
|
|
|
|
}
|
|
|
|
}
|
2013-04-16 21:25:10 +08:00
|
|
|
|
2013-04-03 09:01:20 +08:00
|
|
|
bool videoInput::getPixels(int deviceID, unsigned char * dstBuffer, bool flipRedAndBlue, bool flipImage)
|
|
|
|
{
|
|
|
|
bool success = false;
|
|
|
|
unsigned int bytes = 3;
|
|
|
|
DebugPrintOut *DPO = &DebugPrintOut::getInstance();
|
|
|
|
if (deviceID < 0)
|
|
|
|
{
|
|
|
|
DPO->printOut(L"VIDEODEVICE %i: Invalid device ID\n", deviceID);
|
|
|
|
return success;
|
|
|
|
}
|
|
|
|
if(accessToDevices)
|
|
|
|
{
|
|
|
|
bool isRaw = isDeviceRawDataSource(deviceID);
|
|
|
|
if(isRaw)
|
|
|
|
{
|
|
|
|
videoDevices *VDS = &videoDevices::getInstance();
|
|
|
|
DebugPrintOut *DPO = &DebugPrintOut::getInstance();
|
|
|
|
RawImage *RIOut = VDS->getDevice(deviceID)->getRawImageOut();
|
|
|
|
if(RIOut)
|
|
|
|
{
|
|
|
|
unsigned int height = VDS->getDevice(deviceID)->getHeight();
|
2013-04-03 18:48:23 +08:00
|
|
|
unsigned int width = VDS->getDevice(deviceID)->getWidth();
|
2013-04-03 09:01:20 +08:00
|
|
|
unsigned int size = bytes * width * height;
|
|
|
|
if(size == RIOut->getSize())
|
2013-04-03 18:48:23 +08:00
|
|
|
{
|
2013-04-03 09:01:20 +08:00
|
|
|
processPixels(RIOut->getpPixels(), dstBuffer, width, height, bytes, flipRedAndBlue, flipImage);
|
|
|
|
success = true;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
DPO->printOut(L"ERROR: GetPixels() - bufferSizes do not match!\n");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
DPO->printOut(L"ERROR: GetPixels() - Unable to grab frame for device %i\n", deviceID);
|
2013-04-03 18:48:23 +08:00
|
|
|
}
|
2013-04-03 09:01:20 +08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
DPO->printOut(L"ERROR: GetPixels() - Not raw data source device %i\n", deviceID);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
DPO->printOut(L"VIDEODEVICE(s): There is not any suitable video device\n");
|
|
|
|
}
|
|
|
|
return success;
|
|
|
|
}
|
2013-04-16 21:25:10 +08:00
|
|
|
|
2013-04-03 18:48:23 +08:00
|
|
|
void videoInput::processPixels(unsigned char * src, unsigned char * dst, unsigned int width,
|
2013-04-03 09:01:20 +08:00
|
|
|
unsigned int height, unsigned int bpp, bool bRGB, bool bFlip)
|
2013-04-03 18:48:23 +08:00
|
|
|
{
|
2013-04-03 09:01:20 +08:00
|
|
|
unsigned int widthInBytes = width * bpp;
|
|
|
|
unsigned int numBytes = widthInBytes * height;
|
|
|
|
int *dstInt, *srcInt;
|
|
|
|
if(!bRGB)
|
2013-04-03 18:48:23 +08:00
|
|
|
{
|
2013-04-03 09:01:20 +08:00
|
|
|
if(bFlip)
|
|
|
|
{
|
|
|
|
for(unsigned int y = 0; y < height; y++)
|
|
|
|
{
|
|
|
|
dstInt = (int *)(dst + (y * widthInBytes));
|
|
|
|
srcInt = (int *)(src + ( (height -y -1) * widthInBytes));
|
|
|
|
memcpy(dstInt, srcInt, widthInBytes);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
memcpy(dst, src, numBytes);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if(bFlip)
|
|
|
|
{
|
|
|
|
unsigned int x = 0;
|
|
|
|
unsigned int y = (height - 1) * widthInBytes;
|
|
|
|
src += y;
|
|
|
|
for(unsigned int i = 0; i < numBytes; i+=3)
|
|
|
|
{
|
|
|
|
if(x >= width)
|
|
|
|
{
|
|
|
|
x = 0;
|
|
|
|
src -= widthInBytes*2;
|
|
|
|
}
|
|
|
|
*dst = *(src+2);
|
|
|
|
dst++;
|
|
|
|
*dst = *(src+1);
|
2013-04-03 18:48:23 +08:00
|
|
|
dst++;
|
2013-04-03 09:01:20 +08:00
|
|
|
*dst = *src;
|
2013-04-03 18:48:23 +08:00
|
|
|
dst++;
|
|
|
|
src+=3;
|
|
|
|
x++;
|
2013-04-03 09:01:20 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
2013-04-03 18:48:23 +08:00
|
|
|
{
|
2013-04-03 09:01:20 +08:00
|
|
|
for(unsigned int i = 0; i < numBytes; i+=3)
|
|
|
|
{
|
|
|
|
*dst = *(src+2);
|
|
|
|
dst++;
|
|
|
|
*dst = *(src+1);
|
2013-04-03 18:48:23 +08:00
|
|
|
dst++;
|
2013-04-03 09:01:20 +08:00
|
|
|
*dst = *src;
|
2013-04-03 18:48:23 +08:00
|
|
|
dst++;
|
|
|
|
src+=3;
|
2013-04-03 09:01:20 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2013-04-16 21:25:10 +08:00
|
|
|
|
2013-04-03 09:01:20 +08:00
|
|
|
/******* Capturing video from camera via Microsoft Media Foundation **********/
|
|
|
|
class CvCaptureCAM_MSMF : public CvCapture
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
CvCaptureCAM_MSMF();
|
|
|
|
virtual ~CvCaptureCAM_MSMF();
|
|
|
|
virtual bool open( int index );
|
|
|
|
virtual void close();
|
|
|
|
virtual double getProperty(int);
|
|
|
|
virtual bool setProperty(int, double);
|
|
|
|
virtual bool grabFrame();
|
|
|
|
virtual IplImage* retrieveFrame(int);
|
|
|
|
virtual int getCaptureDomain() { return CV_CAP_MSMF; } // Return the type of the capture object: CV_CAP_VFW, etc...
|
|
|
|
protected:
|
|
|
|
void init();
|
2013-06-27 14:56:50 +08:00
|
|
|
int index, width, height, fourcc;
|
2013-04-03 09:01:20 +08:00
|
|
|
IplImage* frame;
|
|
|
|
videoInput VI;
|
Update cap_msmf.cpp
Add support for WinRT in the MF capture framework by removing the disallowed calls to enumerate devices and create a sample grabber sink and adding framework for the MediaCapture interface and a custom sink which interfaces with the sample grabber callback interface. The change requires discussion for making it completely functional as redundancy is required given that if the source is a video file, the old code pathways must be used. Otherwise all IMFMediaSession, IMFMediaSource, and IMFActivate code must use a MediaCapture code path and all sink code must use the CMediaSink custom sink.
Support for the custom sink is extended to non-WinRT not for compatibility as Windows Vista client is a minimum regardless, but because it offers more flexibility, could be faster and is able to be used as an optionally different code path during sink creation based on a future configuration parameter.
My discussion and proposal to finish this change:
Devices are so easily enumerated through WinRT Windows.Devices namespace that wrapping the calls in a library is quite a chore for little benefit though to get the various modes and formats could still be a worthwhile project. For now conditional compilation to remove videodevices and any offending non-video file related activity in videodevice. In my opinion, this is a different , far less fundamental and important change which can possibly be done as a future project and also much more easily implemented in C++/CX.
ImageGrabber has the IMFSampleGrabberSinkCallback replaced with a base class (SharedSampleGrabber) which also be is base class for ImageGrabberRT. This change is necessary as the custom sink does not require a thread to pump events which is done through MediaCapture already. IMFSampleGrabberSinkCallback is the common element between both models and that piece can be shared. Initializing the new ImageGrabberRT is as simple as passing an already initialized MediaCapture object and any video format/encoding parameters.
The concurrency event is necessary to wait for completion and is the way the underlying, IAsyncAction wrappers in the task library work as well. Native WIN32 event objects would be an option if HAVE_CONCURRENCY is not defined. I could even imagine doing it with sleep/thread yield and InterlockedCompareExchange yet I am not enthusiastic about that approach either. Since there is a specific compiler HAVE_ for concurrency, I do not like pulling it in though I think for WinRT it is safe to say we will always have it available though should probably conditionally compile with the Interlocked option as WIN32 events would require HAVE_WIN32.
It looks like C++/CX cannot be used for the IMediaExtension sink (which should not be a problem) as using COM objects requires WRL and though deriving from IMediaExtension can be done, there is little purpose without COM. Objects from C++/CX can be swapped to interact with objects from native C++ as Inspectable* can reinterpret_cast to the ref object IInspectable^ and vice-versa. A solution to the COM class with C++/CX would be great so we could have dual support. Also without #define for every WRL object in use, the code will get quite muddy given that the */^ would need to be ifdef'd everywhere.
Update cap_msmf.cpp
Fixed bugs and completed the change. I believe the new classes need to be moved to a header file as the file has become to large and more classes need to be added for handling all the asynchronous problems (one wrapping IAsyncAction in a task and another for making a task out of IAsyncAction). Unfortunately, blocking on the UI thread is not an option in WinRT so a synchronous architecture is considered "illegal" by Microsoft's standards even if implementable (C++/CX ppltasks library throws errors if you try it). Worse, either by design or a bug in the MF MediaCapture class with Custom Sinks causes a crash if stop/start previewing without reinitializing (spPreferredPreviewMediaType is fatally nulled). After decompiling Windows.Media.dll, I worked around this in my own projects by using an activate-able custom sink ID which strangely assigns 1 to this pointer allowing it to be reinitialized in what can only be described as a hack by Microsoft. This would add additional overhead to the project to implement especially for static libraries as it requires IDL/DLL exporting followed by manifest declaration. Better to document that it is not supported.
Furthermore, an additional class for IMFAttributes should be implemented to make clean architecture for passing around attributes as opposed to directly calling non-COM interface calls on the objects and making use of SetProperties which would also be a set up for an object that uses the RuntimeClass activation ID.
The remaining changes are not difficult and will be complete soon along with debug tracing messages.
Update cap_msmf.cpp
Create cap_msmf.h
Update cap_msmf.cpp
Update cap_msmf.h
Update cap_msmf.cpp
Update cap_msmf.h
Update and rename cap_msmf.h to cap_msmf.hpp
Update cap_msmf.cpp
Update CMakeLists.txt
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.cpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Successful test - samples are grabbed
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Create ppltasks_winrt.h
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update ppltasks_winrt.h
Library updated and cleaned up with comments, marshaling, exceptions and linker settings
Update ppltasks_winrt.h
Fixed trailing whitespace
2013-12-14 16:53:30 +08:00
|
|
|
#ifdef HAVE_WINRT
|
|
|
|
DEFINE_TASK<bool> openTask;
|
|
|
|
Concurrency::critical_section lock;
|
|
|
|
#endif
|
2013-04-03 09:01:20 +08:00
|
|
|
};
|
2013-05-14 20:17:34 +08:00
|
|
|
|
2013-04-03 09:01:20 +08:00
|
|
|
struct SuppressVideoInputMessages
|
|
|
|
{
|
|
|
|
SuppressVideoInputMessages() { videoInput::setVerbose(true); }
|
|
|
|
};
|
2013-05-14 20:17:34 +08:00
|
|
|
|
2013-04-03 09:01:20 +08:00
|
|
|
static SuppressVideoInputMessages do_it;
|
2013-05-14 20:17:34 +08:00
|
|
|
|
2013-04-03 09:01:20 +08:00
|
|
|
CvCaptureCAM_MSMF::CvCaptureCAM_MSMF():
|
|
|
|
index(-1),
|
|
|
|
width(-1),
|
|
|
|
height(-1),
|
|
|
|
fourcc(-1),
|
2013-05-14 20:17:34 +08:00
|
|
|
frame(NULL),
|
2013-04-03 09:01:20 +08:00
|
|
|
VI(videoInput::getInstance())
|
|
|
|
{
|
|
|
|
CoInitialize(0);
|
|
|
|
}
|
2013-06-27 14:56:50 +08:00
|
|
|
|
2013-04-03 09:01:20 +08:00
|
|
|
CvCaptureCAM_MSMF::~CvCaptureCAM_MSMF()
|
|
|
|
{
|
|
|
|
close();
|
|
|
|
CoUninitialize();
|
|
|
|
}
|
2013-06-27 14:56:50 +08:00
|
|
|
|
2013-04-03 09:01:20 +08:00
|
|
|
void CvCaptureCAM_MSMF::close()
|
|
|
|
{
|
|
|
|
if( index >= 0 )
|
|
|
|
{
|
|
|
|
VI.closeDevice(index);
|
|
|
|
index = -1;
|
|
|
|
cvReleaseImage(&frame);
|
|
|
|
}
|
2013-06-27 14:56:50 +08:00
|
|
|
width = height = -1;
|
2013-04-03 09:01:20 +08:00
|
|
|
}
|
2013-04-16 21:25:10 +08:00
|
|
|
|
2013-04-03 09:01:20 +08:00
|
|
|
// Initialize camera input
|
|
|
|
bool CvCaptureCAM_MSMF::open( int _index )
|
|
|
|
{
|
Update cap_msmf.cpp
Add support for WinRT in the MF capture framework by removing the disallowed calls to enumerate devices and create a sample grabber sink and adding framework for the MediaCapture interface and a custom sink which interfaces with the sample grabber callback interface. The change requires discussion for making it completely functional as redundancy is required given that if the source is a video file, the old code pathways must be used. Otherwise all IMFMediaSession, IMFMediaSource, and IMFActivate code must use a MediaCapture code path and all sink code must use the CMediaSink custom sink.
Support for the custom sink is extended to non-WinRT not for compatibility as Windows Vista client is a minimum regardless, but because it offers more flexibility, could be faster and is able to be used as an optionally different code path during sink creation based on a future configuration parameter.
My discussion and proposal to finish this change:
Devices are so easily enumerated through WinRT Windows.Devices namespace that wrapping the calls in a library is quite a chore for little benefit though to get the various modes and formats could still be a worthwhile project. For now conditional compilation to remove videodevices and any offending non-video file related activity in videodevice. In my opinion, this is a different , far less fundamental and important change which can possibly be done as a future project and also much more easily implemented in C++/CX.
ImageGrabber has the IMFSampleGrabberSinkCallback replaced with a base class (SharedSampleGrabber) which also be is base class for ImageGrabberRT. This change is necessary as the custom sink does not require a thread to pump events which is done through MediaCapture already. IMFSampleGrabberSinkCallback is the common element between both models and that piece can be shared. Initializing the new ImageGrabberRT is as simple as passing an already initialized MediaCapture object and any video format/encoding parameters.
The concurrency event is necessary to wait for completion and is the way the underlying, IAsyncAction wrappers in the task library work as well. Native WIN32 event objects would be an option if HAVE_CONCURRENCY is not defined. I could even imagine doing it with sleep/thread yield and InterlockedCompareExchange yet I am not enthusiastic about that approach either. Since there is a specific compiler HAVE_ for concurrency, I do not like pulling it in though I think for WinRT it is safe to say we will always have it available though should probably conditionally compile with the Interlocked option as WIN32 events would require HAVE_WIN32.
It looks like C++/CX cannot be used for the IMediaExtension sink (which should not be a problem) as using COM objects requires WRL and though deriving from IMediaExtension can be done, there is little purpose without COM. Objects from C++/CX can be swapped to interact with objects from native C++ as Inspectable* can reinterpret_cast to the ref object IInspectable^ and vice-versa. A solution to the COM class with C++/CX would be great so we could have dual support. Also without #define for every WRL object in use, the code will get quite muddy given that the */^ would need to be ifdef'd everywhere.
Update cap_msmf.cpp
Fixed bugs and completed the change. I believe the new classes need to be moved to a header file as the file has become to large and more classes need to be added for handling all the asynchronous problems (one wrapping IAsyncAction in a task and another for making a task out of IAsyncAction). Unfortunately, blocking on the UI thread is not an option in WinRT so a synchronous architecture is considered "illegal" by Microsoft's standards even if implementable (C++/CX ppltasks library throws errors if you try it). Worse, either by design or a bug in the MF MediaCapture class with Custom Sinks causes a crash if stop/start previewing without reinitializing (spPreferredPreviewMediaType is fatally nulled). After decompiling Windows.Media.dll, I worked around this in my own projects by using an activate-able custom sink ID which strangely assigns 1 to this pointer allowing it to be reinitialized in what can only be described as a hack by Microsoft. This would add additional overhead to the project to implement especially for static libraries as it requires IDL/DLL exporting followed by manifest declaration. Better to document that it is not supported.
Furthermore, an additional class for IMFAttributes should be implemented to make clean architecture for passing around attributes as opposed to directly calling non-COM interface calls on the objects and making use of SetProperties which would also be a set up for an object that uses the RuntimeClass activation ID.
The remaining changes are not difficult and will be complete soon along with debug tracing messages.
Update cap_msmf.cpp
Create cap_msmf.h
Update cap_msmf.cpp
Update cap_msmf.h
Update cap_msmf.cpp
Update cap_msmf.h
Update and rename cap_msmf.h to cap_msmf.hpp
Update cap_msmf.cpp
Update CMakeLists.txt
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.cpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Successful test - samples are grabbed
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Create ppltasks_winrt.h
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update ppltasks_winrt.h
Library updated and cleaned up with comments, marshaling, exceptions and linker settings
Update ppltasks_winrt.h
Fixed trailing whitespace
2013-12-14 16:53:30 +08:00
|
|
|
#ifdef HAVE_WINRT
|
|
|
|
SAVE_CURRENT_CONTEXT(context);
|
|
|
|
auto func = [_index, context, this]() -> bool {
|
|
|
|
#endif
|
2013-04-03 09:01:20 +08:00
|
|
|
int try_index = _index;
|
|
|
|
int devices = 0;
|
|
|
|
close();
|
|
|
|
devices = VI.listDevices(true);
|
|
|
|
if (devices == 0)
|
|
|
|
return false;
|
|
|
|
try_index = try_index < 0 ? 0 : (try_index > devices-1 ? devices-1 : try_index);
|
Update cap_msmf.cpp
Add support for WinRT in the MF capture framework by removing the disallowed calls to enumerate devices and create a sample grabber sink and adding framework for the MediaCapture interface and a custom sink which interfaces with the sample grabber callback interface. The change requires discussion for making it completely functional as redundancy is required given that if the source is a video file, the old code pathways must be used. Otherwise all IMFMediaSession, IMFMediaSource, and IMFActivate code must use a MediaCapture code path and all sink code must use the CMediaSink custom sink.
Support for the custom sink is extended to non-WinRT not for compatibility as Windows Vista client is a minimum regardless, but because it offers more flexibility, could be faster and is able to be used as an optionally different code path during sink creation based on a future configuration parameter.
My discussion and proposal to finish this change:
Devices are so easily enumerated through WinRT Windows.Devices namespace that wrapping the calls in a library is quite a chore for little benefit though to get the various modes and formats could still be a worthwhile project. For now conditional compilation to remove videodevices and any offending non-video file related activity in videodevice. In my opinion, this is a different , far less fundamental and important change which can possibly be done as a future project and also much more easily implemented in C++/CX.
ImageGrabber has the IMFSampleGrabberSinkCallback replaced with a base class (SharedSampleGrabber) which also be is base class for ImageGrabberRT. This change is necessary as the custom sink does not require a thread to pump events which is done through MediaCapture already. IMFSampleGrabberSinkCallback is the common element between both models and that piece can be shared. Initializing the new ImageGrabberRT is as simple as passing an already initialized MediaCapture object and any video format/encoding parameters.
The concurrency event is necessary to wait for completion and is the way the underlying, IAsyncAction wrappers in the task library work as well. Native WIN32 event objects would be an option if HAVE_CONCURRENCY is not defined. I could even imagine doing it with sleep/thread yield and InterlockedCompareExchange yet I am not enthusiastic about that approach either. Since there is a specific compiler HAVE_ for concurrency, I do not like pulling it in though I think for WinRT it is safe to say we will always have it available though should probably conditionally compile with the Interlocked option as WIN32 events would require HAVE_WIN32.
It looks like C++/CX cannot be used for the IMediaExtension sink (which should not be a problem) as using COM objects requires WRL and though deriving from IMediaExtension can be done, there is little purpose without COM. Objects from C++/CX can be swapped to interact with objects from native C++ as Inspectable* can reinterpret_cast to the ref object IInspectable^ and vice-versa. A solution to the COM class with C++/CX would be great so we could have dual support. Also without #define for every WRL object in use, the code will get quite muddy given that the */^ would need to be ifdef'd everywhere.
Update cap_msmf.cpp
Fixed bugs and completed the change. I believe the new classes need to be moved to a header file as the file has become to large and more classes need to be added for handling all the asynchronous problems (one wrapping IAsyncAction in a task and another for making a task out of IAsyncAction). Unfortunately, blocking on the UI thread is not an option in WinRT so a synchronous architecture is considered "illegal" by Microsoft's standards even if implementable (C++/CX ppltasks library throws errors if you try it). Worse, either by design or a bug in the MF MediaCapture class with Custom Sinks causes a crash if stop/start previewing without reinitializing (spPreferredPreviewMediaType is fatally nulled). After decompiling Windows.Media.dll, I worked around this in my own projects by using an activate-able custom sink ID which strangely assigns 1 to this pointer allowing it to be reinitialized in what can only be described as a hack by Microsoft. This would add additional overhead to the project to implement especially for static libraries as it requires IDL/DLL exporting followed by manifest declaration. Better to document that it is not supported.
Furthermore, an additional class for IMFAttributes should be implemented to make clean architecture for passing around attributes as opposed to directly calling non-COM interface calls on the objects and making use of SetProperties which would also be a set up for an object that uses the RuntimeClass activation ID.
The remaining changes are not difficult and will be complete soon along with debug tracing messages.
Update cap_msmf.cpp
Create cap_msmf.h
Update cap_msmf.cpp
Update cap_msmf.h
Update cap_msmf.cpp
Update cap_msmf.h
Update and rename cap_msmf.h to cap_msmf.hpp
Update cap_msmf.cpp
Update CMakeLists.txt
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.cpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Successful test - samples are grabbed
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Create ppltasks_winrt.h
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update ppltasks_winrt.h
Library updated and cleaned up with comments, marshaling, exceptions and linker settings
Update ppltasks_winrt.h
Fixed trailing whitespace
2013-12-14 16:53:30 +08:00
|
|
|
#ifdef HAVE_WINRT
|
|
|
|
HRESULT hr;
|
|
|
|
BEGIN_CALL_IN_CONTEXT(hr, context, this, try_index)
|
|
|
|
#endif
|
2013-04-03 09:01:20 +08:00
|
|
|
VI.setupDevice(try_index);
|
Update cap_msmf.cpp
Add support for WinRT in the MF capture framework by removing the disallowed calls to enumerate devices and create a sample grabber sink and adding framework for the MediaCapture interface and a custom sink which interfaces with the sample grabber callback interface. The change requires discussion for making it completely functional as redundancy is required given that if the source is a video file, the old code pathways must be used. Otherwise all IMFMediaSession, IMFMediaSource, and IMFActivate code must use a MediaCapture code path and all sink code must use the CMediaSink custom sink.
Support for the custom sink is extended to non-WinRT not for compatibility as Windows Vista client is a minimum regardless, but because it offers more flexibility, could be faster and is able to be used as an optionally different code path during sink creation based on a future configuration parameter.
My discussion and proposal to finish this change:
Devices are so easily enumerated through WinRT Windows.Devices namespace that wrapping the calls in a library is quite a chore for little benefit though to get the various modes and formats could still be a worthwhile project. For now conditional compilation to remove videodevices and any offending non-video file related activity in videodevice. In my opinion, this is a different , far less fundamental and important change which can possibly be done as a future project and also much more easily implemented in C++/CX.
ImageGrabber has the IMFSampleGrabberSinkCallback replaced with a base class (SharedSampleGrabber) which also be is base class for ImageGrabberRT. This change is necessary as the custom sink does not require a thread to pump events which is done through MediaCapture already. IMFSampleGrabberSinkCallback is the common element between both models and that piece can be shared. Initializing the new ImageGrabberRT is as simple as passing an already initialized MediaCapture object and any video format/encoding parameters.
The concurrency event is necessary to wait for completion and is the way the underlying, IAsyncAction wrappers in the task library work as well. Native WIN32 event objects would be an option if HAVE_CONCURRENCY is not defined. I could even imagine doing it with sleep/thread yield and InterlockedCompareExchange yet I am not enthusiastic about that approach either. Since there is a specific compiler HAVE_ for concurrency, I do not like pulling it in though I think for WinRT it is safe to say we will always have it available though should probably conditionally compile with the Interlocked option as WIN32 events would require HAVE_WIN32.
It looks like C++/CX cannot be used for the IMediaExtension sink (which should not be a problem) as using COM objects requires WRL and though deriving from IMediaExtension can be done, there is little purpose without COM. Objects from C++/CX can be swapped to interact with objects from native C++ as Inspectable* can reinterpret_cast to the ref object IInspectable^ and vice-versa. A solution to the COM class with C++/CX would be great so we could have dual support. Also without #define for every WRL object in use, the code will get quite muddy given that the */^ would need to be ifdef'd everywhere.
Update cap_msmf.cpp
Fixed bugs and completed the change. I believe the new classes need to be moved to a header file as the file has become to large and more classes need to be added for handling all the asynchronous problems (one wrapping IAsyncAction in a task and another for making a task out of IAsyncAction). Unfortunately, blocking on the UI thread is not an option in WinRT so a synchronous architecture is considered "illegal" by Microsoft's standards even if implementable (C++/CX ppltasks library throws errors if you try it). Worse, either by design or a bug in the MF MediaCapture class with Custom Sinks causes a crash if stop/start previewing without reinitializing (spPreferredPreviewMediaType is fatally nulled). After decompiling Windows.Media.dll, I worked around this in my own projects by using an activate-able custom sink ID which strangely assigns 1 to this pointer allowing it to be reinitialized in what can only be described as a hack by Microsoft. This would add additional overhead to the project to implement especially for static libraries as it requires IDL/DLL exporting followed by manifest declaration. Better to document that it is not supported.
Furthermore, an additional class for IMFAttributes should be implemented to make clean architecture for passing around attributes as opposed to directly calling non-COM interface calls on the objects and making use of SetProperties which would also be a set up for an object that uses the RuntimeClass activation ID.
The remaining changes are not difficult and will be complete soon along with debug tracing messages.
Update cap_msmf.cpp
Create cap_msmf.h
Update cap_msmf.cpp
Update cap_msmf.h
Update cap_msmf.cpp
Update cap_msmf.h
Update and rename cap_msmf.h to cap_msmf.hpp
Update cap_msmf.cpp
Update CMakeLists.txt
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.cpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Successful test - samples are grabbed
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Create ppltasks_winrt.h
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update ppltasks_winrt.h
Library updated and cleaned up with comments, marshaling, exceptions and linker settings
Update ppltasks_winrt.h
Fixed trailing whitespace
2013-12-14 16:53:30 +08:00
|
|
|
#ifdef HAVE_WINRT
|
|
|
|
END_CALL_IN_CONTEXT(S_OK)
|
|
|
|
VI.waitForDevice(try_index);
|
|
|
|
BEGIN_CALL_IN_CONTEXT(hr, context, this, try_index)
|
|
|
|
HRESULT hr = S_OK;
|
|
|
|
#endif
|
2013-04-03 09:01:20 +08:00
|
|
|
if( !VI.isFrameNew(try_index) )
|
Update cap_msmf.cpp
Add support for WinRT in the MF capture framework by removing the disallowed calls to enumerate devices and create a sample grabber sink and adding framework for the MediaCapture interface and a custom sink which interfaces with the sample grabber callback interface. The change requires discussion for making it completely functional as redundancy is required given that if the source is a video file, the old code pathways must be used. Otherwise all IMFMediaSession, IMFMediaSource, and IMFActivate code must use a MediaCapture code path and all sink code must use the CMediaSink custom sink.
Support for the custom sink is extended to non-WinRT not for compatibility as Windows Vista client is a minimum regardless, but because it offers more flexibility, could be faster and is able to be used as an optionally different code path during sink creation based on a future configuration parameter.
My discussion and proposal to finish this change:
Devices are so easily enumerated through WinRT Windows.Devices namespace that wrapping the calls in a library is quite a chore for little benefit though to get the various modes and formats could still be a worthwhile project. For now conditional compilation to remove videodevices and any offending non-video file related activity in videodevice. In my opinion, this is a different , far less fundamental and important change which can possibly be done as a future project and also much more easily implemented in C++/CX.
ImageGrabber has the IMFSampleGrabberSinkCallback replaced with a base class (SharedSampleGrabber) which also be is base class for ImageGrabberRT. This change is necessary as the custom sink does not require a thread to pump events which is done through MediaCapture already. IMFSampleGrabberSinkCallback is the common element between both models and that piece can be shared. Initializing the new ImageGrabberRT is as simple as passing an already initialized MediaCapture object and any video format/encoding parameters.
The concurrency event is necessary to wait for completion and is the way the underlying, IAsyncAction wrappers in the task library work as well. Native WIN32 event objects would be an option if HAVE_CONCURRENCY is not defined. I could even imagine doing it with sleep/thread yield and InterlockedCompareExchange yet I am not enthusiastic about that approach either. Since there is a specific compiler HAVE_ for concurrency, I do not like pulling it in though I think for WinRT it is safe to say we will always have it available though should probably conditionally compile with the Interlocked option as WIN32 events would require HAVE_WIN32.
It looks like C++/CX cannot be used for the IMediaExtension sink (which should not be a problem) as using COM objects requires WRL and though deriving from IMediaExtension can be done, there is little purpose without COM. Objects from C++/CX can be swapped to interact with objects from native C++ as Inspectable* can reinterpret_cast to the ref object IInspectable^ and vice-versa. A solution to the COM class with C++/CX would be great so we could have dual support. Also without #define for every WRL object in use, the code will get quite muddy given that the */^ would need to be ifdef'd everywhere.
Update cap_msmf.cpp
Fixed bugs and completed the change. I believe the new classes need to be moved to a header file as the file has become to large and more classes need to be added for handling all the asynchronous problems (one wrapping IAsyncAction in a task and another for making a task out of IAsyncAction). Unfortunately, blocking on the UI thread is not an option in WinRT so a synchronous architecture is considered "illegal" by Microsoft's standards even if implementable (C++/CX ppltasks library throws errors if you try it). Worse, either by design or a bug in the MF MediaCapture class with Custom Sinks causes a crash if stop/start previewing without reinitializing (spPreferredPreviewMediaType is fatally nulled). After decompiling Windows.Media.dll, I worked around this in my own projects by using an activate-able custom sink ID which strangely assigns 1 to this pointer allowing it to be reinitialized in what can only be described as a hack by Microsoft. This would add additional overhead to the project to implement especially for static libraries as it requires IDL/DLL exporting followed by manifest declaration. Better to document that it is not supported.
Furthermore, an additional class for IMFAttributes should be implemented to make clean architecture for passing around attributes as opposed to directly calling non-COM interface calls on the objects and making use of SetProperties which would also be a set up for an object that uses the RuntimeClass activation ID.
The remaining changes are not difficult and will be complete soon along with debug tracing messages.
Update cap_msmf.cpp
Create cap_msmf.h
Update cap_msmf.cpp
Update cap_msmf.h
Update cap_msmf.cpp
Update cap_msmf.h
Update and rename cap_msmf.h to cap_msmf.hpp
Update cap_msmf.cpp
Update CMakeLists.txt
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.cpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Successful test - samples are grabbed
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Create ppltasks_winrt.h
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update ppltasks_winrt.h
Library updated and cleaned up with comments, marshaling, exceptions and linker settings
Update ppltasks_winrt.h
Fixed trailing whitespace
2013-12-14 16:53:30 +08:00
|
|
|
#ifdef HAVE_WINRT
|
|
|
|
hr = E_FAIL;
|
|
|
|
#else
|
2013-04-03 09:01:20 +08:00
|
|
|
return false;
|
Update cap_msmf.cpp
Add support for WinRT in the MF capture framework by removing the disallowed calls to enumerate devices and create a sample grabber sink and adding framework for the MediaCapture interface and a custom sink which interfaces with the sample grabber callback interface. The change requires discussion for making it completely functional as redundancy is required given that if the source is a video file, the old code pathways must be used. Otherwise all IMFMediaSession, IMFMediaSource, and IMFActivate code must use a MediaCapture code path and all sink code must use the CMediaSink custom sink.
Support for the custom sink is extended to non-WinRT not for compatibility as Windows Vista client is a minimum regardless, but because it offers more flexibility, could be faster and is able to be used as an optionally different code path during sink creation based on a future configuration parameter.
My discussion and proposal to finish this change:
Devices are so easily enumerated through WinRT Windows.Devices namespace that wrapping the calls in a library is quite a chore for little benefit though to get the various modes and formats could still be a worthwhile project. For now conditional compilation to remove videodevices and any offending non-video file related activity in videodevice. In my opinion, this is a different , far less fundamental and important change which can possibly be done as a future project and also much more easily implemented in C++/CX.
ImageGrabber has the IMFSampleGrabberSinkCallback replaced with a base class (SharedSampleGrabber) which also be is base class for ImageGrabberRT. This change is necessary as the custom sink does not require a thread to pump events which is done through MediaCapture already. IMFSampleGrabberSinkCallback is the common element between both models and that piece can be shared. Initializing the new ImageGrabberRT is as simple as passing an already initialized MediaCapture object and any video format/encoding parameters.
The concurrency event is necessary to wait for completion and is the way the underlying, IAsyncAction wrappers in the task library work as well. Native WIN32 event objects would be an option if HAVE_CONCURRENCY is not defined. I could even imagine doing it with sleep/thread yield and InterlockedCompareExchange yet I am not enthusiastic about that approach either. Since there is a specific compiler HAVE_ for concurrency, I do not like pulling it in though I think for WinRT it is safe to say we will always have it available though should probably conditionally compile with the Interlocked option as WIN32 events would require HAVE_WIN32.
It looks like C++/CX cannot be used for the IMediaExtension sink (which should not be a problem) as using COM objects requires WRL and though deriving from IMediaExtension can be done, there is little purpose without COM. Objects from C++/CX can be swapped to interact with objects from native C++ as Inspectable* can reinterpret_cast to the ref object IInspectable^ and vice-versa. A solution to the COM class with C++/CX would be great so we could have dual support. Also without #define for every WRL object in use, the code will get quite muddy given that the */^ would need to be ifdef'd everywhere.
Update cap_msmf.cpp
Fixed bugs and completed the change. I believe the new classes need to be moved to a header file as the file has become to large and more classes need to be added for handling all the asynchronous problems (one wrapping IAsyncAction in a task and another for making a task out of IAsyncAction). Unfortunately, blocking on the UI thread is not an option in WinRT so a synchronous architecture is considered "illegal" by Microsoft's standards even if implementable (C++/CX ppltasks library throws errors if you try it). Worse, either by design or a bug in the MF MediaCapture class with Custom Sinks causes a crash if stop/start previewing without reinitializing (spPreferredPreviewMediaType is fatally nulled). After decompiling Windows.Media.dll, I worked around this in my own projects by using an activate-able custom sink ID which strangely assigns 1 to this pointer allowing it to be reinitialized in what can only be described as a hack by Microsoft. This would add additional overhead to the project to implement especially for static libraries as it requires IDL/DLL exporting followed by manifest declaration. Better to document that it is not supported.
Furthermore, an additional class for IMFAttributes should be implemented to make clean architecture for passing around attributes as opposed to directly calling non-COM interface calls on the objects and making use of SetProperties which would also be a set up for an object that uses the RuntimeClass activation ID.
The remaining changes are not difficult and will be complete soon along with debug tracing messages.
Update cap_msmf.cpp
Create cap_msmf.h
Update cap_msmf.cpp
Update cap_msmf.h
Update cap_msmf.cpp
Update cap_msmf.h
Update and rename cap_msmf.h to cap_msmf.hpp
Update cap_msmf.cpp
Update CMakeLists.txt
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.cpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Successful test - samples are grabbed
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Create ppltasks_winrt.h
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update ppltasks_winrt.h
Library updated and cleaned up with comments, marshaling, exceptions and linker settings
Update ppltasks_winrt.h
Fixed trailing whitespace
2013-12-14 16:53:30 +08:00
|
|
|
#endif
|
2013-04-03 09:01:20 +08:00
|
|
|
index = try_index;
|
Update cap_msmf.cpp
Add support for WinRT in the MF capture framework by removing the disallowed calls to enumerate devices and create a sample grabber sink and adding framework for the MediaCapture interface and a custom sink which interfaces with the sample grabber callback interface. The change requires discussion for making it completely functional as redundancy is required given that if the source is a video file, the old code pathways must be used. Otherwise all IMFMediaSession, IMFMediaSource, and IMFActivate code must use a MediaCapture code path and all sink code must use the CMediaSink custom sink.
Support for the custom sink is extended to non-WinRT not for compatibility as Windows Vista client is a minimum regardless, but because it offers more flexibility, could be faster and is able to be used as an optionally different code path during sink creation based on a future configuration parameter.
My discussion and proposal to finish this change:
Devices are so easily enumerated through WinRT Windows.Devices namespace that wrapping the calls in a library is quite a chore for little benefit though to get the various modes and formats could still be a worthwhile project. For now conditional compilation to remove videodevices and any offending non-video file related activity in videodevice. In my opinion, this is a different , far less fundamental and important change which can possibly be done as a future project and also much more easily implemented in C++/CX.
ImageGrabber has the IMFSampleGrabberSinkCallback replaced with a base class (SharedSampleGrabber) which also be is base class for ImageGrabberRT. This change is necessary as the custom sink does not require a thread to pump events which is done through MediaCapture already. IMFSampleGrabberSinkCallback is the common element between both models and that piece can be shared. Initializing the new ImageGrabberRT is as simple as passing an already initialized MediaCapture object and any video format/encoding parameters.
The concurrency event is necessary to wait for completion and is the way the underlying, IAsyncAction wrappers in the task library work as well. Native WIN32 event objects would be an option if HAVE_CONCURRENCY is not defined. I could even imagine doing it with sleep/thread yield and InterlockedCompareExchange yet I am not enthusiastic about that approach either. Since there is a specific compiler HAVE_ for concurrency, I do not like pulling it in though I think for WinRT it is safe to say we will always have it available though should probably conditionally compile with the Interlocked option as WIN32 events would require HAVE_WIN32.
It looks like C++/CX cannot be used for the IMediaExtension sink (which should not be a problem) as using COM objects requires WRL and though deriving from IMediaExtension can be done, there is little purpose without COM. Objects from C++/CX can be swapped to interact with objects from native C++ as Inspectable* can reinterpret_cast to the ref object IInspectable^ and vice-versa. A solution to the COM class with C++/CX would be great so we could have dual support. Also without #define for every WRL object in use, the code will get quite muddy given that the */^ would need to be ifdef'd everywhere.
Update cap_msmf.cpp
Fixed bugs and completed the change. I believe the new classes need to be moved to a header file as the file has become to large and more classes need to be added for handling all the asynchronous problems (one wrapping IAsyncAction in a task and another for making a task out of IAsyncAction). Unfortunately, blocking on the UI thread is not an option in WinRT so a synchronous architecture is considered "illegal" by Microsoft's standards even if implementable (C++/CX ppltasks library throws errors if you try it). Worse, either by design or a bug in the MF MediaCapture class with Custom Sinks causes a crash if stop/start previewing without reinitializing (spPreferredPreviewMediaType is fatally nulled). After decompiling Windows.Media.dll, I worked around this in my own projects by using an activate-able custom sink ID which strangely assigns 1 to this pointer allowing it to be reinitialized in what can only be described as a hack by Microsoft. This would add additional overhead to the project to implement especially for static libraries as it requires IDL/DLL exporting followed by manifest declaration. Better to document that it is not supported.
Furthermore, an additional class for IMFAttributes should be implemented to make clean architecture for passing around attributes as opposed to directly calling non-COM interface calls on the objects and making use of SetProperties which would also be a set up for an object that uses the RuntimeClass activation ID.
The remaining changes are not difficult and will be complete soon along with debug tracing messages.
Update cap_msmf.cpp
Create cap_msmf.h
Update cap_msmf.cpp
Update cap_msmf.h
Update cap_msmf.cpp
Update cap_msmf.h
Update and rename cap_msmf.h to cap_msmf.hpp
Update cap_msmf.cpp
Update CMakeLists.txt
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.cpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Successful test - samples are grabbed
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Create ppltasks_winrt.h
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update ppltasks_winrt.h
Library updated and cleaned up with comments, marshaling, exceptions and linker settings
Update ppltasks_winrt.h
Fixed trailing whitespace
2013-12-14 16:53:30 +08:00
|
|
|
#ifdef HAVE_WINRT
|
|
|
|
END_CALL_IN_CONTEXT(hr);
|
|
|
|
return true;
|
|
|
|
};
|
|
|
|
Concurrency::critical_section::scoped_lock _LockHolder(lock);
|
|
|
|
CREATE_OR_CONTINUE_TASK(openTask, bool, func)
|
|
|
|
#endif
|
2013-04-03 09:01:20 +08:00
|
|
|
return true;
|
|
|
|
}
|
2013-04-16 21:25:10 +08:00
|
|
|
|
2013-04-03 09:01:20 +08:00
|
|
|
bool CvCaptureCAM_MSMF::grabFrame()
|
|
|
|
{
|
2013-04-16 21:25:10 +08:00
|
|
|
while (VI.isDeviceSetup(index) && !VI.isFrameNew(index))
|
|
|
|
Sleep(1);
|
|
|
|
return VI.isDeviceSetup(index);
|
2013-04-03 09:01:20 +08:00
|
|
|
}
|
2013-04-16 21:25:10 +08:00
|
|
|
|
2013-04-03 09:01:20 +08:00
|
|
|
IplImage* CvCaptureCAM_MSMF::retrieveFrame(int)
|
|
|
|
{
|
|
|
|
if( !frame || (int)VI.getWidth(index) != frame->width || (int)VI.getHeight(index) != frame->height )
|
|
|
|
{
|
|
|
|
if (frame)
|
|
|
|
cvReleaseImage( &frame );
|
|
|
|
unsigned int w = VI.getWidth(index), h = VI.getHeight(index);
|
|
|
|
frame = cvCreateImage( cvSize(w,h), 8, 3 );
|
|
|
|
}
|
|
|
|
VI.getPixels( index, (uchar*)frame->imageData, false, true );
|
|
|
|
return frame;
|
|
|
|
}
|
2013-04-16 21:25:10 +08:00
|
|
|
|
2013-04-03 09:01:20 +08:00
|
|
|
double CvCaptureCAM_MSMF::getProperty( int property_id )
|
|
|
|
{
|
|
|
|
// image format proprrties
|
|
|
|
switch( property_id )
|
|
|
|
{
|
|
|
|
case CV_CAP_PROP_FRAME_WIDTH:
|
|
|
|
return VI.getWidth(index);
|
|
|
|
case CV_CAP_PROP_FRAME_HEIGHT:
|
|
|
|
return VI.getHeight(index);
|
|
|
|
}
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
bool CvCaptureCAM_MSMF::setProperty( int property_id, double value )
|
|
|
|
{
|
|
|
|
// image capture properties
|
|
|
|
bool handled = false;
|
|
|
|
switch( property_id )
|
|
|
|
{
|
|
|
|
case CV_CAP_PROP_FRAME_WIDTH:
|
|
|
|
width = cvRound(value);
|
|
|
|
handled = true;
|
|
|
|
break;
|
|
|
|
case CV_CAP_PROP_FRAME_HEIGHT:
|
|
|
|
height = cvRound(value);
|
|
|
|
handled = true;
|
|
|
|
break;
|
|
|
|
}
|
2013-06-27 14:56:50 +08:00
|
|
|
|
2013-04-03 09:01:20 +08:00
|
|
|
if ( handled ) {
|
|
|
|
if( width > 0 && height > 0 )
|
|
|
|
{
|
2013-06-27 14:56:50 +08:00
|
|
|
if( width != (int)VI.getWidth(index) || height != (int)VI.getHeight(index) && VI.isDeviceSetup(index))//|| fourcc != VI.getFourcc(index) )
|
2013-04-03 09:01:20 +08:00
|
|
|
{
|
2013-06-27 14:56:50 +08:00
|
|
|
VI.closeDevice(index);
|
|
|
|
VI.setupDevice(index, width, height);
|
2013-04-03 09:01:20 +08:00
|
|
|
}
|
2013-06-27 14:56:50 +08:00
|
|
|
return VI.isDeviceSetup(index);
|
2013-04-03 09:01:20 +08:00
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
2013-06-27 14:56:50 +08:00
|
|
|
|
2013-04-03 09:01:20 +08:00
|
|
|
return false;
|
|
|
|
}
|
2013-05-14 20:17:34 +08:00
|
|
|
|
|
|
|
class CvCaptureFile_MSMF : public CvCapture
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
CvCaptureFile_MSMF();
|
|
|
|
virtual ~CvCaptureFile_MSMF();
|
|
|
|
|
|
|
|
virtual bool open( const char* filename );
|
|
|
|
virtual void close();
|
|
|
|
|
|
|
|
virtual double getProperty(int);
|
|
|
|
virtual bool setProperty(int, double);
|
|
|
|
virtual bool grabFrame();
|
|
|
|
virtual IplImage* retrieveFrame(int);
|
|
|
|
virtual int getCaptureDomain() { return CV_CAP_MSMF; }
|
|
|
|
protected:
|
|
|
|
ImageGrabberThread* grabberThread;
|
|
|
|
IMFMediaSource* videoFileSource;
|
|
|
|
std::vector<MediaType> captureFormats;
|
|
|
|
int captureFormatIndex;
|
|
|
|
IplImage* frame;
|
|
|
|
bool isOpened;
|
|
|
|
|
2013-05-19 04:04:31 +08:00
|
|
|
HRESULT enumerateCaptureFormats(IMFMediaSource *pSource);
|
2013-05-23 00:50:54 +08:00
|
|
|
HRESULT getSourceDuration(IMFMediaSource *pSource, MFTIME *pDuration);
|
2013-05-14 20:17:34 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
CvCaptureFile_MSMF::CvCaptureFile_MSMF():
|
|
|
|
grabberThread(NULL),
|
|
|
|
videoFileSource(NULL),
|
|
|
|
captureFormatIndex(0),
|
|
|
|
frame(NULL),
|
|
|
|
isOpened(false)
|
|
|
|
{
|
|
|
|
MFStartup(MF_VERSION);
|
|
|
|
}
|
|
|
|
|
|
|
|
CvCaptureFile_MSMF::~CvCaptureFile_MSMF()
|
|
|
|
{
|
2013-05-22 19:21:23 +08:00
|
|
|
close();
|
2013-05-14 20:17:34 +08:00
|
|
|
MFShutdown();
|
|
|
|
}
|
|
|
|
|
|
|
|
bool CvCaptureFile_MSMF::open(const char* filename)
|
|
|
|
{
|
|
|
|
if (!filename)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
wchar_t* unicodeFileName = new wchar_t[strlen(filename)+1];
|
Update cap_msmf.cpp
Add support for WinRT in the MF capture framework by removing the disallowed calls to enumerate devices and create a sample grabber sink and adding framework for the MediaCapture interface and a custom sink which interfaces with the sample grabber callback interface. The change requires discussion for making it completely functional as redundancy is required given that if the source is a video file, the old code pathways must be used. Otherwise all IMFMediaSession, IMFMediaSource, and IMFActivate code must use a MediaCapture code path and all sink code must use the CMediaSink custom sink.
Support for the custom sink is extended to non-WinRT not for compatibility as Windows Vista client is a minimum regardless, but because it offers more flexibility, could be faster and is able to be used as an optionally different code path during sink creation based on a future configuration parameter.
My discussion and proposal to finish this change:
Devices are so easily enumerated through WinRT Windows.Devices namespace that wrapping the calls in a library is quite a chore for little benefit though to get the various modes and formats could still be a worthwhile project. For now conditional compilation to remove videodevices and any offending non-video file related activity in videodevice. In my opinion, this is a different , far less fundamental and important change which can possibly be done as a future project and also much more easily implemented in C++/CX.
ImageGrabber has the IMFSampleGrabberSinkCallback replaced with a base class (SharedSampleGrabber) which also be is base class for ImageGrabberRT. This change is necessary as the custom sink does not require a thread to pump events which is done through MediaCapture already. IMFSampleGrabberSinkCallback is the common element between both models and that piece can be shared. Initializing the new ImageGrabberRT is as simple as passing an already initialized MediaCapture object and any video format/encoding parameters.
The concurrency event is necessary to wait for completion and is the way the underlying, IAsyncAction wrappers in the task library work as well. Native WIN32 event objects would be an option if HAVE_CONCURRENCY is not defined. I could even imagine doing it with sleep/thread yield and InterlockedCompareExchange yet I am not enthusiastic about that approach either. Since there is a specific compiler HAVE_ for concurrency, I do not like pulling it in though I think for WinRT it is safe to say we will always have it available though should probably conditionally compile with the Interlocked option as WIN32 events would require HAVE_WIN32.
It looks like C++/CX cannot be used for the IMediaExtension sink (which should not be a problem) as using COM objects requires WRL and though deriving from IMediaExtension can be done, there is little purpose without COM. Objects from C++/CX can be swapped to interact with objects from native C++ as Inspectable* can reinterpret_cast to the ref object IInspectable^ and vice-versa. A solution to the COM class with C++/CX would be great so we could have dual support. Also without #define for every WRL object in use, the code will get quite muddy given that the */^ would need to be ifdef'd everywhere.
Update cap_msmf.cpp
Fixed bugs and completed the change. I believe the new classes need to be moved to a header file as the file has become to large and more classes need to be added for handling all the asynchronous problems (one wrapping IAsyncAction in a task and another for making a task out of IAsyncAction). Unfortunately, blocking on the UI thread is not an option in WinRT so a synchronous architecture is considered "illegal" by Microsoft's standards even if implementable (C++/CX ppltasks library throws errors if you try it). Worse, either by design or a bug in the MF MediaCapture class with Custom Sinks causes a crash if stop/start previewing without reinitializing (spPreferredPreviewMediaType is fatally nulled). After decompiling Windows.Media.dll, I worked around this in my own projects by using an activate-able custom sink ID which strangely assigns 1 to this pointer allowing it to be reinitialized in what can only be described as a hack by Microsoft. This would add additional overhead to the project to implement especially for static libraries as it requires IDL/DLL exporting followed by manifest declaration. Better to document that it is not supported.
Furthermore, an additional class for IMFAttributes should be implemented to make clean architecture for passing around attributes as opposed to directly calling non-COM interface calls on the objects and making use of SetProperties which would also be a set up for an object that uses the RuntimeClass activation ID.
The remaining changes are not difficult and will be complete soon along with debug tracing messages.
Update cap_msmf.cpp
Create cap_msmf.h
Update cap_msmf.cpp
Update cap_msmf.h
Update cap_msmf.cpp
Update cap_msmf.h
Update and rename cap_msmf.h to cap_msmf.hpp
Update cap_msmf.cpp
Update CMakeLists.txt
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.cpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Successful test - samples are grabbed
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Create ppltasks_winrt.h
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update ppltasks_winrt.h
Library updated and cleaned up with comments, marshaling, exceptions and linker settings
Update ppltasks_winrt.h
Fixed trailing whitespace
2013-12-14 16:53:30 +08:00
|
|
|
MultiByteToWideChar(CP_ACP, 0, filename, -1, unicodeFileName, (int)strlen(filename)+1);
|
2013-05-14 20:17:34 +08:00
|
|
|
|
|
|
|
HRESULT hr = S_OK;
|
|
|
|
|
|
|
|
MF_OBJECT_TYPE ObjectType = MF_OBJECT_INVALID;
|
|
|
|
|
2013-05-19 04:04:31 +08:00
|
|
|
ComPtr<IMFSourceResolver> pSourceResolver = NULL;
|
2013-05-14 20:17:34 +08:00
|
|
|
IUnknown* pUnkSource = NULL;
|
|
|
|
|
2013-05-19 04:04:31 +08:00
|
|
|
hr = MFCreateSourceResolver(pSourceResolver.GetAddressOf());
|
2013-05-14 20:17:34 +08:00
|
|
|
|
|
|
|
if (SUCCEEDED(hr))
|
|
|
|
{
|
|
|
|
hr = pSourceResolver->CreateObjectFromURL(
|
|
|
|
unicodeFileName,
|
|
|
|
MF_RESOLUTION_MEDIASOURCE,
|
|
|
|
NULL, // Optional property store.
|
|
|
|
&ObjectType,
|
|
|
|
&pUnkSource
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Get the IMFMediaSource from the IUnknown pointer.
|
|
|
|
if (SUCCEEDED(hr))
|
|
|
|
{
|
|
|
|
hr = pUnkSource->QueryInterface(IID_PPV_ARGS(&videoFileSource));
|
|
|
|
}
|
|
|
|
|
|
|
|
SafeRelease(&pUnkSource);
|
|
|
|
|
2013-05-19 04:04:31 +08:00
|
|
|
if (SUCCEEDED(hr))
|
|
|
|
{
|
|
|
|
hr = enumerateCaptureFormats(videoFileSource);
|
|
|
|
}
|
2013-05-14 20:17:34 +08:00
|
|
|
|
|
|
|
if (SUCCEEDED(hr))
|
|
|
|
{
|
2013-05-23 00:50:54 +08:00
|
|
|
hr = ImageGrabberThread::CreateInstance(&grabberThread, videoFileSource, (unsigned int)-2, true);
|
2013-05-14 20:17:34 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
if (SUCCEEDED(hr))
|
|
|
|
{
|
|
|
|
grabberThread->start();
|
|
|
|
}
|
|
|
|
|
2013-05-19 04:04:31 +08:00
|
|
|
isOpened = SUCCEEDED(hr);
|
2013-05-14 20:17:34 +08:00
|
|
|
|
2013-05-19 04:04:31 +08:00
|
|
|
return isOpened;
|
2013-05-14 20:17:34 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
void CvCaptureFile_MSMF::close()
|
|
|
|
{
|
|
|
|
if (grabberThread)
|
|
|
|
{
|
|
|
|
isOpened = false;
|
2013-05-22 19:21:23 +08:00
|
|
|
SetEvent(grabberThread->getImageGrabber()->ig_hFinish);
|
2013-05-14 20:17:34 +08:00
|
|
|
grabberThread->stop();
|
|
|
|
delete grabberThread;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (videoFileSource)
|
|
|
|
{
|
2013-06-24 16:10:18 +08:00
|
|
|
videoFileSource->Shutdown();
|
2013-05-14 20:17:34 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
bool CvCaptureFile_MSMF::setProperty(int property_id, double value)
|
|
|
|
{
|
|
|
|
// image capture properties
|
|
|
|
// FIXME: implement method in VideoInput back end
|
2013-06-27 14:56:50 +08:00
|
|
|
(void) property_id;
|
|
|
|
(void) value;
|
2013-05-14 20:17:34 +08:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
double CvCaptureFile_MSMF::getProperty(int property_id)
|
|
|
|
{
|
|
|
|
// image format proprrties
|
|
|
|
switch( property_id )
|
|
|
|
{
|
|
|
|
case CV_CAP_PROP_FRAME_WIDTH:
|
|
|
|
return captureFormats[captureFormatIndex].width;
|
|
|
|
case CV_CAP_PROP_FRAME_HEIGHT:
|
|
|
|
return captureFormats[captureFormatIndex].height;
|
2013-05-19 04:04:31 +08:00
|
|
|
case CV_CAP_PROP_FRAME_COUNT:
|
2013-05-23 00:50:54 +08:00
|
|
|
{
|
|
|
|
MFTIME duration;
|
|
|
|
getSourceDuration(this->videoFileSource, &duration);
|
|
|
|
double fps = ((double)captureFormats[captureFormatIndex].MF_MT_FRAME_RATE_NUMERATOR) /
|
|
|
|
((double)captureFormats[captureFormatIndex].MF_MT_FRAME_RATE_DENOMINATOR);
|
|
|
|
return (double)floor(((double)duration/1e7)*fps+0.5);
|
|
|
|
}
|
2013-05-14 20:17:34 +08:00
|
|
|
case CV_CAP_PROP_FOURCC:
|
2013-05-23 00:50:54 +08:00
|
|
|
return captureFormats[captureFormatIndex].MF_MT_SUBTYPE.Data1;
|
2013-05-14 20:17:34 +08:00
|
|
|
case CV_CAP_PROP_FPS:
|
2013-05-23 00:50:54 +08:00
|
|
|
return ((double)captureFormats[captureFormatIndex].MF_MT_FRAME_RATE_NUMERATOR) /
|
|
|
|
((double)captureFormats[captureFormatIndex].MF_MT_FRAME_RATE_DENOMINATOR);
|
2013-05-14 20:17:34 +08:00
|
|
|
}
|
2013-08-21 20:44:09 +08:00
|
|
|
|
2013-05-14 20:17:34 +08:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool CvCaptureFile_MSMF::grabFrame()
|
|
|
|
{
|
2013-06-27 14:56:50 +08:00
|
|
|
DWORD waitResult = (DWORD)-1;
|
2013-05-14 20:17:34 +08:00
|
|
|
if (isOpened)
|
|
|
|
{
|
2013-05-22 19:21:23 +08:00
|
|
|
SetEvent(grabberThread->getImageGrabber()->ig_hFrameGrabbed);
|
2013-05-14 20:17:34 +08:00
|
|
|
HANDLE tmp[] = {grabberThread->getImageGrabber()->ig_hFrameReady, grabberThread->getImageGrabber()->ig_hFinish, 0};
|
|
|
|
waitResult = WaitForMultipleObjects(2, tmp, FALSE, INFINITE);
|
|
|
|
}
|
|
|
|
|
2013-05-22 19:21:23 +08:00
|
|
|
return isOpened && grabberThread->getImageGrabber()->getRawImage()->isNew() && (waitResult == WAIT_OBJECT_0);
|
2013-05-14 20:17:34 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
IplImage* CvCaptureFile_MSMF::retrieveFrame(int)
|
|
|
|
{
|
|
|
|
unsigned int width = captureFormats[captureFormatIndex].width;
|
|
|
|
unsigned int height = captureFormats[captureFormatIndex].height;
|
|
|
|
unsigned int bytes = 3;
|
2013-05-23 00:50:54 +08:00
|
|
|
if( !frame || (int)width != frame->width || (int)height != frame->height )
|
2013-05-14 20:17:34 +08:00
|
|
|
{
|
|
|
|
if (frame)
|
|
|
|
cvReleaseImage( &frame );
|
|
|
|
frame = cvCreateImage( cvSize(width,height), 8, 3 );
|
|
|
|
}
|
|
|
|
|
|
|
|
RawImage *RIOut = grabberThread->getImageGrabber()->getRawImage();
|
|
|
|
unsigned int size = bytes * width * height;
|
|
|
|
|
2013-05-19 04:04:31 +08:00
|
|
|
bool verticalFlip = captureFormats[captureFormatIndex].MF_MT_DEFAULT_STRIDE < 0;
|
|
|
|
|
2013-05-14 20:17:34 +08:00
|
|
|
if(RIOut && size == RIOut->getSize())
|
|
|
|
{
|
2013-08-21 20:44:09 +08:00
|
|
|
videoInput::processPixels(RIOut->getpPixels(), (unsigned char*)frame->imageData, width,
|
2013-05-19 04:04:31 +08:00
|
|
|
height, bytes, false, verticalFlip);
|
2013-05-14 20:17:34 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
return frame;
|
|
|
|
}
|
|
|
|
|
2013-05-19 04:04:31 +08:00
|
|
|
HRESULT CvCaptureFile_MSMF::enumerateCaptureFormats(IMFMediaSource *pSource)
|
2013-05-14 20:17:34 +08:00
|
|
|
{
|
2013-05-15 21:09:03 +08:00
|
|
|
ComPtr<IMFPresentationDescriptor> pPD = NULL;
|
|
|
|
ComPtr<IMFStreamDescriptor> pSD = NULL;
|
|
|
|
ComPtr<IMFMediaTypeHandler> pHandler = NULL;
|
|
|
|
ComPtr<IMFMediaType> pType = NULL;
|
|
|
|
HRESULT hr = pSource->CreatePresentationDescriptor(pPD.GetAddressOf());
|
2013-05-14 20:17:34 +08:00
|
|
|
if (FAILED(hr))
|
|
|
|
{
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
|
|
|
|
BOOL fSelected;
|
2013-05-15 21:09:03 +08:00
|
|
|
hr = pPD->GetStreamDescriptorByIndex(0, &fSelected, pSD.GetAddressOf());
|
2013-05-14 20:17:34 +08:00
|
|
|
if (FAILED(hr))
|
|
|
|
{
|
|
|
|
goto done;
|
|
|
|
}
|
2013-05-15 21:09:03 +08:00
|
|
|
hr = pSD->GetMediaTypeHandler(pHandler.GetAddressOf());
|
2013-05-14 20:17:34 +08:00
|
|
|
if (FAILED(hr))
|
|
|
|
{
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
DWORD cTypes = 0;
|
|
|
|
hr = pHandler->GetMediaTypeCount(&cTypes);
|
|
|
|
if (FAILED(hr))
|
|
|
|
{
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
for (DWORD i = 0; i < cTypes; i++)
|
|
|
|
{
|
2013-05-15 21:09:03 +08:00
|
|
|
hr = pHandler->GetMediaTypeByIndex(i, pType.GetAddressOf());
|
2013-05-14 20:17:34 +08:00
|
|
|
if (FAILED(hr))
|
|
|
|
{
|
|
|
|
goto done;
|
|
|
|
}
|
2013-05-15 21:09:03 +08:00
|
|
|
MediaType MT = FormatReader::Read(pType.Get());
|
2013-05-14 20:17:34 +08:00
|
|
|
captureFormats.push_back(MT);
|
|
|
|
}
|
|
|
|
|
|
|
|
done:
|
|
|
|
return hr;
|
|
|
|
}
|
|
|
|
|
2013-05-23 00:50:54 +08:00
|
|
|
HRESULT CvCaptureFile_MSMF::getSourceDuration(IMFMediaSource *pSource, MFTIME *pDuration)
|
|
|
|
{
|
|
|
|
*pDuration = 0;
|
|
|
|
|
|
|
|
IMFPresentationDescriptor *pPD = NULL;
|
|
|
|
|
|
|
|
HRESULT hr = pSource->CreatePresentationDescriptor(&pPD);
|
|
|
|
if (SUCCEEDED(hr))
|
|
|
|
{
|
|
|
|
hr = pPD->GetUINT64(MF_PD_DURATION, (UINT64*)pDuration);
|
|
|
|
pPD->Release();
|
|
|
|
}
|
|
|
|
return hr;
|
|
|
|
}
|
2013-05-14 20:17:34 +08:00
|
|
|
|
2013-04-03 09:01:20 +08:00
|
|
|
CvCapture* cvCreateCameraCapture_MSMF( int index )
|
|
|
|
{
|
|
|
|
CvCaptureCAM_MSMF* capture = new CvCaptureCAM_MSMF;
|
|
|
|
try
|
|
|
|
{
|
|
|
|
if( capture->open( index ))
|
|
|
|
return capture;
|
|
|
|
}
|
|
|
|
catch(...)
|
|
|
|
{
|
|
|
|
delete capture;
|
|
|
|
throw;
|
|
|
|
}
|
|
|
|
delete capture;
|
|
|
|
return 0;
|
|
|
|
}
|
2013-05-06 18:36:51 +08:00
|
|
|
|
2013-05-14 20:17:34 +08:00
|
|
|
CvCapture* cvCreateFileCapture_MSMF (const char* filename)
|
|
|
|
{
|
|
|
|
CvCaptureFile_MSMF* capture = new CvCaptureFile_MSMF;
|
2013-05-19 04:04:31 +08:00
|
|
|
try
|
|
|
|
{
|
|
|
|
if( capture->open(filename) )
|
|
|
|
return capture;
|
|
|
|
else
|
|
|
|
{
|
|
|
|
delete capture;
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
catch(...)
|
|
|
|
{
|
|
|
|
delete capture;
|
|
|
|
throw;
|
|
|
|
}
|
2013-05-14 20:17:34 +08:00
|
|
|
}
|
2013-05-06 18:36:51 +08:00
|
|
|
|
|
|
|
//
|
|
|
|
//
|
|
|
|
// Media Foundation-based Video Writer
|
|
|
|
//
|
|
|
|
//
|
|
|
|
|
|
|
|
class CvVideoWriter_MSMF : public CvVideoWriter
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
CvVideoWriter_MSMF();
|
|
|
|
virtual ~CvVideoWriter_MSMF();
|
2013-05-19 04:04:31 +08:00
|
|
|
virtual bool open(const char* filename, int fourcc,
|
|
|
|
double fps, CvSize frameSize, bool isColor);
|
2013-05-06 18:36:51 +08:00
|
|
|
virtual void close();
|
2013-05-19 04:04:31 +08:00
|
|
|
virtual bool writeFrame(const IplImage* img);
|
2013-05-06 18:36:51 +08:00
|
|
|
|
|
|
|
private:
|
|
|
|
UINT32 videoWidth;
|
|
|
|
UINT32 videoHeight;
|
|
|
|
double fps;
|
|
|
|
UINT32 bitRate;
|
|
|
|
UINT32 frameSize;
|
|
|
|
GUID encodingFormat;
|
|
|
|
GUID inputFormat;
|
|
|
|
|
|
|
|
DWORD streamIndex;
|
|
|
|
ComPtr<IMFSinkWriter> sinkWriter;
|
|
|
|
|
|
|
|
bool initiated;
|
|
|
|
|
|
|
|
LONGLONG rtStart;
|
|
|
|
UINT64 rtDuration;
|
|
|
|
|
|
|
|
HRESULT InitializeSinkWriter(const char* filename);
|
2013-05-06 22:17:53 +08:00
|
|
|
static const GUID FourCC2GUID(int fourcc);
|
2013-05-06 18:36:51 +08:00
|
|
|
HRESULT WriteFrame(DWORD *videoFrameBuffer, const LONGLONG& rtStart, const LONGLONG& rtDuration);
|
|
|
|
};
|
|
|
|
|
2013-05-22 19:21:23 +08:00
|
|
|
CvVideoWriter_MSMF::CvVideoWriter_MSMF():
|
|
|
|
initiated(false)
|
2013-05-06 18:36:51 +08:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
CvVideoWriter_MSMF::~CvVideoWriter_MSMF()
|
|
|
|
{
|
|
|
|
close();
|
|
|
|
}
|
|
|
|
|
2013-05-06 22:17:53 +08:00
|
|
|
const GUID CvVideoWriter_MSMF::FourCC2GUID(int fourcc)
|
|
|
|
{
|
|
|
|
switch(fourcc)
|
|
|
|
{
|
2013-05-22 19:21:23 +08:00
|
|
|
case CV_FOURCC_MACRO('d', 'v', '2', '5'):
|
2013-05-06 22:17:53 +08:00
|
|
|
return MFVideoFormat_DV25; break;
|
2013-05-22 19:21:23 +08:00
|
|
|
case CV_FOURCC_MACRO('d', 'v', '5', '0'):
|
2013-05-06 22:17:53 +08:00
|
|
|
return MFVideoFormat_DV50; break;
|
2013-05-22 19:21:23 +08:00
|
|
|
case CV_FOURCC_MACRO('d', 'v', 'c', ' '):
|
2013-05-06 22:17:53 +08:00
|
|
|
return MFVideoFormat_DVC; break;
|
2013-05-22 19:21:23 +08:00
|
|
|
case CV_FOURCC_MACRO('d', 'v', 'h', '1'):
|
2013-05-06 22:17:53 +08:00
|
|
|
return MFVideoFormat_DVH1; break;
|
2013-05-22 19:21:23 +08:00
|
|
|
case CV_FOURCC_MACRO('d', 'v', 'h', 'd'):
|
2013-05-06 22:17:53 +08:00
|
|
|
return MFVideoFormat_DVHD; break;
|
2013-05-22 19:21:23 +08:00
|
|
|
case CV_FOURCC_MACRO('d', 'v', 's', 'd'):
|
2013-05-06 22:17:53 +08:00
|
|
|
return MFVideoFormat_DVSD; break;
|
2013-05-22 19:21:23 +08:00
|
|
|
case CV_FOURCC_MACRO('d', 'v', 's', 'l'):
|
2013-05-06 22:17:53 +08:00
|
|
|
return MFVideoFormat_DVSL; break;
|
2013-05-22 19:21:23 +08:00
|
|
|
case CV_FOURCC_MACRO('H', '2', '6', '3'):
|
2013-05-06 22:17:53 +08:00
|
|
|
return MFVideoFormat_H263; break;
|
2013-05-22 19:21:23 +08:00
|
|
|
case CV_FOURCC_MACRO('H', '2', '6', '4'):
|
2013-05-06 22:17:53 +08:00
|
|
|
return MFVideoFormat_H264; break;
|
2013-05-22 19:21:23 +08:00
|
|
|
case CV_FOURCC_MACRO('M', '4', 'S', '2'):
|
2013-05-06 22:17:53 +08:00
|
|
|
return MFVideoFormat_M4S2; break;
|
2013-05-22 19:21:23 +08:00
|
|
|
case CV_FOURCC_MACRO('M', 'J', 'P', 'G'):
|
2013-05-06 22:17:53 +08:00
|
|
|
return MFVideoFormat_MJPG; break;
|
2013-05-22 19:21:23 +08:00
|
|
|
case CV_FOURCC_MACRO('M', 'P', '4', '3'):
|
2013-05-06 22:17:53 +08:00
|
|
|
return MFVideoFormat_MP43; break;
|
2013-05-22 19:21:23 +08:00
|
|
|
case CV_FOURCC_MACRO('M', 'P', '4', 'S'):
|
2013-05-06 22:17:53 +08:00
|
|
|
return MFVideoFormat_MP4S; break;
|
2013-05-22 19:21:23 +08:00
|
|
|
case CV_FOURCC_MACRO('M', 'P', '4', 'V'):
|
2013-05-06 22:17:53 +08:00
|
|
|
return MFVideoFormat_MP4V; break;
|
2013-05-22 19:21:23 +08:00
|
|
|
case CV_FOURCC_MACRO('M', 'P', 'G', '1'):
|
2013-05-06 22:17:53 +08:00
|
|
|
return MFVideoFormat_MPG1; break;
|
2013-05-22 19:21:23 +08:00
|
|
|
case CV_FOURCC_MACRO('M', 'S', 'S', '1'):
|
2013-05-06 22:17:53 +08:00
|
|
|
return MFVideoFormat_MSS1; break;
|
2013-05-22 19:21:23 +08:00
|
|
|
case CV_FOURCC_MACRO('M', 'S', 'S', '2'):
|
2013-05-06 22:17:53 +08:00
|
|
|
return MFVideoFormat_MSS2; break;
|
2013-05-22 19:21:23 +08:00
|
|
|
case CV_FOURCC_MACRO('W', 'M', 'V', '1'):
|
2013-05-06 22:17:53 +08:00
|
|
|
return MFVideoFormat_WMV1; break;
|
2013-05-22 19:21:23 +08:00
|
|
|
case CV_FOURCC_MACRO('W', 'M', 'V', '2'):
|
2013-05-06 22:17:53 +08:00
|
|
|
return MFVideoFormat_WMV2; break;
|
2013-05-22 19:21:23 +08:00
|
|
|
case CV_FOURCC_MACRO('W', 'M', 'V', '3'):
|
2013-05-06 22:17:53 +08:00
|
|
|
return MFVideoFormat_WMV3; break;
|
2013-05-22 19:21:23 +08:00
|
|
|
case CV_FOURCC_MACRO('W', 'V', 'C', '1'):
|
2013-05-06 22:17:53 +08:00
|
|
|
return MFVideoFormat_WVC1; break;
|
|
|
|
default:
|
|
|
|
return MFVideoFormat_H264;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-05-06 18:36:51 +08:00
|
|
|
bool CvVideoWriter_MSMF::open( const char* filename, int fourcc,
|
2013-05-23 00:50:54 +08:00
|
|
|
double _fps, CvSize frameSize, bool /*isColor*/ )
|
2013-05-06 18:36:51 +08:00
|
|
|
{
|
|
|
|
videoWidth = frameSize.width;
|
|
|
|
videoHeight = frameSize.height;
|
|
|
|
fps = _fps;
|
2013-05-23 00:50:54 +08:00
|
|
|
bitRate = (UINT32)fps*videoWidth*videoHeight; // 1-bit per pixel
|
2013-05-06 22:17:53 +08:00
|
|
|
encodingFormat = FourCC2GUID(fourcc);
|
2013-05-06 18:36:51 +08:00
|
|
|
inputFormat = MFVideoFormat_RGB32;
|
|
|
|
|
|
|
|
HRESULT hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
|
|
|
|
if (SUCCEEDED(hr))
|
|
|
|
{
|
|
|
|
hr = MFStartup(MF_VERSION);
|
|
|
|
if (SUCCEEDED(hr))
|
|
|
|
{
|
|
|
|
hr = InitializeSinkWriter(filename);
|
|
|
|
if (SUCCEEDED(hr))
|
|
|
|
{
|
|
|
|
initiated = true;
|
|
|
|
rtStart = 0;
|
2013-05-06 22:17:53 +08:00
|
|
|
MFFrameRateToAverageTimePerFrame((UINT32)fps, 1, &rtDuration);
|
2013-05-06 18:36:51 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return SUCCEEDED(hr);
|
|
|
|
}
|
|
|
|
|
|
|
|
void CvVideoWriter_MSMF::close()
|
|
|
|
{
|
|
|
|
if (!initiated)
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
initiated = false;
|
2013-06-27 14:56:50 +08:00
|
|
|
sinkWriter->Finalize();
|
2013-05-06 18:36:51 +08:00
|
|
|
MFShutdown();
|
|
|
|
}
|
|
|
|
|
|
|
|
bool CvVideoWriter_MSMF::writeFrame(const IplImage* img)
|
|
|
|
{
|
|
|
|
if (!img)
|
|
|
|
return false;
|
|
|
|
|
2013-05-06 22:17:53 +08:00
|
|
|
int length = img->width * img->height * 4;
|
2013-05-06 18:36:51 +08:00
|
|
|
DWORD* target = new DWORD[length];
|
|
|
|
|
|
|
|
for (int rowIdx = 0; rowIdx < img->height; rowIdx++)
|
|
|
|
{
|
|
|
|
char* rowStart = img->imageData + rowIdx*img->widthStep;
|
|
|
|
for (int colIdx = 0; colIdx < img->width; colIdx++)
|
|
|
|
{
|
|
|
|
BYTE b = rowStart[colIdx * img->nChannels + 0];
|
|
|
|
BYTE g = rowStart[colIdx * img->nChannels + 1];
|
|
|
|
BYTE r = rowStart[colIdx * img->nChannels + 2];
|
|
|
|
|
|
|
|
target[rowIdx*img->width+colIdx] = (r << 16) + (g << 8) + b;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Send frame to the sink writer.
|
|
|
|
HRESULT hr = WriteFrame(target, rtStart, rtDuration);
|
|
|
|
if (FAILED(hr))
|
|
|
|
{
|
|
|
|
delete[] target;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
rtStart += rtDuration;
|
|
|
|
|
|
|
|
delete[] target;
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
HRESULT CvVideoWriter_MSMF::InitializeSinkWriter(const char* filename)
|
|
|
|
{
|
|
|
|
ComPtr<IMFAttributes> spAttr;
|
|
|
|
ComPtr<IMFMediaType> mediaTypeOut;
|
|
|
|
ComPtr<IMFMediaType> mediaTypeIn;
|
|
|
|
ComPtr<IMFByteStream> spByteStream;
|
|
|
|
|
|
|
|
MFCreateAttributes(&spAttr, 10);
|
|
|
|
spAttr->SetUINT32(MF_READWRITE_ENABLE_HARDWARE_TRANSFORMS, true);
|
|
|
|
|
|
|
|
wchar_t* unicodeFileName = new wchar_t[strlen(filename)+1];
|
Update cap_msmf.cpp
Add support for WinRT in the MF capture framework by removing the disallowed calls to enumerate devices and create a sample grabber sink and adding framework for the MediaCapture interface and a custom sink which interfaces with the sample grabber callback interface. The change requires discussion for making it completely functional as redundancy is required given that if the source is a video file, the old code pathways must be used. Otherwise all IMFMediaSession, IMFMediaSource, and IMFActivate code must use a MediaCapture code path and all sink code must use the CMediaSink custom sink.
Support for the custom sink is extended to non-WinRT not for compatibility as Windows Vista client is a minimum regardless, but because it offers more flexibility, could be faster and is able to be used as an optionally different code path during sink creation based on a future configuration parameter.
My discussion and proposal to finish this change:
Devices are so easily enumerated through WinRT Windows.Devices namespace that wrapping the calls in a library is quite a chore for little benefit though to get the various modes and formats could still be a worthwhile project. For now conditional compilation to remove videodevices and any offending non-video file related activity in videodevice. In my opinion, this is a different , far less fundamental and important change which can possibly be done as a future project and also much more easily implemented in C++/CX.
ImageGrabber has the IMFSampleGrabberSinkCallback replaced with a base class (SharedSampleGrabber) which also be is base class for ImageGrabberRT. This change is necessary as the custom sink does not require a thread to pump events which is done through MediaCapture already. IMFSampleGrabberSinkCallback is the common element between both models and that piece can be shared. Initializing the new ImageGrabberRT is as simple as passing an already initialized MediaCapture object and any video format/encoding parameters.
The concurrency event is necessary to wait for completion and is the way the underlying, IAsyncAction wrappers in the task library work as well. Native WIN32 event objects would be an option if HAVE_CONCURRENCY is not defined. I could even imagine doing it with sleep/thread yield and InterlockedCompareExchange yet I am not enthusiastic about that approach either. Since there is a specific compiler HAVE_ for concurrency, I do not like pulling it in though I think for WinRT it is safe to say we will always have it available though should probably conditionally compile with the Interlocked option as WIN32 events would require HAVE_WIN32.
It looks like C++/CX cannot be used for the IMediaExtension sink (which should not be a problem) as using COM objects requires WRL and though deriving from IMediaExtension can be done, there is little purpose without COM. Objects from C++/CX can be swapped to interact with objects from native C++ as Inspectable* can reinterpret_cast to the ref object IInspectable^ and vice-versa. A solution to the COM class with C++/CX would be great so we could have dual support. Also without #define for every WRL object in use, the code will get quite muddy given that the */^ would need to be ifdef'd everywhere.
Update cap_msmf.cpp
Fixed bugs and completed the change. I believe the new classes need to be moved to a header file as the file has become to large and more classes need to be added for handling all the asynchronous problems (one wrapping IAsyncAction in a task and another for making a task out of IAsyncAction). Unfortunately, blocking on the UI thread is not an option in WinRT so a synchronous architecture is considered "illegal" by Microsoft's standards even if implementable (C++/CX ppltasks library throws errors if you try it). Worse, either by design or a bug in the MF MediaCapture class with Custom Sinks causes a crash if stop/start previewing without reinitializing (spPreferredPreviewMediaType is fatally nulled). After decompiling Windows.Media.dll, I worked around this in my own projects by using an activate-able custom sink ID which strangely assigns 1 to this pointer allowing it to be reinitialized in what can only be described as a hack by Microsoft. This would add additional overhead to the project to implement especially for static libraries as it requires IDL/DLL exporting followed by manifest declaration. Better to document that it is not supported.
Furthermore, an additional class for IMFAttributes should be implemented to make clean architecture for passing around attributes as opposed to directly calling non-COM interface calls on the objects and making use of SetProperties which would also be a set up for an object that uses the RuntimeClass activation ID.
The remaining changes are not difficult and will be complete soon along with debug tracing messages.
Update cap_msmf.cpp
Create cap_msmf.h
Update cap_msmf.cpp
Update cap_msmf.h
Update cap_msmf.cpp
Update cap_msmf.h
Update and rename cap_msmf.h to cap_msmf.hpp
Update cap_msmf.cpp
Update CMakeLists.txt
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.cpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Successful test - samples are grabbed
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update cap_msmf.hpp
Create ppltasks_winrt.h
Update cap_msmf.hpp
Update cap_msmf.hpp
Update cap_msmf.cpp
Update ppltasks_winrt.h
Library updated and cleaned up with comments, marshaling, exceptions and linker settings
Update ppltasks_winrt.h
Fixed trailing whitespace
2013-12-14 16:53:30 +08:00
|
|
|
MultiByteToWideChar(CP_ACP, 0, filename, -1, unicodeFileName, (int)strlen(filename)+1);
|
2013-05-06 18:36:51 +08:00
|
|
|
|
|
|
|
HRESULT hr = MFCreateSinkWriterFromURL(unicodeFileName, NULL, spAttr.Get(), &sinkWriter);
|
|
|
|
|
|
|
|
delete[] unicodeFileName;
|
|
|
|
|
|
|
|
// Set the output media type.
|
|
|
|
if (SUCCEEDED(hr))
|
|
|
|
{
|
|
|
|
hr = MFCreateMediaType(&mediaTypeOut);
|
|
|
|
}
|
|
|
|
if (SUCCEEDED(hr))
|
|
|
|
{
|
|
|
|
hr = mediaTypeOut->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Video);
|
|
|
|
}
|
|
|
|
if (SUCCEEDED(hr))
|
|
|
|
{
|
|
|
|
hr = mediaTypeOut->SetGUID(MF_MT_SUBTYPE, encodingFormat);
|
|
|
|
}
|
|
|
|
if (SUCCEEDED(hr))
|
|
|
|
{
|
|
|
|
hr = mediaTypeOut->SetUINT32(MF_MT_AVG_BITRATE, bitRate);
|
|
|
|
}
|
|
|
|
if (SUCCEEDED(hr))
|
|
|
|
{
|
|
|
|
hr = mediaTypeOut->SetUINT32(MF_MT_INTERLACE_MODE, MFVideoInterlace_Progressive);
|
|
|
|
}
|
|
|
|
if (SUCCEEDED(hr))
|
|
|
|
{
|
|
|
|
hr = MFSetAttributeSize(mediaTypeOut.Get(), MF_MT_FRAME_SIZE, videoWidth, videoHeight);
|
|
|
|
}
|
|
|
|
if (SUCCEEDED(hr))
|
|
|
|
{
|
2013-05-06 22:17:53 +08:00
|
|
|
hr = MFSetAttributeRatio(mediaTypeOut.Get(), MF_MT_FRAME_RATE, (UINT32)fps, 1);
|
2013-05-06 18:36:51 +08:00
|
|
|
}
|
|
|
|
if (SUCCEEDED(hr))
|
|
|
|
{
|
|
|
|
hr = MFSetAttributeRatio(mediaTypeOut.Get(), MF_MT_PIXEL_ASPECT_RATIO, 1, 1);
|
|
|
|
}
|
2013-05-19 04:04:31 +08:00
|
|
|
|
2013-05-06 18:36:51 +08:00
|
|
|
if (SUCCEEDED(hr))
|
|
|
|
{
|
|
|
|
hr = sinkWriter->AddStream(mediaTypeOut.Get(), &streamIndex);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Set the input media type.
|
|
|
|
if (SUCCEEDED(hr))
|
|
|
|
{
|
|
|
|
hr = MFCreateMediaType(&mediaTypeIn);
|
|
|
|
}
|
|
|
|
if (SUCCEEDED(hr))
|
|
|
|
{
|
|
|
|
hr = mediaTypeIn->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Video);
|
|
|
|
}
|
|
|
|
if (SUCCEEDED(hr))
|
|
|
|
{
|
|
|
|
hr = mediaTypeIn->SetGUID(MF_MT_SUBTYPE, inputFormat);
|
|
|
|
}
|
|
|
|
if (SUCCEEDED(hr))
|
|
|
|
{
|
|
|
|
hr = mediaTypeIn->SetUINT32(MF_MT_INTERLACE_MODE, MFVideoInterlace_Progressive);
|
|
|
|
}
|
|
|
|
if (SUCCEEDED(hr))
|
|
|
|
{
|
|
|
|
hr = MFSetAttributeSize(mediaTypeIn.Get(), MF_MT_FRAME_SIZE, videoWidth, videoHeight);
|
|
|
|
}
|
|
|
|
if (SUCCEEDED(hr))
|
|
|
|
{
|
2013-05-06 22:17:53 +08:00
|
|
|
hr = MFSetAttributeRatio(mediaTypeIn.Get(), MF_MT_FRAME_RATE, (UINT32)fps, 1);
|
2013-05-06 18:36:51 +08:00
|
|
|
}
|
|
|
|
if (SUCCEEDED(hr))
|
|
|
|
{
|
|
|
|
hr = MFSetAttributeRatio(mediaTypeIn.Get(), MF_MT_PIXEL_ASPECT_RATIO, 1, 1);
|
|
|
|
}
|
2013-05-22 19:21:23 +08:00
|
|
|
|
|
|
|
if (SUCCEEDED(hr))
|
2013-05-06 18:36:51 +08:00
|
|
|
{
|
|
|
|
hr = sinkWriter->SetInputMediaType(streamIndex, mediaTypeIn.Get(), NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Tell the sink writer to start accepting data.
|
|
|
|
if (SUCCEEDED(hr))
|
|
|
|
{
|
|
|
|
hr = sinkWriter->BeginWriting();
|
|
|
|
}
|
|
|
|
|
|
|
|
return hr;
|
|
|
|
}
|
|
|
|
|
|
|
|
HRESULT CvVideoWriter_MSMF::WriteFrame(DWORD *videoFrameBuffer, const LONGLONG& Start, const LONGLONG& Duration)
|
|
|
|
{
|
2013-05-06 22:17:53 +08:00
|
|
|
ComPtr<IMFSample> sample;
|
|
|
|
ComPtr<IMFMediaBuffer> buffer;
|
2013-05-06 18:36:51 +08:00
|
|
|
|
|
|
|
const LONG cbWidth = 4 * videoWidth;
|
|
|
|
const DWORD cbBuffer = cbWidth * videoHeight;
|
|
|
|
|
|
|
|
BYTE *pData = NULL;
|
|
|
|
|
|
|
|
// Create a new memory buffer.
|
|
|
|
HRESULT hr = MFCreateMemoryBuffer(cbBuffer, &buffer);
|
|
|
|
|
|
|
|
// Lock the buffer and copy the video frame to the buffer.
|
|
|
|
if (SUCCEEDED(hr))
|
|
|
|
{
|
|
|
|
hr = buffer->Lock(&pData, NULL, NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (SUCCEEDED(hr))
|
|
|
|
{
|
2013-06-27 14:56:50 +08:00
|
|
|
#if defined(_M_ARM)
|
|
|
|
hr = MFCopyImage(
|
|
|
|
pData, // Destination buffer.
|
|
|
|
-cbWidth, // Destination stride.
|
|
|
|
(BYTE*)videoFrameBuffer, // First row in source image.
|
|
|
|
cbWidth, // Source stride.
|
|
|
|
cbWidth, // Image width in bytes.
|
|
|
|
videoHeight // Image height in pixels.
|
|
|
|
);
|
|
|
|
#else
|
2013-05-06 18:36:51 +08:00
|
|
|
hr = MFCopyImage(
|
|
|
|
pData, // Destination buffer.
|
|
|
|
cbWidth, // Destination stride.
|
|
|
|
(BYTE*)videoFrameBuffer, // First row in source image.
|
|
|
|
cbWidth, // Source stride.
|
|
|
|
cbWidth, // Image width in bytes.
|
|
|
|
videoHeight // Image height in pixels.
|
|
|
|
);
|
2013-06-27 14:56:50 +08:00
|
|
|
#endif
|
2013-05-06 18:36:51 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
if (buffer)
|
|
|
|
{
|
|
|
|
buffer->Unlock();
|
|
|
|
}
|
|
|
|
|
|
|
|
// Set the data length of the buffer.
|
|
|
|
if (SUCCEEDED(hr))
|
|
|
|
{
|
|
|
|
hr = buffer->SetCurrentLength(cbBuffer);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Create a media sample and add the buffer to the sample.
|
|
|
|
if (SUCCEEDED(hr))
|
|
|
|
{
|
|
|
|
hr = MFCreateSample(&sample);
|
|
|
|
}
|
|
|
|
if (SUCCEEDED(hr))
|
|
|
|
{
|
2013-05-06 22:17:53 +08:00
|
|
|
hr = sample->AddBuffer(buffer.Get());
|
2013-05-06 18:36:51 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// Set the time stamp and the duration.
|
|
|
|
if (SUCCEEDED(hr))
|
|
|
|
{
|
|
|
|
hr = sample->SetSampleTime(Start);
|
|
|
|
}
|
|
|
|
if (SUCCEEDED(hr))
|
|
|
|
{
|
|
|
|
hr = sample->SetSampleDuration(Duration);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Send the sample to the Sink Writer.
|
|
|
|
if (SUCCEEDED(hr))
|
|
|
|
{
|
2013-05-06 22:17:53 +08:00
|
|
|
hr = sinkWriter->WriteSample(streamIndex, sample.Get());
|
2013-05-06 18:36:51 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
return hr;
|
|
|
|
}
|
|
|
|
|
|
|
|
CvVideoWriter* cvCreateVideoWriter_MSMF( const char* filename, int fourcc,
|
|
|
|
double fps, CvSize frameSize, int isColor )
|
|
|
|
{
|
|
|
|
CvVideoWriter_MSMF* writer = new CvVideoWriter_MSMF;
|
|
|
|
if( writer->open( filename, fourcc, fps, frameSize, isColor != 0 ))
|
|
|
|
return writer;
|
|
|
|
delete writer;
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2013-08-21 21:26:54 +08:00
|
|
|
#endif
|