تونل‌زنی چندرسانه‌ای

تونل‌سازی چندرسانه‌ای، که با نام حالت تونل نیز شناخته می‌شود، داده‌های ویدیویی فشرده‌شده را قادر می‌سازد تا ازطریق یک رمزگشای ویدیویی سخت‌افزاری مستقیماً به نمایشگر تونل‌سازی شوند، بدون اینکه توسط کد برنامه یا کد چارچوب Android پردازش شوند. کد مختص دستگاه در زیر پشته Android تعیین می‌کند کدام فریم‌های ویدیو به نمایشگر ارسال شود و چه زمانی ارسال شود. این کار با مقایسه مُهرهای زمان ارائه فریم ویدیو با یکی از انواع ساعت داخلی زیر انجام می‌شود:

  • برای بازپخش ویدیو درخواستی در Android 5 یا بالاتر، یک ساعت AudioTrack همگام‌سازی‌شده با مُهرهای زمانی ارائه صوتی ارسال‌شده توسط برنامه

  • برای بازپخش پخش زنده در Android 11 یا بالاتر، ساعت مرجع برنامه (PCR) یا ساعت زمان سیستم (STC) که توسط تیونر هدایت می‌شود

پس‌زمینه

بازپخش ویدیو در حالت غیرتونلی در Android وقتی فریم ویدیو فشرده‌شده رمزگشایی می‌شود، به برنامه اطلاع می‌دهد. سپس برنامه فریم ویدیو رمزگشایی‌شده را برای نمایش منتشر می‌کند تا در همان زمان ساعت سیستم به‌عنوان فریم صوتی مربوطه رندر شود، و نمونه‌های تاریخی AudioTimestamp را برای محاسبه زمان‌بندی صحیح بازیابی می‌کند.

ازآنجایی‌که بازپخش ویدیو تونل‌شده کد برنامه را دور می‌زند و تعداد فرایندهای تأثیرگذار بر ویدیو را کاهش می‌دهد، می‌تواند بسته به پیاده‌سازی OEM، پرداز ویدیو کارآمدتری ارائه دهد. همچنین می‌تواند با اجتناب از مشکلات زمان‌بندی ناشی از انحراف احتمالی بین زمان‌بندی درخواست‌های Android برای رندر کردن ویدیو و زمان‌بندی همگام‌سازی عمودی سخت‌افزار واقعی، آهنگ و همگام‌سازی دقیق‌تری برای ساعت انتخاب‌شده (PRC،‏ STC، یا صدا) ارائه دهد. بااین‌حال، تونل‌سازی می‌تواند پشتیبانی از جلوه‌های GPU مانند محو کردن یا گوشه‌های گرد در پنجره‌های تصویردرتصویر (PiP) را نیز کاهش دهد، زیرا میان‌گیرها پشته گرافیکی Android را دور می‌زنند.

نمودار زیر نشان می‌دهد که چگونه تونل‌سازی فرایند بازپخش ویدیو را ساده می‌کند.

مقایسه حالت‌های سنتی و تونل

شکل ۱. مقایسه فرایندهای بازپخش ویدیو تونل‌نشده و تونل‌شده.

برای توسعه‌دهندگان نرم‌افزار

ازآنجایی‌که اکثر توسعه‌دهندگان برنامه برای پیاده‌سازی بازپخش با یک کتابخانه ادغام می‌شوند، در بیشتر موارد پیاده‌سازی فقط به پیکربندی مجدد آن کتابخانه برای بازپخش تونل‌شده نیاز دارد. برای پیاده‌سازی سطح پایین پخش‌کننده ویدیو تونل‌شده، از دستورالعمل‌های زیر استفاده کنید.

برای بازپخش ویدیو درخواستی در Android 5 یا بالاتر:

  1. نمونه SurfaceView ایجاد کنید.

  2. نمونه audioSessionId ایجاد کنید.

  3. نمونه‌های AudioTrack و MediaCodec را با نمونه audioSessionId ایجادشده در مرحله ۲ بسازید.

  4. داده‌های صوتی را با مُهر زمان ارائه برای اولین قاب صوتی در داده‌های صوتی در صف AudioTrack قرار دهید.

برای بازپخش پخش زنده در Android نسخه ۱۱ یا بالاتر:

  1. نمونه SurfaceView ایجاد کنید.

  2. نمونه‌ای از avSyncHwId را از Tuner دریافت کنید.

  3. نمونه‌های AudioTrack و MediaCodec را با نمونه avSyncHwId ایجادشده در مرحله ۲ بسازید.

