मल्टीमीडिया टनलिंग

मल्टीमीडिया टनल करने की सुविधा की मदद से, कंप्रेस किए गए वीडियो डेटा को ऐप्लिकेशन कोड या Android फ़्रेमवर्क कोड के ज़रिए प्रोसेस किए बिना, सीधे डिसप्ले पर दिखाया जा सकता है. इसके लिए, वीडियो को हार्डवेयर वीडियो डिकोडर के ज़रिए टनल किया जाता है. Android स्टैक के नीचे दिए गए डिवाइस के हिसाब से बने कोड से तय होता है कि डिसप्ले पर कौनसे वीडियो फ़्रेम भेजने हैं और उन्हें कब भेजना है. इसके लिए, अंदरूनी घड़ी के इनमें से किसी एक टाइप से वीडियो फ़्रेम प्रज़ेंटेशन के टाइमस्टैंप की तुलना की जाती है.

  • Android 5 या इसके बाद वाले वर्शन में मांग पर वीडियो चलाने के लिए, ऐप्लिकेशन में AudioTrack ऑडियो प्रज़ेंटेशन के टाइमस्टैंप से सिंक की गई घड़ी की दिशा पास होती है

  • Android 11 या उसके बाद के वर्शन में लाइव ब्रॉडकास्ट वीडियो चलाने के लिए, ट्यूनर से चलने वाली प्रोग्राम रेफ़रंस क्लॉक (पीसीआर) या सिस्टम टाइम क्लॉक (एसटीसी)

बैकग्राउंड

Android पर परंपरागत वीडियो फ़्रेम को डिकोड किए जाने पर, ऐप्लिकेशन को सूचना दी जाती है. इसके बाद, ऐप्लिकेशन डिकोड किए गए वीडियो फ़्रेम को डिसप्ले पर रिलीज़ करता है, ताकि सही समय का हिसाब लगाने के लिए, सिस्टम के तय समय पर रेंडर होने में लगने वाले समय का पता लगाया जा सके. साथ ही, इससे जुड़े ऑडियो फ़्रेम को हासिल करके पुराने AudioTimestamps इंस्टेंस वापस आते हैं.

टनल किए गए वीडियो के प्लेबैक की सुविधा, ऐप्लिकेशन कोड को बायपास करती है और वीडियो पर काम करने वाली प्रोसेस की संख्या को कम करती है. इसलिए, OEM के लागू होने के आधार पर, यह वीडियो को ज़्यादा बेहतर तरीके से रेंडर कर सकती है. यह चुनी गई घड़ी (पीआरसी, एसटीसी या ऑडियो) के लिए वीडियो के अपलोड होने और सिंक करने की ज़्यादा सटीक सुविधा दे सकता है. ऐसा करने के लिए, Android के वीडियो रेंडर करने के अनुरोधों के समय और असल हार्डवेयर vसिंक के समय के बीच आने वाले संभावित अंतर की वजह से आने वाली समस्याओं से बचा जा सकता है. हालांकि, ट्यूनिंग से जीपीयू इफ़ेक्ट के लिए सहायता कम हो सकती है. जैसे, धुंधला करने या पिक्चर में पिक्चर (पीआईपी) विंडो में गोल कोने. ऐसा इसलिए होता है, क्योंकि बफ़र, Android ग्राफ़िक्स स्टैक को बायपास कर देते हैं.

नीचे दिया गया डायग्राम दिखाता है कि टनलिंग, वीडियो चलाने की प्रोसेस को कैसे आसान बनाती है.

पारंपरिक और टनल मोड की तुलना

पहली इमेज. वीडियो चलाने की पारंपरिक और टनल वाली प्रोसेस की तुलना

ऐप्लिकेशन डेवलपर के लिए जानकारी

