Поделиться через


Настройка формата вывода видео

[Функция, связанная с этой страницей DirectShow, является устаревшей функцией. Он был заменен MediaPlayer, IMFMediaEngine, и аудио/ видео захвата в Media Foundation. Эти функции оптимизированы для Windows 10 и Windows 11. Корпорация Майкрософт настоятельно рекомендует использовать в новом коде MediaPlayer, IMFMediaEngine и аудио/видеозахват в Media Foundation вместо DirectShow, когда это возможно. Корпорация Майкрософт предлагает переписать существующий код, в котором используются устаревшие API, чтобы по возможности использовать новые API.]

Примечание

Функциональные возможности, описанные в этом разделе, являются устаревшими. Чтобы настроить выходной формат устройства захвата, приложение должно использовать структуру AM_MEDIA_TYPE , возвращаемую IAMStreamConfig::GetFormat в параметре pmt .

 

Устройство захвата может поддерживать ряд форматов вывода. Например, устройство может поддерживать 16-разрядную RGB, 32-разрядную RGB и YUYV. В каждом из этих форматов устройство может поддерживать диапазон размеров кадров.

На устройстве WDM интерфейс IAMStreamConfig используется для создания отчетов о форматах, поддерживаемых устройством, и для задания формата. (Для устаревших устройств VFW используйте диалоговое окно Видеоформат VFW, как описано в разделе Отображение диалоговых окон захвата VFW.) Интерфейс IAMStreamConfig предоставляется в контакте захвата, контакте предварительного просмотра или в обоих вариантах. Используйте метод ICaptureGraphBuilder2::FindInterface , чтобы получить указатель интерфейса:

IAMStreamConfig *pConfig = NULL;
hr = pBuild->FindInterface(
    &PIN_CATEGORY_PREVIEW, // Preview pin.
    0,    // Any media type.
    pCap, // Pointer to the capture filter.
    IID_IAMStreamConfig, (void**)&pConfig);

Устройство имеет список поддерживаемых типов мультимедиа. Для каждого типа мультимедиа устройство также предоставляет набор возможностей. К ним относятся диапазон размеров кадров, доступных для этого формата, то, насколько хорошо устройство может растянуть или сжать изображение, а также диапазон частоты кадров.

Чтобы получить количество типов мультимедиа, вызовите метод IAMStreamConfig::GetNumberOfCapabilities . Метод возвращает два значения:

  • Количество типов мультимедиа.
  • Размер структуры, содержащей сведения о возможностях.

Значение размера необходимо, так как интерфейс IAMStreamConfig используется как для аудио, так и для видео (и может быть расширен на другие типы мультимедиа). Для видео возможности описываются с помощью структуры VIDEO_STREAM_CONFIG_CAPS , а аудио — AUDIO_STREAM_CONFIG_CAPS структуры.

Чтобы перечислить типы мультимедиа, вызовите метод IAMStreamConfig::GetStreamCaps с отсчитываемого от нуля индекса. Метод GetStreamCaps возвращает тип носителя и соответствующую структуру возможностей:

int iCount = 0, iSize = 0;
hr = pConfig->GetNumberOfCapabilities(&iCount, &iSize);

