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

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

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

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

बैकग्राउंड

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

टनल किए गए वीडियो के प्लेबैक की सुविधा, ऐप्लिकेशन कोड को बायपास करती है और वीडियो पर काम करने वाली प्रोसेस की संख्या को कम करती है. इसलिए, OEM के लागू होने के आधार पर, यह वीडियो को ज़्यादा बेहतर तरीके से रेंडर कर सकती है. यह चुनी गई घड़ी (पीआरसी, एसटीसी या ऑडियो) के लिए, वीडियो के ताल और सिंक को ज़्यादा सटीक बना सकता है. ऐसा, वीडियो को रेंडर करने के लिए Android के अनुरोधों के समय और असल हार्डवेयर vsyncs के समय के बीच संभावित अंतर की वजह से होने वाली समय से जुड़ी समस्याओं से बचकर किया जा सकता है. हालांकि, टनल करने से GPU इफ़ेक्ट के लिए सहायता भी कम हो सकती है. जैसे, पिक्चर में पिक्चर (PiP) विंडो में धुंधला करना या कोनों को गोल करना. ऐसा इसलिए होता है, क्योंकि बफ़र, 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 को ऑडियो डेटा नहीं दिया जाता और बफ़र खाली होते हैं (ऑडियो का कम चलना), तो वीडियो तब तक नहीं चलता, जब तक ज़्यादा ऑडियो डेटा नहीं लिखा जाता, क्योंकि ऑडियो क्लॉक अब आगे नहीं बढ़ रहा है.

  • ऑडियो चलाने के दौरान, ऑडियो प्रज़ेंटेशन के टाइमस्टैंप में ऐसी रुकावटें दिख सकती हैं जिन्हें ऐप्लिकेशन ठीक नहीं कर सकता. ऐसा होने पर, OEM मौजूदा वीडियो फ़्रेम को रोककर, नेगेटिव गैप को ठीक करता है. साथ ही, वीडियो फ़्रेम को हटाकर या साइलेंट ऑडियो फ़्रेम डालकर, पॉज़िटिव गैप को ठीक करता है. हालांकि, यह OEM के लागू करने के तरीके पर निर्भर करता है. डाले गए साइलेंट ऑडियो फ़्रेम के लिए, 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 आईडी को OMX या Codec2 कॉम्पोनेंट में पास किया जाता है. भले ही, यह किसी ऑडियो आउटपुट स्ट्रीम या Tuner कॉन्फ़िगरेशन से जुड़ा हो. इससे 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 पर सेट करें.

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

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

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

सहायता रोकना

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

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

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

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

ऑडियो एचएएल

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

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

OMX

डिवाइस बनाने वाली कंपनियों के पास, टनल किए गए वीडियो को चलाने के लिए एक अलग 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, OMX वीडियो कॉम्पोनेंट से असाइन किया गया साइडबैंड हैंडल होता है.

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

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

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

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