ज़्यादातर ऐप्लिकेशन डेवलपर, वीडियो चलाने के लिए एक लाइब्रेरी के साथ इंटिग्रेट करते हैं. इसलिए, ज़्यादातर मामलों में लागू करने के लिए, टनल किए गए प्लेबैक के लिए सिर्फ़ लाइब्रेरी को फिर से कॉन्फ़िगर करने की ज़रूरत होती है. टनल किए गए वीडियो प्लेयर को लो-लेवल पर लागू करने के लिए, नीचे दिए गए निर्देशों का पालन करें.

Android 5 या इसके बाद वाले वर्शन में मांग पर वीडियो चलाने के लिए:

  1. SurfaceView इंस्टेंस बनाएं.

  2. audioSessionId इंस्टेंस बनाएं.

  3. दूसरे चरण में बनाए गए audioSessionId इंस्टेंस की मदद से, AudioTrack और MediaCodec इंस्टेंस बनाएं.

  4. ऑडियो डेटा में पहले ऑडियो फ़्रेम के लिए, प्रज़ेंटेशन के टाइमस्टैंप के साथ ऑडियो डेटा को AudioTrack में जोड़ें.

Android 11 या इसके बाद के वर्शन में लाइव ब्रॉडकास्ट चलाने के लिए:

  1. SurfaceView इंस्टेंस बनाएं.

  2. Tuner से avSyncHwId इंस्टेंस पाएं.

  3. दूसरे चरण में बनाए गए avSyncHwId इंस्टेंस की मदद से, AudioTrack और MediaCodec इंस्टेंस बनाएं.

एपीआई कॉल फ़्लो, इन कोड स्निपेट में दिखाया जाता है:

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);

मांग पर वीडियो चलाने की सुविधा

मांग पर टनल किए गए वीडियो प्लेबैक, AudioTrack प्लेबैक से जुड़े होते हैं. इसलिए, टनल किए गए वीडियो प्लेबैक का तरीका, ऑडियो प्लेबैक के व्यवहार पर निर्भर कर सकता है.

  • डिफ़ॉल्ट रूप से, ज़्यादातर डिवाइसों पर वीडियो फ़्रेम तब तक रेंडर नहीं होता, जब तक ऑडियो प्लेबैक शुरू नहीं होता. हालांकि, ऑडियो चलाने से पहले ऐप्लिकेशन को वीडियो फ़्रेम रेंडर करना पड़ सकता है. उदाहरण के लिए, वीडियो में आगे-पीछे जाने के दौरान, उपयोगकर्ता को वीडियो की मौजूदा पोज़िशन दिखाने के लिए.

    • यह बताने के लिए कि सूची में शामिल पहला वीडियो फ़्रेम, डिकोड होते ही रेंडर हो जाना चाहिए, PARAMETER_KEY_TUNNEL_PEEK पैरामीटर को 1 पर सेट करें. सूची में कंप्रेस किए गए वीडियो फ़्रेम का क्रम बदलने पर (जैसे, जब B-फ़्रेम मौजूद हों), इसका मतलब है कि दिखाया गया पहला वीडियो फ़्रेम हमेशा I-फ़्रेम होना चाहिए.

    • अगर आपको ऑडियो प्लेबैक शुरू होने से पहले, सूची में शामिल पहले वीडियो फ़्रेम को रेंडर नहीं करना है, तो इस पैरामीटर को 0 पर सेट करें.

    • अगर यह पैरामीटर सेट नहीं किया गया है, तो OEM डिवाइस के लिए व्यवहार तय करता है.

  • जब AudioTrack को ऑडियो डेटा नहीं दिया जाता और बफ़र खाली होते हैं (ऑडियो का कम चलना), तो वीडियो तब तक नहीं चलता, जब तक ज़्यादा ऑडियो डेटा नहीं लिखा जाता, क्योंकि ऑडियो क्लॉक अब आगे नहीं बढ़ रहा है.

  • ऑडियो चलाने के दौरान, ऑडियो प्रज़ेंटेशन के टाइमस्टैंप में ऐसी रुकावटें दिख सकती हैं जिन्हें ऐप्लिकेशन ठीक नहीं कर सकता. ऐसा होने पर ओईएम, मौजूदा वीडियो फ़्रेम को रोककर या वीडियो फ़्रेम को ड्रॉप करके या साइलेंट ऑडियो फ़्रेम शामिल करके (ओईएम लागू करने के आधार पर) नकारात्मक अंतरों को ठीक करता है. शामिल किए गए साइलेंट ऑडियो फ़्रेम के लिए, AudioTimestamp फ़्रेम की पोज़िशन नहीं बढ़ती.

