Udostępnij przez


Przetwarzanie danych w DMO

[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. Microsoft zdecydowanie zaleca, aby nowy kod używał MediaPlayer, IMFMediaEngine i Audio/Video Capture w platformie 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 tej sekcji opisano sposób przetwarzania strumienia danych przy użyciu dmo. Czynności wymienione w tej sekcji są zachowaniem domyślnym; wszystkie obiekty DMO muszą obsługiwać metody opisane tutaj. Te metody używają oddzielnych buforów dla danych wejściowych i wyjściowych. Niektóre DMO obsługują również przetwarzanie lokalne przy użyciu pojedynczego buforu. Aby uzyskać więcej informacji na temat przetwarzania w miejscu, zobacz In-Place Processing.

przydzielanie buforów

Klient jest odpowiedzialny za całą alokację buforu. Po skonfigurowaniu typów nośników w obiekcie DMO, wykonaj zapytanie do DMO o wymagania dotyczące buforu dla każdego strumienia. Mogą one ulec zmianie w zależności od typu nośnika. Dla każdego strumienia wywołaj metodę IMediaObject::GetInputSizeInfo lub IMediaObject::GetOutputSizeInfo. Te metody zwracają następujące informacje:

  • Minimalny rozmiar buforu w bajtach.
  • Wymagania dotyczące wyrównania, jeśli istnieją. Bufor jest wyrównany, jeśli adres początkowy jest wielokrotnością określonej liczby całkowitej.
  • Maksymalna ilość danych, które będą przechowywane przez DMO na potrzeby wyprzedzenia. Ta liczba ma zastosowanie tylko do strumieni wejściowych. W przypadku niektórych rodzajów danych (na przykład kodowanie MPEG), DMO może potrzebować przeanalizować przyszłe dane w strumieniu. Wartość przewidywania (lookahead) wskazuje, ile danych wejściowych będzie potrzebnych DMO, aby mogło wygenerować dane wyjściowe.

Klient musi przydzielić bufory, które spełniają te wymagania. Ponadto dmo może mieć wymagania dotyczące sposobu, w jaki klient pakuje dane wejściowe. Na przykład DMO może wymagać, aby każdy bufor zawierał dokładnie jedną próbkę (lub ramkę wideo). Aby określić te wymagania, wywołaj metodę IMediaObject::GetInputStreamInfo. Metoda IMediaObject::GetOutputStreamInfo zwraca podobne informacje o strumieniu wyjściowym.

W domyślnym modelu przesyłania strumieniowego klient nie przekazuje surowych wskaźników bufora do DMO. Zamiast tego używa uproszczonego obiektu COM, który uwidacznia interfejsIMediaBuffer. Interfejs IMediaBuffer współdziała jako opakowanie COM dla bloku pamięci. Ponieważ jest to obiekt COM, obsługuje zliczanie odwołań, co pomaga upewnić się, że bufory nie są zwalniane, gdy są nadal używane.

Notatka

Interfejs IMediaBuffer obsługuje funkcję podobną do interfejsu IMediaSample w directshow.

 

Klient musi zaimplementować obiekt IMediaBuffer. Aby uzyskać więcej informacji, zobacz Implementowanie IMediaBuffer.

Przetwarzanie Danych

Aby przetworzyć dane, wykonaj następujące czynności:

  1. Dla każdego strumienia wejściowego wypełnij bufor danymi wejściowymi.
  2. Wywołaj IMediaObject::ProcessInput, aby dostarczyć każdy bufor.
  3. Wywołaj IMediaObject::ProcessOutput, aby przetworzyć dane. Ta metoda przyjmuje tablicę buforów, po jednym dla każdego strumienia wyjściowego.
  4. Powtarzaj, dopóki nie będzie więcej danych wejściowych.

Metoda ProcessInput akceptuje dane wejściowe dla jednego strumienia naraz. Zazwyczaj metoda zwraca natychmiast, a obiekt DMO przechowuje liczbę referencji dla obiektu IMediaBuffer. Zwalnia obiekt po przetworzeniu wszystkich danych w buforze lub gdy aplikacja opróżnia DMO. Nie należy ponownie używać buforu, dopóki DMO go nie zwolni. Aby określić, czy strumień wejściowy może akceptować więcej danych, wywołaj metodę IMediaObject::GetInputStatus. Ta metoda zwraca flagę DMO_INPUT_STATUSF_ACCEPT_DATA, jeśli strumień może zaakceptować więcej danych wejściowych.

Metoda ProcessOutput generuje dane wyjściowe dla wszystkich strumieni wyjściowych jednocześnie. Aplikacja przekazuje tablicę struktur DMO_OUTPUT_DATA_BUFFER, po jednej dla każdego strumienia wyjściowego. Każda struktura tablicy ma wskaźnik do obiektu IMediaBuffer. DMO zapisuje tyle danych wyjściowych, ile może, do buforów. Ustawia również różne flagi, aby zgłosić stan operacji. Flaga DMO_OUTPUT_DATA_BUFFERF_INCOMPLETE wskazuje, że DMO może wygenerować więcej danych wyjściowych z istniejących danych wejściowych. W takim przypadku klient może ponownie wywołać ProcessOutput. W przeciwnym razie powinno wywołać ProcessInput z większą ilością danych wejściowych. Funkcja DMO nigdy nie modyfikuje danych w buforach wejściowych; zapisuje tylko w buforach wyjściowych.

Po dostarczeniu wszystkich danych do strumienia wejściowego wywołaj metodę IMediaObject::Discontinuity. DMO nie akceptuje dalszych danych wejściowych do tego strumienia, dopóki nie zostaną przetworzone pozostałe dane wyjściowe (lub opróżnij DMO).

W dowolnym momencie po rozpoczęciu przesyłania strumieniowego dmo może odbierać dane wejściowe lub generować dane wyjściowe albo oba te elementy. W związku z tym, albo GetInputStatus zwraca DMO_INPUT_STATUSF_ACCEPT_DATA, albo ProcessOutput zwraca DMO_OUTPUT_DATA_BUFFERF_INCOMPLETE. Aplikacja utrzymuje ciągłość przepływu danych, testując te flagi i wywołując ProcessInput lub ProcessOutput stosownie. Aby przerwać przepływ danych, wywołaj metodę IMediaObject::Flush. Ta metoda powoduje, że DMO odrzuca wszystkie bufory, które przechowuje wewnętrznie.

Bezpośrednie hostowanie DMO

In-Place Przetwarzanie