Untuk Android 11 atau lebih tinggi, Anda dapat menggunakan framework Android Tuner untuk mengirimkan konten A/V. Kerangka kerja ini menggunakan alur perangkat keras dari vendor, sehingga cocok untuk SoC kelas bawah dan kelas atas. Kerangka kerja ini menyediakan cara yang aman untuk mengirimkan konten A/V yang dilindungi oleh lingkungan eksekusi tepercaya (TEE) dan jalur media aman (SMP), sehingga 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 kerangka kerja dan aplikasi
- Tuner Resource Manager (TRM): Mengkoordinasikan sumber daya Tuner HW
Untuk Android 11, komponen berikut telah ditingkatkan.
- CAS V2
-
TvInputService
atau Layanan Input TV (TIS) -
TvInputManagerService
atau Layanan Manajer Input TV (TIMS) -
MediaCodec
atau kodek media -
AudioTrack
atau trek audio -
MediaResourceManager
atau manajer sumber daya media (MRM)
Gambar 1. Interaksi antar komponen Android TV
Fitur
Frontend mendukung standar DTV di bawah ini.
- ATSC
- ATSC3
- DVB C/S/T
- ISDB S/S3/T
- Analog
Frontend di Android 12 dengan Tuner HAL 1.1 atau lebih tinggi mendukung standar DTV di bawah.
- DTMB
Demux mendukung protokol streaming di bawah ini.
- Arus transportasi (TS)
- Protokol transportasi media MPEG (MMTP)
- Protokol Internet (IP)
- Ketik nilai panjang (TLV)
- Protokol lapisan tautan ATSC (ALP)
Descrambler mendukung perlindungan konten di bawah ini.
- Jalur media yang aman
- Hapus jalur media
- Amankan catatan lokal
- Amankan pemutaran lokal
Tuner API mendukung kasus penggunaan di bawah ini.
- Pindai
- Hidup
- Pemutaran
- Catatan
Tuner, MediaCodec
, dan AudioTrack
mendukung mode aliran data di bawah ini.
- Payload ES dengan buffer memori yang jelas
- Payload ES dengan pegangan memori yang aman
- Melewati
Desain keseluruhan
Tuner HAL ditentukan antara kerangka Android dan perangkat keras vendor.
- Menjelaskan apa yang diharapkan kerangka kerja dari vendor dan bagaimana vendor dapat melakukannya.
- Mengekspor fungsionalitas frontend, demux, dan descrambler ke kerangka kerja melalui antarmuka
IFrontend
,IDemux
,IDescrambler
,IFilter
,IDvr
, danILnb
. - Termasuk fungsi untuk mengintegrasikan Tuner HAL dengan komponen kerangka kerja lainnya, seperti
MediaCodec
danAudioTrack
.
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 yang terbatas, seperti Frontend, LNB, sesi CAS, dan perangkat input TV dari input TV HAL.
- Menerapkan aturan untuk mendapatkan kembali sumber daya yang tidak mencukupi dari aplikasi. Aturan defaultnya adalah kemenangan latar depan.
Media CAS dan CAS HAL ditingkatkan dengan fitur di bawah ini.
- Membuka sesi CAS untuk penggunaan dan algoritma yang berbeda.
- Mendukung sistem CAS dinamis, seperti pelepasan dan penyisipan CICAM.
- Terintegrasi dengan Tuner HAL dengan menyediakan token kunci.
MediaCodec
dan AudioTrack
ditingkatkan dengan 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.
Gambar 2. Diagram komponen-komponen dalam Tuner HAL
Alur kerja keseluruhan
Diagram di bawah mengilustrasikan urutan panggilan untuk pemutaran siaran langsung.
Mempersiapkan
Gambar 3. Urutan pengaturan untuk pemutaran siaran langsung
Menangani A/V
Gambar 4. Menangani A/V untuk pemutaran siaran langsung
Menangani konten yang diacak
Gambar 5. Menangani konten yang diacak untuk pemutaran siaran langsung
Memproses data A/V
Gambar 6. Memproses A/V untuk pemutaran siaran langsung
API SDK Penyetel
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.
Gambar 7. Interaksi dengan Tuner SDK API
Versi
Mulai Android 12, Tuner SDK API mendukung fitur baru di Tuner HAL 1.1, yang merupakan 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 di dokumentasi API Android 12 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
Gambar 8. Paket Tuner SDK API
Android.media.tv.tuner
Paket Tuner adalah titik masuk untuk menggunakan kerangka Tuner. Aplikasi TIS menggunakan paket untuk menginisialisasi dan memperoleh instans sumber daya dengan menentukan pengaturan awal dan panggilan balik.
-
tuner()
: Menginisialisasi instance Tuner dengan menentukan parameteruseCase
dansessionId
. -
tune()
: Mengakuisisi sumber daya frontend dan menyetelnya dengan menentukan parameterFrontendSetting
. -
openFilter()
: Mengakuisisi instance filter dengan menentukan tipe filter. -
openDvrRecorder()
: Mengakuisisi instance rekaman dengan menentukan ukuran buffer. -
openDvrPlayback()
: Mengakuisisi instance pemutaran dengan menentukan ukuran buffer. -
openDescrambler()
: Mengakuisisi instance descrambler. -
openLnb()
: Mengakuisisi instance LNB internal. -
openLnbByName()
: Mengakuisisi instance LNB eksternal. -
openTimeFilter()
: Mengakuisisi instance filter waktu.
Paket Tuner menyediakan fungsionalitas 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 pengaturan, informasi, status, peristiwa, dan kemampuan terkait frontend.
Kelas
FrontendSettings
diturunkan untuk standar DTV yang berbeda berdasarkan kelas di bawah.
-
AnalogFrontendSettings
-
Atsc3FrontendSettings
-
AtscFrontendSettings
-
DvbcFrontendSettings
-
DvbsFrontendSettings
-
DvbtFrontendSettings
-
Isdbs3FrontendSettings
-
IsdbsFrontendSettings
-
IsdbtFrontendSettings
Mulai Android 12 dengan Tuner HAL 1.1 atau lebih tinggi, standar DTV berikut didukung.
-
DtmbFrontendSettings
FrontendCapabilities
diturunkan untuk standar DTV yang berbeda berdasarkan kelas di bawah.
-
AnalogFrontendCapabilities
-
Atsc3FrontendCapabilities
-
AtscFrontendCapabilities
-
DvbcFrontendCapabilities
-
DvbsFrontendCapabilities
-
DvbtFrontendCapabilities
-
Isdbs3FrontendCapabilities
-
IsdbsFrontendCapabilities
-
IsdbtFrontendCapabilities
Mulai Android 12 dengan Tuner HAL 1.1 atau lebih tinggi, standar DTV berikut didukung.
-
DtmbFrontendCapabilities
FrontendInfo
mengambil informasi frontend. FrontendStatus
mengambil status frontend saat ini. OnTuneEventListener
mendengarkan acara di frontend. Aplikasi TIS menggunakan ScanCallback
untuk memproses pesan pindaian dari frontend.
Pemindaian saluran
Untuk menyiapkan TV, aplikasi memindai kemungkinan frekuensi 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, ID PLD), maka Tuner.tune
direkomendasikan sebagai opsi yang lebih cepat .
Saat pengguna memanggil Tuner.tune
, tindakan berikut terjadi:
- TIS mengisi
FrontendSettings
dengan informasi yang diperlukan menggunakanTuner.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 hingga 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
, namun 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)
denganFrontendSettings
diisi dengan frekuensi.Laporan HAL memindai pesan
LOCKED
jika sinyal terkunci. HAL mungkin juga melaporkan pesan pemindaian lainnya untuk memberikan informasi tambahan tentang sinyal tersebut.TIS menggunakan
Frontend.getStatus
untuk mengumpulkan informasi yang diperlukan.TIS memanggil
Tuner.scan
agar HAL melanjutkan ke pengaturan berikutnya pada frekuensi yang sama. Jika strukturFrontendSettings
kosong, HAL menggunakan pengaturan berikutnya yang tersedia. Jika tidak, HAL menggunakanFrontendSettings
untuk pemindaian satu kali dan mengirimkanEND
untuk menunjukkan bahwa operasi pemindaian telah selesai.TIS mengulangi tindakan di atas hingga semua pengaturan 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 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 diFrontendSettings
untuk frekuensi awal, namun TIS mengabaikan pengaturan lain diFrontendSettings
. - HAL melaporkan pesan pindaian
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 menambah frekuensi tanpa perlu tindakan apa pun dari TIS. HAL melaporkan
PROGRESS
.
TIS memanggil Tuner.scan(AUTO_SCAN)
lagi hingga 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.
Gambar 9. Diagram alur pemindaian TIS
Android.media.tv.tuner.filter
Paket filter adalah kumpulan operasi filter beserta konfigurasi, pengaturan, callback, dan peristiwa. Paket ini 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
berasal dari kelas di bawah ini. Konfigurasinya ditujukan untuk jenis filter utama dan menentukan protokol mana yang digunakan filter untuk mengekstrak data.
-
AlpFilterConfiguration
-
IpFilterConfiguration
-
MmtpFilterConfiguration
-
TlvFilterConfiguration
-
TsFilterConfiguration
Pengaturannya berasal dari kelas di bawah ini. Setelannya ditujukan 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 peristiwa untuk berbagai jenis data.
-
SectionEvent
-
MediaEvent
-
PesEvent
-
TsRecordEvent
-
MmtpRecordEvent
-
TemiEvent
-
DownloadEvent
-
IpPayloadEvent
Mulai Android 12 dengan Tuner HAL 1.1 atau lebih tinggi, event berikut didukung.
-
IpCidChangeEvent
-
RestartEvent
-
ScramblingStatusEvent
Acara dan format data dari filter
Jenis penyaring | Bendera | Acara | Operasi data | Format data |
---|---|---|---|---|
TS.SECTION MMTP.SECTION IP.SECTION TLV.SECTION ALP.SECTION | isRaw: | Wajib:DemuxFilterStatus::DATA_READY DemuxFilterStatus::DATA_OVERFLOW Direkomendasikan: DemuxFilterStatus::LOW_WATER DemuxFilterStatus::HIGH_WATER | Sesuai dengan acara dan jadwal internal, jalankanFilter.read(buffer, offset, adjustedSize) satu kali atau lebih.Data disalin dari MQ HAL ke buffer klien. | Satu paket sesi rakitan diisi FMQ dengan paket sesi lainnya. |
isRaw: | Wajib:DemuxFilterEvent::DemuxFilterSectionEvent[n] DemuxFilterStatus::DATA_READY DemuxFilterStatus::DATA_OVERFLOW Opsional: DemuxFilterStatus::LOW_WATER DemuxFilterStatus::HIGH_WATER | for i=0; i<n; i++ Data disalin dari MQ HAL ke buffer klien. | ||
TS.PES | isRaw: | Wajib:DemuxFilterStatus::DATA_READY DemuxFilterStatus::DATA_OVERFLOW Direkomendasikan: DemuxFilterStatus::LOW_WATER DemuxFilterStatus::HIGH_WATER | Sesuai dengan acara dan jadwal internal, jalankanFilter.read(buffer, offset, adjustedSize) satu kali atau lebih.Data disalin dari MQ HAL ke buffer klien. | Satu paket PES rakitan diisi FMQ oleh paket PES lainnya. |
isRaw: | Wajib:DemuxFilterEvent::DemuxFilterPesEvent[n] DemuxFilterStatus::DATA_READY DemuxFilterStatus::DATA_OVERFLOW Opsional: DemuxFilterStatus::LOW_WATER DemuxFilterStatus::HIGH_WATER | for i=0; i<n; i++ Data disalin dari MQ HAL ke buffer klien. | ||
MMTP.PES | isRaw: | Wajib:DemuxFilterStatus::DATA_READY DemuxFilterStatus::DATA_OVERFLOW Direkomendasikan: DemuxFilterStatus::LOW_WATER DemuxFilterStatus::HIGH_WATER | Sesuai dengan acara dan jadwal internal, jalankanFilter.read(buffer, offset, adjustedSize) satu kali atau lebih.Data disalin dari MQ HAL ke buffer klien. | Satu paket MFU rakitan diisi FMQ dengan paket MFU lainnya. |
isRaw: | Wajib:DemuxFilterEvent::DemuxFilterPesEvent[n] DemuxFilterStatus::DATA_READY DemuxFilterStatus::DATA_OVERFLOW Opsional: DemuxFilterStatus::LOW_WATER DemuxFilterStatus::HIGH_WATER | for i=0; i<n; i++ Data disalin dari MQ HAL ke buffer klien. | ||
TS.TS | T/A | Wajib:DemuxFilterStatus::DATA_READY DemuxFilterStatus::DATA_OVERFLOW Direkomendasikan: DemuxFilterStatus::LOW_WATER DemuxFilterStatus::HIGH_WATER | Sesuai dengan acara dan jadwal internal, jalankanFilter.read(buffer, offset, adjustedSize) satu kali atau lebih.Data disalin dari MQ HAL ke buffer klien. | Memfilter ts dengan header ts diisi FMQ. |
TS.Audio TS.Video MMTP.Audio MMTP.Video | isPassthrough: | 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: | 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++ Untuk menggunakan Audio Langsung dari AudioTrack :for i=0; i<n; i++ | ES atau sebagian data ES dalam memori ION. | |
TS.PCR IP.NTP ALP.PTP | T/A | Wajib: Tidak Ada Opsional: Tidak Ada | 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++ Untuk konten yang direkam , menurut RecordStatus::* dan jadwal internal, lakukan salah satu hal berikut:
| Untuk data indeks: Dibawa dalam payload acara. Untuk konten rekaman: Aliran TS muxed diisi 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++ | T/A |
MMTP.MMTP | T/A | Wajib:DemuxFilterStatus::DATA_READY DemuxFilterStatus::DATA_OVERFLOW Direkomendasikan: DemuxFilterStatus::LOW_WATER DemuxFilterStatus::HIGH_WATER | Sesuai dengan acara dan jadwal internal, jalankanFilter.read(buffer, offset, adjustedSize) satu kali atau lebih.Data disalin dari MQ HAL ke buffer klien. | Memfilter mmtp 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 Opsional: DemuxFilterStatus::DATA_READY DemuxFilterStatus::DATA_OVERFLOW DemuxFilterStatus::LOW_WATER DemuxFilterStatus::HIGH_WATER | Untuk data indeks: for i=0; i<n; i++ Untuk konten yang direkam , menurut RecordStatus::* dan jadwal internal, lakukan salah satu hal berikut:
| Untuk data indeks: Dibawa dalam payload acara. Untuk konten rekaman: Aliran rekaman muxed diisi dalam FMQ. Jika sumber filter untuk perekaman 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 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 FMQ dengan 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 muatan IP diisi di FMQ oleh paket muatan IP lainnya. |
IP.IP TLV.TLV ALP.ALP | isPassthrough: | Opsional:DemuxFilterStatus::DATA_READY DemuxFilterStatus::DATA_OVERFLOW | Subaliran protokol yang difilter memberi umpan pada filter berikutnya dalam rantai filter. | T/A |
isPassthrough: | Wajib:DemuxFilterStatus::DATA_READY DemuxFilterStatus::DATA_OVERFLOW Direkomendasikan: DemuxFilterStatus::LOW_WATER DemuxFilterStatus::HIGH_WATER | Sesuai dengan acara dan jadwal internal, jalankanFilter.read(buffer, offset, adjustedSize) satu kali atau lebih.Data disalin dari MQ HAL ke buffer klien. | Subaliran protokol yang disaring dengan header protokol diisi dalam FMQ. | |
IP.PAYLOAD_THROUGH TLV.PAYLOAD_THROUGH ALP.PAYLOAD_THROUGH | T/A | Opsional:DemuxFilterStatus::DATA_READY DemuxFilterStatus::DATA_OVERFLOW | Muatan protokol yang difilter memberi umpan pada filter berikutnya dalam rantai filter. | T/A |
Contoh alur penggunaan filter untuk membangun PSI/SI
Gambar 10. Alur membangun PSI/SI
Buka penyaring.
Filter filter = tuner.openFilter( Filter.TYPE_TS, Filter.SUBTYPE_SECTION, /* bufferSize */1000, executor, filterCallback );
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();
SectionEvent
ProsesEvent .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
Gambar 11. Alur penggunaan MediaEvent dari filter
- Buka, konfigurasikan, dan mulai filter A/V.
- Proses
MediaEvent
. - Terima
MediaEvent
. - Antrean blok linier ke
codec
. - Lepaskan pegangan A/V ketika data telah dikonsumsi.
Android.media.tv.tuner.dvr
DvrRecorder
menyediakan metode perekaman ini.
-
configure
-
attachFilter
-
detachFilter
-
start
-
flush
-
stop
-
setFileDescriptor
-
write
DvrPlayback
menyediakan metode pemutaran ini.
-
configure
-
start
-
flush
-
stop
-
setFileDescriptor
-
read
DvrSettings
digunakan untuk mengkonfigurasi DvrRecorder
dan DvrPlayback
. OnPlaybackStatusChangedListener
dan OnRecordStatusChangedListener
digunakan untuk melaporkan status instans DVR.
Contoh alur untuk memulai pencatatan
Gambar 12. Alur untuk memulai pencatatan
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();
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. } } } };
Inisialisasi
OnRecordStatusChangedListener
dan simpan data rekaman.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); } } };
Penyetel 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
Penyetel 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 |
Gambar 13. Diagram interaksi antar modul Tuner HAL
Filter keterkaitan
Tuner HAL mendukung hubungan filter sehingga filter dapat dihubungkan ke filter lain untuk beberapa lapisan. Filter mengikuti aturan di bawah ini.
- Filter ditautkan sebagai pohon, jalur dekat tidak diperbolehkan.
- Node root adalah demux.
- Filter beroperasi secara independen.
- Semua filter mulai mendapatkan data.
- Tautan filter mengalir 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>)
}
Gambar 14. Diagram alir hubungan filter untuk beberapa lapisan
Manajer Sumber Daya Tuner
Sebelum Tuner Resource Manager (TRM), peralihan antara dua aplikasi memerlukan perangkat keras Tuner yang sama. TV Input Framework (TIF) menggunakan mekanisme "kemenangan yang diperoleh pertama kali", yang berarti aplikasi mana pun yang mendapatkan sumber daya terlebih dahulu akan mempertahankan sumber daya tersebut. 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 "kemenangan latar depan", yang menghitung prioritas aplikasi berdasarkan status latar depan atau latar belakang aplikasi serta 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 kerangka kerja Tuner, MediaCas
, dan TvInputHardwareManager
untuk mendaftarkan, meminta, atau melepaskan sumber daya.
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 melepaskan sumber daya 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
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 juga dapat diperbarui dengan nilai prioritas sewenang-wenang dari klien.
Parameter di profil klien
TRM mengambil ID proses dari mTvInputSessionId
untuk memutuskan apakah suatu aplikasi merupakan aplikasi latar depan atau latar belakang. Untuk membuat mTvInputSessionId
, TvInputService.onCreateSession
, atau TvInputService.onCreateRecordingSession
menginisialisasi sesi TIS.
mUseCase
menunjukkan kasus penggunaan sesi. Kasus penggunaan yang telah ditentukan sebelumnya 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
}
Berkas konfigurasi
File konfigurasi default
File konfigurasi default di bawah ini 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 use case dan nilai prioritas use case. File yang disesuaikan dapat menggunakan platform/hardware/interfaces/tv/tuner/1.0/config/tunerResourceManagerUseCaseConfigSample.xml
sebagai templat.
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 sewenang-wenang dan nilai bagus. Nilai prioritas sewenang-wenang menimpa nilai prioritas yang dihitung dari jenis kasus penggunaan dan ID sesi.
Nilai bagus menunjukkan betapa lunaknya perilaku klien ketika berkonflik 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 diambil kembali dan ditetapkan ketika terjadi konflik sumber daya.
Gambar 15. Diagram mekanisme reklamasi konflik antar sumber daya Tuner
,Untuk Android 11 atau lebih tinggi, Anda dapat menggunakan framework Android Tuner untuk mengirimkan konten A/V. Kerangka kerja ini menggunakan alur perangkat keras dari vendor, sehingga cocok untuk SoC kelas bawah dan kelas atas. Kerangka kerja ini menyediakan cara yang aman untuk mengirimkan konten A/V yang dilindungi oleh lingkungan eksekusi tepercaya (TEE) dan jalur media aman (SMP), sehingga 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 kerangka kerja dan aplikasi
- Tuner Resource Manager (TRM): Mengkoordinasikan sumber daya Tuner HW
Untuk Android 11, komponen berikut telah ditingkatkan.
- CAS V2
-
TvInputService
atau Layanan Input TV (TIS) -
TvInputManagerService
atau Layanan Manajer Input TV (TIMS) -
MediaCodec
atau kodek media -
AudioTrack
atau trek audio -
MediaResourceManager
atau manajer sumber daya media (MRM)
Gambar 1. Interaksi antar komponen Android TV
Fitur
Frontend mendukung standar DTV di bawah ini.
- ATSC
- ATSC3
- DVB C/S/T
- ISDB S/S3/T
- Analog
Frontend di Android 12 dengan Tuner HAL 1.1 atau lebih tinggi mendukung standar DTV di bawah.
- DTMB
Demux mendukung protokol streaming di bawah ini.
- Arus transportasi (TS)
- Protokol transportasi media MPEG (MMTP)
- Protokol Internet (IP)
- Ketik nilai panjang (TLV)
- Protokol lapisan tautan ATSC (ALP)
Descrambler mendukung perlindungan konten di bawah ini.
- Jalur media yang aman
- Hapus jalur media
- Amankan catatan lokal
- Amankan pemutaran lokal
Tuner API mendukung kasus penggunaan di bawah ini.
- Pindai
- Hidup
- Pemutaran
- Catatan
Tuner, MediaCodec
, dan AudioTrack
mendukung mode aliran data di bawah ini.
- Payload ES dengan buffer memori yang jelas
- Payload ES dengan pegangan memori yang aman
- Melewati
Desain keseluruhan
Tuner HAL ditentukan antara kerangka Android dan perangkat keras vendor.
- Menjelaskan apa yang diharapkan kerangka kerja dari vendor dan bagaimana vendor dapat melakukannya.
- Mengekspor fungsionalitas frontend, demux, dan descrambler ke kerangka kerja melalui antarmuka
IFrontend
,IDemux
,IDescrambler
,IFilter
,IDvr
, danILnb
. - Termasuk fungsi untuk mengintegrasikan Tuner HAL dengan komponen kerangka kerja lainnya, seperti
MediaCodec
danAudioTrack
.
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 yang terbatas, seperti Frontend, LNB, sesi CAS, dan perangkat input TV dari input TV HAL.
- Menerapkan aturan untuk mendapatkan kembali sumber daya yang tidak mencukupi dari aplikasi. Aturan defaultnya adalah kemenangan latar depan.
Media CAS dan CAS HAL ditingkatkan dengan fitur di bawah ini.
- Membuka sesi CAS untuk penggunaan dan algoritma yang berbeda.
- Mendukung sistem CAS dinamis, seperti pelepasan dan penyisipan CICAM.
- Terintegrasi dengan Tuner HAL dengan menyediakan token kunci.
MediaCodec
dan AudioTrack
ditingkatkan dengan 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.
Gambar 2. Diagram komponen-komponen dalam Tuner HAL
Alur kerja keseluruhan
Diagram di bawah mengilustrasikan urutan panggilan untuk pemutaran siaran langsung.
Mempersiapkan
Gambar 3. Urutan pengaturan untuk pemutaran siaran langsung
Menangani A/V
Gambar 4. Menangani A/V untuk pemutaran siaran langsung
Menangani konten yang diacak
Gambar 5. Menangani konten yang diacak untuk pemutaran siaran langsung
Memproses data A/V
Gambar 6. Memproses A/V untuk pemutaran siaran langsung
API SDK Penyetel
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.
Gambar 7. Interaksi dengan Tuner SDK API
Versi
Mulai Android 12, Tuner SDK API mendukung fitur baru di Tuner HAL 1.1, yang merupakan 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 di dokumentasi API Android 12 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
Gambar 8. Paket Tuner SDK API
Android.media.tv.tuner
Paket Tuner adalah titik masuk untuk menggunakan kerangka Tuner. Aplikasi TIS menggunakan paket untuk menginisialisasi dan memperoleh instans sumber daya dengan menentukan pengaturan awal dan panggilan balik.
-
tuner()
: Menginisialisasi instance Tuner dengan menentukan parameteruseCase
dansessionId
. -
tune()
: Mengakuisisi sumber daya frontend dan menyetelnya dengan menentukan parameterFrontendSetting
. -
openFilter()
: Mengakuisisi instance filter dengan menentukan tipe filter. -
openDvrRecorder()
: Mengakuisisi instance rekaman dengan menentukan ukuran buffer. -
openDvrPlayback()
: Mengakuisisi instance pemutaran dengan menentukan ukuran buffer. -
openDescrambler()
: Mengakuisisi instance descrambler. -
openLnb()
: Mengakuisisi instance LNB internal. -
openLnbByName()
: Mengakuisisi instance LNB eksternal. -
openTimeFilter()
: Mengakuisisi instance filter waktu.
Paket Tuner menyediakan fungsionalitas 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 pengaturan, informasi, status, peristiwa, dan kemampuan terkait frontend.
Kelas
FrontendSettings
diturunkan untuk standar DTV yang berbeda berdasarkan kelas di bawah.
-
AnalogFrontendSettings
-
Atsc3FrontendSettings
-
AtscFrontendSettings
-
DvbcFrontendSettings
-
DvbsFrontendSettings
-
DvbtFrontendSettings
-
Isdbs3FrontendSettings
-
IsdbsFrontendSettings
-
IsdbtFrontendSettings
Mulai Android 12 dengan Tuner HAL 1.1 atau lebih tinggi, standar DTV berikut didukung.
-
DtmbFrontendSettings
FrontendCapabilities
diturunkan untuk standar DTV yang berbeda berdasarkan kelas di bawah.
-
AnalogFrontendCapabilities
-
Atsc3FrontendCapabilities
-
AtscFrontendCapabilities
-
DvbcFrontendCapabilities
-
DvbsFrontendCapabilities
-
DvbtFrontendCapabilities
-
Isdbs3FrontendCapabilities
-
IsdbsFrontendCapabilities
-
IsdbtFrontendCapabilities
Mulai Android 12 dengan Tuner HAL 1.1 atau lebih tinggi, standar DTV berikut didukung.
-
DtmbFrontendCapabilities
FrontendInfo
mengambil informasi frontend. FrontendStatus
mengambil status frontend saat ini. OnTuneEventListener
mendengarkan acara di frontend. Aplikasi TIS menggunakan ScanCallback
untuk memproses pesan pindaian dari frontend.
Pemindaian saluran
Untuk menyiapkan TV, aplikasi memindai kemungkinan frekuensi 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, ID PLD), maka Tuner.tune
direkomendasikan sebagai opsi yang lebih cepat .
Saat pengguna memanggil Tuner.tune
, tindakan berikut terjadi:
- TIS mengisi
FrontendSettings
dengan informasi yang diperlukan menggunakanTuner.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 hingga 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
, namun 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)
denganFrontendSettings
diisi dengan frekuensi.Laporan HAL memindai pesan
LOCKED
jika sinyal terkunci. HAL mungkin juga melaporkan pesan pemindaian lainnya untuk memberikan informasi tambahan tentang sinyal tersebut.TIS menggunakan
Frontend.getStatus
untuk mengumpulkan informasi yang diperlukan.TIS memanggil
Tuner.scan
agar HAL melanjutkan ke pengaturan berikutnya pada frekuensi yang sama. Jika strukturFrontendSettings
kosong, HAL menggunakan pengaturan berikutnya yang tersedia. Jika tidak, HAL menggunakanFrontendSettings
untuk pemindaian satu kali dan mengirimkanEND
untuk menunjukkan bahwa operasi pemindaian telah selesai.TIS mengulangi tindakan di atas hingga semua pengaturan 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 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 diFrontendSettings
untuk frekuensi awal, namun TIS mengabaikan pengaturan lain diFrontendSettings
. - HAL melaporkan pesan pindaian
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 menambah frekuensi tanpa perlu tindakan apa pun dari TIS. HAL melaporkan
PROGRESS
.
TIS memanggil Tuner.scan(AUTO_SCAN)
lagi hingga 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.
Gambar 9. Diagram alur pemindaian TIS
Android.media.tv.tuner.filter
Paket filter adalah kumpulan operasi filter beserta konfigurasi, pengaturan, callback, dan peristiwa. Paket ini 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
berasal dari kelas di bawah ini. Konfigurasinya ditujukan untuk jenis filter utama dan menentukan protokol mana yang digunakan filter untuk mengekstrak data.
-
AlpFilterConfiguration
-
IpFilterConfiguration
-
MmtpFilterConfiguration
-
TlvFilterConfiguration
-
TsFilterConfiguration
Pengaturannya berasal dari kelas di bawah ini. Setelannya ditujukan 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 acara untuk berbagai jenis data.
-
SectionEvent
-
MediaEvent
-
PesEvent
-
TsRecordEvent
-
MmtpRecordEvent
-
TemiEvent
-
DownloadEvent
-
IpPayloadEvent
Dari Android 12 dengan Tuner HAL 1.1 atau lebih tinggi, peristiwa berikut didukung.
-
IpCidChangeEvent
-
RestartEvent
-
ScramblingStatusEvent
Acara dan format data dari filter
Jenis penyaring | Bendera | Acara | Operasi data | Format data |
---|---|---|---|---|
TS.SECTION MMTP.SECTION IP.SECTION TLV.SECTION ALP.SECTION | isRaw: | Wajib:DemuxFilterStatus::DATA_READY DemuxFilterStatus::DATA_OVERFLOW Direkomendasikan: DemuxFilterStatus::LOW_WATER DemuxFilterStatus::HIGH_WATER | Menurut acara dan jadwal internal, jalankanFilter.read(buffer, offset, adjustedSize) satu atau lebih kali.Data disalin dari MQ Hal ke buffer klien. | Satu paket sesi yang dirakit diisi dalam FMQ oleh paket sesi lain. |
isRaw: | Wajib:DemuxFilterEvent::DemuxFilterSectionEvent[n] DemuxFilterStatus::DATA_READY DemuxFilterStatus::DATA_OVERFLOW Opsional: DemuxFilterStatus::LOW_WATER DemuxFilterStatus::HIGH_WATER | for i=0; i<n; i++ Data disalin dari MQ Hal ke buffer klien. | ||
TS.PES | isRaw: | Wajib:DemuxFilterStatus::DATA_READY DemuxFilterStatus::DATA_OVERFLOW Direkomendasikan: DemuxFilterStatus::LOW_WATER DemuxFilterStatus::HIGH_WATER | Menurut acara dan jadwal internal, jalankanFilter.read(buffer, offset, adjustedSize) satu atau lebih kali.Data disalin dari MQ HAL ke buffer klien. | Satu paket PES yang dirakit diisi dalam FMQ oleh paket PES lain. |
isRaw: | Wajib:DemuxFilterEvent::DemuxFilterPesEvent[n] DemuxFilterStatus::DATA_READY DemuxFilterStatus::DATA_OVERFLOW Opsional: DemuxFilterStatus::LOW_WATER DemuxFilterStatus::HIGH_WATER | for i=0; i<n; i++ Data disalin dari MQ Hal ke buffer klien. | ||
MMTP.PES | isRaw: | Wajib:DemuxFilterStatus::DATA_READY DemuxFilterStatus::DATA_OVERFLOW Direkomendasikan: DemuxFilterStatus::LOW_WATER DemuxFilterStatus::HIGH_WATER | Menurut acara dan jadwal internal, jalankanFilter.read(buffer, offset, adjustedSize) satu atau lebih kali.Data disalin dari MQ HAL ke buffer klien. | Satu paket MFU yang dirakit diisi dalam FMQ oleh paket MFU lain. |
isRaw: | Wajib:DemuxFilterEvent::DemuxFilterPesEvent[n] DemuxFilterStatus::DATA_READY DemuxFilterStatus::DATA_OVERFLOW Opsional: DemuxFilterStatus::LOW_WATER DemuxFilterStatus::HIGH_WATER | for i=0; i<n; i++ 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 | Menurut acara dan jadwal internal, jalankanFilter.read(buffer, offset, adjustedSize) satu atau lebih kali.Data disalin dari MQ HAL ke buffer klien. | Disaring ts dengan header ts diisi dalam FMQ. |
TS.Audio TS.Video MMTP.Audio MMTP.Video | isPassthrough: | Opsional:DemuxFilterStatus::DATA_READY DemuxFilterStatus::DATA_OVERFLOW | Klien dapat memulai MediaCodec setelah menerima DemuxFilterStatus::DATA_READY .Klien dapat menghubungi Filter.flush setelah menerima DemuxFilterStatus::DATA_OVERFLOW . | T/A |
isPassthrough: | 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++ Untuk menggunakan audio langsung dari AudioTrack :for i=0; i<n; i++ | ES atau data ES parsial 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 Opsional: DemuxFilterStatus::DATA_READY DemuxFilterStatus::DATA_OVERFLOW DemuxFilterStatus::LOW_WATER DemuxFilterStatus::HIGH_WATER | Untuk data indeks:for i=0; i<n; i++ Untuk konten yang direkam , menurut RecordStatus::* dan jadwal internal, lakukan salah satu dari yang berikut:
| Untuk data indeks: dibawa dalam muatan acara. Untuk konten yang direkam: aliran TS muxed diisi 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++ | T/A |
MMTP.MMTP | T/A | Wajib:DemuxFilterStatus::DATA_READY DemuxFilterStatus::DATA_OVERFLOW Direkomendasikan: DemuxFilterStatus::LOW_WATER DemuxFilterStatus::HIGH_WATER | Menurut acara dan jadwal internal, jalankanFilter.read(buffer, offset, adjustedSize) satu atau lebih kali.Data disalin dari MQ HAL ke buffer klien. | Disaring mmtp dengan header mmtp diisi dalam 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++ Untuk konten yang direkam , menurut RecordStatus::* dan jadwal internal, lakukan salah satu dari yang berikut:
| Untuk data indeks: dibawa dalam muatan acara. Untuk konten yang direkam: aliran rekaman muxed diisi FMQ. Jika sumber filter untuk perekaman adalah TLV.TLV ke IP.IP dengan PASSTHROUGH, aliran 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 unduhan diisi dalam FMQ oleh paket unduhan 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 dalam FMQ oleh paket payload IP lain. |
IP.IP TLV.TLV ALP.ALP | isPassthrough: | Opsional:DemuxFilterStatus::DATA_READY DemuxFilterStatus::DATA_OVERFLOW | Sub aliran Sub Protokol yang disaring memberi makan filter berikutnya dalam rantai filter. | T/A |
isPassthrough: | Wajib:DemuxFilterStatus::DATA_READY DemuxFilterStatus::DATA_OVERFLOW Direkomendasikan: DemuxFilterStatus::LOW_WATER DemuxFilterStatus::HIGH_WATER | Menurut acara dan jadwal internal, jalankanFilter.read(buffer, offset, adjustedSize) satu atau lebih kali.Data disalin dari MQ HAL ke buffer klien. | Sub aliran protokol yang disaring dengan header protokol diisi dalam FMQ. | |
IP.PAYLOAD_THROUGH TLV.PAYLOAD_THROUGH ALP.PAYLOAD_THROUGH | T/A | Opsional:DemuxFilterStatus::DATA_READY DemuxFilterStatus::DATA_OVERFLOW | Feed Payload Protokol Difilter Filter berikutnya dalam rantai filter. | T/A |
Contoh Aliran untuk Menggunakan Filter untuk Membangun PSI/SI
Gambar 10. Aliran untuk membangun psi/si
Buka filter.
Filter filter = tuner.openFilter( Filter.TYPE_TS, Filter.SUBTYPE_SECTION, /* bufferSize */1000, executor, filterCallback );
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();
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 Aliran untuk Menggunakan MediaEvent dari Filter
Gambar 11. Aliran untuk menggunakan mediaEevent dari filter
- Buka, konfigurasikan, dan mulai filter A/V.
- Proses
MediaEvent
. - Menerima
MediaEvent
. - Antri blok linier ke
codec
. - 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 mengonfigurasi DvrRecorder
dan DvrPlayback
. OnPlaybackStatusChangedListener
dan OnRecordStatusChangedListener
digunakan untuk melaporkan status instance DVR.
Contoh Aliran untuk Memulai Rekor
Gambar 12. Aliran untuk memulai catatan
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();
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. } } } };
Inisialisasi
OnRecordStatusChangedListener
dan simpan data catatan.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
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 |
Gambar 13. Diagram interaksi antara modul Tuner HAL
Linkage Filter
Tuner HAL mendukung keterkaitan filter sehingga filter dapat ditautkan ke filter lain untuk beberapa lapisan. Filter mengikuti aturan di bawah ini.
- Filter dihubungkan sebagai pohon, jalan dekat tidak diperbolehkan.
- Node root adalah Demux.
- Filter beroperasi secara independen.
- Semua filter mulai mendapatkan data.
- Linkage filter menyiram pada filter terakhir.
Blok kode di bawah ini dan Gambar 14 menggambarkan contoh penyaringan 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>)
}
Gambar 14. Diagram alir dari tautan filter untuk beberapa lapisan
Tuner Resource Manager
Sebelum Tuner Resource Manager (TRM), beralih di antara dua aplikasi membutuhkan perangkat keras tuner yang sama. Kerangka Input TV (TIF) menggunakan mekanisme "kemenangan pertama ke Acquire", yang berarti aplikasi mana pun yang mendapatkan sumber daya terlebih dahulu menjaga sumber daya. Namun, mekanisme ini mungkin tidak ideal untuk beberapa kasus penggunaan yang rumit.
TRM berjalan sebagai layanan sistem untuk mengelola tuner, TVInput
, dan sumber daya perangkat keras CAS untuk aplikasi. TRM menggunakan mekanisme "foreground win", yang menghitung prioritas aplikasi berdasarkan status latar depan atau latar belakang aplikasi dan penggunaan jenis kasus. TRM memberi 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 kerangka kerja tuner, MediaCas
, dan TvInputHardwareManager
untuk mendaftar, meminta, atau melepaskan sumber daya.
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 melepaskan 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 juga dapat diperbarui oleh nilai prioritas sewenang -wenang 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
menginisialisasi sesi TIS.
mUseCase
menunjukkan kasus penggunaan sesi. Kasing 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
}
Berkas konfigurasi
File konfigurasi default
File konfigurasi default di bawah ini menyediakan 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 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 templat.
Misalnya, kasus penggunaan vendor baru adalah VENDOR_USE_CASE__[A-Z0-9]+, [0 - 1000]
. Format 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 sewenang -wenang dan nilai yang bagus. Nilai prioritas sewenang -wenang menimpa nilai prioritas yang dihitung dari jenis kasus penggunaan dan ID sesi.
Nilai yang bagus menunjukkan seberapa lunak perilaku klien saat bertentangan dengan klien lain. Nilai yang bagus mengurangi nilai prioritas klien sebelum nilai prioritasnya dibandingkan dengan klien yang menantang.
Mekanisme reklamasi
Diagram di bawah ini menunjukkan bagaimana sumber daya direklamasi dan ditugaskan ketika konflik sumber daya terjadi.
Gambar 15. Diagram mekanisme reklamasi untuk konflik antara sumber daya tuner
,Untuk Android 11 atau lebih tinggi, Anda dapat menggunakan Kerangka Tuner Android untuk mengirimkan konten A/V. Kerangka kerja menggunakan pipa perangkat keras dari vendor, membuatnya cocok untuk SOC kelas bawah dan kelas atas. Kerangka kerja ini menyediakan cara yang aman untuk memberikan konten A/V yang dilindungi oleh lingkungan eksekusi tepercaya (TEE) dan Secure Media Path (SMP), yang 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 TV Android. 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 kerangka dan aplikasi
- Tuner Resource Manager (TRM): Koordinat Tuner HW Resources
Untuk Android 11, komponen berikut telah ditingkatkan.
- CAS V2
-
TvInputService
atau Layanan Input TV (TIS) -
TvInputManagerService
atau Layanan Manajer Input TV (TIMS) -
MediaCodec
atau codec media -
AudioTrack
atau trek audio -
MediaResourceManager
atau Manajer Sumber Daya Media (MRM)
Gambar 1. Interaksi antara komponen TV Android
Fitur
Frontend mendukung standar DTV di bawah ini.
- ATSC
- ATSC3
- DVB C/S/T
- ISDB S/S3/T
- Analog
Frontend di Android 12 dengan Tuner HAL 1.1 atau lebih tinggi mendukung standar DTV di bawah ini.
- DTMB
Demux mendukung protokol aliran di bawah ini.
- Transport Stream (TS)
- MPEG Media Transport Protocol (MMTP)
- Protokol Internet (IP)
- Jenis Nilai Panjang (TLV)
- ATSC Link-Layer Protocol (ALP)
Descrambler mendukung perlindungan konten di bawah ini.
- Jalur media yang aman
- Jalur media yang jelas
- Mengamankan catatan lokal
- Mengamankan pemutaran lokal
Tuner API mendukung kasus penggunaan di bawah ini.
- Pindai
- Hidup
- Pemutaran
- Catatan
Tuner, MediaCodec
, dan AudioTrack
mendukung mode aliran data di bawah ini.
- ES payload dengan buffer memori yang jelas
- ES payload dengan pegangan memori yang aman
- Melewati
Desain keseluruhan
Tuner HAL didefinisikan antara kerangka Android dan perangkat keras vendor.
- Menjelaskan apa yang diharapkan kerangka kerja dari vendor dan bagaimana vendor bisa melakukannya.
- Ekspor fungsionalitas frontend, demux dan descrambler ke kerangka kerja melalui
IFrontend
,IDemux
,IDescrambler
,IFilter
,IDvr
, dan antarmukaILnb
. - Termasuk fungsi untuk mengintegrasikan Tuner HAL dengan komponen kerangka kerja lainnya, seperti
MediaCodec
danAudioTrack
.
Kelas tuner Java dan kelas asli dibuat.
- Tuner Java API memungkinkan aplikasi untuk mengakses Tuner HAL melalui API publik.
- Kelas asli memungkinkan kontrol izin dan penanganan data perekaman atau pemutaran dalam jumlah besar dengan Tuner HAL.
- Modul Tuner Asli adalah jembatan antara kelas Tuner Java dan Tuner HAL.
Kelas TRM dibuat.
- Mengelola sumber daya tuner terbatas, seperti Frontend, LNB, Sesi CAS, dan perangkat input TV dari HAL input TV.
- Menerapkan aturan untuk merebut kembali sumber daya yang tidak mencukupi dari aplikasi. Aturan default adalah kemenangan latar depan.
Media CAS dan CAS HAL ditingkatkan dengan fitur di bawah ini.
- Membuka sesi CAS untuk penggunaan dan algoritma yang berbeda.
- Mendukung sistem CAS dinamis, seperti penghapusan dan penyisipan CICAM.
- Terintegrasi dengan Tuner HAL dengan memberikan token kunci.
MediaCodec
dan AudioTrack
ditingkatkan dengan fitur di bawah ini.
- Mengambil memori A/V yang aman sebagai input konten.
- Dikonfigurasi untuk melakukan sinkronisasi A/V perangkat keras dalam pemutaran tunneled.
- Dukungan yang dikonfigurasi untuk mode
ES_payload
dan passthrough.
Gambar 2. Diagram komponen di dalam tuner HAL
Alur kerja keseluruhan
Diagram di bawah ini menggambarkan urutan panggilan untuk pemutaran siaran langsung.
Mempersiapkan
Gambar 3. Urutan pengaturan untuk pemutaran siaran langsung
Menangani A/V
Gambar 4. Menangani A/V untuk pemutaran siaran langsung
Menangani konten orak -arik
Gambar 5. Menangani konten orak -arik untuk pemutaran siaran langsung
Memproses Data A/V
Gambar 6. Memproses A/V untuk pemutaran siaran langsung
Tuner SDK API
Tuner SDK API menangani interaksi dengan Tuner JNI, Tuner HAL, dan TunerResourceManager
. Aplikasi TIS menggunakan API Tuner SDK untuk mengakses sumber daya tuner dan subkomponen seperti filter dan descrambler. Frontend dan Demux adalah komponen internal.
Gambar 7. Interaksi dengan Tuner SDK API
Versi
Dari Android 12, API Tuner SDK mendukung fitur baru di Tuner HAL 1.1, yang merupakan peningkatan versi yang kompatibel dengan tuner 1.0.
Gunakan API berikut untuk memeriksa versi HAL yang 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
Gambar 8. Paket API Tuner SDK
Android.media.tv.tuner
Paket tuner adalah titik masuk untuk menggunakan kerangka kerja tuner. Aplikasi TIS menggunakan paket untuk menginisialisasi dan memperoleh instance sumber daya dengan menentukan pengaturan awal dan panggilan balik.
-
tuner()
: Menginisialisasi instance tuner dengan menentukan parameteruseCase
dansessionId
. -
tune()
: Mengakuisisi sumber daya frontend dan tune dengan menentukan parameterFrontendSetting
. -
openFilter()
: Memperoleh instance filter dengan menentukan jenis filter. -
openDvrRecorder()
: Memperoleh instance perekaman dengan menentukan ukuran buffer. -
openDvrPlayback()
: Mengakuisisi instance pemutaran dengan menentukan ukuran buffer. -
openDescrambler()
: Mengakuisisi contoh descrambler. -
openLnb()
: Mengakuisisi instance LNB internal. -
openLnbByName()
: Mengakuisisi instance LNB eksternal. -
openTimeFilter()
: Mengakuisisi instance filter waktu.
Paket Tuner menyediakan fungsionalitas yang tidak tercakup dalam paket filter, DVR, dan frontend. Fungsionalitas tercantum di bawah ini.
-
cancelTuning
-
scan
/cancelScanning
-
getAvSyncHwId
-
getAvSyncTime
-
connectCiCam1
/disconnectCiCam
-
shareFrontendFromTuner
-
updateResourcePriority
-
setOnTuneEventListener
-
setResourceLostListener
Android.media.tv.tuner.frontend
Paket Frontend mencakup koleksi pengaturan, informasi, status, acara, dan kemampuan yang terkait dengan frontend.
Kelas
FrontendSettings
diturunkan untuk standar DTV yang berbeda oleh kelas di bawah ini.
-
AnalogFrontendSettings
-
Atsc3FrontendSettings
-
AtscFrontendSettings
-
DvbcFrontendSettings
-
DvbsFrontendSettings
-
DvbtFrontendSettings
-
Isdbs3FrontendSettings
-
IsdbsFrontendSettings
-
IsdbtFrontendSettings
Dari Android 12 dengan Tuner HAL 1.1 atau lebih tinggi, standar DTV berikut didukung.
-
DtmbFrontendSettings
FrontendCapabilities
diturunkan untuk standar DTV yang berbeda oleh kelas di bawah ini.
-
AnalogFrontendCapabilities
-
Atsc3FrontendCapabilities
-
AtscFrontendCapabilities
-
DvbcFrontendCapabilities
-
DvbsFrontendCapabilities
-
DvbtFrontendCapabilities
-
Isdbs3FrontendCapabilities
-
IsdbsFrontendCapabilities
-
IsdbtFrontendCapabilities
Dari Android 12 dengan Tuner HAL 1.1 atau lebih tinggi, standar DTV berikut didukung.
-
DtmbFrontendCapabilities
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 mengatur TV, aplikasi memindai kemungkinan frekuensi dan membangun lineup 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 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 .
Ketika pengguna memanggil Tuner.tune
, tindakan berikut terjadi:
- TIS mengisi
FrontendSettings
dengan informasi yang diperlukan menggunakanTuner.tune
. - HAL melaporkan pesan
LOCKED
jika sinyal terkunci. - TIS menggunakan
Frontend.getStatus
untuk mengumpulkan informasi yang diperlukan. - TIS bergerak ke frekuensi yang tersedia berikutnya dalam daftar frekuensinya.
TIS menyebut Tuner.tune
Lagi sampai semua frekuensi habis.
Selama tuning, Anda dapat menghubungi 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 tipe standar (misalnya, DVB T/C/S), maka Tuner.scan(AUTO_SCAN)
disarankan.
Ketika pengguna memanggil Tuner.scan(AUTO_SCAN)
, tindakan berikut terjadi:
TIS menggunakan
Tuner.scan(AUTO_SCAN)
denganFrontendSettings
diisi dengan frekuensi.HAL melaporkan memindai pesan
LOCKED
jika sinyal terkunci. HAL juga dapat melaporkan pesan pemindaian lain untuk memberikan informasi tambahan tentang sinyal.TIS menggunakan
Frontend.getStatus
untuk mengumpulkan informasi yang diperlukan.TIS memanggil
Tuner.scan
untuk HAL untuk melanjutkan ke pengaturan berikutnya pada frekuensi yang sama. Jika strukturFrontendSettings
kosong, HAL menggunakan pengaturan yang tersedia berikutnya. Kalau tidak, HAL menggunakanFrontendSettings
untuk pemindaian satu kali dan mengirimkanEND
untuk menunjukkan bahwa operasi pemindaian selesai.Ini mengulangi tindakan di atas sampai semua pengaturan pada frekuensi habis.
HAL mengirimkan
END
untuk menunjukkan bahwa operasi pemindaian selesai.TIS bergerak ke frekuensi yang tersedia berikutnya dalam daftar frekuensinya.
TIS menyebut Tuner.scan(AUTO_SCAN)
lagi sampai semua frekuensi habis.
Selama pemindaian, Anda dapat menghubungi 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)
disarankan.
- TIS menggunakan
Tuner.scan(BLIND_SCAN)
. Frekuensi dapat ditentukan dalamFrontendSettings
untuk frekuensi awal, tetapi ini mengabaikan pengaturan lain diFrontendSettings
. - HAL melaporkan pesan
LOCKED
pemindaian jika sinyal terkunci. - TIS menggunakan
Frontend.getStatus
untuk mengumpulkan informasi yang diperlukan. - Ini memanggil
Tuner.scan
lagi untuk melanjutkan pemindaian. (FrontendSettings
diabaikan.) - Ini mengulangi tindakan di atas sampai semua pengaturan pada frekuensi habis. HAL menambah frekuensi tanpa tindakan yang diperlukan dari TIS. HAL melaporkan
PROGRESS
.
TIS menyebut Tuner.scan(AUTO_SCAN)
lagi sampai semua frekuensi habis. Laporan HAL END
untuk menunjukkan bahwa operasi pemindaian selesai.
Selama pemindaian, Anda dapat menghubungi stopScan()
atau close()
untuk menjeda atau mengakhiri pemindaian.
Gambar 9. Diagram alir pemindaian TIS
Android.media.tv.tuner.filter
Paket filter adalah kumpulan operasi filter bersama dengan konfigurasi, pengaturan, panggilan balik, dan acara. Paket termasuk operasi di bawah ini. Lihat kode sumber Android untuk daftar operasi lengkap.
-
configure()
-
start()
-
stop()
-
flush()
-
read()
Lihat kode sumber Android untuk daftar lengkap.
FilterConfiguration
berasal dari kelas di bawah ini. Konfigurasi adalah untuk jenis filter utama dan mereka menentukan protokol mana yang digunakan filter untuk mengekstrak data.
-
AlpFilterConfiguration
-
IpFilterConfiguration
-
MmtpFilterConfiguration
-
TlvFilterConfiguration
-
TsFilterConfiguration
Pengaturan berasal dari kelas di bawah ini. Pengaturan untuk subtipe filter dan mereka menentukan jenis data apa yang dapat dikecualikan filter.
-
SectionSettings
-
AvSettings
-
PesSettings
-
RecordSettings
-
DownloadSettings
FilterEvent
berasal dari kelas di bawah ini untuk melaporkan acara untuk berbagai jenis data.
-
SectionEvent
-
MediaEvent
-
PesEvent
-
TsRecordEvent
-
MmtpRecordEvent
-
TemiEvent
-
DownloadEvent
-
IpPayloadEvent
Dari Android 12 dengan Tuner HAL 1.1 atau lebih tinggi, peristiwa berikut didukung.
-
IpCidChangeEvent
-
RestartEvent
-
ScramblingStatusEvent
Acara dan format data dari filter
Jenis penyaring | Bendera | Acara | Operasi data | Format data |
---|---|---|---|---|
TS.SECTION MMTP.SECTION IP.SECTION TLV.SECTION ALP.SECTION | isRaw: | Wajib:DemuxFilterStatus::DATA_READY DemuxFilterStatus::DATA_OVERFLOW Direkomendasikan: DemuxFilterStatus::LOW_WATER DemuxFilterStatus::HIGH_WATER | Menurut acara dan jadwal internal, jalankanFilter.read(buffer, offset, adjustedSize) satu atau lebih kali.Data disalin dari MQ Hal ke buffer klien. | Satu paket sesi yang dirakit diisi dalam FMQ oleh paket sesi lain. |
isRaw: | Wajib:DemuxFilterEvent::DemuxFilterSectionEvent[n] DemuxFilterStatus::DATA_READY DemuxFilterStatus::DATA_OVERFLOW Opsional: DemuxFilterStatus::LOW_WATER DemuxFilterStatus::HIGH_WATER | for i=0; i<n; i++ Data disalin dari MQ Hal ke buffer klien. | ||
TS.PES | isRaw: | Wajib:DemuxFilterStatus::DATA_READY DemuxFilterStatus::DATA_OVERFLOW Direkomendasikan: DemuxFilterStatus::LOW_WATER DemuxFilterStatus::HIGH_WATER | Menurut acara dan jadwal internal, jalankanFilter.read(buffer, offset, adjustedSize) satu atau lebih kali.Data disalin dari MQ HAL ke buffer klien. | Satu paket PES yang dirakit diisi dalam FMQ oleh paket PES lain. |
isRaw: | Wajib:DemuxFilterEvent::DemuxFilterPesEvent[n] DemuxFilterStatus::DATA_READY DemuxFilterStatus::DATA_OVERFLOW Opsional: DemuxFilterStatus::LOW_WATER DemuxFilterStatus::HIGH_WATER | for i=0; i<n; i++ Data disalin dari MQ Hal ke buffer klien. | ||
MMTP.PES | isRaw: | Wajib:DemuxFilterStatus::DATA_READY DemuxFilterStatus::DATA_OVERFLOW Direkomendasikan: DemuxFilterStatus::LOW_WATER DemuxFilterStatus::HIGH_WATER | Menurut acara dan jadwal internal, jalankanFilter.read(buffer, offset, adjustedSize) satu atau lebih kali.Data disalin dari MQ HAL ke buffer klien. | Satu paket MFU yang dirakit diisi dalam FMQ oleh paket MFU lain. |
isRaw: | Wajib:DemuxFilterEvent::DemuxFilterPesEvent[n] DemuxFilterStatus::DATA_READY DemuxFilterStatus::DATA_OVERFLOW Opsional: DemuxFilterStatus::LOW_WATER DemuxFilterStatus::HIGH_WATER | for i=0; i<n; i++ 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 | Menurut acara dan jadwal internal, jalankanFilter.read(buffer, offset, adjustedSize) satu atau lebih kali.Data disalin dari MQ HAL ke buffer klien. | Disaring ts dengan header ts diisi dalam FMQ. |
TS.Audio TS.Video MMTP.Audio MMTP.Video | isPassthrough: | Opsional:DemuxFilterStatus::DATA_READY DemuxFilterStatus::DATA_OVERFLOW | Klien dapat memulai MediaCodec setelah menerima DemuxFilterStatus::DATA_READY .Klien dapat menghubungi Filter.flush setelah menerima DemuxFilterStatus::DATA_OVERFLOW . | T/A |
isPassthrough: | 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++ Untuk menggunakan audio langsung dari AudioTrack :for i=0; i<n; i++ | ES atau data ES parsial 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 Opsional: DemuxFilterStatus::DATA_READY DemuxFilterStatus::DATA_OVERFLOW DemuxFilterStatus::LOW_WATER DemuxFilterStatus::HIGH_WATER | Untuk data indeks:for i=0; i<n; i++ Untuk konten yang direkam , menurut RecordStatus::* dan jadwal internal, lakukan salah satu dari yang berikut:
| Untuk data indeks: dibawa dalam muatan acara. Untuk konten yang direkam: aliran TS muxed diisi 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++ | T/A |
MMTP.MMTP | T/A | Wajib:DemuxFilterStatus::DATA_READY DemuxFilterStatus::DATA_OVERFLOW Direkomendasikan: DemuxFilterStatus::LOW_WATER DemuxFilterStatus::HIGH_WATER | Menurut acara dan jadwal internal, jalankanFilter.read(buffer, offset, adjustedSize) satu atau lebih kali.Data disalin dari MQ HAL ke buffer klien. | Disaring mmtp dengan header mmtp diisi dalam 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++ Untuk konten yang direkam , menurut RecordStatus::* dan jadwal internal, lakukan salah satu dari yang berikut:
| Untuk data indeks: dibawa dalam muatan acara. Untuk konten yang direkam: aliran rekaman muxed diisi FMQ. Jika sumber filter untuk perekaman adalah TLV.TLV ke IP.IP dengan PASSTHROUGH, aliran 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 unduhan diisi dalam FMQ oleh paket unduhan 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 dalam FMQ oleh paket payload IP lain. |
IP.IP TLV.TLV ALP.ALP | isPassthrough: | Opsional:DemuxFilterStatus::DATA_READY DemuxFilterStatus::DATA_OVERFLOW | Sub aliran Sub Protokol yang disaring memberi makan filter berikutnya dalam rantai filter. | T/A |
isPassthrough: | Wajib:DemuxFilterStatus::DATA_READY DemuxFilterStatus::DATA_OVERFLOW Direkomendasikan: DemuxFilterStatus::LOW_WATER DemuxFilterStatus::HIGH_WATER | Menurut acara dan jadwal internal, jalankanFilter.read(buffer, offset, adjustedSize) satu atau lebih kali.Data disalin dari MQ HAL ke buffer klien. | Sub aliran protokol yang disaring dengan header protokol diisi dalam FMQ. | |
IP.PAYLOAD_THROUGH TLV.PAYLOAD_THROUGH ALP.PAYLOAD_THROUGH | T/A | Opsional:DemuxFilterStatus::DATA_READY DemuxFilterStatus::DATA_OVERFLOW | Feed Payload Protokol Difilter Filter berikutnya dalam rantai filter. | T/A |
Contoh Aliran untuk Menggunakan Filter untuk Membangun PSI/SI
Gambar 10. Aliran untuk membangun psi/si
Buka filter.
Filter filter = tuner.openFilter( Filter.TYPE_TS, Filter.SUBTYPE_SECTION, /* bufferSize */1000, executor, filterCallback );
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();
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 Aliran untuk Menggunakan MediaEvent dari Filter
Gambar 11. Aliran untuk menggunakan mediaEevent dari filter
- Buka, konfigurasikan, dan mulai filter A/V.
- Proses
MediaEvent
. - Menerima
MediaEvent
. - Antri blok linier ke
codec
. - 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 mengonfigurasi DvrRecorder
dan DvrPlayback
. OnPlaybackStatusChangedListener
dan OnRecordStatusChangedListener
digunakan untuk melaporkan status instance DVR.
Contoh Aliran untuk Memulai Rekor
Gambar 12. Aliran untuk memulai catatan
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();
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. } } } };
Inisialisasi
OnRecordStatusChangedListener
dan simpan data catatan.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
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 |
Gambar 13. Diagram interaksi antara modul Tuner HAL
Linkage Filter
Tuner HAL mendukung keterkaitan filter sehingga filter dapat ditautkan ke filter lain untuk beberapa lapisan. Filter mengikuti aturan di bawah ini.
- Filter dihubungkan sebagai pohon, jalan dekat tidak diperbolehkan.
- Node root adalah Demux.
- Filter beroperasi secara independen.
- Semua filter mulai mendapatkan data.
- Linkage filter menyiram pada filter terakhir.
Blok kode di bawah ini dan Gambar 14 menggambarkan contoh penyaringan 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>)
}
Gambar 14. Diagram alir dari tautan filter untuk beberapa lapisan
Tuner Resource Manager
Sebelum Tuner Resource Manager (TRM), beralih di antara dua aplikasi membutuhkan perangkat keras tuner yang sama. Kerangka Input TV (TIF) menggunakan mekanisme "kemenangan pertama ke Acquire", yang berarti aplikasi mana pun yang mendapatkan sumber daya terlebih dahulu menjaga sumber daya. Namun, mekanisme ini mungkin tidak ideal untuk beberapa kasus penggunaan yang rumit.
TRM berjalan sebagai layanan sistem untuk mengelola tuner, TVInput
, dan sumber daya perangkat keras CAS untuk aplikasi. TRM menggunakan mekanisme "foreground win", yang menghitung prioritas aplikasi berdasarkan status latar depan atau latar belakang aplikasi dan penggunaan jenis kasus. TRM memberi 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 kerangka kerja tuner, MediaCas
, dan TvInputHardwareManager
untuk mendaftar, meminta, atau melepaskan sumber daya.
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 melepaskan 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 juga dapat diperbarui oleh nilai prioritas sewenang -wenang 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
menginisialisasi sesi TIS.
mUseCase
menunjukkan kasus penggunaan sesi. Kasing 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
}
Berkas konfigurasi
File konfigurasi default
File konfigurasi default di bawah ini menyediakan 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 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 templat.
Misalnya, kasus penggunaan vendor baru adalah VENDOR_USE_CASE__[A-Z0-9]+, [0 - 1000]
. Format 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 sewenang -wenang dan nilai yang bagus. Nilai prioritas sewenang -wenang menimpa nilai prioritas yang dihitung dari jenis kasus penggunaan dan ID sesi.
Nilai yang bagus menunjukkan seberapa lunak perilaku klien saat bertentangan dengan klien lain. Nilai yang bagus mengurangi nilai prioritas klien sebelum nilai prioritasnya dibandingkan dengan klien yang menantang.
Mekanisme reklamasi
Diagram di bawah ini menunjukkan bagaimana sumber daya direklamasi dan ditugaskan ketika konflik sumber daya terjadi.
Gambar 15. Diagram mekanisme reklamasi untuk konflik antara sumber daya tuner