Cadre de tuner

Pour Android 11 ou supérieur, vous pouvez utiliser le framework Android Tuner pour diffuser du contenu A/V. Le framework utilise le pipeline matériel des fournisseurs, ce qui le rend adapté aux SoC bas de gamme et haut de gamme. Le cadre fournit un moyen sécurisé de diffuser du contenu A/V protégé par un environnement d'exécution fiable (TEE) et un chemin multimédia sécurisé (SMP), ce qui lui permet d'être utilisé dans un environnement de protection de contenu hautement restreint.

L'interface standardisée entre Tuner et Android CAS permet une intégration plus rapide entre les fournisseurs Tuner et les fournisseurs CAS. L'interface Tuner fonctionne avec MediaCodec et AudioTrack pour créer une solution mondiale pour Android TV. L'interface Tuner prend en charge à la fois la télévision numérique et la télévision analogique sur la base des principales normes de diffusion.

Composants

Pour Android 11, trois composants sont spécifiquement conçus pour la plate-forme TV.

  • Tuner HAL : une interface entre le framework et les fournisseurs
  • API Tuner SDK : une interface entre le framework et les applications
  • Tuner Resource Manager (TRM): Coordonne les ressources matérielles Tuner

Pour Android 11, les composants suivants ont été améliorés.

  • CAS V2
  • TvInputService ou service d'entrée TV (TIS)
  • TvInputManagerService ou service de gestionnaire d'entrée TV (TIMS)
  • MediaCodec ou codec multimédia
  • AudioTrack ou piste audio
  • MediaResourceManager ou gestionnaire de ressources multimédias (MRM)

Organigramme des composants du framework Tuner.

Figure 1. Interactions entre les composants Android TV

Caractéristiques

Frontend prend en charge les normes DTV ci-dessous.

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

L'interface d'Android 12 avec Tuner HAL 1.1 ou supérieur prend en charge la norme DTV ci-dessous.

  • DTMB

Demux prend en charge les protocoles de flux ci-dessous.

  • Flux de transport (TS)
  • Protocole de transport multimédia MPEG (MMTP)
  • Protocole Internet (IP)
  • Valeur de longueur de type (TLV)
  • Protocole de couche liaison ATSC (ALP)

Le désembrouilleur prend en charge les protections de contenu ci-dessous.

  • Chemin multimédia sécurisé
  • Effacer le chemin du média
  • Enregistrement local sécurisé
  • Lecture locale sécurisée

Les API Tuner prennent en charge les cas d'utilisation ci-dessous.

  • Analyse
  • Habitent
  • Relecture
  • Enregistrement

Tuner, MediaCodec et AudioTrack prennent en charge les modes de flux de données ci-dessous.

  • Charge utile ES avec tampon de mémoire vide
  • Charge utile ES avec poignée de mémoire sécurisée
  • Traverser

Conception générale

Le Tuner HAL est défini entre le framework Android et le matériel du fournisseur.

  • Décrit ce que le framework attend du fournisseur et comment le fournisseur peut le faire.
  • Exporte les fonctionnalités du frontend, du démultiplexeur et du désembrouilleur vers le framework via IFrontend , IDemux , IDescrambler , IFilter , IDvr et ILnb .
  • Inclut les fonctions pour intégrer le Tuner HAL avec d'autres composants du framework, tels que MediaCodec et AudioTrack .

Une classe Tuner Java et une classe native sont créées.

  • L'API Tuner Java permet aux applications d'accéder à Tuner HAL via des API publiques.
  • La classe native permet le contrôle des autorisations et la gestion de grandes quantités de données d'enregistrement ou de lecture avec le Tuner HAL.
  • Le module Native Tuner est un pont entre la classe Tuner Java et Tuner HAL.

Une classe TRM est créée.

  • Gère les ressources tuner limitées, telles que les sessions Frontend, LNB, CAS et un périphérique d'entrée TV à partir de l'entrée TV HAL.
  • Applique des règles pour récupérer les ressources insuffisantes des applications. La règle par défaut est la victoire au premier plan.

Media CAS et CAS HAL sont améliorés avec les fonctionnalités ci-dessous.

  • Ouvre des sessions CAS pour différents usages et algorithmes.
  • Prend en charge les systèmes CAS dynamiques, tels que le retrait et l'insertion de CICAM.
  • S'intègre au Tuner HAL en fournissant des jetons de clé.