جریان فراخوانی میانای برنامه‌سازی کاربردی در تکه‌کدهای زیر نشان داده شده است:

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 برای قاب‌های صوتی بی‌صدای درج‌شده افزایش نمی‌یابد.

جریان توالی جستجوی دقیق

«جستجوی دقیق» به شما امکان می‌دهد نقطه خاصی را در ویدیو پیدا کنید. برخلاف جستجوی فریم کلیدی که فقط به نزدیک‌ترین فریم I می‌پرد و می‌تواند چند ثانیه از موقعیت هدف منحرف شود، جستجوی دقیق ویدیو را در مُهر زمان دقیق درخواست‌شده ارائه می‌دهد. پیروی از این توالی میانای برنامه‌سازی کاربردی خاص به برنامه امکان می‌دهد پیش‌پخش پس‌زمینه و همگام‌سازی زمان‌بندی را به‌طور یکپارچه انجام دهد. این کار تضمین می‌کند که قاب هدف فوراً هنگام ازسرگیری بازپخش نمایش داده شود.

برای انجام جستجوی دقیق، ترتیب اجرای نشان‌داده‌شده در شکل ۲ را دنبال کنید:

جریان توالی جستجو

شکل ۲. Sequence flow to achieve precise seek.

جزئیات کلیدی شامل موارد زیر است:

  • اجرای موازی: می‌توانید مراحل را به‌طور هم‌زمان در یک چارگوش par اجرا کنید. برای مثال، تماس‌های MediaCodec ویدیویی مستقل از AudioTrack هستند.

  • وابستگی‌های متوالی: قبل‌از رفتن به چارگوش par دوم، همه عملیات‌های داخل چارگوش par اول را فراخوانی کنید. به‌طور خاص، برنامه باید مطمئن شود که AudioTrack.write و میان‌گیرها در ویدیو MediaCodec قبل‌از فراخوانی AudioTrack.play در صف قرار گرفته‌اند.

جریان توالی بازپخش با سرعت متغیر

بازپخش با سرعت متغیر به شما امکان می‌دهد ویدیو را با سرعتی سریع‌تر یا کندتر از سرعت عادی پخش کنید. این ویژگی معمولاً توسط برنامه‌ها استفاده می‌شود تا به کاربران اجازه دهد محتوا را سریع‌تر (مانند پخش سخنرانی‌های آموزشی یا پادکست‌ها با سرعت ۱٫۵ برابر یا ۲٫۰ برابر برای صرفه‌جویی در زمان) یا کندتر (مانند تحلیل بازی‌های ورزشی یا ویدیوهای آموزشی با سرعت ۰٫۵ برابر) مصرف کنند.

برای تنظیم سرعت، ترتیب اجرای نشان‌داده‌شده در «شکل ۳» را دنبال کنید:

جریان توالی سرعت

شکل ۳. جریان توالی برای تنظیم سرعت.

رفتارها و الزامات فنی زیر در نمودار توالی شکل ۳ ثبت نشده است:

  • AudioTrack.getTimestamp براساس فرکانس ورودی صدای اصلی، framePosition را برمی‌گرداند. برای مثال، با ورودی ۴۴۱۰۰ هرتز و سرعت پخش ۲٫۰ برابر، پس‌از پخش ۲ ثانیه، AudioTrack.getTimestamp framePosition ۱۷۶۴۰۰ را برمی‌گرداند.

  • اگر برنامه setSpeed(1.5) را فراخوانی کند و این فراخوانی موفقیت‌آمیز باشد، و سپس برنامه setSpeed(30) را فراخوانی کند و این فراخوانی ناموفق باشد، بازپخش روی سرعت ۱٫۵ برابر باقی می‌ماند.

  • اگر صدا بی‌صدا باشد (بااستفاده از setVolume)، برنامه همچنان باید میان‌گیرهای صوتی را ارسال کند زیرا قاب‌های ویدیو براساس موقعیت صدا رندر می‌شوند.

  • وقتی سرعت تغییر می‌کند، زیروبمی صدا حفظ می‌شود.

  • سرعت بازپخش تحت تأثیر کنش‌های بازپخش دیگر قرار نمی‌گیرد.

    • مثال ۱: اگر سرعت بازپخش ۱٫۵ برابر باشد و AudioTrack موقتاً متوقف شود، سرعت پس‌از ازسرگیری AudioTrack روی ۱٫۵ برابر باقی می‌ماند.

    • مثال ۲: اگر سرعت بازپخش ۱٫۵ برابر باشد و کاربر به PTS دیگری برود، با دنبال کردن شکل ۲، بازپخش روی ۱٫۵ برابر باقی می‌ماند.

  • برای کمک به اطمینان از اینکه همه فریم‌ها به‌موقع رمزگشایی می‌شوند تا با سرعت انتخاب‌شده ارائه شوند، KEY_OPERATING_RATE را طوری تنظیم کنید که با حاصل‌ضرب نرخ فریم ویدیو و سرعت بازپخش مطابقت داشته باشد. اگر KEY_OPERATING_RATE به‌اندازه کافی بالا تنظیم نشده باشد، ممکن است کدک نتواند فریم‌ها را به‌اندازه کافی سریع رمزگشایی کند و این امر باعث افت ناخواسته فریم درطول بازپخش می‌شود.

    • مثال: اگر نرخ فریم اصلی محتوا ۶۰ فریم در ثانیه باشد و سرعت بازپخش ۲ برابر باشد، KEY_OPERATING_RATE را روی 120 تنظیم کنید.
  • تنظیم مکرر سرعت با سرعت‌های پشتیبانی‌شده مختلف نباید هیچ خطایی را راه‌اندازی کند، و رفتار بازپخش پس‌از آخرین فراخوانی باید همانند زمانی باشد که سرعت فقط یک‌بار روی جدیدترین تنظیم سرعت تنظیم شده است.

