Pour Android 11 ou version ultérieure, 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 fournir du contenu audiovisuel protégé par un environnement d'exécution de confiance (TEE) et un chemin multimédia sécurisé (SMP), lui permettant 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 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 plateforme 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 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 de gestion des entrées TV (TIMS) -
MediaCodec
ou codec multimédia -
AudioTrack
ou piste audio -
MediaResourceManager
ou gestionnaire de ressources multimédias (MRM)
Figure 1. Interactions entre les composants d'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 sous 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)
Descrambler prend en charge les protections de contenu ci-dessous.
- Chemin multimédia sécurisé
- Chemin multimédia clair
- Enregistrement local sécurisé
- Lecture locale sécurisée
Les API Tuner prennent en charge les cas d'utilisation ci-dessous.
- Analyse
- En direct
- Relecture
- Enregistrer
Tuner, MediaCodec
et AudioTrack
prennent en charge les modes de flux de données ci-dessous.
- Charge utile ES avec tampon 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émultiplexage et du désembrouilleur vers le framework via les interfaces
IFrontend
,IDemux
,IDescrambler
,IFilter
,IDvr
etILnb
. - Inclut les fonctions permettant d'intégrer le Tuner HAL avec 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 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 le Tuner HAL.
Une classe TRM est créée.
- Gère les ressources limitées du tuner, telles que le frontend, le LNB, les sessions 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 les sessions CAS pour différents usages et algorithmes.
- Prend en charge les systèmes CAS dynamiques, tels que le retrait et l'insertion CICAM.
- S'intègre au Tuner HAL en fournissant des jetons clés.
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 la synchronisation A/V matérielle en lecture tunnelée.
- Prise en charge configurée pour
ES_payload
et le mode passthrough.
Figure 2. Schéma des composants du Tuner HAL
Flux de travail global
Les diagrammes ci-dessous illustrent les séquences d'appel pour la lecture d'une diffusion en direct.
Installation
Figure 3. Séquence de configuration pour la lecture d'une diffusion en direct
Gestion de l'audiovisuel
Figure 4. Gestion de l'A/V pour la lecture d'une diffusion en direct
Gestion du contenu crypté
Figure 5. Gestion du contenu crypté pour la lecture de diffusion en direct
Traitement des données A/V
Figure 6. Traitement A/V pour la lecture d'une diffusion en direct
API du SDK du 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. Frontend et demux sont des composants internes.
Figure 7. Interactions avec l'API du SDK Tuner
Versions
À partir d'Android 12, l'API Tuner SDK prend en charge la nouvelle fonctionnalité de 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 minimale requise de HAL se trouve 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
Figure 8. Packages 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 frontend 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 du 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 de filtre, DVR et frontend. Les fonctionnalités sont répertoriées ci-dessous.
-
cancelTuning
-
scan
/cancelScanning
-
getAvSyncHwId
-
getAvSyncTime
-
connectCiCam1
/disconnectCiCam
-
shareFrontendFromTuner
-
updateResourcePriority
-
setOnTuneEventListener
-
setResourceLostListener
Android.media.tv.tuner.frontend
Le package frontend comprend des ensembles de paramètres, d'informations, de statuts, d'événements et de fonctionnalités liés au frontend.
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 provenant du frontend.
Balayage des chaînes
Pour configurer un téléviseur, l'application analyse les fréquences possibles et crée une gamme de chaînes accessible aux utilisateurs. TIS peut utiliser Tuner.tune
, Tuner.scan(BLIND_SCAN)
ou Tuner.scan(AUTO_SCAN)
pour terminer la numérisation 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, ID PLD), alors Tuner.tune
est recommandé comme option la plus rapide. .
Lorsque l'utilisateur appelle Tuner.tune
, les actions suivantes se produisent :
- TIS remplit
FrontendSettings
avec les informations requises à l'aideTuner.tune
. - Le HAL signale l'accord des messages
LOCKED
si le signal est verrouillé. - TIS utilise
Frontend.getStatus
pour collecter les informations nécessaires. - TIS passe à la fréquence disponible suivante 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 mettre fin à 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)
avecFrontendSettings
rempli de fréquence.Les rapports HAL analysent les messages
LOCKED
si le signal est verrouillé. Le 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 le HAL passe au réglage suivant sur la même fréquence. Si la structureFrontendSettings
est vide, la HAL utilise le paramètre disponible suivant. Sinon, HAL utiliseFrontendSettings
pour une analyse unique 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 réglages sur la fréquence soient épuisés.
Le HAL envoie
END
pour indiquer que l'opération d'analyse est terminée.TIS passe à la fréquence disponible suivante dans sa liste de fréquences.
TIS appelle à 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 terminer l'analyse.
Tuner.scan(BLIND_SCAN)
Si TIS ne dispose pas de liste de fréquences et que le fournisseur HAL peut rechercher la fréquence du frontend spécifié par l'utilisateur pour obtenir la ressource frontend, alors 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 de balayage
LOCKED
si le signal est verrouillé. - TIS utilise
Frontend.getStatus
pour collecter les informations nécessaires. - TIS appelle à nouveau
Tuner.scan
pour poursuivre la numérisation. (FrontendSettings
est ignoré.) - TIS répète les actions ci-dessus jusqu'à ce que tous les réglages sur la fréquence soient épuisés. Le HAL incrémente la fréquence sans aucune action nécessaire de la part du TIS. Le HAL rapporte
PROGRESS
.
TIS appelle à nouveau Tuner.scan(AUTO_SCAN)
jusqu'à ce que toutes les fréquences soient épuisées. Le HAL rapporte END
pour indiquer que l'opération d'analyse est terminée.
Pendant l'analyse, vous pouvez appeler stopScan()
ou close()
pour suspendre ou terminer l'analyse.
Figure 9. Organigramme d'une analyse TIS
Android.media.tv.tuner.filter
Le package de filtrage est un ensemble d'opérations de filtrage 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 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 des données |
---|---|---|---|---|
TS.SECTION MMTP.SECTION IP.SECTION TLV.SECTION ALP.SECTION | isRaw: | Obligatoire:DemuxFilterStatus::DATA_READY DemuxFilterStatus::DATA_OVERFLOW Recommandé: DemuxFilterStatus::LOW_WATER DemuxFilterStatus::HIGH_WATER | Selon l'événement et le planning 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 package de session assemblé est rempli en FMQ par un autre package 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 Recommandé: DemuxFilterStatus::LOW_WATER DemuxFilterStatus::HIGH_WATER | Selon l'événement et le planning 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 package PES assemblé est rempli en FMQ par un autre package 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 Recommandé: DemuxFilterStatus::LOW_WATER DemuxFilterStatus::HIGH_WATER | Selon l'événement et le planning 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 package MFU assemblé est rempli en FMQ par un autre package 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 le planning 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. | ts filtré avec en-tête ts est rempli en 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 d' AudioTrack :for i=0; i<n; i++ | 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 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é , selon RecordStatus::* et la planification interne, effectuez l'une des opérations suivantes :
| 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] 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 le planning 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. | mmtp filtré avec l'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 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é , selon RecordStatus::* et la planification interne, effectuez l'une des opérations suivantes :
| 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 de filtre pour l'enregistrement est TLV.TLV vers IP.IP avec passthrough, 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 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 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 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 package de charge utile IP est rempli dans FMQ par un autre package 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 filtre suivant dans 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 le planning 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. | 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 | Facultatif:DemuxFilterStatus::DATA_READY DemuxFilterStatus::DATA_OVERFLOW | La charge utile du protocole filtrée alimente le filtre suivant dans la chaîne de filtres. | N / A |
Exemple de flux pour utiliser le filtre pour créer PSI/SI
Figure 10. Flux pour construire 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();
Traiter
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 pour utiliser MediaEvent à partir du filtre
- Ouvrez, configurez et démarrez les filtres A/V.
- Traiter
MediaEvent
. - Recevez
MediaEvent
. - Mettez le bloc linéaire en file d'attente dans
codec
. - 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
Figure 12. Flux 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();
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. } } } };
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); } } };
Accordeur 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 le Tuner HAL et le framework l'utilise pour communiquer avec l'implémentation du Tuner HAL.
Modules
Accordeur HAL 1.0
Modules | Contrôles 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 | Contrôles 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 Tuner HAL
Liaison de filtre
Le Tuner HAL prend en charge la liaison de filtres de telle 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, la fermeture du chemin n'est pas autorisée.
- Le nœud racine est démultiplexé.
- Les filtres fonctionnent indépendamment.
- Tous les filtres commencent à obtenir des données.
- La tringlerie du filtre rince 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>)
}
Figure 14. Organigramme d'une liaison de filtre pour plusieurs couches
Gestionnaire de ressources du tuner
Avant Tuner Resource Manager (TRM), la commutation entre deux applications nécessitait le même matériel Tuner. TV Input Framework (TIF) a utilisé un mécanisme de « premier à acquérir la victoire », ce qui signifie que la première application qui obtient la ressource conserve la ressource. Cependant, ce mécanisme n’est peut-être pas idéal pour certains cas d’utilisation complexes.
TRM fonctionne comme un service système pour gérer les ressources matérielles Tuner, TVInput
et CAS pour les applications. TRM utilise un mécanisme de « victoire au 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. 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 pour la 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 clients et de demandes 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 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 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 de 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 prioritaire arbitraire et valeur intéressante
TRM fournit updateClientPriority
pour que le client mette à jour la valeur de priorité arbitraire et la valeur intéressante. 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 à quel point le comportement du client est indulgent lorsqu'il est en conflit avec un autre client. La valeur intéressante 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 diagramme 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 ressources Tuner
,Pour Android 11 ou version ultérieure, 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 fournir du contenu audiovisuel protégé par un environnement d'exécution de confiance (TEE) et un chemin multimédia sécurisé (SMP), lui permettant 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 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 plateforme 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 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 de gestion des entrées TV (TIMS) -
MediaCodec
ou codec multimédia -
AudioTrack
ou piste audio -
MediaResourceManager
ou gestionnaire de ressources multimédias (MRM)
Figure 1. Interactions entre les composants d'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 sous 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)
Descrambler prend en charge les protections de contenu ci-dessous.
- Chemin multimédia sécurisé
- Chemin multimédia clair
- Enregistrement local sécurisé
- Lecture locale sécurisée
Les API Tuner prennent en charge les cas d'utilisation ci-dessous.
- Analyse
- En direct
- Relecture
- Enregistrer
Tuner, MediaCodec
et AudioTrack
prennent en charge les modes de flux de données ci-dessous.
- Charge utile ES avec tampon 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émultiplexage et du désembrouilleur vers le framework via les interfaces
IFrontend
,IDemux
,IDescrambler
,IFilter
,IDvr
etILnb
. - Inclut les fonctions permettant d'intégrer le Tuner HAL avec 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 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 le Tuner HAL.
Une classe TRM est créée.
- Gère les ressources limitées du tuner, telles que le frontend, le LNB, les sessions 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 les sessions CAS pour différents usages et algorithmes.
- Prend en charge les systèmes CAS dynamiques, tels que le retrait et l'insertion CICAM.
- S'intègre au Tuner HAL en fournissant des jetons clés.
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 la synchronisation A/V matérielle en lecture tunnelée.
- Prise en charge configurée pour
ES_payload
et le mode passthrough.
Figure 2. Schéma des composants du Tuner HAL
Flux de travail global
Les diagrammes ci-dessous illustrent les séquences d'appel pour la lecture d'une diffusion en direct.
Installation
Figure 3. Séquence de configuration pour la lecture d'une diffusion en direct
Gestion de l'audiovisuel
Figure 4. Gestion de l'A/V pour la lecture d'une diffusion en direct
Gestion du contenu crypté
Figure 5. Gestion du contenu crypté pour la lecture de diffusion en direct
Traitement des données A/V
Figure 6. Traitement A/V pour la lecture d'une diffusion en direct
API du SDK du 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. Frontend et demux sont des composants internes.
Figure 7. Interactions avec l'API du SDK Tuner
Versions
À partir d'Android 12, l'API Tuner SDK prend en charge la nouvelle fonctionnalité de 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 minimale requise de HAL se trouve 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
Figure 8. Packages 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 frontend 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 du 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 de filtre, DVR et frontend. Les fonctionnalités sont répertoriées ci-dessous.
-
cancelTuning
-
scan
/cancelScanning
-
getAvSyncHwId
-
getAvSyncTime
-
connectCiCam1
/disconnectCiCam
-
shareFrontendFromTuner
-
updateResourcePriority
-
setOnTuneEventListener
-
setResourceLostListener
Android.media.tv.tuner.frontend
Le package frontend comprend des ensembles de paramètres, d'informations, de statuts, d'événements et de fonctionnalités liés au frontend.
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 provenant du frontend.
Balayage des chaînes
Pour configurer un téléviseur, l'application analyse les fréquences possibles et crée une gamme de chaînes accessible aux utilisateurs. TIS peut utiliser Tuner.tune
, Tuner.scan(BLIND_SCAN)
ou Tuner.scan(AUTO_SCAN)
pour terminer la numérisation 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, ID PLD), alors Tuner.tune
est recommandé comme option la plus rapide. .
Lorsque l'utilisateur appelle Tuner.tune
, les actions suivantes se produisent :
- TIS remplit
FrontendSettings
avec les informations requises à l'aideTuner.tune
. - Le HAL signale l'accord des messages
LOCKED
si le signal est verrouillé. - TIS utilise
Frontend.getStatus
pour collecter les informations nécessaires. - TIS passe à la fréquence disponible suivante 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 mettre fin à 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)
avecFrontendSettings
rempli de fréquence.Les rapports HAL analysent les messages
LOCKED
si le signal est verrouillé. Le 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 le HAL passe au réglage suivant sur la même fréquence. Si la structureFrontendSettings
est vide, la HAL utilise le paramètre disponible suivant. Sinon, HAL utiliseFrontendSettings
pour une analyse unique 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 réglages sur la fréquence soient épuisés.
Le HAL envoie
END
pour indiquer que l'opération d'analyse est terminée.TIS passe à la fréquence disponible suivante dans sa liste de fréquences.
TIS appelle à 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 terminer l'analyse.
Tuner.scan(BLIND_SCAN)
Si TIS ne dispose pas de liste de fréquences et que le fournisseur HAL peut rechercher la fréquence du frontend spécifié par l'utilisateur pour obtenir la ressource frontend, alors 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 de balayage
LOCKED
si le signal est verrouillé. - TIS utilise
Frontend.getStatus
pour collecter les informations nécessaires. - TIS appelle à nouveau
Tuner.scan
pour poursuivre la numérisation. (FrontendSettings
est ignoré.) - TIS répète les actions ci-dessus jusqu'à ce que tous les réglages sur la fréquence soient épuisés. Le HAL incrémente la fréquence sans aucune action nécessaire de la part du TIS. Le HAL rapporte
PROGRESS
.
TIS appelle à nouveau Tuner.scan(AUTO_SCAN)
jusqu'à ce que toutes les fréquences soient épuisées. Le HAL rapporte END
pour indiquer que l'opération d'analyse est terminée.
Pendant l'analyse, vous pouvez appeler stopScan()
ou close()
pour suspendre ou terminer l'analyse.
Figure 9. Organigramme d'une analyse TIS
Android.media.tv.tuner.filter
Le package de filtrage est un ensemble d'opérations de filtrage 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 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 des données |
---|---|---|---|---|
TS.SECTION MMTP.SECTION IP.SECTION TLV.SECTION ALP.SECTION | isRaw: | Obligatoire:DemuxFilterStatus::DATA_READY DemuxFilterStatus::DATA_OVERFLOW Recommandé: DemuxFilterStatus::LOW_WATER DemuxFilterStatus::HIGH_WATER | Selon l'événement et le planning 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 package de session assemblé est rempli en FMQ par un autre package 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 Recommandé: DemuxFilterStatus::LOW_WATER DemuxFilterStatus::HIGH_WATER | Selon l'événement et le planning 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 package PES assemblé est rempli en FMQ par un autre package 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 Recommandé: DemuxFilterStatus::LOW_WATER DemuxFilterStatus::HIGH_WATER | Selon l'événement et le planning 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 package MFU assemblé est rempli en FMQ par un autre package 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 le planning 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. | ts filtré avec en-tête ts est rempli en 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 d' AudioTrack :for i=0; i<n; i++ | 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 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é , selon RecordStatus::* et la planification interne, effectuez l'une des opérations suivantes :
| 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] 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 le planning 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. | mmtp filtré avec l'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 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é , selon RecordStatus::* et la planification interne, effectuez l'une des opérations suivantes :
| 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 de filtre pour l'enregistrement est TLV.TLV vers IP.IP avec passthrough, 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 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 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 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 package de charge utile IP est rempli dans FMQ par un autre package 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 filtre suivant dans 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 le planning 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. | 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 | Facultatif:DemuxFilterStatus::DATA_READY DemuxFilterStatus::DATA_OVERFLOW | La charge utile du protocole filtrée alimente le filtre suivant dans la chaîne de filtres. | N / A |
Exemple de flux pour utiliser le filtre pour créer PSI/SI
Figure 10. Flux pour construire 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();
Traiter
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 pour utiliser MediaEvent à partir du filtre
- Ouvrez, configurez et démarrez les filtres A/V.
- Traiter
MediaEvent
. - Recevez
MediaEvent
. - Mettez le bloc linéaire en file d'attente dans
codec
. - 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
Figure 12. Flux 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();
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. } } } };
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); } } };
Accordeur 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 le Tuner HAL et le framework l'utilise pour communiquer avec l'implémentation du Tuner HAL.
Modules
Accordeur HAL 1.0
Modules | Contrôles 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 | Contrôles 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 Tuner HAL
Liaison de filtre
Le Tuner HAL prend en charge la liaison de filtres de telle 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, la fermeture du chemin n'est pas autorisée.
- Le nœud racine est démultiplexé.
- Les filtres fonctionnent indépendamment.
- Tous les filtres commencent à obtenir des données.
- La tringlerie du filtre rince 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>)
}
Figure 14. Organigramme d'une liaison de filtre pour plusieurs couches
Gestionnaire de ressources du tuner
Avant Tuner Resource Manager (TRM), la commutation entre deux applications nécessitait le même matériel Tuner. TV Input Framework (TIF) a utilisé un mécanisme de « premier à acquérir la victoire », ce qui signifie que la première application qui obtient la ressource conserve la ressource. Cependant, ce mécanisme n’est peut-être pas idéal pour certains cas d’utilisation complexes.
TRM fonctionne comme un service système pour gérer les ressources matérielles Tuner, TVInput
et CAS pour les applications. TRM utilise un mécanisme de « victoire au 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. 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 pour la 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 clients et de demandes 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 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 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 de 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 prioritaire arbitraire et valeur intéressante
TRM fournit updateClientPriority
pour que le client mette à jour la valeur de priorité arbitraire et la valeur intéressante. 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 à quel point le comportement du client est indulgent lorsqu'il est en conflit avec un autre client. La valeur intéressante 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 diagramme 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 ressources Tuner
,Pour Android 11 ou version ultérieure, 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 fournir du contenu audiovisuel protégé par un environnement d'exécution de confiance (TEE) et un chemin multimédia sécurisé (SMP), lui permettant 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 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 plateforme 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 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 de gestion des entrées TV (TIMS) -
MediaCodec
ou codec multimédia -
AudioTrack
ou piste audio -
MediaResourceManager
ou gestionnaire de ressources multimédias (MRM)
Figure 1. Interactions entre les composants d'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 sous 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)
Descrambler prend en charge les protections de contenu ci-dessous.
- Chemin multimédia sécurisé
- Chemin multimédia clair
- Enregistrement local sécurisé
- Lecture locale sécurisée
Les API Tuner prennent en charge les cas d'utilisation ci-dessous.
- Analyse
- En direct
- Relecture
- Enregistrer
Tuner, MediaCodec
et AudioTrack
prennent en charge les modes de flux de données ci-dessous.
- Charge utile ES avec tampon 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émultiplexage et du désembrouilleur vers le framework via les interfaces
IFrontend
,IDemux
,IDescrambler
,IFilter
,IDvr
etILnb
. - Inclut les fonctions permettant d'intégrer le Tuner HAL avec 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 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 le Tuner HAL.
Une classe TRM est créée.
- Gère les ressources limitées du tuner, telles que le frontend, le LNB, les sessions 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 les sessions CAS pour différents usages et algorithmes.
- Prend en charge les systèmes CAS dynamiques, tels que le retrait et l'insertion CICAM.
- S'intègre au Tuner HAL en fournissant des jetons clés.
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 la synchronisation A/V matérielle en lecture tunnelée.
- Prise en charge configurée pour
ES_payload
et le mode passthrough.
Figure 2. Schéma des composants du Tuner HAL
Flux de travail global
Les diagrammes ci-dessous illustrent les séquences d'appel pour la lecture d'une diffusion en direct.
Installation
Figure 3. Séquence de configuration pour la lecture d'une diffusion en direct
Gestion de l'audiovisuel
Figure 4. Gestion de l'A/V pour la lecture d'une diffusion en direct
Gestion du contenu crypté
Figure 5. Gestion du contenu crypté pour la lecture de diffusion en direct
Traitement des données A/V
Figure 6. Traitement A/V pour la lecture d'une diffusion en direct
API du SDK du 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. Frontend et demux sont des composants internes.
Figure 7. Interactions avec l'API du SDK Tuner
Versions
À partir d'Android 12, l'API Tuner SDK prend en charge la nouvelle fonctionnalité de 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 minimale requise de HAL se trouve 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
Figure 8. Packages 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 frontend 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 du 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 de filtre, DVR et frontend. Les fonctionnalités sont répertoriées ci-dessous.
-
cancelTuning
-
scan
/cancelScanning
-
getAvSyncHwId
-
getAvSyncTime
-
connectCiCam1
/disconnectCiCam
-
shareFrontendFromTuner
-
updateResourcePriority
-
setOnTuneEventListener
-
setResourceLostListener
Android.media.tv.tuner.frontend
Le package frontend comprend des ensembles de paramètres, d'informations, de statuts, d'événements et de fonctionnalités liés au frontend.
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 provenant du frontend.
Balayage des chaînes
Pour configurer un téléviseur, l'application analyse les fréquences possibles et crée une gamme de chaînes accessible aux utilisateurs. TIS peut utiliser Tuner.tune
, Tuner.scan(BLIND_SCAN)
ou Tuner.scan(AUTO_SCAN)
pour terminer la numérisation 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, ID PLD), alors Tuner.tune
est recommandé comme option la plus rapide. .
Lorsque l'utilisateur appelle Tuner.tune
, les actions suivantes se produisent :
- TIS remplit
FrontendSettings
avec les informations requises à l'aideTuner.tune
. - Le HAL signale l'accord des messages
LOCKED
si le signal est verrouillé. - TIS utilise
Frontend.getStatus
pour collecter les informations nécessaires. - TIS passe à la fréquence disponible suivante 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 mettre fin à 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)
avecFrontendSettings
rempli de fréquence.Les rapports HAL analysent les messages
LOCKED
si le signal est verrouillé. Le 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 le HAL passe au réglage suivant sur la même fréquence. Si la structureFrontendSettings
est vide, la HAL utilise le paramètre disponible suivant. Sinon, HAL utiliseFrontendSettings
pour une analyse unique 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 réglages sur la fréquence soient épuisés.
Le HAL envoie
END
pour indiquer que l'opération d'analyse est terminée.TIS passe à la fréquence disponible suivante dans sa liste de fréquences.
TIS appelle à 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 terminer l'analyse.
Tuner.scan(BLIND_SCAN)
Si TIS ne dispose pas de liste de fréquences et que le fournisseur HAL peut rechercher la fréquence du frontend spécifié par l'utilisateur pour obtenir la ressource frontend, alors 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 de balayage
LOCKED
si le signal est verrouillé. - TIS utilise
Frontend.getStatus
pour collecter les informations nécessaires. - TIS appelle à nouveau
Tuner.scan
pour poursuivre la numérisation. (FrontendSettings
est ignoré.) - TIS répète les actions ci-dessus jusqu'à ce que tous les réglages sur la fréquence soient épuisés. Le HAL incrémente la fréquence sans aucune action nécessaire de la part du TIS. Le HAL rapporte
PROGRESS
.
TIS appelle à nouveau Tuner.scan(AUTO_SCAN)
jusqu'à ce que toutes les fréquences soient épuisées. Le HAL rapporte END
pour indiquer que l'opération d'analyse est terminée.
Pendant l'analyse, vous pouvez appeler stopScan()
ou close()
pour suspendre ou terminer l'analyse.
Figure 9. Organigramme d'une analyse TIS
Android.media.tv.tuner.filter
Le package de filtrage est un ensemble d'opérations de filtrage 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 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 des données |
---|---|---|---|---|
TS.SECTION MMTP.SECTION IP.SECTION TLV.SECTION ALP.SECTION | isRaw: | Obligatoire:DemuxFilterStatus::DATA_READY DemuxFilterStatus::DATA_OVERFLOW Recommandé: DemuxFilterStatus::LOW_WATER DemuxFilterStatus::HIGH_WATER | Selon l'événement et le planning 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 package de session assemblé est rempli en FMQ par un autre package 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 Recommandé: DemuxFilterStatus::LOW_WATER DemuxFilterStatus::HIGH_WATER | Selon l'événement et le planning 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 package PES assemblé est rempli en FMQ par un autre package 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 Recommandé: DemuxFilterStatus::LOW_WATER DemuxFilterStatus::HIGH_WATER | Selon l'événement et le planning 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 package MFU assemblé est rempli en FMQ par un autre package 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 le planning 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. | ts filtré avec en-tête ts est rempli en 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 d' AudioTrack :for i=0; i<n; i++ | 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 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é , selon RecordStatus::* et la planification interne, effectuez l'une des opérations suivantes :
| 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] 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 le planning 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. | mmtp filtré avec l'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 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é , selon RecordStatus::* et la planification interne, effectuez l'une des opérations suivantes :
| 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 de filtre pour l'enregistrement est TLV.TLV vers IP.IP avec passthrough, 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 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 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 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 package de charge utile IP est rempli dans FMQ par un autre package 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 filtre suivant dans 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 le planning 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. | 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 | Facultatif:DemuxFilterStatus::DATA_READY DemuxFilterStatus::DATA_OVERFLOW | La charge utile du protocole filtrée alimente le filtre suivant dans la chaîne de filtres. | N / A |
Exemple de flux pour utiliser le filtre pour créer PSI/SI
Figure 10. Flux pour construire 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();
Traiter
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 pour utiliser MediaEvent à partir du filtre
- Ouvrez, configurez et démarrez les filtres A/V.
- Traiter
MediaEvent
. - Recevez
MediaEvent
. - Mettez le bloc linéaire en file d'attente dans
codec
. - 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
Figure 12. Flux 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();
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. } } } };
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); } } };
Accordeur 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 le Tuner HAL et le framework l'utilise pour communiquer avec l'implémentation du Tuner HAL.
Modules
Accordeur HAL 1.0
Modules | Contrôles 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 | Contrôles 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 Tuner HAL
Liaison de filtre
Le Tuner HAL prend en charge la liaison de filtres de telle 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, la fermeture du chemin n'est pas autorisée.
- Le nœud racine est démultiplexé.
- Les filtres fonctionnent indépendamment.
- Tous les filtres commencent à obtenir des données.
- La tringlerie du filtre rince 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>)
}
Figure 14. Organigramme d'une liaison de filtre pour plusieurs couches
Gestionnaire de ressources du tuner
Avant Tuner Resource Manager (TRM), la commutation entre deux applications nécessitait le même matériel Tuner. TV Input Framework (TIF) a utilisé un mécanisme de « premier à acquérir la victoire », ce qui signifie que la première application qui obtient la ressource conserve la ressource. Cependant, ce mécanisme n’est peut-être pas idéal pour certains cas d’utilisation complexes.
TRM fonctionne comme un service système pour gérer les ressources matérielles Tuner, TVInput
et CAS pour les applications. TRM utilise un mécanisme de « victoire au 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. 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 pour la 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 clients et de demandes 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 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 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 de 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 prioritaire arbitraire et valeur intéressante
TRM fournit updateClientPriority
pour que le client mette à jour la valeur de priorité arbitraire et la valeur intéressante. 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 à quel point le comportement du client est indulgent lorsqu'il est en conflit avec un autre client. La valeur intéressante 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 diagramme 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 ressources Tuner