Quadro sintonizzatore

Per Android 11 o versioni successive, puoi utilizzare il framework Android Tuner per fornire contenuti A/V. Il framework utilizza la pipeline hardware dei fornitori, rendendolo adatto sia per SoC di fascia bassa che di fascia alta. Il framework fornisce un modo sicuro per fornire contenuti A/V protetti da un ambiente di esecuzione affidabile (TEE) e un percorso multimediale sicuro (SMP), consentendone l'utilizzo in un ambiente di protezione dei contenuti altamente limitato.

L'interfaccia standardizzata tra Tuner e Android CAS si traduce in un'integrazione più rapida tra i fornitori di Tuner e i fornitori di CAS. Le opere di interfaccia Tuner con MediaCodec e AudioTrack per costruire una soluzione one mondo 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 progettati specificamente per la piattaforma TV.

  • Tuner HAL: un'interfaccia tra il quadro e venditori
  • Tuner SDK API: un'interfaccia tra il quadro e applicazioni
  • Resource Manager Tuner (TRM): risorse Coordinate sintonizzatore HW

Per Android 11, i seguenti componenti sono stati migliorati.

  • CAS V2
  • TvInputService o TV Servizio di ingresso (TIS)
  • TvInputManagerService o TV Input Service Manager (TIMS)
  • MediaCodec o supporto codec
  • AudioTrack o una traccia audio
  • MediaResourceManager o gestore delle risorse dei media (MRM)

Diagramma di flusso dei componenti del framework Tuner.

Figura 1. Le interazioni fra i componenti della TV Android

Caratteristiche

Il frontend supporta gli standard DTV di seguito.

  • ATSC
  • ATSC3
  • DVB C/S/T
  • ISDB S/S3/T
  • Analogico

Il frontend in Android 12 con sintonizzatore HAL 1.1 o versioni successive supporta lo standard DTV di seguito.

  • DTMB

Demux supporta i seguenti protocolli di streaming.

  • Flusso di trasporto (TS)
  • Protocollo di trasporto multimediale MPEG (MMTP)
  • Protocollo Internet (IP)
  • Tipo valore lunghezza (TLV)
  • Protocollo ATSC a livello di collegamento (ALP)

Descrambler supporta le protezioni dei contenuti di seguito.

  • Percorso multimediale sicuro
  • Cancella percorso multimediale
  • Registrazione locale sicura
  • Riproduzione locale sicura

Le API di sintonizzazione supportano i casi d'uso riportati di seguito.

  • Scansione
  • Abitare
  • Riproduzione
  • Disco

Sintonizzatore, MediaCodec , e AudioTrack sostenere i dati modalità sotto flusso.

  • Payload ES con buffer di memoria pulito
  • Payload ES con handle di memoria sicuro
  • Passthrough

Design generale

Il Tuner HAL è definito tra il framework Android e l'hardware del fornitore.

  • Descrive cosa si aspetta il framework dal fornitore e come il fornitore potrebbe farlo.
  • Esportazioni le funzionalità di frontend, demux e descrambler alla struttura attraverso IFrontend , IDemux , IDescrambler , IFilter , IDvr e ILnb interfacce.
  • Include le funzioni per integrare il sintonizzatore HAL con gli altri componenti del framework, come ad esempio MediaCodec e AudioTrack .

Vengono create una classe Tuner Java e una classe nativa.

  • L'API Tuner Java consente alle app di accedere a Tuner HAL tramite API pubbliche.
  • La classe nativa consente il controllo dei permessi e la gestione di grandi quantità di dati di registrazione o riproduzione con il sintonizzatore HAL.
  • Il modulo Native Tuner è un ponte tra la classe Tuner Java 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 dalle app. La regola predefinita è la vittoria in primo piano.

Media CAS e CAS HAL sono migliorati con le funzionalità seguenti.

  • Apre sessioni CAS per usi e algoritmi diversi.
  • Supporta sistemi CAS dinamici, come la rimozione e l'inserimento di CICAM.
  • Si integra con il sintonizzatore HAL fornendo token chiave.

MediaCodec e AudioTrack sono arricchite con le caratteristiche di seguito.

  • Prende una memoria A/V sicura come input di contenuto.
  • Configurato per eseguire la sincronizzazione A/V hardware nella riproduzione con tunnel.
  • Supporto configurato per ES_payload e la modalità passthrough.

Design generale del sintonizzatore HAL.

