چارچوب تیونر

برای اندروید ۱۱ یا بالاتر، می‌توانید از چارچوب Android Tuner برای ارائه محتوای A/V استفاده کنید. این چارچوب از خط لوله سخت‌افزاری فروشندگان استفاده می‌کند و آن را برای SoCهای رده پایین و بالا مناسب می‌سازد. این چارچوب روشی امن برای ارائه محتوای A/V محافظت‌شده توسط یک محیط اجرای قابل اعتماد (TEE) و مسیر رسانه‌ای امن (SMP) فراهم می‌کند و امکان استفاده از آن را در یک محیط محافظت از محتوا با محدودیت بالا فراهم می‌کند.

رابط استاندارد بین Tuner و Android CAS منجر به ادغام سریع‌تر بین فروشندگان Tuner و فروشندگان CAS می‌شود. رابط Tuner با MediaCodec و AudioTrack کار می‌کند تا یک راه‌حل جهانی برای Android TV ایجاد کند. رابط Tuner از تلویزیون دیجیتال و تلویزیون آنالوگ بر اساس استانداردهای اصلی پخش پشتیبانی می‌کند.

قطعات

برای اندروید ۱۱، سه جزء به طور خاص برای پلتفرم تلویزیون طراحی شده‌اند.

  • تنظیم‌کننده HAL: رابطی بین چارچوب و فروشندگان
  • رابط برنامه‌نویسی کیت توسعه نرم‌افزار (SDK API) تیونر: رابطی بین چارچوب و برنامه‌ها
  • مدیر منابع تیونر (TRM): منابع سخت‌افزاری تیونر را هماهنگ می‌کند.

برای اندروید ۱۱، اجزای زیر بهبود یافته‌اند.

  • CAS V2
  • سرویس ورودی TvInputService یا TIS
  • سرویس مدیریت ورودی تلویزیون (TIMS) یا TvInputManagerService
  • MediaCodec یا کدک رسانه
  • AudioTrack یا آهنگ صوتی
  • MediaResourceManager یا مدیر منابع رسانه (MRM)

نمودار جریان اجزای چارچوب Tuner.

شکل 1. تعاملات بین اجزای تلویزیون اندروید

ویژگی‌ها

فرانت‌اند از استانداردهای DTV زیر پشتیبانی می‌کند.

  • ATSC
  • ATSC3
  • دی‌وی‌بی سی/اس/تی
  • ISDB S/S3/T
  • آنالوگ

رابط کاربری در اندروید ۱۲ با Tuner HAL 1.1 یا بالاتر از استاندارد DTV زیر پشتیبانی می‌کند.

  • دی‌تی‌ام‌بی

Demux از پروتکل‌های استریم زیر پشتیبانی می‌کند.

  • جریان حمل و نقل (TS)
  • پروتکل انتقال رسانه MPEG (MMTP)
  • پروتکل اینترنت (IP)
  • مقدار طول نوع (TLV)
  • پروتکل لایه پیوند ATSC (ALP)

Descrambler از محافظت‌های محتوای زیر پشتیبانی می‌کند.

  • مسیر رسانه‌ای امن
  • مسیر رسانه را پاک کنید
  • رکورد محلی امن
  • پخش محلی امن

APIهای تنظیم‌کننده از موارد استفاده زیر پشتیبانی می‌کنند.

  • اسکن
  • زنده
  • پخش
  • رکورد

Tuner، MediaCodec و AudioTrack از حالت‌های جریان داده زیر پشتیبانی می‌کنند.

  • بار داده ES با پاک کردن بافر حافظه
  • بار داده ES با مدیریت حافظه امن
  • عبور

طراحی کلی

Tuner HAL بین چارچوب اندروید و سخت‌افزار فروشنده تعریف شده است.

  • توصیف می‌کند که چارچوب از فروشنده چه انتظاری دارد و فروشنده چگونه می‌تواند آن را انجام دهد.
  • قابلیت‌های frontend، demux و descrambler را از طریق رابط‌های IFrontend ، IDemux ، IDescrambler ، IFilter ، IDvr و ILnb به فریم‌ورک منتقل می‌کند.
  • شامل توابعی برای ادغام Tuner HAL با سایر اجزای چارچوب، مانند MediaCodec و AudioTrack است.

یک کلاس Tuner Java و یک کلاس native ایجاد می‌شوند.

  • رابط برنامه‌نویسی کاربردی جاوای Tuner به برنامه‌ها اجازه می‌دهد تا از طریق APIهای عمومی به Tuner HAL دسترسی داشته باشند.
  • کلاس Native امکان کنترل مجوز و مدیریت حجم زیادی از داده‌های ضبط یا پخش را با Tuner HAL فراهم می‌کند.
  • ماژول Native Tuner پلی بین کلاس Tuner Java و Tuner HAL است.

یک کلاس TRM ایجاد می‌شود.

  • منابع محدود تیونر، مانند Frontend، LNB، جلسات CAS و یک دستگاه ورودی تلویزیون از ورودی تلویزیون HAL را مدیریت می‌کند.
  • قوانینی را برای بازپس‌گیری منابع ناکافی از برنامه‌ها اعمال می‌کند. قانون پیش‌فرض، پیروزی در پیش‌زمینه است.

Media CAS و CAS HAL با ویژگی‌های زیر بهبود یافته‌اند.

  • جلسات CAS را برای کاربردها و الگوریتم‌های مختلف باز می‌کند.
  • از سیستم‌های CAS پویا، مانند حذف و درج CICAM، پشتیبانی می‌کند.
  • با ارائه توکن‌های کلیدی با تیونر HAL ادغام می‌شود.