डिवाइस बनाने वाली कंपनियों के लिए

कॉन्फ़िगरेशन

टनल किए गए वीडियो को चलाने के लिए, OEM को एक अलग वीडियो डिकोडर बनाना चाहिए. इस डिकोडर को विज्ञापन दिखाना चाहिए कि यह media_codecs.xml फ़ाइल में टनल किए जा सकने वाले वीडियो में काम कर सकता है:

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

जब टनल किए गए MediaCodec इंस्टेंस को ऑडियो सेशन आईडी के साथ कॉन्फ़िगर किया जाता है, तो यह इस HW_AV_SYNC आईडी के लिए, AudioFlinger से क्वेरी करता है:

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);
}

इस क्वेरी के दौरान, AudioFlinger प्राइमरी ऑडियो डिवाइस से HW_AV_SYNC आईडी को वापस लाता है और उसे ऑडियो सेशन आईडी से जोड़ता है:

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);

अगर AudioTrack इंस्टेंस पहले से बना हुआ है, तो HW_AV_SYNC आईडी को उसी ऑडियो सेशन आईडी के साथ आउटपुट स्ट्रीम में पास किया जाता है. अगर अब तक आईडी नहीं बनाया गया है, तो इसे बनाने के दौरान HW_AV_SYNC आईडी को आउटपुट स्ट्रीम में भेजा जाता है. AudioTrack. ऐसा प्लेबैक ट्रैड की मदद से किया जाता है:

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

HW_AV_SYNC आईडी, चाहे वह किसी ऑडियो आउटपुट स्ट्रीम या Tuner कॉन्फ़िगरेशन से जुड़ा हो, OMX या Codec2 कॉम्पोनेंट में पास किया जाता है. इससे OEM कोड, कोडेक को उससे जुड़े ऑडियो आउटपुट स्ट्रीम या ट्यूनर स्ट्रीम के साथ जोड़ सकता है.

कॉम्पोनेंट कॉन्फ़िगरेशन के दौरान, OMX या Codec2 कॉम्पोनेंट को एक साइडबैंड हैंडल दिखाना चाहिए. इसका इस्तेमाल, कोडेक को हार्डवेयर कंपोजर (एचडब्ल्यूसी) लेयर से जोड़ने के लिए किया जा सकता है. जब ऐप्लिकेशन किसी सरफ़ेस को MediaCodec से जोड़ता है, तो इस साइडबैंड हैंडल को SurfaceFlinger के ज़रिए HWC को भेजा जाता है. यह लेयर को साइडबैंड लेयर के तौर पर कॉन्फ़िगर करता है.

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;
}

एचडब्ल्यूसी, कोडेक आउटपुट से सही समय पर नई इमेज बफ़र पाने के लिए ज़िम्मेदार होता है. यह बफ़र, ऑडियो आउटपुट स्ट्रीम या ट्यूनर प्रोग्राम रेफ़रंस क्लॉक के साथ सिंक किए जाते हैं. साथ ही, बफ़र को अन्य लेयर के मौजूदा कॉन्टेंट के साथ कंपोज किया जाता है और इमेज दिखाई जाती है. यह, सामान्य तौर पर तैयार करने और सेट करने के चक्र से अलग होता है. कॉल तैयार करने और सेट करने का काम सिर्फ़ तब होता है, जब अन्य लेयर में बदलाव होता है या साइडबैंड लेयर की प्रॉपर्टी (जैसे कि पोज़िशन या साइज़) बदलती है.

