Udostępnij przez


Dostarczanie przykładów

[Funkcja skojarzona z tą stroną, DirectShow, jest starszą funkcją. Został zastąpiony 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.]

W tym artykule opisano sposób, w jaki filtr dostarcza przykład. Opisuje on zarówno model wypychania, używając metod IMemInputPin, jak i modelu ściągania przy użyciu IAsyncReader.

Model wypychający : dostarczanie próbki

Pin wyjściowy dostarcza próbkę, wywołując metodę IMemInputPin::Receive lub metodę IMemInputPin::ReceiveMultiple, która jest równoważna, ale dostarcza tablicę próbek. Pin wejściowy może blokować wewnątrz Receive (lub ReceiveMultiple). Jeśli pinezka może blokować, powinna S_OK zostać zwrócona metoda IMemInputPin::ReceiveCanBlock. Jeśli PIN gwarantuje, że nigdy nie będzie blokował, ReceiveCanBlock powinien zwrócić S_FALSE. Wartość zwracana S_OK nie oznacza, że Odbieranie zawsze jest blokowane, tylko że może tak być.

Mimo że Odbieranie może zablokować oczekiwanie na udostępnienie zasobu, nie powinno blokować oczekiwania na więcej danych z filtru nadrzędnego. Może to spowodować zakleszczenie, w którym filtr wyższego rzędu czeka, aż filtr niższego rzędu zwolni próbkę, co nigdy nie następuje, ponieważ filtr niższego rzędu czeka na filtr wyższego rzędu. Jeśli filtr zawiera wiele wyprowadzeń wejściowych, jeden numer PIN może jednak poczekać na odebranie danych przez inny numer PIN. Na przykład filtr AVI Mux robi to, aby móc przeplatać dane audio i wideo.

Pin może odrzucić próbkę z kilku powodów:

  • Pin jest przepłukiwany (zobacz Przepłukiwanie).
  • Pin nie jest podłączony.
  • Filtr jest zatrzymany.
  • Wystąpił inny błąd.

Metoda Receive powinna zwrócić S_FALSE w pierwszym przypadku, a kod niepowodzenia w pozostałych przypadkach. Filtr nadrzędny powinien przestać wysyłać przykłady, gdy kod powrotny jest inny niż S_OK.

Możesz traktować pierwsze trzy przypadki jako "oczekiwane" błędy, w sensie, że filtr był w niewłaściwym stanie, by otrzymywać próbki. Nieoczekiwana awaria może spowodować odrzucenie próbki przez pin, nawet gdy pin jest gotowy do odbioru. Jeśli wystąpi błąd tego typu, pin powinien wysłać powiadomienie o zakończeniu strumienia i wysłać zdarzenie EC_ERRORABORT do Menedżera grafu filtrów.

W klasach bazowych DirectShow metoda CBaseInputPin::CheckStreaming sprawdza typowe przypadki awarii — opróżnianie, zatrzymanie i tak dalej. Klasa pochodna musi sprawdzić błędy specyficzne dla filtru. W przypadku błędu metoda CBaseInputPin::Receive wysyła powiadomienie o zakończeniu strumienia i zdarzenie EC_ERRORABORT.

model ściągania : żądanie przykładowego

W interfejsie IAsyncReader pin wejściowy żąda próbek od pinu wyjściowego przez wywołanie jednej z następujących metod:

Metoda żądania jest asynchroniczna; pin wejściowy wywołuje IAsyncReader::WaitForNext, aby poczekać na zakończenie żądania. Pozostałe dwie metody są synchroniczne.

kiedy dostarczać dane

Filtr zawsze dostarcza próbki, gdy jest w stanie działania. W większości przypadków filtr dostarcza również próbki w czasie wstrzymania. Dzięki temu wykres może podsycić dane, aby odtwarzanie rozpoczynało się natychmiast po wywołaniu Uruchom (zobacz Stany filtru). Jeśli filtr nie dostarcza danych podczas wstrzymania, metoda IMediaFilter::GetState powinna zwrócić VFW_S_CANT_CUE w stanie wstrzymania. Ten kod zwrotny sygnalizuje, że graf filtru nie musi czekać na dane z Twojego filtru przed zakończeniem procesu wstrzymania. W przeciwnym razie metoda Pause będzie blokowana na czas nieokreślony. Aby uzyskać przykładowy kod, zobacz CBaseFilter::GetState.

Poniżej przedstawiono kilka przykładów, w których filtr może być zmuszony zwrócić VFW_S_CANT_CUE:

  • Źródła na żywo, takie jak filtry przechwytywania, nie powinny wysyłać danych w stanie pauzy. Zobacz produkcję danych w filtrze przechwytywania.
  • Filtr podziału może wysyłać lub nie wysyłać danych podczas wstrzymania, w zależności od implementacji. Jeśli filtr używa oddzielnych wątków do kolejkowania danych na każdym pinie wyjściowym, może wysyłać dane nawet wtedy, gdy jest wstrzymany. Jeśli jednak filtr używa pojedynczego wątku dla każdego wyprowadzenia wyjściowego, pierwszy pin może zablokować wątek, gdy wywołuje Receive, co uniemożliwi wysyłanie danych przez inne piny. W takim przypadku należy zwrócić VFW_S_CANT_CUE.
  • Filtr może sporadycznie dostarczać dane. Na przykład może przeanalizować niestandardowy strumień danych i odfiltrować niektóre pakiety podczas dostarczania innych. W takim przypadku nie ma gwarancji, że filtr dostarczy dane podczas pauzy.

Filtr źródłowy (przy użyciu modelu wypychania) lub filtr parsujący (przy użyciu modelu wypychania/ściągania) tworzy co najmniej jeden wątek przesyłania strumieniowego, dostarczający próbki najszybciej jak to możliwe. Filtry podrzędne, takie jak dekodery i przekształcenia, zwykle wysyłają dane tylko wtedy, gdy na ich wyprowadzeniach wejściowych wywoływana jest metoda Receive.

odbieranie i dostarczanie próbek