MediaCodec و AudioTrack با ویژگی‌های زیر بهبود یافته‌اند.

  • حافظه امن A/V را به عنوان ورودی محتوا در نظر می‌گیرد.
  • طوری پیکربندی شده که همگام‌سازی سخت‌افزاری صدا/تصویر را در پخش تونلی انجام دهد.
  • پشتیبانی پیکربندی‌شده برای ES_payload و حالت عبور.

طراحی کلی تیونر HAL.

شکل ۲. نمودار اجزای درون تیونر HAL

گردش کار کلی

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

راه‌اندازی

ترتیب تنظیمات نمودار پخش زنده.

شکل ۳. ترتیب تنظیمات برای پخش زنده

مدیریت سیستم صوتی و تصویری

نمودار پخش زنده با قابلیت مدیریت A/V.

شکل ۴. مدیریت A/V برای پخش زنده

مدیریت محتوای درهم‌ریخته

مدیریت محتوای درهم‌ریخته برای نمودار پخش زنده.

شکل ۵. مدیریت محتوای درهم‌ریخته برای پخش زنده

پردازش داده‌های صوتی/تصویری

پردازش داده‌های A/V برای نمودار پخش زنده.

شکل ۶. پردازش A/V برای پخش زنده

رابط برنامه‌نویسی نرم‌افزار تیونر SDK

رابط برنامه‌نویسی نرم‌افزار Tuner SDK، تعاملات با Tuner JNI، Tuner HAL و TunerResourceManager مدیریت می‌کند. برنامه TIS از رابط برنامه‌نویسی نرم‌افزار Tuner SDK برای دسترسی به منابع و زیرکامپوننت‌های Tuner مانند فیلتر و رمزگشایی استفاده می‌کند. Frontend و demux اجزای داخلی هستند.

نمودار جریان رابط برنامه‌نویسی نرم‌افزار Tuner SDK.

شکل 7. تعاملات با رابط برنامه‌نویسی نرم‌افزار Tuner SDK

نسخه‌ها

از اندروید ۱۲، رابط برنامه‌نویسی کاربردی Tuner SDK از ویژگی جدید Tuner HAL 1.1 پشتیبانی می‌کند که یک نسخه ارتقا یافته سازگار با نسخه‌های قبلی Tuner 1.0 است.

برای بررسی نسخه HAL در حال اجرا از API زیر استفاده کنید.

  • android.media.tv.tuner.TunerVersionChecker.getTunerVersion()

حداقل نسخه HAL مورد نیاز را می‌توانید در مستندات APIهای جدید اندروید ۱۲ پیدا کنید.

بسته‌ها

رابط برنامه‌نویسی نرم‌افزار Tuner SDK چهار بسته زیر را ارائه می‌دهد.

  • android.media.tv.tuner
  • android.media.tv.tuner.frontend
  • android.media.tv.tuner.filter
  • android.media.tv.tuner.dvr

نمودار جریان بسته‌های API کیت توسعه نرم‌افزار (SDK) تیونر.

شکل 8. بسته‌های API کیت توسعه نرم‌افزار تیونر

تیونر.اندروید.رسانه.تلویزیون

پکیج Tuner نقطه ورود برای استفاده از چارچوب Tuner است. اپلیکیشن TIS از این پکیج برای مقداردهی اولیه و دریافت نمونه‌های منبع با مشخص کردن تنظیمات اولیه و فراخوانی مجدد استفاده می‌کند.

  • tuner() : با مشخص کردن پارامترهای useCase و sessionId ، یک نمونه Tuner را مقداردهی اولیه می‌کند.
  • tune() : یک منبع frontend را دریافت کرده و با تعیین پارامتر FrontendSetting آن را تنظیم می‌کند.
  • openFilter() : با مشخص کردن نوع فیلتر، یک نمونه فیلتر دریافت می‌کند.
  • openDvrRecorder() : با مشخص کردن اندازه بافر، یک نمونه ضبط را دریافت می‌کند.
  • openDvrPlayback() : با مشخص کردن اندازه بافر، یک نمونه پخش را دریافت می‌کند.
  • openDescrambler() یک نمونه از descrambler را دریافت می‌کند.
  • openLnb() : یک نمونه LNB داخلی را دریافت می‌کند.
  • openLnbByName() : یک نمونه LNB خارجی را دریافت می‌کند.
  • openTimeFilter() : یک نمونه فیلتر زمان را دریافت می‌کند.

بسته Tuner قابلیت‌هایی را ارائه می‌دهد که در بسته‌های filter، DVR و frontend پوشش داده نمی‌شوند. این قابلیت‌ها در زیر فهرست شده‌اند.

  • cancelTuning
  • scan / cancelScanning
  • getAvSyncHwId
  • getAvSyncTime
  • connectCiCam1 / disconnectCiCam
  • shareFrontendFromTuner
  • updateResourcePriority
  • setOnTuneEventListener
  • setResourceLostListener

اندروید.رسانه.تلویزیون.تیونر.ظاهر

بسته frontend شامل مجموعه‌ای از تنظیمات، اطلاعات، وضعیت‌ها، رویدادها و قابلیت‌های مرتبط با frontend است.

کلاس‌ها

