Шаг 3A. Реализация метода CheckInputType

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

Это шаг 3A учебника Написание фильтров преобразования.

Метод CTransformFilter::CheckInputType вызывается, когда фильтр вышестоящий предлагает фильтру преобразования тип носителя. Этот метод принимает указатель на объект CMediaType , который является тонкой оболочкой для структуры AM_MEDIA_TYPE . В этом методе следует изучить все соответствующие поля структуры AM_MEDIA_TYPE , включая поля в блоке форматирования. Можно использовать методы доступа, определенные в CMediaType, или ссылаться непосредственно на члены структуры. Если какое-либо поле не является допустимым, верните VFW_E_TYPE_NOT_ACCEPTED. Если весь тип носителя является допустимым, верните S_OK.

Например, в фильтре кодировщика RLE тип входных данных должен быть 8-разрядным или 4-разрядным несжатой RGB-видео. Нет причин для поддержки других форматов ввода, таких как 16- или 24-разрядный RGB, так как фильтру придется преобразовать их в меньшую глубину бита, а DirectShow уже предоставляет фильтр Color Space Converter для этой цели. В следующем примере предполагается, что кодировщик поддерживает 8-разрядное видео, но не 4-разрядное видео:

HRESULT CRleFilter::CheckInputType(const CMediaType *mtIn)
{
    if ((mtIn->majortype != MEDIATYPE_Video) ||
        (mtIn->subtype != MEDIASUBTYPE_RGB8) ||
        (mtIn->formattype != FORMAT_VideoInfo) || 
        (mtIn->cbFormat < sizeof(VIDEOINFOHEADER)))
    {
        return VFW_E_TYPE_NOT_ACCEPTED;
    }

    VIDEOINFOHEADER *pVih = 
        reinterpret_cast<VIDEOINFOHEADER*>(mtIn->pbFormat);
    if ((pVih->bmiHeader.biBitCount != 8) ||
        (pVih->bmiHeader.biCompression != BI_RGB))
    {
        return VFW_E_TYPE_NOT_ACCEPTED;
    }

    // Check the palette table.
    if (pVih->bmiHeader.biClrUsed > PALETTE_ENTRIES(pVih))
    {
        return VFW_E_TYPE_NOT_ACCEPTED;
    }
    DWORD cbPalette = pVih->bmiHeader.biClrUsed * sizeof(RGBQUAD);
    if (mtIn->cbFormat < sizeof(VIDEOINFOHEADER) + cbPalette)
    {
        return VFW_E_TYPE_NOT_ACCEPTED;
    }

    // Everything is good.
    return S_OK;
}

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

Если тип формата правильный, в примере проверяются члены biBitCount и biCompression структуры VIDEOINFOHEADER , чтобы убедиться, что формат имеет 8-разрядный формат RGB без сжатия. Как показано в этом примере, необходимо прину

pbFormat

указатель на правильную структуру в зависимости от типа формата. Всегда проверка guid типа формата (formattype) и размер блока форматирования (cbFormat) перед приведением указателя.

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

Далее: Шаг 3B. Реализация метода GetMediaType.

Написание фильтров DirectShow