Figura 2. Schema dei componenti all'interno del sintonizzatore HAL

Flusso di lavoro generale

I diagrammi seguenti illustrano le sequenze di chiamata per la riproduzione di trasmissioni in diretta.

Impostare

Sequenza di impostazione del diagramma di riproduzione della trasmissione in diretta.

Figura 3. sequenza di installazione per la riproduzione trasmissione in diretta

Gestione A/V

Schema di gestione A/V per la riproduzione di trasmissioni in diretta.

Figura 4. Handling A / V per la riproduzione trasmissione in diretta

Gestione di contenuti criptati

Gestione dei contenuti criptati per il diagramma di riproduzione della trasmissione in diretta.

Figura 5. Gestione di contenuto criptato per la riproduzione trasmissione in diretta

Elaborazione dei dati A/V

Elabora i dati A/V per il diagramma di riproduzione della trasmissione in diretta.

Figura 6. Elaborazione A / V per la riproduzione trasmissione in diretta

Tuner SDK API

L'API sintonizzatore SDK gestisce le interazioni con il sintonizzatore JNI, il sintonizzatore HAL, e TunerResourceManager . L'app TIS utilizza l'API Tuner SDK per accedere alle risorse e ai sottocomponenti Tuner come il filtro e il descrambler. Frontend e demux sono componenti interni.

Diagramma di flusso dell'API Tuner SDK.

Figura 7. Interazioni con l'API sintonizzatore SDK

Versioni

Da Android 12, l'API Tuner SDK supporta la nuova funzionalità in Tuner HAL 1.1, che è un aggiornamento della versione compatibile con le versioni precedenti di Tuner 1.0.

Utilizzare la seguente API per verificare la versione HAL in esecuzione.

  • android.media.tv.tuner.TunerVersionChecker.getTunerVersion()

La versione HAL minima richiesta è disponibile nella documentazione delle nuove API di Android 12.

Pacchetti

L'API Tuner SDK fornisce i quattro pacchetti seguenti.

  • android.media.tv.tuner
  • android.media.tv.tuner.frontend
  • android.media.tv.tuner.filter
  • android.media.tv.tuner.dvr

Diagramma di flusso dei pacchetti dell'API Tuner SDK.

Pacchetti API Figura 8. Tuner SDK

sintonizzatore.media.tv.Android

Il pacchetto Tuner è un punto di ingresso per utilizzare il framework Tuner. L'app TIS usa il pacchetto per inizializzare e acquisire istanze di risorse specificando l'impostazione iniziale e il callback.

  • tuner() : inizializza un'istanza Tuner specificando i useCase e sessionId parametri.
  • tune() : Acquisisce una risorsa frontend e sintonizzare specificando il FrontendSetting parametro.
  • openFilter() : acquisisce un'istanza del filtro specificando il tipo di filtro.
  • openDvrRecorder() : acquista un esempio di registrazione specificando la dimensione del buffer.
  • openDvrPlayback() : acquisisce un'istanza di riproduzione specificando la dimensione del buffer.
  • openDescrambler() : acquisisce un'istanza decodificatore.
  • openLnb() : Acquisisce un'istanza LNB interna.
  • openLnbByName() : Acquisisce un'istanza LNB esterna.
  • openTimeFilter() : acquisisce un'istanza filtro temporale.

Il pacchetto Tuner fornisce funzionalità che non sono coperte dai pacchetti filtro, 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, informazioni, stati, eventi e funzionalità relative al frontend.

Classi

FrontendSettings deriva per diversi standard DTV dalle classi sottostanti.

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

Da Android 12 con sintonizzatore HAL 1.1 o versioni successive, è supportato il seguente standard DTV.

  • DtmbFrontendSettings

FrontendCapabilities deriva per diversi standard DTV dalle classi sottostanti.

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

Da Android 12 con sintonizzatore HAL 1.1 o versioni successive, è supportato il seguente standard DTV.

  • DtmbFrontendCapabilities

FrontendInfo recupera le informazioni del frontend. FrontendStatus recupera lo stato corrente del frontend. OnTuneEventListener ascolta gli eventi sul frontend. Gli usi app TIS ScanCallback per elaborare i messaggi di scansione dal frontend.

Scansione canali

Per configurare una TV, l'app esegue la scansione delle possibili frequenze e crea una scaletta di canali a cui gli utenti possono accedere. TIS potrebbe utilizzare Tuner.tune , Tuner.scan(BLIND_SCAN) , o Tuner.scan(AUTO_SCAN) per la scansione dei canali completa.