FrontendSettings برای استانداردهای مختلف تلویزیون دیجیتال (DTV) توسط کلاس‌های زیر مشتق شده است.

  • AnalogFrontendSettings
  • Atsc3FrontendSettings
  • AtscFrontendSettings
  • DvbcFrontendSettings
  • DvbsFrontendSettings
  • DvbtFrontendSettings
  • Isdbs3FrontendSettings
  • IsdbsFrontendSettings
  • IsdbtFrontendSettings

از اندروید ۱۲ با تیونر HAL 1.1 یا بالاتر، استاندارد DTV زیر پشتیبانی می‌شود.

  • DtmbFrontendSettings

FrontendCapabilities برای استانداردهای مختلف DTV توسط کلاس‌های زیر استخراج می‌شود.

  • AnalogFrontendCapabilities
  • Atsc3FrontendCapabilities
  • AtscFrontendCapabilities
  • DvbcFrontendCapabilities
  • DvbsFrontendCapabilities
  • DvbtFrontendCapabilities
  • Isdbs3FrontendCapabilities
  • IsdbsFrontendCapabilities
  • IsdbtFrontendCapabilities

از اندروید ۱۲ با تیونر HAL 1.1 یا بالاتر، استاندارد DTV زیر پشتیبانی می‌شود.

  • DtmbFrontendCapabilities

FrontendInfo اطلاعات مربوط به frontend را بازیابی می‌کند. FrontendStatus وضعیت فعلی frontend را بازیابی می‌کند. OnTuneEventListener به رویدادهای frontend گوش می‌دهد. برنامه TIS از ScanCallback برای پردازش پیام‌های اسکن از frontend استفاده می‌کند.

اسکن کانال

برای تنظیم تلویزیون، برنامه فرکانس‌های ممکن را اسکن می‌کند و یک فهرست کانال برای دسترسی کاربران ایجاد می‌کند. TIS ممکن است از Tuner.tune ، Tuner.scan(BLIND_SCAN) یا Tuner.scan(AUTO_SCAN) برای تکمیل اسکن کانال استفاده کند.

اگر TIS اطلاعات دقیقی از نحوه‌ی دریافت سیگنال، مانند فرکانس، استاندارد (مثلاً T/T2، S/S2) و اطلاعات ضروری اضافی (مثلاً PLD ID) داشته باشد، Tuner.tune به عنوان گزینه‌ی سریع‌تر توصیه می‌شود.

وقتی کاربر Tuner.tune را فراخوانی می‌کند، اقدامات زیر اتفاق می‌افتد:

  • TIS با استفاده از Tuner.tune اطلاعات مورد نیاز FrontendSettings را پر می‌کند.
  • اگر سیگنال قفل شده باشد، HAL پیام‌های tune LOCKED را گزارش می‌دهد.
  • TIS از Frontend.getStatus برای جمع‌آوری اطلاعات لازم استفاده می‌کند.
  • TIS به فرکانس موجود بعدی در لیست فرکانس‌های خود منتقل می‌شود.

TIS دوباره Tuner.tune فراخوانی می‌کند تا زمانی که همه فرکانس‌ها به پایان برسند.

در حین تنظیم، می‌توانید برای مکث یا پایان دادن به فراخوانی Tuner.tune ، از stopTune() یا close() استفاده کنید.

اسکن تیونر (اسکن خودکار)

اگر TIS اطلاعات کافی برای استفاده از Tuner.tune نداشته باشد، اما لیست فرکانس و نوع استاندارد (مثلاً DVB T/C/S) را داشته باشد، Tuner.scan(AUTO_SCAN) توصیه می‌شود.

وقتی کاربر تابع Tuner.scan(AUTO_SCAN) را فراخوانی می‌کند، اقدامات زیر اتفاق می‌افتد:

  • TIS از Tuner.scan(AUTO_SCAN) به همراه FrontendSettings پر شده با فرکانس استفاده می‌کند.

  • اگر سیگنال قفل شده باشد، HAL پیام‌های اسکن LOCKED را گزارش می‌دهد. HAL همچنین ممکن است پیام‌های اسکن دیگری را برای ارائه اطلاعات بیشتر در مورد سیگنال گزارش دهد.

  • TIS از Frontend.getStatus برای جمع‌آوری اطلاعات لازم استفاده می‌کند.

  • TIS تابع Tuner.scan را برای HAL فراخوانی می‌کند تا به تنظیمات بعدی روی همان فرکانس ادامه دهد. اگر ساختار FrontendSettings خالی باشد، HAL از تنظیمات بعدی موجود استفاده می‌کند. در غیر این صورت، HAL از FrontendSettings برای یک اسکن یک‌باره استفاده می‌کند و END برای اعلام اتمام عملیات اسکن ارسال می‌کند.

  • TIS اقدامات بالا را تا زمانی که تمام تنظیمات روی فرکانس به پایان برسد، تکرار می‌کند.

  • HAL با ارسال END اعلام می‌کند که عملیات اسکن به پایان رسیده است.

  • TIS به فرکانس موجود بعدی در لیست فرکانس‌های خود منتقل می‌شود.

TIS تابع Tuner.scan(AUTO_SCAN) را دوباره فراخوانی می‌کند تا زمانی که تمام فرکانس‌ها به پایان برسند.

در حین اسکن، می‌توانید برای مکث یا پایان دادن به اسکن، تابع‌های stopScan() یا close() را فراخوانی کنید.

اسکن تیونر (BLIND_SCAN)

