Framework tuner

Untuk Android 11 atau yang lebih tinggi, Anda dapat menggunakan framework Tuner Android untuk mengirimkan konten A/V. Framework ini menggunakan pipeline hardware 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 yang aman (SMP), sehingga memungkinkannya digunakan di lingkungan perlindungan konten yang sangat terbatas.

Antarmuka standar antara Tuner dan Android CAS menghasilkan integrasi yang lebih cepat 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 siaran utama.

Komponen

Untuk Android 11, tiga komponen didesain khusus 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 Layanan Pengelola Input TV (TIMS)
  • MediaCodec atau codec media
  • AudioTrack atau trek audio
  • MediaResourceManager atau pengelola resource media (MRM)

Diagram alir komponen framework Tuner.

Gambar 1. Interaksi antara komponen Android TV

Fitur

Frontend mendukung standar DTV di bawah.

  • 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)
  • MPEG media transport protocol (MMTP)
  • Internet Protocol (IP)
  • Nilai panjang jenis (TLV)
  • Protokol lapisan link (ALP) ATSC

Descrambler mendukung perlindungan konten di bawah.

  • Jalur media yang aman
  • Menghapus jalur media
  • Amankan data lokal
  • Mengamankan pemutaran lokal

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 antara framework Android dan hardware vendor.

  • Menjelaskan apa yang diharapkan framework dari vendor dan bagaimana vendor dapat melakukannya.
  • Mengekspor fungsi frontend, demux, dan descrambler ke framework melalui antarmuka IFrontend, IDemux, IDescrambler, IFilter, IDvr, dan ILnb.
  • Menyertakan fungsi untuk mengintegrasikan Tuner HAL dengan komponen framework lainnya, 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 data rekaman atau pemutaran dalam jumlah besar 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 resource yang tidak mencukupi dari aplikasi. Aturan defaultnya adalah latar depan menang.

Media CAS dan CAS HAL ditingkatkan dengan fitur di bawah.

  • 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 mengilustrasikan urutan panggilan untuk pemutaran live streaming.

Penyiapan

Urutan penyiapan diagram pemutaran siaran langsung.

Gambar 3. Siapkan urutan untuk pemutaran live streaming

Menangani A/V

Diagram penanganan A/V untuk pemutaran siaran live.

Gambar 4. Menangani A/V untuk pemutaran live streaming

Menangani konten yang diacak

Diagram penanganan konten yang diacak untuk pemutaran siaran live.

Gambar 5. Menangani konten yang diacak untuk pemutaran siaran langsung

Memproses data A/V

Diagram pemrosesan data A/V untuk pemutaran siaran live.

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 resource dan subkomponen Tuner seperti filter dan descrambler. {i>Frontend<i} dan {i>demux<i} 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 Tuner 1.0 yang kompatibel dengan versi lama.

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 melakukan inisialisasi dan memperoleh instance resource dengan menentukan setelan awal dan callback.

  • tuner(): Melakukan inisialisasi instance Tuner dengan menentukan parameter useCase dan sessionId.
  • tune(): Mendapatkan resource frontend dan melakukan penyesuaian dengan menentukan parameter FrontendSetting.
  • openFilter(): Mendapatkan instance filter dengan menentukan jenis filter.
  • openDvrRecorder(): Mendapatkan instance perekaman dengan menentukan ukuran buffer.
  • openDvrPlayback(): Mendapatkan instance pemutaran dengan menentukan ukuran buffer.
  • openDescrambler(): Mendapatkan instance descrambler.
  • openLnb(): Memperoleh instance LNB internal.
  • openLnbByName(): Memperoleh 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, informasi, status, peristiwa, dan kemampuan yang terkait dengan frontend.

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 akan memindai kemungkinan frekuensi dan membuat rangkaian saluran yang dapat diakses pengguna. TIS mungkin menggunakan Tuner.tune, Tuner.scan(BLIND_SCAN), atau Tuner.scan(AUTO_SCAN) untuk menyelesaikan pemindaian saluran.

