Media Foundation set video capture frame rate using PROPVARIANT structure

1.7k views Asked by At

I'm writing a media foundation application where I need to set the capture frame rate for a video device. The function I'm writing is something like:

bool SetRequestedFrameRate(const size_t requestedFramesPerSecond);

where I pass a user-defined integer as the frame rate parameter. I'm following the code snippet on https://msdn.microsoft.com/en-us/library/windows/desktop/ff485859(v=vs.85).aspx :

PROPVARIANT var;
if (SUCCEEDED(pType->GetItem(MF_MT_FRAME_RATE_RANGE_MAX, &var)))
{
    hr = pType->SetItem(MF_MT_FRAME_RATE, var);

    PropVariantClear(&var);

    if (FAILED(hr))
    {
        goto done;
    }

    hr = pHandler->SetCurrentMediaType(pType);
}

Apparantly it uses the PROVARIANT structure to hold frame rate data. But how do I construct a PROVARIANT structure from my "const size_t requestedFramesPerSecond" parameter? If I already have a PROVARIANT that holds the frame rate, how do I retrieve the actual frame rate integer from it ? Also, does COM provide a way to compare two PROVARIANT structures that represent frame rate ?

Please help, thank!

2

There are 2 answers

7
Jeff On BEST ANSWER

As Roman pointed out, you can avoid dealing with the PROPVARIANT structure, by using the utility functions to access the IMFAttributes store. However, as #7 points out on the page you referenced:

  1. Query the media type for the MF_MT_FRAME_RATE_RANGE_MAX and MF_MT_FRAME_RATE_RANGE_MIN attributes. This values give the range of supported frame rates. The device might support other frame rates within this range.

Enumerate the native media types of the capture device, and simply select (choose one) and reuse the media type to set the current media type. Otherwise you will be frustrated with failed calls which do not match the capabilities of the capture device. I discuss frame rates a bit and show how to enumerate the native media type here. Good luck.

2
Roman Ryltsov On

MF_MT_FRAME_RATE attribute is a pair of 32-bit integers representing numerator and denominator. MFSetAttributeRatio and friends are helpers to set/get the values in a friendly way. Using PROVARIANT you should handle it as a 64-bit UINT64 value.

The frame rate is expressed as a ratio. The upper 32 bits of the attribute value contain the numerator and the lower 32 bits contain the denominator. For example, if the frame rate is 30 frames per second (fps), the ratio is 30/1. If the frame rate is 29.97 fps, the ratio is 30,000/1001.