Получите все поддерживаемые значения FPS камеры в Microsoft Media Foundation

Я хочу получить список всех значений FPS, которые поддерживает моя веб-камера.

В разделе Как настроить захват видео Частота кадров в статье msdn говорится, что я могу запросить у системы максимальный и минимальный поддерживаемый FPS для конкретной камеры.

Там также говорится:

Устройство может поддерживать другие частоты кадров в этом диапазоне.

И в MF_MT_FRAME_RATE_RANGE_MIN он говорит:

Не гарантируется, что устройство будет поддерживать каждое приращение в этом диапазоне.

Таким образом, похоже, что невозможно получить все значения FPS, поддерживаемые камерой в Media Foundation, только максимальное и минимальное.

Я знаю, что в Linux команда v4l2-ctl --list-formats-ext выводит намного больше поддерживаемых FPS, чем просто min и max.

Вот лишь несколько примеров из Linux с использованием разных камер:

$ v4l2-ctl --list-formats-ext
ioctl: VIDIOC_ENUM_FMT
  Index       : 0
  Type        : Video Capture
  Pixel Format: 'YUYV'
  Name        : YUV 4:2:2 (YUYV)
    Size: Discrete 160x120
      Interval: Discrete 0.033s (30.000 fps)
      Interval: Discrete 0.036s (27.500 fps)
      Interval: Discrete 0.040s (25.000 fps)
      Interval: Discrete 0.044s (22.500 fps)
      Interval: Discrete 0.050s (20.000 fps)
      Interval: Discrete 0.057s (17.500 fps)
      Interval: Discrete 0.067s (15.000 fps)
      Interval: Discrete 0.080s (12.500 fps)
      Interval: Discrete 0.100s (10.000 fps)
      Interval: Discrete 0.133s (7.500 fps)
      Interval: Discrete 0.200s (5.000 fps)
    Size: Discrete 176x144
      Interval: Discrete 0.033s (30.000 fps)
      ...

и

$ v4l2-ctl --list-formats-ext
ioctl: VIDIOC_ENUM_FMT
    Index       : 0
    Type        : Video Capture
    Pixel Format: 'YUYV'
    Name        : YUV 4:2:2 (YUYV)
        Size: Discrete 640x360
            Interval: Discrete 0.033s (30.000 fps)
            Interval: Discrete 0.040s (25.000 fps)
            Interval: Discrete 0.050s (20.000 fps)
            Interval: Discrete 0.067s (15.000 fps)
            Interval: Discrete 0.100s (10.000 fps)
            Interval: Discrete 0.200s (5.000 fps)
        Size: Discrete 640x480
            Interval: Discrete 0.033s (30.000 fps)
            Interval: Discrete 0.040s (25.000 fps)
            Interval: Discrete 0.050s (20.000 fps)
            Interval: Discrete 0.067s (15.000 fps)
            Interval: Discrete 0.100s (10.000 fps)
            Interval: Discrete 0.200s (5.000 fps)
        Size: Discrete 320x240
            Interval: Discrete 0.033s (30.000 fps)
            Interval: Discrete 0.040s (25.000 fps)
            Interval: Discrete 0.050s (20.000 fps)
            Interval: Discrete 0.067s (15.000 fps)
            Interval: Discrete 0.100s (10.000 fps)
            Interval: Discrete 0.200s (5.000 fps)
        Size: Discrete 160x120
            Interval: Discrete 0.033s (30.000 fps)
            Interval: Discrete 0.040s (25.000 fps)
            Interval: Discrete 0.050s (20.000 fps)
            Interval: Discrete 0.067s (15.000 fps)
            Interval: Discrete 0.100s (10.000 fps)
            Interval: Discrete 0.200s (5.000 fps)
        Size: Discrete 960x544
            Interval: Discrete 0.067s (15.000 fps)
            Interval: Discrete 0.100s (10.000 fps)
            Interval: Discrete 0.200s (5.000 fps)
        Size: Discrete 1280x720
            Interval: Discrete 0.100s (10.000 fps)
            Interval: Discrete 0.200s (5.000 fps)

и

$ v4l2-ctl --list-formats-ext    
ioctl: VIDIOC_ENUM_FMT
        Index       : 0
        Type        : Video Capture
        Pixel Format: 'YUYV'
        Name        : YUV 4:2:2 (YUYV)
                Size: Discrete 1280x720
                        Interval: Discrete 0.111s (9.000 fps)
                Size: Discrete 160x120
                        Interval: Discrete 0.033s (30.000 fps)
                Size: Discrete 320x240
                        Interval: Discrete 0.033s (30.000 fps)
                Size: Discrete 1280x800
                        Interval: Discrete 0.111s (9.000 fps)
                Size: Discrete 640x480
                        Interval: Discrete 0.033s (30.000 fps)

        Index       : 1
        Type        : Video Capture
        Pixel Format: 'MJPG' (compressed)
        Name        : MJPEG
                Size: Discrete 1280x720
                        Interval: Discrete 0.033s (30.000 fps)
                Size: Discrete 160x120
                        Interval: Discrete 0.033s (30.000 fps)
                Size: Discrete 320x240
                        Interval: Discrete 0.033s (30.000 fps)
                Size: Discrete 1280x800
                        Interval: Discrete 0.033s (30.000 fps)
                Size: Discrete 640x480
                        Interval: Discrete 0.033s (30.000 fps)