Se TIS ha informazioni consegna accurata del segnale, come la frequenza, standard (ad esempio, T / T2, S / S2), e le informazioni necessarie ulteriori (per esempio, PLD ID), quindi Tuner.tune è raccomandato come opzione più veloce .

Quando l'utente chiama Tuner.tune , le seguenti azioni avvengono:

  • TIS popola FrontendSettings con le informazioni richieste utilizzando Tuner.tune .
  • L'HAL riporta tune LOCKED messaggi se il segnale è bloccato.
  • TIS utilizza Frontend.getStatus per raccogliere le informazioni necessarie.
  • TIS passa alla frequenza successiva disponibile nel suo elenco di frequenze.

TIS chiama Tuner.tune nuovo fino a quando tutte le frequenze sono esauriti.

Durante la messa a punto, è possibile chiamare stopTune() o close() per mettere in pausa o terminare la Tuner.tune chiamata.

Sintonizzatore.scan(AUTO_SCAN)

Se TIS non dispone di informazioni sufficienti per utilizzare Tuner.tune , ma ha una lista di frequenze e di tipo standard (ad esempio, DVB T / C / S), quindi Tuner.scan(AUTO_SCAN) è raccomandato.

Quando l'utente chiama Tuner.scan(AUTO_SCAN) , le seguenti azioni avvengono:

  • TIS utilizza Tuner.scan(AUTO_SCAN) con FrontendSettings pieni di frequenza.

  • Le relazioni HAL Scan LOCKED messaggi se il segnale è bloccato. L'HAL potrebbe anche segnalare altri messaggi di scansione per fornire ulteriori informazioni sul segnale.

  • TIS utilizza Frontend.getStatus per raccogliere le informazioni necessarie.

  • TIS chiama Tuner.scan per l'HAL per continuare con la successiva impostazione sulla stessa frequenza. Se la FrontendSettings struttura è vuota, il HAL utilizza successiva disponibile. Altrimenti, HAL utilizza FrontendSettings per la scansione di una volta e invia END per indicare che l'operazione di scansione è terminata.

  • TIS ripete le azioni di cui sopra fino ad esaurire tutte le impostazioni sulla frequenza.

  • Il HAL invia END per indicare che l'operazione di scansione è terminata.

  • TIS passa alla frequenza successiva disponibile nel suo elenco di frequenze.

TIS chiama Tuner.scan(AUTO_SCAN) di nuovo fino a tutte le frequenze sono esauriti.

Durante la scansione, è possibile chiamare stopScan() o close() per mettere in pausa o terminare la scansione.

Tuner.scan(BLIND_SCAN)

Se TIS non dispone di una lista di frequenze e il Venditore HAL può cercare la frequenza del frontend specificata dall'utente per ottenere la risorsa frontend, quindi Tuner.scan(BLIND_SCAN) è raccomandato.

  • TIS utilizza Tuner.scan(BLIND_SCAN) . Una frequenza può essere specificato in FrontendSettings per frequenza di avvio, ma TIS ignora altre impostazioni in FrontendSettings .
  • L'HAL riporta una scansione LOCKED messaggio se il segnale è bloccato.
  • TIS utilizza Frontend.getStatus per raccogliere le informazioni necessarie.
  • TIS chiama Tuner.scan di nuovo per continuare la scansione. ( FrontendSettings viene ignorato.)
  • TIS ripete le azioni di cui sopra fino ad esaurire tutte le impostazioni sulla frequenza. L'HAL incrementa la frequenza senza che sia necessaria alcuna azione da parte di TIS. L'HAL riporta PROGRESS .

TIS chiama Tuner.scan(AUTO_SCAN) di nuovo fino a tutte le frequenze sono esauriti. L'HAL riferisce END per indicare che l'operazione di scansione è terminata.

Durante la scansione, è possibile chiamare stopScan() o close() per mettere in pausa o terminare la scansione.

Diagramma di flusso del processo TIS Scan.

Diagramma Figura 9. flusso di una scansione TIS

Android.media.tv.tuner.filter

Il pacchetto di filtri è una raccolta di operazioni di filtro insieme a configurazione, impostazioni, callback ed eventi. Il pacchetto include le operazioni seguenti. Fare riferimento al codice sorgente di Android per l'elenco completo delle operazioni.

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