Jika TIS memiliki informasi pengiriman yang akurat untuk sinyal, seperti frekuensi, standar (misalnya, T/T2, S/S2), dan informasi tambahan yang diperlukan (misalnya, ID PLD), maka 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 pesan LOCKED penyesuaian 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 penyesuaian, Anda dapat memanggil stopTune() atau close() untuk menjeda atau mengakhiri panggilan Tuner.tune.

Tuner.scan(AUTO_SCAN)

Jika TIS tidak memiliki informasi yang cukup untuk menggunakan Tuner.tune, tetapi memiliki daftar frekuensi dan jenis standar (misalnya, DVB T/C/S), 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.

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

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

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

  • TIS mengulangi tindakan di atas hingga semua setelan pada frekuensi tidak digunakan lagi.

  • HAL mengirimkan END untuk menunjukkan bahwa operasi pemindaian telah selesai.

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

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

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

Tuner.scan(BLIND_SCAN)

Jika TIS tidak memiliki daftar frekuensi dan Vendor HAL dapat menelusuri frekuensi frontend yang ditentukan pengguna untuk mendapatkan resource frontend, maka Tuner.scan(BLIND_SCAN) akan 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 LOCKED pemindaian jika sinyal terkunci.
  • TIS menggunakan Frontend.getStatus untuk mengumpulkan informasi yang diperlukan.
  • TIS memanggil Tuner.scan lagi untuk melanjutkan pemindaian. (FrontendSettings 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 alur proses Pemindaian TIS.

Gambar 9. Diagram alir pemindaian TIS

Android.media.tv.tuner.filter

Paket filter adalah kumpulan operasi filter beserta 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 mengetahui daftar lengkapnya.

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

  • AlpFilterConfiguration
  • IpFilterConfiguration
  • MmtpFilterConfiguration
  • TlvFilterConfiguration
  • TsFilterConfiguration

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

  • SectionSettings
  • AvSettings
  • PesSettings
  • RecordSettings
  • DownloadSettings

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

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

Dari Android 12 dengan Tuner HAL 1.1 atau yang lebih tinggi, 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 kali atau lebih.

Data disalin dari MQ HAL ke buffer klien.
Satu paket sesi yang dirakit diisi di FMQ oleh paket sesi lainnya.
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 peristiwa dan jadwal internal, jalankan
Filter.read(buffer, offset, adjustedSize) satu atau beberapa kali.

Data disalin dari MQ HAL ke buffer klien.
Satu paket PES yang dirakit diisi di FMQ oleh paket PES lain.
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 peristiwa dan jadwal internal, jalankan
Filter.read(buffer, offset, adjustedSize) satu atau beberapa kali.

Data disalin dari MQ HAL ke buffer klien.
Satu paket MFU yang dirakit diisi FMQ oleh paket MFU lain.
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 peristiwa dan jadwal internal, jalankan
Filter.read(buffer, offset, adjustedSize) satu atau beberapa kali.

Data disalin dari MQ HAL ke buffer klien.
ts yang difilter dengan header ts
diisi di 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 dari 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, sesuai dengan RecordStatus::* dan jadwal internal, lakukan salah satu tindakan berikut:
  • Jalankan DvrRecord.write(adustedSize) satu atau beberapa kali ke penyimpanan.
    Data ditransfer dari MQ HAL ke penyimpanan.
  • Jalankan DvrRecord.write(buffer, adustedSize) satu atau beberapa kali untuk melakukan buffering.
    Data disalin dari MQ HAL ke buffer klien.
Untuk data indeks: Dibawa dalam payload peristiwa.

Untuk konten yang direkam: Streaming TS yang di-mux diisi di 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 peristiwa dan jadwal internal, jalankan
Filter.read(buffer, offset, adjustedSize) satu atau beberapa kali.

Data disalin dari MQ HAL ke buffer klien.
mmtp yang difilter dengan header mmtp
diisi di 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 tindakan berikut:
  • Jalankan DvrRecord.write(adjustedSize) satu atau beberapa kali ke penyimpanan.
    Data ditransfer dari MQ HAL ke penyimpanan.
  • Jalankan DvrRecord.write(buffer, adjustedSize) satu atau beberapa kali untuk melakukan buffering.
    Data disalin dari MQ HAL ke buffer klien.
Untuk data indeks: Dibawa dalam payload peristiwa.

Untuk konten yang direkam: Rekaman beragam streaming yang diisi dengan FMQ.

Jika sumber filter untuk perekaman adalah TLV.TLV ke IP.IP dengan passthrough, streaming yang direkam memiliki header 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 di 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 payload IP diisi di FMQ oleh paket payload IP lain.
IP.IP
TLV.TLV
ALP.ALP
isPassthrough:
true
Opsional:
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW
Sub-aliran protokol yang difilter akan memberi makan filter berikutnya dalam rantai filter. 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 kali atau lebih.

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

Contoh alur untuk menggunakan filter guna membuat PSI/SI.

Gambar 10. Alur untuk membuat PSI/SI

  1. Buka filter.

    Filter filter = tuner.openFilter(
      Filter.TYPE_TS,
      Filter.SUBTYPE_SECTION,
      /* bufferSize */1000,
      executor,
      filterCallback
    );
    
  2. Konfigurasikan 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. Antrekan 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 rekaman

Contoh alur untuk memulai perekaman.

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. Menerima RecordEvent dan mengambil 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);
          }
        }
      };
    

