Tunelowanie multimediów

Tunelowanie multimediów, zwane też trybem tunelowania, umożliwia przesyłanie skompresowanych danych wideo przez sprzętowy dekoder wideo bezpośrednio na wyświetlacz bez przetwarzania przez kod aplikacji ani kod platformy Android. Kod specyficzny dla urządzenia znajdujący się poniżej stosu Androida określa, które klatki wideo mają być wysyłane na wyświetlacz i kiedy mają być wysyłane. Porównuje on sygnatury czasowe prezentacji klatek wideo z jednym z tych typów zegara wewnętrznego:

  • W przypadku odtwarzania wideo na żądanie na Androidzie 5 lub nowszym – AudioTrack zegar zsynchronizowany z sygnaturami czasowymi prezentacji dźwięku przekazywanymi przez aplikację.

  • W przypadku odtwarzania transmisji na żywo na Androidzie 11 lub nowszym – zegar odniesienia programu (PCR) lub zegar czasu systemowego (STC) sterowany przez tuner

Tło

Odtwarzanie wideo w trybie bez tunelowania na Androidzie powiadamia aplikację, gdy skompresowana klatka wideo zostanie zdekodowana. Aplikacja następnie udostępnia zdekodowaną klatkę wideo wyświetlaczowi, aby była renderowana w tym samym czasie zegara systemowego co odpowiadająca jej klatka audio. Pobiera historyczne AudioTimestamp instancje, aby obliczyć prawidłowy czas.

Ponieważ odtwarzanie wideo w trybie tunelowania omija kod aplikacji i zmniejsza liczbę procesów działających na wideo, może zapewnić bardziej wydajne renderowanie wideo w zależności od implementacji OEM. Może też zapewnić dokładniejszą kadencję wideo i synchronizację z wybranym zegarem (PCR, STC lub audio), unikając problemów z synchronizacją spowodowanych potencjalnym przesunięciem między czasem żądań Androida dotyczących renderowania wideo a czasem rzeczywistych synchronizacji pionowych sprzętu. Tunelowanie może jednak ograniczyć obsługę efektów GPU, takich jak rozmycie lub zaokrąglone rogi w oknach obrazu w obrazie (PiP), ponieważ bufory omijają stos graficzny Androida.

Ten schemat pokazuje, jak tunelowanie upraszcza proces odtwarzania wideo.

porównanie trybów tradycyjnego i tunelowego,

Rysunek 1. Porównanie procesów odtwarzania wideo w trybie bez tunelowania i w trybie tunelowania.

Dla deweloperów aplikacji

Ponieważ większość deweloperów aplikacji integruje się z biblioteką w celu wdrożenia odtwarzania, w większości przypadków wdrożenie wymaga tylko ponownej konfiguracji tej biblioteki na potrzeby odtwarzania w trybie tunelowania. Aby wdrożyć odtwarzacz wideo w trybie tunelowania na niskim poziomie, postępuj zgodnie z tymi instrukcjami.

W przypadku odtwarzania wideo na żądanie na Androidzie 5 lub nowszym:

  1. Utwórz instancję SurfaceView.

  2. Utwórz instancję audioSessionId.

  3. Utwórz instancje AudioTrack i MediaCodec z instancją audioSessionId utworzoną w kroku 2.

  4. Umieść dane audio w kolejce do AudioTrack z sygnaturą czasową prezentacji pierwszej klatki audio w danych audio.

W przypadku odtwarzania transmisji na żywo na Androidzie 11 lub nowszym:

  1. Utwórz instancję SurfaceView.

  2. Pobierz instancję avSyncHwId z Tuner.

  3. Utwórz instancje AudioTrack i MediaCodec z instancją avSyncHwId utworzoną w kroku 2.

Przepływ wywołań interfejsu API jest pokazany w tych fragmentach kodu:

aab.setContentType(AudioAttributes.CONTENT_TYPE_MOVIE);

// configure for audio clock sync
aab.setFlag(AudioAttributes.FLAG_HW_AV_SYNC);
// or, for tuner clock sync (Android 11 or higher)
new tunerConfig = TunerConfiguration(0, avSyncId);
aab.setTunerConfiguration(tunerConfig);
if (codecName == null) {
  return FAILURE;
}

// configure for audio clock sync
mf.setInteger(MediaFormat.KEY_AUDIO_SESSION_ID, audioSessionId);
// or, for tuner clock sync (Android 11 or higher)
mf.setInteger(MediaFormat.KEY_HARDWARE_AV_SYNC_ID, avSyncId);

