Google berkomitmen untuk mendorong terwujudnya keadilan ras bagi komunitas Kulit Hitam. Lihat caranya.

Kerangka Tuner

Untuk Android 11 atau lebih tinggi, Anda dapat menggunakan framework Android Tuner untuk mengirimkan konten A / V. Framework ini menggunakan pipeline hardware dari vendor, sehingga cocok untuk SoC low-end dan high-end. Kerangka kerja ini menyediakan cara yang aman untuk mengirimkan konten A / V yang dilindungi oleh lingkungan eksekusi tepercaya (TEE) dan jalur media yang aman (SMP), memungkinkannya digunakan dalam 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 bekerja dengan MediaCodec dan AudioTrack untuk membangun 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 kerangka kerja dan vendor
  • Tuner SDK API: Antarmuka antara framework dan aplikasi
  • Tuner Resource Manager (TRM): Mengkoordinasikan sumber daya Tuner HW

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 pengelola sumber daya media (MRM)

Diagram alir komponen kerangka 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

Demux mendukung protokol aliran di bawah ini.

  • Arus transportasi (TS)
  • MPEG media transport protocol (MMTP)
  • Protokol Internet (IP)
  • Jenis nilai panjang (TLV)
  • ATSC link-layer protocol (ALP)

Descrambler mendukung perlindungan konten di bawah.

  • Jalur media yang aman
  • Hapus jalur media
  • Amankan catatan lokal
  • Mengamankan pemutaran lokal

Tuner API mendukung kasus penggunaan di bawah ini.

  • Pindai
  • Hidup
  • Putar ulang
  • Merekam

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

  • Muatan ES dengan buffer memori yang jelas
  • Muatan ES dengan pegangan memori aman
  • Melewati

Desain keseluruhan

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

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

Kelas Tuner Java dan kelas asli dibuat.

  • Tuner Java API memungkinkan aplikasi mengakses Tuner HAL melalui API publik.
  • Kelas asli memungkinkan kontrol izin dan penanganan data perekaman atau pemutaran dalam jumlah besar dengan Tuner HAL.
  • Modul Native Tuner adalah jembatan antara kelas Tuner Java dan Tuner HAL.

Kelas TRM dibuat.

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

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

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

MediaCodec dan AudioTrack ditingkatkan dengan fitur-fitur di bawah ini.

  • Mengambil memori A / V yang aman sebagai input konten.
  • Dikonfigurasi untuk melakukan sinkronisasi A / V perangkat keras dalam pemutaran terowongan.
  • Dukungan yang dikonfigurasi untuk ES_payload dan mode passthrough.

Desain keseluruhan dari Tuner HAL.

Gambar 2. Diagram komponen dalam Tuner HAL

Alur kerja keseluruhan

Diagram di bawah mengilustrasikan urutan panggilan untuk pemutaran siaran langsung.

Mendirikan

Urutan pengaturan diagram pemutaran siaran langsung.

Gambar 3. Urutan pengaturan untuk pemutaran siaran langsung

Menangani A / V

Menangani A / V untuk diagram pemutaran siaran langsung.

Gambar 4. Menangani A / V untuk pemutaran siaran langsung

Menangani konten yang diacak

Menangani konten acak untuk diagram pemutaran siaran langsung.

Gambar 5. Menangani konten yang diacak untuk pemutaran siaran langsung

Memproses data A / V

Memproses data A / V untuk diagram pemutaran siaran langsung.

Gambar 6. Memproses A / V untuk pemutaran siaran langsung

API SDK Tuner

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

Diagram alir dari Tuner SDK API.