اگر TIS لیست فرکانس نداشته باشد و فروشنده HAL بتواند فرکانس frontend مشخص شده توسط کاربر را برای دریافت منبع frontend جستجو کند، Tuner.scan(BLIND_SCAN) توصیه می‌شود.

  • TIS از Tuner.scan(BLIND_SCAN) استفاده می‌کند. می‌توان فرکانسی را در FrontendSettings برای فرکانس شروع مشخص کرد، اما TIS سایر تنظیمات موجود در FrontendSettings را نادیده می‌گیرد.
  • اگر سیگنال قفل شده باشد، HAL یک پیام اسکن LOCKED را گزارش می‌دهد.
  • TIS از Frontend.getStatus برای جمع‌آوری اطلاعات لازم استفاده می‌کند.
  • TIS دوباره Tuner.scan را برای ادامه اسکن فراخوانی می‌کند. ( FrontendSettings نادیده گرفته می‌شود.)
  • TIS اقدامات فوق را تا زمانی که تمام تنظیمات روی فرکانس به پایان برسد، تکرار می‌کند. HAL فرکانس را بدون نیاز به هیچ اقدامی از TIS افزایش می‌دهد. HAL PROGRESS را گزارش می‌دهد.

TIS دوباره Tuner.scan(AUTO_SCAN) را فراخوانی می‌کند تا زمانی که همه فرکانس‌ها به پایان برسند. HAL END را گزارش می‌دهد تا نشان دهد که عملیات اسکن پایان یافته است.

در حین اسکن، می‌توانید برای مکث یا پایان دادن به اسکن، تابع‌های stopScan() یا close() را فراخوانی کنید.

نمودار جریان فرآیند اسکن TIS.

شکل ۹. نمودار جریان یک اسکن TIS

فیلتر.تیونر.رسانه.تلویزیون.اندروید

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

  • configure()
  • start()
  • stop()
  • flush()
  • read()

برای مشاهده لیست کامل به کد منبع اندروید مراجعه کنید.

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

  • AlpFilterConfiguration
  • IpFilterConfiguration
  • MmtpFilterConfiguration
  • TlvFilterConfiguration
  • TsFilterConfiguration

تنظیمات از کلاس‌های زیر گرفته شده‌اند. این تنظیمات برای زیرگروه فیلتر هستند و مشخص می‌کنند که فیلتر چه نوع داده‌هایی را می‌تواند حذف کند.

  • SectionSettings
  • AvSettings
  • PesSettings
  • RecordSettings
  • DownloadSettings

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

  • SectionEvent
  • MediaEvent
  • PesEvent
  • TsRecordEvent
  • MmtpRecordEvent
  • TemiEvent
  • DownloadEvent
  • IpPayloadEvent

از اندروید ۱۲ با Tuner HAL 1.1 یا بالاتر، رویدادهای زیر پشتیبانی می‌شوند.

  • IpCidChangeEvent
  • RestartEvent
  • ScramblingStatusEvent
رویدادها و قالب داده‌ها از فیلتر
نوع فیلتر پرچم‌ها رویدادها عملیات داده قالب داده
TS.SECTION
MMTP.SECTION
IP.SECTION
TLV.SECTION
ALP.SECTION
isRaw:
true
اجباری:
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW

توصیه شده:
DemuxFilterStatus::LOW_WATER
DemuxFilterStatus::HIGH_WATER
طبق برنامه رویداد و داخلی، اجرا کنید
یک یا چند بار Filter.read(buffer, offset, adjustedSize) .

داده‌ها از MQ مربوط به HAL به بافر کلاینت کپی می‌شوند.
یک بسته جلسه مونتاژ شده توسط یک بسته جلسه دیگر در FMQ پر می‌شود.
isRaw:
false
اجباری:
DemuxFilterEvent::DemuxFilterSectionEvent[n]
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW

اختیاری:
DemuxFilterStatus::LOW_WATER
DemuxFilterStatus::HIGH_WATER
for i=0; i<n; i++
Filter.read(buffer, offset, DemuxFilterSectionEven[i].size)


داده‌ها از MQ مربوط به HAL به بافر کلاینت کپی می‌شوند.
TS.PES isRaw:
true
اجباری:
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW

توصیه شده:
DemuxFilterStatus::LOW_WATER
DemuxFilterStatus::HIGH_WATER
طبق برنامه رویداد و داخلی، اجرا کنید
یک یا چند بار Filter.read(buffer, offset, adjustedSize) .

داده‌ها از MQ مربوط به HAL به بافر کلاینت کپی می‌شوند.
یک بسته PES مونتاژ شده توسط یک بسته PES دیگر در FMQ پر می‌شود.
isRaw:
false
اجباری:
DemuxFilterEvent::DemuxFilterPesEvent[n]
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW

اختیاری:
DemuxFilterStatus::LOW_WATER
DemuxFilterStatus::HIGH_WATER
for i=0; i<n; i++
Filter.read(buffer, offset, DemuxFilterPesEven[i].size)


داده‌ها از MQ مربوط به HAL به بافر کلاینت کپی می‌شوند.
MMTP.PES isRaw:
true
اجباری:
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW

توصیه شده:
DemuxFilterStatus::LOW_WATER
DemuxFilterStatus::HIGH_WATER
طبق برنامه رویداد و داخلی، اجرا کنید
یک یا چند بار Filter.read(buffer, offset, adjustedSize) .

داده‌ها از MQ مربوط به HAL به بافر کلاینت کپی می‌شوند.
یک بسته MFU مونتاژ شده توسط یک بسته MFU دیگر در FMQ پر می‌شود.
isRaw:
false
اجباری:
DemuxFilterEvent::DemuxFilterPesEvent[n]
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW

اختیاری:
DemuxFilterStatus::LOW_WATER
DemuxFilterStatus::HIGH_WATER
for i=0; i<n; i++
Filter.read(buffer, offset, DemuxFilterPesEven[i].size)


داده‌ها از MQ مربوط به HAL به بافر کلاینت کپی می‌شوند.
TS.TS
ناموجود اجباری:
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW

توصیه شده:
DemuxFilterStatus::LOW_WATER
DemuxFilterStatus::HIGH_WATER
طبق برنامه رویداد و داخلی، اجرا کنید
یک یا چند بار Filter.read(buffer, offset, adjustedSize) .

داده‌ها از MQ مربوط به HAL به بافر کلاینت کپی می‌شوند.
ts را با هدر ts فیلتر کرد
در FMQ پر شده است.
TS.Audio
TS.Video
MMTP.Audio
MMTP.Video
isPassthrough:
true
اختیاری:
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW
کلاینت می‌تواند پس از دریافت DemuxFilterStatus::DATA_READY ، MediaCodec اجرا کند.
کلاینت می‌تواند پس از دریافت DemuxFilterStatus::DATA_OVERFLOW تابع Filter.flush را فراخوانی کند.
ناموجود
isPassthrough:
false
اجباری:
DemuxFilterEvent::DemuxFilterMediaEvent[n]
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW

اختیاری:
DemuxFilterStatus::LOW_WATER
DemuxFilterStatus::HIGH_WATER
برای استفاده از MediaCodec :
for i=0; i<n; i++
linearblock = MediaEvent[i].getLinearBlock();
codec.startQueueLinearBlock(linearblock)
linearblock.recycle()


برای استفاده از صدای مستقیم AudioTrack :
for i=0; i<n; i++
audioHandle = MediaEvent[i].getAudioHandle();
audiotrack.write(encapsulated(audiohandle))
داده‌های ES یا ES جزئی در حافظه ION.
TS.PCR
IP.NTP
ALP.PTP
ناموجود اجباری: ناموجود
اختیاری: ناموجود
ناموجود ناموجود
TS.RECORD ناموجود اجباری:
DemuxFilterEvent::DemuxFilterTsRecordEvent[n]
RecordStatus::DATA_READY
RecordStatus::DATA_OVERFLOW
RecordStatus::LOW_WATER
RecordStatus::HIGH_WATER

اختیاری:
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW
DemuxFilterStatus::LOW_WATER
DemuxFilterStatus::HIGH_WATER
برای داده‌های شاخص:
for i=0; i<n; i++
DemuxFilterTsRecordEvent[i];


برای محتوای ضبط‌شده ، طبق RecordStatus::* و برنامه داخلی، یکی از موارد زیر را انجام دهید:
  • دستور DvrRecord.write(adustedSize) را یک یا چند بار در حافظه اجرا کنید.
    داده‌ها از MQ مربوط به HAL به حافظه منتقل می‌شوند.
  • برای بافر کردن، یک یا چند بار DvrRecord.write(buffer, adustedSize) را اجرا کنید.
    داده‌ها از MQ مربوط به HAL به بافر کلاینت کپی می‌شوند.
برای داده‌های شاخص: در بار مفید رویداد حمل می‌شود.

برای محتوای ضبط‌شده: جریان TS ترکیبی (Muxed TS) پر شده با FMQ.
TS.TEMI ناموجود اجباری:
DemuxFilterEvent::DemuxFilterTemiEvent[n]

اختیاری:
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW
DemuxFilterStatus::LOW_WATER
DemuxFilterStatus::HIGH_WATER
for i=0; i<n; i++
DemuxFilterTemiEvent[i];
ناموجود
MMTP.MMTP ناموجود اجباری:
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW

توصیه شده:
DemuxFilterStatus::LOW_WATER
DemuxFilterStatus::HIGH_WATER
طبق برنامه رویداد و داخلی، اجرا کنید
یک یا چند بار Filter.read(buffer, offset, adjustedSize) .

داده‌ها از MQ مربوط به HAL به بافر کلاینت کپی می‌شوند.
mmtp با هدر mmtp فیلتر شده است
در FMQ پر شده است.
MMTP.RECORD ناموجود اجباری:
DemuxFilterEvent::DemuxFilterMmtpRecordEvent[n]
RecordStatus::DATA_READY
RecordStatus::DATA_OVERFLOW
RecordStatus::LOW_WATER
RecordStatus::HIGH_WATER

اختیاری:
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW
DemuxFilterStatus::LOW_WATER
DemuxFilterStatus::HIGH_WATER
برای داده‌های شاخص: for i=0; i<n; i++
DemuxFilterMmtpRecordEvent[i];


برای محتوای ضبط‌شده ، طبق RecordStatus::* و برنامه داخلی، یکی از موارد زیر را انجام دهید:
  • دستور DvrRecord.write(adjustedSize) را یک یا چند بار در حافظه اجرا کنید.
    داده‌ها از MQ مربوط به HAL به حافظه منتقل می‌شوند.
  • برای بافر کردن، یک یا چند بار DvrRecord.write(buffer, adjustedSize) را اجرا کنید.
    داده‌ها از MQ مربوط به HAL به بافر کلاینت کپی می‌شوند.
برای داده‌های شاخص: در بار مفید رویداد حمل می‌شود.

برای محتوای ضبط‌شده: جریان ضبط‌شده‌ی ترکیبی (Muxed) که با FMQ پر شده است.

