في نظام التشغيل Android 11 أو الإصدارات الأحدث، يمكنك استخدام إطار عمل Android Tuner لتقديم محتوى الصوت والفيديو. يستخدم إطار العمل مسار الأجهزة من المورّدين، ما يجعله مناسبًا لكل من شرائح النظام المنخفضة والعالية الأداء. يوفّر إطار العمل طريقة آمنة لتقديم محتوى صوتي ومرئي محمي بواسطة بيئة تنفيذ موثوقة (TEE) ومسار وسائط آمن (SMP)، ما يتيح استخدامه في بيئة مقيّدة للغاية لحماية المحتوى.
تؤدي الواجهة الموحّدة بين Tuner وAndroid CAS إلى تسريع عملية الدمج بين مورّدي Tuner ومورّدي CAS. تعمل واجهة Tuner مع MediaCodec وAudioTrack لإنشاء حلّ واحد لمنصّة Android TV.
تتوافق واجهة Tuner مع كل من التلفزيون الرقمي والتلفزيون التناظري استنادًا إلى معايير البث الرئيسية.
المكونات
في نظام التشغيل Android 11، تم تصميم ثلاثة مكونات خصيصًا لمنصة التلفزيون.
- طبقة HAL الخاصة بجهاز استقبال البث: هي واجهة بين إطار العمل والمورّدين.
- واجهة برمجة التطبيقات لحزمة تطوير البرامج (SDK) الخاصة ببرنامج الضبط: هي واجهة بين إطار العمل والتطبيقات
- Tuner Resource Manager (TRM): ينسّق موارد أجهزة Tuner
تم تحسين المكوّنات التالية في Android 11.
- CAS V2
TvInputServiceأو خدمة إدخال التلفزيون (TIS)TvInputManagerServiceأو خدمة "إدارة إدخال التلفزيون" (TIMS)MediaCodecأو ترميز الوسائطAudioTrackأو مقطع صوتيMediaResourceManagerأو "مدير موارد الوسائط" (MRM)
الشكل 1: التفاعلات بين مكوّنات Android TV
الميزات
يتوافق الواجهة الأمامية مع معايير DTV أدناه.
- ATSC
- ATSC3
- DVB C/S/T
- ISDB S/S3/T
- ساعة عادية
تتيح الواجهة الأمامية في Android 12 التي تتضمّن الإصدار 1.1 أو إصدارًا أحدث من Tuner HAL استخدام معيار DTV أدناه.
- DTMB
يتوافق Demux مع بروتوكولات البث أدناه.
- بث النقل (TS)
- بروتوكول نقل وسائط MPEG (MMTP)
- بروتوكول الإنترنت (IP)
- قيمة طول النوع (TLV)
- بروتوكول طبقة الربط (ALP) في معيار ATSC
يتوافق برنامج فك التشفير مع وسائل حماية المحتوى أدناه.
- مسار الوسائط الآمن
- محو مسار الوسائط
- سجلّ محلي آمن
- تشغيل المحتوى المحلي بشكل آمن
تتيح واجهات برمجة التطبيقات الخاصة بأجهزة الضبط حالات الاستخدام أدناه.
- فحص
- مباشر
- التشغيل
- تسجيل
تتيح أدوات الضبط وMediaCodec وAudioTrack أوضاع تدفّق البيانات أدناه.
- حمولة ES مع مخزن مؤقت للذاكرة فارغ
- حمولة ES مع معرّف آمن للذاكرة
- رؤية العالم المحيط
التصميم العام
يتم تحديد طبقة HAL الخاصة بأداة Tuner بين إطار عمل Android والأجهزة التابعة للمورّد.
- تصف هذه السمة ما يتوقّعه إطار العمل من المورّد وكيف يمكن للمورّد تنفيذ ذلك.
- تصدّر هذه السمة وظائف الواجهة الأمامية وإزالة التداخل وإزالة التشويش إلى إطار العمل من خلال الواجهات
IFrontendوIDemuxوIDescramblerوIFilterوIDvrوILnb. - تتضمّن هذه الواجهة الدوال اللازمة لدمج طبقة HAL الخاصة بأداة Tuner مع مكوّنات أخرى من إطار العمل، مثل
MediaCodecوAudioTrack.
يتم إنشاء فئة Tuner Java وفئة أصلية.
- تتيح واجهة برمجة التطبيقات Tuner Java API للتطبيقات الوصول إلى طبقة تجريد الأجهزة (HAL) الخاصة بـ Tuner من خلال واجهات برمجة التطبيقات العامة.
- تسمح الفئة الأصلية بالتحكّم في الأذونات ومعالجة كميات كبيرة من بيانات التسجيل أو التشغيل باستخدام Tuner HAL.
- وحدة Native Tuner هي جسر بين فئة Tuner Java وTuner HAL.
يتم إنشاء فئة TRM.
- تدير موارد Tuner المحدودة، مثل Frontend وLNB وجلسات CAS وجهاز إدخال بيانات التلفزيون من TV Input HAL.
- تطبيق قواعد لاسترداد الموارد غير الكافية من التطبيقات القاعدة التلقائية هي أن يكون التطبيق في المقدّمة هو الفائز.
تم تحسين Media CAS وCAS HAL باستخدام الميزات أدناه.
- يفتح جلسات CAS لاستخدامات وخوارزميات مختلفة.
- يتوافق مع أنظمة CAS الديناميكية، مثل إزالة CICAM وإدخالها.
- يتكامل مع Tuner HAL من خلال توفير رموز مميزة للمفاتيح.
تم تحسين MediaCodec وAudioTrack باستخدام الميزات أدناه.
- تأخذ هذه السمة ذاكرة A/V آمنة كمدخل للمحتوى.
- تم ضبطه على مزامنة الصوت والفيديو على مستوى الجهاز في وضع التشغيل عبر الأنفاق.
- تم ضبط إمكانية استخدام
ES_payloadووضع "نقل البيانات".
الشكل 2: مخطّط لمكوّنات Tuner HAL
سير العمل العام
توضّح المخططات البيانية أدناه تسلسلات المكالمات لتشغيل البث المباشر.
الإعداد
الشكل 3: ترتيب الإعدادات لتشغيل البث المباشر
التعامل مع الصوت والفيديو
الشكل 4. التعامل مع الصوت والفيديو لتشغيل البث المباشر
التعامل مع المحتوى المشوّش
الشكل 5. التعامل مع المحتوى المشوّش لتشغيل البث المباشر
معالجة بيانات الصوت والفيديو
الشكل 6. معالجة الصوت والفيديو لتشغيل البث المباشر
Tuner SDK API
تتعامل واجهة برمجة التطبيقات Tuner SDK مع التفاعلات مع Tuner JNI وTuner HAL وTunerResourceManager. يستخدم تطبيق TIS واجهة برمجة التطبيقات Tuner SDK للوصول إلى موارد Tuner ومكوناته الفرعية، مثل الفلتر وجهاز فك التشفير. الواجهة الأمامية وdemux هما مكوّنان داخليان.
الشكل 7. التفاعلات مع واجهة برمجة التطبيقات Tuner SDK
الإصدارات
بدءًا من Android 12، تتيح واجهة برمجة التطبيقات الخاصة بحزمة تطوير البرامج (SDK) لأداة Tuner ميزة جديدة في الإصدار 1.1 من طبقة تجريد الأجهزة (HAL) لأداة Tuner، وهو إصدار مطوّر ومتوافق مع الإصدار السابق من أداة Tuner 1.0.
استخدِم واجهة برمجة التطبيقات التالية للتحقّق من إصدار طبقة تجريد الأجهزة (HAL) قيد التشغيل.
android.media.tv.tuner.TunerVersionChecker.getTunerVersion()
يمكنك العثور على الحد الأدنى المطلوب لإصدار HAL في مستندات واجهات برمجة التطبيقات الجديدة في Android 12.
إدارة الحِزم
توفّر واجهة برمجة التطبيقات الخاصة بحزمة تطوير البرامج (SDK) لأداة Tuner الحِزم الأربع أدناه.
android.media.tv.tunerandroid.media.tv.tuner.frontendandroid.media.tv.tuner.filterandroid.media.tv.tuner.dvr
الشكل 8. حِزم واجهة برمجة التطبيقات الخاصة بحزمة تطوير البرامج (SDK) لأداة Tuner
Android.media.tv.tuner
حزمة Tuner هي نقطة دخول لاستخدام إطار عمل Tuner. يستخدم تطبيق TIS الحزمة لتهيئة مثيلات الموارد والحصول عليها من خلال تحديد الإعداد الأولي ومعاودة الاتصال.
tuner(): تهيئة مثيل Tuner من خلال تحديد المَعلمتَينuseCaseوsessionIdtune(): للحصول على مورد من الواجهة الأمامية وضبطه من خلال تحديد المَعلمةFrontendSetting.-
openFilter(): للحصول على مثيل فلتر من خلال تحديد نوع الفلتر. -
openDvrRecorder(): للحصول على مثيل تسجيل من خلال تحديد حجم المخزن المؤقت. -
openDvrPlayback(): للحصول على مثيل تشغيل من خلال تحديد حجم المخزن المؤقت. openDescrambler(): الحصول على مثيل لبرنامج فك التشفير-
openLnb(): للحصول على مثيل LNB داخلي openLnbByName(): الحصول على مثيل LNB خارجي-
openTimeFilter(): الحصول على مثيل لفلتر الوقت
توفّر حزمة Tuner وظائف لا تغطيها حِزم الفلتر ومسجّل الفيديو الرقمي والواجهة الأمامية. وفي ما يلي قائمة بالوظائف.
cancelTuningscan/cancelScanninggetAvSyncHwIdgetAvSyncTimeconnectCiCam1/disconnectCiCamshareFrontendFromTunerupdateResourcePrioritysetOnTuneEventListenersetResourceLostListener
Android.media.tv.tuner.frontend
تتضمّن حزمة الواجهة الأمامية مجموعات من الإعدادات والمعلومات والحالات والأحداث والإمكانات ذات الصلة بالواجهة الأمامية.
صفوف
يتم اشتقاق FrontendSettings لمعايير DTV المختلفة من خلال الفئات أدناه.
AnalogFrontendSettingsAtsc3FrontendSettingsAtscFrontendSettingsDvbcFrontendSettingsDvbsFrontendSettingsDvbtFrontendSettingsIsdbs3FrontendSettingsIsdbsFrontendSettingsIsdbtFrontendSettings
بدءًا من الإصدار 12 من نظام التشغيل Android مع الإصدار 1.1 أو الإصدارات الأحدث من Tuner HAL، يتوفّر معيار DTV التالي.
DtmbFrontendSettings
يتم اشتقاق FrontendCapabilities لمعايير DTV المختلفة من خلال الفئات
أدناه.
AnalogFrontendCapabilitiesAtsc3FrontendCapabilitiesAtscFrontendCapabilitiesDvbcFrontendCapabilitiesDvbsFrontendCapabilitiesDvbtFrontendCapabilitiesIsdbs3FrontendCapabilitiesIsdbsFrontendCapabilitiesIsdbtFrontendCapabilities
بدءًا من الإصدار 12 من نظام التشغيل Android مع الإصدار 1.1 أو الإصدارات الأحدث من Tuner HAL، يتوفّر معيار DTV التالي.
DtmbFrontendCapabilities
تعرض FrontendInfo معلومات الواجهة الأمامية.
يستردّ FrontendStatus الحالة الحالية للواجهة الأمامية.
تستمع OnTuneEventListener إلى الأحداث في الواجهة الأمامية.
يستخدم تطبيق TIS ScanCallback لمعالجة رسائل الفحص من الواجهة الأمامية.
البحث عن القنوات
لإعداد تلفزيون، يبحث التطبيق عن الترددات المتاحة وينشئ قائمة بالقنوات يمكن للمستخدمين الوصول إليها. قد تستخدم خدمة TIS Tuner.tune أو Tuner.scan(BLIND_SCAN) أو Tuner.scan(AUTO_SCAN) لإكمال عملية فحص القنوات.
إذا كان لدى TIS معلومات دقيقة عن التسليم للإشارة، مثل التردد والمعيار (على سبيل المثال، T/T2 أو S/S2) ومعلومات إضافية ضرورية (على سبيل المثال، معرّف PLD)، يُنصح باستخدام Tuner.tune كخيار أسرع.
عندما يتصل المستخدم بالرقم Tuner.tune، تحدث الإجراءات التالية:
- تعبئ "أداة إدارة معلومات الطلاب"
FrontendSettingsبالمعلومات المطلوبة باستخدامTuner.tune. - تعرض طبقة تجريد الأجهزة (HAL) رسائل
LOCKEDإذا كانت الإشارة مقفلة. - تستخدم أداة "نظام تذاكر الدعم"
Frontend.getStatusلجمع المعلومات اللازمة. - ينتقل نظام معلومات حركة المرور إلى التردد المتاح التالي في قائمة الترددات.
تتصل خدمة TIS Tuner.tune مرة أخرى إلى أن يتم استنفاد جميع الترددات.
أثناء الضبط، يمكنك الاتصال بالرقم stopTune() أو close() لإيقاف المكالمة Tuner.tune مؤقتًا أو إنهائها.
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 أيضًا رسائل مسح ضوئي أخرى لتقديم معلومات إضافية حول الإشارة.تستخدم "خدمة معلومات الضرائب"
Frontend.getStatusلجمع المعلومات اللازمة.تطلب خدمة TIS من HAL تنفيذ
Tuner.scanلمواصلة الانتقال إلى الإعداد التالي بالوتيرة نفسها. إذا كانت بنيةFrontendSettingsفارغة، يستخدم HAL الإعداد التالي المتاح. بخلاف ذلك، يستخدم HALFrontendSettingsلإجراء عملية فحص لمرة واحدة ويرسلENDللإشارة إلى أنّ عملية الفحص قد انتهت.تكرّر خدمة TIS الإجراءات المذكورة أعلاه إلى أن يتم استنفاد جميع الإعدادات المتعلقة بالتكرار.
يرسل HAL
ENDللإشارة إلى انتهاء عملية الفحص.ينتقل نظام معلومات حركة المرور إلى التردد المتاح التالي في قائمة الترددات.
تتصل خدمة TIS Tuner.scan(AUTO_SCAN) مرة أخرى إلى أن يتم استنفاد جميع الترددات.
أثناء الفحص، يمكنك الاتصال بالرقم stopScan() أو close() لإيقاف الفحص مؤقتًا أو إنهائه.
Tuner.scan(BLIND_SCAN)
إذا لم يكن لدى TIS قائمة بالترددات وكان بإمكان Vendor HAL البحث عن تردد الواجهة الأمامية التي يحدّدها المستخدم للحصول على مورد الواجهة الأمامية، يُنصح باستخدام Tuner.scan(BLIND_SCAN).
- تستخدم خدمة TIS
Tuner.scan(BLIND_SCAN). يمكن تحديد عدد مرات التكرار فيFrontendSettingsلعدد مرات التكرار عند البدء، ولكن تتجاهل خدمة TIS الإعدادات الأخرى فيFrontendSettings. - تعرض طبقة تجريد الأجهزة (HAL) رسالة
LOCKEDفحص إذا كانت الإشارة مقفلة. - تستخدم "خدمة معلومات الضرائب"
Frontend.getStatusلجمع المعلومات اللازمة. - ستتصل خدمة TIS بك
Tuner.scanمرة أخرى لمواصلة عملية المسح الضوئي. (سيتم تجاهلFrontendSettings). - تكرّر خدمة TIS الإجراءات المذكورة أعلاه إلى أن يتم استنفاد جميع الإعدادات المتعلقة بالتكرار. تزيد طبقة تجريد الأجهزة (HAL) من التكرار بدون الحاجة إلى اتّخاذ أي إجراء من نظام معلومات النقل (TIS).
تعرض طبقة تجريد الأجهزة (HAL) الرسالة
PROGRESS.
تتصل خدمة TIS Tuner.scan(AUTO_SCAN) مرة أخرى إلى أن يتم استنفاد جميع الترددات.
تعرض طبقة تجريد الأجهزة END للإشارة إلى انتهاء عملية الفحص.
أثناء الفحص، يمكنك الاتصال بالرقم stopScan() أو close() لإيقاف الفحص مؤقتًا أو إنهائه.
الشكل 9. مخطّط انسيابي لعملية فحص TIS
Android.media.tv.tuner.filter
حزمة الفلتر هي مجموعة من عمليات الفلترة بالإضافة إلى الإعدادات والخيارات وعمليات الرجوع والأحداث. تتضمّن الحزمة العمليات أدناه. راجِع رمز المصدر لنظام التشغيل Android للحصول على القائمة الكاملة بالعمليات.
configure()start()stop()flush()read()
للحصول على القائمة الكاملة، يُرجى الرجوع إلى رمز المصدر لنظام التشغيل Android.
يتم اشتقاق FilterConfiguration من الفئات أدناه. تتضمّن الإعدادات نوع الفلتر الرئيسي، وتحدّد البروتوكول الذي يستخدمه الفلتر لاستخراج البيانات.
AlpFilterConfigurationIpFilterConfigurationMmtpFilterConfigurationTlvFilterConfigurationTsFilterConfiguration
يتم استخلاص الإعدادات من الفئات أدناه. تخصّ هذه الإعدادات النوع الفرعي للفلتر، وتحدّد أنواع البيانات التي يمكن للفلتر استبعادها.
SectionSettingsAvSettingsPesSettingsRecordSettingsDownloadSettings
يتم اشتقاق FilterEvent من الفئات أدناه لإعداد تقارير عن الأحداث لأنواع مختلفة من البيانات.
SectionEventMediaEventPesEventTsRecordEventMmtpRecordEventTemiEventDownloadEventIpPayloadEvent
بدءًا من Android 12 مع الإصدار 1.1 أو الإصدارات الأحدث من Tuner HAL، تتوفّر الأحداث التالية.
IpCidChangeEventRestartEventScramblingStatusEvent
تنسيق الأحداث وتنسيق البيانات من الفلتر
| نوع الفلتر | العلامات | الأحداث | عملية البيانات | تنسيق البيانات |
|---|---|---|---|---|
TS.SECTIONMMTP.SECTIONIP.SECTIONTLV.SECTIONALP.SECTION |
isRaw: |
إجراء إلزامي:DemuxFilterStatus::DATA_READYDemuxFilterStatus::DATA_OVERFLOWإجراء مقترَح: DemuxFilterStatus::LOW_WATERDemuxFilterStatus::HIGH_WATER |
استنادًا إلى الحدث والجدول الزمني الداخلي، شغِّلFilter.read(buffer, offset, adjustedSize) مرة واحدة أو أكثر.يتم نسخ البيانات من قائمة انتظار الرسائل في طبقة تجريد الأجهزة (HAL) إلى المخزن المؤقت للعميل. |
يتم ملء حزمة جلسة مجمّعة في FMQ بحزمة جلسة أخرى. |
isRaw: |
إلزامي:DemuxFilterEvent::DemuxFilterSectionEvent[n]DemuxFilterStatus::DATA_READYDemuxFilterStatus::DATA_OVERFLOWاختياري: DemuxFilterStatus::LOW_WATERDemuxFilterStatus::HIGH_WATER |
for i=0; i<n; i++يتم نسخ البيانات من قائمة انتظار الرسائل في طبقة HAL إلى المخزن المؤقت للعميل. |
||
TS.PES |
isRaw: |
إجراء إلزامي:DemuxFilterStatus::DATA_READYDemuxFilterStatus::DATA_OVERFLOWإجراء مقترَح: DemuxFilterStatus::LOW_WATERDemuxFilterStatus::HIGH_WATER |
استنادًا إلى الحدث والجدول الزمني الداخلي، شغِّلFilter.read(buffer, offset, adjustedSize) مرة واحدة أو أكثر.يتم نسخ البيانات من قائمة انتظار الرسائل في طبقة تجريد الأجهزة إلى المخزن المؤقت للعميل. |
يتم ملء حزمة PES مجمّعة واحدة في FMQ بحزمة PES أخرى. |
isRaw: |
إلزامي:DemuxFilterEvent::DemuxFilterPesEvent[n]DemuxFilterStatus::DATA_READYDemuxFilterStatus::DATA_OVERFLOWاختياري: DemuxFilterStatus::LOW_WATERDemuxFilterStatus::HIGH_WATER |
for i=0; i<n; i++يتم نسخ البيانات من قائمة انتظار الرسائل في طبقة HAL إلى المخزن المؤقت للعميل. |
||
MMTP.PES |
isRaw: |
إجراء إلزامي:DemuxFilterStatus::DATA_READYDemuxFilterStatus::DATA_OVERFLOWإجراء مقترَح: DemuxFilterStatus::LOW_WATERDemuxFilterStatus::HIGH_WATER |
استنادًا إلى الحدث والجدول الزمني الداخلي، شغِّلFilter.read(buffer, offset, adjustedSize) مرة واحدة أو أكثر.يتم نسخ البيانات من قائمة انتظار الرسائل في طبقة تجريد الأجهزة إلى المخزن المؤقت للعميل. |
يتم ملء إحدى حِزم MFU المجمّعة في FMQ بحزمة MFU أخرى. |
isRaw: |
إلزامي:DemuxFilterEvent::DemuxFilterPesEvent[n]DemuxFilterStatus::DATA_READYDemuxFilterStatus::DATA_OVERFLOWاختياري: DemuxFilterStatus::LOW_WATERDemuxFilterStatus::HIGH_WATER |
for i=0; i<n; i++يتم نسخ البيانات من قائمة انتظار الرسائل في طبقة تجريد الأجهزة إلى المخزن المؤقت للعميل. |
||
TS.TS |
لا ينطبق | إجراء إلزامي:DemuxFilterStatus::DATA_READYDemuxFilterStatus::DATA_OVERFLOWإجراء مقترَح: DemuxFilterStatus::LOW_WATERDemuxFilterStatus::HIGH_WATER |
استنادًا إلى الحدث والجدول الزمني الداخلي، شغِّلFilter.read(buffer, offset, adjustedSize) مرة واحدة أو أكثر.يتم نسخ البيانات من قائمة انتظار الرسائل في طبقة تجريد الأجهزة إلى المخزن المؤقت للعميل. |
تمت تعبئة ts الذي تم استبعاده باستخدام العنوان tsفي FMQ. |
TS.AudioTS.VideoMMTP.AudioMMTP.Video |
isPassthrough: |
اختياري:DemuxFilterStatus::DATA_READYDemuxFilterStatus::DATA_OVERFLOW |
يمكن للعميل بدء MediaCodec بعد تلقّي DemuxFilterStatus::DATA_READY.يمكن للعميل استدعاء Filter.flush بعد تلقّي DemuxFilterStatus::DATA_OVERFLOW. |
لا ينطبق |
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 المدمج في 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) مرة واحدة أو أكثر.يتم نسخ البيانات من قائمة انتظار الرسائل في طبقة تجريد الأجهزة إلى المخزن المؤقت للعميل. |
تمت تعبئة 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::* والجدول الزمني الداخلي، اتّبِع أحد الإجراءات
التالية:
|
بالنسبة إلى بيانات الفهرس: يتم تضمينها في حمولة الحدث. بالنسبة إلى المحتوى المسجّل: تم ملء حزمة البث المسجّل المدمجة في 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)يتم نسخ البيانات من قائمة انتظار الرسائل في طبقة 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)يتم نسخ البيانات من قائمة انتظار الرسائل في طبقة HAL إلى المخزن المؤقت للعميل. |
يتم ملء حزمة حمولة بيانات بروتوكول الإنترنت في FMQ بحزمة حمولة بيانات بروتوكول إنترنت أخرى. |
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) مرة واحدة أو أكثر.يتم نسخ البيانات من قائمة انتظار الرسائل في طبقة تجريد الأجهزة إلى المخزن المؤقت للعميل. |
تم ملء 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();معالجة
SectionEventFilterCallback 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. Flow لاستخدام MediaEvent من الفلتر
- افتح فلاتر الصوت والفيديو وأعِدّها وابدأها.
- معالجة
MediaEvent - استلام
MediaEvent - أضِفوا المحتوى غير الخطي إلى قائمة المحتوى التالي "
codec". - إصدار معرّف A/V عند استهلاك البيانات
Android.media.tv.tuner.dvr
توفّر DvrRecorder طُرق التسجيل التالية.
configureattachFilterdetachFilterstartflushstopsetFileDescriptorwrite
توفّر DvrPlayback هذه الطرق لتشغيل المحتوى.
configurestartflushstopsetFileDescriptorread
يُستخدَم DvrSettings لضبط DvrRecorder وDvrPlayback.
يتم استخدام OnPlaybackStatusChangedListener وOnRecordStatusChangedListener للإبلاغ عن حالة مثيل مسجّل فيديو رقمي.
مثال على سير عمل لبدء تسجيل
الشكل 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 الخاصة ببرنامج Tuner لغة تعريف واجهة HIDL وتحدّد الواجهة بين إطار العمل وأجهزة المورّد. يستخدم المورّدون الواجهة لتنفيذ Tuner HAL، ويستخدمها إطار العمل للتواصل مع عملية تنفيذ Tuner HAL.
الوحدات
Tuner 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 |
الإصدار 1.1 من طبقة تجريد الأجهزة الخاصة بأداة استقبال التلفزيون (مستمد من الإصدار 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 |
الشكل 13. مخطّط تفاعلات وحدات Tuner HAL
ربط الفلاتر
تتيح طبقة تجريد الأجهزة (HAL) الخاصة ببرنامج Tuner ربط الفلاتر ببعضها، ما يتيح ربط الفلاتر بفلاتر أخرى لإنشاء طبقات متعددة. تخضع الفلاتر للقواعد التالية.
- يتم ربط الفلاتر كشجرة، ولا يُسمح بالمسار المغلق.
- عقدة الجذر هي 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. مخطّط انسيابي لربط الفلاتر بطبقات متعددة
Tuner Resource Manager
قبل توفّر واجهة برمجة التطبيقات Tuner Resource Manager (TRM)، كان التبديل بين تطبيقَين يتطلّب استخدام جهاز Tuner نفسه. استخدم إطار عمل إدخال التلفزيون (TIF) آلية "الفوز بالاستحواذ أولاً"، ما يعني أنّ التطبيق الذي يحصل على المورد أولاً يحتفظ به. ومع ذلك، قد لا تكون هذه الآلية مناسبة لبعض حالات الاستخدام المعقّدة.
تعمل "إدارة الموارد التلفزيونية" كخدمة تابعة لنظام التشغيل لإدارة موارد الأجهزة الخاصة بـ "الموالف" (Tuner) وTVInput وCAS للتطبيقات. تستخدِم ميزة "إدارة الموارد الحرارية" آلية "الفوز في المقدّمة" التي تحتسب أولوية التطبيق استنادًا إلى حالة التطبيق في المقدّمة أو الخلفية ونوع حالة الاستخدام. يمنح مدير الموارد أو يبطلها استنادًا إلى الأولوية. تتيح إدارة الموارد في 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)/releaseFrontendrequestDemux(TunerDemuxRequest request, int[] demuxHandle)/releaseDemuxrequestDescrambler(TunerDescramblerRequest request, int[] descramblerHandle)/releaseDescramblerrequestCasSession(CasSessionRequest request, int[] casSessionHandle)/releaseCasSessionrequestLnb(TunerLnbRequest request, int[] lnbHandle)/releaseLnb
في ما يلي قائمة بفئات العملاء والطلبات.
ResourceClientProfileResourcesReclaimListenerTunerFrontendRequestTunerDemuxRequestTunerDescramblerRequestCasSessionRequestTunerLnbRequest
أولوية العميل
تحسب خدمة TRM أولوية العميل باستخدام مَعلمات من ملف تعريف العميل وقيمة الأولوية من ملف الإعداد. يمكن أيضًا تعديل الأولوية باستخدام قيمة أولوية عشوائية من العميل.
المَعلمات في الملف الشخصي للعميل
يستردّ TRM معرّف العملية من mTvInputSessionId لتحديد ما إذا كان التطبيق يعمل في المقدّمة أو في الخلفية. لإنشاء mTvInputSessionId أو TvInputService.onCreateSession أو TvInputService.onCreateRecordingSession، يبدأ TvInputService.onCreateSession جلسة 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.
قيمة الأولوية العشوائية وقيمة nice
توفّر TRM updateClientPriority للعميل من أجل تعديل قيمة الأولوية والقيمة اللطيفة العشوائية.
تستبدل قيمة الأولوية العشوائية قيمة الأولوية المحسوبة من نوع حالة الاستخدام ومعرّف الجلسة.
تشير قيمة nice إلى مدى تساهل سلوك العميل عندما يتعارض مع عميل آخر. تؤدي قيمة nice إلى خفض قيمة أولوية العميل قبل مقارنتها بأولوية العميل الصعب.
آلية الاسترداد
يوضِّح المخطّط البياني أدناه كيفية استرداد الموارد وتعيينها عند حدوث تعارض في الموارد.
الشكل 15. مخطّط لآلية استرداد الموارد في حال حدوث تعارض بين موارد Tuner