إطار الموالف

بالنسبة لنظام التشغيل Android 11 أو الإصدارات الأحدث، يمكنك استخدام إطار عمل Android Tuner لتقديم محتوى الصوت/الفيديو. يستخدم إطار العمل مسار الأجهزة من البائعين، مما يجعله مناسبًا لكل من شركة نفط الجنوب (SoC) المنخفضة والمتطورة. يوفر إطار العمل طريقة آمنة لتقديم محتوى الصوت والفيديو المحمي بواسطة بيئة تنفيذ موثوقة (TEE) ومسار وسائط آمن (SMP)، مما يسمح باستخدامه في بيئة حماية المحتوى المقيدة للغاية.

تؤدي الواجهة الموحدة بين Tuner وAndroid CAS إلى تكامل أسرع بين موردي Tuner وموردي CAS. تعمل واجهة Tuner مع MediaCodec و AudioTrack لإنشاء حل عالمي واحد لأجهزة Android TV. تدعم واجهة Tuner كلا من التلفزيون الرقمي والتلفزيون التناظري بناءً على معايير البث الرئيسية.

عناصر

بالنسبة لنظام Android 11، تم تصميم ثلاثة مكونات خصيصًا لمنصة التلفزيون.

  • Tuner HAL: واجهة بين الإطار والبائعين
  • Tuner SDK API: واجهة بين الإطار والتطبيقات
  • مدير موارد الموالف (TRM): ينسق موارد الموالف HW

بالنسبة لنظام التشغيل Android 11، تم تحسين المكونات التالية.

  • كاس V2
  • TvInputService أو خدمة إدخال التلفزيون (TIS)
  • TvInputManagerService أو خدمة إدارة إدخال التلفزيون (TIMS)
  • MediaCodec أو برنامج ترميز الوسائط
  • مسار AudioTrack أو المسار الصوتي
  • MediaResourceManager أو مدير موارد الوسائط (MRM)

مخطط تدفق مكونات إطار موالف.

الشكل 1. التفاعلات بين مكونات Android TV

سمات

تدعم الواجهة الأمامية معايير DTV الموضحة أدناه.

  • ATSC
  • ATSC3
  • دي في بي سي/اس/تي
  • البنك الإسلامي للتنمية S/S3/T
  • التناظرية

تدعم الواجهة الأمامية في Android 12 مع Tuner HAL 1.1 أو أعلى معيار DTV أدناه.

  • دي تي إم بي

يدعم Demux بروتوكولات الدفق أدناه.

  • تيار النقل (TS)
  • بروتوكول نقل الوسائط MPEG (MMTP)
  • بروتوكول الإنترنت (IP)
  • قيمة طول النوع (TLV)
  • بروتوكول طبقة الارتباط ATSC (ALP)

يدعم Decrambler حماية المحتوى أدناه.

  • تأمين مسار الوسائط
  • مسح مسار الوسائط
  • تأمين السجل المحلي
  • تأمين التشغيل المحلي

تدعم واجهات برمجة تطبيقات الموالف حالات الاستخدام الموضحة أدناه.

  • مسح
  • يعيش
  • التشغيل
  • سِجِلّ

يدعم Tuner و MediaCodec و AudioTrack أوضاع تدفق البيانات أدناه.

  • حمولة ES مع مخزن مؤقت للذاكرة
  • حمولة ES مع مقبض ذاكرة آمن
  • يمر من خلال

التصميم الكلي

يتم تعريف Tuner HAL بين إطار عمل Android وأجهزة البائع.

  • يصف ما يتوقعه إطار العمل من البائع وكيف يمكن أن يفعل البائع ذلك.
  • تصدير وظائف الواجهة الأمامية وdemux وdescrambler إلى إطار العمل من خلال واجهات IFrontend و IDemux و IDescrambler و IFilter و IDvr و ILnb .
  • يتضمن وظائف لدمج Tuner HAL مع مكونات إطار العمل الأخرى، مثل MediaCodec و AudioTrack .

