Framework tuner

Untuk Android 11 atau yang lebih baru, Anda dapat menggunakan Android Framework tuner untuk menayangkan konten A/V. Kerangka kerja ini menggunakan perangkat keras dari vendor, sehingga cocok untuk SoC kelas bawah dan kelas atas. Framework ini memberikan cara yang aman untuk menayangkan konten A/V yang dilindungi oleh Trusted Execution Environment (TEE) dan jalur media aman (SMP), yang memungkinkan untuk digunakan dalam lingkungan perlindungan konten yang sangat terbatas.

Antarmuka yang distandardisasi antara Tuner dan Android CAS menghasilkan integrasi antara vendor Tuner dan vendor CAS. Antarmuka Tuner berfungsi dengan MediaCodec dan AudioTrack untuk membuat solusi satu dunia untuk Android TV. Antarmuka Tuner mendukung TV digital dan TV analog berdasarkan standar penyiaran.

Komponen

Untuk Android 11, tiga komponen secara khusus yang dirancang untuk platform TV.

  • Tuner HAL: Antarmuka antara framework dan vendor
  • Tuner SDK API: Antarmuka antara framework dan aplikasi
  • Tuner Resource Manager (TRM): Mengoordinasikan resource HW Tuner

Untuk Android 11, komponen berikut telah ditingkatkan.

  • CAS V2
  • TvInputService atau TV Input Service (TIS)
  • TvInputManagerService atau TV Input Manager Service (TIMS)
  • MediaCodec atau codec media
  • AudioTrack atau trek audio
  • MediaResourceManager atau media resource manager (MRM)

Diagram alir komponen framework Tuner.

Gambar 1. Interaksi antara komponen Android TV

Fitur

Frontend mendukung standar DTV di bawah ini.

  • ATSC
  • ATSC3
  • DVB C/S/T
  • ISDB S/S3/T
  • Analog

Frontend di Android 12 dengan Tuner HAL 1.1 atau yang lebih tinggi mendukung standar DTV di bawah.

  • DTMB

Demux mendukung protokol streaming di bawah ini.

  • Streaming transpor (TS)
  • Protokol Transportasi Media MPEG (MMTP)
  • Protokol internet (IP)
  • Nilai panjang jenis (TLV)
  • Protokol lapisan link (ALP) ATSC

Descrambler mendukung perlindungan konten di bawah ini.

  • Jalur media yang aman
  • Hapus jalur media
  • Amankan data lokal
  • Pemutaran lokal yang aman

Tuner API mendukung kasus penggunaan di bawah ini.

  • Pindai
  • Live
  • Pemutaran
  • Rekam

Tuner, MediaCodec, dan AudioTrack mendukung mode aliran data di bawah.

  • Payload ES dengan buffer memori yang jelas
  • Payload ES dengan handle memori aman
  • Passthrough

Desain keseluruhan

Tuner HAL ditentukan di antara kerangka kerja Android dan perangkat keras.

  • Menjelaskan apa yang diharapkan kerangka kerja dari vendor dan bagaimana vendor mungkin melakukannya.
  • Mengekspor fungsi frontend, demux, dan descrambler ke framework baru melalui IFrontend, IDemux, IDescrambler, IFilter, IDvr, dan ILnb.
  • Menyertakan fungsi untuk mengintegrasikan Tuner HAL dengan kerangka kerja lain komponennya, seperti MediaCodec dan AudioTrack.

Class Java Tuner dan class native dibuat.

  • Tuner Java API memungkinkan aplikasi mengakses Tuner HAL melalui API publik.
  • Class native memungkinkan kontrol izin dan penanganan perekaman atau pemutaran data dengan Tuner HAL.
  • Modul Native Tuner adalah jembatan antara class Tuner Java dan Tuner HAL.

Class TRM dibuat.

  • Mengelola resource Tuner terbatas, seperti Frontend, LNB, Sesi CAS, dan perangkat input TV dari HAL input TV.
  • Menerapkan aturan untuk mengklaim kembali sumber daya yang tidak mencukupi dari aplikasi. Aturan defaultnya adalah kemenangan di latar depan.