اگر منبع فیلتر برای ضبط، TLV.TLV به IP.IP با گذرگاه باشد، جریان ضبط شده دارای سرآیند TLV و IP است.
MMTP.DOWNLOAD ناموجود اجباری:
DemuxFilterEvent::DemuxFilterDownloadEvent[n]
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW

اختیاری:
DemuxFilterStatus::LOW_WATER
DemuxFilterStatus::HIGH_WATER
for i=0; i<n; i++ Filter.read(buffer, offset, DemuxFilterDownloadEvent[i].size)

داده‌ها از MQ مربوط به HAL به بافر کلاینت کپی می‌شوند.
بسته دانلود در FMQ توسط یک بسته دانلود IP دیگر پر شده است.
IP.IP_PAYLOAD ناموجود اجباری:
DemuxFilterEvent::DemuxFilterIpPayloadEvent[n]
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW

اختیاری:
DemuxFilterStatus::LOW_WATER
DemuxFilterStatus::HIGH_WATER
for i=0; i<n; i++ Filter.read(buffer, offset, DemuxFilterIpPayloadEvent[i].size)

داده‌ها از MQ مربوط به HAL به بافر کلاینت کپی می‌شوند.
بسته‌ی بار اطلاعاتی IP در FMQ توسط یک بسته‌ی بار اطلاعاتی IP دیگر پر می‌شود.
IP.IP
TLV.TLV
ALP.ALP
isPassthrough:
true
اختیاری:
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW
زیرجریان پروتکل فیلتر شده، فیلتر بعدی در زنجیره فیلتر را تغذیه می‌کند. ناموجود
isPassthrough:
false
اجباری:
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW

توصیه شده:
DemuxFilterStatus::LOW_WATER
DemuxFilterStatus::HIGH_WATER
طبق برنامه رویداد و داخلی، اجرا کنید
یک یا چند بار Filter.read(buffer, offset, adjustedSize) .

داده‌ها از MQ مربوط به HAL به بافر کلاینت کپی می‌شوند.
زیرجریان پروتکل فیلتر شده با سرآیند پروتکل در FMQ پر می‌شود.
IP.PAYLOAD_THROUGH
TLV.PAYLOAD_THROUGH
ALP.PAYLOAD_THROUGH
ناموجود اختیاری:
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW
بار مفید پروتکل فیلتر شده، فیلتر بعدی در زنجیره فیلتر را تغذیه می‌کند. ناموجود
مثالی از جریان استفاده از فیلتر برای ساخت PSI/SI

مثالی از جریان کار با استفاده از فیلتر برای ساخت PSI/SI.

شکل 10. جریان برای ساخت PSI/SI

  1. یک فیلتر باز کنید.

    Filter filter = tuner.openFilter(
      Filter.TYPE_TS,
      Filter.SUBTYPE_SECTION,
      /* bufferSize */1000,
      executor,
      filterCallback
    );
    
  2. فیلتر را پیکربندی و شروع کنید.

    Settings settings = SectionSettingsWithTableInfo
        .builder(Filter.TYPE_TS)
        .setTableId(2)
        .setVersion(1)
        .setCrcEnabled(true)
        .setRaw(false)
        .setRepeat(false)
        .build();
      FilterConfiguration config = TsFilterConfiguration
        .builder()
        .setTpid(10)
        .setSettings(settings)
        .build();
      filter.configure(config);
      filter.start();
    
  3. SectionEvent فرآیند.

    FilterCallback filterCallback = new FilterCallback() {
      @Override
      public void onFilterEvent(Filter filter, FilterEvent[] events) {
        for (FilterEvent event : events) {
          if (event instanceof SectionEvent) {
            SectionEvent sectionEvent = (SectionEvent) event;
            int tableId = sectionEvent.getTableId();
            int version = sectionEvent.getVersion();
            int dataLength = sectionEvent.getDataLength();
            int sectionNumber = sectionEvent.getSectionNumber();
            filter.read(buffer, 0, dataLength); }
          }
        }
    };
    
مثالی از جریان استفاده از MediaEvent از فیلتر

مثالی از جریان استفاده از MediaEvent از فیلتر.

شکل ۱۱. جریان استفاده از MediaEvent از فیلتر

  1. فیلترهای A/V را باز، پیکربندی و شروع کنید.
  2. پردازش MediaEvent .
  3. MediaEvent را دریافت کنید.
  4. بلوک خطی را در codec قرار دهید.
  5. وقتی داده‌ها مصرف شدند، دسته A/V را رها کنید.

اندروید.رسانه.تلویزیون.تیونر.دستگاه ضبط تصویر

DvrRecorder این روش‌ها را برای ضبط فراهم می‌کند.

  • configure
  • attachFilter
  • detachFilter
  • start
  • flush
  • stop
  • setFileDescriptor
  • write

DvrPlayback این روش‌ها را برای پخش فراهم می‌کند.

  • configure
  • start
  • flush
  • stop
  • setFileDescriptor
  • read

DvrSettings برای پیکربندی DvrRecorder و DvrPlayback استفاده می‌شود. OnPlaybackStatusChangedListener و OnRecordStatusChangedListener برای گزارش وضعیت یک نمونه DVR استفاده می‌شود.

مثالی از جریان شروع یک رکورد

مثالی از روند شروع یک رکورد.