Fare riferimento al codice sorgente di Android per l'elenco completo.

FilterConfiguration deriva dalle classi sottostanti. Le configurazioni sono per il tipo di filtro principale e specificano quale protocollo utilizza il filtro per estrarre i dati.

  • AlpFilterConfiguration
  • IpFilterConfiguration
  • MmtpFilterConfiguration
  • TlvFilterConfiguration
  • TsFilterConfiguration

Le impostazioni sono derivate dalle classi seguenti. Le impostazioni riguardano il sottotipo di filtro e specificano i tipi di dati che il filtro può escludere.

  • SectionSettings
  • AvSettings
  • PesSettings
  • RecordSettings
  • DownloadSettings

FilterEvent è derivata dalle classi di seguito agli eventi del report per diversi tipi di dati.

  • SectionEvent
  • MediaEvent
  • PesEvent
  • TsRecordEvent
  • MmtpRecordEvent
  • TemiEvent
  • DownloadEvent
  • IpPayloadEvent

Da Android 12 con Tuner HAL 1.1 o versioni successive, sono supportati i seguenti eventi.

  • IpCidChangeEvent
  • RestartEvent
  • ScramblingStatusEvent
Eventi e formato dati dal filtro
Tipo di filtro bandiere Eventi Operazione dati Formato dei dati
TS.SECTION
MMTP.SECTION
IP.SECTION
TLV.SECTION
ALP.SECTION
isRaw:
true
Obbligatorio:
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW

Consigliato:
DemuxFilterStatus::LOW_WATER
DemuxFilterStatus::HIGH_WATER
In base all'evento e al programma interno, eseguire
Filter.read(buffer, offset, adjustedSize) una o più volte.

I dati vengono copiati dal MQ di HAL al buffer del client.
Un pacchetto di sessione assemblato viene compilato in FMQ da un altro pacchetto di sessione.
isRaw:
false
Obbligatorio:
DemuxFilterEvent::DemuxFilterSectionEvent[n]
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW

Opzionale:
DemuxFilterStatus::LOW_WATER
DemuxFilterStatus::HIGH_WATER
for i=0; i<n; i++
Filter.read(buffer, offset, DemuxFilterSectionEven[i].size)


I dati vengono copiati dal MQ di HAL al buffer del client.
TS.PES isRaw:
true
Obbligatorio:
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW

Consigliato:
DemuxFilterStatus::LOW_WATER
DemuxFilterStatus::HIGH_WATER
In base all'evento e al programma interno, eseguire
Filter.read(buffer, offset, adjustedSize) una o più volte.

I dati vengono copiati dal MQ di HAL al buffer del client.
Un pacchetto PES assemblato viene compilato in FMQ da un altro pacchetto PES.
isRaw:
false
Obbligatorio:
DemuxFilterEvent::DemuxFilterPesEvent[n]
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW

Opzionale:
DemuxFilterStatus::LOW_WATER
DemuxFilterStatus::HIGH_WATER
for i=0; i<n; i++
Filter.read(buffer, offset, DemuxFilterPesEven[i].size)


I dati vengono copiati dal MQ di HAL al buffer del client.
MMTP.PES isRaw:
true
Obbligatorio:
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW

Consigliato:
DemuxFilterStatus::LOW_WATER
DemuxFilterStatus::HIGH_WATER
In base all'evento e al programma interno, eseguire
Filter.read(buffer, offset, adjustedSize) una o più volte.

I dati vengono copiati dal MQ di HAL al buffer del client.
Un pacchetto MFU assemblato viene compilato in FMQ da un altro pacchetto MFU.
isRaw:
false
Obbligatorio:
DemuxFilterEvent::DemuxFilterPesEvent[n]
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW

Opzionale:
DemuxFilterStatus::LOW_WATER
DemuxFilterStatus::HIGH_WATER
for i=0; i<n; i++
Filter.read(buffer, offset, DemuxFilterPesEven[i].size)


I dati vengono copiati dal MQ di HAL al buffer del client.
TS.TS
N / A Obbligatorio:
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW

Consigliato:
DemuxFilterStatus::LOW_WATER
DemuxFilterStatus::HIGH_WATER
In base all'evento e al programma interno, eseguire
Filter.read(buffer, offset, adjustedSize) una o più volte.