Gambar 7. Interaksi dengan Tuner SDK API

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 masuk untuk menggunakan framework Tuner. Aplikasi TIS menggunakan paket untuk menginisialisasi dan memperoleh instance sumber daya dengan menentukan pengaturan awal dan callback.

  • tuner() : menginisialisasi Tuner misalnya dengan menentukan useCase dan sessionId parameter.
  • tune() : Memperoleh resource frontend dan tune dengan menentukan parameter FrontendSetting .
  • openFilter() : openFilter() contoh filter dengan menentukan jenis filter.
  • openDvrRecorder() : openDvrRecorder() instance perekaman dengan menentukan ukuran buffer.
  • openDvrPlayback() : openDvrPlayback() instance pemutaran dengan menentukan ukuran buffer.
  • openDescrambler() : openDescrambler() instance descrambler.
  • openLnb() : openLnb() instans LNB internal.
  • openLnbByName() : openLnbByName() instans LNB eksternal.
  • openTimeFilter() : openTimeFilter() contoh filter waktu.

Paket Tuner menyediakan fungsionalitas yang tidak tercakup dalam filter, DVR, dan paket 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 pengaturan, informasi, status, acara, dan kemampuan terkait frontend.

Kelas

FrontendSettings diturunkan untuk standar DTV yang berbeda menurut kelas di bawah ini.

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

FrontendCapabilities diturunkan untuk standar DTV yang berbeda dengan kelas di bawah ini.

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

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

Pemindaian saluran

Untuk menyiapkan TV, aplikasi memindai frekuensi yang mungkin dan membuat daftar saluran untuk 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 sinyal yang akurat, seperti frekuensi, standar (misalnya, T / T2, S / S2), dan informasi tambahan yang diperlukan (misalnya, PLD ID), maka Tuner.tune direkomendasikan sebagai opsi yang lebih cepat .

Saat pengguna memanggil Tuner.tune , tindakan berikut terjadi:

  • TIS mengisi FrontendSettings dengan informasi yang diperlukan menggunakan Tuner.tune .
  • HAL melaporkan pesan LOCKED 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 sampai semua frekuensi habis.

Selama penyetelan, Anda dapat 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 daftar frekuensi dan tipe standar (misalnya, DVB T / C / S), maka Tuner.scan(AUTO_SCAN) direkomendasikan.

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

  • TIS menggunakan Tuner.scan(AUTO_SCAN) dengan FrontendSettings 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 agar HAL melanjutkan ke pengaturan berikutnya pada frekuensi yang sama. Jika struktur FrontendSettings kosong, HAL menggunakan pengaturan berikutnya yang tersedia. Jika tidak, HAL menggunakan FrontendSettings untuk pemindaian satu kali dan mengirim END untuk menunjukkan bahwa operasi pemindaian telah selesai.

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

  • HAL mengirim 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 sampai 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 mencari frekuensi frontend yang ditentukan pengguna untuk mendapatkan sumber daya frontend, maka Tuner.scan(BLIND_SCAN) direkomendasikan.

  • TIS menggunakan Tuner.scan(BLIND_SCAN) . Frekuensi dapat ditentukan di FrontendSettings untuk frekuensi mulai, tetapi TIS mengabaikan pengaturan lain di FrontendSettings .
  • HAL melaporkan pesan scan LOCKED 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 pengaturan pada frekuensi habis. HAL meningkatkan frekuensi tanpa perlu tindakan dari TIS. HAL melaporkan PROGRESS .

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

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

Diagram alir proses TIS Scan.

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 tersebut mencakup operasi di bawah ini. Lihat kode sumber Android untuk daftar lengkap operasi.

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

Lihat kode sumber Android untuk daftar lengkapnya.

FilterConfiguration diturunkan dari kelas-kelas di bawah ini. Konfigurasi tersebut untuk jenis filter utama dan menentukan protokol mana yang digunakan filter untuk mengekstrak data.

  • AlpFilterConfiguration
  • IpFilterConfiguration
  • MmtpFilterConfiguration
  • TlvFilterConfiguration
  • TsFilterConfiguration