HAL Tuner

Tuner HAL mengikuti HIDL dan menentukan antarmuka antara framework dan hardware vendor. Vendor menggunakan antarmuka untuk menerapkan Tuner HAL dan framework menggunakannya untuk berkomunikasi dengan penerapan 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 (berasal 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 alur interaksi antar-modul Tuner HAL.

Gambar 13. Diagram interaksi antar-modul HAL Tuner

Penautan filter

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

  • Filter ditautkan sebagai hierarki, jalur tutup 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 dan Gambar 14 mengilustrasikan contoh pemfilteran beberapa lapisan.

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 alur penautan filter untuk beberapa lapisan

Pengelola Resource Tuner

Sebelum Tuner Resource Manager (TRM), beralih antar-aplikasi memerlukan hardware Tuner yang sama. Framework Input TV (TIF) menggunakan mekanisme "kemenangan pertama yang diperoleh", yang berarti aplikasi mana pun yang mendapatkan resource lebih dulu akan mempertahankan resource. Namun, mekanisme ini mungkin tidak ideal untuk beberapa kasus penggunaan yang rumit.

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

Antarmuka TRM

TRM mengekspos antarmuka AIDL di ITunerResourceManager.aidl untuk framework Tuner, MediaCas, dan TvInputHardwareManager guna mendaftarkan, meminta, atau merilis resource.

Antarmuka untuk pengelolaan klien tercantum di bawah.

  • 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 menggunakan parameter dari profil klien dan nilai prioritas dari file konfigurasi. Prioritas tersebut juga dapat diperbarui oleh nilai prioritas arbitrer dari klien.

Parameter di profil klien

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

mUseCase menunjukkan kasus penggunaan sesi. Kasus penggunaan yang telah ditentukan 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 kasus penggunaan yang telah ditentukan. 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 nilai prioritas arbitrer dan nilai yang menarik. Nilai prioritas arbitrer menimpa nilai prioritas yang dihitung dari jenis kasus penggunaan dan ID sesi.

Nilai yang bagus menunjukkan seberapa longgar perilaku klien saat mengalami konflik dengan klien lain. Nilai bagus akan menurunkan nilai prioritas klien sebelum nilai prioritasnya dibandingkan dengan klien yang menantang.

Mekanisme klaim kembali

Diagram di bawah menunjukkan cara resource diambil kembali dan ditetapkan saat terjadi konflik resource.

Diagram proses mekanisme klaim kembali.

Gambar 15. Diagram mekanisme pengambil alihan untuk konflik antara resource Tuner