Media CAS dan CAS HAL ditingkatkan dengan fitur di bawah ini.

  • Membuka sesi CAS untuk berbagai penggunaan dan algoritma.
  • Mendukung sistem CAS dinamis, seperti penghapusan dan penyisipan CICAM.
  • Terintegrasi dengan Tuner HAL dengan menyediakan token kunci.

MediaCodec dan AudioTrack ditingkatkan dengan fitur di bawah ini.

  • Menggunakan memori A/V yang aman sebagai input konten.
  • Dikonfigurasi untuk melakukan sinkronisasi A/V hardware dalam pemutaran yang disalurkan.
  • Dukungan yang dikonfigurasi untuk ES_payload dan mode passthrough.

Desain keseluruhan Tuner HAL.

Gambar 2. Diagram komponen dalam Tuner HAL

Alur kerja keseluruhan

Diagram di bawah ini menggambarkan urutan panggilan untuk pemutaran live streaming.

Penyiapan

Siapkan urutan diagram pemutaran live streaming.

Gambar 3. Siapkan urutan untuk pemutaran live streaming

Menangani A/V

Menangani diagram A/V untuk pemutaran live streaming.

Gambar 4. Menangani A/V untuk pemutaran live streaming

Menangani konten yang diacak

Menangani konten acak untuk diagram pemutaran siaran langsung.

Gambar 5. Menangani konten acak untuk pemutaran live streaming

Memproses data A/V

Memproses data A/V untuk diagram pemutaran siaran langsung.

Gambar 6. Memproses A/V untuk pemutaran live streaming

Tuner SDK API

Tuner SDK API menangani interaksi dengan Tuner JNI, Tuner HAL, dan TunerResourceManager. Aplikasi TIS menggunakan Tuner SDK API untuk mengakses Tuner resource dan subkomponen seperti filter dan descrambler. Frontend dan demux adalah komponen internal.

Diagram alur Tuner SDK API.

Gambar 7. Interaksi dengan Tuner SDK API

Versi

Dari Android 12, Tuner SDK API mendukung fitur baru di Tuner HAL 1.1, yang adalah upgrade versi yang kompatibel dengan versi sebelumnya dari Tuner 1.0.

Gunakan API berikut untuk memeriksa versi HAL yang sedang berjalan.

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

Versi HAL minimum yang diperlukan dapat ditemukan dalam dokumentasi API Android 12 yang baru.

Paket

Tuner SDK API menyediakan empat paket di bawah ini.

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

Diagram alir paket Tuner SDK API.

Gambar 8. Paket Tuner SDK API

Android.media.tv.tuner

Paket Tuner adalah titik entri untuk menggunakan framework Tuner. Aplikasi TIS menggunakan paket untuk menginisialisasi dan mendapatkan instance resource dengan menentukan callback dan setelan awal.

  • tuner(): Melakukan inisialisasi instance Tuner dengan menentukan useCase dan Parameter sessionId.
  • tune(): Mendapatkan resource frontend dan melakukan penyesuaian dengan menentukan Parameter FrontendSetting.
  • openFilter(): Memperoleh instance filter dengan menentukan jenis filter.
  • openDvrRecorder(): Mendapatkan instance perekaman dengan menentukan buffer ukuran.
  • openDvrPlayback(): Mendapatkan instance pemutaran dengan menentukan buffer ukuran.
  • openDescrambler(): Mendapatkan instance descrambler.
  • openLnb(): Memperoleh instance LNB internal.
  • openLnbByName(): Mendapatkan instance LNB eksternal.
  • openTimeFilter(): Mendapatkan instance filter waktu.

Paket Tuner menyediakan fungsi yang tidak tercakup dalam filter, DVR, dan paket frontend. Fungsi tersebut tercantum di bawah ini.

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

Android.media.tv.tuner.frontend