Zachowanie odtwarzania wideo na żądanie

Ponieważ odtwarzanie wideo na żądanie w trybie tunelowania jest niejawnie powiązane z odtwarzaniem AudioTrack, działanie odtwarzania wideo w trybie tunelowania może zależeć od działania odtwarzania dźwięku.

  • Na większości urządzeń domyślnie klatka wideo nie jest renderowana, dopóki nie rozpocznie się odtwarzanie dźwięku. Aplikacja może jednak potrzebować renderować klatkę wideo przed rozpoczęciem odtwarzania dźwięku, na przykład aby pokazać użytkownikowi bieżącą pozycję wideo podczas przewijania.

    • Aby zasygnalizować, że pierwsza klatka wideo w kolejce powinna być renderowana natychmiast po zdekodowaniu, ustaw PARAMETER_KEY_TUNNEL_PEEK parametr na 1. Gdy skompresowane klatki wideo są zmieniane w kolejce (np. gdy występują klatki B ), oznacza to, że pierwsza wyświetlana klatka wideo powinna być zawsze klatką I.

    • Jeśli nie chcesz, aby pierwsza klatka wideo w kolejce była renderowana, dopóki nie rozpocznie się odtwarzanie dźwięku, ustaw ten parametr na 0.

    • Jeśli ten parametr nie jest ustawiony, producent OEM określa działanie urządzenia.

  • Gdy dane audio nie są dostarczane do AudioTrack, a bufory są puste (niedobór dźwięku), odtwarzanie wideo zatrzymuje się, dopóki nie zostaną zapisane kolejne dane audio, ponieważ zegar audio nie działa.

  • Podczas odtwarzania w sygnaturach czasowych prezentacji dźwięku mogą pojawiać się nieciągłości, których aplikacja nie może skorygować. W takim przypadku producent OEM koryguje ujemne luki, wstrzymując bieżącą klatkę wideo, a luki dodatnie – przez pomijanie klatek wideo lub wstawianie cichych klatek audio (w zależności od implementacji OEM). Pozycja klatki AudioTimestamp nie zwiększa się w przypadku wstawionych cichych klatek audio.

Przepływ sekwencji precyzyjnego przewijania

Precyzyjne przewijanie pozwala znaleźć konkretne miejsce w filmie. W przeciwieństwie do przewijania do klatki kluczowej, które przeskakuje tylko do najbliższej klatki I i może odbiegać od pozycji docelowej o kilka sekund, precyzyjne przewijanie renderuje wideo w dokładnej sygnaturze czasowej. Przestrzeganie tej konkretnej sekwencji interfejsu API umożliwia aplikacji bezproblemowe wykonywanie wstępnego buforowania w tle i synchronizacji czasu. Dzięki temu po wznowieniu odtwarzania wyświetla się natychmiast klatka docelowa.

Aby wykonać precyzyjne przewijanie, postępuj zgodnie z kolejnością wykonywania przedstawioną na rysunku 2:

sekwencja przewijania

Rysunek 2. Przepływ sekwencji umożliwiający precyzyjne przewijanie.

Najważniejsze informacje:

  • Równoległe wykonywanie: kroki w jednym polu par można wykonywać jednocześnie. Na przykład wywołania wideo MediaCodec są niezależne od AudioTrack.

  • Zależności sekwencyjne: przed przejściem do drugiego pola par wywołaj wszystkie operacje w pierwszym polu par. W szczególności aplikacja musi się upewnić że AudioTrack.write i bufory w MediaCodec wideo są umieszczane w kolejce przed wywołaniem AudioTrack.play.

Przepływ sekwencji odtwarzania ze zmienną szybkością

Odtwarzanie ze zmienną szybkością umożliwia odtwarzanie wideo z szybkością większą lub mniejszą niż normalna. Ta funkcja jest powszechnie używana przez aplikacje, aby umożliwić użytkownikom szybsze (np. odtwarzanie wykładów edukacyjnych lub podcastów z szybkością 1,5x lub 2,0x, aby zaoszczędzić czas) lub wolniejsze (np. analizowanie gier sportowych lub filmów instruktażowych z szybkością 0,5x) korzystanie z treści.

Aby ustawić szybkość, postępuj zgodnie z kolejnością wykonywania przedstawioną na rysunku 3:

szybki przepływ sekwencji