يتم إنشاء فئة Tuner Java والفئة الأصلية.

  • تسمح Tuner Java API للتطبيقات بالوصول إلى Tuner HAL من خلال واجهات برمجة التطبيقات العامة.
  • تسمح الفئة الأصلية بالتحكم في الأذونات والتعامل مع كميات كبيرة من بيانات التسجيل أو التشغيل باستخدام 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 آمنة كمدخل للمحتوى.
  • تم تكوينه لإجراء مزامنة الصوت والصورة للأجهزة أثناء التشغيل النفقي.
  • تم تكوين الدعم لوضع ES_payload والعبور.

التصميم العام للموالف HAL.

الشكل 2. رسم تخطيطي للمكونات داخل موالف HAL

سير العمل الشامل

توضح الرسوم البيانية أدناه تسلسل المكالمات لتشغيل البث المباشر.

يثبت

تسلسل الإعداد لمخطط تشغيل البث المباشر.

الشكل 3. تسلسل الإعداد لتشغيل البث المباشر

التعامل مع الصوت والصورة

التعامل مع A/V لمخطط تشغيل البث المباشر.

الشكل 4. التعامل مع الصوت والصورة لتشغيل البث المباشر

التعامل مع المحتوى المختلط

التعامل مع المحتوى المخلوط لمخطط تشغيل البث المباشر.

الشكل 5. التعامل مع المحتوى المشفر لتشغيل البث المباشر

معالجة بيانات الصوت والصورة

معالجة بيانات الصوت والصورة لمخطط تشغيل البث المباشر.

الشكل 6. معالجة الصوت والصورة لتشغيل البث المباشر

موالف SDK API

تتعامل واجهة برمجة تطبيقات Tuner SDK مع التفاعلات مع Tuner JNI وTuner HAL و TunerResourceManager . يستخدم تطبيق TIS واجهة برمجة تطبيقات Tuner SDK للوصول إلى موارد Tuner والمكونات الفرعية مثل عامل التصفية وأداة إلغاء التشفير. الواجهة الأمامية و Demux هي مكونات داخلية.

مخطط التدفق لواجهة برمجة تطبيقات Tuner SDK.

الشكل 7. التفاعلات مع Tuner SDK API

الإصدارات

بدءًا من Android 12، تدعم Tuner SDK API الميزة الجديدة في Tuner HAL 1.1، وهي ترقية إصدار متوافق مع الإصدارات السابقة من Tuner 1.0.

استخدم واجهة برمجة التطبيقات التالية للتحقق من إصدار HAL قيد التشغيل.

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

يمكن العثور على الحد الأدنى المطلوب من إصدار HAL في وثائق واجهات برمجة تطبيقات 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. حزم Tuner SDK API

Android.media.tv.tuner

تعد حزمة Tuner نقطة دخول لاستخدام إطار عمل Tuner. يستخدم تطبيق TIS الحزمة لتهيئة مثيلات الموارد والحصول عليها عن طريق تحديد الإعداد الأولي ورد الاتصال.

  • tuner() : يقوم بتهيئة مثيل Tuner عن طريق تحديد معلمات useCase و sessionId .
  • tune() : الحصول على مورد الواجهة الأمامية وضبطه عن طريق تحديد معلمة FrontendSetting .
  • openFilter() : الحصول على مثيل عامل التصفية عن طريق تحديد نوع المرشح.
  • openDvrRecorder() : الحصول على مثيل التسجيل عن طريق تحديد حجم المخزن المؤقت.
  • openDvrPlayback() : الحصول على نسخة التشغيل عن طريق تحديد حجم المخزن المؤقت.
  • openDescrambler() : الحصول على نسخة أداة إلغاء التشفير.
  • openLnb() : الحصول على مثيل LNB داخلي.
  • openLnbByName() : الحصول على مثيل LNB خارجي.
  • openTimeFilter() : الحصول على مثيل مرشح الوقت.

توفر حزمة Tuner وظائف لا يتم تغطيتها ضمن حزم المرشح ومسجل الفيديو الرقمي والواجهة الأمامية. الوظائف مذكورة أدناه.

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

Android.media.tv.tuner.frontend

تتضمن حزمة الواجهة الأمامية مجموعات من الإعدادات والمعلومات والحالات والأحداث والإمكانيات المتعلقة بالواجهة الأمامية.

الطبقات