Paket frontend mencakup kumpulan setelan terkait frontend, informasi, status, peristiwa, dan kemampuan.

Class

FrontendSettings berasal untuk berbagai standar DTV oleh class di bawah ini.

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

Dari Android 12 dengan Tuner HAL 1.1 atau yang lebih tinggi, standar DTV berikut didukung.

  • DtmbFrontendSettings

FrontendCapabilities berasal untuk berbagai standar DTV berdasarkan class di bawah ini.

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

Dari Android 12 dengan Tuner HAL 1.1 atau yang lebih tinggi, standar DTV berikut didukung.

  • DtmbFrontendCapabilities

FrontendInfo mengambil informasi frontend. FrontendStatus mengambil status frontend saat ini. OnTuneEventListener memproses peristiwa di frontend. Aplikasi TIS menggunakan ScanCallback untuk memproses pesan pemindaian dari frontend.

Pemindaian saluran

Untuk menyiapkan TV, aplikasi memindai kemungkinan frekuensi dan membuat saluran grup channel yang dapat diakses oleh pengguna. TIS mungkin menggunakan Tuner.tune, Tuner.scan(BLIND_SCAN), atau Tuner.scan(AUTO_SCAN) untuk menyelesaikan channel pemindaian.

Jika TIS memiliki informasi pengiriman sinyal yang akurat, seperti frekuensi, standar (misalnya, T/T2, S/S2), dan informasi tambahan yang diperlukan (misalnya, PLD ID), lalu Tuner.tune direkomendasikan sebagai opsi yang lebih cepat.

Saat pengguna memanggil Tuner.tune, tindakan berikut akan terjadi:

  • TIS mengisi FrontendSettings dengan informasi yang diperlukan menggunakan Tuner.tune.
  • HAL melaporkan menyesuaikan pesan LOCKED jika sinyal terkunci.
  • TIS menggunakan Frontend.getStatus untuk mengumpulkan informasi yang diperlukan.
  • TIS berpindah ke frekuensi berikutnya yang tersedia dalam daftar frekuensi.

TIS memanggil Tuner.tune lagi hingga semua frekuensi habis.

Selama tuning, Anda bisa memanggil stopTune() atau close() untuk menjeda atau mengakhiri Panggilan Tuner.tune.

Tuner.scan(AUTO_SCAN)

Jika TIS tidak memiliki cukup informasi untuk menggunakan Tuner.tune, tetapi memiliki frekuensi dan jenis standar (misalnya, DVB T/C/S), maka Tuner.scan(AUTO_SCAN) direkomendasikan.

Saat pengguna memanggil Tuner.scan(AUTO_SCAN), tindakan berikut akan terjadi:

  • TIS menggunakan Tuner.scan(AUTO_SCAN) dengan FrontendSettings yang diisi dengan frekuensi.

  • Laporan HAL memindai pesan LOCKED jika sinyal terkunci. HAL mungkin juga melaporkan pesan pemindaian lainnya untuk memberikan informasi tambahan tentang sinyal.

  • TIS menggunakan Frontend.getStatus untuk mengumpulkan informasi yang diperlukan.

  • TIS memanggil Tuner.scan untuk HAL guna melanjutkan ke setelan berikutnya di frekuensi. Jika struktur FrontendSettings kosong, HAL menggunakan setelan yang tersedia. Jika tidak, HAL akan menggunakan FrontendSettings untuk satu kali memindai dan mengirim END untuk menunjukkan bahwa operasi pemindaian selesai.

  • TIS mengulangi tindakan di atas hingga semua setelan pada frekuensi habis.

  • HAL mengirim END untuk menunjukkan bahwa operasi pemindaian selesai.

  • TIS berpindah ke frekuensi berikutnya yang tersedia dalam daftar frekuensi.

TIS memanggil Tuner.scan(AUTO_SCAN) lagi hingga semua frekuensi habis.

Selama pemindaian, Anda dapat memanggil stopScan() atau close() untuk menjeda atau mengakhiri memindai.

Tuner.scan(BLIND_SCAN)