Pengaturan diturunkan dari kelas-kelas di bawah ini. Pengaturannya adalah untuk subtipe filter dan menentukan jenis data apa yang dapat dikecualikan oleh filter.

  • SectionSettings
  • AvSettings
  • PesSettings
  • RecordSettings
  • DownloadSettings

FilterEvent berasal dari kelas di bawah ini untuk melaporkan kejadian untuk berbagai jenis data.

  • SectionEvent
  • MediaEvent
  • PesEvent
  • TsRecordEvent
  • MmtpRecordEvent
  • TemiEvent
  • DownloadEvent
  • IpPayloadEvent
Acara dan format data dari filter
Jenis filter Bendera Acara 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 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 telah dirakit diisi dengan FMQ oleh paket sesi lainnya.
isRaw:
false
Wajib:
DemuxFilterEvent::DemuxFilterSectionEvent[n]
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW

Pilihan:
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 acara dan jadwal internal, jalankan
Filter.read(buffer, offset, adjustedSize) satu kali atau lebih.

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

Pilihan:
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 acara dan jadwal internal, jalankan
Filter.read(buffer, offset, adjustedSize) satu kali atau lebih.

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

Pilihan:
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 acara dan jadwal internal, jalankan
Filter.read(buffer, offset, adjustedSize) satu kali atau lebih.

Data disalin dari MQ HAL ke buffer klien.
Disaring ts dengan ts sundulan
diisi FMQ.
TS.Audio
TS.Video
MMTP.Audio
MMTP.Video
isPassthrough:
true
Pilihan:
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

Pilihan:
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))
ES atau sebagian ES data dalam memori ION.
TS.PCR
IP.NTP
ALP.PTP
T / A Wajib: N / A
Opsional: N / 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

Pilihan:
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:
  • Jalankan DvrRecord.write(adustedSize) satu kali atau lebih ke penyimpanan.
    Data ditransfer dari MQ HAL ke penyimpanan.
  • Jalankan DvrRecord.write(buffer, adustedSize) satu atau beberapa kali ke buffer.
    Data disalin dari MQ HAL ke buffer klien.
Untuk data indeks: Dilakukan saat payload acara.

Untuk konten yang direkam: Aliran TS gabungan yang diisi dalam FMQ.
TS.TEMI T / A Wajib:
DemuxFilterEvent::DemuxFilterTemiEvent[n]

Pilihan:
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 acara dan jadwal internal, jalankan
Filter.read(buffer, offset, adjustedSize) satu kali atau lebih.

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

Pilihan:
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 , menurut RecordStatus::* dan jadwal internal, lakukan salah satu hal berikut:
  • Jalankan DvrRecord.write(adjustedSize) satu kali atau lebih ke penyimpanan.
    Data ditransfer dari MQ HAL ke penyimpanan.
  • Jalankan DvrRecord.write(buffer, adjustedSize) satu kali atau lebih ke buffer.
    Data disalin dari MQ HAL ke buffer klien.
Untuk data indeks: Dilakukan saat payload acara.

Untuk konten rekaman: Aliran rekaman gabungan yang diisi dalam FMQ.

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

Pilihan:
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 unduhan diisi FMQ oleh paket unduhan IP lain.
IP.IP_PAYLOAD T / A Wajib:
DemuxFilterEvent::DemuxFilterIpPayloadEvent[n]
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW

Pilihan:
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 muatan IP diisi di FMQ oleh paket muatan IP lain.
IP.IP
TLV.TLV
ALP.ALP
isPassthrough:
true
Pilihan:
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW
Sub-aliran protokol yang disaring 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 acara dan jadwal internal, jalankan
Filter.read(buffer, offset, adjustedSize) satu kali atau lebih.

Data disalin dari MQ HAL ke buffer klien.
Sub stream protokol yang disaring dengan header protokol diisi dengan FMQ.
IP.PAYLOAD_THROUGH
TLV.PAYLOAD_THROUGH
ALP.PAYLOAD_THROUGH
T / A Pilihan:
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW
Muatan protokol yang disaring memberi makan filter berikutnya dalam rantai filter. T / A
Contoh aliran untuk menggunakan filter untuk membangun PSI / SI