يتم اشتقاق FrontendSettings لمعايير DTV المختلفة حسب الفئات أدناه.

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

بدءًا من Android 12 مع Tuner HAL 1.1 أو أعلى، يتم دعم معيار DTV التالي.

  • DtmbFrontendSettings

يتم اشتقاق FrontendCapabilities لمعايير DTV المختلفة حسب الفئات أدناه.

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

بدءًا من Android 12 مع Tuner HAL 1.1 أو أعلى، يتم دعم معيار 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 ، تحدث الإجراءات التالية:

  • يقوم TIS بملء FrontendSettings بالمعلومات المطلوبة باستخدام Tuner.tune .
  • تقوم تقارير HAL بضبط الرسائل LOCKED إذا كانت الإشارة مقفلة.
  • يستخدم TIS Frontend.getStatus لجمع المعلومات الضرورية.
  • ينتقل TIS إلى التردد التالي المتاح في قائمة الترددات الخاصة به.

يستدعي 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 أيضًا بالإبلاغ عن رسائل مسح أخرى لتوفير معلومات إضافية حول الإشارة.

  • يستخدم 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

حزمة التصفية عبارة عن مجموعة من عمليات التصفية بالإضافة إلى التكوين والإعدادات وعمليات الاسترجاعات والأحداث. تتضمن الحزمة العمليات أدناه. ارجع إلى كود مصدر Android للحصول على القائمة الكاملة للعمليات.

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

ارجع إلى كود مصدر Android للحصول على القائمة الكاملة.

يتم اشتقاق FilterConfiguration من الفئات أدناه. التكوينات مخصصة لنوع الفلتر الرئيسي وهي تحدد البروتوكول الذي يستخدمه الفلتر لاستخراج البيانات.

  • AlpFilterConfiguration
  • IpFilterConfiguration
  • MmtpFilterConfiguration
  • TlvFilterConfiguration
  • TsFilterConfiguration

الإعدادات مستمدة من الفئات أدناه. الإعدادات مخصصة للنوع الفرعي لعامل التصفية وتحدد أنواع البيانات التي يمكن أن يستبعدها عامل التصفية.

  • SectionSettings
  • AvSettings
  • PesSettings
  • RecordSettings
  • DownloadSettings

يتم اشتقاق FilterEvent من الفئات أدناه للإبلاغ عن الأحداث لأنواع مختلفة من البيانات.

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

بدءًا من Android 12 مع Tuner HAL 1.1 أو أعلى، يتم دعم الأحداث التالية.

  • IpCidChangeEvent
  • RestartEvent
  • ScramblingStatusEvent
الأحداث وتنسيق البيانات من عامل التصفية
نوع فلتر أعلام الأحداث عملية البيانات تنسيق البيانات
TS.SECTION
MMTP.SECTION
IP.SECTION
TLV.SECTION
ALP.SECTION
isRaw:
true
إلزامي:
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW

مُستَحسَن:
DemuxFilterStatus::LOW_WATER
DemuxFilterStatus::HIGH_WATER
وفقًا للحدث والجدول الزمني الداخلي، قم بالتشغيل
Filter.read(buffer, offset, adjustedSize) مرة واحدة أو أكثر.

يتم نسخ البيانات من MQ الخاص بـ HAL إلى المخزن المؤقت للعميل.
تتم تعبئة حزمة جلسة مجمعة واحدة في FMQ بواسطة حزمة جلسة أخرى.
isRaw:
false
إلزامي:
DemuxFilterEvent::DemuxFilterSectionEvent[n]
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW

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


يتم نسخ البيانات من MQ الخاص بـ HAL إلى المخزن المؤقت للعميل.
TS.PES isRaw:
true
إلزامي:
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW

مُستَحسَن:
DemuxFilterStatus::LOW_WATER
DemuxFilterStatus::HIGH_WATER
وفقًا للحدث والجدول الزمني الداخلي، قم بالتشغيل
Filter.read(buffer, offset, adjustedSize) مرة واحدة أو أكثر.

يتم نسخ البيانات من MQ الخاص بـ HAL إلى المخزن المؤقت للعميل.
تتم تعبئة حزمة PES المجمعة في FMQ بواسطة حزمة PES أخرى.
isRaw:
false
إلزامي:
DemuxFilterEvent::DemuxFilterPesEvent[n]
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW

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