MediaCodec et AudioTrack sont améliorés avec les fonctionnalités ci-dessous.

  • Prend une mémoire A/V sécurisée comme entrée de contenu.
  • Configuré pour effectuer une synchronisation A/V matérielle en lecture tunnel.
  • Prise en charge configurée pour ES_payload et le mode passthrough.

Conception globale du Tuner HAL.

Figure 2. Schéma des composants de la HAL Tuner

Flux de travail global

Les schémas ci-dessous illustrent les séquences d'appels pour la diffusion en direct.

Installer

Séquence de configuration du diagramme de lecture de diffusion en direct.

Figure 3. Séquence de configuration pour la diffusion en direct

Gestion A/V

Gestion A/V pour le schéma de lecture de diffusion en direct.

Figure 4. Gestion A/V pour la diffusion en direct

Gestion du contenu brouillé

Gestion du contenu brouillé pour le diagramme de lecture de diffusion en direct.

Figure 5. Traitement du contenu crypté pour la diffusion en direct

Traitement des données A/V

Traiter les données A/V pour le diagramme de lecture de diffusion en direct.

Figure 6. Traitement A/V pour la diffusion en direct

API du SDK Tuner

L'API Tuner SDK gère les interactions avec Tuner JNI, Tuner HAL et TunerResourceManager . L'application TIS utilise l'API Tuner SDK pour accéder aux ressources et sous-composants Tuner tels que le filtre et le désembrouilleur. Le frontend et le démultiplexeur sont des composants internes.

Organigramme de l'API Tuner SDK.

Figure 7. Interactions avec l'API Tuner SDK

Versions

À partir d'Android 12, l'API Tuner SDK prend en charge une nouvelle fonctionnalité dans Tuner HAL 1.1, qui est une mise à niveau de version rétrocompatible de Tuner 1.0.

Utilisez l'API suivante pour vérifier la version HAL en cours d'exécution.

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

La version HAL minimale requise peut être trouvée dans la documentation des nouvelles API Android 12.

Paquets

L'API Tuner SDK fournit les quatre packages ci-dessous.

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

Organigramme des packages API Tuner SDK.

Figure 8. Packages API Tuner SDK

Android.media.tv.tuner

Le package Tuner est un point d'entrée pour utiliser le framework Tuner. L'application TIS utilise le package pour initialiser et acquérir des instances de ressource en spécifiant le paramètre initial et le rappel.

  • tuner() : Initialise une instance Tuner en spécifiant les paramètres useCase et sessionId .
  • tune() : acquiert une ressource frontale et s'accorde en spécifiant le paramètre FrontendSetting .
  • openFilter() : acquiert une instance de filtre en spécifiant le type de filtre.
  • openDvrRecorder() : acquiert une instance d'enregistrement en spécifiant la taille de la mémoire tampon.
  • openDvrPlayback() : acquiert une instance de lecture en spécifiant la taille du tampon.
  • openDescrambler() : Acquiert une instance de désembrouilleur.
  • openLnb() : Acquiert une instance LNB interne.
  • openLnbByName() : Acquiert une instance LNB externe.
  • openTimeFilter() : Acquiert une instance de filtre temporel.

Le package Tuner fournit des fonctionnalités qui ne sont pas couvertes par les packages filtre, DVR et frontal. Les fonctionnalités sont listées ci-dessous.

  • cancelTuning
  • scan / cancelScanning
  • getAvSyncHwId
  • getAvSyncTime
  • connectCiCam1 / disconnectCiCam
  • shareFrontendFromTuner
  • updateResourcePriority
  • setOnTuneEventListener
  • setResourceLostListener

Android.media.tv.tuner.frontend

Le package frontal comprend des ensembles de paramètres, d'informations, d'états, d'événements et de fonctionnalités liés au frontal.

Des classes

FrontendSettings est dérivé pour différentes normes DTV par les classes ci-dessous.

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

À partir d'Android 12 avec Tuner HAL 1.1 ou supérieur, la norme DTV suivante est prise en charge.

  • DtmbFrontendSettings

FrontendCapabilities est dérivé pour différentes normes DTV par les classes ci-dessous.

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