// Check the size to make sure we pass in the correct structure.
if (iSize == sizeof(VIDEO_STREAM_CONFIG_CAPS))
{
    // Use the video capabilities structure.

    for (int iFormat = 0; iFormat < iCount; iFormat++)
    {
        VIDEO_STREAM_CONFIG_CAPS scc;
        AM_MEDIA_TYPE *pmtConfig;
        hr = pConfig->GetStreamCaps(iFormat, &pmtConfig, (BYTE*)&scc);
        if (SUCCEEDED(hr))
        {
            /* Examine the format, and possibly use it. */

            // Delete the media type when you are done.
            DeleteMediaType(pmtConfig);
        }
}

Обратите внимание, как выделяются структуры для метода GetStreamCaps . Метод выделяет структуру типа мультимедиа, а вызывающий объект — структуру возможностей. Приведите структуру возможностей к указателю массива байтов. Завершив работу с типом носителя, удалите структуру AM_MEDIA_TYPE вместе с блоком формата типа мультимедиа.

Вы можете настроить устройство для использования формата, возвращаемого методом GetStreamCaps . Просто вызовите IAMStreamConfig::SetFormat с типом носителя:

hr = pConfig->SetFormat(pmtConfig);

Если контакт не подключен, он попытается использовать этот формат при подключении. Если контакт уже подключен, он пытается повторно подключиться с использованием нового формата. В любом случае нисходящий фильтр может отклонить формат.

Вы также можете изменить тип носителя перед его передачей в метод SetFormat . Именно здесь происходит VIDEO_STREAM_CONFIG_CAPS структура. Здесь описаны все допустимые способы изменения типа мультимедиа. Чтобы использовать эти сведения, необходимо понимать сведения о конкретном типе мультимедиа.

Например, предположим, что GetStreamCaps возвращает 24-разрядный формат RGB с размером кадра 320 x 240 пикселей. Эти сведения можно получить, изучив основной тип, подтип и блок формата типа носителя:

if ((pmtConfig.majortype == MEDIATYPE_Video) &&
    (pmtConfig.subtype == MEDIASUBTYPE_RGB24) &&
    (pmtConfig.formattype == FORMAT_VideoInfo) &&
    (pmtConfig.cbFormat >= sizeof (VIDEOINFOHEADER)) &&
    (pmtConfig.pbFormat != NULL))
{
    VIDEOINFOHEADER *pVih = (VIDEOINFOHEADER*)pmtConfig.pbFormat;
    // pVih contains the detailed format information.
    LONG lWidth = pVih->bmiHeader.biWidth;
    LONG lHeight = pVih->bmiHeader.biHeight;
}

Структура VIDEO_STREAM_CONFIG_CAPS предоставляет минимальную и максимальную ширину и высоту, которые можно использовать для этого типа мультимедиа. Он также предоставляет размер шага, который определяет приращения, с помощью которых можно настроить ширину или высоту. Например, устройство может вернуть следующее:

  • MinOutputSize: 160 x 120
  • MaxOutputSize: 320 x 240
  • OutputGranularityX: 8 пикселей (размер горизонтального шага)
  • OutputGranularityY: 8 пикселей (размер вертикального шага)

Учитывая эти числа, можно задать ширину для чего угодно в диапазоне (160, 168, 176, ... 304, 312, 320) и высота к чему-либо в диапазоне (120, 128, 136, ... 104, 112, 120). Этот процесс представлен на схеме ниже.

размеры видеоформатов

Чтобы задать новый размер кадра, непосредственно измените структуру AM_MEDIA_TYPE , возвращенную в GetStreamCaps:

pVih->bmiHeader.biWidth = 160;
pVih->bmiHeader.biHeight = 120;
pVih->bmiHeader.biSizeImage = DIBSIZE(pVih->bmiHeader);

Затем передайте тип носителя в метод SetFormat , как описано выше.

Элементы MinFrameInterval и MaxFrameIntervalVIDEO_STREAM_CONFIG_CAPS — это минимальная и максимальная длина каждого видеокадра, которую можно преобразовать в частоту кадров следующим образом:

frames per second = 10,000,000 / frame duration

Чтобы запросить определенную частоту кадров, измените значение AvgTimePerFrame в структуре VIDEOINFOHEADER или VIDEOINFOHEADER2 в типе носителя. Устройство может не поддерживать все возможные значения в диапазоне от минимального до максимального, поэтому драйвер будет использовать ближайшее к нему значение. Чтобы узнать, какое значение фактически использовал драйвер, вызовите IAMStreamConfig::GetFormat после вызова SetFormat.

Некоторые драйверы могут указывать значение MAXLONGLONG (0x7FFFFFFFFFFFFFFF) для значения MaxFrameInterval, что фактически означает отсутствие максимальной длительности. Однако вам может потребоваться обеспечить минимальную частоту кадров в приложении, например 1 кадр/с.

Сведения о типах мультимедиа

Настройка устройства захвата видео