Rysunek 3. Przepływ sekwencji umożliwiający ustawienie szybkości.

Na schemacie sekwencji na rysunku 3 nie są uwzględnione te zachowania i wymagania techniczne:

  • AudioTrack.getTimestamp zwraca framePosition na podstawie pierwotnej częstotliwości wejściowej dźwięku. Na przykład przy częstotliwości wejściowej 44100 Hz i szybkości odtwarzania 2,0x po 2 sekundach odtwarzania AudioTrack.getTimestamp zwraca framePosition o wartości 176400.

  • Jeśli aplikacja wywoła setSpeed(1.5) i operacja się powiedzie, a potem aplikacja wywoła setSpeed(30) i operacja się nie powiedzie, odtwarzanie pozostanie na poziomie 1,5x.

  • Jeśli dźwięk jest wyciszony (za pomocą setVolume), aplikacja nadal musi wysyłać bufory audio, ponieważ klatki wideo są renderowane na podstawie pozycji audio.

  • Ton dźwięku jest zachowywany po zmianie szybkości.

  • Na szybkość odtwarzania nie mają wpływu inne działania związane z odtwarzaniem.

    • Przykład 1: jeśli szybkość odtwarzania wynosi 1,5x, a AudioTrack jest wstrzymany, po wznowieniu AudioTrack szybkość pozostanie na poziomie 1,5x.

    • Przykład 2: jeśli szybkość odtwarzania wynosi 1,5x, a użytkownik przewinie do innej sygnatury czasowej prezentacji, odtwarzanie pozostanie na poziomie 1,5x.

  • Aby mieć pewność, że wszystkie klatki są dekodowane na czas i mogą być renderowane z wybraną szybkością, ustaw KEY_OPERATING_RATE tak, aby odpowiadała iloczynowi liczby klatek na sekundę i szybkości odtwarzania. Jeśli KEY_OPERATING_RATE nie jest ustawiona na wystarczająco wysoką wartość, kodek może nie dekodować klatek wystarczająco szybko, co spowoduje nieoczekiwane pomijanie klatek podczas odtwarzania.

    • Przykład: jeśli pierwotna liczba klatek na sekundę wynosi 60, a szybkość odtwarzania to 2x, ustaw KEY_OPERATING_RATE na 120.
  • Wielokrotne ustawianie szybkości z różnymi obsługiwanymi szybkościami nie powinno powodować żadnych błędów, a działanie odtwarzania po ostatnim wywołaniu powinno być takie samo jak w przypadku, gdy szybkość jest ustawiona tylko raz na najnowszą wartość.

Informacje dla producentów urządzeń

Konfiguracja

Producenci OEM powinni utworzyć osobny dekoder wideo, aby obsługiwać odtwarzanie wideo w trybie tunelowania. Ten dekoder powinien informować, że obsługuje odtwarzanie w trybie tunelowania, w pliku media_codecs.xml:

<Feature name="tunneled-playback" required="true"/>

Gdy instancja MediaCodec w trybie tunelowania jest skonfigurowana z identyfikatorem sesji audio, wysyła do AudioFlinger zapytanie o ten identyfikator HW_AV_SYNC:

if (entry.getKey().equals(MediaFormat.KEY_AUDIO_SESSION_ID)) {
    int sessionId = 0;
    try {
        sessionId = (Integer)entry.getValue();
    }
    catch (Exception e) {
        throw new IllegalArgumentException("Wrong Session ID Parameter!");
    }
    keys[i] = "audio-hw-sync";
    values[i] = AudioSystem.getAudioHwSyncForSession(sessionId);
}

Podczas tego zapytania, AudioFlinger pobiera identyfikator HW_AV_SYNC ID z podstawowego urządzenia audio i wewnętrznie łączy go z identyfikatorem sesji audio:

audio_hw_device_t *dev = mPrimaryHardwareDev->hwDevice();
char *reply = dev->get_parameters(dev, AUDIO_PARAMETER_HW_AV_SYNC);
AudioParameter param = AudioParameter(String8(reply));
int hwAVSyncId;
param.getInt(String8(AUDIO_PARAMETER_HW_AV_SYNC), hwAVSyncId);

Jeśli instancja AudioTrack została już utworzona, identyfikator HW_AV_SYNC jest przekazywany do strumienia wyjściowego z tym samym identyfikatorem sesji audio. Jeśli nie została jeszcze utworzona, identyfikator HW_AV_SYNC jest przekazywany do strumienia wyjściowego podczas tworzenia AudioTrack. Odbywa się to w wątku odtwarzania wątku:

mOutput->stream->common.set_parameters(&mOutput->stream->common, AUDIO_PARAMETER_STREAM_HW_AV_SYNC, hwAVSyncId);

Identyfikator HW_AV_SYNC, niezależnie od tego, czy odpowiada strumieniowi wyjściowemu audio, czy konfiguracji Tuner, jest przekazywany do komponentu OMX lub Codec2, aby kod OEM mógł powiązać kodek z odpowiednim strumieniem wyjściowym audio lub strumieniem tunera.

Podczas konfiguracji komponentu komponent OMX lub Codec2 powinien zwrócić uchwyt pasma bocznego, którego można użyć do powiązania kodeka z warstwą Hardware Composer (HWC). Gdy aplikacja powiąże powierzchnię z MediaCodec, ten uchwyt pasma bocznego jest przekazywany do HWC przez SurfaceFlinger, który konfiguruje warstwę jako warstwę pasma bocznego.

err = native_window_set_sideband_stream(nativeWindow.get(), sidebandHandle);
if (err != OK) {
  ALOGE("native_window_set_sideband_stream(%p) failed! (err %d).", sidebandHandle, err);
  return err;
}

HWC jest odpowiedzialny za odbieranie nowych buforów obrazu z wyjścia kodeka w odpowiednim czasie, zsynchronizowanych z powiązanym strumieniem wyjściowym audio lub zegarem odniesienia programu tunera, łączenie buforów z bieżącą zawartością innych warstw i wyświetlanie wynikowego obrazu. Odbywa się to niezależnie od normalnego cyklu przygotowania i ustawienia. Wywołania przygotowania i ustawienia są wykonywane tylko wtedy, gdy zmieniają się inne warstwy lub gdy zmieniają się właściwości warstwy pasma bocznego (np. pozycja lub rozmiar).

OMX

Komponent dekodera w trybie tunelowania powinien obsługiwać te funkcje:

  • Ustawianie rozszerzonego parametru OMX.google.android.index.configureVideoTunnelMode, który używa struktury ConfigureVideoTunnelModeParams do przekazywania identyfikatora HW_AV_SYNC powiązanego z urządzeniem wyjściowym audio.

  • Konfigurowanie parametru OMX_IndexConfigAndroidTunnelPeek, który informuje kodek, czy ma renderować pierwszą zdekodowaną klatkę wideo, niezależnie od tego, czy rozpoczęło się odtwarzanie dźwięku.

  • Wysyłanie zdarzenia OMX_EventOnFirstTunnelFrameReady, gdy pierwsza klatka wideo w trybie tunelowania zostanie zdekodowana i będzie gotowa do renderowania.

Implementacja AOSP konfiguruje tryb tunelowania w ACodec za pomocą OMXNodeInstance , jak pokazano w tym fragmencie kodu:

OMX_INDEXTYPE index;
OMX_STRING name = const_cast<OMX_STRING>(
        "OMX.google.android.index.configureVideoTunnelMode");

OMX_ERRORTYPE err = OMX_GetExtensionIndex(mHandle, name, &index);

ConfigureVideoTunnelModeParams tunnelParams;
InitOMXParams(&tunnelParams);
tunnelParams.nPortIndex = portIndex;
tunnelParams.bTunneled = tunneled;
tunnelParams.nAudioHwSync = audioHwSync;
err = OMX_SetParameter(mHandle, index, &tunnelParams);
err = OMX_GetParameter(mHandle, index, &tunnelParams);
sidebandHandle = (native_handle_t*)tunnelParams.pSidebandWindow;

Jeśli komponent obsługuje tę konfigurację, powinien przydzielić uchwyt pasma bocznego do tego kodeka i przekazać go z powrotem przez element pSidebandWindow, aby HWC mógł zidentyfikować powiązany kodek. Jeśli komponent nie obsługuje tej konfiguracji, powinien ustawić bTunneled na OMX_FALSE.

Codec2