Jika TIS tidak memiliki daftar frekuensi dan Vendor HAL dapat mencari frekuensi frontend yang ditentukan pengguna untuk mendapatkan resource frontend, Tuner.scan(BLIND_SCAN) direkomendasikan.

  • TIS menggunakan Tuner.scan(BLIND_SCAN). Frekuensi dapat ditentukan dalam FrontendSettings untuk frekuensi awal, tetapi TIS mengabaikan setelan lainnya di FrontendSettings.
  • HAL melaporkan pesan pemindaian LOCKED jika sinyal terkunci.
  • TIS menggunakan Frontend.getStatus untuk mengumpulkan informasi yang diperlukan.
  • TIS memanggil Tuner.scan lagi untuk melanjutkan pemindaian. (FrontendSettings adalah diabaikan.)
  • TIS mengulangi tindakan di atas hingga semua setelan pada frekuensi habis. HAL menambah frekuensi tanpa perlu tindakan apa pun dari TIS. HAL melaporkan PROGRESS.

TIS memanggil Tuner.scan(AUTO_SCAN) lagi hingga semua frekuensi habis. HAL melaporkan END untuk menunjukkan bahwa operasi pemindaian selesai.

Selama pemindaian, Anda dapat memanggil stopScan() atau close() untuk menjeda atau mengakhiri pemindaian.

Diagram alir proses Pemindaian TIS.

Gambar 9. Diagram alir pemindaian TIS

Android.media.tv.tuner.filter

Paket filter adalah kumpulan operasi filter bersama dengan konfigurasi, setelan, callback, dan peristiwa. Paket ini mencakup operasi di bawah ini. Lihat kode sumber Android untuk mengetahui daftar lengkap operasi.

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

Lihat kode sumber Android untuk daftar lengkapnya.

FilterConfiguration berasal dari class di bawah ini. Konfigurasinya adalah untuk jenis filter utama dan menentukan protokol mana yang digunakan filter untuk mengekstrak data.

  • AlpFilterConfiguration
  • IpFilterConfiguration
  • MmtpFilterConfiguration
  • TlvFilterConfiguration
  • TsFilterConfiguration

Setelan berasal dari class di bawah. Setelan ini ditujukan untuk filter dan menentukan jenis data yang dapat dikecualikan oleh filter.

  • SectionSettings
  • AvSettings
  • PesSettings
  • RecordSettings
  • DownloadSettings

FilterEvent berasal dari class di bawah ini untuk melaporkan peristiwa untuk berbagai berbagai jenis data.

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

Dari Android 12 dengan Tuner HAL 1.1 atau yang lebih baru, peristiwa berikut didukung.

  • IpCidChangeEvent
  • RestartEvent
  • ScramblingStatusEvent
Peristiwa dan format data dari filter
Jenis filter Tanda Peristiwa Operasi data Format data
TS.SECTION
MMTP.SECTION
IP.SECTION
TLV.SECTION
ALP.SECTION
isRaw:
true
Wajib:
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW

Direkomendasikan:
DemuxFilterStatus::LOW_WATER
DemuxFilterStatus::HIGH_WATER
Sesuai dengan acara dan jadwal internal, jalankan
Filter.read(buffer, offset, adjustedSize) satu atau lebih kali.

Data disalin dari MQ HAL ke buffer klien.
Satu paket sesi yang telah disusun diisi FMQ oleh paket lainnya paket sesi.
isRaw:
false
Wajib:
DemuxFilterEvent::DemuxFilterSectionEvent[n]
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW

Opsional:
DemuxFilterStatus::LOW_WATER
DemuxFilterStatus::HIGH_WATER

for i=0; i<n; i++
Filter.read(buffer, offset, DemuxFilterSectionEven[i].size)

Data disalin dari MQ HAL ke buffer klien.
TS.PES isRaw:
true
Wajib:
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW

Direkomendasikan:
DemuxFilterStatus::LOW_WATER
DemuxFilterStatus::HIGH_WATER
Sesuai dengan acara dan jadwal internal, jalankan
Filter.read(buffer, offset, adjustedSize) satu atau lebih kali.