Итак, есть ли способ получить все поддерживаемые FPS камерой в Microsoft Media Foundation, или он действительно ограничен в этом аспекте?


person Yellow Ray    schedule 13.06.2015    source источник


Ответы (1)


Частоту кадров и другие атрибуты можно получить с помощью кода, подобного следующему (для краткости проверка ошибок опущена):

Microsoft::WRL::ComPtr<IMFSourceReader> reader = nullptr;
/* reader code omitted */

IMFMediaType* mediaType = nullptr;
GUID          subtype { 0 };

UINT32 frameRate    = 0u;
UINT32 frameRateMin = 0u;
UINT32 frameRateMax = 0u;
UINT32 denominator  = 0u;

DWORD index         = 0u;
DWORD width         = 0u;
DWORD height        = 0u;

HRESULT hr = S_OK;
while (hr == S_OK)
{
    hr = reader->GetNativeMediaType((DWORD) MF_SOURCE_READER_FIRST_VIDEO_STREAM, index, &mediaType);
    if (hr == MF_E_NO_MORE_TYPES)
        break;

    // Error checking omitted for brevity
    hr = mediaType->GetGUID(MF_MT_SUBTYPE, &subtype);
    hr = MFGetAttributeSize(mediaType, MF_MT_FRAME_SIZE, &width, &height);
    hr = MFGetAttributeRatio(mediaType, MF_MT_FRAME_RATE, &frameRate, &denominator);
    hr = MFGetAttributeRatio(mediaType, MF_MT_FRAME_RATE_RANGE_MIN, &frameRateMin, &denominator);
    hr = MFGetAttributeRatio(mediaType, MF_MT_FRAME_RATE_RANGE_MAX, &frameRateMax, &denominator);
    ++index;
}

Частота кадров выражается в виде отношения. Старшие 32 бита значения атрибута содержат числитель, а младшие 32 бита содержат знаменатель. Например, если частота кадров составляет 30 кадров в секунду (fps), соотношение равно 30/1. Если частота кадров составляет 29,97 кадров в секунду, соотношение составляет 30 000/1001.

Как правило, знаменатель будет равен 1 (другого я не видел). И с различными веб-камерами, которые я тестировал, frameRate, frameRateMin и frameRateMax имеют одно и то же число. Результаты будут выглядеть почти так же, как вы перечислили выше.

Изменить:

Например, ниже приведен вывод вышеприведенного кода (без printf) на консольный вывод собственных форматов, поддерживаемых для Logitech Webcam Pro 9000:

введите здесь описание изображения

У этой старой веб-камеры 46 собственных форматов, тогда как у более новых веб-камер их гораздо больше (у C930e их 216). Вот первые 81 собственный формат C930e:

введите здесь описание изображения

Иногда веб-камера будет иметь очень высокие числа, что обычно означает, что кадры не будут дросселироваться и доставляться как можно быстрее, что зависит от скорости затвора, разрешения и т. д. (я максимизирую это число до 99 для удобства чтения).

Я думаю, вы зациклились на следующей цитате:

Устройство может поддерживать другие частоты кадров в этом диапазоне.

Однако это если минимальная и максимальная не равны частоте кадров, и я не видел веб-камер, которые различаются по этим числам. Имейте в виду, что это можно использовать с любым устройством захвата. Карта захвата PCIe с 4 линиями имеет пропускную способность, позволяющую справиться практически со всем, что вы хотите, поэтому они предпочтут написать драйвер соответствующим образом (несколько форматов с большой разницей между минимальным и максимальным).

person Jeff    schedule 15.06.2015
comment
Пожалуйста, прочтите вопрос и постарайтесь понять, о чем он говорит, прежде чем отвечать. - person Yellow Ray; 19.06.2015
comment
Если бы вы попробовали приведенный выше код на нескольких камерах, вы бы не написали этот комментарий. Я отредактирую ответ, чтобы он был слишком явным. - person Jeff; 19.06.2015
comment
Если вы прочтете мой вопрос, то увидите, что я хочу получить ВСЕ действительные значения FPS для камеры, а не только MF_MT_FRAME_RATE, MF_MT_FRAME_RATE_RANGE_MIN и MF_MT_FRAME_RATE_RANGE_MAX. Ваш ответ бесполезен для меня, так как он получает только MF_MT_FRAME_RATE, MF_MT_FRAME_RATE_RANGE_MIN и MF_MT_FRAME_RATE_RANGE_MAX, которые я уже знаю, как получить. - person Yellow Ray; 20.06.2015
comment
Перебирая собственные форматы камеры и запрашивая эти значения, вы получаете все допустимые частоты кадров для камеры, что в точности соответствует приведенному выше списку. На самом деле, если бы мы попробовали это на той же камере, мы бы получили те же значения. С вашим отношением я не буду тратить время, чтобы снова ответить вам на вопрос. - person Jeff; 21.06.2015
comment
О, я вижу, как это. Вы получаете несколько типов мультимедиа, которые отличаются только FPS. Я думал, что вы получите одно, скажем, для 800x600 из нижнего изображения, с min: 5 и max: 99, и это все для 800x600, вы не будете знать ни о каких значениях FPS между 5 и 99. Но у вас есть 6 медиатипов для 800x600, каждый с разным FPS. Это именно то, что я искал, спасибо, что справились с моим отношением :) - person Yellow Ray; 22.06.2015