Na Androidzie 11 lub nowszym Codec2 obsługuje odtwarzanie w trybie tunelowania. Komponent dekodera powinien obsługiwać te funkcje:

  • Konfigurowanie C2PortTunneledModeTuning, które konfiguruje tryb tunelowania i przekazuje identyfikator HW_AV_SYNC pobrany z urządzenia wyjściowego audio lub konfiguracji tunera.

  • Wysyłanie zapytania C2_PARAMKEY_OUTPUT_TUNNEL_HANDLE, aby przydzielić i pobrać uchwyt pasma bocznego dla HWC.

  • Obsługiwanie C2_PARAMKEY_TUNNEL_HOLD_RENDER po dołączeniu do C2Work, które instruuje kodek, aby dekodował i sygnalizował zakończenie pracy, ale nie renderował bufora wyjściowego, dopóki 1) kodek nie otrzyma później instrukcji renderowania lub 2) nie rozpocznie się odtwarzanie dźwięku.

  • Obsługiwanie C2_PARAMKEY_TUNNEL_START_RENDER, które instruuje kodek, aby natychmiast renderował klatkę oznaczoną jako C2_PARAMKEY_TUNNEL_HOLD_RENDER, nawet jeśli nie rozpoczęło się odtwarzanie dźwięku.

  • Pozostaw debug.stagefright.ccodec_delayed_params bez konfiguracji (zalecane). Jeśli ją skonfigurujesz, ustaw wartość false.

Implementacja AOSP konfiguruje tryb tunelowania w CCodec za pomocą C2PortTunnelModeTuning, jak pokazano w tym fragmencie kodu:

if (msg->findInt32("audio-hw-sync", &tunneledPlayback->m.syncId[0])) {
    tunneledPlayback->m.syncType =
            C2PortTunneledModeTuning::Struct::sync_type_t::AUDIO_HW_SYNC;
} else if (msg->findInt32("hw-av-sync-id", &tunneledPlayback->m.syncId[0])) {
    tunneledPlayback->m.syncType =
            C2PortTunneledModeTuning::Struct::sync_type_t::HW_AV_SYNC;
} else {
    tunneledPlayback->m.syncType =
            C2PortTunneledModeTuning::Struct::sync_type_t::REALTIME;
    tunneledPlayback->setFlexCount(0);
}
c2_status_t c2err = comp->config({ tunneledPlayback.get() }, C2_MAY_BLOCK,
        failures);
std::vector<std::unique_ptr<C2Param>> params;
c2err = comp->query({}, {C2PortTunnelHandleTuning::output::PARAM_TYPE},
        C2_DONT_BLOCK, &params);
if (c2err == C2_OK && params.size() == 1u) {
    C2PortTunnelHandleTuning::output *videoTunnelSideband =
            C2PortTunnelHandleTuning::output::From(params[0].get());
    return OK;
}

Jeśli komponent obsługuje tę konfigurację, powinien przydzielić uchwyt pasma bocznego do tego kodeka i przekazać go z powrotem przez C2PortTunnelHandlingTuning, aby HWC mógł zidentyfikować powiązany kodek.

Audio HAL

W przypadku odtwarzania wideo na żądanie Audio HAL otrzymuje sygnatury czasowe prezentacji dźwięku w formacie big-endian w nagłówku znajdującym się na początku każdego bloku danych audio zapisywanego przez aplikację:

struct TunnelModeSyncHeader {
  // The 32-bit data to identify the sync header (0x55550002)
  int32 syncWord;
  // The size of the audio data following the sync header before the next sync
  // header might be found.
  int32 sizeInBytes;
  // The presentation timestamp of the first audio sample following the sync
  // header.
  int64 presentationTimestamp;
  // The number of bytes to skip after the beginning of the sync header to find the
  // first audio sample (20 bytes for compressed audio, or larger for PCM, aligned
  // to the channel count and sample size).
  int32 offset;
}

Aby HWC renderował klatki wideo w synchronizacji z odpowiadającymi im klatkami audio, Audio HAL powinien analizować nagłówek synchronizacji i używać sygnatury czasowej prezentacji do ponownej synchronizacji zegara odtwarzania z renderowaniem dźwięku. Aby ponownie zsynchronizować odtwarzanie skompresowanego dźwięku, Audio HAL może potrzebować analizować metadane w skompresowanych danych audio, aby określić czas trwania odtwarzania.

Obsługa wstrzymywania

Android 5 lub starszy nie obsługuje wstrzymywania. Odtwarzanie w trybie tunelowania można wstrzymać tylko przez niedobór A/V, ale jeśli wewnętrzny bufor wideo jest duży (np. w komponencie OMX jest sekunda danych), wstrzymanie wygląda na niereagujące.

