GetProperty method for MSMF VideoCapture implemented.

This commit is contained in:
Alexander Smorkalov 2013-05-22 09:50:54 -07:00
parent 08a0e1c91b
commit 2bc1d3709c

View File

@ -119,8 +119,8 @@ struct MediaType
wchar_t *pMF_MT_AM_FORMAT_TYPEName; wchar_t *pMF_MT_AM_FORMAT_TYPEName;
unsigned int MF_MT_FIXED_SIZE_SAMPLES; unsigned int MF_MT_FIXED_SIZE_SAMPLES;
unsigned int MF_MT_VIDEO_NOMINAL_RANGE; unsigned int MF_MT_VIDEO_NOMINAL_RANGE;
unsigned int MF_MT_FRAME_RATE; unsigned int MF_MT_FRAME_RATE_NUMERATOR;
unsigned int MF_MT_FRAME_RATE_low; unsigned int MF_MT_FRAME_RATE_DENOMINATOR;
unsigned int MF_MT_PIXEL_ASPECT_RATIO; unsigned int MF_MT_PIXEL_ASPECT_RATIO;
unsigned int MF_MT_PIXEL_ASPECT_RATIO_low; unsigned int MF_MT_PIXEL_ASPECT_RATIO_low;
unsigned int MF_MT_ALL_SAMPLES_INDEPENDENT; unsigned int MF_MT_ALL_SAMPLES_INDEPENDENT;
@ -625,14 +625,17 @@ done:
} }
return hr; return hr;
} }
void LogUINT32AsUINT64New(const PROPVARIANT& var, UINT32 &uHigh, UINT32 &uLow) void LogUINT32AsUINT64New(const PROPVARIANT& var, UINT32 &uHigh, UINT32 &uLow)
{ {
Unpack2UINT32AsUINT64(var.uhVal.QuadPart, &uHigh, &uLow); Unpack2UINT32AsUINT64(var.uhVal.QuadPart, &uHigh, &uLow);
} }
float OffsetToFloatNew(const MFOffset& offset) float OffsetToFloatNew(const MFOffset& offset)
{ {
return offset.value + (static_cast<float>(offset.fract) / 65536.0f); return offset.value + (static_cast<float>(offset.fract) / 65536.0f);
} }
HRESULT LogVideoAreaNew(const PROPVARIANT& var) HRESULT LogVideoAreaNew(const PROPVARIANT& var)
{ {
if (var.caub.cElems < sizeof(MFVideoArea)) if (var.caub.cElems < sizeof(MFVideoArea))
@ -641,6 +644,7 @@ HRESULT LogVideoAreaNew(const PROPVARIANT& var)
} }
return S_OK; return S_OK;
} }
HRESULT SpecialCaseAttributeValueNew(GUID guid, const PROPVARIANT& var, MediaType &out) HRESULT SpecialCaseAttributeValueNew(GUID guid, const PROPVARIANT& var, MediaType &out)
{ {
if (guid == MF_MT_DEFAULT_STRIDE) if (guid == MF_MT_DEFAULT_STRIDE)
@ -660,8 +664,8 @@ HRESULT SpecialCaseAttributeValueNew(GUID guid, const PROPVARIANT& var, MediaTyp
{ {
UINT32 uHigh = 0, uLow = 0; UINT32 uHigh = 0, uLow = 0;
LogUINT32AsUINT64New(var, uHigh, uLow); LogUINT32AsUINT64New(var, uHigh, uLow);
out.MF_MT_FRAME_RATE = uHigh; out.MF_MT_FRAME_RATE_NUMERATOR = uHigh;
out.MF_MT_FRAME_RATE_low = uLow; out.MF_MT_FRAME_RATE_DENOMINATOR = uLow;
} }
else else
if (guid == MF_MT_FRAME_RATE_RANGE_MAX) if (guid == MF_MT_FRAME_RATE_RANGE_MAX)
@ -693,9 +697,11 @@ HRESULT SpecialCaseAttributeValueNew(GUID guid, const PROPVARIANT& var, MediaTyp
} }
return S_OK; return S_OK;
} }
#ifndef IF_EQUAL_RETURN #ifndef IF_EQUAL_RETURN
#define IF_EQUAL_RETURN(param, val) if(val == param) return L#val #define IF_EQUAL_RETURN(param, val) if(val == param) return L#val
#endif #endif
LPCWSTR GetGUIDNameConstNew(const GUID& guid) LPCWSTR GetGUIDNameConstNew(const GUID& guid)
{ {
IF_EQUAL_RETURN(guid, MF_MT_MAJOR_TYPE); IF_EQUAL_RETURN(guid, MF_MT_MAJOR_TYPE);
@ -875,6 +881,7 @@ MediaType FormatReader::Read(IMFMediaType *pType)
} }
return out; return out;
} }
FormatReader::~FormatReader(void) FormatReader::~FormatReader(void)
{ {
} }
@ -1880,6 +1887,7 @@ int videoDevice::findType(unsigned int size, unsigned int frameRate)
return 0; return 0;
return VN[0]; return VN[0];
} }
void videoDevice::buildLibraryofTypes() void videoDevice::buildLibraryofTypes()
{ {
unsigned int size; unsigned int size;
@ -1889,7 +1897,7 @@ void videoDevice::buildLibraryofTypes()
for(; i != vd_CurrentFormats.end(); i++) for(; i != vd_CurrentFormats.end(); i++)
{ {
size = (*i).MF_MT_FRAME_SIZE; size = (*i).MF_MT_FRAME_SIZE;
framerate = (*i).MF_MT_FRAME_RATE; framerate = (*i).MF_MT_FRAME_RATE_NUMERATOR;
FrameRateMap FRM = vd_CaptureFormats[size]; FrameRateMap FRM = vd_CaptureFormats[size];
SUBTYPEMap STM = FRM[framerate]; SUBTYPEMap STM = FRM[framerate];
String subType((*i).pMF_MT_SUBTYPEName); String subType((*i).pMF_MT_SUBTYPEName);
@ -2187,8 +2195,8 @@ void MediaType::Clear()
MF_MT_VIDEO_CHROMA_SITING = 0; MF_MT_VIDEO_CHROMA_SITING = 0;
MF_MT_FIXED_SIZE_SAMPLES = 0; MF_MT_FIXED_SIZE_SAMPLES = 0;
MF_MT_VIDEO_NOMINAL_RANGE = 0; MF_MT_VIDEO_NOMINAL_RANGE = 0;
MF_MT_FRAME_RATE = 0; MF_MT_FRAME_RATE_NUMERATOR = 0;
MF_MT_FRAME_RATE_low = 0; MF_MT_FRAME_RATE_DENOMINATOR = 0;
MF_MT_PIXEL_ASPECT_RATIO = 0; MF_MT_PIXEL_ASPECT_RATIO = 0;
MF_MT_PIXEL_ASPECT_RATIO_low = 0; MF_MT_PIXEL_ASPECT_RATIO_low = 0;
MF_MT_ALL_SAMPLES_INDEPENDENT = 0; MF_MT_ALL_SAMPLES_INDEPENDENT = 0;
@ -3033,6 +3041,7 @@ protected:
bool isOpened; bool isOpened;
HRESULT enumerateCaptureFormats(IMFMediaSource *pSource); HRESULT enumerateCaptureFormats(IMFMediaSource *pSource);
HRESULT getSourceDuration(IMFMediaSource *pSource, MFTIME *pDuration);
}; };
CvCaptureFile_MSMF::CvCaptureFile_MSMF(): CvCaptureFile_MSMF::CvCaptureFile_MSMF():
@ -3094,7 +3103,7 @@ bool CvCaptureFile_MSMF::open(const char* filename)
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
hr = ImageGrabberThread::CreateInstance(&grabberThread, videoFileSource, -2, true); hr = ImageGrabberThread::CreateInstance(&grabberThread, videoFileSource, (unsigned int)-2, true);
} }
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
@ -3131,7 +3140,8 @@ bool CvCaptureFile_MSMF::setProperty(int property_id, double value)
{ {
// image capture properties // image capture properties
bool handled = false; bool handled = false;
int width, height, fourcc; unsigned int width, height;
int fourcc;
switch( property_id ) switch( property_id )
{ {
case CV_CAP_PROP_FRAME_WIDTH: case CV_CAP_PROP_FRAME_WIDTH:
@ -3239,57 +3249,26 @@ double CvCaptureFile_MSMF::getProperty(int property_id)
case CV_CAP_PROP_FRAME_HEIGHT: case CV_CAP_PROP_FRAME_HEIGHT:
return captureFormats[captureFormatIndex].height; return captureFormats[captureFormatIndex].height;
case CV_CAP_PROP_FRAME_COUNT: case CV_CAP_PROP_FRAME_COUNT:
return 30; {
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);
}
case CV_CAP_PROP_FOURCC: case CV_CAP_PROP_FOURCC:
// FIXME: implement method in VideoInput back end return captureFormats[captureFormatIndex].MF_MT_SUBTYPE.Data1;
//return VI.getFourcc(index);
;
case CV_CAP_PROP_FPS: case CV_CAP_PROP_FPS:
// FIXME: implement method in VideoInput back end return ((double)captureFormats[captureFormatIndex].MF_MT_FRAME_RATE_NUMERATOR) /
//return VI.getFPS(index); ((double)captureFormats[captureFormatIndex].MF_MT_FRAME_RATE_DENOMINATOR);
;
} }
// video filter properties
switch( property_id )
{
case CV_CAP_PROP_BRIGHTNESS:
case CV_CAP_PROP_CONTRAST:
case CV_CAP_PROP_HUE:
case CV_CAP_PROP_SATURATION:
case CV_CAP_PROP_SHARPNESS:
case CV_CAP_PROP_GAMMA:
case CV_CAP_PROP_MONOCROME:
case CV_CAP_PROP_WHITE_BALANCE_BLUE_U:
case CV_CAP_PROP_BACKLIGHT:
case CV_CAP_PROP_GAIN:
// FIXME: implement method in VideoInput back end
// if ( VI.getVideoSettingFilter(index, VI.getVideoPropertyFromCV(property_id), min_value,
// max_value, stepping_delta, current_value, flags,defaultValue) )
// return (double)current_value;
return 0.;
}
// camera properties
switch( property_id )
{
case CV_CAP_PROP_PAN:
case CV_CAP_PROP_TILT:
case CV_CAP_PROP_ROLL:
case CV_CAP_PROP_ZOOM:
case CV_CAP_PROP_EXPOSURE:
case CV_CAP_PROP_IRIS:
case CV_CAP_PROP_FOCUS:
// FIXME: implement method in VideoInput back end
// if (VI.getVideoSettingCamera(index,VI.getCameraPropertyFromCV(property_id),min_value,
// max_value,stepping_delta,current_value,flags,defaultValue) ) return (double)current_value;
return 0.;
}
// unknown parameter or value not available
return -1; return -1;
} }
bool CvCaptureFile_MSMF::grabFrame() bool CvCaptureFile_MSMF::grabFrame()
{ {
DWORD waitResult; DWORD waitResult = -1;
if (isOpened) if (isOpened)
{ {
SetEvent(grabberThread->getImageGrabber()->ig_hFrameGrabbed); SetEvent(grabberThread->getImageGrabber()->ig_hFrameGrabbed);
@ -3305,7 +3284,7 @@ IplImage* CvCaptureFile_MSMF::retrieveFrame(int)
unsigned int width = captureFormats[captureFormatIndex].width; unsigned int width = captureFormats[captureFormatIndex].width;
unsigned int height = captureFormats[captureFormatIndex].height; unsigned int height = captureFormats[captureFormatIndex].height;
unsigned int bytes = 3; unsigned int bytes = 3;
if( !frame || width != frame->width || height != frame->height ) if( !frame || (int)width != frame->width || (int)height != frame->height )
{ {
if (frame) if (frame)
cvReleaseImage( &frame ); cvReleaseImage( &frame );
@ -3370,6 +3349,20 @@ done:
return hr; return hr;
} }
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;
}
CvCapture* cvCreateCameraCapture_MSMF( int index ) CvCapture* cvCreateCameraCapture_MSMF( int index )
{ {
@ -3508,12 +3501,12 @@ const GUID CvVideoWriter_MSMF::FourCC2GUID(int fourcc)
} }
bool CvVideoWriter_MSMF::open( const char* filename, int fourcc, bool CvVideoWriter_MSMF::open( const char* filename, int fourcc,
double _fps, CvSize frameSize, bool isColor ) double _fps, CvSize frameSize, bool /*isColor*/ )
{ {
videoWidth = frameSize.width; videoWidth = frameSize.width;
videoHeight = frameSize.height; videoHeight = frameSize.height;
fps = _fps; fps = _fps;
bitRate = fps*videoWidth*videoHeight; // 1-bit per pixel bitRate = (UINT32)fps*videoWidth*videoHeight; // 1-bit per pixel
encodingFormat = FourCC2GUID(fourcc); encodingFormat = FourCC2GUID(fourcc);
inputFormat = MFVideoFormat_RGB32; inputFormat = MFVideoFormat_RGB32;