À partir d'Android 12 avec Tuner HAL 1.1 ou supérieur, la norme DTV suivante est prise en charge.

  • DtmbFrontendCapabilities

FrontendInfo récupère les informations du frontend. FrontendStatus récupère l'état actuel du frontend. OnTuneEventListener écoute les événements sur le frontend. L'application TIS utilise ScanCallback pour traiter les messages d'analyse du frontend.

Balayage des canaux

Pour configurer un téléviseur, l'application analyse les fréquences possibles et crée une liste de chaînes accessible aux utilisateurs. TIS peut utiliser Tuner.tune , Tuner.scan(BLIND_SCAN) ou Tuner.scan(AUTO_SCAN) pour terminer le balayage des chaînes.

Si TIS dispose d'informations de livraison précises pour le signal, telles que la fréquence, la norme (par exemple, T/T2, S/S2) et des informations supplémentaires nécessaires (par exemple, PLD ID), alors Tuner.tune est recommandé comme option plus rapide. .

Lorsque l'utilisateur appelle Tuner.tune , les actions suivantes se produisent :

  • TIS remplit FrontendSettings avec les informations requises à l'aide Tuner.tune .
  • Le HAL signale des messages LOCKED si le signal est verrouillé.
  • TIS utilise Frontend.getStatus pour collecter les informations nécessaires.
  • TIS passe à la prochaine fréquence disponible dans sa liste de fréquences.

TIS appelle à nouveau Tuner.tune jusqu'à ce que toutes les fréquences soient épuisées.

Pendant le réglage, vous pouvez appeler stopTune() ou close() pour mettre en pause ou terminer l'appel Tuner.tune .

Tuner.scan(AUTO_SCAN)

Si TIS ne dispose pas de suffisamment d'informations pour utiliser Tuner.tune , mais dispose d'une liste de fréquences et d'un type standard (par exemple, DVB T/C/S), alors Tuner.scan(AUTO_SCAN) est recommandé.

Lorsque l'utilisateur appelle Tuner.scan(AUTO_SCAN) , les actions suivantes se produisent :

  • TIS utilise Tuner.scan(AUTO_SCAN) avec FrontendSettings rempli de fréquence.

  • Les rapports HAL scannent les messages LOCKED si le signal est verrouillé. La couche HAL peut également signaler d'autres messages d'analyse pour fournir des informations supplémentaires sur le signal.

  • TIS utilise Frontend.getStatus pour collecter les informations nécessaires.

  • TIS appelle Tuner.scan pour que HAL passe au réglage suivant sur la même fréquence. Si la structure FrontendSettings est vide, HAL utilise le prochain paramètre disponible. Sinon, HAL utilise FrontendSettings pour une analyse unique et envoie END pour indiquer que l'opération d'analyse est terminée.

  • TIS répète les actions ci-dessus jusqu'à ce que tous les réglages de la fréquence soient épuisés.

  • Le HAL envoie END pour indiquer que l'opération de balayage est terminée.

  • TIS passe à la prochaine fréquence disponible dans sa liste de fréquences.

TIS appelle Tuner.scan(AUTO_SCAN) jusqu'à ce que toutes les fréquences soient épuisées.

Pendant l'analyse, vous pouvez appeler stopScan() ou close() pour mettre en pause ou terminer l'analyse.

Tuner.scan(BLIND_SCAN)

Si TIS n'a pas de liste de fréquences et que le fournisseur HAL peut rechercher la fréquence de l'interface spécifiée par l'utilisateur pour obtenir la ressource d'interface, alors Tuner.scan(BLIND_SCAN) est recommandé.

  • TIS utilise Tuner.scan(BLIND_SCAN) . Une fréquence peut être spécifiée dans FrontendSettings pour la fréquence de démarrage, mais TIS ignore les autres paramètres dans FrontendSettings .
  • Le HAL signale un message de balayage LOCKED si le signal est verrouillé.
  • TIS utilise Frontend.getStatus pour collecter les informations nécessaires.
  • TIS appelle à nouveau Tuner.scan pour continuer la numérisation. ( FrontendSettings est ignoré.)
  • TIS répète les actions ci-dessus jusqu'à ce que tous les réglages de la fréquence soient épuisés. Le HAL incrémente la fréquence sans action nécessaire de TIS. La HAL signale PROGRESS .

