Nuta
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować się zalogować lub zmienić katalog.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
ujścia multimediów to obiekty potoku odbierające dane multimedialne. Ujście multimediów jest miejscem docelowym dla co najmniej jednego strumienia multimediów. Ujścia multimediów należą do dwóch ogólnych kategorii:
renderer to ujście multimediów, które przedstawia dane do odtwarzania. Ulepszony moduł renderowania wideo (EVR) wyświetla ramki wideo, a renderator audio odtwarza strumienie audio za pośrednictwem karty dźwiękowej lub innego urządzenia audio.
Ujście archiwum to ujście multimediów, które zapisuje dane w pliku lub innym magazynie.
Główną różnicą między nimi jest to, że ujście archiwum nie zużywa danych w stałym tempie odtwarzania. Zamiast tego zapisuje dane odbierane tak szybko, jak to możliwe.
Ujścia multimediów uwidaczniają interfejs IMFMediaSink. Każdy ujście multimediów zawiera co najmniej jeden ujścia strumienia. Każdy ujście strumienia odbiera dane z jednego strumienia. Ujścia strumienia uwidaczniają interfejs IMFStreamSink. Zazwyczaj aplikacja nie tworzy bezpośrednio ujścia multimediów. Zamiast tego aplikacja tworzy co najmniej jeden obiekt aktywacji, którego używa sesja multimediów do utworzenia ujścia. Wszystkie inne operacje na ujściu są obsługiwane przez sesję multimediów, a aplikacja nie wywołuje żadnych metod ujścia multimediów ani żadnego z ujścia strumienia. Aby uzyskać więcej informacji na temat obiektów aktywacji, zobacz Activation Objects.
Pozostałe części tego tematu należy przeczytać, jeśli piszesz niestandardowy ujście multimediów lub jeśli chcesz użyć ujścia multimediów bezpośrednio bez sesji multimediów.
- ujścia strumienia
- zegar prezentacji
- formaty strumienia
- przepływ danych
- znaczniki
- zmiany stanu
- finalizowanie
- zamykanie
- interfejsy ujścia multimediów
- interfejsy ujścia strumienia
- zdarzenia ujścia strumienia
- Tematy pokrewne
Ujścia strumienia
Ujście multimediów może mieć stałą liczbę ujść strumienia lub może obsługiwać dodawanie i usuwanie ujść strumienia. Jeśli ma stałą liczbę ujścia strumienia, IMFMediaSink::GetCharacteristics metoda zwraca flagę MEDIASINK_FIXED_STREAMS. W przeciwnym razie można dodawać i usuwać ujścia strumienia. Aby dodać nowy ujście strumienia, wywołaj metodę IMFMediaSink::AddStreamSink. Aby usunąć ujście strumienia, wywołaj metodę IMFMediaSink::RemoveStreamSink. Flaga MEDIASINK_FIXED_STREAMS wskazuje, że ujście multimediów nie obsługuje tych dwóch metod. (Może obsługiwać inny sposób konfigurowania liczby strumieni, na przykład przez ustawienie parametrów inicjowania podczas tworzenia ujścia). Lista ujściów strumienia jest uporządkowana. Aby wyliczyć je według wartości indeksu, wywołaj metodę IMFMediaSink::GetStreamSinkByIndex.
Ujścia strumienia mają również identyfikatory. Identyfikatory strumienia są unikatowe w ujściu multimediów, ale nie muszą być kolejne. W zależności od ujścia multimediów identyfikatory strumienia mogą mieć pewne znaczenie związane z zawartością. Na przykład ujście archiwum może zapisywać identyfikatory strumienia w nagłówku pliku. W przeciwnym razie są one dowolne. Aby uzyskać ujście strumienia według jego identyfikatora, wywołaj IMFMediaSink::GetStreamSinkById.
Zegar prezentacji
Szybkość, z jaką ujście multimediów zużywa próbki, jest kontrolowana przez zegar prezentacji . Sesja multimediów wybiera zegar prezentacji i ustawia go na ujściu multimediów, wywołując IMFMediaSink::SetPresentationClock metody. Zegar prezentacji musi być ustawiony na ujściu multimediów przed rozpoczęciem przesyłania strumieniowego. Każdy ujście multimediów wymaga uruchomienia zegara prezentacji. Ujście multimediów używa zegara prezentacji do dwóch celów:
Aby otrzymywać powiadomienia podczas uruchamiania lub zatrzymywania przesyłania strumieniowego. Ujście multimediów odbiera te powiadomienia za pośrednictwem interfejsu IMFClockStateSink, który musi implementować wszystkie ujścia multimediów.
Aby określić, kiedy powinny być renderowane przykłady. Gdy ujście multimediów odbiera nowy przykład, pobiera sygnaturę czasową z przykładu i próbuje renderować próbkę w tym czasie prezentacji.
Zegar prezentacji pochodzi zegar z innego obiektu o nazwie źródła czasu prezentacji. Źródła czasu prezentacji udostępniają interfejs IMFPresentationTimeSource. Niektóre ujścia multimediów mają dostęp do dokładnego zegara, więc uwidaczniają ten interfejs. Oznacza to, że ujście multimediów może planować próbki w czasie dostarczonym przez własny zegar. Jednak ujście mediów nie może zakładać, że tak jest. Zawsze musi używać czasu z zegara prezentacji, niezależnie od tego, czy zegar prezentacji jest sterowany przez sam ujście multimediów, czy przez jakiś inny zegar.
Jeśli ujście multimediów nie może dopasować stawek z zegarem innym niż własny, GetCharacteristics metoda zwraca flagę MEDIASINK_CANNOT_MATCH_CLOCK. Jeśli ta flaga jest obecna, a zegar prezentacji używa innego źródła czasu prezentacji, ujście multimediów może działać źle. Na przykład może to spowodować usterki podczas odtwarzania.
sink to ujście multimediów, które ignoruje sygnatury czasowe próbek i zużywa dane natychmiast po nadejściu każdej próbki. Ujście multimediów rateless zwraca flagę MEDIASINK_RATELESS z metody GetCharacteristics. Zazwyczaj ta flaga ma zastosowanie do zlewów archiwum. Jeśli każdy ujście multimediów w potoku jest szybki, sesja multimediów używa specjalnego zegara prezentacji bez szybkości. Ten zegar działa tak szybko, jak ujścia zużywają próbki.
Formaty strumieni
Zanim ujście nośnika będzie mógł odbierać próbki, klient musi ustawić typ nośnika w ujściach strumienia. Aby ustawić typ nośnika, wywołaj metodęIMFStreamSink::GetMediaTypeHandler ujścia strumienia. Ta metoda zwraca wskaźnik do interfejsuIMFMediaTypeHandler. Użyj tego interfejsu, aby uzyskać listę preferowanych typów multimediów, pobrać bieżący typ nośnika i ustawić typ nośnika.
Aby uzyskać listę preferowanych typów multimediów, wywołaj metodę IMFMediaTypeHandler::GetMediaTypeByIndex. Preferowane typy należy traktować jako wskazówkę dla klienta. Lista może być niekompletna lub zawierać częściowe typy multimediów. Typ częściowego nośnika to taki, który nie ma wszystkich atrybutów potrzebnych do opisania prawidłowego formatu. Na przykład częściowy typ wideo może określać przestrzeń kolorów i głębokość bitów, ale nie szerokość lub wysokość obrazu. Częściowy typ dźwięku może określać format kompresji i częstotliwość próbkowania, ale nie liczbę kanałów audio.
Aby uzyskać bieżący typ nośnika ujścia strumienia, wywołaj metodę IMFMediaTypeHandler::GetCurrentMediaTypeType. Po pierwszym utworzeniu ujścia strumienia może on mieć już ustawiony domyślny typ nośnika lub nie ma żadnego typu nośnika, dopóki klient go nie ustawi.
Aby ustawić typ nośnika, wywołaj metodę IMFMediaTypeHandler::SetCurrentMediaTypeType. Niektóre ujścia strumienia mogą nie obsługiwać zmiany typu po ustawieniu. Dlatego warto przetestować typy multimediów przed ich ustawieniem. Aby sprawdzić, czy ujście multimediów zaakceptuje typ nośnika (bez ustawienia typu), wywołaj metodę IMFMediaTypeHandler::IsMediaTypeSupported.
Przepływ danych
Ujścia multimediów używają modelu ściągania , co oznacza, że ujścia strumienia żądają danych w miarę ich potrzeb. Klient powinien reagować w odpowiednim czasie, aby uniknąć jakichkolwiek swędzenia.
Niektóre ujścia multimediów obsługują wstępne. Wstępne wyrejestrowanie to proces przekazywania danych do ujścia multimediów przed rozpoczęciem zegara prezentacji. Jeśli ujście multimediów obsługuje wstępne wyrejestrowanie, ujście multimediów uwidacznia interfejs IMFMediaSinkPreroll i getCharacteristics metoda zwraca flagę MEDIASINK_CAN_PREROLL. Wstępne wyrejestrowanie gwarantuje, że ujście multimediów jest gotowe do przedstawienia pierwszego przykładu po uruchomieniu zegara prezentacji. Zaleca się, aby klient zawsze prerollować, jeśli ujście nośnika go obsługuje, ponieważ może zapobiec gl swędzenie lub przerwy podczas odtwarzania.
Przepływ danych do ujścia multimediów działa w następujący sposób:
- Klient ustawia typy multimediów i zegar prezentacji. Ujście multimediów rejestruje się w zegarze prezentacji, aby otrzymywać powiadomienia o zmianach stanu zegara.
- Opcjonalnie klient wysyła zapytania dotyczące IMFMediaSinkPreroll. Jeśli ujście multimediów uwidacznia ten interfejs, klient wywołuje IMFMediaSinkPreroll::NotifyPreroll. W przeciwnym razie klient pominie krok 5.
- Każdy ujście strumienia wysyła co najmniej jedno zdarzenie MEStreamSinkRequestSample. W odpowiedzi na każde z tych zdarzeń klient pobiera kolejną próbkę danych dla tego strumienia i wywołuje IMFStreamSink::P rocessSample.
- Gdy każdy ujście strumienia odbiera wystarczającą ilość danych wstępnych, wysyła zdarzenie MEStreamSinkPrerolled.
- Klient wywołuje IMFPresentationClock::Start, aby rozpocząć zegar prezentacji.
- Zegar prezentacji powiadamia ujście multimediów, że zegar jest uruchamiany, wywołując IMFClockStateSink::OnClockStart.
- Aby uzyskać więcej danych, każdy ujście strumienia wysyła MEStreamSinkRequestSample zdarzeń. W odpowiedzi na każde z tych zdarzeń klient pobiera następny przykład i wywołuje ProcessSample. Ten krok jest powtarzany do momentu zakończenia prezentacji.
Większość ujść multimediów przetwarza próbki asynchronicznie, więc ujścia strumienia mogą wysyłać więcej niż jedno przykładowe żądanie naraz.
Podczas przesyłania strumieniowego klient może wywołać IMFStreamSink::P laceMarker i IMFStreamSink::Flush w dowolnym momencie. Znaczniki są opisane w następnej sekcji. Opróżnianie powoduje, że ujście strumienia upuszcza wszystkie próbki, które zostały jeszcze w kolejce, ale nie zostały jeszcze renderowane.
Znaczniki
Znaczniki umożliwiają klientowi wskazanie określonych punktów w strumieniu. Znacznik składa się z następujących informacji:
- Typ znacznika zdefiniowany jako element członkowski wyliczenia MFSTREAMSINK_MARKER_TYPE.
- Dane skojarzone ze znacznikiem. Znaczenie danych zależy od typu znacznika. Niektóre typy znaczników nie mają danych.
- Opcjonalne dane dotyczące własnego użycia klienta.
Aby umieścić znacznik, klient wywołuje IMFStreamSink::P laceMarker. Ujście strumienia kończy przetwarzanie wszystkich próbek odebranych przed wywołaniem placemarker, a następnie wysyła zdarzenie MEStreamSinkMarker.
Większość ujść multimediów utrzymuje kolejkę oczekujących próbek, które przetwarzają asynchronicznie. Zdarzenia znaczników muszą być serializowane przy użyciu przetwarzania próbek, więc ujście multimediów powinno umieścić znaczniki w tej samej kolejce. Załóżmy na przykład, że klient wykonuje następujące wywołania metody:
- ProcessSample (przykład nr 1)
- ProcessSample (przykład nr 2)
- PlaceMarker (znacznik #1)
- ProcessSample (przykład nr 3)
- PlaceMarker (znacznik #2)
W tym przykładzie ujście strumienia musi wysłać zdarzenie MEStreamSinkMarker dla znacznika #1 po jego przetwarzaniu próbki #2, a zdarzenie dla znacznika 2 po jego przetwarzaniu próbki #3.
Jeśli klient opróżnia ujście strumienia, ujście strumienia natychmiast przetwarza wszelkie znaczniki, które znajdowały się w kolejce. Ustawia kod stanu E_ABORT na te zdarzenia.
Niektóre znaczniki zawierają informacje istotne dla ujścia multimediów:
- MFSTREAMSINK_MARKER_TICK: wskazuje, że w strumieniu występuje luka. Następna próbka będzie przestać działać.
- MFSTREAMSINK_MARKER_ENDOFSEGMENT: wskazuje koniec segmentu lub koniec strumienia. Następny przykład (jeśli istnieje) może być zaprzestaniem działania.
- MFSTREAMSINK_MARKER_EVENT: zawiera zdarzenie. W zależności od typu zdarzenia i implementacji ujścia multimediów ujście nośnika może obsłużyć zdarzenie lub zignorować je.
Zmiany stanu
Ujście multimediów jest powiadamiane o zmianach stanu w zegarze prezentacji za pośrednictwem IMFClockStateSink interfejsu. Gdy klient ustawia zegar prezentacji, ujście multimediów wywołuje IMFPresentationClock::AddClockStateSink zarejestrować się na potrzeby powiadomień z zegara. W poniższej tabeli podsumowano zachowanie ujścia multimediów w odpowiedzi na zmiany stanu zegara.
| Zmiana stanu zegara | Przykładowe przetwarzanie | Przetwarzanie znaczników |
|---|---|---|
| OnClockStart | Próbki procesów, których sygnatura czasowa jest równa lub późniejsza niż godzina rozpoczęcia zegara. | Wyślij zdarzenie MEStreamSinkMarker, gdy wszystkie próbki odebrane przed przetworzeniem znacznika. |
| OnClockPause | Ujście multimediów może zakończyć się niepowodzeniem ProcessSample podczas wstrzymania. Jeśli ujście multimediów akceptuje próbki podczas wstrzymania, musi je w kolejce do czasu ponownego uruchomienia zegara. Nie przetwarzaj żadnych przykładów w kolejce podczas wstrzymania. |
Jeśli istnieją próbki umieszczone w kolejce, umieść znaczniki w tej samej kolejce. Wyślij zdarzenie znacznika po ponownym uruchomieniu zegara. W przeciwnym razie wyślij zdarzenie znacznika natychmiast. |
| OnClockRestart | Przetwórz wszystkie próbki, które zostały w kolejce podczas wstrzymania, a następnie traktuj je tak samo jak OnClockStart. | Wyślij zdarzenia MEStreamSinkMarker dla znaczników w kolejce (serializowane z przetwarzaniem próbek), a następnie traktuj je tak samo jak OnClockStart. |
| OnClockStop | Porzucanie wszystkich przykładów w kolejce. Dalsze wywołania ProcessSample mogą zakończyć się niepowodzeniem. | Wysyłanie zdarzeń znacznika w kolejce. Po kolejnych wywołaniach PlaceMarkerwyślij zdarzenie znacznika natychmiast. |
Ponadto ujścia strumienia muszą wysyłać następujące zdarzenia po zakończeniu przejścia stanu:
- OnClockStart, OnClockRestart: MEStreamSinkStarted zdarzenie
- OnClockPause: MEStreamSinkPaused zdarzenie
- OnClockStop: MEStreamSinkStopped zdarzenie
Finalizacji
Niektóre ujścia multimediów wymagają dodatkowego kroku przetwarzania po dostarczeniu ostatniej próbki. Zazwyczaj to wymaganie dotyczy ujść archiwum, które muszą zapisywać nagłówki lub indeksy w pliku. Jeśli ujście multimediów wymaga ostatecznego przetwarzania, uwidacznia interfejs IMFFinalizableMediaSink.
Gdy klient dostarczy ostatni przykład, klient wykonuje zapytania dotyczące tego interfejsu. Jeśli ujście multimediów obsługuje interfejs, klient wywołuje IMFFinalizableMediaSink::BeginFinalize, aby wykonać końcowe przetwarzanie asynchronicznie. Ta metoda jest zgodna ze standardowym modelem asynchronicznym programu Media Foundation opisanym w Asynchroniczne metody wywołania zwrotnego. Ujście multimediów może zakładać, że klient wywoła BeginFinalize. Nie można wywołać BeginFinalize może spowodować niepoprawnie utworzony plik.
Zamykanie
Po zakończeniu korzystania z ujścia multimediów klient wywołuje IMFMediaSink::Shutdown. Wewnątrz tej metody ujście multimediów powinno przerwać wszystkie cykliczne liczby odwołań. Zazwyczaj między ujściem nośnika a ujściami strumienia będą odwoływale cykliczne.
Jeśli używasz obiektu pomocnika kolejki zdarzeń do zaimplementowania IMFMediaEventGenerator, wywołaj IMFMediaEventQueue::Shutdown w kolejce zdarzeń. Ta metoda wyłącza kolejkę zdarzeń i sygnalizuje wszelkie wywołujące, które obecnie oczekuje na zdarzenie.
Po zamknięciu wszystkie metody ujścia nośnika zwracają MF_E_SHUTDOWN, z wyjątkiem metod IUnknown.
Interfejsy ujścia multimediów
W poniższej tabeli wymieniono standardowe interfejsy, które ujścia multimediów mogą uwidaczniać za pośrednictwem QueryInterface. Ujścia multimediów mogą również uwidaczniać interfejsy niestandardowe.
| Interfejs | Opis |
|---|---|
| MFWMediaSink | Podstawowy interfejs ujścia multimediów. (Wymagane). |
| IMFClockStateSink | Służy do powiadamiania ujścia multimediów, gdy zegar prezentacji zmienia stan. (Wymagane). |
| MFWFinalizableMediaSink | Zaimplementuj, jeśli ujście multimediów musi wykonać końcowy krok przetwarzania. (Opcjonalnie). |
| IMFGetService | Zaimplementuj, jeśli ujście multimediów uwidacznia interfejsy usługi. (Opcjonalnie). |
| IMFMediaEventGenerator | Zaimplementuj, jeśli ujście multimediów wysyła jakiekolwiek zdarzenia. (Opcjonalnie). |
| IMFMediaSinkPreroll | Zaimplementuj, jeśli ujście multimediów obsługuje wstępne wyrejestrowanie. (Opcjonalnie). |
| IMFPresentationTimeSource | Zaimplementuj, jeśli ujście multimediów może zapewnić źródło czasu zegara prezentacji. (Opcjonalnie). |
| IMFQualityAdvise | Zaimplementuj, jeśli ujście multimediów może dostosować jakość odtwarzania. (Opcjonalnie). |
Opcjonalnie ujście multimediów może zaimplementować następujący interfejs jako usługa.
| Interfejs usługi | Opis |
|---|---|
| IMFRateSupport | Raportuje zakres obsługiwanych współczynników odtwarzania. |
Aby uzyskać więcej informacji na temat interfejsów usług i IMFGetService, zobacz interfejsy usługi .
Interfejsy ujścia strumienia
Ujścia strumienia muszą uwidocznić następujące interfejsy za pośrednictwem QueryInterface.
| Interfejs | Opis |
|---|---|
| IMFStreamSink | Podstawowy interfejs ujścia strumienia. (Wymagane). |
| IMFMediaEventGenerator | Kolejki zdarzeń. Interfejs IMFStreamSink dziedziczy ten interfejs. (Wymagane). |
Obecnie żadne interfejsy usługi nie są zdefiniowane dla ujścia strumienia.
Zdarzenia ujścia strumienia
W poniższej tabeli wymieniono zdarzenia zdefiniowane dla ogólnych ujściów strumienia. Ujścia strumienia mogą również wysyłać zdarzenia niestandardowe, które nie są wymienione tutaj.
| Zdarzenie | Opis |
|---|---|
| MEStreamSinkFormatChanged | Typ nośnika ujścia strumienia nie jest już prawidłowy. (Opcjonalnie). |
| MEStreamSinkMarker | Przetworzony został znacznik. (Wymagane). |
| MEStreamSinkPaused | Ujście strumienia zostało wstrzymane. (Wymagane). |
| MEStreamSinkPrerolled | Wstępne wyrejestrowanie zostało ukończone. (Opcjonalnie). |
| MEStreamSinkRateChanged | Ujście strumienia zmieniło częstotliwość odtwarzania. (Opcjonalnie). |
| MEStreamSinkRequestSample | Zażądano nowego przykładu. (Wymagane). |
| MEStreamSinkScrubSampleComplete | Ukończono żądanie czyszczenia. (Opcjonalnie). |
| MEStreamSinkStarted | Rozpoczęto ujście strumienia. (Wymagane). |
| MEStreamSinkStopped | Ujście strumienia zostało zatrzymane. (Wymagane). |
Obecnie nie zdefiniowano zdarzeń ogólnego przeznaczenia dla ujściów multimediów. Niektóre ujścia multimediów mogą wysyłać zdarzenia niestandardowe.
Tematy pokrewne
-
architektura Media Foundation