برای اندروید ۱۱ یا بالاتر، میتوانید از چارچوب 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)

شکل 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
گردش کار کلی
نمودارهای زیر توالی تماسها را برای پخش زنده نشان میدهند.
راهاندازی

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

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

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

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

شکل 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

شکل 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
فیلتر.تیونر.رسانه.تلویزیون.اندروید
بسته فیلتر مجموعهای از عملیات فیلتر به همراه پیکربندی، تنظیمات، فراخوانیهای برگشتی و رویدادها است. این بسته شامل عملیات زیر است. برای لیست کامل عملیات به کد منبع اندروید مراجعه کنید.
-
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.SECTIONMMTP.SECTIONIP.SECTIONTLV.SECTIONALP.SECTION | isRaw: | اجباری:DemuxFilterStatus::DATA_READYDemuxFilterStatus::DATA_OVERFLOWتوصیه شده: DemuxFilterStatus::LOW_WATERDemuxFilterStatus::HIGH_WATER | طبق برنامه رویداد و داخلی، اجرا کنید یک یا چند بار Filter.read(buffer, offset, adjustedSize) .دادهها از MQ مربوط به HAL به بافر کلاینت کپی میشوند. | یک بسته جلسه مونتاژ شده توسط یک بسته جلسه دیگر در FMQ پر میشود. |
isRaw: | اجباری:DemuxFilterEvent::DemuxFilterSectionEvent[n]DemuxFilterStatus::DATA_READYDemuxFilterStatus::DATA_OVERFLOWاختیاری: DemuxFilterStatus::LOW_WATERDemuxFilterStatus::HIGH_WATER | for i=0; i<n; i++دادهها از MQ مربوط به HAL به بافر کلاینت کپی میشوند. | ||
TS.PES | isRaw: | اجباری:DemuxFilterStatus::DATA_READYDemuxFilterStatus::DATA_OVERFLOWتوصیه شده: DemuxFilterStatus::LOW_WATERDemuxFilterStatus::HIGH_WATER | طبق برنامه رویداد و داخلی، اجرا کنید یک یا چند بار Filter.read(buffer, offset, adjustedSize) .دادهها از MQ مربوط به HAL به بافر کلاینت کپی میشوند. | یک بسته PES مونتاژ شده توسط یک بسته PES دیگر در FMQ پر میشود. |
isRaw: | اجباری:DemuxFilterEvent::DemuxFilterPesEvent[n]DemuxFilterStatus::DATA_READYDemuxFilterStatus::DATA_OVERFLOWاختیاری: DemuxFilterStatus::LOW_WATERDemuxFilterStatus::HIGH_WATER | for i=0; i<n; i++دادهها از MQ مربوط به HAL به بافر کلاینت کپی میشوند. | ||
MMTP.PES | isRaw: | اجباری:DemuxFilterStatus::DATA_READYDemuxFilterStatus::DATA_OVERFLOWتوصیه شده: DemuxFilterStatus::LOW_WATERDemuxFilterStatus::HIGH_WATER | طبق برنامه رویداد و داخلی، اجرا کنید یک یا چند بار Filter.read(buffer, offset, adjustedSize) .دادهها از MQ مربوط به HAL به بافر کلاینت کپی میشوند. | یک بسته MFU مونتاژ شده توسط یک بسته MFU دیگر در FMQ پر میشود. |
isRaw: | اجباری:DemuxFilterEvent::DemuxFilterPesEvent[n]DemuxFilterStatus::DATA_READYDemuxFilterStatus::DATA_OVERFLOWاختیاری: DemuxFilterStatus::LOW_WATERDemuxFilterStatus::HIGH_WATER | for i=0; i<n; i++دادهها از MQ مربوط به HAL به بافر کلاینت کپی میشوند. | ||
TS.TS | ناموجود | اجباری:DemuxFilterStatus::DATA_READYDemuxFilterStatus::DATA_OVERFLOWتوصیه شده: DemuxFilterStatus::LOW_WATERDemuxFilterStatus::HIGH_WATER | طبق برنامه رویداد و داخلی، اجرا کنید یک یا چند بار Filter.read(buffer, offset, adjustedSize) .دادهها از MQ مربوط به HAL به بافر کلاینت کپی میشوند. | ts را با هدر ts فیلتر کرددر FMQ پر شده است. |
TS.AudioTS.VideoMMTP.AudioMMTP.Video | isPassthrough: | اختیاری:DemuxFilterStatus::DATA_READYDemuxFilterStatus::DATA_OVERFLOW | کلاینت میتواند پس از دریافت DemuxFilterStatus::DATA_READY ، MediaCodec اجرا کند.کلاینت میتواند پس از دریافت DemuxFilterStatus::DATA_OVERFLOW تابع Filter.flush را فراخوانی کند. | ناموجود |
isPassthrough: | اجباری:DemuxFilterEvent::DemuxFilterMediaEvent[n]DemuxFilterStatus::DATA_READYDemuxFilterStatus::DATA_OVERFLOWاختیاری: DemuxFilterStatus::LOW_WATERDemuxFilterStatus::HIGH_WATER | برای استفاده از MediaCodec :for i=0; i<n; i++برای استفاده از صدای مستقیم AudioTrack :for i=0; i<n; i++ | دادههای ES یا ES جزئی در حافظه ION. | |
TS.PCRIP.NTPALP.PTP | ناموجود | اجباری: ناموجود اختیاری: ناموجود | ناموجود | ناموجود |
TS.RECORD | ناموجود | اجباری:DemuxFilterEvent::DemuxFilterTsRecordEvent[n]RecordStatus::DATA_READYRecordStatus::DATA_OVERFLOWRecordStatus::LOW_WATERRecordStatus::HIGH_WATERاختیاری: DemuxFilterStatus::DATA_READYDemuxFilterStatus::DATA_OVERFLOWDemuxFilterStatus::LOW_WATERDemuxFilterStatus::HIGH_WATER | برای دادههای شاخص:for i=0; i<n; i++برای محتوای ضبطشده ، طبق RecordStatus::* و برنامه داخلی، یکی از موارد زیر را انجام دهید:
| برای دادههای شاخص: در بار مفید رویداد حمل میشود. برای محتوای ضبطشده: جریان TS ترکیبی (Muxed TS) پر شده با FMQ. |
TS.TEMI | ناموجود | اجباری:DemuxFilterEvent::DemuxFilterTemiEvent[n]اختیاری: DemuxFilterStatus::DATA_READYDemuxFilterStatus::DATA_OVERFLOWDemuxFilterStatus::LOW_WATERDemuxFilterStatus::HIGH_WATER | for i=0; i<n; i++ | ناموجود |
MMTP.MMTP | ناموجود | اجباری:DemuxFilterStatus::DATA_READYDemuxFilterStatus::DATA_OVERFLOWتوصیه شده: DemuxFilterStatus::LOW_WATERDemuxFilterStatus::HIGH_WATER | طبق برنامه رویداد و داخلی، اجرا کنید یک یا چند بار Filter.read(buffer, offset, adjustedSize) .دادهها از MQ مربوط به HAL به بافر کلاینت کپی میشوند. | mmtp با هدر mmtp فیلتر شده استدر FMQ پر شده است. |
MMTP.RECORD | ناموجود | اجباری:DemuxFilterEvent::DemuxFilterMmtpRecordEvent[n]RecordStatus::DATA_READYRecordStatus::DATA_OVERFLOWRecordStatus::LOW_WATERRecordStatus::HIGH_WATERاختیاری: DemuxFilterStatus::DATA_READYDemuxFilterStatus::DATA_OVERFLOWDemuxFilterStatus::LOW_WATERDemuxFilterStatus::HIGH_WATER | برای دادههای شاخص: for i=0; i<n; i++برای محتوای ضبطشده ، طبق RecordStatus::* و برنامه داخلی، یکی از موارد زیر را انجام دهید:
| برای دادههای شاخص: در بار مفید رویداد حمل میشود. برای محتوای ضبطشده: جریان ضبطشدهی ترکیبی (Muxed) که با FMQ پر شده است. اگر منبع فیلتر برای ضبط، TLV.TLV به IP.IP با گذرگاه باشد، جریان ضبط شده دارای سرآیند TLV و IP است. |
MMTP.DOWNLOAD | ناموجود | اجباری:DemuxFilterEvent::DemuxFilterDownloadEvent[n]DemuxFilterStatus::DATA_READYDemuxFilterStatus::DATA_OVERFLOWاختیاری: DemuxFilterStatus::LOW_WATERDemuxFilterStatus::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_READYDemuxFilterStatus::DATA_OVERFLOWاختیاری: DemuxFilterStatus::LOW_WATERDemuxFilterStatus::HIGH_WATER | for i=0; i<n; i++ Filter.read(buffer, offset, DemuxFilterIpPayloadEvent[i].size)دادهها از MQ مربوط به HAL به بافر کلاینت کپی میشوند. | بستهی بار اطلاعاتی IP در FMQ توسط یک بستهی بار اطلاعاتی IP دیگر پر میشود. |
IP.IPTLV.TLVALP.ALP | isPassthrough: | اختیاری:DemuxFilterStatus::DATA_READYDemuxFilterStatus::DATA_OVERFLOW | زیرجریان پروتکل فیلتر شده، فیلتر بعدی در زنجیره فیلتر را تغذیه میکند. | ناموجود |
isPassthrough: | اجباری:DemuxFilterStatus::DATA_READYDemuxFilterStatus::DATA_OVERFLOWتوصیه شده: DemuxFilterStatus::LOW_WATERDemuxFilterStatus::HIGH_WATER | طبق برنامه رویداد و داخلی، اجرا کنید یک یا چند بار Filter.read(buffer, offset, adjustedSize) .دادهها از MQ مربوط به HAL به بافر کلاینت کپی میشوند. | زیرجریان پروتکل فیلتر شده با سرآیند پروتکل در FMQ پر میشود. | |
IP.PAYLOAD_THROUGHTLV.PAYLOAD_THROUGHALP.PAYLOAD_THROUGH | ناموجود | اختیاری:DemuxFilterStatus::DATA_READYDemuxFilterStatus::DATA_OVERFLOW | بار مفید پروتکل فیلتر شده، فیلتر بعدی در زنجیره فیلتر را تغذیه میکند. | ناموجود |
مثالی از جریان استفاده از فیلتر برای ساخت PSI/SI