I dati vengono copiati dal MQ di HAL al buffer del client.
Filtrati ts con ts intestazione
è compilato in FMQ.
TS.Audio
TS.Video
MMTP.Audio
MMTP.Video
isPassthrough:
true
Opzionale:
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW
Il cliente può iniziare MediaCodec dopo aver ricevuto DemuxFilterStatus::DATA_READY .
Il cliente può chiamare Filter.flush dopo aver ricevuto DemuxFilterStatus::DATA_OVERFLOW .
N / A
isPassthrough:
false
Obbligatorio:
DemuxFilterEvent::DemuxFilterMediaEvent[n]
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW

Opzionale:
DemuxFilterStatus::LOW_WATER
DemuxFilterStatus::HIGH_WATER
Per utilizzare MediaCodec :
for i=0; i<n; i++
linearblock = MediaEvent[i].getLinearBlock();
codec.startQueueLinearBlock(linearblock)
linearblock.recycle()


Per utilizzare Diretta audio di AudioTrack :
for i=0; i<n; i++
audioHandle = MediaEvent[i].getAudioHandle();
audiotrack.write(encapsulated(audiohandle))
Dati ES o ES parziali nella memoria ION.
TS.PCR
IP.NTP
ALP.PTP
N / A Obbligatoria: N / A
Optional: N / A
N / A N / A
TS.RECORD N / A Obbligatorio:
DemuxFilterEvent::DemuxFilterTsRecordEvent[n]
RecordStatus::DATA_READY
RecordStatus::DATA_OVERFLOW
RecordStatus::LOW_WATER
RecordStatus::HIGH_WATER

Opzionale:
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW
DemuxFilterStatus::LOW_WATER
DemuxFilterStatus::HIGH_WATER
Per i dati dell'indice:
for i=0; i<n; i++
DemuxFilterTsRecordEvent[i];


Per contenuti registrati, secondo RecordStatus::* e pianificazione interna, eseguire una delle seguenti operazioni:
  • Run DvrRecord.write(adustedSize) una o più volte per lo stoccaggio.
    I dati vengono trasferiti dal MQ dell'HAL allo storage.
  • Run DvrRecord.write(buffer, adustedSize) una o più volte al buffer.
    I dati vengono copiati dal MQ di HAL al buffer del client.
Per i dati di indice: Portato in payload evento.

Per contenuti registrati: Muxed TS STREAM compilato FMQ.
TS.TEMI N / A Obbligatorio:
DemuxFilterEvent::DemuxFilterTemiEvent[n]

Opzionale:
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW
DemuxFilterStatus::LOW_WATER
DemuxFilterStatus::HIGH_WATER
for i=0; i<n; i++
DemuxFilterTemiEvent[i];
N / A
MMTP.MMTP N / A Obbligatorio:
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW

Consigliato:
DemuxFilterStatus::LOW_WATER
DemuxFilterStatus::HIGH_WATER
In base all'evento e al programma interno, eseguire
Filter.read(buffer, offset, adjustedSize) una o più volte.

I dati vengono copiati dal MQ di HAL al buffer del client.
Filtrato mmtp con mmtp intestazione
è compilato in FMQ.
MMTP.RECORD N / A Obbligatorio:
DemuxFilterEvent::DemuxFilterMmtpRecordEvent[n]
RecordStatus::DATA_READY
RecordStatus::DATA_OVERFLOW
RecordStatus::LOW_WATER
RecordStatus::HIGH_WATER

Opzionale:
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW
DemuxFilterStatus::LOW_WATER
DemuxFilterStatus::HIGH_WATER
Per i dati index: for i=0; i<n; i++
DemuxFilterMmtpRecordEvent[i];


Per contenuti registrati, secondo RecordStatus::* e pianificazione interna, eseguire una delle seguenti operazioni:
  • Run DvrRecord.write(adjustedSize) una o più volte per lo stoccaggio.
    I dati vengono trasferiti dal MQ dell'HAL allo storage.
  • Run DvrRecord.write(buffer, adjustedSize) una o più volte al buffer.
    I dati vengono copiati dal MQ di HAL al buffer del client.
Per i dati di indice: Portato in payload evento.

Per contenuti registrati: Muxed registrato flusso compilato FMQ.

Se l'origine del filtro per la registrazione è TLV.TLV per IP.IP con passthrough, il flusso registrato ha un'intestazione TLV e IP.
MMTP.DOWNLOAD N / A Obbligatorio:
DemuxFilterEvent::DemuxFilterDownloadEvent[n]
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW

Opzionale:
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 di HAL al buffer del client.
Il pacchetto di download è compilato in FMQ da un altro pacchetto di download IP.
IP.IP_PAYLOAD N / A Obbligatorio:
DemuxFilterEvent::DemuxFilterIpPayloadEvent[n]
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW

Opzionale:
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 di HAL al buffer del client.
Il pacchetto payload IP viene compilato in FMQ da un altro pacchetto payload IP.
IP.IP
TLV.TLV
ALP.ALP
isPassthrough:
true
Opzionale:
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW
Il sottoflusso del protocollo filtrato alimenta il filtro successivo nella catena di filtri. N / A
isPassthrough:
false
Obbligatorio:
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW

Consigliato:
DemuxFilterStatus::LOW_WATER
DemuxFilterStatus::HIGH_WATER
In base all'evento e al programma interno, eseguire
Filter.read(buffer, offset, adjustedSize) una o più volte.

I dati vengono copiati dal MQ di HAL al buffer del client.
Il flusso secondario del protocollo filtrato con l'intestazione del protocollo viene compilato in FMQ.
IP.PAYLOAD_THROUGH
TLV.PAYLOAD_THROUGH
ALP.PAYLOAD_THROUGH
N / A Opzionale:
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW
Il payload del protocollo filtrato alimenta il filtro successivo nella catena di filtri. N / A
Esempio di flusso per utilizzare il filtro per creare PSI/SI

Esempio di flusso per l'utilizzo del filtro per creare PSI/SI.

Figura 10. Flusso di costruire PSI / SI

  1. Apri un filtro.

    Filter filter = tuner.openFilter(
      Filter.TYPE_TS,
      Filter.SUBTYPE_SECTION,
      /* bufferSize */1000,
      executor,
      filterCallback
    );
    
  2. 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();
    
  3. Elaborare 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); }
          }
        }
    };
    
Esempio di flusso per utilizzare MediaEvent dal filtro

Flusso di esempio per utilizzare MediaEvent dal filtro.

Figura 11. Flusso di utilizzare MediaEvent dal filtro

  1. Apri, configura e avvia i filtri A/V.
  2. Elaborare MediaEvent .
  3. Ricevere MediaEvent .
  4. Coda il blocco lineare di codec .
  5. Rilasciare l'handle A/V quando i dati sono stati consumati.

Android.media.tv.tuner.dvr

DvrRecorder fornisce questi metodi per la registrazione.

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

DvrPlayback fornisce questi metodi per la riproduzione.

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

DvrSettings viene utilizzato per configurare DvrRecorder e DvrPlayback . OnPlaybackStatusChangedListener e OnRecordStatusChangedListener vengono utilizzati per segnalare lo stato di un'istanza DVR.

Esempio di flusso per avviare un record

Esempio di flusso per avviare un record.

Figura 12. Flusso per avviare un record

  1. Open, configurare e iniziare DvrRecorder .

    DvrRecorder recorder = openDvrRecorder(/* bufferSize */ 1000, executor, listener);
    DvrSettings dvrSettings = DvrSettings
    .builder()
    .setDataFormat(DvrSettings.DATA_FORMAT_TS)
    .setLowThreshold(100)
    .setHighThreshold(900)
    .setPacketSize(188)
    .build();
    recorder.configure(dvrSettings);
    recorder.attachFilter(filter);
    recorder.setFileDescriptor(fd);
    recorder.start();
    
  2. Ricevere RecordEvent e recuperare le informazioni di 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. }
          }
        }
    };
    
  3. Inizializza OnRecordStatusChangedListener e memorizzare 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);
          }
        }
      };
    

Accordatore HAL

Il Tuner HAL segue HIDL e definisce l'interfaccia tra il framework e l'hardware del fornitore. I fornitori utilizzano l'interfaccia per implementare il Tuner HAL e il framework lo utilizza per comunicare con l'implementazione del Tuner HAL.

Moduli

Accordatore HAL 1.0

Moduli Controlli di base Controlli specifici del modulo File HAL
ITuner N / 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 (derivato da Tuner HAL 1.0)

Moduli Controlli di base Controlli specifici del modulo File HAL
ITuner N / 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

Diagramma di flusso delle interazioni tra i moduli del Tuner HAL.

Figura 13. Schema delle interazioni tra i moduli Tuner HAL

