چارچوب تیونر

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

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

اجزاء

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

  • تیونر HAL: رابط بین فریم ورک و فروشندگان
  • Tuner SDK API: رابطی بین چارچوب و برنامه ها
  • مدیر منابع تیونر (TRM): منابع تیونر HW را هماهنگ می کند

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

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

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

شکل 1. تعامل بین اجزای Android TV

امکانات

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

  • ATSC
  • ATSC3
  • DVB C/S/T
  • ISDB S/S3/T
  • آنالوگ

قسمت جلویی اندروید 12 با تیونر HAL 1.1 یا بالاتر از استاندارد DTV زیر پشتیبانی می کند.

  • DTMB

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

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

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

  • مسیر رسانه ای امن
  • مسیر رسانه را پاک کنید
  • ضبط محلی ایمن
  • پخش محلی ایمن

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

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

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

  • محموله ES با بافر حافظه شفاف
  • محموله ES با دسته حافظه ایمن
  • عبور

طراحی کلی

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

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

یک کلاس جاوا Tuner و کلاس بومی ایجاد می شود.

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

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

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

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

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

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

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

طراحی کلی Tuner HAL.

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

گردش کار کلی

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

برپایی

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

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

مدیریت A/V

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

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

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

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

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

پردازش داده های A/V

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

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

Tuner SDK API

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

نمودار جریان API Tuner SDK.

شکل 7. تعامل با Tuner SDK API

نسخه ها

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

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

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

حداقل نسخه HAL مورد نیاز را می توان در اسناد APIهای جدید Android 12 یافت.

بسته ها

Tuner SDK API چهار بسته زیر را ارائه می دهد.

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

نمودار جریان بسته های Tuner SDK API.

شکل 8. بسته های API SDK Tuner

Android.media.tv.tuner

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

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

بسته تیونر قابلیت هایی را ارائه می دهد که تحت فیلتر، DVR و بسته های frontend پوشش داده نمی شوند. عملکردها در زیر ذکر شده است.

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

Android.media.tv.tuner.frontend

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

کلاس ها

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

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

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

  • DtmbFrontendSettings

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

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

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

  • DtmbFrontendCapabilities

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

اسکن کانال

برای راه‌اندازی تلویزیون، برنامه فرکانس‌های احتمالی را اسکن می‌کند و ردیف کانالی را برای دسترسی کاربران ایجاد می‌کند. 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 پیام های LOCKED را تنظیم می کند.
  • TIS از Frontend.getStatus برای جمع آوری اطلاعات لازم استفاده می کند.
  • TIS به فرکانس بعدی موجود در لیست فرکانس خود حرکت می کند.

TIS دوباره با Tuner.tune تماس می گیرد تا زمانی که تمام فرکانس ها تمام شود.

در طول تنظیم، می توانید برای توقف یا پایان تماس Tuner.tune stopTune() یا close() فراخوانی کنید.

Tuner.scan (AUTO_SCAN)

اگر 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() را فراخوانی کنید.

Tuner.scan (BLIND_SCAN)

اگر TIS فهرست فرکانس ندارد و فروشنده HAL می‌تواند فرکانس ظاهری مشخص شده توسط کاربر را برای دریافت منبع ظاهری جستجو کند، 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.

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

Android.media.tv.tuner.filter

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

  • 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

از Android 12 با تیونر 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) یک یا چند بار.

داده ها از HAL's MQ در بافر مشتری کپی می شوند.
یک بسته جلسه مونتاژ شده توسط بسته جلسه دیگری در 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)


داده ها از HAL's MQ در بافر مشتری کپی می شوند.
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)


داده ها از HAL's MQ در بافر مشتری کپی می شوند.
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
N/A اجباری:
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
مشتری می تواند MediaCodec پس از دریافت DemuxFilterStatus::DATA_READY راه اندازی کند.
مشتری می تواند پس از دریافت DemuxFilterStatus::DATA_OVERFLOW با Filter.flush تماس بگیرد.
N/A
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
N/A الزامی: N/A
اختیاری: N/A
N/A N/A
TS.RECORD N/A اجباری:
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 مختلط پر شده در FMQ.
TS.TEMI N/A اجباری:
DemuxFilterEvent::DemuxFilterTemiEvent[n]

اختیاری:
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW
DemuxFilterStatus::LOW_WATER
DemuxFilterStatus::HIGH_WATER
for i=0; i<n; i++
DemuxFilterTemiEvent[i];
N/A
MMTP.MMTP N/A اجباری:
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW

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

داده ها از MQ HAL در بافر مشتری کپی می شوند.
mmtp با هدر mmtp فیلتر شد
در FMQ پر شده است.
MMTP.RECORD N/A اجباری:
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 در بافر مشتری کپی می شوند.
برای داده های شاخص: حمل شده در بار رویداد.

برای محتوای ضبط شده: جریان ضبط شده مختلط پر شده در FMQ.

اگر منبع فیلتر برای ضبط TLV.TLV به IP.IP با عبور باشد، جریان ضبط شده دارای یک TLV و هدر IP است.
MMTP.DOWNLOAD N/A اجباری:
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)

داده ها از HAL's MQ در بافر مشتری کپی می شوند.
بسته دانلودی توسط بسته دانلود IP دیگری در FMQ پر می شود.
IP.IP_PAYLOAD N/A اجباری:
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)

داده ها از HAL's MQ در بافر مشتری کپی می شوند.
بسته بار IP توسط بسته بار IP دیگری در FMQ پر می شود.
IP.IP
TLV.TLV
ALP.ALP
isPassthrough:
true
اختیاری:
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW
جریان فرعی پروتکل فیلتر شده فیلتر بعدی را در زنجیره فیلتر تغذیه می کند. N/A
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
N/A اختیاری:
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW
محموله پروتکل فیلتر شده فیلتر بعدی را در زنجیره فیلتر تغذیه می کند. N/A
جریان مثال برای استفاده از فیلتر برای ساخت 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. Process 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 از فیلتر.

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

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

Android.media.tv.tuner.dvr

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

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

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

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

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

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

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

شکل 12. جریان برای شروع یک رکورد

  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

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

ماژول ها

تیونر HAL 1.0

ماژول ها کنترل های اساسی کنترل های مخصوص ماژول فایل های HAL
ITuner N/A 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 N/A 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.

شکل 13. نمودار تعاملات بین ماژول های Tuner HAL

پیوند فیلتر

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

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

بلوک کد زیر و شکل 14 نمونه ای از فیلتر چندین لایه را نشان می دهد.

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

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

شکل 14. نمودار جریان یک پیوند فیلتر برای چندین لایه

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

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

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

رابط TRM

TRM رابط های AIDL را در ITunerResourceManager.aidl برای چارچوب تیونر، 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 490 400
PLAYBACK 480 300
RECORD 600 500
SCAN 450 200
BACKGROUND 180 100
فایل پیکربندی سفارشی

فروشندگان می توانند فایل پیکربندی /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 قبل از اینکه ارزش اولویت آن با مشتری چالش برانگیز مقایسه شود، ارزش اولویت مشتری را کاهش می دهد.

مکانیسم بازیابی

نمودار زیر نحوه بازیابی و تخصیص منابع را هنگام وقوع تضاد منابع نشان می دهد.

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

شکل 15. نمودار مکانیسم بازیابی برای تضاد بین منابع تیونر