Data disalin dari MQ HAL ke buffer klien.
Satu paket PES hasil rakitan diisi dengan FMQ oleh paket lain paket PES.
isRaw:
false
Wajib:
DemuxFilterEvent::DemuxFilterPesEvent[n]
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW

Opsional:
DemuxFilterStatus::LOW_WATER
DemuxFilterStatus::HIGH_WATER

for i=0; i<n; i++
Filter.read(buffer, offset, DemuxFilterPesEven[i].size)

Data disalin dari MQ HAL ke buffer klien.
MMTP.PES isRaw:
true
Wajib:
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW

Direkomendasikan:
DemuxFilterStatus::LOW_WATER
DemuxFilterStatus::HIGH_WATER
Sesuai dengan acara dan jadwal internal, jalankan
Filter.read(buffer, offset, adjustedSize) satu atau lebih kali.

Data disalin dari MQ HAL ke buffer klien.
Satu paket MFU yang dirakit diisi FMQ oleh paket lain MFU.
isRaw:
false
Wajib:
DemuxFilterEvent::DemuxFilterPesEvent[n]
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW

Opsional:
DemuxFilterStatus::LOW_WATER
DemuxFilterStatus::HIGH_WATER

for i=0; i<n; i++
Filter.read(buffer, offset, DemuxFilterPesEven[i].size)

Data disalin dari MQ HAL ke buffer klien.
TS.TS
T/A Wajib:
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW

Direkomendasikan:
DemuxFilterStatus::LOW_WATER
DemuxFilterStatus::HIGH_WATER
Sesuai dengan acara dan jadwal internal, jalankan
Filter.read(buffer, offset, adjustedSize) satu atau lebih kali.

Data disalin dari MQ HAL ke buffer klien.
Memfilter ts dengan ts header
diisi dengan FMQ.
TS.Audio
TS.Video
MMTP.Audio
MMTP.Video
isPassthrough:
true
Opsional:
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW
Klien dapat memulai MediaCodec setelah menerima DemuxFilterStatus::DATA_READY.
Klien dapat memanggil Filter.flush setelah menerima DemuxFilterStatus::DATA_OVERFLOW.
T/A
isPassthrough:
false
Wajib:
DemuxFilterEvent::DemuxFilterMediaEvent[n]
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW

Opsional:
DemuxFilterStatus::LOW_WATER
DemuxFilterStatus::HIGH_WATER
Untuk menggunakan MediaCodec:
for i=0; i<n; i++
linearblock = MediaEvent[i].getLinearBlock();
codec.startQueueLinearBlock(linearblock)
linearblock.recycle()


Untuk menggunakan Audio Langsung AudioTrack:
for i=0; i<n; i++
audioHandle = MediaEvent[i].getAudioHandle();
audiotrack.write(encapsulated(audiohandle))
Data ES atau sebagian ES dalam memori ION.
TS.PCR
IP.NTP
ALP.PTP
T/A Wajib: T/A
Opsional: T/A
T/A T/A
TS.RECORD T/A Wajib:
DemuxFilterEvent::DemuxFilterTsRecordEvent[n]
RecordStatus::DATA_READY
RecordStatus::DATA_OVERFLOW
RecordStatus::LOW_WATER
RecordStatus::HIGH_WATER

Opsional:
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW
DemuxFilterStatus::LOW_WATER
DemuxFilterStatus::HIGH_WATER
Untuk data indeks:
for i=0; i<n; i++
DemuxFilterTsRecordEvent[i];


Untuk konten yang direkam, menurut RecordStatus::* dan jadwal internal, lakukan salah satu hal berikut:
  • Lari DvrRecord.write(adustedSize) sekali atau beberapa kali ke penyimpanan.
    Data ditransfer dari MQ HAL ke penyimpanan.
  • Lari DvrRecord.write(buffer, adustedSize) sekali atau lebih untuk {i>buffer<i}.
    Data disalin dari MQ HAL ke buffer klien.