TIS appelle Tuner.scan(AUTO_SCAN) jusqu'à ce que toutes les fréquences soient épuisées. Le HAL signale END pour indiquer que l'opération de balayage est terminée.

Pendant l'analyse, vous pouvez appeler stopScan() ou close() pour mettre en pause ou terminer l'analyse.

Organigramme du processus TIS Scan.

Figure 9. Organigramme d'une analyse TIS

Android.media.tv.tuner.filter

Le package de filtre est une collection d'opérations de filtre ainsi que la configuration, les paramètres, les rappels et les événements. Le package comprend les opérations ci-dessous. Reportez-vous au code source Android pour la liste complète des opérations.

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

Reportez-vous au code source Android pour la liste complète.

FilterConfiguration est dérivé des classes ci-dessous. Les configurations concernent le type de filtre principal et elles spécifient le protocole utilisé par le filtre pour extraire les données.

  • AlpFilterConfiguration
  • IpFilterConfiguration
  • MmtpFilterConfiguration
  • TlvFilterConfiguration
  • TsFilterConfiguration

Les paramètres sont dérivés des classes ci-dessous. Les paramètres concernent le sous-type de filtre et spécifient les types de données que le filtre peut exclure.

  • SectionSettings
  • AvSettings
  • PesSettings
  • RecordSettings
  • DownloadSettings

FilterEvent est dérivé des classes ci-dessous pour signaler des événements pour différents types de données.

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

À partir d'Android 12 avec Tuner HAL 1.1 ou supérieur, les événements suivants sont pris en charge.

  • IpCidChangeEvent
  • RestartEvent
  • ScramblingStatusEvent
Événements et format de données du filtre
Type de filtre Drapeaux Événements Opération de données Format de données
TS.SECTION
MMTP.SECTION
IP.SECTION
TLV.SECTION
ALP.SECTION
isRaw:
true
Obligatoire:
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW

Conseillé:
DemuxFilterStatus::LOW_WATER
DemuxFilterStatus::HIGH_WATER
Selon l'événement et le calendrier interne, exécutez
Filter.read(buffer, offset, adjustedSize) une ou plusieurs fois.

Les données sont copiées du MQ de HAL vers le tampon client.
Un paquet de session assemblé est rempli dans FMQ par un autre paquet de session.
isRaw:
false
Obligatoire:
DemuxFilterEvent::DemuxFilterSectionEvent[n]
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW

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


Les données sont copiées du MQ de HAL vers le tampon client.
TS.PES isRaw:
true
Obligatoire:
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW

Conseillé:
DemuxFilterStatus::LOW_WATER
DemuxFilterStatus::HIGH_WATER
Selon l'événement et le calendrier interne, exécutez
Filter.read(buffer, offset, adjustedSize) une ou plusieurs fois.

Les données sont copiées du MQ de HAL vers le tampon client.
Un package PES assemblé est rempli en FMQ par un autre package PES.
isRaw:
false
Obligatoire:
DemuxFilterEvent::DemuxFilterPesEvent[n]
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW

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


Les données sont copiées du MQ de HAL vers le tampon client.
MMTP.PES isRaw:
true
Obligatoire:
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW

Conseillé:
DemuxFilterStatus::LOW_WATER
DemuxFilterStatus::HIGH_WATER
Selon l'événement et le calendrier interne, exécutez
Filter.read(buffer, offset, adjustedSize) une ou plusieurs fois.

Les données sont copiées du MQ de HAL vers le tampon client.
Un package MFU assemblé est rempli en FMQ par un autre package MFU.
isRaw:
false
Obligatoire:
DemuxFilterEvent::DemuxFilterPesEvent[n]
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW

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


Les données sont copiées du MQ de HAL vers le tampon client.
TS.TS
N / A Obligatoire:
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW

Conseillé:
DemuxFilterStatus::LOW_WATER
DemuxFilterStatus::HIGH_WATER
Selon l'événement et le calendrier interne, exécutez
Filter.read(buffer, offset, adjustedSize) une ou plusieurs fois.

