Per Android 11 o versioni successive, puoi usare la versione Framework di sintonizzazione per pubblicare contenuti A/V. Il framework utilizza l'hardware dei fornitori, il che lo rende adatto sia a SoC di fascia bassa che a SoC di fascia alta. Il framework fornisce un modo sicuro per pubblicare contenuti audio/video protetti da un un ambiente di esecuzione affidabile (TEE, Secure Media Path) e SMP (Secure Media Path), consentendo l'utilizzo in un ambiente di protezione dei contenuti altamente limitato.
L'interfaccia standardizzata tra Tuner e Android CAS garantisce
integrazione tra fornitori di Tuner e fornitori CAS. L'interfaccia di Tuner
con MediaCodec
e AudioTrack
per creare una soluzione unica per Android TV.
L'interfaccia del sintonizzatore supporta sia la TV digitale che la TV analogica in base ai principali
standard di trasmissione.
Componenti
Per Android 11, tre componenti sono specificamente progettato per la piattaforma TV.
- HAL di ottimizzazione: un'interfaccia tra il framework e i fornitori
- API Tuner SDK:un'interfaccia tra il framework e le app
- Tuner Resource Manager (TRM): risorse HW di Coordinates Tuner
Per Android 11, sono stati effettuati i seguenti componenti avanzate.
- CAS V2
TvInputService
o TV Input Service (TIS)TvInputManagerService
o TV Input Manager Service (TIMS)MediaCodec
o codec multimedialeAudioTrack
o traccia audioMediaResourceManager
o Media Resource Manager (MRM)
Figura 1. Interazioni tra i componenti di Android TV
Funzionalità
Frontend supporta gli standard DTV riportati di seguito.
- ATSC
- ATSC3
- DVB C/S/T
- ISDB S/S3/T
- Analogici
Il frontend in Android 12 con Tuner HAL 1.1 o superiore supporta lo standard DTV riportato di seguito.
- DTMB
Demux supporta i seguenti protocolli di flusso.
- Stream di trasporto (TS)
- MPEG Media Transport Protocol (MMTP)
- IP (Internet Protocol)
- Valore lunghezza del tipo (TLV)
- Protocollo di livello link (ALP) ATSC
Descrambler supporta le seguenti protezioni dei contenuti.
- Percorso multimediale sicuro
- Cancella percorso contenuti multimediali
- Record locale sicuro
- Riproduzione locale sicura
Le API di ottimizzazione supportano i casi d'uso riportati di seguito.
- Scansione
- In diretta
- Riproduzione
- Registra
Tuner, MediaCodec
e AudioTrack
supportano le seguenti modalità di flusso di dati.
- Payload ES con buffer di memoria libera
- Payload ES con handle di memoria sicuro
- Passthrough
Design complessivo
L'HAL per il sintonizzatore è definito tra il framework Android e il hardware.
- Descrive cosa il framework si aspetta dal fornitore e come quest'ultimo potrebbe fallo.
- Esporta le funzionalità di frontend, demux e decodificatore nel
tramite
IFrontend
,IDemux
,IDescrambler
,IFilter
,IDvr
, eILnb
. - Include le funzioni per integrare Tuner HAL con altri framework
come
MediaCodec
eAudioTrack
.
Vengono create una classe Java e una classe nativa Tuner.
- L'API Tuner Java consente alle app di accedere a Tuner HAL tramite API pubbliche.
- La classe nativa consente il controllo delle autorizzazioni e la gestione di la registrazione o la riproduzione dei dati con il Tuner HAL.
- Il modulo Native Tuner è un bridge tra la classe Java Tuner e il Tuner HAL
Viene creata una classe TRM.
- Gestisce risorse limitate del sintonizzatore, come Frontend, LNB Sessioni CAS e un dispositivo di ingresso TV dall'HAL di ingresso TV.
- Applica regole per recuperare risorse insufficienti da app. La regola predefinita è la vittoria in primo piano.
Media CAS e CAS HAL sono stati migliorati con le funzionalità riportate di seguito.
- Apre sessioni CAS per diversi utilizzi e algoritmi.
- Supporta sistemi CAS dinamici, come la rimozione e l'inserimento di CICAM.
- Si integra con Tuner HAL fornendo token chiave.
MediaCodec
e AudioTrack
sono migliorati con le funzionalità riportate di seguito.
- Prende una memoria A/V sicura come input dei contenuti.
- Configurata per la sincronizzazione A/V hardware nella riproduzione con tunnel.
- Supporto configurato per
ES_payload
e la modalità passthrough.
Figura 2. Diagramma dei componenti all'interno dell'HAL per il sintonizzatore
Flusso di lavoro complessivo
I seguenti diagrammi illustrano le sequenze di chiamate per la riproduzione di trasmissioni dal vivo.
Configura
Figura 3. Configura la sequenza per la riproduzione della trasmissione live
Gestione audio/video
Figura 4. Gestione audio/video per la riproduzione di trasmissioni live
Gestione dei contenuti illeggibili
Figura 5. Gestione di contenuti criptati per la riproduzione di trasmissioni live
Elaborazione dei dati audio/video
Figura 6. Elaborazione audio/video per la riproduzione di trasmissioni live
API Tuner SDK
L'API Tuner SDK gestisce le interazioni con Tuner JNI, Tuner HAL
e TunerResourceManager
. L'app TIS utilizza l'API dell'SDK Tuner per accedere a Tuner
risorse e sottocomponenti come filtro e decodificatore. Frontend e
demux sono componenti interni.
Figura 7. Interazioni con l'API dell'SDK Tuner
Versioni
A partire da Android 12, l'API Tuner SDK supporta la nuova funzionalità in Tuner HAL 1.1, è un aggiornamento della versione compatibile con le versioni precedenti di Tuner 1.0.
Usa l'API seguente per verificare la versione dell'HAL in esecuzione.
android.media.tv.tuner.TunerVersionChecker.getTunerVersion()
La versione minima dell'HAL richiesta è disponibile nella documentazione delle nuove API Android 12.
Pacchetti
L'API Tuner SDK fornisce i quattro pacchetti riportati di seguito.
android.media.tv.tuner
android.media.tv.tuner.frontend
android.media.tv.tuner.filter
android.media.tv.tuner.dvr
Figura 8. Pacchetti API dell'SDK del Tuner
Android.media.tv.tuner
Il pacchetto Tuner è un punto di ingresso per utilizzare il framework Tuner. L'app TIS Utilizza il pacchetto per inizializzare e acquisire le istanze delle risorse specificando l'impostazione iniziale e il callback.
tuner()
: inizializza un'istanza di Tuner specificandouseCase
e ParametrisessionId
.tune()
: acquisisce una risorsa frontend ed esegui l'ottimizzazione specificando ilFrontendSetting
.openFilter()
: acquisisce un'istanza di filtro specificando il tipo di filtro.openDvrRecorder()
: acquisisce un'istanza di registrazione specificando il buffer dimensioni.openDvrPlayback()
: acquisisce un'istanza di riproduzione specificando il buffer dimensioni.openDescrambler()
: acquisisce un'istanza del decodificatore.openLnb()
: acquisisce un'istanza LNB interna.openLnbByName()
: acquisisce un'istanza LNB esterna.openTimeFilter()
: acquisisce un'istanza di filtro temporale.
Il pacchetto Tuner fornisce funzionalità che non sono trattate in i pacchetti di filtri, DVR e frontend. Le funzionalità sono elencate di seguito.
cancelTuning
scan
/cancelScanning
getAvSyncHwId
getAvSyncTime
connectCiCam1
/disconnectCiCam
shareFrontendFromTuner
updateResourcePriority
setOnTuneEventListener
setResourceLostListener
Android.media.tv.tuner.frontend
Il pacchetto frontend include raccolte di impostazioni relative al frontend, informazioni, stati, eventi e funzionalità.
Classi
FrontendSettings
deriva da diversi standard DTV in base alle classi seguenti.
AnalogFrontendSettings
Atsc3FrontendSettings
AtscFrontendSettings
DvbcFrontendSettings
DvbsFrontendSettings
DvbtFrontendSettings
Isdbs3FrontendSettings
IsdbsFrontendSettings
IsdbtFrontendSettings
A partire da Android 12 con Tuner HAL 1.1 o successivo, è supportato il seguente standard DTV.
DtmbFrontendSettings
FrontendCapabilities
deriva da standard DTV diversi in base alle classi
di seguito.
AnalogFrontendCapabilities
Atsc3FrontendCapabilities
AtscFrontendCapabilities
DvbcFrontendCapabilities
DvbsFrontendCapabilities
DvbtFrontendCapabilities
Isdbs3FrontendCapabilities
IsdbsFrontendCapabilities
IsdbtFrontendCapabilities
A partire da Android 12 con Tuner HAL 1.1 o successivo, è supportato il seguente standard DTV.
DtmbFrontendCapabilities
FrontendInfo
recupera le informazioni del frontend.
FrontendStatus
recupera lo stato attuale del frontend.
OnTuneEventListener
ascolta gli eventi sul frontend.
L'app TIS utilizza ScanCallback
per elaborare i messaggi di scansione dal frontend.
Ricerca canali
Per configurare una TV, l'app analizza le possibili frequenze e crea un canale
a cui gli utenti possono accedere. TIS potrebbe utilizzare Tuner.tune
,
Tuner.scan(BLIND_SCAN)
o Tuner.scan(AUTO_SCAN)
per completare il canale
scansione.
Se il TIS dispone di informazioni di consegna accurate per l'indicatore, ad esempio frequenza,
standard (ad es. T/T2, S/S2) e ulteriori informazioni necessarie
(ad es. ID PLD),
Tuner.tune
è l'opzione più veloce.
Quando l'utente chiama Tuner.tune
, si verificano le seguenti azioni:
- Il TIS compila
FrontendSettings
con le informazioni richieste utilizzandoTuner.tune
. - I report dell'HAL ottimizzano i messaggi
LOCKED
se il segnale è bloccato. - TIS utilizza
Frontend.getStatus
per raccogliere le informazioni necessarie. - Il TIS passa alla successiva frequenza disponibile nel suo elenco di frequenze.
TIS chiama di nuovo Tuner.tune
fino a esaurimento di tutte le frequenze.
Durante l'ottimizzazione, puoi chiamare stopTune()
o close()
per mettere in pausa o terminare
Chiamata Tuner.tune
.
Tuner.scan(AUTO_SCAN)
Se TIS non dispone di informazioni sufficienti per utilizzare Tuner.tune
, ma ha una frequenza
elenco e tipo standard (ad es. DVB T/C/S),
allora è consigliato Tuner.scan(AUTO_SCAN)
.
Quando l'utente chiama Tuner.scan(AUTO_SCAN)
, si verificano le seguenti azioni:
Il TIS utilizza
Tuner.scan(AUTO_SCAN)
conFrontendSettings
riempito con frequenza.I report dell'HAL analizzano i messaggi
LOCKED
se il segnale è bloccato. L'HAL potrebbe segnalare anche altri messaggi di scansione per fornire ulteriori informazioni il segnale.TIS utilizza
Frontend.getStatus
per raccogliere le informazioni necessarie.TIS chiama
Tuner.scan
per l'HAL per passare all'impostazione successiva sulla stessa frequenza. Se la strutturaFrontendSettings
è vuota, l'HAL utilizza la versione l'impostazione disponibile. In caso contrario, l'HAL utilizzaFrontendSettings
per un account scansione e inviaEND
per indicare che l'operazione di scansione è terminata.Il TIS ripete le azioni sopra descritte finché tutte le impostazioni della frequenza non vengono esausto.
L'HAL invia
END
per indicare che l'operazione di scansione è terminata.Il TIS passa alla successiva frequenza disponibile nel suo elenco di frequenze.
TIS chiama di nuovo Tuner.scan(AUTO_SCAN)
fino a esaurimento di tutte le frequenze.
Durante la scansione, puoi chiamare stopScan()
o close()
per mettere in pausa o terminare la
scansione.
Tuner.scan(BLIND_SCAN)
Se TIS non ha un elenco di frequenze e l'HAL del fornitore può cercare
la frequenza del frontend specificato dall'utente per ottenere la risorsa frontend,
Orario consigliato: Tuner.scan(BLIND_SCAN)
.
- Il TIS utilizza
Tuner.scan(BLIND_SCAN)
. È possibile specificare una frequenzaFrontendSettings
per la frequenza iniziale, ma TIS ignora altre impostazioni aFrontendSettings
. - L'HAL segnala un messaggio di scansione
LOCKED
se il segnale è bloccato. - TIS utilizza
Frontend.getStatus
per raccogliere le informazioni necessarie. - TIS chiama di nuovo
Tuner.scan
per continuare la scansione. (FrontendSettings
corrisponde a ignorato). - Il TIS ripete le azioni sopra descritte finché tutte le impostazioni della frequenza non vengono
esausto. L'HAL incrementa la frequenza senza che sia richiesta alcuna azione da parte di TIS.
L'HAL segnala
PROGRESS
.
TIS chiama di nuovo Tuner.scan(AUTO_SCAN)
fino a esaurimento di tutte le frequenze.
L'HAL segnala END
per indicare che l'operazione di scansione è terminata.
Durante la scansione, puoi chiamare stopScan()
o close()
per metterla in pausa o terminarla.
Figura 9. Diagramma di flusso di una scansione TIS
Android.media.tv.tuner.filter
Il pacchetto filtri è una raccolta di operazioni di filtro, oltre a operazioni di configurazione, impostazioni, callback ed eventi. Il pacchetto include le operazioni riportate di seguito. Per l'elenco completo delle operazioni, fai riferimento al codice sorgente di Android.
configure()
start()
stop()
flush()
read()
Per l'elenco completo, fai riferimento al codice sorgente Android.
FilterConfiguration
deriva dalle classi seguenti. Le configurazioni sono
per il tipo di filtro principale e specificano il protocollo utilizzato dal filtro
estrarre i dati.
AlpFilterConfiguration
IpFilterConfiguration
MmtpFilterConfiguration
TlvFilterConfiguration
TsFilterConfiguration
Le impostazioni derivano dalle classi seguenti. Le impostazioni riguardano il filtro e specificano i tipi di dati che il filtro può escludere.
SectionSettings
AvSettings
PesSettings
RecordSettings
DownloadSettings
FilterEvent
deriva dalle classi seguenti per segnalare eventi per diversi
tipi di dati.
SectionEvent
MediaEvent
PesEvent
TsRecordEvent
MmtpRecordEvent
TemiEvent
DownloadEvent
IpPayloadEvent
A partire da Android 12 con Tuner HAL 1.1 o successivo, sono supportati i seguenti eventi.
IpCidChangeEvent
RestartEvent
ScramblingStatusEvent
Eventi e formato dei dati dal filtro
Tipo di filtro | Bandiere | Eventi | Operazione sui dati | Formato dei dati |
---|---|---|---|---|
TS.SECTION MMTP.SECTION IP.SECTION TLV.SECTION ALP.SECTION |
isRaw: |
Obbligatorio:DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW
Consigliato: DemuxFilterStatus::LOW_WATER DemuxFilterStatus::HIGH_WATER |
In base all'evento e alla programmazione interna, eseguiFilter.read(buffer, offset, adjustedSize) uno o più
volte.I dati vengono copiati dal MQ dell'HAL al buffer del client. |
Un pacchetto di sessioni assemblate viene compilato in FMQ da un altro di alta qualità. |
isRaw: |
Obbligatorio:DemuxFilterEvent::DemuxFilterSectionEvent[n]
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW Facoltativo: DemuxFilterStatus::LOW_WATER
DemuxFilterStatus::HIGH_WATER |
for i=0; i<n; i++ I dati vengono copiati dal MQ dell'HAL al buffer del client. |
||
TS.PES |
isRaw: |
Obbligatorio:DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW
Consigliato: DemuxFilterStatus::LOW_WATER DemuxFilterStatus::HIGH_WATER |
In base all'evento e alla programmazione interna, eseguiFilter.read(buffer, offset, adjustedSize) uno o più
volte.I dati vengono copiati dal MQ dell'HAL al buffer client. |
Un pacco PES assemblato viene compilato in FMQ da un altro Pacchetto PES. |
isRaw: |
Obbligatorio:DemuxFilterEvent::DemuxFilterPesEvent[n]
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW Facoltativo: DemuxFilterStatus::LOW_WATER
DemuxFilterStatus::HIGH_WATER |
for i=0; i<n; i++ I dati vengono copiati dal MQ dell'HAL al buffer del client. |
||
MMTP.PES |
isRaw: |
Obbligatorio:DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW
Consigliato: DemuxFilterStatus::LOW_WATER DemuxFilterStatus::HIGH_WATER |
In base all'evento e alla programmazione interna, eseguiFilter.read(buffer, offset, adjustedSize) uno o più
volte.I dati vengono copiati dal MQ dell'HAL al buffer client. |
Un pacchetto MFU assemblato viene compilato in FMQ da un altro Pacchetto MFU. |
isRaw: |
Obbligatorio:DemuxFilterEvent::DemuxFilterPesEvent[n]
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW Facoltativo: DemuxFilterStatus::LOW_WATER
DemuxFilterStatus::HIGH_WATER |
for i=0; i<n; i++ I dati vengono copiati dal MQ dell'HAL al buffer client. |
||
TS.TS |
N/D | Obbligatorio:DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW
Consigliato: DemuxFilterStatus::LOW_WATER DemuxFilterStatus::HIGH_WATER |
In base all'evento e alla programmazione interna, eseguiFilter.read(buffer, offset, adjustedSize) uno o più
volte.I dati vengono copiati dal MQ dell'HAL al buffer client. |
ts filtrato con ts intestazionesia compilato in FMQ. |
TS.Audio TS.Video MMTP.Audio MMTP.Video |
isPassthrough: |
Facoltativo:DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW
|
Il client può avviare MediaCodec dopo aver ricevuto DemuxFilterStatus::DATA_READY .Il cliente può chiamare Filter.flush dopo aver ricevuto DemuxFilterStatus::DATA_OVERFLOW . |
N/D |
isPassthrough: |
Obbligatorio:DemuxFilterEvent::DemuxFilterMediaEvent[n]
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW Facoltativo: DemuxFilterStatus::LOW_WATER
DemuxFilterStatus::HIGH_WATER |
Per usare MediaCodec :for i=0; i<n; i++
Per usare l'audio diretto di AudioTrack :for i=0; i<n; i++ |
Dati ES o dati ES parziali nella memoria ION. | |
TS.PCR IP.NTP ALP.PTP |
N/D | Obbligatorio:N/A
Facoltativo:N/D |
N/D | N/D |
TS.RECORD |
N/D | Obbligatorio: DemuxFilterEvent::DemuxFilterTsRecordEvent[n]
RecordStatus::DATA_READY
RecordStatus::DATA_OVERFLOW RecordStatus::LOW_WATER
RecordStatus::HIGH_WATER
Facoltativo: DemuxFilterStatus::DATA_READY DemuxFilterStatus::DATA_OVERFLOW DemuxFilterStatus::LOW_WATER DemuxFilterStatus::HIGH_WATER |
Per i dati dell'indice:for i=0; i<n; i++
Per i contenuti registrati: in base a RecordStatus::* e alla programmazione interna,
uno dei seguenti:
|
Per i dati di indice: viene trasferito il payload dell'evento. Per i contenuti registrati: stream TS Mux compilato in FMQ. |
TS.TEMI |
N/D | Obbligatorio:DemuxFilterEvent::DemuxFilterTemiEvent[n]
Facoltativo: DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW DemuxFilterStatus::LOW_WATER
DemuxFilterStatus::HIGH_WATER |
for i=0; i<n; i++ |
N/D |
MMTP.MMTP |
N/D | Obbligatorio:DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW
Consigliato: DemuxFilterStatus::LOW_WATER DemuxFilterStatus::HIGH_WATER |
In base all'evento e alla programmazione interna, eseguiFilter.read(buffer, offset, adjustedSize) uno o più
volte.I dati vengono copiati dal MQ dell'HAL al buffer client. |
mmtp filtrato con mmtp intestazionesia compilato in FMQ. |
MMTP.RECORD |
N/D | Obbligatorio:DemuxFilterEvent::DemuxFilterMmtpRecordEvent[n]
RecordStatus::DATA_READY
RecordStatus::DATA_OVERFLOW RecordStatus::LOW_WATER
RecordStatus::HIGH_WATER
Facoltativo: DemuxFilterStatus::DATA_READY DemuxFilterStatus::DATA_OVERFLOW DemuxFilterStatus::LOW_WATER DemuxFilterStatus::HIGH_WATER |
Per i dati dell'indice: for i=0; i<n; i++ Per i contenuti registrati, in base a RecordStatus::* e la programmazione interna, esegui una delle
seguenti:
|
Per i dati di indice: viene trasferito il payload dell'evento. Per i contenuti registrati: stream registrato con Mux compilato FMQ. Se l'origine del filtro per la registrazione è TLV.TLV per
IP.IP con passthrough, lo stream registrato ha un
TLV e IP header. |
MMTP.DOWNLOAD |
N/D | Obbligatorio:DemuxFilterEvent::DemuxFilterDownloadEvent[n]
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW Facoltativo: DemuxFilterStatus::LOW_WATER
DemuxFilterStatus::HIGH_WATER |
for i=0; i<n; i++
Filter.read(buffer, offset, DemuxFilterDownloadEvent[i].size) I dati vengono copiati dal MQ dell'HAL al buffer del client. |
Il pacchetto di download è compilato in FMQ da un altro pacchetto di download IP. |
IP.IP_PAYLOAD |
N/D | Obbligatorio:DemuxFilterEvent::DemuxFilterIpPayloadEvent[n]
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW Facoltativo: DemuxFilterStatus::LOW_WATER
DemuxFilterStatus::HIGH_WATER |
for i=0; i<n; i++
Filter.read(buffer, offset, DemuxFilterIpPayloadEvent[i].size) I dati vengono copiati dal MQ dell'HAL al buffer del client. |
Il pacchetto di payload IP viene compilato in FMQ da un altro pacchetto di payload IP. |
IP.IP TLV.TLV ALP.ALP |
isPassthrough: |
Facoltativo:DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW
|
Lo stream secondario di protocollo filtrato alimenta il filtro successivo nel filtro o la catena di fornitura. | N/D |
isPassthrough: |
Obbligatorio:DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW
Consigliato: DemuxFilterStatus::LOW_WATER DemuxFilterStatus::HIGH_WATER |
In base all'evento e alla programmazione interna, eseguiFilter.read(buffer, offset, adjustedSize) uno o più
volte.I dati vengono copiati dal MQ dell'HAL al buffer client. |
Il flusso secondario del protocollo filtrato con l'intestazione del protocollo è compilato FMQ. | |
IP.PAYLOAD_THROUGH TLV.PAYLOAD_THROUGH ALP.PAYLOAD_THROUGH |
N/D | Facoltativo:DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW
|
Il payload del protocollo filtrato alimenta il filtro successivo nel filtro o la catena di fornitura. | N/D |
Flusso di esempio per utilizzare il filtro per creare PSI/SI
Figura 10. Flusso per la creazione di PSI/SI
Apri un filtro.
Filter filter = tuner.openFilter( Filter.TYPE_TS, Filter.SUBTYPE_SECTION, /* bufferSize */1000, executor, filterCallback );
Configura e avvia il filtro.
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();
Elabora
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); } } } };
Flusso di esempio per l'utilizzo di MediaEvent dal filtro
Figura 11. Flusso per utilizzare MediaEvent dal filtro
- Apri, configura e avvia i filtri A/V.
- Elabora
MediaEvent
. - Ricevi
MediaEvent
. - Metti in coda il blocco lineare in
codec
. - Rilascia l'handle A/V una volta consumati i dati.
Android.media.tv.tuner.dvr
DvrRecorder
fornisce questi metodi per la registrazione.
configure
attachFilter
detachFilter
start
flush
stop
setFileDescriptor
write
DvrPlayback
offre questi metodi per la riproduzione.
configure
start
flush
stop
setFileDescriptor
read
DvrSettings
viene utilizzato per configurare DvrRecorder
e DvrPlayback
.
OnPlaybackStatusChangedListener
e OnRecordStatusChangedListener
sono in uso
per segnalare lo stato di un'istanza DVR.
Flusso di esempio per avviare un record
Figura 12. Flusso per avviare un record
Apri, configura e avvia
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();
Ricevi
RecordEvent
e recupera le informazioni dell'indice.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. } } } };
Inizializza
OnRecordStatusChangedListener
e archivia i dati del record.OnRecordStatusChangedListener listener = new OnRecordStatusChangedListener() { @Override public void onRecordStatusChanged(int status) { // a customized way to consume data efficiently by using status as a hint. if (status == Filter.STATUS_DATA_READY) { recorder.write(size); } } };
HAL per sintonizzatore
L'HAL per l'accordatore è conforme al protocollo HIDL e definisce l'interfaccia tra il framework e l'hardware del fornitore. I fornitori utilizzano l'interfaccia per implementare l'HAL per il sintonizzatore lo utilizza per comunicare con l'implementazione di Tuner HAL.
Moduli
Sintonizzatore HAL 1.0
Moduli | Comandi di base | Controlli specifici del modulo | File HAL |
---|---|---|---|
ITuner |
N/D | frontend(open, getIds, getInfo) , openDemux ,
openDescrambler openLnb
getDemuxCaps |
ITuner.hal |
IFrontend |
setCallback , getStatus e close
| tune , stopTune , scan
stopScan setLnb |
IFrontend.hal IFrontendCallback.hal |
IDemux |
close |
setFrontendDataSource , openFilter , openDvr e getAvSyncHwId
getAvSyncTime , connect / disconnectCiCam |
IDemux.hal |
IDvr |
close , start , stop , configure |
attach/detachFilters , flush e getQueueDesc |
IDvr.hal IDvrCallback.hal |
IFilter |
close , start , stop , configure e 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 |
Sintonizzatore HAL 1.1 (derivato da Sintonizzatore HAL 1.0)
Moduli | Comandi di base | Controlli specifici del modulo | File HAL |
---|---|---|---|
ITuner |
N/D | getFrontendDtmbCapabilities |
@1.1::ITuner.hal |
IFrontend |
tune_1_1 , scan_1_1 e 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 |
Figura 13. Diagramma delle interazioni tra i moduli dell'HAL per il sintonizzatore
Filtra collegamento
L'HAL per l'accordatore supporta il collegamento dei filtri in modo che i filtri possano essere collegati ad altri filtri per più livelli. I filtri seguono le regole riportate di seguito.
- I filtri sono collegati come struttura ad albero. Il percorso di chiusura non è consentito.
- Il nodo radice è demux.
- I filtri funzionano in modo indipendente.
- Tutti i filtri iniziano a ricevere dati.
- Il collegamento viene eseguito il flush dell'ultimo filtro.
Il blocco di codice riportato di seguito e la Figura 14 illustrano un esempio di filtraggio di più elementi diversi strati.
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>)
}
Figura 14. Diagramma di flusso di un collegamento di filtri per più strati
Resource Manager per accordare
Prima di Tuner Resource Manager (TRM), il passaggio tra due app richiedeva lo stesso hardware del sintonizzatore. Il framework TV Input Framework (TIF) ha utilizzato una "vittoria prima ad acquisire" meccanismo di attenzione, il che significa che qualsiasi app riceve la risorsa per prima la conserva. Tuttavia, questo meccanismo potrebbe non essere l'ideale per alcuni casi d'uso complicati.
TRM viene eseguito come servizio di sistema per gestire l'hardware del sintonizzatore, di TVInput
e di CAS
le risorse per le app. TRM utilizza una "vittoria in primo piano" meccanismo di attenzione, che
Calcola la priorità dell'app in base al suo primo piano o allo sfondo
e il tipo di caso d'uso. TRM concede o revoca la risorsa in base a
la priorità. TRM centralizza la gestione delle risorse ATV per trasmissioni, OTT,
e DVR.
Interfaccia TRM
TRM espone le interfacce AIDL in ITunerResourceManager.aidl
per il sintonizzatore
framework, MediaCas
e TvInputHardwareManager
per registrare, richiedere o
di svincolare le risorse.
Le interfacce per la gestione dei clienti sono elencate di seguito.
registerClientProfile(in ResourceClientProfile profile, IResourcesReclaimListener listener, out int[] clientId)
unregisterClientProfile(in int clientId)
Le interfacce per richiedere e rilasciare risorse sono elencate di seguito.
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
Di seguito sono elencate le classi dei clienti e delle richieste.
ResourceClientProfile
ResourcesReclaimListener
TunerFrontendRequest
TunerDemuxRequest
TunerDescramblerRequest
CasSessionRequest
TunerLnbRequest
Priorità del client
TRM calcola la priorità del cliente utilizzando i parametri della sua profilo e il valore di priorità dal file di configurazione. La priorità può essere essere aggiornati anche con un valore di priorità arbitrario dal client.
Parametri nel profilo del cliente
Il TRM recupera l'ID processo da mTvInputSessionId
per decidere se un'app
è un'app in primo piano o in background. Per creare mTvInputSessionId
,
TvInputService.onCreateSession
, oppure TvInputService.onCreateRecordingSession
inizializza una sessione TIS.
mUseCase
indica il caso d'uso della sessione. I casi d'uso predefiniti
elencati di seguito.
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 di configurazione
File di configurazione predefinito
Il file di configurazione predefinito riportato di seguito fornisce valori di priorità per l'uso predefinito d'uso diversi. Gli utenti possono modificare i valori utilizzando un file di configurazione personalizzata.
Caso d'uso | Primo piano | Premessa |
---|---|---|
LIVE |
490 | 400 |
PLAYBACK |
480 | 300 |
RECORD |
600 | 500 |
SCAN |
450 | 200 |
BACKGROUND |
180 | 100 |
File di configurazione personalizzato
I fornitori possono personalizzare il file di configurazione
/vendor/etc/tunerResourceManagerUseCaseConfig.xml
. Questo file è utilizzato
per aggiungere, rimuovere o aggiornare i tipi di caso d'uso e i relativi valori di priorità.
Il file personalizzato può utilizzare
platform/hardware/interfaces/tv/tuner/1.0/config/tunerResourceManagerUseCaseConfigSample.xml
come modello.
Ad esempio, un nuovo caso d'uso di un fornitore è VENDOR_USE_CASE__[A-Z0-9]+, [0 - 1000]
.
Il formato deve seguire
platform/hardware/interfaces/tv/tuner/1.0/config/tunerResourceManagerUseCaseConfig.xsd
.
Valore di priorità arbitrario e valore accettabile
TRM fornisce updateClientPriority
al client per aggiornare il valore arbitrario
valore di priorità e valore accettabile.
Il valore di priorità arbitrario sovrascrive il valore di priorità calcolato
dal tipo di caso d'uso e dall'ID sessione.
Il valore interessante indica quanto è permissivo il comportamento del cliente quando è in è in conflitto con un altro client. Il valore accettabile diminuisce la priorità del cliente prima che il suo valore di priorità venga confrontato con il client impegnativo.
Meccanismo di recupero
Il diagramma seguente mostra in che modo le risorse vengono recuperate e assegnate quando si verifica un conflitto tra le risorse.
Figura 15. Diagramma del meccanismo di recupero in caso di conflitto tra sintonizzatore risorse