شکل 10. جریان برای ساخت PSI/SI
یک فیلتر باز کنید.
Filter filter = tuner.openFilter( Filter.TYPE_TS, Filter.SUBTYPE_SECTION, /* bufferSize */1000, executor, filterCallback );فیلتر را پیکربندی و شروع کنید.
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();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 از فیلتر
- فیلترهای A/V را باز، پیکربندی و شروع کنید.
- پردازش
MediaEvent. -
MediaEventرا دریافت کنید. - بلوک خطی را در
codecقرار دهید. - وقتی دادهها مصرف شدند، دسته A/V را رها کنید.
اندروید.رسانه.تلویزیون.تیونر.دستگاه ضبط تصویر
DvrRecorder این روشها را برای ضبط فراهم میکند.
-
configure -
attachFilter -
detachFilter -
start -
flush -
stop -
setFileDescriptor -
write
DvrPlayback این روشها را برای پخش فراهم میکند.
-
configure -
start -
flush -
stop -
setFileDescriptor -
read
DvrSettings برای پیکربندی DvrRecorder و DvrPlayback استفاده میشود. OnPlaybackStatusChangedListener و OnRecordStatusChangedListener برای گزارش وضعیت یک نمونه DVR استفاده میشود.
مثالی از جریان شروع یک رکورد