Na Androidzie 5.1 lub nowszym AudioFlinger obsługuje wstrzymywanie i wznawianie bezpośrednich (tunelowanych) wyjść audio. Jeśli HAL implementuje wstrzymywanie i wznawianie, wstrzymywanie i wznawianie ścieżki jest przekazywane do HAL.

Sekwencja wywołań wstrzymania, opróżnienia i wznowienia jest respektowana przez wykonywanie wywołań HAL w wątku odtwarzania (tak samo jak w przypadku odciążania).

Sugestie dotyczące implementacji

Audio HAL

W przypadku Androida 11 do synchronizacji A/V można używać identyfikatora synchronizacji sprzętowej z PCR lub STC, dlatego obsługiwany jest strumień tylko wideo.

W przypadku Androida 10 lub starszego urządzenia obsługujące odtwarzanie wideo w trybie tunelowania powinny mieć co najmniej 1 profil strumienia wyjściowego audio z flagami FLAG_HW_AV_SYNC i AUDIO_OUTPUT_FLAG_DIRECT w pliku audio_policy.conf. Te flagi służą do ustawiania zegara systemowego na podstawie zegara audio.

OMX

Producenci urządzeń powinni mieć osobny komponent OMX do odtwarzania wideo w trybie tunelowania (producenci mogą mieć dodatkowe komponenty OMX do innych typów odtwarzania audio i wideo, np. bezpiecznego odtwarzania). Komponent w trybie tunelowania powinien:

  • Określ 0 buforów (nBufferCountMin, nBufferCountActual) na porcie wyjściowym.

  • Zaimplementuj rozszerzenie OMX.google.android.index.prepareForAdaptivePlayback setParameter.

  • Określ swoje możliwości w pliku media_codecs.xml i zadeklaruj funkcję odtwarzania w trybie tunelowania. Powinien też wyjaśnić wszelkie ograniczenia dotyczące rozmiaru klatki, wyrównania lub przepływności bitowej. Poniżej znajdziesz przykład:

    <MediaCodec name="OMX.OEM_NAME.VIDEO.DECODER.AVC.tunneled"
    type="video/avc" >
        <Feature name="adaptive-playback" />
        <Feature name="tunneled-playback" required=true />
        <Limit name="size" min="32x32" max="3840x2160" />
        <Limit name="alignment" value="2x2" />
        <Limit name="bitrate" range="1-20000000" />
            ...
    </MediaCodec>
    

Jeśli ten sam komponent OMX jest używany do obsługi dekodowania w trybie tunelowania i bez tunelowania, powinien pozostawić funkcję odtwarzania w trybie tunelowania jako nieobowiązkową. Wtedy dekodery w trybie tunelowania i bez tunelowania mają te same ograniczenia. Poniżej znajdziesz przykład:

<MediaCodec name="OMX._OEM\_NAME_.VIDEO.DECODER.AVC" type="video/avc" >
    <Feature name="adaptive-playback" />
    <Feature name="tunneled-playback" />
    <Limit name="size" min="32x32" max="3840x2160" />
    <Limit name="alignment" value="2x2" />
    <Limit name="bitrate" range="1-20000000" />
        ...
</MediaCodec>

Hardware Composer (HWC)

Gdy na wyświetlaczu znajduje się warstwa w trybie tunelowania (warstwa z compositionType HWC_SIDEBAND), sidebandStream warstwy jest uchwytem pasma bocznego przydzielonym przez komponent OMX wideo.

HWC synchronizuje zdekodowane klatki wideo (z komponentu OMX w trybie tunelowania) z powiązaną ścieżką audio (z identyfikatorem audio-hw-sync). Gdy nowa klatka wideo staje się bieżącą, HWC łączy ją z bieżącą zawartością wszystkich warstw otrzymanych podczas ostatniego wywołania przygotowania lub ustawienia i wyświetla wynikowy obraz. Wywołania przygotowania lub ustawienia są wykonywane tylko wtedy, gdy zmieniają się inne warstwy lub gdy zmieniają się właściwości warstwy pasma bocznego (np. pozycja lub rozmiar).

Na ilustracji poniżej przedstawiono HWC współpracujący z synchronizatorem sprzętowym (lub jądra lub sterownika), aby łączyć klatki wideo (7b) z najnowszą kompozycją (7a) w celu wyświetlania w odpowiednim czasie na podstawie dźwięku (7c).

HWC łączący klatki wideo na podstawie dźwięku

Rysunek 4. Synchronizator sprzętowy (lub jądra lub sterownika) HWC.