Pour Android 11 ou version ultérieure, vous pouvez utiliser le framework Android Tuner pour diffuser des contenus 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 framework fournit un moyen sécurisé de diffuser du contenu A/V protégé par un environnement d'exécution sécurisé (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 de Tuner et de CAS. L'interface du tuner fonctionne avec MediaCodec
et AudioTrack
pour créer une solution mondiale pour Android TV.
L'interface du tuner est compatible avec la télévision numérique et la télévision analogique, en fonction des principales normes de diffusion.
Composants
Pour Android 11, trois composants sont spécifiquement conçus pour la plate-forme TV.
- Tuner HAL:interface entre le framework et les fournisseurs
- API du SDK Tuner:interface entre le framework et les applications
- Gestionnaire de ressources du tuner (TRM) : coordonne les ressources matérielles du 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 TV Input Manager (TIMS)MediaCodec
ou codec multimédiaAudioTrack
ou piste audioMediaResourceManager
ou Media Resource Manager (MRM)
Figure 1 : Interactions entre les composants Android TV
Fonctionnalités
L'interface est compatible avec les normes DTV ci-dessous.
- ATSC
- ATSC3
- DVB C/S/T
- ISDB S/S3/T
- Analogique
La partie frontale d'Android 12 avec Tuner HAL 1.1 ou version ultérieure est compatible avec la norme DTV ci-dessous.
- DTMB
Le démultiplexeur est compatible avec les protocoles de flux ci-dessous.
- Flux de transport (TS)
- Protocole MMTP (MPEG media transport protocol)
- Protocole Internet (IP)
- Valeur de longueur de type (TLV)
- Protocole de couche liaison ATSC (ALP)
Le décodeur est compatible avec les protections de contenu ci-dessous.
- Chemin multimédia sécurisé
- Effacer le chemin d'accès aux fichiers multimédias
- Enregistrement local sécurisé
- Lecture locale sécurisée
Les API Tuner sont compatibles avec les cas d'utilisation ci-dessous.
- Analyser
- En direct
- Lecture
- Enregistrer
Le tuner, MediaCodec
et AudioTrack
sont compatibles avec les modes de flux de données ci-dessous.
- Charge utile ES avec mémoire tampon claire
- Charge utile ES avec gestionnaire de mémoire sécurisé
- Passthrough
Aspect général
Le HAL du tuner 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écodeur vers le framework via les interfaces
IFrontend
,IDemux
,IDescrambler
,IFilter
,IDvr
etILnb
. - Inclut les fonctions permettant d'intégrer le HAL du tuner à d'autres composants du framework, tels que
MediaCodec
etAudioTrack
.
Une classe Java Tuner et une classe native sont créées.
- L'API Java Tuner permet aux applications d'accéder au HAL de Tuner via des API publiques.
- La classe native permet de contrôler les autorisations et de gérer de grandes quantités de données d'enregistrement ou de lecture avec le HAL du tuner.
- Le module Tuner natif constitue un pont entre la classe Java Tuner et le HAL du Tuner.
Une classe TRM est créée.
- Gère les ressources limitées du tuner, telles que le front-end, le LNB, les sessions CAS et un appareil d'entrée TV à partir du HAL d'entrée TV.
- 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.
Le CAS multimédia et le HAL CAS sont améliorés grâce aux fonctionnalités ci-dessous.
- Ouvre des sessions CAS pour différents usages et algorithmes.
- Compatible avec les systèmes CAS dynamiques, tels que la suppression et l'insertion de contenus CICAM.
- Intégration au HAL du tuner en fournissant des jetons de clé.
MediaCodec
et AudioTrack
sont améliorés avec les fonctionnalités ci-dessous.
- Utilise une mémoire A/V sécurisée en tant qu'entrée de contenu.
- Configuré pour effectuer une synchronisation A/V matérielle en mode lecture en tunnel.
- Prise en charge configurée pour
ES_payload
et le mode passthrough.
Figure 2. Schéma des composants du HAL du tuner
Workflow global
Les schémas ci-dessous illustrent les séquences d'appel pour la lecture d'une diffusion en direct.
Configuration
Figure 3. Configurer la séquence pour la diffusion en direct
Gérer les contenus audio et vidéo
Figure 4. Gérer l'A/V pour la diffusion en direct
Gérer les contenus encodés
Figure 5. Gérer le contenu crypté pour la lecture de diffusions en direct
Traitement des données A/V
Figure 6. Traitement A/V pour la diffusion en direct...
API du SDK Tuner
L'API du SDK du tuner gère les interactions avec le JNI du tuner, le HAL du tuner et TunerResourceManager
. L'application TIS utilise l'API du SDK Tuner pour accéder aux ressources et sous-composants du tuner, tels que le filtre et le décodeur. Le frontend et le démultiplexeur sont des composants internes.
Figure 7. Interactions avec l'API du SDK Tuner
Versions
À partir d'Android 12, l'API du SDK Tuner prend en charge la nouvelle fonctionnalité de Tuner HAL 1.1, qui est une mise à niveau rétrocompatible de Tuner 1.0.
Utilisez l'API suivante pour vérifier la version du HAL en cours d'exécution.
android.media.tv.tuner.TunerVersionChecker.getTunerVersion()
Vous trouverez la version minimale requise de HAL dans la documentation des nouvelles API Android 12.
Packages
L'API du SDK Tuner 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
Figure 8. Packages d'API du SDK Tuner
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 ressources en spécifiant le paramètre initial et le rappel.
tuner()
: initialise une instance de tuner en spécifiant les paramètresuseCase
etsessionId
.tune()
: acquiert une ressource d'interface et la règle en spécifiant le paramètreFrontendSetting
.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 de tampon.openDescrambler()
: acquiert une instance de décodeur.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 de filtre, de DVR et de frontend. Les fonctionnalités sont présentées ci-dessous.
cancelTuning
scan
/cancelScanning
getAvSyncHwId
getAvSyncTime
connectCiCam1
/disconnectCiCam
shareFrontendFromTuner
updateResourcePriority
setOnTuneEventListener
setResourceLostListener
Android.media.tv.tuner.frontend
Le package de frontend inclut des collections de paramètres, d'informations, d'états, d'événements et de fonctionnalités liés au frontend.
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 version ultérieure, 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 version ultérieure, la norme DTV suivante est prise en charge.
DtmbFrontendCapabilities
FrontendInfo
récupère les informations de l'interface utilisateur.
FrontendStatus
récupère l'état actuel du frontend.
OnTuneEventListener
écoute les événements côté client.
L'application TIS utilise ScanCallback
pour traiter les messages de numérisation à partir de l'interface utilisateur.
Recherche de chaînes
Pour configurer un téléviseur, l'application analyse les fréquences possibles et crée une grille de canaux à laquelle les utilisateurs peuvent accéder. TIS peut utiliser Tuner.tune
, Tuner.scan(BLIND_SCAN)
ou Tuner.scan(AUTO_SCAN)
pour effectuer l'analyse des canaux.
Si TIS dispose d'informations de diffusion précises pour le signal, telles que la fréquence, la norme (par exemple, T/T2, S/S2) et d'autres informations nécessaires (par exemple, l'ID PLD), Tuner.tune
est l'option la plus rapide.
Lorsque l'utilisateur appelle Tuner.tune
, les actions suivantes se produisent :
- TIS renseigne
FrontendSettings
avec les informations requises à l'aide deTuner.tune
. - Les rapports HAL ajustent les messages
LOCKED
si le signal est verrouillé. - TIS utilise
Frontend.getStatus
pour collecter les informations nécessaires. - Le TIS passe à la fréquence suivante disponible dans sa liste de fréquences.
TIS appelle à nouveau Tuner.tune
jusqu'à ce que toutes les fréquences soient épuisées.
Lors du réglage, vous pouvez appeler stopTune()
ou close()
pour mettre en pause ou mettre fin à l'appel Tuner.tune
.
Tuner.scan(AUTO_SCAN)
Si le TIS ne dispose pas d'informations suffisantes pour utiliser Tuner.tune
, mais qu'il dispose d'une liste de fréquences et d'un type standard (par exemple, DVB T/C/S), 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)
avecFrontendSettings
rempli de fréquence.Les rapports HAL analysent
LOCKED
messages si le signal est verrouillé. Le HAL peut également signaler d'autres messages de numérisation 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 le HAL passe au paramètre suivant à la même fréquence. Si la structureFrontendSettings
est vide, le HAL utilise le prochain paramètre disponible. Sinon, HAL utiliseFrontendSettings
pour une analyse ponctuelle et envoieEND
pour indiquer que l'opération d'analyse est terminée.TIS répète les actions ci-dessus jusqu'à ce que tous les paramètres de la fréquence soient épuisés.
Le HAL envoie
END
pour indiquer que l'opération d'analyse est terminée.Le TIS passe à la fréquence suivante disponible dans sa liste de fréquences.
TIS appelle de nouveau Tuner.scan(AUTO_SCAN)
jusqu'à ce que toutes les fréquences soient épuisées.
Pendant l'analyse, vous pouvez appeler stopScan()
ou close()
pour suspendre ou arrêter l'analyse.
Tuner.scan(BLIND_SCAN)
Si le TIS ne dispose pas d'une liste de fréquences et que le HAL du fournisseur peut rechercher la fréquence du frontend spécifié par l'utilisateur pour obtenir la ressource de frontend, Tuner.scan(BLIND_SCAN)
est recommandé.
- TIS utilise
Tuner.scan(BLIND_SCAN)
. Une fréquence peut être spécifiée dansFrontendSettings
pour la fréquence de démarrage, mais TIS ignore les autres paramètres dansFrontendSettings
. - Le HAL signale un message d'analyse
LOCKED
si le signal est verrouillé. - TIS utilise
Frontend.getStatus
pour collecter les informations nécessaires. - TIS appelle à nouveau
Tuner.scan
pour continuer l'analyse. (FrontendSettings
est ignoré.) - TIS répète les actions ci-dessus jusqu'à ce que tous les paramètres de la fréquence soient épuisés. Le HAL incrémente la fréquence sans aucune action requise de la part du TIS.
Le HAL signale
PROGRESS
.
TIS appelle de nouveau Tuner.scan(AUTO_SCAN)
jusqu'à ce que toutes les fréquences soient épuisées.
Le HAL signale END
pour indiquer que l'opération d'analyse est terminée.
Pendant l'analyse, vous pouvez appeler stopScan()
ou close()
pour suspendre ou arrêter l'analyse.
Figure 9. Schéma de flux d'une analyse TIS
Android.media.tv.tuner.filter
Le package de filtres est une collection d'opérations de filtrage, ainsi que de configuration, de paramètres, de rappels et d'événements. Le package inclut les opérations ci-dessous. Pour obtenir la liste complète des opérations, consultez le code source Android.
configure()
start()
stop()
flush()
read()
Pour obtenir la liste complète, reportez-vous au code source Android.
FilterConfiguration
est dérivé des classes ci-dessous. Les configurations sont destinées au type de filtre principal et 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 sont destinés au 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 version ultérieure, les événements suivants sont acceptés.
IpCidChangeEvent
RestartEvent
ScramblingStatusEvent
Format des événements et des données à partir du filtre
Type de filtre | Drapeaux | Événements | Opération de données | Format des données |
---|---|---|---|---|
TS.SECTION MMTP.SECTION IP.SECTION TLV.SECTION ALP.SECTION |
isRaw: |
Obligatoire:DemuxFilterStatus::DATA_READY DemuxFilterStatus::DATA_OVERFLOW Recommandation: DemuxFilterStatus::LOW_WATER DemuxFilterStatus::HIGH_WATER |
En fonction de l'événement et de la programmation interne, exécutezFilter.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: |
Obligatoire:DemuxFilterEvent::DemuxFilterSectionEvent[n] DemuxFilterStatus::DATA_READY DemuxFilterStatus::DATA_OVERFLOW Facultatif: DemuxFilterStatus::LOW_WATER DemuxFilterStatus::HIGH_WATER |
for i=0; i<n; i++ Les données sont copiées du MQ de HAL vers le tampon client. |
||
TS.PES |
isRaw: |
Obligatoire:DemuxFilterStatus::DATA_READY DemuxFilterStatus::DATA_OVERFLOW Recommandation: DemuxFilterStatus::LOW_WATER DemuxFilterStatus::HIGH_WATER |
Selon l'événement et la planification interne, exécutez Filter.read(buffer, offset, adjustedSize) une ou plusieurs fois.Les données sont copiées du MQ du HAL vers le tampon client. |
Un paquet PES assemblé est rempli dans FMQ par un autre paquet PES. |
isRaw: |
Obligatoire:DemuxFilterEvent::DemuxFilterPesEvent[n] DemuxFilterStatus::DATA_READY DemuxFilterStatus::DATA_OVERFLOW Facultatif: DemuxFilterStatus::LOW_WATER DemuxFilterStatus::HIGH_WATER |
for i=0; i<n; i++ Les données sont copiées du MQ de HAL vers le tampon client. |
||
MMTP.PES |
isRaw: |
Obligatoire:DemuxFilterStatus::DATA_READY DemuxFilterStatus::DATA_OVERFLOW Recommandation: DemuxFilterStatus::LOW_WATER DemuxFilterStatus::HIGH_WATER |
En fonction de l'événement et de la programmation interne, exécutezFilter.read(buffer, offset, adjustedSize) une ou plusieurs
fois.Les données sont copiées du MQ du HAL vers le tampon client. |
Un paquet MFU assemblé est rempli dans FMQ par un autre paquet MFU. |
isRaw: |
Obligatoire :DemuxFilterEvent::DemuxFilterPesEvent[n] DemuxFilterStatus::DATA_READY DemuxFilterStatus::DATA_OVERFLOW Facultatif : DemuxFilterStatus::LOW_WATER DemuxFilterStatus::HIGH_WATER |
for i=0; i<n; i++ Les données sont copiées du MQ du HAL vers le tampon client. |
||
TS.TS |
N/A | Obligatoire :DemuxFilterStatus::DATA_READY DemuxFilterStatus::DATA_OVERFLOW Recommandé : DemuxFilterStatus::LOW_WATER DemuxFilterStatus::HIGH_WATER |
Selon l'événement et la planification interne, exécutez Filter.read(buffer, offset, adjustedSize) une ou plusieurs fois.Les données sont copiées du MQ du HAL vers le tampon client. |
ts filtré avec l'en-tête ts est renseigné dans FMQ. |
TS.Audio TS.Video MMTP.Audio MMTP.Video |
isPassthrough: |
Facultatif :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: |
Obligatoire :DemuxFilterEvent::DemuxFilterMediaEvent[n] DemuxFilterStatus::DATA_READY DemuxFilterStatus::DATA_OVERFLOW Facultatif : DemuxFilterStatus::LOW_WATER DemuxFilterStatus::HIGH_WATER |
Pour utiliser MediaCodec :for i=0; i<n; i++ Pour utiliser l'audio direct de AudioTrack :for i=0; i<n; i++ |
Données ES ou données 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 Facultatif : DemuxFilterStatus::DATA_READY DemuxFilterStatus::DATA_OVERFLOW DemuxFilterStatus::LOW_WATER DemuxFilterStatus::HIGH_WATER |
Pour les données d'index:for i=0; i<n; i++ Pour le contenu enregistré, en fonction de RecordStatus::* et du calendrier interne, effectuez l'une des opérations suivantes :
|
Pour les données d'index:elles sont transmises dans la charge utile de l'événement. Pour le contenu enregistré:flux TS multiplexé rempli dans FMQ. |
TS.TEMI |
N/A | Obligatoire :DemuxFilterEvent::DemuxFilterTemiEvent[n] Facultatif : DemuxFilterStatus::DATA_READY DemuxFilterStatus::DATA_OVERFLOW DemuxFilterStatus::LOW_WATER DemuxFilterStatus::HIGH_WATER |
for i=0; i<n; i++ |
N/A |
MMTP.MMTP |
N/A | Obligatoire :DemuxFilterStatus::DATA_READY DemuxFilterStatus::DATA_OVERFLOW Recommandé : DemuxFilterStatus::LOW_WATER DemuxFilterStatus::HIGH_WATER |
Selon l'événement et la planification interne, exécutez Filter.read(buffer, offset, adjustedSize) une ou plusieurs fois.Les données sont copiées du MQ du HAL vers le tampon client. |
Le filtre mmtp avec l'en-tête mmtp est rempli dans FMQ. |
MMTP.RECORD |
N/A | Obligatoire:DemuxFilterEvent::DemuxFilterMmtpRecordEvent[n] RecordStatus::DATA_READY RecordStatus::DATA_OVERFLOW RecordStatus::LOW_WATER RecordStatus::HIGH_WATER Facultatif: DemuxFilterStatus::DATA_READY DemuxFilterStatus::DATA_OVERFLOW DemuxFilterStatus::LOW_WATER DemuxFilterStatus::HIGH_WATER |
Pour les données d'index: for i=0; i<n; i++ Pour le contenu enregistré, en fonction de RecordStatus::* et du calendrier interne, effectuez l'une des opérations suivantes:
|
Pour les données d'index:effectuée dans la charge utile de l'événement. Pour le contenu enregistré:flux enregistré avec le mux rempli au format FMQ. Si la source de filtre pour l'enregistrement est TLV.TLV à IP.IP avec passthrough, le flux enregistré comporte un en-tête TLV et IP. |
MMTP.DOWNLOAD |
N/A | Obligatoire:DemuxFilterEvent::DemuxFilterDownloadEvent[n] DemuxFilterStatus::DATA_READY DemuxFilterStatus::DATA_OVERFLOW Facultatif: 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 renseigné 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 Facultatif: 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 paquet de charge utile IP est rempli dans FMQ par un autre paquet de charge utile IP. |
IP.IP TLV.TLV ALP.ALP |
isPassthrough: |
Facultatif :DemuxFilterStatus::DATA_READY DemuxFilterStatus::DATA_OVERFLOW |
Le sous-flux de protocole filtré alimente le prochain filtre de la chaîne de filtres. | N/A |
isPassthrough: |
Obligatoire :DemuxFilterStatus::DATA_READY DemuxFilterStatus::DATA_OVERFLOW Recommandé : DemuxFilterStatus::LOW_WATER DemuxFilterStatus::HIGH_WATER |
Selon l'événement et la planification interne, exécutez Filter.read(buffer, offset, adjustedSize) une ou plusieurs fois.Les données sont copiées du MQ de la HAL au tampon client. |
Le sous-flux de protocole filtré avec l'en-tête de protocole est renseigné dans FMQ. | |
IP.PAYLOAD_THROUGH TLV.PAYLOAD_THROUGH ALP.PAYLOAD_THROUGH |
N/A | Facultatif:DemuxFilterStatus::DATA_READY DemuxFilterStatus::DATA_OVERFLOW |
La charge utile du protocole filtrée alimente le prochain filtre de la chaîne de filtres. | N/A |
Exemple de flux permettant d'utiliser un filtre pour créer des PSI/SI
Figure 10. Flux de création de PSI/SI
Ouvrez un filtre.
Filter filter = tuner.openFilter( Filter.TYPE_TS, Filter.SUBTYPE_SECTION, /* bufferSize */1000, executor, filterCallback );
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();
Traitement de
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); } } } };
Exemple de flux pour utiliser MediaEvent à partir du filtre
Figure 11 : Flux permettant d'utiliser MediaEvent à partir d'un filtre
- Ouvrez, configurez et démarrez les filtres audio/visuels.
- Traitement de
MediaEvent
. - Recevoir
MediaEvent
. - Placez le bloc linéaire dans la file d'attente de
codec
. - Libérez le conteneur A/V une fois que 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 pour la lecture.
configure
start
flush
stop
setFileDescriptor
read
DvrSettings
permet de configurer DvrRecorder
et DvrPlayback
.
OnPlaybackStatusChangedListener
et OnRecordStatusChangedListener
sont utilisés pour signaler l'état d'une instance DVR.
Exemple de procédure pour démarrer un enregistrement
Figure 12. Procédure pour démarrer un enregistrement
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();
Recevoir
RecordEvent
et récupérer les informations d'indexFilterCallback 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. } } } };
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); } } };
Tuner HAL
Le HAL de Tuner suit le HIDL et définit l'interface entre le framework et le matériel du fournisseur. Les fournisseurs utilisent l'interface pour implémenter le HAL du tuner, et le framework l'utilise pour communiquer avec l'implémentation du HAL du tuner.
Modules
Tuner HAL 1.0
Modules | Commandes de base | Commandes 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 |
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é de Tuner HAL 1.0)
Modules | Commandes de base | Commandes 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 |
Figure 13. Schéma des interactions entre les modules HAL du tuner
Association de filtres
Le HAL du tuner prend en charge l'association de filtres afin que les filtres puissent être associés à d'autres filtres pour plusieurs calques. Les filtres respectent les règles ci-dessous.
- Les filtres sont associés sous forme d'arborescence. Le chemin de fermeture n'est pas autorisé.
- Le nœud racine est demux.
- Les filtres fonctionnent indépendamment.
- Tous les filtres commencent à recueillir des données.
- La liaison de filtres est effacée sur le dernier filtre.
Le bloc de code ci-dessous et la figure 14 illustrent un exemple de filtrage de plusieurs calques.
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>)
}
Figure 14. Diagramme de flux d'un lien de filtre pour plusieurs calques
Gestionnaire de ressources du tuner
Avant le Tuner Resource Manager (TRM), le passage d'une application à une autre nécessitait le même matériel de tuner. Le TV Input Framework (TIF) utilisait un mécanisme de "premier arrivé, premier servi", ce qui signifie que l'application qui obtient la ressource en premier la conserve. Toutefois, ce mécanisme n'est peut-être pas idéal pour certains cas d'utilisation complexes.
Le TRM s'exécute en tant que service système pour gérer les ressources matérielles du tuner, de TVInput
et du CAS pour les applications. TRM utilise un mécanisme de "victoire de premier plan", qui calcule la priorité de l'application en fonction de l'état de premier plan ou d'arrière-plan de l'application, et du type de cas d'utilisation. Le TRM accorde ou révoque la ressource en fonction de la priorité. La gestion des risques technologiques centralise la gestion des ressources ATV pour la diffusion, l'OTT et le DVR.
Interface TRM
Le TRM expose des interfaces AIDL dans ITunerResourceManager.aidl
pour que le framework Tuner, MediaCas
et TvInputHardwareManager
puissent enregistrer, demander ou libérer des ressources.
Les interfaces de gestion des clients sont listées ci-dessous.
registerClientProfile(in ResourceClientProfile profile, IResourcesReclaimListener listener, out int[] clientId)
unregisterClientProfile(in int clientId)
Les interfaces permettant de demander et de libérer des ressources sont indiqué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 requête sont listées ci-dessous.
ResourceClientProfile
ResourcesReclaimListener
TunerFrontendRequest
TunerDemuxRequest
TunerDescramblerRequest
CasSessionRequest
TunerLnbRequest
Priorité du client
Le TRM calcule la priorité du client à l'aide des paramètres de son profil et de 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
Le TRM récupère l'ID de processus à partir de mTvInputSessionId
pour déterminer si une application est une application de premier plan ou en arrière-plan. Pour créer mTvInputSessionId
, TvInputService.onCreateSession
ou TvInputService.onCreateRecordingSession
, une session TIS est initialisée.
mUseCase
indique le cas d'utilisation de la session. Les cas d'utilisation prédéfinis sont listé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 les 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 | Arrière-plan |
---|---|---|
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 permet d'ajouter, de supprimer ou de modifier 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, VENDOR_USE_CASE__[A-Z0-9]+, [0 - 1000]
est un nouveau cas d'utilisation de fournisseur.
Le format doit respecter platform/hardware/interfaces/tv/tuner/1.0/config/tunerResourceManagerUseCaseConfig.xsd
.
Valeur de priorité arbitraire et valeur agréable
TRM fournit au client updateClientPriority
pour mettre à jour la valeur de priorité arbitraire et la valeur agréable.
La valeur de priorité arbitraire écrase la valeur de priorité calculée à partir du type de cas d'utilisation et de l'ID de session.
La valeur "nice" indique le niveau de tolérance du comportement du client en cas de conflit avec un autre client. La valeur "nice" diminue la valeur de priorité du client avant que sa valeur de priorité ne soit comparée à celle du client difficile.
Mécanisme de récupération
Le schéma ci-dessous montre comment les ressources sont récupérées et attribuées en cas de conflit de ressources.
Figure 15. Schéma du mécanisme de récupération en cas de conflit entre les ressources du tuner