Untuk Android 11 atau yang lebih tinggi, Anda dapat menggunakan framework Tuner Android untuk mengirimkan konten A/V. Framework ini menggunakan pipeline hardware dari vendor, sehingga cocok untuk SoC kelas bawah dan kelas atas. Framework ini menyediakan cara aman untuk mengirimkan konten A/V yang dilindungi oleh trusted execution environment (TEE) dan secure media path (SMP), sehingga memungkinkannya digunakan di lingkungan perlindungan konten yang sangat dibatasi.
Antarmuka standar antara Tuner dan Android CAS menghasilkan integrasi
yang lebih cepat antara vendor Tuner dan vendor CAS. Antarmuka Tuner berfungsi
dengan MediaCodec
dan AudioTrack
untuk membuat solusi satu dunia untuk Android TV.
Antarmuka Tuner mendukung TV digital dan TV analog berdasarkan standar
siaran utama.
Komponen
Untuk Android 11, tiga komponen dirancang khusus untuk platform TV.
- Tuner HAL: Antarmuka antara framework dan vendor
- Tuner SDK API: Antarmuka antara framework dan aplikasi
- Tuner Resource Manager (TRM): Mengkoordinasikan resource HW Tuner
Untuk Android 11, komponen berikut telah ditingkatkan.
- CAS V2
TvInputService
atau Layanan Input TV (TIS)TvInputManagerService
atau Layanan Pengelola Input TV (TIMS)MediaCodec
atau codec mediaAudioTrack
atau trek audioMediaResourceManager
atau pengelola resource media (MRM)
Gambar 1. Interaksi antarkomponen Android TV
Fitur
Frontend mendukung standar DTV di bawah.
- ATSC
- ATSC3
- DVB C/S/T
- ISDB S/S3/T
- Analog
Frontend di Android 12 dengan Tuner HAL 1.1 atau yang lebih tinggi mendukung standar DTV di bawah.
- DTMB
Demux mendukung protokol streaming di bawah.
- Transport stream (TS)
- MPEG media transport protocol (MMTP)
- Internet Protocol (IP)
- Nilai panjang jenis (TLV)
- Protokol lapisan link ATSC (ALP)
Descrambler mendukung perlindungan konten di bawah.
- Jalur media aman
- Menghapus jalur media
- Mengamankan data lokal
- Mengamankan pemutaran lokal
Tuner API mendukung kasus penggunaan di bawah.
- Pindai
- Live
- Pemutaran
- Rekam
Tuner, MediaCodec
, dan AudioTrack
mendukung mode aliran data di bawah.
- Payload ES dengan buffer memori yang jelas
- Payload ES dengan handle memori aman
- Passthrough
Desain keseluruhan
Tuner HAL ditentukan antara framework Android dan hardware vendor.
- Menjelaskan apa yang diharapkan framework dari vendor dan bagaimana vendor dapat melakukannya.
- Mengekspor fungsi frontend, demux, dan descrambler ke
framework melalui antarmuka
IFrontend
,IDemux
,IDescrambler
,IFilter
,IDvr
, danILnb
. - Menyertakan fungsi untuk mengintegrasikan Tuner HAL dengan komponen
framework lainnya, seperti
MediaCodec
danAudioTrack
.
Class Java Tuner dan class native dibuat.
- Tuner Java API memungkinkan aplikasi mengakses Tuner HAL melalui API publik.
- Class native memungkinkan kontrol izin dan penanganan data rekaman atau pemutaran dalam jumlah besar dengan Tuner HAL.
- Modul Tuner Native adalah jembatan antara class Java Tuner dan Tuner HAL.
Class TRM dibuat.
- Mengelola resource Tuner terbatas, seperti Frontend, LNB, sesi CAS, dan perangkat input TV dari HAL input TV.
- Menerapkan aturan untuk mengklaim kembali resource yang tidak memadai dari aplikasi. Aturan defaultnya adalah latar depan menang.
Media CAS dan CAS HAL ditingkatkan dengan fitur di bawah.
- Membuka sesi CAS untuk berbagai penggunaan dan algoritma.
- Mendukung sistem CAS dinamis, seperti penghapusan dan penyisipan CICAM.
- Mengintegrasikan dengan Tuner HAL dengan menyediakan token kunci.
MediaCodec
dan AudioTrack
ditingkatkan dengan fitur di bawah.
- Menggunakan memori A/V aman sebagai input konten.
- Dikonfigurasi untuk melakukan sinkronisasi A/V hardware dalam pemutaran yang di-tunnel.
- Mendukung konfigurasi untuk
ES_payload
dan mode passthrough.
Gambar 2. Diagram komponen dalam Tuner HAL
Alur kerja keseluruhan
Diagram di bawah mengilustrasikan urutan panggilan untuk pemutaran live streaming.
Penyiapan
Gambar 3. Menyiapkan urutan untuk pemutaran siaran live
Menangani A/V
Gambar 4. Menangani A/V untuk pemutaran live streaming
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 live streaming
Tuner SDK API
Tuner SDK API menangani interaksi dengan Tuner JNI, Tuner HAL,
dan TunerResourceManager
. Aplikasi TIS menggunakan Tuner SDK API untuk mengakses resource
dan subkomponen Tuner seperti filter dan descrambler. Frontend dan
demux adalah komponen internal.
Gambar 7. Interaksi dengan Tuner SDK API
Versi
Dari Android 12, Tuner SDK API mendukung fitur baru di Tuner HAL 1.1, yang adalah upgrade versi Tuner 1.0 yang kompatibel dengan versi sebelumnya.
Gunakan API berikut untuk memeriksa versi HAL yang sedang berjalan.
android.media.tv.tuner.TunerVersionChecker.getTunerVersion()
Versi HAL minimum yang diperlukan dapat ditemukan dalam dokumentasi API Android 12 baru.
Paket
Tuner SDK API menyediakan empat paket di bawah.
android.media.tv.tuner
android.media.tv.tuner.frontend
android.media.tv.tuner.filter
android.media.tv.tuner.dvr
Gambar 8. Paket Tuner SDK API
Android.media.tv.tuner
Paket Tuner adalah titik entri untuk menggunakan framework Tuner. Aplikasi TIS menggunakan paket untuk melakukan inisialisasi dan memperoleh instance resource dengan menentukan setelan awal dan callback.
tuner()
: Melakukan inisialisasi instance Tuner dengan menentukan parameteruseCase
dansessionId
.tune()
: Memperoleh resource frontend dan menyesuaikan dengan menentukan parameterFrontendSetting
.openFilter()
: Mendapatkan instance filter dengan menentukan jenis filter.openDvrRecorder()
: Mendapatkan instance perekaman dengan menentukan ukuran buffer.openDvrPlayback()
: Mendapatkan instance pemutaran dengan menentukan ukuran buffering.openDescrambler()
: Memperoleh instance descrambler.openLnb()
: Memperoleh instance LNB internal.openLnbByName()
: Memperoleh instance LNB eksternal.openTimeFilter()
: Mendapatkan instance filter waktu.
Paket Tuner menyediakan fungsi yang tidak tercakup dalam paket filter, DVR, dan frontend. Fungsinya tercantum di bawah ini.
cancelTuning
scan
/cancelScanning
getAvSyncHwId
getAvSyncTime
connectCiCam1
/disconnectCiCam
shareFrontendFromTuner
updateResourcePriority
setOnTuneEventListener
setResourceLostListener
Android.media.tv.tuner.frontend
Paket frontend mencakup kumpulan setelan, informasi, status, peristiwa, dan kemampuan terkait frontend.
Class
FrontendSettings
berasal dari berbagai standar DTV oleh class di bawah.
AnalogFrontendSettings
Atsc3FrontendSettings
AtscFrontendSettings
DvbcFrontendSettings
DvbsFrontendSettings
DvbtFrontendSettings
Isdbs3FrontendSettings
IsdbsFrontendSettings
IsdbtFrontendSettings
Dari Android 12 dengan Tuner HAL 1.1 atau yang lebih tinggi, standar DTV berikut didukung.
DtmbFrontendSettings
FrontendCapabilities
berasal dari berbagai standar DTV oleh class
di bawah.
AnalogFrontendCapabilities
Atsc3FrontendCapabilities
AtscFrontendCapabilities
DvbcFrontendCapabilities
DvbsFrontendCapabilities
DvbtFrontendCapabilities
Isdbs3FrontendCapabilities
IsdbsFrontendCapabilities
IsdbtFrontendCapabilities
Dari Android 12 dengan Tuner HAL 1.1 atau yang lebih tinggi, standar DTV berikut didukung.
DtmbFrontendCapabilities
FrontendInfo
mengambil informasi frontend.
FrontendStatus
mengambil status frontend saat ini.
OnTuneEventListener
memproses peristiwa di frontend.
Aplikasi TIS menggunakan ScanCallback
untuk memproses pesan pemindaian dari frontend.
Pemindaian saluran
Untuk menyiapkan TV, aplikasi akan memindai kemungkinan frekuensi dan membuat rangkaian saluran
yang dapat diakses pengguna. TIS mungkin menggunakan Tuner.tune
,
Tuner.scan(BLIND_SCAN)
, atau Tuner.scan(AUTO_SCAN)
untuk menyelesaikan pemindaian
saluran.
Jika TIS memiliki informasi pengiriman yang akurat untuk sinyal, seperti frekuensi,
standar (misalnya, T/T2, S/S2), dan informasi tambahan yang diperlukan
(misalnya, ID PLD), maka
Tuner.tune
direkomendasikan sebagai opsi yang lebih cepat.
Saat pengguna memanggil Tuner.tune
, tindakan berikut akan terjadi:
- TIS mengisi
FrontendSettings
dengan informasi yang diperlukan menggunakanTuner.tune
. - HAL melaporkan pesan
LOCKED
penyesuaian jika sinyal terkunci. - TIS menggunakan
Frontend.getStatus
untuk mengumpulkan informasi yang diperlukan. - TIS berpindah ke frekuensi berikutnya yang tersedia dalam daftar frekuensinya.
TIS memanggil Tuner.tune
lagi hingga semua frekuensi habis.
Selama penyesuaian, Anda dapat memanggil stopTune()
atau close()
untuk menjeda atau mengakhiri
panggilan Tuner.tune
.
Tuner.scan(AUTO_SCAN)
Jika TIS tidak memiliki informasi yang cukup untuk menggunakan Tuner.tune
, tetapi memiliki daftar
frekuensi dan jenis standar (misalnya, DVB T/C/S),
Tuner.scan(AUTO_SCAN)
direkomendasikan.
Saat pengguna memanggil Tuner.scan(AUTO_SCAN)
, tindakan berikut akan terjadi:
TIS menggunakan
Tuner.scan(AUTO_SCAN)
denganFrontendSettings
yang diisi dengan frekuensi.HAL melaporkan pesan
LOCKED
pemindaian jika sinyal terkunci. HAL mungkin juga melaporkan pesan pemindaian lainnya untuk memberikan informasi tambahan tentang sinyal.TIS menggunakan
Frontend.getStatus
untuk mengumpulkan informasi yang diperlukan.TIS memanggil
Tuner.scan
agar HAL melanjutkan ke setelan berikutnya pada frekuensi yang sama. Jika strukturFrontendSettings
kosong, HAL akan menggunakan setelan berikut yang tersedia. Jika tidak, HAL akan menggunakanFrontendSettings
untuk pemindaian satu kali dan mengirimEND
untuk menunjukkan bahwa operasi pemindaian telah selesai.TIS mengulangi tindakan di atas hingga semua setelan pada frekuensi habis.
HAL mengirimkan
END
untuk menunjukkan bahwa operasi pemindaian telah selesai.TIS berpindah ke frekuensi berikutnya yang tersedia dalam daftar frekuensinya.
TIS memanggil Tuner.scan(AUTO_SCAN)
lagi hingga semua frekuensi habis.
Selama pemindaian, Anda dapat memanggil stopScan()
atau close()
untuk menjeda atau menghentikan
pemindaian.
Tuner.scan(BLIND_SCAN)
Jika TIS tidak memiliki daftar frekuensi dan HAL Vendor dapat menelusuri
frekuensi frontend yang ditentukan pengguna untuk mendapatkan resource frontend, Tuner.scan(BLIND_SCAN)
direkomendasikan.
- TIS menggunakan
Tuner.scan(BLIND_SCAN)
. Frekuensi dapat ditentukan diFrontendSettings
untuk frekuensi awal, tetapi TIS mengabaikan setelan lain diFrontendSettings
. - HAL melaporkan pesan
LOCKED
pemindaian jika sinyal terkunci. - TIS menggunakan
Frontend.getStatus
untuk mengumpulkan informasi yang diperlukan. - TIS memanggil
Tuner.scan
lagi untuk melanjutkan pemindaian. (FrontendSettings
diabaikan.) - TIS mengulangi tindakan di atas hingga semua setelan pada frekuensi
habis. HAL menambahkan frekuensi tanpa perlu tindakan dari TIS.
HAL melaporkan
PROGRESS
.
TIS memanggil Tuner.scan(AUTO_SCAN)
lagi hingga semua frekuensi habis.
HAL melaporkan END
untuk menunjukkan bahwa operasi pemindaian telah selesai.
Selama pemindaian, Anda dapat memanggil stopScan()
atau close()
untuk menjeda atau mengakhiri pemindaian.
Gambar 9. Diagram alur pemindaian TIS
Android.media.tv.tuner.filter
Paket filter adalah kumpulan operasi filter beserta konfigurasi, setelan, callback, dan peristiwa. Paket ini mencakup operasi di bawah. Lihat kode sumber Android untuk mengetahui daftar lengkap operasi.
configure()
start()
stop()
flush()
read()
Lihat kode sumber Android untuk mengetahui daftar lengkapnya.
FilterConfiguration
berasal dari class di bawah. Konfigurasi ini
untuk jenis filter utama dan menentukan protokol yang digunakan filter untuk
mengekstrak data.
AlpFilterConfiguration
IpFilterConfiguration
MmtpFilterConfiguration
TlvFilterConfiguration
TsFilterConfiguration
Setelan ini berasal dari class di bawah. Setelan ini ditujukan untuk subjenis filter dan menentukan jenis data yang dapat dikecualikan oleh filter.
SectionSettings
AvSettings
PesSettings
RecordSettings
DownloadSettings
FilterEvent
berasal dari class di bawah untuk melaporkan peristiwa untuk berbagai jenis data.
SectionEvent
MediaEvent
PesEvent
TsRecordEvent
MmtpRecordEvent
TemiEvent
DownloadEvent
IpPayloadEvent
Dari Android 12 dengan Tuner HAL 1.1 atau yang lebih tinggi, peristiwa berikut didukung.
IpCidChangeEvent
RestartEvent
ScramblingStatusEvent
Peristiwa dan format data dari filter
Jenis filter | Tanda | Peristiwa | Operasi data | Format data |
---|---|---|---|---|
TS.SECTION MMTP.SECTION IP.SECTION TLV.SECTION ALP.SECTION |
isRaw: |
Wajib:DemuxFilterStatus::DATA_READY DemuxFilterStatus::DATA_OVERFLOW Direkomendasikan: DemuxFilterStatus::LOW_WATER DemuxFilterStatus::HIGH_WATER |
Sesuai dengan peristiwa dan jadwal internal, jalankanFilter.read(buffer, offset, adjustedSize) satu atau beberapa
kali.Data disalin dari MQ HAL ke buffer klien. |
Satu paket sesi yang telah dirakit diisi di FMQ oleh paket sesi lain. |
isRaw: |
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 peristiwa dan jadwal internal, jalankanFilter.read(buffer, offset, adjustedSize) satu atau beberapa
kali.Data disalin dari MQ HAL ke buffer klien. |
Satu paket PES yang dirakit diisi di FMQ oleh paket PES lain. |
isRaw: |
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 peristiwa dan jadwal internal, jalankanFilter.read(buffer, offset, adjustedSize) satu atau beberapa
kali.Data disalin dari MQ HAL ke buffer klien. |
Satu paket MFU yang dirakit diisi di FMQ oleh paket MFU lain. |
isRaw: |
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 peristiwa dan jadwal internal, jalankanFilter.read(buffer, offset, adjustedSize) satu atau beberapa
kali.Data disalin dari MQ HAL ke buffer klien. |
ts yang difilter dengan header ts diisi di FMQ. |
TS.Audio TS.Video MMTP.Audio MMTP.Video |
isPassthrough: |
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 AudioTrack :for i=0; i<n; i++ |
Data ES atau ES parsial dalam memori ION. | |
TS.PCR IP.NTP ALP.PTP |
T/A | Wajib: T/A
Opsional: T/A |
T/A | T/A |
TS.RECORD |
T/A | Wajib: DemuxFilterEvent::DemuxFilterTsRecordEvent[n] RecordStatus::DATA_READY RecordStatus::DATA_OVERFLOW RecordStatus::LOW_WATER RecordStatus::HIGH_WATER Opsional: DemuxFilterStatus::DATA_READY DemuxFilterStatus::DATA_OVERFLOW DemuxFilterStatus::LOW_WATER DemuxFilterStatus::HIGH_WATER |
Untuk data indeks:for i=0; i<n; i++ Untuk konten yang direkam, sesuai dengan RecordStatus::* dan jadwal internal, lakukan
salah satu tindakan berikut:
|
Untuk data indeks: Dibawa dalam payload peristiwa. Untuk konten yang direkam: Streaming TS yang di-mux diisi di FMQ. |
TS.TEMI |
T/A | Wajib:DemuxFilterEvent::DemuxFilterTemiEvent[n] Opsional: DemuxFilterStatus::DATA_READY DemuxFilterStatus::DATA_OVERFLOW DemuxFilterStatus::LOW_WATER DemuxFilterStatus::HIGH_WATER |
for i=0; i<n; i++ |
T/A |
MMTP.MMTP |
T/A | Wajib:DemuxFilterStatus::DATA_READY DemuxFilterStatus::DATA_OVERFLOW Direkomendasikan: DemuxFilterStatus::LOW_WATER DemuxFilterStatus::HIGH_WATER |
Sesuai dengan peristiwa dan jadwal internal, jalankanFilter.read(buffer, offset, adjustedSize) satu atau beberapa
kali.Data disalin dari MQ HAL ke buffer klien. |
mmtp yang difilter dengan header mmtp diisi di FMQ. |
MMTP.RECORD |
T/A | Wajib:DemuxFilterEvent::DemuxFilterMmtpRecordEvent[n] RecordStatus::DATA_READY RecordStatus::DATA_OVERFLOW RecordStatus::LOW_WATER RecordStatus::HIGH_WATER Opsional: DemuxFilterStatus::DATA_READY DemuxFilterStatus::DATA_OVERFLOW DemuxFilterStatus::LOW_WATER DemuxFilterStatus::HIGH_WATER |
Untuk data indeks: for i=0; i<n; i++ Untuk konten yang direkam, sesuai dengan RecordStatus::* dan jadwal internal, lakukan salah satu
tindakan berikut:
|
Untuk data indeks: Dibawa dalam payload peristiwa. Untuk konten yang direkam: Streaming yang direkam dan di-mux diisi di FMQ. Jika sumber filter untuk perekaman adalah TLV.TLV hingga
IP.IP dengan passthrough, streaming yang direkam memiliki
header TLV dan IP. |
MMTP.DOWNLOAD |
T/A | Wajib:DemuxFilterEvent::DemuxFilterDownloadEvent[n] DemuxFilterStatus::DATA_READY DemuxFilterStatus::DATA_OVERFLOW Opsional: DemuxFilterStatus::LOW_WATER DemuxFilterStatus::HIGH_WATER |
for i=0; i<n; i++
Filter.read(buffer, offset, DemuxFilterDownloadEvent[i].size) Data disalin dari MQ HAL ke buffer klien. |
Paket download diisi di FMQ oleh paket download IP lain. |
IP.IP_PAYLOAD |
T/A | Wajib:DemuxFilterEvent::DemuxFilterIpPayloadEvent[n] DemuxFilterStatus::DATA_READY DemuxFilterStatus::DATA_OVERFLOW Opsional: DemuxFilterStatus::LOW_WATER DemuxFilterStatus::HIGH_WATER |
for i=0; i<n; i++
Filter.read(buffer, offset, DemuxFilterIpPayloadEvent[i].size) Data disalin dari MQ HAL ke buffer klien. |
Paket payload IP diisi di FMQ oleh paket payload IP lain. |
IP.IP TLV.TLV ALP.ALP |
isPassthrough: |
Opsional:DemuxFilterStatus::DATA_READY DemuxFilterStatus::DATA_OVERFLOW |
Sub-aliran protokol yang difilter akan memberi makan filter berikutnya dalam rantai filter. | T/A |
isPassthrough: |
Wajib:DemuxFilterStatus::DATA_READY DemuxFilterStatus::DATA_OVERFLOW Direkomendasikan: DemuxFilterStatus::LOW_WATER DemuxFilterStatus::HIGH_WATER |
Sesuai dengan peristiwa dan jadwal internal, jalankanFilter.read(buffer, offset, adjustedSize) satu atau beberapa
kali.Data disalin dari MQ HAL ke buffer klien. |
Sub-aliran protokol yang difilter dengan header protokol diisi di FMQ. | |
IP.PAYLOAD_THROUGH TLV.PAYLOAD_THROUGH ALP.PAYLOAD_THROUGH |
T/A | Opsional:DemuxFilterStatus::DATA_READY DemuxFilterStatus::DATA_OVERFLOW |
Payload protokol yang difilter akan mengisi filter berikutnya dalam rantai filter. | T/A |
Contoh alur untuk menggunakan filter guna membuat PSI/SI
Gambar 10. Alur untuk membuat 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();
Memproses
SectionEvent
.FilterCallback filterCallback = new FilterCallback() { @Override public void onFilterEvent(Filter filter, FilterEvent[] events) { for (FilterEvent event : events) { if (event instanceof SectionEvent) { SectionEvent sectionEvent = (SectionEvent) event; int tableId = sectionEvent.getTableId(); int version = sectionEvent.getVersion(); int dataLength = sectionEvent.getDataLength(); int sectionNumber = sectionEvent.getSectionNumber(); filter.read(buffer, 0, dataLength); } } } };
Contoh alur untuk menggunakan MediaEvent dari filter
Gambar 11. Alur untuk menggunakan MediaEvent dari filter
- Buka, konfigurasi, dan mulai filter A/V.
- Memproses
MediaEvent
. - Menerima
MediaEvent
. - Antrekan blok linear ke
codec
. - Lepaskan handle A/V saat data telah digunakan.
Android.media.tv.tuner.dvr
DvrRecorder
menyediakan metode ini untuk perekaman.
configure
attachFilter
detachFilter
start
flush
stop
setFileDescriptor
write
DvrPlayback
menyediakan metode ini untuk pemutaran.
configure
start
flush
stop
setFileDescriptor
read
DvrSettings
digunakan untuk mengonfigurasi DvrRecorder
dan DvrPlayback
.
OnPlaybackStatusChangedListener
dan OnRecordStatusChangedListener
digunakan
untuk melaporkan status instance DVR.
Contoh alur untuk memulai rekaman
Gambar 12. Alur untuk memulai perekaman
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();
Menerima
RecordEvent
dan mengambil informasi indeks.FilterCallback filterCallback = new FilterCallback() { @Override public void onFilterEvent(Filter filter, FilterEvent[] events) { for (FilterEvent event : events) { if (event instanceof TsRecordEvent) { TsRecordEvent recordEvent = (TsRecordEvent) event; int tsMask = recordEvent.getTsIndexMask(); int scMask = recordEvent.getScIndexMask(); int packetId = recordEvent.getPacketId(); long dataLength = recordEvent.getDataLength(); // handle the masks etc. } } } };
Lakukan inisialisasi
OnRecordStatusChangedListener
dan simpan data data.OnRecordStatusChangedListener listener = new OnRecordStatusChangedListener() { @Override public void onRecordStatusChanged(int status) { // a customized way to consume data efficiently by using status as a hint. if (status == Filter.STATUS_DATA_READY) { recorder.write(size); } } };
HAL Tuner
Tuner HAL mengikuti HIDL dan menentukan antarmuka antara framework dan hardware vendor. Vendor menggunakan antarmuka untuk menerapkan Tuner HAL dan framework menggunakannya untuk berkomunikasi dengan penerapan Tuner HAL.
Modul
Tuner HAL 1.0
Modul | Kontrol dasar | Kontrol khusus modul | File HAL |
---|---|---|---|
ITuner |
T/A | frontend(open, getIds, getInfo) , openDemux ,
openDescrambler , openLnb ,
getDemuxCaps |
ITuner.hal |
IFrontend |
setCallback , getStatus , close
| tune , stopTune , scan ,
stopScan , setLnb |
IFrontend.hal IFrontendCallback.hal |
IDemux |
close |
setFrontendDataSource , openFilter , openDvr , getAvSyncHwId ,
getAvSyncTime , connect / disconnectCiCam |
IDemux.hal |
IDvr |
close , start , stop , configure |
attach/detachFilters , flush , getQueueDesc |
IDvr.hal IDvrCallback.hal |
IFilter |
close , start , stop , configure , getId |
flush , getQueueDesc , releaseAvHandle , setDataSource |
IFilter.hal IFilterCallback.hal |
ILnb |
close , setCallback |
setVoltage , setTone , setSatellitePosition , sendDiseqcMessage |
ILnb.hal ILnbCallback.hal |
IDescrambler |
close |
setDemuxSource , setKeyToken ,
addPid , removePid |
IDescrambler.hal |
Tuner HAL 1.1 (berasal dari Tuner HAL 1.0)
Modul | Kontrol dasar | Kontrol khusus modul | File HAL |
---|---|---|---|
ITuner |
T/A | getFrontendDtmbCapabilities |
@1.1::ITuner.hal |
IFrontend |
tune_1_1 , scan_1_1 , getStatusExt1_1 |
link/unlinkCiCam |
@1.1::IFrontend.hal @1.1::IFrontendCallback.hal |
IFilter |
getStatusExt1_1 |
configureIpCid , configureAvStreamType , getAvSharedHandle , configureMonitorEvent |
@1.1::IFilter.hal @1.1::IFilterCallback.hal |
Gambar 13. Diagram interaksi antara modul HAL Tuner
Penautan filter
Tuner HAL mendukung penautan filter sehingga filter dapat ditautkan ke filter lain untuk beberapa lapisan. Filter mengikuti aturan di bawah.
- Filter ditautkan sebagai hierarki, jalur tutup tidak diizinkan.
- Node root adalah demux.
- Filter beroperasi secara independen.
- Semua filter mulai mendapatkan data.
- Penautan filter dihapus pada filter terakhir.
Blok kode di bawah dan Gambar 14 mengilustrasikan contoh pemfilteran beberapa lapisan.
demuxCaps = ITuner.getDemuxCap;
If (demuxCaps[IP][MMTP] == true) {
ipFilter = ITuner.openFilter(<IP, ..>)
mmtpFilter1 = ITuner.openFilter(<MMTP ..>)
mmtpFilter2 = ITuner.openFilter(<MMTP ..>)
mmtpFilter1.setDataSource(<ipFilter>)
mmtpFilter2.setDataSource(<ipFilter>)
}
Gambar 14. Diagram alur penautan filter untuk beberapa lapisan
Tuner Resource Manager
Sebelum Tuner Resource Manager (TRM), beralih antar-aplikasi memerlukan hardware Tuner yang sama. TV Input Framework (TIF) menggunakan mekanisme "menang pertama kali diperoleh", yang berarti aplikasi mana pun yang mendapatkan resource terlebih dahulu akan menyimpan resource tersebut. Namun, mekanisme ini mungkin tidak ideal untuk beberapa kasus penggunaan yang rumit.
TRM berjalan sebagai layanan sistem untuk mengelola resource hardware Tuner, TVInput
, dan CAS
untuk aplikasi. TRM menggunakan mekanisme "foreground win", yang
menghitung prioritas aplikasi berdasarkan status latar depan atau latar belakang
aplikasi dan jenis kasus penggunaan. TRM memberikan atau mencabut resource berdasarkan
prioritas. TRM memusatkan pengelolaan resource ATV untuk siaran, OTT,
dan DVR.
Antarmuka TRM
TRM mengekspos antarmuka AIDL di ITunerResourceManager.aidl
untuk framework
Tuner, MediaCas
, dan TvInputHardwareManager
guna mendaftarkan, meminta, atau
merilis resource.
Antarmuka untuk pengelolaan klien tercantum di bawah.
registerClientProfile(in ResourceClientProfile profile, IResourcesReclaimListener listener, out int[] clientId)
unregisterClientProfile(in int clientId)
Antarmuka untuk meminta dan merilis resource tercantum di bawah.
requestFrontend(TunerFrontendRequest request, int[] frontendHandle)
/releaseFrontend
requestDemux(TunerDemuxRequest request, int[] demuxHandle)
/releaseDemux
requestDescrambler(TunerDescramblerRequest request, int[] descramblerHandle)
/releaseDescrambler
requestCasSession(CasSessionRequest request, int[] casSessionHandle)
/releaseCasSession
requestLnb(TunerLnbRequest request, int[] lnbHandle)
/releaseLnb
Class klien dan permintaan tercantum di bawah.
ResourceClientProfile
ResourcesReclaimListener
TunerFrontendRequest
TunerDemuxRequest
TunerDescramblerRequest
CasSessionRequest
TunerLnbRequest
Prioritas klien
TRM menghitung prioritas klien menggunakan parameter dari profil klien dan nilai prioritas dari file konfigurasi. Prioritas juga dapat diperbarui oleh nilai prioritas arbitrer dari klien.
Parameter di profil klien
TRM mengambil ID proses dari mTvInputSessionId
untuk memutuskan apakah aplikasi
adalah aplikasi latar depan atau latar belakang. Untuk membuat mTvInputSessionId
,
TvInputService.onCreateSession
, atau TvInputService.onCreateRecordingSession
akan melakukan inisialisasi sesi TIS.
mUseCase
menunjukkan kasus penggunaan sesi. Kasus penggunaan standar
tercantum di bawah.
TvInputService.PriorityHintUseCaseType {
PRIORITY_HINT_USE_CASE_TYPE_PLAYBACK
PRIORITY_HINT_USE_CASE_TYPE_LIVE
PRIORITY_HINT_USE_CASE_TYPE_RECORD,
PRIORITY_HINT_USE_CASE_TYPE_SCAN,
PRIORITY_HINT_USE_CASE_TYPE_BACKGROUND
}
File konfigurasi
File konfigurasi default
File konfigurasi default di bawah memberikan nilai prioritas untuk kasus penggunaan yang telah ditentukan. Pengguna dapat mengubah nilai menggunakan file konfigurasi yang disesuaikan.
Kasus penggunaan | Latar depan | Latar belakang |
---|---|---|
LIVE |
490 | 400 |
PLAYBACK |
480 | 300 |
RECORD |
600 | 500 |
SCAN |
450 | 200 |
BACKGROUND |
180 | 100 |
File konfigurasi yang disesuaikan
Vendor dapat menyesuaikan file konfigurasi
/vendor/etc/tunerResourceManagerUseCaseConfig.xml
. File ini digunakan
untuk menambahkan, menghapus, atau memperbarui jenis kasus penggunaan dan nilai prioritas kasus penggunaan.
File yang disesuaikan dapat menggunakan
platform/hardware/interfaces/tv/tuner/1.0/config/tunerResourceManagerUseCaseConfigSample.xml
sebagai template.
Misalnya, kasus penggunaan vendor baru adalah VENDOR_USE_CASE__[A-Z0-9]+, [0 - 1000]
.
Formatnya harus mengikuti
platform/hardware/interfaces/tv/tuner/1.0/config/tunerResourceManagerUseCaseConfig.xsd
.
Nilai prioritas arbitrer dan nilai bagus
TRM menyediakan updateClientPriority
bagi klien untuk memperbarui nilai prioritas arbitrer dan nilai nice.
Nilai prioritas arbitrer menimpa nilai prioritas yang dihitung
dari jenis kasus penggunaan dan ID sesi.
Nilai nice menunjukkan seberapa longgar perilaku klien saat bertentangan dengan klien lain. Nilai bagus akan menurunkan nilai prioritas klien sebelum nilai prioritasnya dibandingkan dengan klien yang menantang.
Mekanisme pemulihan
Diagram di bawah menunjukkan cara resource diambil kembali dan ditetapkan saat terjadi konflik resource.
Gambar 15. Diagram mekanisme pengambil alihan untuk konflik antara resource Tuner