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 menyediakan cara aman untuk mengirimkan konten A/V yang dilindungi oleh trusted execution environment (TEE) dan secure media path (SMP), sehingga memungkinkannya digunakan di lingkungan perlindungan konten yang sangat dibatasi.

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 dirancang khusus untuk platform TV.

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

Untuk Android 11, komponen berikut telah ditingkatkan.

  • CAS V2
  • TvInputService atau Layanan Input TV (TIS)
  • TvInputManagerService atau Layanan Pengelola Input TV (TIMS)
  • MediaCodec atau codec media
  • AudioTrack atau trek audio
  • MediaResourceManager atau pengelola resource media (MRM)

Diagram alur komponen framework Tuner.

Gambar 1. Interaksi antarkomponen 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.

  • Transport stream (TS)
  • MPEG media transport protocol (MMTP)
  • Internet Protocol (IP)
  • Nilai panjang jenis (TLV)
  • Protokol lapisan link ATSC (ALP)

Descrambler mendukung perlindungan konten di bawah.

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

Tuner API mendukung kasus penggunaan di bawah.

  • 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 Tuner Native adalah jembatan antara class Java Tuner 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 memadai 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.
  • Mengintegrasikan dengan Tuner HAL dengan menyediakan token kunci.

MediaCodec dan AudioTrack ditingkatkan dengan fitur di bawah.

  • Menggunakan memori A/V aman sebagai input konten.
  • Dikonfigurasi untuk melakukan sinkronisasi A/V hardware dalam pemutaran yang di-tunnel.
  • Mendukung konfigurasi 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. Menyiapkan urutan untuk pemutaran siaran live

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. 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 Tuner 1.0 yang kompatibel dengan versi sebelumnya.

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 baru.

Paket

Tuner SDK API menyediakan empat paket di bawah.

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

Diagram alur 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(): Memperoleh resource frontend dan menyesuaikan 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 buffering.
  • openDescrambler(): Memperoleh 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 paket filter, DVR, dan frontend. Fungsinya 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 terkait frontend.

Class

FrontendSettings berasal dari berbagai standar DTV oleh class di bawah.

  • 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 dari berbagai standar DTV oleh class di bawah.

  • 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 frekuensinya.

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 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 agar HAL melanjutkan ke setelan berikutnya pada frekuensi yang sama. Jika struktur FrontendSettings kosong, HAL akan menggunakan setelan berikut 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 habis.

  • 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 menghentikan pemindaian.

Tuner.scan(BLIND_SCAN)

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

  • TIS menggunakan Tuner.scan(BLIND_SCAN). Frekuensi dapat ditentukan di FrontendSettings untuk frekuensi awal, tetapi TIS mengabaikan setelan lain 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 menambahkan frekuensi tanpa perlu tindakan dari TIS. HAL melaporkan PROGRESS.

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

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

Diagram alur proses Pemindaian TIS.

Gambar 9. Diagram alur 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. 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 peristiwa dan jadwal internal, jalankan
Filter.read(buffer, offset, adjustedSize) satu atau beberapa kali.

Data disalin dari MQ HAL ke buffer klien.
Satu paket sesi yang telah dirakit diisi di FMQ oleh paket sesi lain.
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 di 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 AudioTrack:
for i=0; i<n; i++
audioHandle = MediaEvent[i].getAudioHandle();
audiotrack.write(encapsulated(audiohandle))
Data ES atau ES parsial 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: Streaming yang direkam dan di-mux diisi di FMQ.

Jika sumber filter untuk perekaman adalah TLV.TLV hingga 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 peristiwa dan jadwal internal, jalankan
Filter.read(buffer, offset, adjustedSize) satu atau beberapa kali.

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. Memproses 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. Memproses MediaEvent.
  3. Menerima MediaEvent.
  4. Antrekan blok linear ke codec.
  5. Lepaskan handle 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 perekaman

  1. Buka, konfigurasikan, 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 data.

      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 antara modul HAL Tuner

Penautan filter

Tuner HAL mendukung penautan filter sehingga filter dapat ditautkan ke filter lain untuk beberapa lapisan. Filter 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.
  • Penautan filter dihapus 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

Tuner Resource Manager

Sebelum Tuner Resource Manager (TRM), beralih antar-aplikasi memerlukan hardware Tuner yang sama. TV Input Framework (TIF) menggunakan mekanisme "menang pertama kali diperoleh", yang berarti aplikasi mana pun yang mendapatkan resource terlebih dahulu akan menyimpan resource tersebut. 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 "foreground win", 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 merilis resource tercantum di bawah.

  • 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.

  • 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 juga dapat diperbarui oleh nilai prioritas arbitrer dari klien.

Parameter di profil klien

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

mUseCase menunjukkan kasus penggunaan sesi. Kasus penggunaan standar tercantum di bawah.

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 memperbarui nilai prioritas arbitrer dan nilai nice. Nilai prioritas arbitrer menimpa nilai prioritas yang dihitung dari jenis kasus penggunaan dan ID sesi.

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

Mekanisme pemulihan

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

Diagram proses mekanisme pengklaiman kembali.

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