شکل ۱۲. جریان شروع یک رکورد
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();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. } } } };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.halIFrontendCallback.hal |
IDemux | close | setFrontendDataSource ، openFilter ، openDvr ، getAvSyncHwId ، getAvSyncTime ، connect / disconnectCiCam | IDemux.hal |
IDvr | close ، start ، stop ، configure | attach/detachFilters ، flush ، getQueueDesc | IDvr.halIDvrCallback.hal |
IFilter | close ، start ، stop ، configure ، getId | flush ، getQueueDesc ، releaseAvHandle ، setDataSource | IFilter.halIFilterCallback.hal |
ILnb | close ، setCallback | setVoltage ، setTone ، setSatellitePosition ، sendDiseqcMessage | ILnb.halILnbCallback.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 از اتصال فیلتر پشتیبانی میکند به طوری که فیلترها میتوانند برای چندین لایه به فیلترهای دیگر متصل شوند. فیلترها از قوانین زیر پیروی میکنند.
- فیلترها به صورت درختی به هم متصل هستند، بستن مسیر مجاز نیست.
- گره ریشه 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 را بهروزرسانی کند. مقدار اولویت دلخواه، مقدار اولویت محاسبهشده از نوع مورد استفاده و شناسه جلسه را بازنویسی میکند.
مقدار «خوب» نشان میدهد که رفتار مشتری در هنگام درگیری با مشتری دیگر چقدر ملایم است. مقدار «خوب»، ارزش اولویت مشتری را قبل از مقایسه با مشتری چالشبرانگیز کاهش میدهد.
مکانیسم بازپسگیری
نمودار زیر نحوهی بازپسگیری و تخصیص منابع را در صورت بروز تداخل منابع نشان میدهد.

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