Les données sont copiées du MQ de HAL vers le tampon client.
Filtrer les ts avec l'en-tête ts
est rempli en FMQ.
TS.Audio
TS.Video
MMTP.Audio
MMTP.Video
isPassthrough:
true
Optionnel:
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW
Le client peut démarrer MediaCodec après avoir reçu DemuxFilterStatus::DATA_READY .
Le client peut appeler Filter.flush après avoir reçu DemuxFilterStatus::DATA_OVERFLOW .
N / A
isPassthrough:
false
Obligatoire:
DemuxFilterEvent::DemuxFilterMediaEvent[n]
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW

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


Pour utiliser le Direct Audio d' AudioTrack :
for i=0; i<n; i++
audioHandle = MediaEvent[i].getAudioHandle();
audiotrack.write(encapsulated(audiohandle))
Données ES ou ES partielles dans la mémoire ION.
TS.PCR
IP.NTP
ALP.PTP
N / A Obligatoire : N/A
Facultatif : N/A
N / A N / A
TS.RECORD N / A Obligatoire:
DemuxFilterEvent::DemuxFilterTsRecordEvent[n]
RecordStatus::DATA_READY
RecordStatus::DATA_OVERFLOW
RecordStatus::LOW_WATER
RecordStatus::HIGH_WATER

Optionnel:
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW
DemuxFilterStatus::LOW_WATER
DemuxFilterStatus::HIGH_WATER
Pour les données d'index :
for i=0; i<n; i++
DemuxFilterTsRecordEvent[i];


Pour le contenu enregistré , selon RecordStatus::* et le calendrier interne, effectuez l'une des opérations suivantes :
  • Exécutez DvrRecord.write(adustedSize) une ou plusieurs fois vers le stockage.
    Les données sont transférées du MQ de HAL vers le stockage.
  • Exécutez DvrRecord.write(buffer, adustedSize) une ou plusieurs fois pour mettre en mémoire tampon.
    Les données sont copiées du MQ de HAL vers le tampon client.
Pour les données d'index : transportées dans la charge utile de l'événement.

Pour le contenu enregistré : Flux TS multiplexé rempli en FMQ.
TS.TEMI N / A Obligatoire:
DemuxFilterEvent::DemuxFilterTemiEvent[n]

Optionnel:
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 Obligatoire:
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW

Conseillé:
DemuxFilterStatus::LOW_WATER
DemuxFilterStatus::HIGH_WATER
Selon l'événement et le calendrier interne, exécutez
Filter.read(buffer, offset, adjustedSize) une ou plusieurs fois.

Les données sont copiées du MQ de HAL vers le tampon client.
mmtp filtré avec en-tête mmtp
est rempli en FMQ.
MMTP.RECORD N / A Obligatoire:
DemuxFilterEvent::DemuxFilterMmtpRecordEvent[n]
RecordStatus::DATA_READY
RecordStatus::DATA_OVERFLOW
RecordStatus::LOW_WATER
RecordStatus::HIGH_WATER

Optionnel:
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW
DemuxFilterStatus::LOW_WATER
DemuxFilterStatus::HIGH_WATER
Pour les données d'index : for i=0; i<n; i++
DemuxFilterMmtpRecordEvent[i];


Pour le contenu enregistré , selon RecordStatus::* et le calendrier interne, effectuez l'une des opérations suivantes :
  • Exécutez DvrRecord.write(adjustedSize) une ou plusieurs fois vers le stockage.
    Les données sont transférées du MQ de HAL vers le stockage.
  • Exécutez DvrRecord.write(buffer, adjustedSize) une ou plusieurs fois pour mettre en mémoire tampon.
    Les données sont copiées du MQ de HAL vers le tampon client.
Pour les données d'index : transportées dans la charge utile de l'événement.

Pour le contenu enregistré : flux enregistré multiplexé rempli en FMQ.

Si la source du filtre pour l'enregistrement est TLV.TLV vers IP.IP avec relais, le flux enregistré a un en-tête TLV et IP.
MMTP.DOWNLOAD N / A Obligatoire:
DemuxFilterEvent::DemuxFilterDownloadEvent[n]
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW

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

Les données sont copiées du MQ de HAL vers le tampon client.
Le package de téléchargement est rempli dans FMQ par un autre package de téléchargement IP.
IP.IP_PAYLOAD N / A Obligatoire:
DemuxFilterEvent::DemuxFilterIpPayloadEvent[n]
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW

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