برای سازندگان دستگاه

پیکربندی

سازندگان اصلی تجهیزات باید رمزگشای ویدیویی جداگانه‌ای برای پشتیبانی از بازپخش ویدیو تونل‌سازی‌شده ایجاد کنند. این رمزگشا باید در فایل media_codecs.xml اعلام کند که قادر به بازپخش تونلی است:

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

وقتی نمونه MediaCodec تونل‌شده با شناسه جلسه صوتی پیکربندی می‌شود، AudioFlinger را برای این شناسه 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);
}

درطول این پُرسمان، 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 باید یک دسته باند جانبی برگرداند که بتوان از آن برای مرتبط کردن کدک با لایه Hardware Composer (HWC) استفاده کرد. وقتی برنامه سطحی را با 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;
}

HWC مسئول دریافت میان‌گیرهای تصویر جدید از خروجی کدک در زمان مناسب است، که یا با جریان خروجی صوتی مرتبط یا ساعت مرجع برنامه تیونر همگام‌سازی می‌شود، میان‌گیرها را با محتویات فعلی لایه‌های دیگر ترکیب می‌کند و تصویر حاصل را نمایش می‌دهد. این اتفاق مستقل از چرخه آماده‌سازی و تنظیم عادی رخ می‌دهد. فراخوانی‌های آماده‌سازی و تنظیم فقط زمانی اتفاق می‌افتند که لایه‌های دیگر تغییر کنند، یا زمانی که ویژگی‌های لایه باند جانبی (مانند موقعیت یا اندازه) تغییر کنند.

OMX

جزء رمزگشای تونل‌شده باید از موارد زیر پشتیبانی کند:

  • تنظیم پارامتر گسترش‌یافته OMX.google.android.index.configureVideoTunnelMode، که از ساختار ConfigureVideoTunnelModeParams برای ارسال شناسه HW_AV_SYNC مرتبط با دستگاه خروجی صوتی استفاده می‌کند.

  • پیکربندی پارامتر 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(mHand&le, name, index);

ConfigureVideoTunnelModeParams tunnelParams;
Init&OMXParams(tunnelParams);
tunnelParams.nPortIndex = portIndex;
tunnelParams.bTunneled = tunneled;
tunnelParams.nAudioHwSync = audioHwSync;
err = OMX_SetParameter(mHandl&e, index, tunnelParams);
err = OMX_GetParameter(mHandl&e, index, tunnelParams);
sidebandHandle = (native_handle_t*)tunnelParams.pSidebandWindow;

اگر مؤلفه از این پیکربندی پشتیبانی می‌کند، باید یک دسته باند جانبی به این کدک اختصاص دهد و آن را ازطریق عضو pSidebandWindow برگرداند تا HWC بتواند کدک مرتبط را شناسایی کند. اگر مؤلفه از این پیکربندی پشتیبانی نمی‌کند، باید bTunneled را روی OMX_FALSE تنظیم کند.

کدک۲