يتم نسخ البيانات من MQ الخاص بـ HAL إلى المخزن المؤقت للعميل.
MMTP.PES isRaw:
true
إلزامي:
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW

مُستَحسَن:
DemuxFilterStatus::LOW_WATER
DemuxFilterStatus::HIGH_WATER
وفقًا للحدث والجدول الزمني الداخلي، قم بالتشغيل
Filter.read(buffer, offset, adjustedSize) مرة واحدة أو أكثر.

يتم نسخ البيانات من MQ الخاص بـ HAL إلى المخزن المؤقت للعميل.
يتم تعبئة حزمة MFU مجمعة واحدة في FMQ بواسطة حزمة MFU أخرى.
isRaw:
false
إلزامي:
DemuxFilterEvent::DemuxFilterPesEvent[n]
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW

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


يتم نسخ البيانات من MQ الخاص بـ HAL إلى المخزن المؤقت للعميل.
TS.TS
لا يوجد إلزامي:
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW

مُستَحسَن:
DemuxFilterStatus::LOW_WATER
DemuxFilterStatus::HIGH_WATER
وفقًا للحدث والجدول الزمني الداخلي، قم بالتشغيل
Filter.read(buffer, offset, adjustedSize) مرة واحدة أو أكثر.

يتم نسخ البيانات من MQ الخاص بـ HAL إلى المخزن المؤقت للعميل.
تمت تصفيته من ts برأس ts
يتم ملؤه في FMQ.
TS.Audio
TS.Video
MMTP.Audio
MMTP.Video
isPassthrough:
true
خياري:
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW
يمكن للعميل بدء تشغيل MediaCodec بعد تلقي DemuxFilterStatus::DATA_READY .
يمكن للعميل الاتصال بـ Filter.flush بعد تلقي DemuxFilterStatus::DATA_OVERFLOW .
لا يوجد
isPassthrough:
false
إلزامي:
DemuxFilterEvent::DemuxFilterMediaEvent[n]
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW

خياري:
DemuxFilterStatus::LOW_WATER
DemuxFilterStatus::HIGH_WATER
لاستخدام MediaCodec :
for i=0; i<n; i++
linearblock = MediaEvent[i].getLinearBlock();
codec.startQueueLinearBlock(linearblock)
linearblock.recycle()


لاستخدام الصوت المباشر لـ AudioTrack :
for i=0; i<n; i++
audioHandle = MediaEvent[i].getAudioHandle();
audiotrack.write(encapsulated(audiohandle))
بيانات ES أو ES جزئية في ذاكرة ION.
TS.PCR
IP.NTP
ALP.PTP
لا يوجد إلزامي: غير متاح
اختياري: غير متاح
لا يوجد لا يوجد
TS.RECORD لا يوجد إلزامي:
DemuxFilterEvent::DemuxFilterTsRecordEvent[n]
RecordStatus::DATA_READY
RecordStatus::DATA_OVERFLOW
RecordStatus::LOW_WATER
RecordStatus::HIGH_WATER

خياري:
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW
DemuxFilterStatus::LOW_WATER
DemuxFilterStatus::HIGH_WATER
بالنسبة لبيانات الفهرس:
for i=0; i<n; i++
DemuxFilterTsRecordEvent[i];


بالنسبة للمحتوى المسجل ، وفقًا لـ RecordStatus::* والجدول الداخلي، قم بأحد الإجراءات التالية:
  • قم بتشغيل DvrRecord.write(adustedSize) مرة واحدة أو أكثر للتخزين.
    يتم نقل البيانات من MQ الخاص بـ HAL إلى وحدة التخزين.
  • قم بتشغيل DvrRecord.write(buffer, adustedSize) مرة واحدة أو أكثر للتخزين المؤقت.
    يتم نسخ البيانات من MQ الخاص بـ HAL إلى المخزن المؤقت للعميل.
بالنسبة لبيانات الفهرس: محمولة في حمولة الحدث.

بالنسبة للمحتوى المسجل: تدفق Muxed TS مملوء بـ FMQ.
TS.TEMI لا يوجد إلزامي:
DemuxFilterEvent::DemuxFilterTemiEvent[n]