Les données sont copiées du MQ de HAL vers le tampon client.
Le package de charge utile IP est rempli dans FMQ par un autre package de charge utile IP.
IP.IP
TLV.TLV
ALP.ALP
isPassthrough:
true
Optionnel:
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW
Le sous-flux de protocole filtré alimente le filtre suivant dans la chaîne de filtres. N / A
isPassthrough:
false
Obligatoire:
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW

Conseillé:
DemuxFilterStatus::LOW_WATER
DemuxFilterStatus::HIGH_WATER
Selon l'événement et le calendrier interne, exécutez
Filter.read(buffer, offset, adjustedSize) une ou plusieurs fois.

Les données sont copiées du MQ de HAL vers le tampon client.
Le sous-flux de protocole filtré avec en-tête de protocole est rempli dans FMQ.
IP.PAYLOAD_THROUGH
TLV.PAYLOAD_THROUGH
ALP.PAYLOAD_THROUGH
N / A Optionnel:
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW
La charge utile de protocole filtrée alimente le filtre suivant dans la chaîne de filtres. N / A
Exemple de flux pour utiliser un filtre pour construire PSI/SI

Exemple de flux pour l'utilisation d'un filtre pour construire PSI/SI.

Figure 10. Flux pour construire PSI/SI

  1. Ouvrez un filtre.

    Filter filter = tuner.openFilter(
      Filter.TYPE_TS,
      Filter.SUBTYPE_SECTION,
      /* bufferSize */1000,
      executor,
      filterCallback
    );
    
  2. Configurez et démarrez le filtre.

    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. Traiter l' SectionEvent de section .

    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); }
          }
        }
    };
    
Exemple de flux pour utiliser MediaEvent à partir du filtre

Exemple de flux pour utiliser MediaEvent à partir du filtre.

Figure 11. Flux pour utiliser MediaEvent à partir du filtre

  1. Ouvrez, configurez et démarrez les filtres A/V.
  2. Traiter MediaEvent .
  3. Recevoir MediaEvent .
  4. Mettez le bloc linéaire en file d'attente dans le codec .
  5. Relâchez la poignée A/V lorsque les données ont été consommées.

Android.media.tv.tuner.dvr

DvrRecorder fournit ces méthodes d'enregistrement.

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

DvrPlayback fournit ces méthodes de lecture.

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

DvrSettings est utilisé pour configurer DvrRecorder et DvrPlayback . OnPlaybackStatusChangedListener et OnRecordStatusChangedListener sont utilisés pour signaler l'état d'une instance DVR.

Exemple de flux pour démarrer un enregistrement

Exemple de flux pour démarrer un enregistrement.

Figure 12. Flux pour démarrer un enregistrement

  1. Ouvrez, configurez et démarrez 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. Recevez RecordEvent et récupérez les informations d'index.

    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. Initialisez OnRecordStatusChangedListener et stockez les données d'enregistrement.

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

Syntoniseur HAL

Le Tuner HAL suit HIDL et définit l'interface entre le framework et le matériel du fournisseur. Les fournisseurs utilisent l'interface pour implémenter Tuner HAL et le framework l'utilise pour communiquer avec l'implémentation Tuner HAL.

Modules

Syntoniseur HAL 1.0

Modules Commandes de base Contrôles spécifiques au module Fichiers 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 CiCam 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 (dérivé du tuner HAL 1.0)

Modules Commandes de base Contrôles spécifiques au module Fichiers 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

Organigramme des interactions entre les modules du Tuner HAL.

Figure 13. Schéma des interactions entre les modules Tuner HAL

Liaison de filtre

Le tuner HAL prend en charge la liaison de filtres de sorte que les filtres peuvent être liés à d'autres filtres pour plusieurs couches. Les filtres suivent les règles ci-dessous.

  • Les filtres sont liés sous forme d'arborescence, le chemin de fermeture n'est pas autorisé.
  • Le nœud racine est démultiplexé.
  • Les filtres fonctionnent indépendamment.
  • Tous les filtres commencent à obtenir des données.
  • La tringlerie du filtre se vide sur le dernier filtre.

Le bloc de code ci-dessous et la figure 14 illustrent un exemple de filtrage de plusieurs couches.

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

Schéma d'un exemple de liaison de filtre.

