Pour Android 11 ou supérieur, vous pouvez utiliser le framework Android Tuner pour diffuser du contenu A/V. Le framework utilise le pipeline matériel des fournisseurs, ce qui le rend adapté aux SoC bas de gamme et haut de gamme. Le cadre fournit un moyen sécurisé de diffuser du contenu A/V protégé par un environnement d'exécution fiable (TEE) et un chemin multimédia sécurisé (SMP), ce qui lui permet d'être utilisé dans un environnement de protection de contenu hautement restreint.
L'interface standardisée entre Tuner et Android CAS permet une intégration plus rapide entre les fournisseurs Tuner et les fournisseurs CAS. L'interface Tuner fonctionne avec MediaCodec
et AudioTrack
pour créer une solution mondiale pour Android TV. L'interface Tuner prend en charge à la fois la télévision numérique et la télévision analogique sur la base des principales normes de diffusion.
Composants
Pour Android 11, trois composants sont spécifiquement conçus pour la plate-forme TV.
- Tuner HAL : une interface entre le framework et les fournisseurs
- API Tuner SDK : une interface entre le framework et les applications
- Tuner Resource Manager (TRM): Coordonne les ressources matérielles Tuner
Pour Android 11, les composants suivants ont été améliorés.
- CAS V2
-
TvInputService
ou service d'entrée TV (TIS) -
TvInputManagerService
ou service de gestionnaire d'entrée TV (TIMS) -
MediaCodec
ou codec multimédia -
AudioTrack
ou piste audio -
MediaResourceManager
ou gestionnaire de ressources multimédias (MRM)
Figure 1. Interactions entre les composants Android TV
Caractéristiques
Frontend prend en charge les normes DTV ci-dessous.
- ATSC
- ATSC3
- DVB C/S/T
- ISDB S/S3/T
- Analogique
L'interface d'Android 12 avec Tuner HAL 1.1 ou supérieur prend en charge la norme DTV ci-dessous.
- DTMB
Demux prend en charge les protocoles de flux ci-dessous.
- Flux de transport (TS)
- Protocole de transport multimédia MPEG (MMTP)
- Protocole Internet (IP)
- Valeur de longueur de type (TLV)
- Protocole de couche liaison ATSC (ALP)
Le désembrouilleur prend en charge les protections de contenu ci-dessous.
- Chemin multimédia sécurisé
- Effacer le chemin du média
- Enregistrement local sécurisé
- Lecture locale sécurisée
Les API Tuner prennent en charge les cas d'utilisation ci-dessous.
- Analyse
- Habitent
- Relecture
- Enregistrement
Tuner, MediaCodec
et AudioTrack
prennent en charge les modes de flux de données ci-dessous.
- Charge utile ES avec tampon de mémoire vide
- Charge utile ES avec poignée de mémoire sécurisée
- Traverser
Conception générale
Le Tuner HAL est défini entre le framework Android et le matériel du fournisseur.
- Décrit ce que le framework attend du fournisseur et comment le fournisseur peut le faire.
- Exporte les fonctionnalités du frontend, du démultiplexeur et du désembrouilleur vers le framework via
IFrontend
,IDemux
,IDescrambler
,IFilter
,IDvr
etILnb
. - Inclut les fonctions pour intégrer le Tuner HAL avec d'autres composants du framework, tels que
MediaCodec
etAudioTrack
.
Une classe Tuner Java et une classe native sont créées.
- L'API Tuner Java permet aux applications d'accéder à Tuner HAL via des API publiques.
- La classe native permet le contrôle des autorisations et la gestion de grandes quantités de données d'enregistrement ou de lecture avec le Tuner HAL.
- Le module Native Tuner est un pont entre la classe Tuner Java et Tuner HAL.
Une classe TRM est créée.
- Gère les ressources tuner limitées, telles que les sessions Frontend, LNB, CAS et un périphérique d'entrée TV à partir de l'entrée TV HAL.
- Applique des règles pour récupérer les ressources insuffisantes des applications. La règle par défaut est la victoire au premier plan.
Media CAS et CAS HAL sont améliorés avec les fonctionnalités ci-dessous.
- Ouvre des sessions CAS pour différents usages et algorithmes.
- Prend en charge les systèmes CAS dynamiques, tels que le retrait et l'insertion de CICAM.
- S'intègre au Tuner HAL en fournissant des jetons de clé.
MediaCodec
et AudioTrack
sont améliorés avec les fonctionnalités ci-dessous.
- Prend une mémoire A/V sécurisée comme entrée de contenu.
- Configuré pour effectuer une synchronisation A/V matérielle en lecture tunnel.
- Prise en charge configurée pour
ES_payload
et le mode passthrough.
Figure 2. Schéma des composants de la HAL Tuner
Flux de travail global
Les schémas ci-dessous illustrent les séquences d'appels pour la diffusion en direct.
Installer
Figure 3. Séquence de configuration pour la diffusion en direct
Gestion A/V
Figure 4. Gestion A/V pour la diffusion en direct
Gestion du contenu brouillé
Figure 5. Traitement du contenu crypté pour la diffusion en direct
Traitement des données A/V
Figure 6. Traitement A/V pour la diffusion en direct
API du SDK Tuner
L'API Tuner SDK gère les interactions avec Tuner JNI, Tuner HAL et TunerResourceManager
. L'application TIS utilise l'API Tuner SDK pour accéder aux ressources et sous-composants Tuner tels que le filtre et le désembrouilleur. Le frontend et le démultiplexeur sont des composants internes.
Figure 7. Interactions avec l'API Tuner SDK
Versions
À partir d'Android 12, l'API Tuner SDK prend en charge une nouvelle fonctionnalité dans Tuner HAL 1.1, qui est une mise à niveau de version rétrocompatible de Tuner 1.0.
Utilisez l'API suivante pour vérifier la version HAL en cours d'exécution.
-
android.media.tv.tuner.TunerVersionChecker.getTunerVersion()
La version HAL minimale requise peut être trouvée dans la documentation des nouvelles API Android 12.
Paquets
L'API Tuner SDK fournit les quatre packages ci-dessous.
-
android.media.tv.tuner
-
android.media.tv.tuner.frontend
-
android.media.tv.tuner.filter
-
android.media.tv.tuner.dvr
Figure 8. Packages API Tuner SDK
Android.media.tv.tuner
Le package Tuner est un point d'entrée pour utiliser le framework Tuner. L'application TIS utilise le package pour initialiser et acquérir des instances de ressource en spécifiant le paramètre initial et le rappel.
-
tuner()
: Initialise une instance Tuner en spécifiant les paramètresuseCase
etsessionId
. -
tune()
: acquiert une ressource frontale et s'accorde en spécifiant le paramètreFrontendSetting
. -
openFilter()
: acquiert une instance de filtre en spécifiant le type de filtre. -
openDvrRecorder()
: acquiert une instance d'enregistrement en spécifiant la taille de la mémoire tampon. -
openDvrPlayback()
: acquiert une instance de lecture en spécifiant la taille du tampon. -
openDescrambler()
: Acquiert une instance de désembrouilleur. -
openLnb()
: Acquiert une instance LNB interne. -
openLnbByName()
: Acquiert une instance LNB externe. -
openTimeFilter()
: Acquiert une instance de filtre temporel.
Le package Tuner fournit des fonctionnalités qui ne sont pas couvertes par les packages filtre, DVR et frontal. Les fonctionnalités sont listées ci-dessous.
-
cancelTuning
-
scan
/cancelScanning
-
getAvSyncHwId
-
getAvSyncTime
-
connectCiCam1
/disconnectCiCam
-
shareFrontendFromTuner
-
updateResourcePriority
-
setOnTuneEventListener
-
setResourceLostListener
Android.media.tv.tuner.frontend
Le package frontal comprend des ensembles de paramètres, d'informations, d'états, d'événements et de fonctionnalités liés au frontal.
Des classes
FrontendSettings
est dérivé pour différentes normes DTV par les classes ci-dessous.
-
AnalogFrontendSettings
-
Atsc3FrontendSettings
-
AtscFrontendSettings
-
DvbcFrontendSettings
-
DvbsFrontendSettings
-
DvbtFrontendSettings
-
Isdbs3FrontendSettings
-
IsdbsFrontendSettings
-
IsdbtFrontendSettings
À partir d'Android 12 avec Tuner HAL 1.1 ou supérieur, la norme DTV suivante est prise en charge.
-
DtmbFrontendSettings
FrontendCapabilities
est dérivé pour différentes normes DTV par les classes ci-dessous.
-
AnalogFrontendCapabilities
-
Atsc3FrontendCapabilities
-
AtscFrontendCapabilities
-
DvbcFrontendCapabilities
-
DvbsFrontendCapabilities
-
DvbtFrontendCapabilities
-
Isdbs3FrontendCapabilities
-
IsdbsFrontendCapabilities
-
IsdbtFrontendCapabilities
À partir d'Android 12 avec Tuner HAL 1.1 ou supérieur, la norme DTV suivante est prise en charge.
-
DtmbFrontendCapabilities
FrontendInfo
récupère les informations du frontend. FrontendStatus
récupère l'état actuel du frontend. OnTuneEventListener
écoute les événements sur le frontend. L'application TIS utilise ScanCallback
pour traiter les messages d'analyse du frontend.
Balayage des canaux
Pour configurer un téléviseur, l'application analyse les fréquences possibles et crée une liste de chaînes accessible aux utilisateurs. TIS peut utiliser Tuner.tune
, Tuner.scan(BLIND_SCAN)
ou Tuner.scan(AUTO_SCAN)
pour terminer le balayage des chaînes.
Si TIS dispose d'informations de livraison précises pour le signal, telles que la fréquence, la norme (par exemple, T/T2, S/S2) et des informations supplémentaires nécessaires (par exemple, PLD ID), alors Tuner.tune
est recommandé comme option plus rapide. .
Lorsque l'utilisateur appelle Tuner.tune
, les actions suivantes se produisent :
- TIS remplit
FrontendSettings
avec les informations requises à l'aideTuner.tune
. - Le HAL signale des messages
LOCKED
si le signal est verrouillé. - TIS utilise
Frontend.getStatus
pour collecter les informations nécessaires. - TIS passe à la prochaine fréquence disponible dans sa liste de fréquences.
TIS appelle à nouveau Tuner.tune
jusqu'à ce que toutes les fréquences soient épuisées.
Pendant le réglage, vous pouvez appeler stopTune()
ou close()
pour mettre en pause ou terminer l'appel Tuner.tune
.
Tuner.scan(AUTO_SCAN)
Si TIS ne dispose pas de suffisamment d'informations pour utiliser Tuner.tune
, mais dispose d'une liste de fréquences et d'un type standard (par exemple, DVB T/C/S), alors Tuner.scan(AUTO_SCAN)
est recommandé.
Lorsque l'utilisateur appelle Tuner.scan(AUTO_SCAN)
, les actions suivantes se produisent :
TIS utilise
Tuner.scan(AUTO_SCAN)
avecFrontendSettings
rempli de fréquence.Les rapports HAL scannent les messages
LOCKED
si le signal est verrouillé. La couche HAL peut également signaler d'autres messages d'analyse pour fournir des informations supplémentaires sur le signal.TIS utilise
Frontend.getStatus
pour collecter les informations nécessaires.TIS appelle
Tuner.scan
pour que HAL passe au réglage suivant sur la même fréquence. Si la structureFrontendSettings
est vide, HAL utilise le prochain paramètre disponible. 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 de la fréquence soient épuisés.
Le HAL envoie
END
pour indiquer que l'opération de balayage est terminée.TIS passe à la prochaine fréquence disponible dans sa liste de fréquences.
TIS appelle Tuner.scan(AUTO_SCAN)
jusqu'à ce que toutes les fréquences soient épuisées.
Pendant l'analyse, vous pouvez appeler stopScan()
ou close()
pour mettre en pause ou terminer l'analyse.
Tuner.scan(BLIND_SCAN)
Si TIS n'a pas de liste de fréquences et que le fournisseur HAL peut rechercher la fréquence de l'interface spécifiée par l'utilisateur pour obtenir la ressource d'interface, alors Tuner.scan(BLIND_SCAN)
est recommandé.
- TIS utilise
Tuner.scan(BLIND_SCAN)
. Une fréquence peut être spécifiée 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 continuer la numérisation. (FrontendSettings
est ignoré.) - TIS répète les actions ci-dessus jusqu'à ce que tous les réglages de la fréquence soient épuisés. Le HAL incrémente la fréquence sans action nécessaire de TIS. La HAL signale
PROGRESS
.
TIS appelle Tuner.scan(AUTO_SCAN)
jusqu'à ce que toutes les fréquences soient épuisées. Le HAL signale END
pour indiquer que l'opération de balayage est terminée.
Pendant l'analyse, vous pouvez appeler stopScan()
ou close()
pour mettre en pause ou terminer l'analyse.
Figure 9. Organigramme d'une analyse TIS
Android.media.tv.tuner.filter
Le package de filtre est une collection d'opérations de filtre ainsi que la configuration, les paramètres, les rappels et les événements. Le package comprend les opérations ci-dessous. Reportez-vous au code source Android pour la liste complète des opérations.
-
configure()
-
start()
-
stop()
-
flush()
-
read()
Reportez-vous au code source Android pour la liste complète.
FilterConfiguration
est dérivé des classes ci-dessous. Les configurations concernent le type de filtre principal et elles spécifient le protocole utilisé par le filtre pour extraire les données.
-
AlpFilterConfiguration
-
IpFilterConfiguration
-
MmtpFilterConfiguration
-
TlvFilterConfiguration
-
TsFilterConfiguration
Les paramètres sont dérivés des classes ci-dessous. Les paramètres concernent le sous-type de filtre et spécifient les types de données que le filtre peut exclure.
-
SectionSettings
-
AvSettings
-
PesSettings
-
RecordSettings
-
DownloadSettings
FilterEvent
est dérivé des classes ci-dessous pour signaler des événements pour différents types de données.
-
SectionEvent
-
MediaEvent
-
PesEvent
-
TsRecordEvent
-
MmtpRecordEvent
-
TemiEvent
-
DownloadEvent
-
IpPayloadEvent
À partir d'Android 12 avec Tuner HAL 1.1 ou supérieur, les événements suivants sont pris en charge.
-
IpCidChangeEvent
-
RestartEvent
-
ScramblingStatusEvent
Événements et format de données du filtre
Type de filtre | Drapeaux | Événements | Opération de données | Format de données |
---|---|---|---|---|
TS.SECTION MMTP.SECTION IP.SECTION TLV.SECTION ALP.SECTION | isRaw: | Obligatoire:DemuxFilterStatus::DATA_READY DemuxFilterStatus::DATA_OVERFLOW Conseillé: DemuxFilterStatus::LOW_WATER DemuxFilterStatus::HIGH_WATER | Selon l'événement et le calendrier interne, exécutezFilter.read(buffer, offset, adjustedSize) une ou plusieurs fois.Les données sont copiées du MQ de HAL vers le tampon client. | Un paquet de session assemblé est rempli dans FMQ par un autre paquet de session. |
isRaw: | Obligatoire:DemuxFilterEvent::DemuxFilterSectionEvent[n] DemuxFilterStatus::DATA_READY DemuxFilterStatus::DATA_OVERFLOW Optionnel: 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 Conseillé: DemuxFilterStatus::LOW_WATER DemuxFilterStatus::HIGH_WATER | Selon l'événement et le calendrier 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 PES assemblé est rempli en FMQ par un autre package PES. |
isRaw: | Obligatoire:DemuxFilterEvent::DemuxFilterPesEvent[n] DemuxFilterStatus::DATA_READY DemuxFilterStatus::DATA_OVERFLOW Optionnel: 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 Conseillé: DemuxFilterStatus::LOW_WATER DemuxFilterStatus::HIGH_WATER | Selon l'événement et le calendrier 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 MFU assemblé est rempli en FMQ par un autre package MFU. |
isRaw: | Obligatoire:DemuxFilterEvent::DemuxFilterPesEvent[n] DemuxFilterStatus::DATA_READY DemuxFilterStatus::DATA_OVERFLOW Optionnel: 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.TS | N / A | Obligatoire:DemuxFilterStatus::DATA_READY DemuxFilterStatus::DATA_OVERFLOW Conseillé: DemuxFilterStatus::LOW_WATER DemuxFilterStatus::HIGH_WATER | Selon l'événement et le calendrier interne, exécutezFilter.read(buffer, offset, adjustedSize) une ou plusieurs fois.Les données sont copiées du MQ de HAL vers le tampon client. | Filtrer les ts avec l'en-tête ts est rempli en FMQ. |
TS.Audio TS.Video MMTP.Audio MMTP.Video | isPassthrough: | Optionnel:DemuxFilterStatus::DATA_READY DemuxFilterStatus::DATA_OVERFLOW | Le client peut démarrer MediaCodec après avoir reçu DemuxFilterStatus::DATA_READY .Le client peut appeler Filter.flush après avoir reçu DemuxFilterStatus::DATA_OVERFLOW . | N / A |
isPassthrough: | Obligatoire:DemuxFilterEvent::DemuxFilterMediaEvent[n] DemuxFilterStatus::DATA_READY DemuxFilterStatus::DATA_OVERFLOW Optionnel: DemuxFilterStatus::LOW_WATER DemuxFilterStatus::HIGH_WATER | Pour utiliser MediaCodec :for i=0; i<n; i++ Pour utiliser le Direct Audio 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 Optionnel: DemuxFilterStatus::DATA_READY DemuxFilterStatus::DATA_OVERFLOW DemuxFilterStatus::LOW_WATER DemuxFilterStatus::HIGH_WATER | Pour les données d'index :for i=0; i<n; i++ Pour le contenu enregistré , selon RecordStatus::* et le calendrier 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] Optionnel: 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 Conseillé: DemuxFilterStatus::LOW_WATER DemuxFilterStatus::HIGH_WATER | Selon l'événement et le calendrier 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. | mmtp filtré avec en-tête mmtp est rempli en FMQ. |
MMTP.RECORD | N / A | Obligatoire:DemuxFilterEvent::DemuxFilterMmtpRecordEvent[n] RecordStatus::DATA_READY RecordStatus::DATA_OVERFLOW RecordStatus::LOW_WATER RecordStatus::HIGH_WATER Optionnel: DemuxFilterStatus::DATA_READY DemuxFilterStatus::DATA_OVERFLOW DemuxFilterStatus::LOW_WATER DemuxFilterStatus::HIGH_WATER | Pour les données d'index : for i=0; i<n; i++ Pour le contenu enregistré , selon RecordStatus::* et le calendrier 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 du filtre pour l'enregistrement est TLV.TLV vers IP.IP avec relais, le flux enregistré a un en-tête TLV et IP. |
MMTP.DOWNLOAD | N / A | Obligatoire:DemuxFilterEvent::DemuxFilterDownloadEvent[n] DemuxFilterStatus::DATA_READY DemuxFilterStatus::DATA_OVERFLOW Optionnel: DemuxFilterStatus::LOW_WATER DemuxFilterStatus::HIGH_WATER | for i=0; i<n; i++ Filter.read(buffer, offset, DemuxFilterDownloadEvent[i].size) Les données sont copiées du MQ de HAL vers le tampon client. | Le package de téléchargement est rempli dans FMQ par un autre package de téléchargement IP. |
IP.IP_PAYLOAD | N / A | Obligatoire:DemuxFilterEvent::DemuxFilterIpPayloadEvent[n] DemuxFilterStatus::DATA_READY DemuxFilterStatus::DATA_OVERFLOW Optionnel: DemuxFilterStatus::LOW_WATER DemuxFilterStatus::HIGH_WATER | for i=0; i<n; i++ Filter.read(buffer, offset, DemuxFilterIpPayloadEvent[i].size) Les données sont copiées du MQ de HAL vers le tampon client. | Le package de charge utile IP est rempli dans FMQ par un autre package de charge utile IP. |
IP.IP TLV.TLV ALP.ALP | isPassthrough: | Optionnel:DemuxFilterStatus::DATA_READY DemuxFilterStatus::DATA_OVERFLOW | Le sous-flux de protocole filtré alimente le filtre suivant dans la chaîne de filtres. | N / A |
isPassthrough: | Obligatoire:DemuxFilterStatus::DATA_READY DemuxFilterStatus::DATA_OVERFLOW Conseillé: DemuxFilterStatus::LOW_WATER DemuxFilterStatus::HIGH_WATER | Selon l'événement et le calendrier 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. | Le sous-flux de protocole filtré avec en-tête de protocole est rempli dans FMQ. | |
IP.PAYLOAD_THROUGH TLV.PAYLOAD_THROUGH ALP.PAYLOAD_THROUGH | N / A | Optionnel:DemuxFilterStatus::DATA_READY DemuxFilterStatus::DATA_OVERFLOW | La charge utile de protocole filtrée alimente le filtre suivant dans la chaîne de filtres. | N / A |
Exemple de flux pour utiliser un filtre pour construire PSI/SI
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 l'
SectionEvent
de section .FilterCallback filterCallback = new FilterCallback() { @Override public void onFilterEvent(Filter filter, FilterEvent[] events) { for (FilterEvent event : events) { if (event instanceof SectionEvent) { SectionEvent sectionEvent = (SectionEvent) event; int tableId = sectionEvent.getTableId(); int version = sectionEvent.getVersion(); int dataLength = sectionEvent.getDataLength(); int sectionNumber = sectionEvent.getSectionNumber(); filter.read(buffer, 0, dataLength); } } } };
Exemple de flux pour utiliser MediaEvent à partir du filtre
Figure 11. Flux pour utiliser MediaEvent à partir du filtre
- Ouvrez, configurez et démarrez les filtres A/V.
- Traiter
MediaEvent
. - Recevoir
MediaEvent
. - Mettez le bloc linéaire en file d'attente dans le
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); } } };
Syntoniseur HAL
Le Tuner HAL suit HIDL et définit l'interface entre le framework et le matériel du fournisseur. Les fournisseurs utilisent l'interface pour implémenter Tuner HAL et le framework l'utilise pour communiquer avec l'implémentation Tuner HAL.
Modules
Syntoniseur HAL 1.0
Modules | Commandes de base | Contrôles spécifiques au module | Fichiers HAL |
---|---|---|---|
ITuner | N / A | frontend(open, getIds, getInfo) , openDemux , openDescrambler , openLnb , getDemuxCaps | ITuner.hal |
IFrontend | setCallback , getStatus , close | tune , stopTune , scan , stopScan , setLnb | IFrontend.hal IFrontendCallback.hal |
IDemux | close | setFrontendDataSource , openFilter , openDvr , getAvSyncHwId , getAvSyncTime , connect / disconnectCiCam CiCam | IDemux.hal |
IDvr | close , start , stop , configure | attach/detachFilters , flush , getQueueDesc | IDvr.hal IDvrCallback.hal |
IFilter | close , start , stop , configure , getId | flush , getQueueDesc , releaseAvHandle , setDataSource | IFilter.hal IFilterCallback.hal |
ILnb | close , setCallback | setVoltage , setTone , setSatellitePosition , sendDiseqcMessage | ILnb.hal ILnbCallback.hal |
IDescrambler | close | setDemuxSource , setKeyToken , addPid , removePid | IDescrambler.hal |
Tuner HAL 1.1 (dérivé du tuner HAL 1.0)
Modules | Commandes de base | Contrôles spécifiques au module | Fichiers HAL |
---|---|---|---|
ITuner | N / A | getFrontendDtmbCapabilities | @1.1::ITuner.hal |
IFrontend | tune_1_1 , scan_1_1 , getStatusExt1_1 | link/unlinkCiCam | @1.1::IFrontend.hal @1.1::IFrontendCallback.hal |
IFilter | getStatusExt1_1 | configureIpCid , configureAvStreamType , getAvSharedHandle , configureMonitorEvent | @1.1::IFilter.hal @1.1::IFilterCallback.hal |
Figure 13. Schéma des interactions entre les modules Tuner HAL
Liaison de filtre
Le tuner HAL prend en charge la liaison de filtres de sorte que les filtres peuvent être liés à d'autres filtres pour plusieurs couches. Les filtres suivent les règles ci-dessous.
- Les filtres sont liés sous forme d'arborescence, le chemin de fermeture n'est pas autorisé.
- Le nœud racine est démultiplexé.
- Les filtres fonctionnent indépendamment.
- Tous les filtres commencent à obtenir des données.
- La tringlerie du filtre se vide sur le dernier filtre.
Le bloc de code ci-dessous et la figure 14 illustrent un exemple de filtrage de plusieurs couches.
demuxCaps = ITuner.getDemuxCap;
If (demuxCaps[IP][MMTP] == true) {
ipFilter = ITuner.openFilter(<IP, ..>)
mmtpFilter1 = ITuner.openFilter(<MMTP ..>)
mmtpFilter2 = ITuner.openFilter(<MMTP ..>)
mmtpFilter1.setDataSource(<ipFilter>)
mmtpFilter2.setDataSource(<ipFilter>)
}
Figure 14. Organigramme d'une liaison de filtre pour plusieurs couches
Gestionnaire de ressources tuner
Avant Tuner Resource Manager (TRM), le basculement entre deux applications nécessitait le même matériel Tuner. TV Input Framework (TIF) utilisait un mécanisme de "première acquisition gagnante", ce qui signifie que l'application qui obtient la ressource en premier conserve la ressource. Cependant, ce mécanisme peut ne pas être idéal pour certains cas d'utilisation compliqués.
TRM s'exécute en tant que service système pour gérer les ressources matérielles Tuner, TVInput
et CAS pour les applications. TRM utilise un mécanisme de « gain de premier plan », qui calcule la priorité de l'application en fonction du statut de premier plan ou d'arrière-plan de l'application et du type de cas d'utilisation. TRM accorde ou révoque la ressource en fonction de la priorité. TRM centralise la gestion des ressources ATV pour la diffusion, l'OTT et le DVR.
Interface TRM
TRM expose les interfaces AIDL dans ITunerResourceManager.aidl
pour le framework Tuner, MediaCas
et TvInputHardwareManager
pour enregistrer, demander ou libérer des ressources.
Les interfaces de gestion des clients sont répertoriées ci-dessous.
-
registerClientProfile(in ResourceClientProfile profile, IResourcesReclaimListener listener, out int[] clientId)
-
unregisterClientProfile(in int clientId)
Les interfaces pour demander et libérer des ressources sont répertoriées ci-dessous.
-
requestFrontend(TunerFrontendRequest request, int[] frontendHandle)
/releaseFrontend
-
requestDemux(TunerDemuxRequest request, int[] demuxHandle)
/releaseDemux
-
requestDescrambler(TunerDescramblerRequest request, int[] descramblerHandle)
/releaseDescrambler
-
requestCasSession(CasSessionRequest request, int[] casSessionHandle)
/releaseCasSession
-
requestLnb(TunerLnbRequest request, int[] lnbHandle)
/releaseLnb
Les classes de client et de demande sont répertoriées ci-dessous.
-
ResourceClientProfile
-
ResourcesReclaimListener
-
TunerFrontendRequest
-
TunerDemuxRequest
-
TunerDescramblerRequest
-
CasSessionRequest
-
TunerLnbRequest
Priorité client
TRM calcule la priorité du client en utilisant les paramètres du profil du client et la valeur de priorité du fichier de configuration. La priorité peut également être mise à jour par une valeur de priorité arbitraire du client.
Paramètres dans le profil du client
TRM récupère l'ID de processus à partir de mTvInputSessionId
pour décider si une application est une application de premier plan ou d'arrière-plan. Pour créer mTvInputSessionId
, TvInputService.onCreateSession
ou TvInputService.onCreateRecordingSession
initialise une session TIS.
mUseCase
indique le cas d'utilisation de la session. Les cas d'utilisation prédéfinis sont répertoriés ci-dessous.
TvInputService.PriorityHintUseCaseType {
PRIORITY_HINT_USE_CASE_TYPE_PLAYBACK
PRIORITY_HINT_USE_CASE_TYPE_LIVE
PRIORITY_HINT_USE_CASE_TYPE_RECORD,
PRIORITY_HINT_USE_CASE_TYPE_SCAN,
PRIORITY_HINT_USE_CASE_TYPE_BACKGROUND
}
Fichier de configuration
Fichier de configuration par défaut
Le fichier de configuration par défaut ci-dessous fournit des valeurs de priorité pour des cas d'utilisation prédéfinis. Les utilisateurs peuvent modifier les valeurs à l'aide d'un fichier de configuration personnalisé .
Cas d'utilisation | Premier plan | Fond |
---|---|---|
LIVE | 490 | 400 |
PLAYBACK | 480 | 300 |
RECORD | 600 | 500 |
SCAN | 450 | 200 |
BACKGROUND | 180 | 100 |
Fichier de configuration personnalisé
Les fournisseurs peuvent personnaliser le fichier de configuration /vendor/etc/tunerResourceManagerUseCaseConfig.xml
. Ce fichier est utilisé pour ajouter, supprimer ou mettre à jour les types de cas d'utilisation et les valeurs de priorité des cas d'utilisation. Le fichier personnalisé peut utiliser platform/hardware/interfaces/tv/tuner/1.0/config/tunerResourceManagerUseCaseConfigSample.xml
comme modèle.
Par exemple, un nouveau cas d'utilisation fournisseur est VENDOR_USE_CASE__[A-Z0-9]+, [0 - 1000]
. Le format doit suivre platform/hardware/interfaces/tv/tuner/1.0/config/tunerResourceManagerUseCaseConfig.xsd
.
Valeur de priorité arbitraire et valeur agréable
TRM fournit updateClientPriority
pour que le client mette à jour la valeur de priorité arbitraire et la valeur nice. La valeur de priorité arbitraire remplace la valeur de priorité calculée à partir du type de cas d'utilisation et de l'ID de session.
La valeur nice indique à quel point le comportement du client est indulgent lorsqu'il est en conflit avec un autre client. La valeur agréable diminue la valeur de priorité du client avant que sa valeur de priorité ne soit comparée au client difficile.
Mécanisme de récupération
Le diagramme ci-dessous montre comment les ressources sont récupérées et affectées lorsqu'un conflit de ressources se produit.
Figure 15. Schéma du mécanisme de récupération en cas de conflit entre ressources Tuner