#include <mfplay.h>
#include <mfobjects.h>
#include <strsafe.h>
-#include <wrl/client.h>
#include <Mfreadwrite.h>
#include <new>
#include <map>
#pragma comment(lib, "Mfreadwrite")
#pragma comment(lib, "MinCore_Downlevel")
+// for ComPtr usage
+#include <wrl/client.h>
using namespace Microsoft::WRL;
struct IMFMediaType;
unsigned int width;
unsigned int MF_MT_YUV_MATRIX;
unsigned int MF_MT_VIDEO_LIGHTING;
- unsigned int MF_MT_DEFAULT_STRIDE;
+ int MF_MT_DEFAULT_STRIDE; // stride is negative if image is bottom-up
unsigned int MF_MT_VIDEO_CHROMA_SITING;
GUID MF_MT_AM_FORMAT_TYPE;
wchar_t *pMF_MT_AM_FORMAT_TYPEName;
DWORD dwSampleSize);
STDMETHODIMP OnShutdown();
};
+
/// Class for controlling of thread of the grabbing raw data from video device
class ImageGrabberThread
{
bool igt_stop;
unsigned int igt_DeviceID;
};
+
// Structure for collecting info about one parametr of current video device
struct Parametr
{
long Flag;
Parametr();
};
+
// Structure for collecting info about 17 parametrs of current video device
struct CamParametrs
{
Parametr Iris;
Parametr Focus;
};
+
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 *);
+
/// Class for controlling of video device
class videoDevice
{
IMFMediaSource *vd_pSource;
emergensyStopEventCallback vd_func;
void *vd_userData;
- long enumerateCaptureFormats(IMFMediaSource *pSource);
+ HRESULT enumerateCaptureFormats(IMFMediaSource *pSource);
long setDeviceFormat(IMFMediaSource *pSource, unsigned long dwFormatIndex);
void buildLibraryofTypes();
int findType(unsigned int size, unsigned int frameRate = 0);
long initDevice();
long checkDevice(IMFAttributes *pAttributes, IMFActivate **pDevice);
};
+
/// Class for managing of list of video devices
class videoDevices
{
std::vector<videoDevice *> vds_Devices;
videoDevices(void);
};
+
// Class for creating of Media Foundation context
class Media_Foundation
{
private:
Media_Foundation(void);
};
+
/// The only visiable class for controlling of video devices in format singelton
class videoInput
{
bool isFrameNew(int deviceID);
// 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);
+ static void processPixels(unsigned char * src, unsigned char * dst, unsigned int width, unsigned int height, unsigned int bpp, bool bRGB, bool bFlip);
private:
bool accessToDevices;
videoInput(void);
- void processPixels(unsigned char * src, unsigned char * dst, unsigned int width, unsigned int height, unsigned int bpp, bool bRGB, bool bFlip);
void updateListOfDevices();
};
+
DebugPrintOut::DebugPrintOut(void):verbose(true)
{
}
+
DebugPrintOut::~DebugPrintOut(void)
{
}
+
DebugPrintOut& DebugPrintOut::getInstance()
{
static DebugPrintOut instance;
return instance;
}
+
void DebugPrintOut::printOut(const wchar_t *format, ...)
{
if(verbose)
va_end (args);
}
}
+
void DebugPrintOut::setVerbose(bool state)
{
verbose = state;
}
+
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);
+
unsigned int *GetParametr(GUID guid, MediaType &out)
{
if(guid == MF_MT_YUV_MATRIX)
if(guid == MF_MT_VIDEO_LIGHTING)
return &(out.MF_MT_VIDEO_LIGHTING);
if(guid == MF_MT_DEFAULT_STRIDE)
- return &(out.MF_MT_DEFAULT_STRIDE);
+ return (unsigned int*)&(out.MF_MT_DEFAULT_STRIDE);
if(guid == MF_MT_VIDEO_CHROMA_SITING)
return &(out.MF_MT_VIDEO_CHROMA_SITING);
if(guid == MF_MT_VIDEO_NOMINAL_RANGE)
return &(out.MF_MT_INTERLACE_MODE);
return NULL;
}
+
HRESULT LogAttributeValueByIndexNew(IMFAttributes *pAttr, DWORD index, MediaType &out)
{
WCHAR *pGuidName = NULL;
PropVariantClear(&var);
return hr;
}
+
HRESULT GetGUIDNameNew(const GUID& guid, WCHAR **ppwsz)
{
HRESULT hr = S_OK;
}
HRESULT SpecialCaseAttributeValueNew(GUID guid, const PROPVARIANT& var, MediaType &out)
{
+ if (guid == MF_MT_DEFAULT_STRIDE)
+ {
+ out.MF_MT_DEFAULT_STRIDE = var.intVal;
+ } else
if (guid == MF_MT_FRAME_SIZE)
{
UINT32 uHigh = 0, uLow = 0;
hr = S_OK;
goto done;
}
+ printf("media foundation event: %d\n", met);
if (met == MESessionEnded)
{
DPO->printOut(L"IMAGEGRABBER VIDEODEVICE %i: MESessionEnded \n", ig_DeviceID);
DPO->printOut(L"IMAGEGRABBER VIDEODEVICE %i: MEVideoCaptureDeviceRemoved \n", ig_DeviceID);
break;
}
+ if ((met == MEError) || (met == MENonFatalError))
+ {
+ pEvent->GetStatus(&hrStatus);
+ DPO->printOut(L"IMAGEGRABBER VIDEODEVICE %i: MEError | MENonFatalError: %u\n", ig_DeviceID, hrStatus);
+ break;
+ }
}
+ DPO->printOut(L"IMAGEGRABBER VIDEODEVICE %i: Finish startGrabbing \n", ig_DeviceID);
+done:
if (ig_Synchronous)
{
SetEvent(ig_hFinish);
}
- DPO->printOut(L"IMAGEGRABBER VIDEODEVICE %i: Finish startGrabbing \n", ig_DeviceID);
-
-done:
SafeRelease(&ig_pSession);
SafeRelease(&ig_pTopology);
CoTaskMemFree(vd_pFriendlyName);
}
-long videoDevice::enumerateCaptureFormats(IMFMediaSource *pSource)
+HRESULT videoDevice::enumerateCaptureFormats(IMFMediaSource *pSource)
{
ComPtr<IMFPresentationDescriptor> pPD = NULL;
ComPtr<IMFStreamDescriptor> pSD = NULL;
IplImage* frame;
bool isOpened;
- long enumerateCaptureFormats(IMFMediaSource *pSource);
- void processPixels(unsigned char * src, unsigned char * dst, unsigned int width,
- unsigned int height, unsigned int bpp, bool bRGB, bool bFlip);
+ HRESULT enumerateCaptureFormats(IMFMediaSource *pSource);
};
CvCaptureFile_MSMF::CvCaptureFile_MSMF():
MF_OBJECT_TYPE ObjectType = MF_OBJECT_INVALID;
- IMFSourceResolver* pSourceResolver = NULL;
+ ComPtr<IMFSourceResolver> pSourceResolver = NULL;
IUnknown* pUnkSource = NULL;
- hr = MFCreateSourceResolver(&pSourceResolver);
+ hr = MFCreateSourceResolver(pSourceResolver.GetAddressOf());
if (SUCCEEDED(hr))
{
hr = pUnkSource->QueryInterface(IID_PPV_ARGS(&videoFileSource));
}
- SafeRelease(&pSourceResolver);
SafeRelease(&pUnkSource);
- enumerateCaptureFormats(videoFileSource);
+ if (SUCCEEDED(hr))
+ {
+ hr = enumerateCaptureFormats(videoFileSource);
+ }
if (SUCCEEDED(hr))
{
grabberThread->start();
}
- isOpened = true;
+ isOpened = SUCCEEDED(hr);
- return true;
+ return isOpened;
}
void CvCaptureFile_MSMF::close()
return captureFormats[captureFormatIndex].width;
case CV_CAP_PROP_FRAME_HEIGHT:
return captureFormats[captureFormatIndex].height;
+ case CV_CAP_PROP_FRAME_COUNT:
+ return 30;
case CV_CAP_PROP_FOURCC:
// FIXME: implement method in VideoInput back end
//return VI.getFourcc(index);
RawImage *RIOut = grabberThread->getImageGrabber()->getRawImage();
unsigned int size = bytes * width * height;
+ bool verticalFlip = captureFormats[captureFormatIndex].MF_MT_DEFAULT_STRIDE < 0;
+
if(RIOut && size == RIOut->getSize())
{
- processPixels(RIOut->getpPixels(), (unsigned char*)frame->imageData, width, height, bytes, false, false);
+ videoInput::processPixels(RIOut->getpPixels(), (unsigned char*)frame->imageData, width,
+ height, bytes, false, verticalFlip);
}
return frame;
}
-void CvCaptureFile_MSMF::processPixels(unsigned char * src, unsigned char * dst, unsigned int width,
- unsigned int height, unsigned int bpp, bool bRGB, bool bFlip)
-{
- unsigned int widthInBytes = width * bpp;
- unsigned int numBytes = widthInBytes * height;
- int *dstInt, *srcInt;
- if(!bRGB)
- {
- 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);
- dst++;
- *dst = *src;
- dst++;
- src+=3;
- x++;
- }
- }
- else
- {
- for(unsigned int i = 0; i < numBytes; i+=3)
- {
- *dst = *(src+2);
- dst++;
- *dst = *(src+1);
- dst++;
- *dst = *src;
- dst++;
- src+=3;
- }
- }
- }
-}
-
-long CvCaptureFile_MSMF::enumerateCaptureFormats(IMFMediaSource *pSource)
+HRESULT CvCaptureFile_MSMF::enumerateCaptureFormats(IMFMediaSource *pSource)
{
ComPtr<IMFPresentationDescriptor> pPD = NULL;
ComPtr<IMFStreamDescriptor> pSD = NULL;
goto done;
}
- DWORD cnt;
-
- pPD->GetStreamDescriptorCount(&cnt);
-
- printf("Stream count: %d\n", cnt);
-
BOOL fSelected;
hr = pPD->GetStreamDescriptorByIndex(0, &fSelected, pSD.GetAddressOf());
if (FAILED(hr))
CvCapture* cvCreateFileCapture_MSMF (const char* filename)
{
CvCaptureFile_MSMF* capture = new CvCaptureFile_MSMF;
- if( capture->open(filename) )
- return capture;
- delete capture;
- return 0;
+ try
+ {
+ if( capture->open(filename) )
+ return capture;
+ else
+ {
+ delete capture;
+ return NULL;
+ }
+ }
+ catch(...)
+ {
+ delete capture;
+ throw;
+ }
}
//
public:
CvVideoWriter_MSMF();
virtual ~CvVideoWriter_MSMF();
- virtual bool open( const char* filename, int fourcc,
- double fps, CvSize frameSize, bool isColor );
+ virtual bool open(const char* filename, int fourcc,
+ double fps, CvSize frameSize, bool isColor);
virtual void close();
- virtual bool writeFrame( const IplImage* img);
+ virtual bool writeFrame(const IplImage* img);
private:
UINT32 videoWidth;
videoWidth = frameSize.width;
videoHeight = frameSize.height;
fps = _fps;
- bitRate = videoWidth*videoHeight; // 1-bit per pixel
+ bitRate = fps*videoWidth*videoHeight; // 1-bit per pixel
encodingFormat = FourCC2GUID(fourcc);
inputFormat = MFVideoFormat_RGB32;
BYTE g = rowStart[colIdx * img->nChannels + 1];
BYTE r = rowStart[colIdx * img->nChannels + 2];
- // On ARM devices data is stored starting from the last line
- // (and not the first line) so you have to revert them on the Y axis
-#if _M_ARM
- int targetRow = videoHeight - rowIdx - 1;
- target[(targetRow * videoWidth) + colIdx] = (r << 16) + (g << 8) + b;
-#else
target[rowIdx*img->width+colIdx] = (r << 16) + (g << 8) + b;
-#endif
}
}
{
hr = MFSetAttributeRatio(mediaTypeOut.Get(), MF_MT_PIXEL_ASPECT_RATIO, 1, 1);
}
+
if (SUCCEEDED(hr))
{
hr = sinkWriter->AddStream(mediaTypeOut.Get(), &streamIndex);
{
hr = MFSetAttributeRatio(mediaTypeIn.Get(), MF_MT_PIXEL_ASPECT_RATIO, 1, 1);
}
- if (SUCCEEDED(hr))
+ if (SUCCEEDED(hr))
{
hr = sinkWriter->SetInputMediaType(streamIndex, mediaTypeIn.Get(), NULL);
}
return format("%c%c%c%c", fourcc & 255, (fourcc >> 8) & 255, (fourcc >> 16) & 255, (fourcc >> 24) & 255);
}
+#ifdef HAVE_MSMF
+const VideoFormat g_specific_fmt_list[] =
+{
+/* VideoFormat("avi", 'dv25'),
+ VideoFormat("avi", 'dv50'),
+ VideoFormat("avi", 'dvc '),
+ VideoFormat("avi", 'dvh1'),
+ VideoFormat("avi", 'dvhd'),
+ VideoFormat("avi", 'dvsd'),
+ VideoFormat("avi", 'dvsl'),
+ VideoFormat("avi", 'M4S2'), */
+ VideoFormat("wmv", 'WMV3'),
+ // VideoFormat("avi", 'H264'),
+ // VideoFormat("avi", 'MJPG'),
+ // VideoFormat("avi", 'MP43'),
+ // VideoFormat("avi", 'MP4S'),
+ // VideoFormat("avi", 'MP4V'),
+/* VideoFormat("avi", 'MPG1'),
+ VideoFormat("avi", 'MSS1'),
+ VideoFormat("avi", 'MSS2'),
+ VideoFormat("avi", 'WMV1'),
+ VideoFormat("avi", 'WMV2'),
+ VideoFormat("avi", 'WMV3'),
+ VideoFormat("avi", 'WVC1'), */
+ VideoFormat()
+};
+#else
const VideoFormat g_specific_fmt_list[] =
{
VideoFormat("avi", CV_FOURCC('X', 'V', 'I', 'D')),
VideoFormat("mkv", CV_FOURCC('X', 'V', 'I', 'D')),
VideoFormat("mkv", CV_FOURCC('M', 'P', 'E', 'G')),
VideoFormat("mkv", CV_FOURCC('M', 'J', 'P', 'G')),
-
VideoFormat("mov", CV_FOURCC('m', 'p', '4', 'v')),
VideoFormat()
};
+#endif
}
class CV_HighGuiTest : public cvtest::BaseTest
{
protected:
- void ImageTest(const string& dir);
+ void ImageTest (const string& dir);
void VideoTest (const string& dir, const cvtest::VideoFormat& fmt);
void SpecificImageTest (const string& dir);
void SpecificVideoTest (const string& dir, const cvtest::VideoFormat& fmt);
if (psnr < thresDbell)
{
printf("Too low psnr = %gdb\n", psnr);
- // imwrite("img.png", img);
- // imwrite("img1.png", img1);
+ //imwrite("original.png", img);
+ //imwrite("after_test.png", img1);
+ //Mat diff;
+ //absdiff(img, img1, diff);
+ //imwrite("diff.png", diff);
ts->set_failed_test_info(ts->FAIL_MISMATCH);
break;
}