Collegamento del filtro

Il Tuner HAL supporta il collegamento dei filtri in modo che i filtri possano essere collegati ad altri filtri per più livelli. I filtri seguono le regole seguenti.

  • I filtri sono collegati come un albero, non è consentito chiudere il percorso.
  • Il nodo radice è demux.
  • I filtri funzionano in modo indipendente.
  • Tutti i filtri iniziano a ricevere dati.
  • Il collegamento del filtro scorre sull'ultimo filtro.

Il blocco di codice sottostante e la Figura 14 illustrano un esempio di filtraggio di più livelli.

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>)
}

Schema di esempio di collegamento del filtro.

Diagramma Figura 14. Flusso di un collegamento filtro per strati multipli

Tuner Resource Manager

Prima di Tuner Resource Manager (TRM), il passaggio tra due app richiedeva lo stesso hardware Tuner. TV Input Framework (TIF) ha utilizzato un meccanismo "first-to-acquisire win", il che significa che qualsiasi app ottiene per prima la risorsa mantiene la risorsa. Tuttavia, questo meccanismo potrebbe non essere l'ideale per alcuni casi d'uso complicati.

TRM viene eseguito come servizio di sistema per la gestione dei Tuner, TVInput risorse hardware, e CAS per le applicazioni. TRM utilizza un meccanismo di "vincita in primo piano", che calcola la priorità dell'app in base allo stato in primo piano o in background dell'app e al tipo di caso d'uso. TRM concede o revoca la risorsa in base alla priorità. TRM centralizza la gestione delle risorse ATV per broadcast, OTT e DVR.

Interfaccia TRM

TRM espone AIDL interfacce ITunerResourceManager.aidl per il quadro Tuner, MediaCas , e TvInputHardwareManager per registrare, risorse richiesta o di rilascio.

Di seguito sono elencate le interfacce per la gestione dei client.

  • 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

Le classi cliente e richiesta sono elencate di seguito.

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

Priorità del cliente

TRM calcola la priorità del client utilizzando i parametri del profilo del client e il valore di priorità del file di configurazione. La priorità potrebbe anche essere aggiornata da un valore di priorità arbitrario dal client.

Parametri nel profilo del cliente

TRM recupera l'ID del processo da mTvInputSessionId per decidere se un app è un primo piano o di sfondo app. Per creare mTvInputSessionId , TvInputService.onCreateSession o TvInputService.onCreateRecordingSession inizializza una sessione di TIS.

mUseCase indica caso d'uso della sessione. I casi d'uso predefiniti sono 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 di seguito fornisce valori di priorità per casi d'uso predefiniti. Gli utenti possono modificare i valori utilizzando un file di configurazione personalizzata .

Caso d'uso Primo piano Sfondo
LIVE 490 400
PLAYBACK 480 300
RECORD 600 500
SCAN 450 200
BACKGROUND 180 100
File di configurazione personalizzato

I venditori possono personalizzare il file di configurazione /vendor/etc/tunerResourceManagerUseCaseConfig.xml . Questo file viene utilizzato per aggiungere, rimuovere o aggiornare i tipi di casi d'uso e i valori di priorità dei casi d'uso. Il file personalizzato può utilizzare platform/hardware/interfaces/tv/tuner/1.0/config/tunerResourceManagerUseCaseConfigSample.xml come modello.

Ad esempio, un nuovo caso d'uso venditore è VENDOR_USE_CASE__[A-Z0-9]+, [0 - 1000] . Il formato dovrebbe seguire platform/hardware/interfaces/tv/tuner/1.0/config/tunerResourceManagerUseCaseConfig.xsd .

Valore di priorità arbitrario e buon valore

TRM prevede updateClientPriority per il cliente di aggiornare il valore di priorità arbitrario e valore nice. Il valore di priorità arbitrario sovrascrive il valore di priorità calcolato dal tipo di caso d'uso e dall'ID di sessione.

Il valore piacevole indica quanto è indulgente il comportamento del cliente quando è in conflitto con un altro cliente. Il valore piacevole riduce il valore di priorità del client prima che il suo valore di priorità venga confrontato con il client impegnativo.

Meccanismo di recupero

Il diagramma seguente mostra come le risorse vengono recuperate e assegnate quando si verifica un conflitto di risorse.

Schema del processo del meccanismo di recupero.

Figura 15. Schema del meccanismo di recupero di un conflitto tra risorse Tuner