Figure 14. Organigramme d'une liaison de filtre pour plusieurs couches

Gestionnaire de ressources tuner

Avant Tuner Resource Manager (TRM), le basculement entre deux applications nécessitait le même matériel Tuner. TV Input Framework (TIF) utilisait un mécanisme de "première acquisition gagnante", ce qui signifie que l'application qui obtient la ressource en premier conserve la ressource. Cependant, ce mécanisme peut ne pas être idéal pour certains cas d'utilisation compliqués.

TRM s'exécute en tant que service système pour gérer les ressources matérielles Tuner, TVInput et CAS pour les applications. TRM utilise un mécanisme de « gain de premier plan », qui calcule la priorité de l'application en fonction du statut de premier plan ou d'arrière-plan de l'application et du type de cas d'utilisation. TRM accorde ou révoque la ressource en fonction de la priorité. TRM centralise la gestion des ressources ATV pour la diffusion, l'OTT et le DVR.

Interface TRM

TRM expose les interfaces AIDL dans ITunerResourceManager.aidl pour le framework Tuner, MediaCas et TvInputHardwareManager pour enregistrer, demander ou libérer des ressources.

Les interfaces de gestion des clients sont répertoriées ci-dessous.

  • registerClientProfile(in ResourceClientProfile profile, IResourcesReclaimListener listener, out int[] clientId)
  • unregisterClientProfile(in int clientId)

Les interfaces pour demander et libérer des ressources sont répertoriées ci-dessous.

  • 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

Les classes de client et de demande sont répertoriées ci-dessous.

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

Priorité client

TRM calcule la priorité du client en utilisant les paramètres du profil du client et la valeur de priorité du fichier de configuration. La priorité peut également être mise à jour par une valeur de priorité arbitraire du client.

Paramètres dans le profil du client

TRM récupère l'ID de processus à partir de mTvInputSessionId pour décider si une application est une application de premier plan ou d'arrière-plan. Pour créer mTvInputSessionId , TvInputService.onCreateSession ou TvInputService.onCreateRecordingSession initialise une session TIS.

mUseCase indique le cas d'utilisation de la session. Les cas d'utilisation prédéfinis sont répertoriés ci-dessous.

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
}

Fichier de configuration

Fichier de configuration par défaut

Le fichier de configuration par défaut ci-dessous fournit des valeurs de priorité pour des cas d'utilisation prédéfinis. Les utilisateurs peuvent modifier les valeurs à l'aide d'un fichier de configuration personnalisé .

Cas d'utilisation Premier plan Fond
LIVE 490 400
PLAYBACK 480 300
RECORD 600 500
SCAN 450 200
BACKGROUND 180 100
Fichier de configuration personnalisé

Les fournisseurs peuvent personnaliser le fichier de configuration /vendor/etc/tunerResourceManagerUseCaseConfig.xml . Ce fichier est utilisé pour ajouter, supprimer ou mettre à jour les types de cas d'utilisation et les valeurs de priorité des cas d'utilisation. Le fichier personnalisé peut utiliser platform/hardware/interfaces/tv/tuner/1.0/config/tunerResourceManagerUseCaseConfigSample.xml comme modèle.

Par exemple, un nouveau cas d'utilisation fournisseur est VENDOR_USE_CASE__[A-Z0-9]+, [0 - 1000] . Le format doit suivre platform/hardware/interfaces/tv/tuner/1.0/config/tunerResourceManagerUseCaseConfig.xsd .

Valeur de priorité arbitraire et valeur agréable

TRM fournit updateClientPriority pour que le client mette à jour la valeur de priorité arbitraire et la valeur nice. La valeur de priorité arbitraire remplace la valeur de priorité calculée à partir du type de cas d'utilisation et de l'ID de session.

La valeur nice indique à quel point le comportement du client est indulgent lorsqu'il est en conflit avec un autre client. La valeur agréable diminue la valeur de priorité du client avant que sa valeur de priorité ne soit comparée au client difficile.

Mécanisme de récupération

Le diagramme ci-dessous montre comment les ressources sont récupérées et affectées lorsqu'un conflit de ressources se produit.

Schéma du processus du mécanisme de récupération.

Figure 15. Schéma du mécanisme de récupération en cas de conflit entre ressources Tuner