Contoh aliran untuk menggunakan filter untuk membangun 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. Process 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 aliran untuk menggunakan MediaEvent dari filter

Contoh aliran untuk menggunakan MediaEvent dari filter.

Gambar 11. Alur untuk menggunakan MediaEvent dari filter

  1. Buka, konfigurasikan, dan mulai filter A / V.
  2. Proses MediaEvent .
  3. Terima MediaEvent .
  4. Antrean blok linier ke codec .
  5. Lepaskan pegangan A / V saat data telah dikonsumsi.

Android.media.tv.tuner.dvr

DvrRecorder menyediakan metode ini untuk merekam.

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

DvrPlayback menyediakan metode ini untuk pemutaran.

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

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

Contoh aliran untuk memulai rekaman

Contoh aliran untuk memulai rekaman.

Gambar 12. Alur untuk memulai rekaman

  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. 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. 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 mendefinisikan antarmuka antara kerangka kerja dan perangkat keras vendor. Vendor menggunakan antarmuka untuk mengimplementasikan Tuner HAL dan kerangka kerja menggunakannya untuk berkomunikasi dengan implementasi Tuner HAL.

Modul

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

Diagram alir interaksi antar modul Tuner HAL.

Gambar 13. Diagram interaksi antara modul Tuner HAL

Keterkaitan filter

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

  • Filter ditautkan sebagai pohon, jalur tertutup tidak diperbolehkan.
  • Node root adalah demux.
  • Filter beroperasi secara independen.
  • Semua filter mulai mendapatkan data.
  • Keterkaitan filter mengalir pada filter terakhir.

Blok kode di bawah ini 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 keterkaitan filter.

Gambar 14. Diagram alir linkage filter untuk beberapa lapisan

Manajer Sumber Daya Tuner

Sebelum Tuner Resource Manager (TRM), beralih di antara dua aplikasi memerlukan perangkat keras Tuner yang sama. TV Input Framework (TIF) menggunakan mekanisme "menang pertama yang mendapatkan", yang berarti aplikasi mana pun yang mendapatkan sumber daya terlebih dahulu menyimpan sumber daya. Namun, mekanisme ini mungkin tidak ideal untuk beberapa kasus penggunaan yang rumit.

TRM berjalan sebagai layanan sistem untuk mengelola sumber daya perangkat keras 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 sumber daya berdasarkan prioritas. TRM memusatkan manajemen sumber daya ATV untuk siaran, OTT, dan DVR.

Antarmuka TRM

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

Antarmuka untuk manajemen klien tercantum di bawah ini.

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

Antarmuka untuk meminta dan merilis sumber daya 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

Kelas klien dan permintaan tercantum di bawah ini.

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

Prioritas klien

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

Parameter di profil klien

TRM mengambil ID proses dari mTvInputSessionId untuk memutuskan apakah suatu 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 dicantumkan 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 sebelumnya. 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 menambah, 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 sewenang-wenang dan nilai bagus

TRM menyediakan updateClientPriority bagi klien untuk memperbarui nilai prioritas arbitrer dan nilai bagus. Nilai prioritas arbitrer menimpa nilai prioritas yang dihitung dari jenis kasus penggunaan dan ID sesi.

Nilai bagus menunjukkan seberapa lunak perilaku klien ketika bertentangan dengan klien lain. Nilai bagus menurunkan nilai prioritas klien sebelum nilai prioritasnya dibandingkan dengan klien yang menantang.

Mekanisme klaim kembali

Diagram di bawah menunjukkan bagaimana sumber daya diklaim ulang dan ditetapkan ketika terjadi konflik sumber daya.

Diagram proses mekanisme reklamasi.

Gambar 15. Diagram mekanisme reklamasi untuk konflik antara sumber daya Tuner