Untuk data indeks: Dibawa dalam payload peristiwa.

Untuk konten yang direkam: Streaming TS muxed diisi dengan FMQ.
TS.TEMI T/A Wajib:
DemuxFilterEvent::DemuxFilterTemiEvent[n]

Opsional:
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW
DemuxFilterStatus::LOW_WATER
DemuxFilterStatus::HIGH_WATER
for i=0; i<n; i++
DemuxFilterTemiEvent[i];
T/A
MMTP.MMTP T/A Wajib:
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW

Direkomendasikan:
DemuxFilterStatus::LOW_WATER
DemuxFilterStatus::HIGH_WATER
Sesuai dengan acara dan jadwal internal, jalankan
Filter.read(buffer, offset, adjustedSize) satu atau lebih kali.

Data disalin dari MQ HAL ke buffer klien.
Memfilter mmtp dengan mmtp header
diisi dengan FMQ.
MMTP.RECORD T/A Wajib:
DemuxFilterEvent::DemuxFilterMmtpRecordEvent[n]
RecordStatus::DATA_READY
RecordStatus::DATA_OVERFLOW
RecordStatus::LOW_WATER
RecordStatus::HIGH_WATER

Opsional:
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW
DemuxFilterStatus::LOW_WATER
DemuxFilterStatus::HIGH_WATER
Untuk data indeks: for i=0; i<n; i++
DemuxFilterMmtpRecordEvent[i];


Untuk konten yang direkam, sesuai dengan RecordStatus::* dan jadwal internal, lakukan salah satu berikut:
  • Jalankan DvrRecord.write(adjustedSize) satu kali atau lebih ke penyimpanan.
    Data ditransfer dari MQ HAL ke penyimpanan.
  • Jalankan DvrRecord.write(buffer, adjustedSize)satu atau lebih banyak kali untuk {i>buffer<i}.
    Data disalin dari MQ HAL ke buffer klien.
Untuk data indeks: Dibawa dalam payload peristiwa.

Untuk konten yang direkam: Rekaman streaming muxed terisi FMQ.

Jika sumber filter untuk perekaman adalah TLV.TLV untuk IP.IP dengan passthrough, streaming yang direkam memiliki TLV dan IP.
MMTP.DOWNLOAD T/A Wajib:
DemuxFilterEvent::DemuxFilterDownloadEvent[n]
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW

Opsional:
DemuxFilterStatus::LOW_WATER
DemuxFilterStatus::HIGH_WATER

for i=0; i<n; i++ Filter.read(buffer, offset, DemuxFilterDownloadEvent[i].size)
Data disalin dari MQ HAL ke buffer klien.
Paket download diisi dalam FMQ oleh paket download IP lain.
IP.IP_PAYLOAD T/A Wajib:
DemuxFilterEvent::DemuxFilterIpPayloadEvent[n]
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW

Opsional:
DemuxFilterStatus::LOW_WATER
DemuxFilterStatus::HIGH_WATER

for i=0; i<n; i++ Filter.read(buffer, offset, DemuxFilterIpPayloadEvent[i].size)
Data disalin dari MQ HAL ke buffer klien.
Paket {i>payload<i} IP diisikan di FMQ oleh paket {i>payload<i} IP lainnya.
IP.IP
TLV.TLV
ALP.ALP
isPassthrough:
true
Opsional:
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW
Sub-aliran protokol yang difilter memberi feed ke filter berikutnya di filter jaringan. T/A
isPassthrough:
false
Wajib:
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW

Direkomendasikan:
DemuxFilterStatus::LOW_WATER
DemuxFilterStatus::HIGH_WATER
Sesuai dengan acara dan jadwal internal, jalankan
Filter.read(buffer, offset, adjustedSize) satu atau lebih kali.