در Android 11 یا بالاتر، Codec2 از بازپخش تونلی پشتیبانی می‌کند. جزء رمزگشا باید از موارد زیر پشتیبانی کند:

  • پیکربندی C2PortTunneledModeTuning، که حالت تونل را پیکربندی می‌کند و HW_AV_SYNC بازیابی‌شده از دستگاه خروجی صوتی یا پیکربندی تیونر را ارسال می‌کند.

  • Querying C2_PARAMKEY_OUTPUT_TUNNEL_HANDLE, to allocate and retrieve the sideband handle for HWC.

  • Handling C2_PARAMKEY_TUNNEL_HOLD_RENDER when attached to a C2Work, which instructs the codec to decode and signal work completion, but not to render the output buffer until either 1) the codec is later instructed to render it or 2) audio playback begins.

  • درحال رسیدگی به C2_PARAMKEY_TUNNEL_START_RENDER، که به کدک دستور می‌دهد فوراً قابی را که با C2_PARAMKEY_TUNNEL_HOLD_RENDER علامت‌گذاری شده است پرداخت کند، حتی اگر بازپخش صدا شروع نشده باشد.

  • debug.stagefright.ccodec_delayed_params را پیکربندی‌نشده رها کنید (توصیه‌شده). اگر آن را پیکربندی می‌کنید، روی false تنظیم کنید.

پیاده‌سازی AOSP حالت تونل را در CCodec ازطریق C2PortTunnelModeTuning پیکربندی می‌کند، همان‌طور که در تکه‌کد زیر نشان داده شده است:

if (msg->findInt32("audio-hw-sy&nc", tunnele>dPlayback-m.syncId[0])) {
    tunnele>dPlayback-m.syncType =
            C2PortTunneledModeTuning::Struct::sync_type_t::AUDIO_HW_SYNC;
} els>e if (msg-findInt32("h&w-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_st>atus_t c2err = comp-config({ tunneledPlayback.get() }, C2_MAY_BLOCK,
        fa<ilures);
std::v<ectorst>>d::unique_ptrC2Param p>arams;
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 برگرداند تا HWC بتواند کدک مرتبط را شناسایی کند.

لایه انتزاع سخت‌افزار صوتی

برای بازپخش ویدیو درخواستی، Audio HAL مُهرهای زمان ارائه صوتی را به‌صورت درون‌خطی با داده‌های صوتی در قالب big-endian در داخل سرصفحه‌ای که در ابتدای هر بلوک از داده‌های صوتی که برنامه می‌نویسد دریافت می‌کند:

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

برای اینکه HWC فریم‌های ویدیو را هم‌زمان با فریم‌های صوتی مربوطه ارائه دهد، Audio HAL باید سرصفحه هم‌زمان‌سازی را تجزیه کند و از مُهر زمان ارائه برای هم‌زمان‌سازی مجدد ساعت بازپخش با ارائه صدا استفاده کند. برای همگام‌سازی مجدد هنگام پخش صدای فشرده‌شده، ممکن است Audio HAL نیاز به تجزیه فراداده در داخل داده‌های صوتی فشرده‌شده داشته باشد تا مدت زمان پخش آن را تعیین کند.

توقف موقت پشتیبانی

Android 5 یا پایین‌تر از توقف موقت پشتیبانی نمی‌کند. بازپخش تونل‌شده را فقط با کمبود صدا/تصویر می‌توانید موقتاً متوقف کنید، اما اگر میان‌گیر داخلی برای ویدیو بزرگ باشد (برای مثال، یک ثانیه داده در مؤلفه OMX وجود داشته باشد)، باعث می‌شود توقف موقت غیرپاسخگو به‌نظر برسد.

در Android نسخه ۵.۱ یا بالاتر، AudioFlinger از توقف موقت و ازسرگیری برای خروجی‌های صوتی مستقیم (تونل‌شده) پشتیبانی می‌کند. اگر HAL توقف موقت و ازسرگیری را پیاده‌سازی کند، توقف موقت و ازسرگیری قطعه به HAL بازارسال می‌شود.

توالی فراخوانی مکث، تخلیه، ازسرگیری با اجرای فراخوانی‌های HAL در رشته بازپخش (همانند باربرداری) رعایت می‌شود.

پیشنهادهای پیاده‌سازی

لایه انتزاع سخت‌افزار صوتی

برای Android 11، شناسه همگام‌سازی سخت‌افزاری از PCR یا STC می‌تواند برای همگام‌سازی صوتی/تصویری استفاده شود، بنابراین جریان فقط ویدیویی پشتیبانی می‌شود.

برای Android نسخه ۱۰ یا پایین‌تر، دستگاه‌هایی که از بازپخش ویدیو تونل‌شده پشتیبانی می‌کنند باید حداقل یک نمایه جاری‌سازی خروجی صدا با پرچم‌های FLAG_HW_AV_SYNC و AUDIO_OUTPUT_FLAG_DIRECT در فایل audio_policy.conf خود داشته باشند. از این پرچم‌ها برای تنظیم ساعت سیستم از ساعت صوتی استفاده می‌شود.

OMX

سازندگان دستگاه باید مؤلفه OMX جداگانه‌ای برای بازپخش ویدیو تونل‌شده داشته باشند (سازندگان می‌توانند مؤلفه‌های OMX دیگری برای انواع دیگر بازپخش صوتی و ویدیویی، مانند بازپخش ایمن، داشته باشند). جزء تونل‌شده باید:

  • ‫۰ میان‌گیر (nBufferCountMin، nBufferCountActual) را در درگاه خروجی‌اش مشخص می‌کند.

  • افزونه OMX.google.android.index.prepareForAdaptivePlayback setParameter را پیاده‌سازی کنید.

  • قابلیت‌های آن را در فایل media_codecs.xml مشخص کنید و ویژگی بازپخش تونل‌شده را اعلام کنید. همچنین باید هرگونه محدودیت در اندازه قاب، تراز، یا نرخ بیت را روشن کند. نمونه‌ای در زیر نشان داده شده است:

    <MediaCodec name="OMX.OEM_NAME.VIDEO.DECODER.AVC.tunneled"
    type=&q>uot;v<ideo/avc" 
        Feature name=&>quot;<adaptive-playback" /
        Feature name="t>unnel<ed-playback" required=”true” /
        Limit n>ame=&<quot;size" min="32x32">; max<="3840x2160" /
        Limit name=&>quot;alignmen<t" val>ue="2x2" /
        Limit name="bitrate" range="1-20000000" /
            ...
    /MediaCodec
    

اگر از همان مؤلفه OMX برای پشتیبانی از رمزگشایی تونل‌شده و غیرتونل‌شده استفاده می‌شود، باید ویژگی بازپخش تونل‌شده را به‌عنوان غیرالزامی رها کند. سپس هر دو رمزگشای تونل‌شده و تونل‌نشده محدودیت‌های قابلیت یکسانی دارند. نمونه‌ای در زیر نشان داده شده است:

<MediaCodec name="OMX._OEM\_NAME_.VIDEO.DECODER.AVC" type=&q>uot;v<ideo/avc" 
    Feature name=&>quot;<adaptive-playback" /
    Feat>ure n<ame="tunneled-playback" /
    Limit n>ame=&<quot;size" min="32x32">; max<="3840x2160" /
    Limit name=&>quot;alignmen<t" val>ue="2x2" /
    Limit name="bitrate" range="1-20000000" /
        ...
/MediaCodec

آهنگ‌ساز سخت‌افزار (HWC)

وقتی لایه تونل‌شده‌ای (لایه با HWC_SIDEBAND compositionType) در نمایشگر وجود دارد، sidebandStream لایه همان دسته باند جانبی است که توسط مؤلفه ویدیویی OMX اختصاص داده شده است.

HWC فریم‌های ویدیو رمزگشایی‌شده (از مؤلفه OMX تونل‌شده) را با قطعه صوتی مرتبط (با شناسه audio-hw-sync) همگام‌سازی می‌کند. وقتی فریم ویدیو جدیدی جاری می‌شود، HWC آن را با محتوای جاری همه لایه‌های دریافت‌شده درطول آخرین فراخوانی آماده‌سازی یا تنظیم ترکیب می‌کند و تصویر حاصل را نمایش می‌دهد. فراخوانی‌های آماده‌سازی یا تنظیم فقط زمانی اتفاق می‌افتد که لایه‌های دیگر تغییر کنند، یا زمانی که ویژگی‌های لایه باند جانبی (مانند موقعیت یا اندازه) تغییر کنند.

شکل زیر نشان‌دهنده HWC است که با همگام‌ساز سخت‌افزار (یا هسته یا درایور) کار می‌کند تا فریم‌های ویدیو (7b) را با جدیدترین ترکیب‌بندی (7a) برای نمایش در زمان صحیح، براساس صدا (7c)، ترکیب کند.

HWC درحال ترکیب فریم‌های ویدیو براساس صدا

شکل ۴. همگام‌ساز سخت‌افزار HWC (یا هسته یا درایور).