Udostępnij za pośrednictwem


Krok 3A. Implementowanie metody CheckInputType

[Funkcja skojarzona z tą stroną, DirectShow, jest starszą funkcją. Zostały zastąpione przez MediaPlayer, IMFMediaEnginei Audio/Video Capture w Media Foundation. Te funkcje zostały zoptymalizowane pod kątem systemów Windows 10 i Windows 11. Firma Microsoft zdecydowanie zaleca, aby nowy kod używał MediaPlayer, IMFMediaEngine i Audio/Video Capture w programie Media Foundation zamiast DirectShow, jeśli to możliwe. Firma Microsoft sugeruje, że istniejący kod, który używa starszych interfejsów API, należy przepisać go do korzystania z nowych interfejsów API, jeśli to możliwe.]

Jest to krok 3A samouczka Pisanie filtrów transformacji.

Metoda CTransformFilter::CheckInputType jest wywoływana, gdy filtr nadrzędny proponuje typ nośnika do filtru przekształcenia. Ta metoda przyjmuje wskaźnik do obiektu CMediaType, który jest cienką otoką struktury AM_MEDIA_TYPE. W tej metodzie należy zbadać każde odpowiednie pole struktury AM_MEDIA_TYPE, w tym pola w bloku formatu. Można skorzystać z metod dostępu zdefiniowanych w CMediaTypelub odwołać się bezpośrednio do składowych struktury. Jeśli jakiekolwiek pole jest nieprawidłowe, zwróć VFW_E_TYPE_NOT_ACCEPTED. Jeśli cały typ nośnika jest prawidłowy, zwróć S_OK.

Na przykład w filtrze kodera RLE typ wejściowy musi być 8-bitowy lub 4-bitowy nieskompresowany wideo RGB. Nie ma powodu, aby obsługiwać inne formaty wejściowe, takie jak 16-lub 24-bitowy RGB, ponieważ filtr musiałby przekonwertować je na niższą głębokość bitów, a DirectShow udostępnia już Color Space Converter filtr do tego celu. W poniższym przykładzie przyjęto założenie, że koder obsługuje 8-bitowe wideo, ale nie 4-bitowe wideo:

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;
}

W tym przykładzie metoda najpierw sprawdza typ główny i podtyp. Następnie sprawdza typ formatu, aby upewnić się, że blok formatu jest strukturą VIDEOINFOHEADER. Filtr może również obsługiwać VIDEOINFOHEADER2, ale w tym przypadku nie przyniosłoby to żadnych rzeczywistych korzyści. Struktura VIDEOINFOHEADER2 dodaje obsługę przeplotu i nieskwadratowych pikseli, które prawdopodobnie nie będą istotne w 8-bitowym wideo.

Jeśli typ formatu jest poprawny, przykład sprawdza elementy składowe biBitCount i biCompression struktury VIDEOINFOHEADER, aby upewnić się, że format jest 8-bitowym nieskompresowanym RGB. Jak pokazano w tym przykładzie, musisz wymusić działania

pbFormat

wskaźnik wskazujący na prawidłową strukturę na podstawie rodzaju formatu. Przed rzutowaniem wskaźnika zawsze sprawdź identyfikator GUID formatu (typ formatu) i rozmiar bloku formatu (cbFormat).

Przykład sprawdza również, czy liczba wpisów palety jest zgodna z głębią bitu, a blok formatu jest wystarczająco duży, aby przechowywać wpisy palety. Jeśli wszystkie te informacje są poprawne, metoda zwraca S_OK.

Następnie: Krok 3B. Zaimplementuj metodę GetMediaType.

Tworzenie filtrów DirectShow