Data disalin dari MQ HAL ke buffer klien.
Sub-aliran protokol yang difilter dengan header protokol terisi FMQ.
IP.PAYLOAD_THROUGH
TLV.PAYLOAD_THROUGH
ALP.PAYLOAD_THROUGH
T/A Opsional:
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW
Payload protokol yang difilter memberi feed ke filter berikutnya di filter jaringan. T/A
Contoh alur untuk menggunakan filter guna membuat PSI/SI

Contoh alur penggunaan filter untuk membuat PSI/SI.

Gambar 10. Alur untuk membangun PSI/SI

  1. Buka filter.

    Filter filter = tuner.openFilter(
      Filter.TYPE_TS,
      Filter.SUBTYPE_SECTION,
      /* bufferSize */1000,
      executor,
      filterCallback
    );
    
  2. Konfigurasi dan mulai filter.

    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. Proses 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); }
          }
        }
    };
    
Contoh alur untuk menggunakan MediaEvent dari filter

Contoh alur untuk menggunakan MediaEvent dari filter.

Gambar 11. Alur untuk menggunakan MediaEvent dari filter

  1. Buka, konfigurasi, dan mulai filter A/V.
  2. Proses MediaEvent.
  3. Terima MediaEvent.
  4. Buat antrean blok linear ke codec.
  5. Lepaskan tuas A/V saat data telah digunakan.

Android.media.tv.tuner.dVR

DvrRecorder menyediakan metode ini untuk perekaman.

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

DvrPlayback menyediakan metode ini untuk pemutaran.

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

DvrSettings digunakan untuk mengonfigurasi DvrRecorder dan DvrPlayback. OnPlaybackStatusChangedListener dan OnRecordStatusChangedListener digunakan untuk melaporkan status instance DVR.

Contoh alur untuk memulai data

Contoh alur untuk memulai data.

Gambar 12. Alur untuk memulai catatan

  1. Buka, konfigurasi, dan mulai 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. Terima RecordEvent dan ambil informasi indeks.

    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. Lakukan inisialisasi OnRecordStatusChangedListener dan simpan data record.

      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

Tuner HAL mengikuti HIDL dan menentukan antarmuka antara perangkat keras vendor. Vendor menggunakan antarmuka untuk menerapkan Tuner HAL dan menggunakannya untuk berkomunikasi dengan implementasi Tuner HAL.

Modul

Tuner HAL 1.0

Modul Kontrol dasar Kontrol khusus modul File HAL
ITuner T/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

Tuner HAL 1.1 (diambil dari Tuner HAL 1.0)

Modul Kontrol dasar Kontrol khusus modul File HAL
ITuner T/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

Diagram alir interaksi antara modul Tuner HAL.

Gambar 13. Diagram interaksi antara modul Tuner HAL

Penautan filter

Tuner HAL mendukung sambungan filter sehingga filter dapat ditautkan ke saluran filter untuk beberapa lapisan. Filter tersebut mengikuti aturan di bawah.

  • Filter ditautkan sebagai hierarki, jalur yang ditutup tidak diizinkan.
  • Node root adalah demux.
  • Filter beroperasi secara independen.
  • Semua filter mulai mendapatkan data.
  • Tautan filter akan dibersihkan pada filter terakhir.

Blok kode di bawah ini dan Gambar 14 menggambarkan contoh pemfilteran beberapa lapisan berbeda.

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

Diagram contoh penautan filter.

Gambar 14. Diagram alir penautan filter untuk beberapa lapisan

Pengelola Resource Tuner

Sebelum Tuner Resource Manager (TRM), beralih antara dua aplikasi memerlukan perangkat keras Tuner yang sama. Framework Input TV (TIF) menggunakan "kemenangan pertama yang diperoleh" yang berarti aplikasi mana pun yang mendapatkan sumber daya lebih dulu akan mempertahankan sumber daya tersebut. Namun, mekanisme ini mungkin tidak ideal untuk beberapa kasus penggunaan yang rumit.