خياري:
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW
DemuxFilterStatus::LOW_WATER
DemuxFilterStatus::HIGH_WATER
for i=0; i<n; i++
DemuxFilterTemiEvent[i];
لا يوجد
MMTP.MMTP لا يوجد إلزامي:
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW

مُستَحسَن:
DemuxFilterStatus::LOW_WATER
DemuxFilterStatus::HIGH_WATER
وفقًا للحدث والجدول الزمني الداخلي، قم بالتشغيل
Filter.read(buffer, offset, adjustedSize) مرة واحدة أو أكثر.

يتم نسخ البيانات من MQ الخاص بـ HAL إلى المخزن المؤقت للعميل.
تمت تصفيته من mmtp برأس mmtp
يتم ملؤه في FMQ.
MMTP.RECORD لا يوجد إلزامي:
DemuxFilterEvent::DemuxFilterMmtpRecordEvent[n]
RecordStatus::DATA_READY
RecordStatus::DATA_OVERFLOW
RecordStatus::LOW_WATER
RecordStatus::HIGH_WATER

خياري:
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW
DemuxFilterStatus::LOW_WATER
DemuxFilterStatus::HIGH_WATER
بالنسبة لبيانات الفهرس: for i=0; i<n; i++
DemuxFilterMmtpRecordEvent[i];


بالنسبة للمحتوى المسجل ، وفقًا لـ RecordStatus::* والجدول الداخلي، قم بأحد الإجراءات التالية:
  • قم بتشغيل DvrRecord.write(adjustedSize) مرة واحدة أو أكثر للتخزين.
    يتم نقل البيانات من MQ الخاص بـ HAL إلى وحدة التخزين.
  • قم بتشغيل DvrRecord.write(buffer, adjustedSize) مرة واحدة أو أكثر للتخزين المؤقت.
    يتم نسخ البيانات من MQ الخاص بـ HAL إلى المخزن المؤقت للعميل.
بالنسبة لبيانات الفهرس: محمولة في حمولة الحدث.

بالنسبة للمحتوى المسجل: دفق Muxed المسجل مملوء بـ FMQ.

إذا كان مصدر عامل التصفية للتسجيل هو TLV.TLV إلى IP.IP مع العبور، فإن الدفق المسجل له رأس TLV وIP.
MMTP.DOWNLOAD لا يوجد إلزامي:
DemuxFilterEvent::DemuxFilterDownloadEvent[n]
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW

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

يتم نسخ البيانات من MQ الخاص بـ HAL إلى المخزن المؤقت للعميل.
يتم تعبئة حزمة التنزيل في FMQ بواسطة حزمة تنزيل IP أخرى.
IP.IP_PAYLOAD لا يوجد إلزامي:
DemuxFilterEvent::DemuxFilterIpPayloadEvent[n]
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW

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

يتم نسخ البيانات من MQ الخاص بـ HAL إلى المخزن المؤقت للعميل.
تتم تعبئة حزمة حمولة IP في FMQ بواسطة حزمة حمولة IP أخرى.
IP.IP
TLV.TLV
ALP.ALP
isPassthrough:
true
خياري:
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW
يغذي الدفق الفرعي للبروتوكول الذي تمت تصفيته عامل التصفية التالي في سلسلة التصفية. لا يوجد
isPassthrough:
false
إلزامي:
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW

مُستَحسَن:
DemuxFilterStatus::LOW_WATER
DemuxFilterStatus::HIGH_WATER
وفقًا للحدث والجدول الزمني الداخلي، قم بالتشغيل
Filter.read(buffer, offset, adjustedSize) مرة واحدة أو أكثر.

يتم نسخ البيانات من MQ الخاص بـ HAL إلى المخزن المؤقت للعميل.
يتم ملء الدفق الفرعي للبروتوكول الذي تمت تصفيته برأس البروتوكول في FMQ.
IP.PAYLOAD_THROUGH
TLV.PAYLOAD_THROUGH
ALP.PAYLOAD_THROUGH
لا يوجد خياري:
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW
تعمل حمولة البروتوكول التي تمت تصفيتها على تغذية المرشح التالي في سلسلة المرشح. لا يوجد
مثال على التدفق لاستخدام عامل التصفية لإنشاء PSI/SI

