برای اندروید 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.
شکل 2. نمودار اجزای داخل تیونر HAL
گردش کار کلی
نمودارهای زیر توالی تماس برای پخش پخش زنده را نشان می دهد.
راه اندازی
شکل 3. ترتیب تنظیم برای پخش پخش زنده
مدیریت A/V
شکل 4. کنترل A/V برای پخش پخش زنده
مدیریت محتوای درهم
شکل 5. مدیریت محتوای درهم برای پخش پخش زنده
پردازش داده های A/V
شکل 6. پردازش A/V برای پخش پخش زنده
Tuner SDK API
Tuner SDK API تعاملات را با Tuner JNI، Tuner HAL و TunerResourceManager
انجام میدهد. برنامه TIS از Tuner SDK API برای دسترسی به منابع و اجزای فرعی Tuner مانند فیلتر و Descrambler استفاده می کند. Frontend و demux اجزای داخلی هستند.
شکل 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
شکل 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()
را فراخوانی کنید.
شکل 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: | اجباری:DemuxFilterStatus::DATA_READY DemuxFilterStatus::DATA_OVERFLOW توصیه شده: DemuxFilterStatus::LOW_WATER DemuxFilterStatus::HIGH_WATER | با توجه به رویداد و برنامه داخلی اجرا کنیدFilter.read(buffer, offset, adjustedSize) یک یا چند بار.داده ها از HAL's MQ در بافر مشتری کپی می شوند. | یک بسته جلسه مونتاژ شده توسط بسته جلسه دیگری در FMQ پر می شود. |
isRaw: | اجباری:DemuxFilterEvent::DemuxFilterSectionEvent[n] DemuxFilterStatus::DATA_READY DemuxFilterStatus::DATA_OVERFLOW اختیاری: DemuxFilterStatus::LOW_WATER DemuxFilterStatus::HIGH_WATER | for i=0; i<n; i++ داده ها از HAL's MQ در بافر مشتری کپی می شوند. | ||
TS.PES | isRaw: | اجباری:DemuxFilterStatus::DATA_READY DemuxFilterStatus::DATA_OVERFLOW توصیه شده: DemuxFilterStatus::LOW_WATER DemuxFilterStatus::HIGH_WATER | با توجه به رویداد و برنامه داخلی اجرا کنیدFilter.read(buffer, offset, adjustedSize) یک یا چند بار.داده ها از MQ HAL در بافر مشتری کپی می شوند. | یک بسته PES مونتاژ شده توسط بسته PES دیگری در FMQ پر می شود. |
isRaw: | اجباری:DemuxFilterEvent::DemuxFilterPesEvent[n] DemuxFilterStatus::DATA_READY DemuxFilterStatus::DATA_OVERFLOW اختیاری: DemuxFilterStatus::LOW_WATER DemuxFilterStatus::HIGH_WATER | for i=0; i<n; i++ داده ها از HAL's MQ در بافر مشتری کپی می شوند. | ||
MMTP.PES | isRaw: | اجباری:DemuxFilterStatus::DATA_READY DemuxFilterStatus::DATA_OVERFLOW توصیه شده: DemuxFilterStatus::LOW_WATER DemuxFilterStatus::HIGH_WATER | با توجه به رویداد و برنامه داخلی اجرا کنیدFilter.read(buffer, offset, adjustedSize) یک یا چند بار.داده ها از MQ HAL در بافر مشتری کپی می شوند. | یک بسته MFU مونتاژ شده توسط بسته MFU دیگری در FMQ پر می شود. |
isRaw: | اجباری:DemuxFilterEvent::DemuxFilterPesEvent[n] DemuxFilterStatus::DATA_READY DemuxFilterStatus::DATA_OVERFLOW اختیاری: DemuxFilterStatus::LOW_WATER DemuxFilterStatus::HIGH_WATER | for i=0; i<n; i++ داده ها از 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: | اختیاری:DemuxFilterStatus::DATA_READY DemuxFilterStatus::DATA_OVERFLOW | مشتری می تواند MediaCodec پس از دریافت DemuxFilterStatus::DATA_READY راه اندازی کند.مشتری می تواند پس از دریافت DemuxFilterStatus::DATA_OVERFLOW با Filter.flush تماس بگیرد. | N/A |
isPassthrough: | اجباری:DemuxFilterEvent::DemuxFilterMediaEvent[n] DemuxFilterStatus::DATA_READY DemuxFilterStatus::DATA_OVERFLOW اختیاری: DemuxFilterStatus::LOW_WATER DemuxFilterStatus::HIGH_WATER | برای استفاده از MediaCodec :for i=0; i<n; i++ برای استفاده از صدای مستقیم AudioTrack :for i=0; i<n; i++ | داده های 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++ برای محتوای ضبط شده ، با توجه به RecordStatus::* و برنامه داخلی، یکی از موارد زیر را انجام دهید:
| برای داده های شاخص: حمل شده در بار رویداد. برای محتوای ضبط شده: جریان 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++ | 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++ برای محتوای ضبط شده ، با توجه به RecordStatus::* و برنامه داخلی، یکی از موارد زیر را انجام دهید:
| برای داده های شاخص: حمل شده در بار رویداد. برای محتوای ضبط شده: جریان ضبط شده مختلط پر شده در 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: | اختیاری:DemuxFilterStatus::DATA_READY DemuxFilterStatus::DATA_OVERFLOW | جریان فرعی پروتکل فیلتر شده فیلتر بعدی را در زنجیره فیلتر تغذیه می کند. | N/A |
isPassthrough: | اجباری: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
شکل 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();
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 از فیلتر
شکل 11. جریان برای استفاده از MediaEvent از فیلتر
- فیلترهای A/V را باز، پیکربندی و راه اندازی کنید.
- پردازش
MediaEvent
. -
MediaEvent
دریافت کنید. - بلوک خطی را در صف
codec
قرار دهید. - هنگامی که داده ها مصرف شد، دسته 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. جریان برای شروع یک رکورد
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
تیونر 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 |
شکل 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. نمودار مکانیسم بازیابی برای تضاد بین منابع تیونر