OMX

टनल किए गए डिकोडर कॉम्पोनेंट को इनके साथ काम करना चाहिए:

  • OMX.google.android.index.configureVideoTunnelMode एक्सटेंडेड पैरामीटर सेट करना. यह ऑडियो आउटपुट डिवाइस से जुड़े HW_AV_SYNC आईडी को पास करने के लिए, ConfigureVideoTunnelModeParams स्ट्रक्चर का इस्तेमाल करता है.

  • OMX_IndexConfigAndroidTunnelPeek पैरामीटर को कॉन्फ़िगर करना, जो कोडेक को पहला डिकोड किया गया वीडियो फ़्रेम रेंडर करने या न करने के लिए कहता है. भले ही, ऑडियो चलाना शुरू हो गया हो.

  • जब टनल किया गया पहला वीडियो फ़्रेम डिकोड हो जाता है और रेंडर होने के लिए तैयार हो जाता है, तब OMX_EventOnFirstTunnelFrameReady इवेंट भेजा जाता है.

AOSP लागू करने पर, टनल मोड को ACodec में कॉन्फ़िगर किया जाता है. इसके लिए, OMXNodeInstance का इस्तेमाल किया जाता है. इस बारे में नीचे दिए गए कोड स्निपेट में बताया गया है:

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;

अगर कॉम्पोनेंट इस कॉन्फ़िगरेशन के साथ काम करता है, तो उसे इस कोडेक के लिए एक साइडबैंड हैंडल असाइन करना चाहिए और उसे pSidebandWindow सदस्य के ज़रिए वापस भेजना चाहिए, ताकि एचडब्ल्यूसी उससे जुड़े कोडेक की पहचान कर सके. अगर कॉम्पोनेंट इस कॉन्फ़िगरेशन के साथ काम नहीं करता है, तो उसे bTunneled को OMX_FALSE पर सेट करना चाहिए.

Codec2

Android 11 या उसके बाद के वर्शन में, Codec2 में टनल किए गए वीडियो चलाने की सुविधा काम करती है. डिकोडर कॉम्पोनेंट को इनके साथ काम करना चाहिए:

  • C2PortTunneledModeTuning को कॉन्फ़िगर करना, जो टनल मोड को कॉन्फ़िगर करता है और ऑडियो आउटपुट डिवाइस या ट्यूनर कॉन्फ़िगरेशन से HW_AV_SYNC को पास करता है.

  • एचडब्ल्यूसी के लिए साइडबैंड हैंडल असाइन करने और वापस लाने के लिए, C2_PARAMKEY_OUTPUT_TUNNEL_HANDLE पर क्वेरी की जा रही है.

  • C2Work के साथ अटैच किए जाने पर C2_PARAMKEY_TUNNEL_HOLD_RENDER को हैंडल करना, जिसमें कोडेक को काम पूरा होने के सिग्नल को डिकोड करने और सिग्नल को भेजने के निर्देश दिए जाते हैं. हालांकि, आउटपुट बफ़र को रेंडर नहीं किया जाता, जब तक कि 1) कोडेक को बाद में इसे रेंडर करने का निर्देश दिया जाता है या 2) ऑडियो प्लेबैक शुरू होता है.

  • C2_PARAMKEY_TUNNEL_START_RENDER को मैनेज करना, जो कोडेक को C2_PARAMKEY_TUNNEL_HOLD_RENDER से मार्क किए गए फ़्रेम को तुरंत रेंडर करने का निर्देश देता है. भले ही, ऑडियो चलाना शुरू न हुआ हो.

  • debug.stagefright.ccodec_delayed_params को कॉन्फ़िगर नहीं किया गया रहने दें (सुझाया गया). कॉन्फ़िगर करने के लिए, इसे false पर सेट करें.