مثال على التدفق لاستخدام عامل التصفية لإنشاء PSI/SI.

الشكل 10. التدفق لبناء PSI/SI

  1. افتح مرشحًا.

    Filter filter = tuner.openFilter(
      Filter.TYPE_TS,
      Filter.SUBTYPE_SECTION,
      /* bufferSize */1000,
      executor,
      filterCallback
    );
    
  2. تكوين وبدء تشغيل عامل التصفية.

    Settings settings = SectionSettingsWithTableInfo
        .builder(Filter.TYPE_TS)
        .setTableId(2)
        .setVersion(1)
        .setCrcEnabled(true)
        .setRaw(false)
        .setRepeat(false)
        .build();
      FilterConfiguration config = TsFilterConfiguration
        .builder()
        .setTpid(10)
        .setSettings(settings)
        .build();
      filter.configure(config);
      filter.start();
    
  3. SectionEvent العملية

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

مثال على التدفق لاستخدام MediaEvent من عامل التصفية.

الشكل 11. التدفق لاستخدام MediaEvent من عامل التصفية

  1. افتح مرشحات الصوت والفيديو وقم بتكوينها وبدء تشغيلها.
  2. MediaEvent العملية
  3. تلقي MediaEvent .
  4. قم بوضع الكتلة الخطية في قائمة الانتظار codec .
  5. حرر مقبض الصوت والصورة عند استهلاك البيانات.

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

موالف هال

يتبع Tuner HAL HIDL ويحدد الواجهة بين إطار العمل وأجهزة البائع. يستخدم البائعون الواجهة لتنفيذ Tuner HAL ويستخدمها إطار العمل للتواصل مع تطبيق Tuner HAL.

وحدات

موالف هال 1.0

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

موالف HAL ​​1.1 (مشتق من موالف HAL ​​1.0)

وحدات الضوابط الأساسية الضوابط الخاصة بالوحدة النمطية ملفات هال
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

مخطط تدفق التفاعلات بين وحدات Tuner HAL.

الشكل 13. رسم تخطيطي للتفاعلات بين وحدات Tuner HAL

ربط التصفية

يدعم Tuner 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. رسم تخطيطي لتدفق وصلة المرشح لطبقات متعددة

مدير موالف الموارد

قبل Tuner Resource Manager (TRM)، كان التبديل بين تطبيقين يتطلب نفس جهاز Tuner. يستخدم TV Input Framework (TIF) آلية "أول من يحصل على الفوز"، مما يعني أن التطبيق الذي يحصل على المورد أولاً يحتفظ بالمورد أولاً. ومع ذلك، قد لا تكون هذه الآلية مثالية لبعض حالات الاستخدام المعقدة.

يعمل TRM كخدمة نظام لإدارة موارد أجهزة Tuner و TVInput وCAS للتطبيقات. يستخدم TRM آلية "الفوز بالمقدمة"، والتي تحسب أولوية التطبيق بناءً على حالة المقدمة أو الخلفية للتطبيق ونوع حالة الاستخدام. يمنح TRM المورد أو يلغيه بناءً على الأولوية. تعمل TRM على مركزية إدارة موارد ATV للبث وOTT وDVR.

واجهة تي آر إم

يعرض 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 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 للعميل لتحديث قيمة الأولوية التعسفية والقيمة اللطيفة. تحل قيمة الأولوية التعسفية محل قيمة الأولوية المحسوبة من نوع حالة الاستخدام ومعرف الجلسة.

تشير القيمة اللطيفة إلى مدى تساهل سلوك العميل عندما يكون في صراع مع عميل آخر. تعمل القيمة اللطيفة على تقليل قيمة أولوية العميل قبل مقارنة قيمة الأولوية الخاصة به بالعميل الذي يمثل تحديًا.

آلية الاسترداد

يوضح الرسم البياني أدناه كيفية استعادة الموارد وتعيينها عند حدوث تعارض في الموارد.

رسم تخطيطي لعملية آلية الاسترداد.

الشكل 15. رسم تخطيطي لآلية الاسترداد للتعارض بين موارد الموالف