شکل ۱۲. جریان شروع یک رکورد

  1. DvrRecorder باز، پیکربندی و اجرا کنید.

    DvrRecorder recorder = openDvrRecorder(/* bufferSize */ 1000, executor, listener);
    DvrSettings dvrSettings = DvrSettings
    .builder()
    .setDataFormat(DvrSettings.DATA_FORMAT_TS)
    .setLowThreshold(100)
    .setHighThreshold(900)
    .setPacketSize(188)
    .build();
    recorder.configure(dvrSettings);
    recorder.attachFilter(filter);
    recorder.setFileDescriptor(fd);
    recorder.start();
    
  2. RecordEvent دریافت کرده و اطلاعات ایندکس را بازیابی کنید.

    FilterCallback filterCallback = new FilterCallback() {
      @Override
      public void onFilterEvent(Filter filter, FilterEvent[] events) {
        for (FilterEvent event : events) {
          if (event instanceof TsRecordEvent) {
            TsRecordEvent recordEvent = (TsRecordEvent) event;
            int tsMask = recordEvent.getTsIndexMask();
            int scMask = recordEvent.getScIndexMask();
            int packetId = recordEvent.getPacketId();
            long dataLength = recordEvent.getDataLength();
            // handle the masks etc. }
          }
        }
    };
    
  3. OnRecordStatusChangedListener مقداردهی اولیه کرده و داده‌های رکورد را ذخیره می‌کند.

      OnRecordStatusChangedListener listener = new OnRecordStatusChangedListener() {
        @Override
        public void onRecordStatusChanged(int status) {
          // a customized way to consume data efficiently by using status as a hint.
          if (status == Filter.STATUS_DATA_READY) {
            recorder.write(size);
          }
        }
      };
    

تیونر HAL

Tuner HAL از HIDL پیروی می‌کند و رابط بین چارچوب و سخت‌افزار فروشنده را تعریف می‌کند. فروشندگان از این رابط برای پیاده‌سازی Tuner HAL استفاده می‌کنند و چارچوب از آن برای ارتباط با پیاده‌سازی Tuner HAL استفاده می‌کند.

ماژول‌ها

تیونر HAL 1.0

ماژول‌ها کنترل‌های پایه کنترل‌های خاص ماژول فایل‌های HAL
ITuner ناموجود frontend(open, getIds, getInfo) ، openDemux ، openDescrambler ، openLnb ، getDemuxCaps ITuner.hal
IFrontend setCallback ، getStatus ، close tune ، stopTune ، scan ، stopScan ، setLnb IFrontend.hal
IFrontendCallback.hal
IDemux close setFrontendDataSource ، openFilter ، openDvr ، getAvSyncHwId ، getAvSyncTime ، connect / disconnectCiCam IDemux.hal
IDvr close ، start ، stop ، configure attach/detachFilters ، flush ، getQueueDesc IDvr.hal
IDvrCallback.hal
IFilter close ، start ، stop ، configure ، getId flush ، getQueueDesc ، releaseAvHandle ، setDataSource IFilter.hal
IFilterCallback.hal
ILnb close ، setCallback setVoltage ، setTone ، setSatellitePosition ، sendDiseqcMessage ILnb.hal
ILnbCallback.hal
IDescrambler close setDemuxSource ، setKeyToken ، addPid ، removePid IDescrambler.hal

تیونر HAL 1.1 (برگرفته از تیونر HAL 1.0)

ماژول‌ها کنترل‌های پایه کنترل‌های خاص ماژول فایل‌های HAL
ITuner ناموجود getFrontendDtmbCapabilities @1.1::ITuner.hal
IFrontend tune_1_1 ، scan_1_1 ، getStatusExt1_1 link/unlinkCiCam @1.1::IFrontend.hal
@1.1::IFrontendCallback.hal
IFilter getStatusExt1_1 configureIpCid ، configureAvStreamType ، getAvSharedHandle ، configureMonitorEvent @1.1::IFilter.hal
@1.1::IFilterCallback.hal

نمودار جریان تعاملات بین ماژول‌های تیونر HAL.

شکل ۱۳. نمودار تعاملات بین ماژول‌های HAL تیونر

پیوند فیلتر

تیونر HAL از اتصال فیلتر پشتیبانی می‌کند به طوری که فیلترها می‌توانند برای چندین لایه به فیلترهای دیگر متصل شوند. فیلترها از قوانین زیر پیروی می‌کنند.

  • فیلترها به صورت درختی به هم متصل هستند، بستن مسیر مجاز نیست.
  • گره ریشه demux است.
  • فیلترها به طور مستقل عمل می‌کنند.
  • همه فیلترها شروع به دریافت داده می‌کنند.
  • اتصال فیلتر روی آخرین فیلتر شسته می‌شود.

بلوک کد زیر و شکل ۱۴ مثالی از فیلتر کردن چندین لایه را نشان می‌دهند.

demuxCaps = ITuner.getDemuxCap;
If (demuxCaps[IP][MMTP] == true) {
        ipFilter = ITuner.openFilter(<IP, ..>)
        mmtpFilter1 = ITuner.openFilter(<MMTP ..>)
        mmtpFilter2 = ITuner.openFilter(<MMTP ..>)
        mmtpFilter1.setDataSource(<ipFilter>)
        mmtpFilter2.setDataSource(<ipFilter>)
}

نمودار مثال اتصال فیلتر.

شکل ۱۴. نمودار جریان اتصال فیلتر برای چندین لایه

مدیر منابع تیونر

قبل از مدیریت منابع Tuner (TRM)، جابجایی بین دو برنامه به سخت‌افزار Tuner یکسانی نیاز داشت. چارچوب ورودی تلویزیون (TIF) از مکانیسم "اولین برنده" استفاده می‌کرد، به این معنی که هر برنامه‌ای که ابتدا منبع را دریافت کند، آن منبع را نگه می‌دارد. با این حال، این مکانیسم ممکن است برای برخی موارد استفاده پیچیده ایده‌آل نباشد.

TRM به عنوان یک سرویس سیستمی برای مدیریت منابع سخت‌افزاری Tuner، TVInput و CAS برای برنامه‌ها اجرا می‌شود. TRM از مکانیزم "برد در پیش‌زمینه" استفاده می‌کند که اولویت برنامه را بر اساس وضعیت پیش‌زمینه یا پس‌زمینه و نوع مورد استفاده برنامه محاسبه می‌کند. TRM بر اساس اولویت، منبع را اعطا یا لغو می‌کند. TRM مدیریت منابع ATV را برای پخش، OTT و DVR متمرکز می‌کند.

رابط TRM

TRM رابط‌های AIDL را در ITunerResourceManager.aidl برای چارچوب Tuner، MediaCas و TvInputHardwareManager جهت ثبت، درخواست یا آزادسازی منابع در معرض نمایش قرار می‌دهد.

رابط‌های کاربری برای مدیریت کلاینت در زیر فهرست شده‌اند.

  • registerClientProfile(in ResourceClientProfile profile, IResourcesReclaimListener listener, out int[] clientId)
  • unregisterClientProfile(in int clientId)

رابط‌های درخواست و آزادسازی منابع در زیر فهرست شده‌اند.

  • requestFrontend(TunerFrontendRequest request, int[] frontendHandle) / releaseFrontend
  • requestDemux(TunerDemuxRequest request, int[] demuxHandle) / releaseDemux
  • requestDescrambler(TunerDescramblerRequest request, int[] descramblerHandle) / releaseDescrambler
  • requestCasSession(CasSessionRequest request, int[] casSessionHandle) / releaseCasSession
  • requestLnb(TunerLnbRequest request, int[] lnbHandle) / releaseLnb

کلاس‌های کلاینت و درخواست در زیر فهرست شده‌اند.

  • ResourceClientProfile
  • ResourcesReclaimListener
  • TunerFrontendRequest
  • TunerDemuxRequest
  • TunerDescramblerRequest
  • CasSessionRequest
  • TunerLnbRequest

اولویت مشتری

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

پارامترهای موجود در پروفایل مشتری

TRM شناسه فرآیند را از mTvInputSessionId بازیابی می‌کند تا تصمیم بگیرد که آیا یک برنامه، برنامه پیش‌زمینه است یا پس‌زمینه. برای ایجاد mTvInputSessionId ، TvInputService.onCreateSession یا TvInputService.onCreateRecordingSession یک جلسه TIS را مقداردهی اولیه می‌کند.

mUseCase مورد استفاده‌ی جلسه را نشان می‌دهد. موارد استفاده‌ی از پیش تعریف شده در زیر فهرست شده‌اند.

TvInputService.PriorityHintUseCaseType  {
  PRIORITY_HINT_USE_CASE_TYPE_PLAYBACK
  PRIORITY_HINT_USE_CASE_TYPE_LIVE
  PRIORITY_HINT_USE_CASE_TYPE_RECORD,
  PRIORITY_HINT_USE_CASE_TYPE_SCAN,
  PRIORITY_HINT_USE_CASE_TYPE_BACKGROUND
}

فایل پیکربندی

فایل پیکربندی پیش‌فرض

فایل پیکربندی پیش‌فرض زیر، مقادیر اولویت را برای موارد استفاده از پیش تعریف‌شده ارائه می‌دهد. کاربران می‌توانند مقادیر را با استفاده از یک فایل پیکربندی سفارشی تغییر دهند.

مورد استفاده پیش‌زمینه پیشینه
LIVE ۴۹۰ ۴۰۰
PLAYBACK ۴۸۰ ۳۰۰
RECORD ۶۰۰ ۵۰۰
SCAN ۴۵۰ ۲۰۰
BACKGROUND ۱۸۰ ۱۰۰
فایل پیکربندی سفارشی

فروشندگان می‌توانند فایل پیکربندی /vendor/etc/tunerResourceManagerUseCaseConfig.xml را سفارشی کنند. این فایل برای اضافه کردن، حذف کردن یا به‌روزرسانی انواع موارد استفاده و مقادیر اولویت موارد استفاده استفاده می‌شود. فایل سفارشی‌سازی شده می‌تواند از platform/hardware/interfaces/tv/tuner/1.0/config/tunerResourceManagerUseCaseConfigSample.xml به عنوان الگو استفاده کند.

برای مثال، یک مورد استفاده جدید برای فروشنده VENDOR_USE_CASE__[A-Z0-9]+, [0 - 1000] است. فرمت آن باید از platform/hardware/interfaces/tv/tuner/1.0/config/tunerResourceManagerUseCaseConfig.xsd پیروی کند.

مقدار اولویت دلخواه و مقدار خوب

TRM updateClientPriority را برای کلاینت فراهم می‌کند تا مقدار اولویت دلخواه و مقدار nice را به‌روزرسانی کند. مقدار اولویت دلخواه، مقدار اولویت محاسبه‌شده از نوع مورد استفاده و شناسه جلسه را بازنویسی می‌کند.

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

مکانیسم بازپس‌گیری

نمودار زیر نحوه‌ی بازپس‌گیری و تخصیص منابع را در صورت بروز تداخل منابع نشان می‌دهد.

نمودار فرآیند مکانیسم بازیابی.

شکل ۱۵. نمودار مکانیسم بازیابی برای تداخل بین منابع تیونر