एओएसपी को लागू करने की प्रक्रिया में, टनल मोड को CCodec से C2PortTunnelModeTuning के ज़रिए कॉन्फ़िगर किया जाता है, जैसा कि इस कोड स्निपेट में दिखाया गया है:

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;
}

अगर कॉम्पोनेंट इस कॉन्फ़िगरेशन के साथ काम करता है, तो उसे इस कोडेक के लिए साइडबैंड हैंडल असाइन करना चाहिए और उसे C2PortTunnelHandlingTuning के ज़रिए वापस पास करना चाहिए. इससे एचडब्ल्यूसी इससे जुड़े कोडेक की पहचान कर पाएगा.

ऑडियो एचएएल

ऑन-डिमांड वीडियो चलाने के लिए, ऑडियो एचएएल को ऑडियो डेटा के साथ इनलाइन में ऑडियो प्रज़ेंटेशन टाइमस्टैंप मिलते हैं. ये टाइमस्टैंप, हेडर में मौजूद होते हैं. हेडर, ऑडियो डेटा के हर ब्लॉक की शुरुआत में होता है. ऐप्लिकेशन में यह हेडर लिखा होता है:

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;
}

एचडब्ल्यूसी, वीडियो फ़्रेम को उससे जुड़े ऑडियो फ़्रेम के साथ सिंक करके रेंडर कर सके, इसके लिए ऑडियो एचएएल को सिंक हेडर को पार्स करना चाहिए. साथ ही, ऑडियो रेंडरिंग के साथ प्लेबैक क्लॉक को फिर से सिंक करने के लिए, प्रज़ेंटेशन टाइमस्टैंप का इस्तेमाल करना चाहिए. कंप्रेस किए गए ऑडियो को चलाए जाने के दौरान उसे फिर से सिंक करने के लिए, ऑडियो एचएएल को कंप्रेस किए गए ऑडियो डेटा के अंदर मेटाडेटा पार्स करना पड़ सकता है. इससे उसके चलने का कुल समय पता किया जा सकता है.

सहायता रोकना

Android 5 या इससे पहले के वर्शन में, वीडियो रोकने की सुविधा नहीं है. टनल किए गए वीडियो को सिर्फ़ A/V स्टैर्व्हेशन की वजह से रोका जा सकता है. हालांकि, अगर वीडियो का इंटरनल बफ़र बड़ा है, तो ऐसा लगता है कि वीडियो को रोका नहीं जा सकता. उदाहरण के लिए, OMX कॉम्पोनेंट में एक सेकंड का डेटा है.

Android 5.1 या इसके बाद के वर्शन में, AudioFlinger सीधे (टनल किए गए) ऑडियो आउटपुट के लिए, रोकने और फिर से शुरू करने की सुविधा देता है. अगर एचएएल, ट्रैक को रोकने और फिर से शुरू करने की सुविधा लागू करता है, तो ट्रैक को रोकने और फिर से शुरू करने की सुविधा, एचएएल को भेज दी जाती है.

प्लेबैक थ्रेड में HAL कॉल को लागू करके, रोकें, फ़्लश करें, फिर से शुरू करें कॉल के क्रम का पालन किया जाता है. यह ऑफ़लोड करने जैसा ही है.

लागू करने के सुझाव

ऑडियो एचएएल

Android 11 के लिए, PCR या STC से मिले एचडब्ल्यू सिंक आईडी का इस्तेमाल, ए/वी सिंक के लिए किया जा सकता है, ताकि सिर्फ़ वीडियो स्ट्रीम की जा सके.

