Untuk Android 11 atau yang lebih tinggi, Anda dapat menggunakan framework Android Tuner 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 yang aman untuk mengirimkan konten A/V yang dilindungi oleh trusted execution environment (TEE) dan jalur media yang aman (SMP), sehingga dapat digunakan di lingkungan perlindungan konten yang sangat terbatas.
Antarmuka standar antara Tuner dan Android CAS menghasilkan integrasi yang lebih cepat antara vendor Tuner dan vendor CAS. Antarmuka Tuner berfungsi
dengan MediaCodec
dan AudioTrack
untuk 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 framework dan vendor
- Tuner SDK API: Antarmuka antara framework dan aplikasi
- Tuner Resource Manager (TRM): Mengoordinasikan resource HW Tuner
Untuk Android 11, komponen berikut telah ditingkatkan.
- CAS V2
TvInputService
atau 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 antar-komponen Android TV
Fitur
Frontend mendukung standar DTV di bawah.
- ATSC
- ATSC3
- DVB C/S/T
- ISDB S/S3/T
- Analog
Frontend di Android 12 dengan Tuner HAL 1.1 atau yang lebih tinggi mendukung standar DTV di bawah.
- DTMB
Demux mendukung protokol streaming di bawah.
- Transport stream (TS)
- MPEG media transport protocol (MMTP)
- Protokol internet (IP)
- Nilai panjang jenis (TLV)
- Protokol lapisan link ATSC (ALP)
Pengacak mendukung perlindungan konten di bawah.
- Jalur media yang aman
- Hapus jalur media
- Mengamankan catatan lokal
- Mengamankan pemutaran lokal
Tuner API mendukung kasus penggunaan di bawah.
- Pindai
- Live
- Pemutaran
- Rekam
Tuner, MediaCodec
, dan AudioTrack
mendukung mode alur data di bawah.
- Payload ES dengan buffer memori yang jelas
- Payload ES dengan handle memori yang 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 pengacak ke framework melalui antarmuka
IFrontend
,IDemux
,IDescrambler
,IFilter
,IDvr
, danILnb
. - Mencakup 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 perekaman atau pemutaran dalam jumlah besar dengan Tuner HAL.
- Modul Native Tuner adalah jembatan antara class Java Tuner dan Tuner HAL.
Kelas 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 kemenangan di latar depan.
CAS Media dan CAS HAL ditingkatkan dengan fitur di bawah.
- Membuka sesi CAS untuk berbagai penggunaan dan algoritma.
- 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.
- Menggunakan memori A/V yang aman sebagai input konten.
- Dikonfigurasi untuk melakukan sinkronisasi A/V hardware dalam pemutaran yang di-tunnel.
- Mengonfigurasi dukungan untuk
ES_payload
dan mode teruskan.
Gambar 2. Diagram komponen dalam Tuner HAL
Alur kerja keseluruhan
Diagram di bawah menggambarkan urutan panggilan untuk pemutaran siaran live.
Penyiapan
Gambar 3. Urutan penyiapan untuk pemutaran siaran langsung
Menangani A/V
Gambar 4. Menangani A/V untuk pemutaran siaran live
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 live
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 pengacak. 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 yang kompatibel mundur dari Tuner 1.0.
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
API Tuner SDK 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 menginisialisasi dan mendapatkan instance resource dengan menentukan setelan awal dan callback.
tuner()
: Menginisialisasi instance Tuner dengan menentukan parameteruseCase
dansessionId
.tune()
: Mendapatkan 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 buffer.openDescrambler()
: Mendapatkan instance pengacak.openLnb()
: Mendapatkan instance LNB internal.openLnbByName()
: Mendapatkan instance LNB eksternal.openTimeFilter()
: Mendapatkan instance filter waktu.
Paket Tuner menyediakan fungsi yang tidak tercakup dalam paket filter, DVR, dan frontend. Fungsi tersebut tercantum di bawah ini.
cancelTuning
scan
/cancelScanning
getAvSyncHwId
getAvSyncTime
connectCiCam1
/disconnectCiCam
shareFrontendFromTuner
updateResourcePriority
setOnTuneEventListener
setResourceLostListener
Android.media.tv.tuner.frontend
Paket frontend mencakup kumpulan setelan, informasi, status, peristiwa, dan kemampuan terkait frontend.
Class
FrontendSettings
diturunkan untuk berbagai standar DTV oleh kelas di bawah.
AnalogFrontendSettings
Atsc3FrontendSettings
AtscFrontendSettings
DvbcFrontendSettings
DvbsFrontendSettings
DvbtFrontendSettings
Isdbs3FrontendSettings
IsdbsFrontendSettings
IsdbtFrontendSettings
Mulai dari Android 12 dengan Tuner HAL 1.1 atau yang lebih tinggi, standar DTV berikut didukung.
DtmbFrontendSettings
FrontendCapabilities
diturunkan untuk berbagai standar DTV berdasarkan kelas di bawah.
AnalogFrontendCapabilities
Atsc3FrontendCapabilities
AtscFrontendCapabilities
DvbcFrontendCapabilities
DvbsFrontendCapabilities
DvbtFrontendCapabilities
Isdbs3FrontendCapabilities
IsdbsFrontendCapabilities
IsdbtFrontendCapabilities
Mulai 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 memindai kemungkinan frekuensi dan membuat daftar saluran yang dapat diakses pengguna. TIS dapat menggunakan Tuner.tune
,
Tuner.scan(BLIND_SCAN)
, atau Tuner.scan(AUTO_SCAN)
untuk menyelesaikan pemindaian channel.
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
tune jika sinyal dikunci. - 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), maka 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 pemindaian pesan
LOCKED
jika sinyal dikunci. HAL juga dapat melaporkan pesan pemindaian lainnya untuk memberikan informasi tambahan tentang sinyal.TIS menggunakan
Frontend.getStatus
untuk mengumpulkan informasi yang diperlukan.TIS memanggil
Tuner.scan
untuk HAL agar melanjutkan ke setelan berikutnya pada frekuensi yang sama. Jika strukturFrontendSettings
kosong, HAL akan menggunakan setelan berikutnya yang tersedia. Jika tidak, HAL 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 mengirim
END
untuk menunjukkan bahwa operasi pemindaian telah selesai.TIS berpindah ke frekuensi berikutnya yang tersedia dalam daftar frekuensinya.
TIS memanggil Tuner.scan(AUTO_SCAN)
lagi hingga semua frekuensi habis.
Selama pemindaian, Anda dapat memanggil stopScan()
atau close()
untuk menjeda atau mengakhiri pemindaian.
Tuner.scan(BLIND_SCAN)
Jika TIS tidak memiliki daftar frekuensi dan Vendor HAL dapat menelusuri
frekuensi frontend yang ditentukan pengguna untuk mendapatkan resource frontend, maka
Tuner.scan(BLIND_SCAN)
direkomendasikan.
- TIS menggunakan
Tuner.scan(BLIND_SCAN)
. Frekuensi dapat ditentukan diFrontendSettings
untuk frekuensi mulai, tetapi TIS mengabaikan setelan lain diFrontendSettings
. - HAL melaporkan pesan
LOCKED
pemindaian jika sinyal dikunci. - 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 meningkatkan frekuensi tanpa memerlukan tindakan dari TIS.
Laporan HAL
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 ditujukan 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
Mulai dari Android 12 dengan Tuner HAL 1.1 atau yang lebih tinggi, peristiwa berikut didukung.
IpCidChangeEvent
RestartEvent
ScramblingStatusEvent
Format data dan peristiwa dari filter
Jenis filter | Tanda | 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 beberapa
kali.Data disalin dari MQ HAL ke buffer klien. |
Satu paket sesi yang 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 |
Menurut acara 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 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 beberapa
kali.Data disalin dari MQ HAL ke buffer klien. |
Satu paket MFU yang dirakit diisi dalam FMQ oleh 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 |
Menurut acara 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: Aliran 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 |
Menurut acara 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: Aliran rekaman yang di-mux diisi FMQ. Jika sumber filter untuk perekaman adalah TLV.TLV ke
IP.IP dengan penerusan, 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 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-stream protokol yang difilter akan memasok 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 beberapa
kali.Data disalin dari MQ HAL ke buffer klien. |
Sub-streaming protokol yang difilter dengan header protokol diisi FMQ. | |
IP.PAYLOAD_THROUGH TLV.PAYLOAD_THROUGH ALP.PAYLOAD_THROUGH |
T/A | Opsional:DemuxFilterStatus::DATA_READY DemuxFilterStatus::DATA_OVERFLOW |
Payload protokol yang difilter akan meneruskan filter berikutnya dalam rantai filter. | T/A |
Contoh alur untuk menggunakan filter guna membuat PSI/SI
Gambar 10. Alur untuk membangun PSI/SI
Buka filter.
Filter filter = tuner.openFilter( Filter.TYPE_TS, Filter.SUBTYPE_SECTION, /* bufferSize */1000, executor, filterCallback );
Konfigurasi dan mulai filter.
Settings settings = SectionSettingsWithTableInfo .builder(Filter.TYPE_TS) .setTableId(2) .setVersion(1) .setCrcEnabled(true) .setRaw(false) .setRepeat(false) .build(); FilterConfiguration config = TsFilterConfiguration .builder() .setTpid(10) .setSettings(settings) .build(); filter.configure(config); filter.start();
Proses
SectionEvent
.FilterCallback filterCallback = new FilterCallback() { @Override public void onFilterEvent(Filter filter, FilterEvent[] events) { for (FilterEvent event : events) { if (event instanceof SectionEvent) { SectionEvent sectionEvent = (SectionEvent) event; int tableId = sectionEvent.getTableId(); int version = sectionEvent.getVersion(); int dataLength = sectionEvent.getDataLength(); int sectionNumber = sectionEvent.getSectionNumber(); filter.read(buffer, 0, dataLength); } } } };
Contoh alur untuk menggunakan MediaEvent dari filter
Gambar 11. Alur untuk menggunakan MediaEvent dari filter
- Buka, konfigurasi, dan mulai filter A/V.
- Proses
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 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 alur untuk memulai rekaman
Gambar 12. Alur untuk memulai rekaman
Buka, konfigurasi, dan mulai
DvrRecorder
.DvrRecorder recorder = openDvrRecorder(/* bufferSize */ 1000, executor, listener); DvrSettings dvrSettings = DvrSettings .builder() .setDataFormat(DvrSettings.DATA_FORMAT_TS) .setLowThreshold(100) .setHighThreshold(900) .setPacketSize(188) .build(); recorder.configure(dvrSettings); recorder.attachFilter(filter); recorder.setFileDescriptor(fd); recorder.start();
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 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); } } };
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 penutup tidak diizinkan.
- Node root adalah demux.
- Filter beroperasi secara independen.
- Semua filter mulai mendapatkan data.
- Penautan filter akan dibersihkan pada filter terakhir.
Blok kode di bawah dan Gambar 14 menggambarkan 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 di antara dua aplikasi memerlukan hardware Tuner yang sama. TV Input Framework (TIF) menggunakan mekanisme "memperoleh pertama kali", yang berarti aplikasi yang mendapatkan resource terlebih dahulu akan mempertahankan 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 "kemenangan di latar depan", yang
menghitung prioritas aplikasi berdasarkan status latar depan atau latar belakang
dan jenis kasus penggunaan aplikasi. 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
untuk mendaftarkan, meminta, atau melepaskan resource.
Antarmuka untuk pengelolaan klien tercantum di bawah.
registerClientProfile(in ResourceClientProfile profile, IResourcesReclaimListener listener, out int[] clientId)
unregisterClientProfile(in int clientId)
Antarmuka untuk meminta dan melepaskan resource tercantum di bawah.
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 dengan 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
menginisialisasi sesi TIS.
mUseCase
menunjukkan kasus penggunaan sesi. Kasus penggunaan yang telah ditentukan sebelumnya 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 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 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
dan nilai bagus yang bersifat arbitrer.
Nilai prioritas arbitrer akan menggantikan nilai prioritas yang dihitung
dari jenis kasus penggunaan dan ID sesi.
Nilai bagus menunjukkan seberapa toleran perilaku klien saat bertentangan dengan klien lain. Nilai bagus mengurangi nilai prioritas klien sebelum nilai prioritasnya dibandingkan dengan klien yang menantang.
Mekanisme klaim ulang
Diagram di bawah menunjukkan cara resource diklaim kembali dan ditetapkan saat terjadi konflik resource.
Gambar 15. Diagram mekanisme pengambilan kembali untuk konflik antara resource Tuner