Udostępnij przez


Krok 4. Ustaw właściwości alokatora

[Funkcja skojarzona z tą stroną, DirectShow, jest starszą funkcją. Zastępują go 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 korzystał z MediaPlayer, IMFMediaEngine i Audio/Video Capture w frameworku 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 4 samouczka Pisanie filtrów przekształceń.

Notatka

Ten krok nie jest wymagany w przypadku filtrów pochodzących z CTransInPlaceFilter.

 

Po ustaleniu przez dwa piny typu nośnika, wybierają alokator dla połączenia i negocjują właściwości alokatora, takie jak rozmiar buforu oraz liczba buforów.

W klasie CTransformFilter istnieją dwa alokatory, jeden dla wejściowego połączenia PIN i jeden dla wyjściowego połączenia PIN. Filtr nadrzędny wybiera nadrzędny alokator, a także wybiera właściwości alokatora. Pin wejściowy akceptuje to, co decyduje filtr źródłowy. Jeśli chcesz zmodyfikować to zachowanie, przesłoń metodę CBaseInputPin::NotifyAllocator.

Pin wyjściowy filtru przekształceń wybiera dalszy alokator. Wykonuje następujące czynności:

  1. Jeśli filtr podrzędny może zapewnić alokator, wyprowadzenie wyjściowe używa tego. W przeciwnym razie pin wyjściowy tworzy nowy alokator.
  2. Wyjściowa nóżka uzyskuje wymagania alokatora filtru odbierającego (jeśli istnieją), wywołując IMemInputPin::GetAllocatorRequirements.
  3. Wyprowadzanie danych wyjściowych wywołuje metodę filtru CTransformFilter::D ecideBufferSize, która jest czysta wirtualna. Parametry tej metody obejmują wskaźnik do alokatora oraz strukturę ALLOCATOR_PROPERTIES, która spełnia wymagania filtru podrzędnego. Jeśli filtr podrzędny nie ma wymagań alokatora, struktura jest wyzerowana.
  4. W metodzie DecideBufferSize klasa pochodna ustawia właściwości alokatora, wywołując metodę IMemAllocator::SetProperties.

Ogólnie rzecz biorąc, klasa pochodna wybierze właściwości alokatora na podstawie formatu wyjściowego, wymagań filtru podrzędnego i własnych wymagań filtru. Spróbuj wybrać właściwości zgodne z żądaniem filtru podrzędnego. W przeciwnym razie filtr podrzędny może odrzucić połączenie.

W poniższym przykładzie koder RLE ustawia minimalne wartości dla rozmiaru buforu, wyrównania buforu i liczby buforów. W przypadku prefiksu używa dowolnej wartości żądanego filtru podrzędnego. Prefiks to zazwyczaj zero bajtów, ale niektóre filtry tego wymagają. Na przykład filtr AVI Mux używa prefiksu do zapisywania nagłówków RIFF.

HRESULT CRleFilter::DecideBufferSize(
    IMemAllocator *pAlloc, ALLOCATOR_PROPERTIES *pProp)
{
    AM_MEDIA_TYPE mt;
    HRESULT hr = m_pOutput->ConnectionMediaType(&mt);
    if (FAILED(hr))
    {
        return hr;
    }

    ASSERT(mt.formattype == FORMAT_VideoInfo);
    BITMAPINFOHEADER *pbmi = HEADER(mt.pbFormat);
    pProp->cbBuffer = DIBSIZE(*pbmi) * 2; 
    if (pProp->cbAlign == 0)
    {
        pProp->cbAlign = 1;
    }
    if (pProp->cBuffers == 0)
    {
        pProp->cBuffers = 1;
    }
    // Release the format block.
    FreeMediaType(mt);

    // Set allocator properties.
    ALLOCATOR_PROPERTIES Actual;
    hr = pAlloc->SetProperties(pProp, &Actual);
    if (FAILED(hr)) 
    {
        return hr;
    }
    // Even when it succeeds, check the actual result.
    if (pProp->cbBuffer > Actual.cbBuffer) 
    {
        return E_FAIL;
    }
    return S_OK;
}

Alokator może nie być w stanie dokładnie dopasować żądania. W związku z tym metoda SetProperties zwraca rzeczywisty wynik w oddzielnej strukturze ALLOCATOR_PROPERTIES (parametr Actual w poprzednim przykładzie). Nawet gdy SetProperties zakończy się sukcesem, należy sprawdzić wynik, aby upewnić się, że spełnia minimalne wymagania filtru.

niestandardowych alokatorów

Domyślnie wszystkie klasy filtrów używają klasy CMemAllocator jako alokatorów. Ta klasa przydziela pamięć z wirtualnej przestrzeni adresowej procesu klienta (przy użyciu VirtualAlloc). Jeśli filtr musi używać innego rodzaju pamięci, takiego jak powierzchnie DirectDraw, możesz zaimplementować niestandardowy alokator. Możesz użyć klasy CBaseAllocator lub napisać zupełnie nową klasę alokatora. Jeśli filtr ma niestandardowy alokator, przesłoń następujące metody, w zależności od tego, który numer PIN używa alokatora:

Jeśli inny filtr odmówi nawiązania połączenia przy użyciu niestandardowego alokatora, Twój filtr może albo nie nawiązać połączenia, albo połączyć się z alokatorem innego filtru. W drugim przypadku może być konieczne ustawienie flagi wewnętrznej wskazującej typ alokatora. Aby zapoznać się z przykładem tego podejścia, zobacz klasa CDrawImage.

Następnie: Krok 5. Przekształć obraz.

Tworzenie filtrów DirectShow