Android 10 या उससे पहले के वर्शन वाले डिवाइसों पर, टनल किए गए वीडियो चलाने की सुविधा काम करती है. इसके लिए, डिवाइस की audio_policy.conf फ़ाइल में FLAG_HW_AV_SYNC और AUDIO_OUTPUT_FLAG_DIRECT फ़्लैग के साथ कम से कम एक ऑडियो आउटपुट स्ट्रीम प्रोफ़ाइल होनी चाहिए. इन फ़्लैग का इस्तेमाल, ऑडियो क्लॉक से सिस्टम क्लॉक को सेट करने के लिए किया जाता है.

ओएमएक्स

डिवाइस बनाने वाली कंपनियों के पास, टनल किए गए वीडियो को चलाने के लिए एक अलग OMX कॉम्पोनेंट होना चाहिए. हालांकि, वे सुरक्षित तरीके से वीडियो चलाने जैसे अन्य ऑडियो और वीडियो चलाने के लिए, अतिरिक्त OMX कॉम्पोनेंट भी जोड़ सकती हैं. टनल किए गए कॉम्पोनेंट को:

  • इसके आउटपुट पोर्ट पर 0 बफ़र (nBufferCountMin, nBufferCountActual) तय करें.

  • OMX.google.android.index.prepareForAdaptivePlayback setParameter एक्सटेंशन लागू करें.

  • media_codecs.xml फ़ाइल में इसकी सुविधाओं के बारे में बताएं और टनल किए गए वीडियो चलाने की सुविधा के बारे में बताएं. इससे फ़्रेम के साइज़, अलाइनमेंट या बिटरेट से जुड़ी सीमाओं के बारे में भी साफ़ तौर पर पता चलना चाहिए. इसका उदाहरण यहां दिया गया है:

    <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>
    

अगर टनल किए गए और टनल नहीं किए गए डेकोडिंग के लिए एक ही OMX कॉम्पोनेंट का इस्तेमाल किया जाता है, तो टनल किए गए वीडियो चलाने की सुविधा को ज़रूरी नहीं माना जाना चाहिए. इसलिए, टनल किए गए और नॉन टनल किए गए डीकोडर की क्षमता एक जैसी होती है. इसका एक उदाहरण नीचे दिया गया है:

<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>

हार्डवेयर कंपोजर (एचडब्ल्यूसी)

जब किसी डिसप्ले पर टनल की गई लेयर (HWC_SIDEBAND compositionType वाली लेयर) होती है, तो लेयर का sidebandStream, ओएमएक्स वीडियो कॉम्पोनेंट से असाइन किया गया साइडबैंड हैंडल होता है.

एचडब्ल्यूसी डिकोड किए गए वीडियो फ़्रेम (टनल किए गए ओएमएक्स कॉम्पोनेंट से) को, उनसे जुड़े ऑडियो ट्रैक (audio-hw-sync आईडी के साथ) के साथ सिंक करता है. जब कोई नया वीडियो फ़्रेम मौजूदा हो जाता है, तो एचडब्ल्यूसी उसे पिछले तैयार या सेट कॉल के दौरान मिली सभी लेयर के मौजूदा कॉन्टेंट के साथ कंपोज करता है और नतीजे में मिली इमेज दिखाता है. तैयार या सेट कॉल सिर्फ़ तब होते हैं, जब अन्य लेयर में बदलाव होता है या जब साइडबैंड लेयर की प्रॉपर्टी (जैसे कि पोज़िशन या साइज़) बदलती है.

नीचे दी गई इमेज में, हार्डवेयर (या कर्नेल या ड्राइवर) सिंक्रोनाइसर के साथ काम करने वाले एचडब्ल्यूसी को दिखाया गया है. यह ऑडियो (7c) के आधार पर, वीडियो फ़्रेम (7b) को नए कॉम्पोनिशन (7a) के साथ जोड़ता है, ताकि सही समय पर डिसप्ले किया जा सके.

ऑडियो के आधार पर वीडियो फ़्रेम को मिलाने वाला एचडब्ल्यूसी

दूसरी इमेज. एचडब्ल्यूसी हार्डवेयर (या कर्नेल या ड्राइवर) सिंक करने वाला टूल