TRM berjalan sebagai layanan sistem untuk mengelola hardware Tuner, TVInput, dan CAS referensi untuk aplikasi. TRM menggunakan "kemenangan latar depan" mekanisme atensi, yang menghitung prioritas aplikasi berdasarkan latar depan atau latar belakang aplikasi status dan jenis kasus penggunaan Anda. TRM memberikan atau mencabut resource berdasarkan prioritas Anda. TRM memusatkan pengelolaan sumber daya ATV untuk siaran, OTT, dan DVR.

Antarmuka TRM

TRM mengekspos antarmuka AIDL di ITunerResourceManager.aidl untuk Tuner framework, MediaCas, dan TvInputHardwareManager untuk mendaftar, meminta, atau melepaskan resource.

Antarmuka untuk pengelolaan klien tercantum di bawah ini.

  • registerClientProfile(in ResourceClientProfile profile, IResourcesReclaimListener listener, out int[] clientId)
  • unregisterClientProfile(in int clientId)

Antarmuka untuk meminta dan melepaskan resource tercantum di bawah ini.

  • 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

Class klien dan permintaan tercantum di bawah ini.

  • ResourceClientProfile
  • ResourcesReclaimListener
  • TunerFrontendRequest
  • TunerDemuxRequest
  • TunerDescramblerRequest
  • CasSessionRequest
  • TunerLnbRequest

Prioritas klien

TRM menghitung prioritas klien dengan menggunakan parameter dari dan nilai prioritas dari file konfigurasi. Prioritasnya mungkin juga diperbarui oleh nilai prioritas arbitrer dari klien.

Parameter di profil klien

TRM mengambil ID proses dari mTvInputSessionId untuk menentukan apakah aplikasi adalah aplikasi latar depan atau latar belakang. Untuk membuat mTvInputSessionId, TvInputService.onCreateSession, atau TvInputService.onCreateRecordingSession menginisialisasi sesi TIS.

mUseCase menunjukkan kasus penggunaan sesi. Kasus penggunaan yang telah ditentukan sebelumnya adalah yang tercantum di bawah ini.

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
}

File konfigurasi

File konfigurasi default

File konfigurasi default di bawah memberikan nilai prioritas untuk penggunaan standar penggunaan. Pengguna dapat mengubah nilai menggunakan file konfigurasi yang disesuaikan.

Kasus penggunaan Latar depan Latar belakang
LIVE 490 400
PLAYBACK 480 300
RECORD 600 500
SCAN 450 200
BACKGROUND 180 100
File konfigurasi yang disesuaikan

Vendor dapat menyesuaikan file konfigurasi /vendor/etc/tunerResourceManagerUseCaseConfig.xml. File ini digunakan untuk menambahkan, menghapus, atau memperbarui jenis kasus penggunaan dan nilai prioritas kasus penggunaan. File yang disesuaikan dapat menggunakan platform/hardware/interfaces/tv/tuner/1.0/config/tunerResourceManagerUseCaseConfigSample.xml sebagai template.

Misalnya, kasus penggunaan vendor baru adalah VENDOR_USE_CASE__[A-Z0-9]+, [0 - 1000]. Formatnya harus mengikuti platform/hardware/interfaces/tv/tuner/1.0/config/tunerResourceManagerUseCaseConfig.xsd.

Nilai prioritas arbitrer dan nilai bagus

TRM menyediakan updateClientPriority bagi klien untuk mengupdate arbitrer prioritas nilai dan {i>bagus<i}. Nilai prioritas arbitrer menimpa nilai prioritas yang dihitung dari jenis kasus penggunaan dan ID sesi.

Nilai yang bagus menunjukkan seberapa longgar perilaku klien saat dalam berkonflik dengan klien lain. Nilai bagus mengurangi prioritas klien sebelum nilai prioritasnya dibandingkan dengan klien yang menantang.

Mekanisme klaim kembali

Diagram di bawah menunjukkan bagaimana resource diperoleh dan ditetapkan kembali saat terjadi konflik sumber daya.

Diagram proses mekanisme klaim kembali.

Gambar 15. Diagram mekanisme klaim kembali untuk konflik antara Tuner sumber daya