Für Android 11 oder höher können Sie das Android Tuner-Framework verwenden, um A/V-Inhalte bereitzustellen. Das Framework nutzt die Hardware-Pipeline von Anbietern und eignet sich daher sowohl für Low-End- als auch für High-End-SoC. Das Framework bietet eine sichere Möglichkeit zur Bereitstellung von A/V-Inhalten, die durch eine vertrauenswürdige Ausführungsumgebung (TEE) und einen sicheren Medienpfad (SMP) geschützt sind, und ermöglicht so die Verwendung in einer stark eingeschränkten Inhaltsschutzumgebung.
Die standardisierte Schnittstelle zwischen Tuner und Android CAS führt zu einer schnelleren Integration zwischen Tuner-Anbietern und CAS-Anbietern. Die Tuner-Schnittstelle arbeitet mit MediaCodec
und AudioTrack
zusammen, um eine einheitliche Lösung für Android TV zu schaffen. Die Tuner-Schnittstelle unterstützt sowohl digitales als auch analoges Fernsehen basierend auf den wichtigsten Rundfunkstandards.
Komponenten
Für Android 11 sind drei Komponenten speziell für die TV-Plattform konzipiert.
- Tuner HAL: Eine Schnittstelle zwischen dem Framework und Anbietern
- Tuner SDK API: Eine Schnittstelle zwischen dem Framework und Apps
- Tuner Resource Manager (TRM): Koordiniert Tuner-HW-Ressourcen
Für Android 11 wurden die folgenden Komponenten erweitert.
- CAS V2
-
TvInputService
oder TV Input Service (TIS) -
TvInputManagerService
oder TV Input Manager Service (TIMS) -
MediaCodec
oder Mediencodec -
AudioTrack
oder Audiospur -
MediaResourceManager
oder Medienressourcenmanager (MRM)
Abbildung 1. Interaktionen zwischen Android TV-Komponenten
Merkmale
Frontend unterstützt die unten aufgeführten DTV-Standards.
- ATSC
- ATSC3
- DVB C/S/T
- ISDB S/S3/T
- Analog
Das Frontend in Android 12 mit Tuner HAL 1.1 oder höher unterstützt den unten aufgeführten DTV-Standard.
- DTMB
Demux unterstützt die folgenden Stream-Protokolle.
- Transportstrom (TS)
- MPEG-Medientransportprotokoll (MMTP)
- Internetprotokoll (IP)
- Typlängenwert (TLV)
- ATSC Link-Layer-Protokoll (ALP)
Descrambler unterstützt die folgenden Inhaltsschutzmaßnahmen.
- Sicherer Medienpfad
- Freier Medienpfad
- Sicherer lokaler Datensatz
- Sichere lokale Wiedergabe
Tuner-APIs unterstützen die folgenden Anwendungsfälle.
- Scan
- Live
- Wiedergabe
- Aufzeichnen
Tuner, MediaCodec
und AudioTrack
unterstützen die folgenden Datenflussmodi.
- ES-Nutzlast mit klarem Speicherpuffer
- ES-Nutzlast mit sicherem Speicherhandle
- Passthrough
Gesamtkonzept
Der Tuner-HAL wird zwischen dem Android-Framework und der Hardware des Anbieters definiert.
- Beschreibt, was das Framework vom Anbieter erwartet und wie der Anbieter dies tun könnte.
- Exportiert die Funktionalitäten von Frontend, Demux und Descrambler über die Schnittstellen
IFrontend
,IDemux
,IDescrambler
,IFilter
,IDvr
undILnb
in das Framework. - Enthält die Funktionen zur Integration des Tuner HAL mit anderen Framework-Komponenten wie
MediaCodec
undAudioTrack
.
Es werden eine Tuner-Java-Klasse und eine native Klasse erstellt.
- Mit der Tuner-Java-API können Apps über öffentliche APIs auf die Tuner-HAL zugreifen.
- Die native Klasse ermöglicht die Berechtigungskontrolle und die Verarbeitung großer Mengen an Aufnahme- oder Wiedergabedaten mit dem Tuner HAL.
- Das Native Tuner-Modul ist eine Brücke zwischen der Tuner-Java-Klasse und der Tuner-HAL.
Eine TRM-Klasse wird erstellt.
- Verwaltet begrenzte Tuner-Ressourcen wie Frontend, LNB, CAS-Sitzungen und ein TV-Eingabegerät über den TV-Eingang HAL.
- Wendet Regeln an, um unzureichende Ressourcen von Apps zurückzugewinnen. Die Standardregel ist der Vordergrundgewinn.
Media CAS und CAS HAL werden um die folgenden Funktionen erweitert.
- Öffnet CAS-Sitzungen für verschiedene Verwendungen und Algorithmen.
- Unterstützt dynamische CAS-Systeme wie CICAM-Entfernung und -Einfügung.
- Integriert sich in den Tuner HAL durch Bereitstellung von Schlüsseltokens.
MediaCodec
und AudioTrack
werden durch die folgenden Funktionen erweitert.
- Verwendet einen sicheren A/V-Speicher als Inhaltseingabe.
- Konfiguriert für die Hardware-A/V-Synchronisierung bei getunnelter Wiedergabe.
- Konfigurierte Unterstützung für
ES_payload
und Passthrough-Modus.
Abbildung 2. Diagramm der Komponenten im Tuner HAL
Gesamtworkflow
Die folgenden Diagramme veranschaulichen Anrufsequenzen für die Live-Übertragungswiedergabe.
Aufstellen
Abbildung 3. Setup-Sequenz für die Live-Übertragungswiedergabe
Umgang mit A/V
Abbildung 4. Handhabung von A/V für die Wiedergabe von Live-Übertragungen
Umgang mit verschlüsselten Inhalten
Abbildung 5. Umgang mit verschlüsselten Inhalten für die Live-Übertragungswiedergabe
Verarbeitung von A/V-Daten
Abbildung 6. A/V-Verarbeitung für die Live-Übertragungswiedergabe
Tuner-SDK-API
Die Tuner SDK-API verarbeitet die Interaktionen mit der Tuner-JNI, der Tuner-HAL und dem TunerResourceManager
. Die TIS-App verwendet die Tuner SDK-API, um auf Tuner-Ressourcen und Unterkomponenten wie Filter und Descrambler zuzugreifen. Frontend und Demux sind interne Komponenten.
Abbildung 7. Interaktionen mit der Tuner SDK API
Versionen
Ab Android 12 unterstützt die Tuner SDK API die neue Funktion in Tuner HAL 1.1, einem abwärtskompatiblen Versions-Upgrade von Tuner 1.0.
Verwenden Sie die folgende API, um die laufende HAL-Version zu überprüfen.
-
android.media.tv.tuner.TunerVersionChecker.getTunerVersion()
Die mindestens erforderliche HAL-Version finden Sie in der Dokumentation der neuen Android 12 APIs.
Pakete
Die Tuner SDK API stellt die vier folgenden Pakete bereit.
-
android.media.tv.tuner
-
android.media.tv.tuner.frontend
-
android.media.tv.tuner.filter
-
android.media.tv.tuner.dvr
Abbildung 8. Tuner SDK-API-Pakete
Android.media.tv.tuner
Das Tuner-Paket ist ein Einstiegspunkt für die Verwendung des Tuner-Frameworks. Die TIS-App verwendet das Paket, um Ressourceninstanzen zu initialisieren und abzurufen, indem sie die Anfangseinstellung und den Rückruf angibt.
-
tuner()
: Initialisiert eine Tuner-Instanz durch Angabe der ParameteruseCase
undsessionId
. -
tune()
: Erhält eine Frontend-Ressource und optimiert sie durch Angabe desFrontendSetting
-Parameters. -
openFilter()
: Erhält eine Filterinstanz durch Angabe des Filtertyps. -
openDvrRecorder()
: Erhält eine Aufzeichnungsinstanz durch Angabe der Puffergröße. -
openDvrPlayback()
: Erhält eine Wiedergabeinstanz durch Angabe der Puffergröße. -
openDescrambler()
: Erhält eine Descrambler-Instanz. -
openLnb()
: Erhält eine interne LNB-Instanz. -
openLnbByName()
: Erhält eine externe LNB-Instanz. -
openTimeFilter()
: Erhält eine Zeitfilterinstanz.
Das Tuner-Paket bietet Funktionalitäten, die nicht von den Filter-, DVR- und Frontend-Paketen abgedeckt werden. Die Funktionalitäten sind unten aufgeführt.
-
cancelTuning
-
scan
/cancelScanning
-
getAvSyncHwId
-
getAvSyncTime
-
connectCiCam1
/disconnectCiCam
-
shareFrontendFromTuner
-
updateResourcePriority
-
setOnTuneEventListener
-
setResourceLostListener
Android.media.tv.tuner.frontend
Das Frontend-Paket umfasst Sammlungen frontendbezogener Einstellungen, Informationen, Status, Ereignisse und Funktionen.
Klassen
FrontendSettings
wird für verschiedene DTV-Standards durch die folgenden Klassen abgeleitet.
-
AnalogFrontendSettings
-
Atsc3FrontendSettings
-
AtscFrontendSettings
-
DvbcFrontendSettings
-
DvbsFrontendSettings
-
DvbtFrontendSettings
-
Isdbs3FrontendSettings
-
IsdbsFrontendSettings
-
IsdbtFrontendSettings
Ab Android 12 mit Tuner HAL 1.1 oder höher wird der folgende DTV-Standard unterstützt.
-
DtmbFrontendSettings
FrontendCapabilities
wird für verschiedene DTV-Standards durch die folgenden Klassen abgeleitet.
-
AnalogFrontendCapabilities
-
Atsc3FrontendCapabilities
-
AtscFrontendCapabilities
-
DvbcFrontendCapabilities
-
DvbsFrontendCapabilities
-
DvbtFrontendCapabilities
-
Isdbs3FrontendCapabilities
-
IsdbsFrontendCapabilities
-
IsdbtFrontendCapabilities
Ab Android 12 mit Tuner HAL 1.1 oder höher wird der folgende DTV-Standard unterstützt.
-
DtmbFrontendCapabilities
FrontendInfo
ruft die Informationen des Frontends ab. FrontendStatus
ruft den aktuellen Status des Frontends ab. OnTuneEventListener
hört die Ereignisse im Frontend ab. Die TIS-App verwendet ScanCallback
um Scan-Nachrichten vom Frontend zu verarbeiten.
Kanalsuche
Um einen Fernseher einzurichten, scannt die App mögliche Frequenzen und erstellt eine Kanalliste, auf die Benutzer zugreifen können. TIS könnte Tuner.tune
, Tuner.scan(BLIND_SCAN)
oder Tuner.scan(AUTO_SCAN)
verwenden, um den Kanalscan abzuschließen.
Wenn TIS über genaue Übertragungsinformationen für das Signal verfügt, z. B. Frequenz, Standard (z. B. T/T2, S/S2) und zusätzliche erforderliche Informationen (z. B. PLD-ID), wird Tuner.tune
als schnellere Option empfohlen .
Wenn der Benutzer Tuner.tune
aufruft, passieren die folgenden Aktionen:
- TIS füllt
FrontendSettings
mithilfe vonTuner.tune
mit den erforderlichen Informationen. - Der HAL meldet Tune
LOCKED
Meldungen, wenn das Signal gesperrt ist. - TIS nutzt
Frontend.getStatus
um die notwendigen Informationen zu sammeln. - TIS wechselt zur nächsten verfügbaren Frequenz in seiner Frequenzliste.
TIS ruft Tuner.tune
erneut auf, bis alle Frequenzen ausgeschöpft sind.
Während der Optimierung können Sie stopTune()
oder close()
aufrufen, um den Tuner.tune
Aufruf anzuhalten oder zu beenden.
Tuner.scan(AUTO_SCAN)
Wenn TIS nicht über genügend Informationen verfügt, um Tuner.tune
zu verwenden, aber über eine Frequenzliste und einen Standardtyp (z. B. DVB T/C/S), dann wird Tuner.scan(AUTO_SCAN)
empfohlen.
Wenn der Benutzer Tuner.scan(AUTO_SCAN)
aufruft, passieren die folgenden Aktionen:
TIS verwendet
Tuner.scan(AUTO_SCAN)
mit mit Frequenz gefülltenFrontendSettings
.Der HAL meldet Scan-
LOCKED
-Meldungen, wenn das Signal gesperrt ist. Der HAL meldet möglicherweise auch andere Scan-Meldungen, um zusätzliche Informationen über das Signal bereitzustellen.TIS verwendet
Frontend.getStatus
, um notwendige Informationen zu sammeln.TIS ruft
Tuner.scan
auf, damit der HAL mit der nächsten Einstellung auf derselben Frequenz fortfährt. Wenn dieFrontendSettings
Struktur leer ist, verwendet die HAL die nächste verfügbare Einstellung. Andernfalls verwendet HALFrontendSettings
für einen einmaligen Scan und sendetEND
, um anzuzeigen, dass der Scanvorgang abgeschlossen ist.TIS wiederholt die oben genannten Aktionen, bis alle Einstellungen für die Frequenz erschöpft sind.
Der HAL sendet
END
, um anzuzeigen, dass der Scanvorgang abgeschlossen ist.TIS wechselt zur nächsten verfügbaren Frequenz in seiner Frequenzliste.
TIS ruft Tuner.scan(AUTO_SCAN)
erneut auf, bis alle Frequenzen erschöpft sind.
Während des Scanvorgangs können Sie stopScan()
oder close()
aufrufen, um den Scan anzuhalten oder zu beenden.
Tuner.scan(BLIND_SCAN)
Wenn TIS keine Häufigkeitsliste hat und der Anbieter-HAL nach der Häufigkeit des vom Benutzer angegebenen Frontends suchen kann, um die Frontend-Ressource zu erhalten, wird Tuner.scan(BLIND_SCAN)
empfohlen.
- TIS verwendet
Tuner.scan(BLIND_SCAN)
. InFrontendSettings
kann eine Häufigkeit für die Starthäufigkeit angegeben werden, TIS ignoriert jedoch andere Einstellungen inFrontendSettings
. - Der HAL meldet eine Scan-
LOCKED
-Meldung, wenn das Signal gesperrt ist. - TIS verwendet
Frontend.getStatus
, um notwendige Informationen zu sammeln. - TIS ruft
Tuner.scan
erneut auf, um mit dem Scannen fortzufahren. (FrontendSettings
wird ignoriert.) - TIS wiederholt die oben genannten Aktionen, bis alle Einstellungen für die Frequenz erschöpft sind. Der HAL erhöht die Frequenz, ohne dass eine Aktion von TIS erforderlich ist. Der HAL meldet
PROGRESS
.
TIS ruft Tuner.scan(AUTO_SCAN)
erneut auf, bis alle Frequenzen erschöpft sind. Der HAL meldet END
, um anzuzeigen, dass der Scanvorgang abgeschlossen ist.
Während des Scanvorgangs können Sie stopScan()
oder close()
aufrufen, um den Scan anzuhalten oder zu beenden.
Abbildung 9. Flussdiagramm eines TIS-Scans
Android.media.tv.tuner.filter
Das Filterpaket ist eine Sammlung von Filteroperationen sowie Konfigurationen, Einstellungen, Rückrufen und Ereignissen. Das Paket umfasst die folgenden Vorgänge. Die vollständige Liste der Vorgänge finden Sie im Android-Quellcode.
-
configure()
-
start()
-
stop()
-
flush()
-
read()
Die vollständige Liste finden Sie im Android-Quellcode.
FilterConfiguration
wird von den folgenden Klassen abgeleitet. Die Konfigurationen gelten für den Hauptfiltertyp und geben an, welches Protokoll der Filter zum Extrahieren von Daten verwendet.
-
AlpFilterConfiguration
-
IpFilterConfiguration
-
MmtpFilterConfiguration
-
TlvFilterConfiguration
-
TsFilterConfiguration
Die Einstellungen leiten sich aus den folgenden Klassen ab. Die Einstellungen gelten für den Filteruntertyp und geben an, welche Arten von Daten der Filter ausschließen kann.
-
SectionSettings
-
AvSettings
-
PesSettings
-
RecordSettings
-
DownloadSettings
FilterEvent
wird von den folgenden Klassen abgeleitet, um Ereignisse für verschiedene Arten von Daten zu melden.
-
SectionEvent
-
MediaEvent
-
PesEvent
-
TsRecordEvent
-
MmtpRecordEvent
-
TemiEvent
-
DownloadEvent
-
IpPayloadEvent
Ab Android 12 mit Tuner HAL 1.1 oder höher werden folgende Events unterstützt.
-
IpCidChangeEvent
-
RestartEvent
-
ScramblingStatusEvent
Ereignisse und Datenformat vom Filter
Filter Typ | Flaggen | Veranstaltungen | Datenbetrieb | Datei Format |
---|---|---|---|---|
TS.SECTION MMTP.SECTION IP.SECTION TLV.SECTION ALP.SECTION | isRaw: | Obligatorisch:DemuxFilterStatus::DATA_READY DemuxFilterStatus::DATA_OVERFLOW Empfohlen: DemuxFilterStatus::LOW_WATER DemuxFilterStatus::HIGH_WATER | Je nach Veranstaltung und internem Zeitplan ausführenFilter.read(buffer, offset, adjustedSize) einmal oder mehrmals.Die Daten werden vom MQ von HAL in den Client-Puffer kopiert. | Ein zusammengestelltes Sitzungspaket wird im FMQ durch ein anderes Sitzungspaket gefüllt. |
isRaw: | Obligatorisch:DemuxFilterEvent::DemuxFilterSectionEvent[n] DemuxFilterStatus::DATA_READY DemuxFilterStatus::DATA_OVERFLOW Optional: DemuxFilterStatus::LOW_WATER DemuxFilterStatus::HIGH_WATER | for i=0; i<n; i++ Die Daten werden vom MQ von HAL in den Client-Puffer kopiert. | ||
TS.PES | isRaw: | Obligatorisch:DemuxFilterStatus::DATA_READY DemuxFilterStatus::DATA_OVERFLOW Empfohlen: DemuxFilterStatus::LOW_WATER DemuxFilterStatus::HIGH_WATER | Je nach Veranstaltung und internem Zeitplan ausführenFilter.read(buffer, offset, adjustedSize) einmal oder mehrmals.Daten werden vom MQ des HAL in den Client-Puffer kopiert. | Ein zusammengestelltes PES-Paket wird im FMQ durch ein anderes PES-Paket gefüllt. |
isRaw: | Obligatorisch:DemuxFilterEvent::DemuxFilterPesEvent[n] DemuxFilterStatus::DATA_READY DemuxFilterStatus::DATA_OVERFLOW Optional: DemuxFilterStatus::LOW_WATER DemuxFilterStatus::HIGH_WATER | for i=0; i<n; i++ Die Daten werden vom MQ von HAL in den Client-Puffer kopiert. | ||
MMTP.PES | isRaw: | Obligatorisch:DemuxFilterStatus::DATA_READY DemuxFilterStatus::DATA_OVERFLOW Empfohlen: DemuxFilterStatus::LOW_WATER DemuxFilterStatus::HIGH_WATER | Je nach Veranstaltung und internem Zeitplan ausführenFilter.read(buffer, offset, adjustedSize) einmal oder mehrmals.Daten werden vom MQ des HAL in den Client-Puffer kopiert. | Ein zusammengestelltes MFU-Paket wird im FMQ durch ein anderes MFU-Paket gefüllt. |
isRaw: | Obligatorisch:DemuxFilterEvent::DemuxFilterPesEvent[n] DemuxFilterStatus::DATA_READY DemuxFilterStatus::DATA_OVERFLOW Optional: DemuxFilterStatus::LOW_WATER DemuxFilterStatus::HIGH_WATER | for i=0; i<n; i++ Daten werden vom MQ des HAL in den Client-Puffer kopiert. | ||
TS.TS | N / A | Obligatorisch:DemuxFilterStatus::DATA_READY DemuxFilterStatus::DATA_OVERFLOW Empfohlen: DemuxFilterStatus::LOW_WATER DemuxFilterStatus::HIGH_WATER | Je nach Veranstaltung und internem Zeitplan ausführenFilter.read(buffer, offset, adjustedSize) einmal oder mehrmals.Daten werden vom MQ des HAL in den Client-Puffer kopiert. | ts mit ts -Header herausgefiltertwird im FMQ ausgefüllt. |
TS.Audio TS.Video MMTP.Audio MMTP.Video | isPassthrough: | Optional:DemuxFilterStatus::DATA_READY DemuxFilterStatus::DATA_OVERFLOW | Der Client kann MediaCodec starten, nachdem er DemuxFilterStatus::DATA_READY empfangen hat.Der Client kann Filter.flush aufrufen, nachdem er DemuxFilterStatus::DATA_OVERFLOW empfangen hat. | N / A |
isPassthrough: | Obligatorisch:DemuxFilterEvent::DemuxFilterMediaEvent[n] DemuxFilterStatus::DATA_READY DemuxFilterStatus::DATA_OVERFLOW Optional: DemuxFilterStatus::LOW_WATER DemuxFilterStatus::HIGH_WATER | So verwenden Sie MediaCodec :for i=0; i<n; i++ So verwenden Sie Direct Audio von AudioTrack :for i=0; i<n; i++ | ES- oder teilweise ES-Daten im ION-Speicher. | |
TS.PCR IP.NTP ALP.PTP | N / A | Obligatorisch: N/A Optional: N/A | N / A | N / A |
TS.RECORD | N / A | Obligatorisch:DemuxFilterEvent::DemuxFilterTsRecordEvent[n] RecordStatus::DATA_READY RecordStatus::DATA_OVERFLOW RecordStatus::LOW_WATER RecordStatus::HIGH_WATER Optional: DemuxFilterStatus::DATA_READY DemuxFilterStatus::DATA_OVERFLOW DemuxFilterStatus::LOW_WATER DemuxFilterStatus::HIGH_WATER | Für Indexdaten:for i=0; i<n; i++ Führen Sie für aufgezeichnete Inhalte gemäß RecordStatus::* und internem Zeitplan einen der folgenden Schritte aus:
| Für Indexdaten: In der Ereignisnutzlast enthalten. Für aufgezeichnete Inhalte: Gemuxter TS-Stream, gefüllt mit FMQ. |
TS.TEMI | N / A | Obligatorisch:DemuxFilterEvent::DemuxFilterTemiEvent[n] Optional: DemuxFilterStatus::DATA_READY DemuxFilterStatus::DATA_OVERFLOW DemuxFilterStatus::LOW_WATER DemuxFilterStatus::HIGH_WATER | for i=0; i<n; i++ | N / A |
MMTP.MMTP | N / A | Obligatorisch:DemuxFilterStatus::DATA_READY DemuxFilterStatus::DATA_OVERFLOW Empfohlen: DemuxFilterStatus::LOW_WATER DemuxFilterStatus::HIGH_WATER | Je nach Veranstaltung und internem Zeitplan ausführenFilter.read(buffer, offset, adjustedSize) einmal oder mehrmals.Daten werden vom MQ des HAL in den Client-Puffer kopiert. | mmtp mit mmtp -Header herausgefiltertwird im FMQ ausgefüllt. |
MMTP.RECORD | N / A | Obligatorisch:DemuxFilterEvent::DemuxFilterMmtpRecordEvent[n] RecordStatus::DATA_READY RecordStatus::DATA_OVERFLOW RecordStatus::LOW_WATER RecordStatus::HIGH_WATER Optional: DemuxFilterStatus::DATA_READY DemuxFilterStatus::DATA_OVERFLOW DemuxFilterStatus::LOW_WATER DemuxFilterStatus::HIGH_WATER | Für Indexdaten: for i=0; i<n; i++ Führen Sie für aufgezeichnete Inhalte gemäß RecordStatus::* und internem Zeitplan einen der folgenden Schritte aus:
| Für Indexdaten: In der Ereignisnutzlast enthalten. Für aufgezeichnete Inhalte: Muxierter aufgezeichneter Stream, gefüllt mit FMQ. Wenn die Filterquelle für die Aufzeichnung TLV.TLV zu IP.IP mit Passthrough ist, verfügt der aufgezeichnete Stream über einen TLV- und IP-Header. |
MMTP.DOWNLOAD | N / A | Obligatorisch:DemuxFilterEvent::DemuxFilterDownloadEvent[n] DemuxFilterStatus::DATA_READY DemuxFilterStatus::DATA_OVERFLOW Optional: DemuxFilterStatus::LOW_WATER DemuxFilterStatus::HIGH_WATER | for i=0; i<n; i++ Filter.read(buffer, offset, DemuxFilterDownloadEvent[i].size) Die Daten werden vom MQ von HAL in den Client-Puffer kopiert. | Das Download-Paket wird im FMQ durch ein anderes IP-Download-Paket gefüllt. |
IP.IP_PAYLOAD | N / A | Obligatorisch:DemuxFilterEvent::DemuxFilterIpPayloadEvent[n] DemuxFilterStatus::DATA_READY DemuxFilterStatus::DATA_OVERFLOW Optional: DemuxFilterStatus::LOW_WATER DemuxFilterStatus::HIGH_WATER | for i=0; i<n; i++ Filter.read(buffer, offset, DemuxFilterIpPayloadEvent[i].size) Die Daten werden vom MQ von HAL in den Client-Puffer kopiert. | Das IP-Payload-Paket wird in FMQ durch ein anderes IP-Payload-Paket gefüllt. |
IP.IP TLV.TLV ALP.ALP | isPassthrough: | Optional:DemuxFilterStatus::DATA_READY DemuxFilterStatus::DATA_OVERFLOW | Der herausgefilterte Protokoll-Substream speist den nächsten Filter in der Filterkette. | N / A |
isPassthrough: | Obligatorisch:DemuxFilterStatus::DATA_READY DemuxFilterStatus::DATA_OVERFLOW Empfohlen: DemuxFilterStatus::LOW_WATER DemuxFilterStatus::HIGH_WATER | Je nach Veranstaltung und internem Zeitplan ausführenFilter.read(buffer, offset, adjustedSize) einmal oder mehrmals.Daten werden vom MQ des HAL in den Client-Puffer kopiert. | Der herausgefilterte Protokoll-Substrom mit Protokoll-Header wird in FMQ gefüllt. | |
IP.PAYLOAD_THROUGH TLV.PAYLOAD_THROUGH ALP.PAYLOAD_THROUGH | N / A | Optional:DemuxFilterStatus::DATA_READY DemuxFilterStatus::DATA_OVERFLOW | Die herausgefilterte Protokollnutzlast speist den nächsten Filter in der Filterkette. | N / A |
Beispielablauf zur Verwendung eines Filters zum Erstellen von PSI/SI
Abbildung 10. Ablauf zum Aufbau von PSI/SI
Öffnen Sie einen Filter.
Filter filter = tuner.openFilter( Filter.TYPE_TS, Filter.SUBTYPE_SECTION, /* bufferSize */1000, executor, filterCallback );
Konfigurieren und starten Sie den Filter.
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();
SectionEvent
verarbeiten.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); } } } };
Beispielablauf zur Verwendung von MediaEvent aus dem Filter
Abbildung 11. Ablauf zur Verwendung von MediaEvent aus dem Filter
- Öffnen, konfigurieren und starten Sie die A/V-Filter.
-
MediaEvent
verarbeiten. -
MediaEvent
empfangen. - Stellen Sie den linearen Block in die
codec
. - Lassen Sie den A/V-Griff los, wenn die Daten verbraucht sind.
Android.media.tv.tuner.dvr
DvrRecorder
bietet diese Aufnahmemethoden.
-
configure
-
attachFilter
-
detachFilter
-
start
-
flush
-
stop
-
setFileDescriptor
-
write
DvrPlayback
stellt diese Methoden für die Wiedergabe bereit.
-
configure
-
start
-
flush
-
stop
-
setFileDescriptor
-
read
DvrSettings
wird zum Konfigurieren DvrRecorder
und DvrPlayback
verwendet. OnPlaybackStatusChangedListener
und OnRecordStatusChangedListener
werden verwendet, um den Status einer DVR-Instanz zu melden.
Beispielablauf zum Starten eines Datensatzes
Abbildung 12. Ablauf zum Starten einer Aufzeichnung
Öffnen, konfigurieren und starten Sie
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();
Empfangen Sie
RecordEvent
und rufen Sie die Indexinformationen ab.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. } } } };
Initialisieren Sie
OnRecordStatusChangedListener
und speichern Sie die Datensatzdaten.OnRecordStatusChangedListener listener = new OnRecordStatusChangedListener() { @Override public void onRecordStatusChanged(int status) { // a customized way to consume data efficiently by using status as a hint. if (status == Filter.STATUS_DATA_READY) { recorder.write(size); } } };
Tuner HAL
Der Tuner HAL folgt HIDL und definiert die Schnittstelle zwischen dem Framework und der Hardware des Anbieters. Anbieter nutzen die Schnittstelle zur Implementierung des Tuner-HAL und das Framework verwendet sie zur Kommunikation mit der Tuner-HAL-Implementierung.
Module
Tuner HAL 1.0
Module | Grundlegende Steuerelemente | Modulspezifische Steuerelemente | HAL-Dateien |
---|---|---|---|
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 (abgeleitet von Tuner HAL 1.0)
Module | Grundlegende Steuerelemente | Modulspezifische Steuerelemente | HAL-Dateien |
---|---|---|---|
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 |
Abbildung 13. Diagramm der Interaktionen zwischen den Tuner-HAL-Modulen
Filterverknüpfung
Der Tuner HAL unterstützt die Filterverknüpfung, sodass Filter für mehrere Ebenen mit anderen Filtern verknüpft werden können. Die Filter folgen den unten aufgeführten Regeln.
- Filter sind als Baum verknüpft, ein enger Pfad ist nicht zulässig.
- Der Wurzelknoten ist Demux.
- Filter arbeiten unabhängig.
- Alle Filter beginnen mit der Datenerfassung.
- Die Filterverknüpfung spült beim letzten Filter.
Der folgende Codeblock und Abbildung 14 veranschaulichen ein Beispiel für das Filtern mehrerer Ebenen.
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>)
}
Abbildung 14. Flussdiagramm einer Filterverknüpfung für mehrere Ebenen
Tuner-Ressourcenmanager
Vor Tuner Resource Manager (TRM) war für den Wechsel zwischen zwei Apps dieselbe Tuner-Hardware erforderlich. Das TV Input Framework (TIF) verwendet einen „First-to-acquire win“-Mechanismus, was bedeutet, dass diejenige App, die die Ressource zuerst erhält, die Ressource behält. Für einige komplizierte Anwendungsfälle ist dieser Mechanismus jedoch möglicherweise nicht ideal.
TRM wird als Systemdienst ausgeführt, um die Tuner-, TVInput
und CAS-Hardwareressourcen für Apps zu verwalten. TRM verwendet einen „Vordergrundgewinn“-Mechanismus, der die Priorität der App basierend auf dem Vordergrund- oder Hintergrundstatus der App und dem Anwendungsfalltyp berechnet. TRM gewährt oder entzieht die Ressource basierend auf der Priorität. TRM zentralisiert die ATV-Ressourcenverwaltung für Rundfunk, OTT und DVR.
TRM-Schnittstelle
TRM stellt AIDL-Schnittstellen in ITunerResourceManager.aidl
für das Tuner-Framework, MediaCas
und TvInputHardwareManager
zur Verfügung, um Ressourcen zu registrieren, anzufordern oder freizugeben.
Nachfolgend sind Schnittstellen zur Clientverwaltung aufgeführt.
-
registerClientProfile(in ResourceClientProfile profile, IResourcesReclaimListener listener, out int[] clientId)
-
unregisterClientProfile(in int clientId)
Die Schnittstellen zum Anfordern und Freigeben von Ressourcen sind unten aufgeführt.
-
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
Client- und Anforderungsklassen sind unten aufgeführt.
-
ResourceClientProfile
-
ResourcesReclaimListener
-
TunerFrontendRequest
-
TunerDemuxRequest
-
TunerDescramblerRequest
-
CasSessionRequest
-
TunerLnbRequest
Kundenpriorität
TRM berechnet die Priorität des Clients anhand von Parametern aus dem Profil des Clients und dem Prioritätswert aus der Konfigurationsdatei. Die Priorität kann auch durch einen beliebigen Prioritätswert vom Client aktualisiert werden.
Parameter im Kundenprofil
TRM ruft die Prozess-ID von mTvInputSessionId
ab, um zu entscheiden, ob eine App eine Vordergrund- oder Hintergrund-App ist. Um mTvInputSessionId
zu erstellen, initialisiert TvInputService.onCreateSession
oder TvInputService.onCreateRecordingSession
eine TIS-Sitzung.
mUseCase
gibt den Anwendungsfall der Sitzung an. Die vordefinierten Anwendungsfälle sind unten aufgeführt.
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
}
Konfigurationsdatei
Standardkonfigurationsdatei
Die folgende Standardkonfigurationsdatei stellt Prioritätswerte für vordefinierte Anwendungsfälle bereit. Benutzer können die Werte mithilfe einer benutzerdefinierten Konfigurationsdatei ändern.
Anwendungsfall | Vordergrund | Hintergrund |
---|---|---|
LIVE | 490 | 400 |
PLAYBACK | 480 | 300 |
RECORD | 600 | 500 |
SCAN | 450 | 200 |
BACKGROUND | 180 | 100 |
Angepasste Konfigurationsdatei
Anbieter können die Konfigurationsdatei /vendor/etc/tunerResourceManagerUseCaseConfig.xml
anpassen. Diese Datei wird zum Hinzufügen, Entfernen oder Aktualisieren der Anwendungsfalltypen und der Anwendungsfallprioritätswerte verwendet. Die angepasste Datei kann platform/hardware/interfaces/tv/tuner/1.0/config/tunerResourceManagerUseCaseConfigSample.xml
als Vorlage verwenden.
Ein neuer Anwendungsfall eines Anbieters ist beispielsweise VENDOR_USE_CASE__[A-Z0-9]+, [0 - 1000]
. Das Format sollte platform/hardware/interfaces/tv/tuner/1.0/config/tunerResourceManagerUseCaseConfig.xsd
folgen.
Beliebiger Prioritätswert und netter Wert
TRM stellt updateClientPriority
für den Client bereit, um den willkürlichen Prioritätswert und den netten Wert zu aktualisieren. Der beliebige Prioritätswert überschreibt den aus Anwendungsfalltyp und Sitzungs-ID berechneten Prioritätswert.
Der nette Wert gibt an, wie nachsichtig sich der Klient im Konflikt mit einem anderen Klienten verhält. Der nette Wert verringert den Prioritätswert des Clients, bevor sein Prioritätswert mit dem herausfordernden Client verglichen wird.
Rückforderungsmechanismus
Das folgende Diagramm zeigt, wie Ressourcen zurückgefordert und zugewiesen werden, wenn ein Ressourcenkonflikt auftritt.
Abbildung 15. Diagramm des Wiederherstellungsmechanismus für einen Konflikt zwischen Tuner-Ressourcen
,Für Android 11 oder höher können Sie das Android Tuner-Framework verwenden, um A/V-Inhalte bereitzustellen. Das Framework nutzt die Hardware-Pipeline von Anbietern und eignet sich daher sowohl für Low-End- als auch für High-End-SoC. Das Framework bietet eine sichere Möglichkeit zur Bereitstellung von A/V-Inhalten, die durch eine vertrauenswürdige Ausführungsumgebung (TEE) und einen sicheren Medienpfad (SMP) geschützt sind, und ermöglicht so die Verwendung in einer stark eingeschränkten Inhaltsschutzumgebung.
Die standardisierte Schnittstelle zwischen Tuner und Android CAS führt zu einer schnelleren Integration zwischen Tuner-Anbietern und CAS-Anbietern. Die Tuner-Schnittstelle arbeitet mit MediaCodec
und AudioTrack
zusammen, um eine einheitliche Lösung für Android TV zu schaffen. Die Tuner-Schnittstelle unterstützt sowohl digitales als auch analoges Fernsehen basierend auf den wichtigsten Rundfunkstandards.
Komponenten
Für Android 11 sind drei Komponenten speziell für die TV-Plattform konzipiert.
- Tuner HAL: Eine Schnittstelle zwischen dem Framework und Anbietern
- Tuner SDK API: Eine Schnittstelle zwischen dem Framework und Apps
- Tuner Resource Manager (TRM): Koordiniert Tuner-HW-Ressourcen
Für Android 11 wurden die folgenden Komponenten erweitert.
- CAS V2
-
TvInputService
oder TV Input Service (TIS) -
TvInputManagerService
oder TV Input Manager Service (TIMS) -
MediaCodec
oder Mediencodec -
AudioTrack
oder Audiospur -
MediaResourceManager
oder Medienressourcenmanager (MRM)
Abbildung 1. Interaktionen zwischen Android TV-Komponenten
Merkmale
Frontend unterstützt die unten aufgeführten DTV-Standards.
- ATSC
- ATSC3
- DVB C/S/T
- ISDB S/S3/T
- Analog
Das Frontend in Android 12 mit Tuner HAL 1.1 oder höher unterstützt den unten aufgeführten DTV-Standard.
- DTMB
Demux unterstützt die folgenden Stream-Protokolle.
- Transportstrom (TS)
- MPEG-Medientransportprotokoll (MMTP)
- Internetprotokoll (IP)
- Typlängenwert (TLV)
- ATSC Link-Layer-Protokoll (ALP)
Descrambler unterstützt die folgenden Inhaltsschutzmaßnahmen.
- Sicherer Medienpfad
- Freier Medienpfad
- Sicherer lokaler Datensatz
- Sichere lokale Wiedergabe
Tuner-APIs unterstützen die folgenden Anwendungsfälle.
- Scan
- Live
- Wiedergabe
- Aufzeichnen
Tuner, MediaCodec
und AudioTrack
unterstützen die folgenden Datenflussmodi.
- ES-Nutzlast mit klarem Speicherpuffer
- ES-Nutzlast mit sicherem Speicherhandle
- Passthrough
Gesamtkonzept
Der Tuner-HAL wird zwischen dem Android-Framework und der Hardware des Anbieters definiert.
- Beschreibt, was das Framework vom Anbieter erwartet und wie der Anbieter dies tun könnte.
- Exportiert die Funktionalitäten von Frontend, Demux und Descrambler über die Schnittstellen
IFrontend
,IDemux
,IDescrambler
,IFilter
,IDvr
undILnb
in das Framework. - Enthält die Funktionen zur Integration des Tuner HAL mit anderen Framework-Komponenten wie
MediaCodec
undAudioTrack
.
Es werden eine Tuner-Java-Klasse und eine native Klasse erstellt.
- Mit der Tuner-Java-API können Apps über öffentliche APIs auf die Tuner-HAL zugreifen.
- Die native Klasse ermöglicht die Berechtigungskontrolle und die Verarbeitung großer Mengen an Aufnahme- oder Wiedergabedaten mit dem Tuner HAL.
- Das Native Tuner-Modul ist eine Brücke zwischen der Tuner-Java-Klasse und der Tuner-HAL.
Eine TRM-Klasse wird erstellt.
- Verwaltet begrenzte Tuner-Ressourcen wie Frontend, LNB, CAS-Sitzungen und ein TV-Eingabegerät über den TV-Eingang HAL.
- Wendet Regeln an, um unzureichende Ressourcen von Apps zurückzugewinnen. Die Standardregel ist der Vordergrundgewinn.
Media CAS und CAS HAL werden um die folgenden Funktionen erweitert.
- Öffnet CAS-Sitzungen für verschiedene Verwendungen und Algorithmen.
- Unterstützt dynamische CAS-Systeme wie CICAM-Entfernung und -Einfügung.
- Integriert sich in den Tuner HAL durch Bereitstellung von Schlüsseltokens.
MediaCodec
und AudioTrack
werden durch die folgenden Funktionen erweitert.
- Verwendet einen sicheren A/V-Speicher als Inhaltseingabe.
- Konfiguriert für die Hardware-A/V-Synchronisierung bei getunnelter Wiedergabe.
- Konfigurierte Unterstützung für
ES_payload
und Passthrough-Modus.
Abbildung 2. Diagramm der Komponenten im Tuner HAL
Gesamtworkflow
Die folgenden Diagramme veranschaulichen Anrufsequenzen für die Live-Übertragungswiedergabe.
Aufstellen
Abbildung 3. Setup-Sequenz für die Live-Übertragungswiedergabe
Umgang mit A/V
Abbildung 4. Handhabung von A/V für die Wiedergabe von Live-Übertragungen
Umgang mit verschlüsselten Inhalten
Abbildung 5. Umgang mit verschlüsselten Inhalten für die Live-Übertragungswiedergabe
Verarbeitung von A/V-Daten
Abbildung 6. A/V-Verarbeitung für die Live-Übertragungswiedergabe
Tuner-SDK-API
Die Tuner SDK-API verarbeitet die Interaktionen mit der Tuner-JNI, der Tuner-HAL und dem TunerResourceManager
. Die TIS-App verwendet die Tuner SDK-API, um auf Tuner-Ressourcen und Unterkomponenten wie Filter und Descrambler zuzugreifen. Frontend und Demux sind interne Komponenten.
Abbildung 7. Interaktionen mit der Tuner SDK API
Versionen
Ab Android 12 unterstützt die Tuner SDK API die neue Funktion in Tuner HAL 1.1, einem abwärtskompatiblen Versions-Upgrade von Tuner 1.0.
Verwenden Sie die folgende API, um die laufende HAL-Version zu überprüfen.
-
android.media.tv.tuner.TunerVersionChecker.getTunerVersion()
Die mindestens erforderliche HAL-Version finden Sie in der Dokumentation der neuen Android 12 APIs.
Pakete
Die Tuner SDK API stellt die vier folgenden Pakete bereit.
-
android.media.tv.tuner
-
android.media.tv.tuner.frontend
-
android.media.tv.tuner.filter
-
android.media.tv.tuner.dvr
Abbildung 8. Tuner SDK-API-Pakete
Android.media.tv.tuner
Das Tuner-Paket ist ein Einstiegspunkt für die Verwendung des Tuner-Frameworks. Die TIS-App verwendet das Paket, um Ressourceninstanzen zu initialisieren und abzurufen, indem sie die Anfangseinstellung und den Rückruf angibt.
-
tuner()
: Initialisiert eine Tuner-Instanz durch Angabe der ParameteruseCase
undsessionId
. -
tune()
: Erhält eine Frontend-Ressource und optimiert sie durch Angabe desFrontendSetting
-Parameters. -
openFilter()
: Erhält eine Filterinstanz durch Angabe des Filtertyps. -
openDvrRecorder()
: Erhält eine Aufzeichnungsinstanz durch Angabe der Puffergröße. -
openDvrPlayback()
: Erhält eine Wiedergabeinstanz durch Angabe der Puffergröße. -
openDescrambler()
: Erhält eine Descrambler-Instanz. -
openLnb()
: Erhält eine interne LNB-Instanz. -
openLnbByName()
: Erhält eine externe LNB-Instanz. -
openTimeFilter()
: Erhält eine Zeitfilterinstanz.
Das Tuner-Paket bietet Funktionalitäten, die nicht von den Filter-, DVR- und Frontend-Paketen abgedeckt werden. Die Funktionalitäten sind unten aufgeführt.
-
cancelTuning
-
scan
/cancelScanning
-
getAvSyncHwId
-
getAvSyncTime
-
connectCiCam1
/disconnectCiCam
-
shareFrontendFromTuner
-
updateResourcePriority
-
setOnTuneEventListener
-
setResourceLostListener
Android.media.tv.tuner.frontend
Das Frontend-Paket umfasst Sammlungen frontendbezogener Einstellungen, Informationen, Status, Ereignisse und Funktionen.
Klassen
FrontendSettings
wird für verschiedene DTV-Standards durch die folgenden Klassen abgeleitet.
-
AnalogFrontendSettings
-
Atsc3FrontendSettings
-
AtscFrontendSettings
-
DvbcFrontendSettings
-
DvbsFrontendSettings
-
DvbtFrontendSettings
-
Isdbs3FrontendSettings
-
IsdbsFrontendSettings
-
IsdbtFrontendSettings
Ab Android 12 mit Tuner HAL 1.1 oder höher wird der folgende DTV-Standard unterstützt.
-
DtmbFrontendSettings
FrontendCapabilities
wird für verschiedene DTV-Standards durch die folgenden Klassen abgeleitet.
-
AnalogFrontendCapabilities
-
Atsc3FrontendCapabilities
-
AtscFrontendCapabilities
-
DvbcFrontendCapabilities
-
DvbsFrontendCapabilities
-
DvbtFrontendCapabilities
-
Isdbs3FrontendCapabilities
-
IsdbsFrontendCapabilities
-
IsdbtFrontendCapabilities
Ab Android 12 mit Tuner HAL 1.1 oder höher wird der folgende DTV-Standard unterstützt.
-
DtmbFrontendCapabilities
FrontendInfo
ruft die Informationen des Frontends ab. FrontendStatus
ruft den aktuellen Status des Frontends ab. OnTuneEventListener
hört die Ereignisse im Frontend ab. Die TIS-App verwendet ScanCallback
um Scan-Nachrichten vom Frontend zu verarbeiten.
Kanalsuche
Um einen Fernseher einzurichten, scannt die App mögliche Frequenzen und erstellt eine Kanalliste, auf die Benutzer zugreifen können. TIS könnte Tuner.tune
, Tuner.scan(BLIND_SCAN)
oder Tuner.scan(AUTO_SCAN)
verwenden, um den Kanalscan abzuschließen.
Wenn TIS über genaue Übertragungsinformationen für das Signal verfügt, z. B. Frequenz, Standard (z. B. T/T2, S/S2) und zusätzliche erforderliche Informationen (z. B. PLD-ID), wird Tuner.tune
als schnellere Option empfohlen .
Wenn der Benutzer Tuner.tune
aufruft, passieren die folgenden Aktionen:
- TIS füllt
FrontendSettings
mithilfe vonTuner.tune
mit den erforderlichen Informationen. - Der HAL meldet Tune
LOCKED
Meldungen, wenn das Signal gesperrt ist. - TIS nutzt
Frontend.getStatus
um die notwendigen Informationen zu sammeln. - TIS wechselt zur nächsten verfügbaren Frequenz in seiner Frequenzliste.
TIS ruft Tuner.tune
erneut auf, bis alle Frequenzen ausgeschöpft sind.
Während der Optimierung können Sie stopTune()
oder close()
aufrufen, um den Tuner.tune
Aufruf anzuhalten oder zu beenden.
Tuner.scan(AUTO_SCAN)
Wenn TIS nicht über genügend Informationen verfügt, um Tuner.tune
zu verwenden, aber über eine Frequenzliste und einen Standardtyp (z. B. DVB T/C/S), dann wird Tuner.scan(AUTO_SCAN)
empfohlen.
Wenn der Benutzer Tuner.scan(AUTO_SCAN)
aufruft, passieren die folgenden Aktionen:
TIS verwendet
Tuner.scan(AUTO_SCAN)
mit mit Frequenz gefülltenFrontendSettings
.Der HAL meldet Scan-
LOCKED
-Meldungen, wenn das Signal gesperrt ist. Der HAL meldet möglicherweise auch andere Scan-Meldungen, um zusätzliche Informationen über das Signal bereitzustellen.TIS verwendet
Frontend.getStatus
, um notwendige Informationen zu sammeln.TIS ruft
Tuner.scan
auf, damit der HAL mit der nächsten Einstellung auf derselben Frequenz fortfährt. Wenn dieFrontendSettings
Struktur leer ist, verwendet die HAL die nächste verfügbare Einstellung. Andernfalls verwendet HALFrontendSettings
für einen einmaligen Scan und sendetEND
, um anzuzeigen, dass der Scanvorgang abgeschlossen ist.TIS wiederholt die oben genannten Aktionen, bis alle Einstellungen für die Frequenz erschöpft sind.
Der HAL sendet
END
, um anzuzeigen, dass der Scanvorgang abgeschlossen ist.TIS wechselt zur nächsten verfügbaren Frequenz in seiner Frequenzliste.
TIS ruft Tuner.scan(AUTO_SCAN)
erneut auf, bis alle Frequenzen erschöpft sind.
Während des Scanvorgangs können Sie stopScan()
oder close()
aufrufen, um den Scan anzuhalten oder zu beenden.
Tuner.scan(BLIND_SCAN)
Wenn TIS keine Häufigkeitsliste hat und der Anbieter-HAL nach der Häufigkeit des vom Benutzer angegebenen Frontends suchen kann, um die Frontend-Ressource zu erhalten, wird Tuner.scan(BLIND_SCAN)
empfohlen.
- TIS verwendet
Tuner.scan(BLIND_SCAN)
. InFrontendSettings
kann eine Häufigkeit für die Starthäufigkeit angegeben werden, TIS ignoriert jedoch andere Einstellungen inFrontendSettings
. - Der HAL meldet eine Scan-
LOCKED
-Meldung, wenn das Signal gesperrt ist. - TIS verwendet
Frontend.getStatus
, um notwendige Informationen zu sammeln. - TIS ruft
Tuner.scan
erneut auf, um mit dem Scannen fortzufahren. (FrontendSettings
wird ignoriert.) - TIS wiederholt die oben genannten Aktionen, bis alle Einstellungen für die Frequenz erschöpft sind. Der HAL erhöht die Frequenz, ohne dass eine Aktion von TIS erforderlich ist. Der HAL meldet
PROGRESS
.
TIS ruft Tuner.scan(AUTO_SCAN)
erneut auf, bis alle Frequenzen erschöpft sind. Der HAL meldet END
, um anzuzeigen, dass der Scanvorgang abgeschlossen ist.
Während des Scanvorgangs können Sie stopScan()
oder close()
aufrufen, um den Scan anzuhalten oder zu beenden.
Abbildung 9. Flussdiagramm eines TIS-Scans
Android.media.tv.tuner.filter
Das Filterpaket ist eine Sammlung von Filteroperationen sowie Konfigurationen, Einstellungen, Rückrufen und Ereignissen. Das Paket umfasst die folgenden Vorgänge. Die vollständige Liste der Vorgänge finden Sie im Android-Quellcode.
-
configure()
-
start()
-
stop()
-
flush()
-
read()
Die vollständige Liste finden Sie im Android-Quellcode.
FilterConfiguration
wird von den folgenden Klassen abgeleitet. Die Konfigurationen gelten für den Hauptfiltertyp und geben an, welches Protokoll der Filter zum Extrahieren von Daten verwendet.
-
AlpFilterConfiguration
-
IpFilterConfiguration
-
MmtpFilterConfiguration
-
TlvFilterConfiguration
-
TsFilterConfiguration
Die Einstellungen leiten sich aus den folgenden Klassen ab. Die Einstellungen gelten für den Filter -Subtyp und geben an, welche Arten von Daten der Filter ausschließen kann.
-
SectionSettings
-
AvSettings
-
PesSettings
-
RecordSettings
-
DownloadSettings
FilterEvent
wird aus den folgenden Klassen abgeleitet, um Ereignisse für verschiedene Arten von Daten zu melden.
-
SectionEvent
-
MediaEvent
-
PesEvent
-
TsRecordEvent
-
MmtpRecordEvent
-
TemiEvent
-
DownloadEvent
-
IpPayloadEvent
Von Android 12 mit Tuner HAL 1.1 oder höher werden die folgenden Ereignisse unterstützt.
-
IpCidChangeEvent
-
RestartEvent
-
ScramblingStatusEvent
Ereignisse und Datenformat aus Filter
Filter Typ | Flaggen | Veranstaltungen | Datenbetrieb | Datei Format |
---|---|---|---|---|
TS.SECTION MMTP.SECTION IP.SECTION TLV.SECTION ALP.SECTION | isRaw: | Obligatorisch:DemuxFilterStatus::DATA_READY DemuxFilterStatus::DATA_OVERFLOW Empfohlen: DemuxFilterStatus::LOW_WATER DemuxFilterStatus::HIGH_WATER | Nach Ereignis und dem internen Zeitplan laufenFilter.read(buffer, offset, adjustedSize) eins oder mehrmals.Die Daten werden vom MQ von HAL in den Clientpuffer kopiert. | Ein zusammengebautes Sitzungspaket wird von einem anderen Sitzungspaket FMQ ausgefüllt. |
isRaw: | Obligatorisch:DemuxFilterEvent::DemuxFilterSectionEvent[n] DemuxFilterStatus::DATA_READY DemuxFilterStatus::DATA_OVERFLOW Optional: DemuxFilterStatus::LOW_WATER DemuxFilterStatus::HIGH_WATER | for i=0; i<n; i++ Die Daten werden vom MQ von HAL in den Clientpuffer kopiert. | ||
TS.PES | isRaw: | Obligatorisch:DemuxFilterStatus::DATA_READY DemuxFilterStatus::DATA_OVERFLOW Empfohlen: DemuxFilterStatus::LOW_WATER DemuxFilterStatus::HIGH_WATER | Nach Ereignis und dem internen Zeitplan laufenFilter.read(buffer, offset, adjustedSize) eins oder mehrmals.Die Daten werden vom MQ des Hals in den Clientpuffer kopiert. | Ein zusammengebautes PES -Paket wird in FMQ von einem anderen PES -Paket gefüllt. |
isRaw: | Obligatorisch:DemuxFilterEvent::DemuxFilterPesEvent[n] DemuxFilterStatus::DATA_READY DemuxFilterStatus::DATA_OVERFLOW Optional: DemuxFilterStatus::LOW_WATER DemuxFilterStatus::HIGH_WATER | for i=0; i<n; i++ Die Daten werden vom MQ von HAL in den Clientpuffer kopiert. | ||
MMTP.PES | isRaw: | Obligatorisch:DemuxFilterStatus::DATA_READY DemuxFilterStatus::DATA_OVERFLOW Empfohlen: DemuxFilterStatus::LOW_WATER DemuxFilterStatus::HIGH_WATER | Nach Ereignis und dem internen Zeitplan laufenFilter.read(buffer, offset, adjustedSize) eins oder mehrmals.Die Daten werden vom MQ des Hals in den Clientpuffer kopiert. | Ein zusammengebautes MFU -Paket wird in FMQ von einem anderen MFU -Paket gefüllt. |
isRaw: | Obligatorisch:DemuxFilterEvent::DemuxFilterPesEvent[n] DemuxFilterStatus::DATA_READY DemuxFilterStatus::DATA_OVERFLOW Optional: DemuxFilterStatus::LOW_WATER DemuxFilterStatus::HIGH_WATER | for i=0; i<n; i++ Die Daten werden vom MQ des Hals in den Clientpuffer kopiert. | ||
TS.TS | N / A | Obligatorisch:DemuxFilterStatus::DATA_READY DemuxFilterStatus::DATA_OVERFLOW Empfohlen: DemuxFilterStatus::LOW_WATER DemuxFilterStatus::HIGH_WATER | Nach Ereignis und dem internen Zeitplan laufenFilter.read(buffer, offset, adjustedSize) eins oder mehrmals.Die Daten werden vom MQ des Hals in den Clientpuffer kopiert. | ts mit ts -Header herausgefiltertist in fmq gefüllt. |
TS.Audio TS.Video MMTP.Audio MMTP.Video | isPassthrough: | Optional:DemuxFilterStatus::DATA_READY DemuxFilterStatus::DATA_OVERFLOW | Der Client kann MediaCodec starten, nachdem er DemuxFilterStatus::DATA_READY empfangen hat.Der Client kann Filter.flush aufrufen, nachdem er DemuxFilterStatus::DATA_OVERFLOW empfangen hat. | N / A |
isPassthrough: | Obligatorisch:DemuxFilterEvent::DemuxFilterMediaEvent[n] DemuxFilterStatus::DATA_READY DemuxFilterStatus::DATA_OVERFLOW Optional: DemuxFilterStatus::LOW_WATER DemuxFilterStatus::HIGH_WATER | MediaCodec verwenden:for i=0; i<n; i++ Direktes Audio AudioTrack -Audio zu verwenden:for i=0; i<n; i++ | Es oder partielle Daten im Ionenspeicher. | |
TS.PCR IP.NTP ALP.PTP | N / A | Obligatorisch: n/a Optional: n/a | N / A | N / A |
TS.RECORD | N / A | Obligatorisch:DemuxFilterEvent::DemuxFilterTsRecordEvent[n] RecordStatus::DATA_READY RecordStatus::DATA_OVERFLOW RecordStatus::LOW_WATER RecordStatus::HIGH_WATER Optional: DemuxFilterStatus::DATA_READY DemuxFilterStatus::DATA_OVERFLOW DemuxFilterStatus::LOW_WATER DemuxFilterStatus::HIGH_WATER | Für Indexdaten:for i=0; i<n; i++ Führen Sie für aufgezeichnete Inhalte gemäß RecordStatus::* und internem Zeitplan einen der folgenden:
| Für Indexdaten: in der Ereignisnutzlast getragen. Für aufgezeichnete Inhalte: Muxed TS Stream füllte FMQ. |
TS.TEMI | N / A | Obligatorisch:DemuxFilterEvent::DemuxFilterTemiEvent[n] Optional: DemuxFilterStatus::DATA_READY DemuxFilterStatus::DATA_OVERFLOW DemuxFilterStatus::LOW_WATER DemuxFilterStatus::HIGH_WATER | for i=0; i<n; i++ | N / A |
MMTP.MMTP | N / A | Obligatorisch:DemuxFilterStatus::DATA_READY DemuxFilterStatus::DATA_OVERFLOW Empfohlen: DemuxFilterStatus::LOW_WATER DemuxFilterStatus::HIGH_WATER | Nach Ereignis und dem internen Zeitplan laufenFilter.read(buffer, offset, adjustedSize) eins oder mehrmals.Die Daten werden vom MQ des Hals in den Clientpuffer kopiert. | mmtp mit mmtp -Header herausgefiltertist in fmq gefüllt. |
MMTP.RECORD | N / A | Obligatorisch:DemuxFilterEvent::DemuxFilterMmtpRecordEvent[n] RecordStatus::DATA_READY RecordStatus::DATA_OVERFLOW RecordStatus::LOW_WATER RecordStatus::HIGH_WATER Optional: DemuxFilterStatus::DATA_READY DemuxFilterStatus::DATA_OVERFLOW DemuxFilterStatus::LOW_WATER DemuxFilterStatus::HIGH_WATER | Für Indexdaten: for i=0; i<n; i++ Führen Sie für aufgezeichnete Inhalte gemäß RecordStatus::* und internem Zeitplan einen der folgenden:
| Für Indexdaten: in der Ereignisnutzlast getragen. Für aufgezeichnete Inhalte: Muxed aufgezeichneter Stream füllte FMQ. Wenn die Filterquelle für die Aufzeichnung von TLV.TLV zu IP.IP mit Passthrough ist, verfügt der aufgenommene Stream über einen TLV- und IP -Header. |
MMTP.DOWNLOAD | N / A | Obligatorisch:DemuxFilterEvent::DemuxFilterDownloadEvent[n] DemuxFilterStatus::DATA_READY DemuxFilterStatus::DATA_OVERFLOW Optional: DemuxFilterStatus::LOW_WATER DemuxFilterStatus::HIGH_WATER | for i=0; i<n; i++ Filter.read(buffer, offset, DemuxFilterDownloadEvent[i].size) Die Daten werden vom MQ von HAL in den Clientpuffer kopiert. | Das Download -Paket wird in FMQ von einem anderen IP -Download -Paket ausgefüllt. |
IP.IP_PAYLOAD | N / A | Obligatorisch:DemuxFilterEvent::DemuxFilterIpPayloadEvent[n] DemuxFilterStatus::DATA_READY DemuxFilterStatus::DATA_OVERFLOW Optional: DemuxFilterStatus::LOW_WATER DemuxFilterStatus::HIGH_WATER | for i=0; i<n; i++ Filter.read(buffer, offset, DemuxFilterIpPayloadEvent[i].size) Die Daten werden vom MQ von HAL in den Clientpuffer kopiert. | Das IP -Payload -Paket wird in FMQ durch ein anderes IP -Nutzlastpaket ausgefüllt. |
IP.IP TLV.TLV ALP.ALP | isPassthrough: | Optional:DemuxFilterStatus::DATA_READY DemuxFilterStatus::DATA_OVERFLOW | Das herausgefilterte Protokoll -Substrom füttert den nächsten Filter in der Filterkette. | N / A |
isPassthrough: | Obligatorisch:DemuxFilterStatus::DATA_READY DemuxFilterStatus::DATA_OVERFLOW Empfohlen: DemuxFilterStatus::LOW_WATER DemuxFilterStatus::HIGH_WATER | Nach Ereignis und dem internen Zeitplan laufenFilter.read(buffer, offset, adjustedSize) eins oder mehrmals.Die Daten werden vom MQ des Hals in den Clientpuffer kopiert. | Der herausgefilterte Protokoll -Substrom mit Protokollheader wird in FMQ gefüllt. | |
IP.PAYLOAD_THROUGH TLV.PAYLOAD_THROUGH ALP.PAYLOAD_THROUGH | N / A | Optional:DemuxFilterStatus::DATA_READY DemuxFilterStatus::DATA_OVERFLOW | Die Protokollnutzlast füttert den nächsten Filter in der Filterkette. | N / A |
Beispielfluss, um den Filter zum Erstellen von PSI/Si zu verwenden
Abbildung 10. Fluss, um PSI/Si zu bauen
Einen Filter öffnen.
Filter filter = tuner.openFilter( Filter.TYPE_TS, Filter.SUBTYPE_SECTION, /* bufferSize */1000, executor, filterCallback );
Konfigurieren und starten Sie den Filter.
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();
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); } } } };
Beispielfluss zur Verwendung von MediaEvent vom Filter
Abbildung 11. Fluss zur Verwendung von Medien vom Filter
- Öffnen Sie, konfigurieren und starten Sie die A/V -Filter.
- Verarbeitung
MediaEvent
. -
MediaEvent
erhalten. - Warten Sie den linearen Block nach
codec
. - Lassen Sie den A/V -Handle frei, wenn die Daten konsumiert wurden.
Android.media.tv.tuner.dvr
DvrRecorder
bietet diese Methoden für die Aufzeichnung.
-
configure
-
attachFilter
-
detachFilter
-
start
-
flush
-
stop
-
setFileDescriptor
-
write
DvrPlayback
bietet diese Methoden für die Wiedergabe.
-
configure
-
start
-
flush
-
stop
-
setFileDescriptor
-
read
DvrSettings
wird verwendet, um DvrRecorder
und DvrPlayback
zu konfigurieren. OnPlaybackStatusChangedListener
und OnRecordStatusChangedListener
werden verwendet, um den Status einer DVR -Instanz zu melden.
Beispielfluss, um einen Datensatz zu starten
Abbildung 12. Fluss, um einen Datensatz zu starten
Öffnen Sie, konfigurieren und starten Sie
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();
Empfangen Sie
RecordEvent
und abrufen die Indexinformationen.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. } } } };
Initialisieren Sie
OnRecordStatusChangedListener
und speichern Sie die Datensatzdaten.OnRecordStatusChangedListener listener = new OnRecordStatusChangedListener() { @Override public void onRecordStatusChanged(int status) { // a customized way to consume data efficiently by using status as a hint. if (status == Filter.STATUS_DATA_READY) { recorder.write(size); } } };
Tuner Hal
Der Tuner HAL folgt HIDL und definiert die Schnittstelle zwischen Framework- und Lieferantenhardware. Anbieter verwenden die Schnittstelle, um den Tuner Hal zu implementieren, und das Framework nutzt sie, um mit der Tuner HAL -Implementierung zu kommunizieren.
Module
Tuner HAL 1.0
Module | Grundlegende Steuerelemente | Modulspezifische Steuerelemente | HAL Dateien |
---|---|---|---|
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 (abgeleitet von Tuner HAL 1.0)
Module | Grundlegende Steuerelemente | Modulspezifische Steuerelemente | HAL Dateien |
---|---|---|---|
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 |
Abbildung 13. Diagramm der Wechselwirkungen zwischen den Tuner HAL -Modulen
Filterverknüpfung
Der Tuner HAL unterstützt die Filterverbindung so, dass Filter mit anderen Filtern für mehrere Ebenen verknüpft werden können. Die Filter befolgen die folgenden Regeln.
- Filter sind als Baum verknüpft, der enge Pfad ist nicht zulässig.
- Der Stammknoten ist Demux.
- Filter arbeiten unabhängig.
- Alle Filter beginnen, Daten zu erhalten.
- Die Filterverknüpfung spügt den letzten Filter.
Der Codeblock unten und Abbildung 14 veranschaulichen ein Beispiel für das Filtern mehrerer Ebenen.
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>)
}
Abbildung 14. Durchflussdiagramm einer Filterverbindung für mehrere Ebenen
Tuner Resource Manager
Vor dem Tuner Resource Manager (TRM) erforderte das Umschalten zwischen zwei Apps dieselbe Tuner -Hardware. TV Input Framework (TIF) verwendete einen Mechanismus für den ersten zugänglichen Sieg, was bedeutet, dass die App die Ressource zuerst erhält die Ressource. Dieser Mechanismus ist jedoch möglicherweise nicht ideal für einige komplizierte Anwendungsfälle.
TRM wird als Systemdienst ausgeführt, um die Ressourcen Tuner, TVInput
und CAS für Apps zu verwalten. TRM verwendet einen "Vordergrundgewinn" -Mechanismus, der die Priorität der App basierend auf dem Vordergrund oder Hintergrundstatus und Anwendungsfall der App berechnet. TRM gewährt die Ressource basierend auf der Priorität. TRM zentralisiert das ATV -Ressourcenmanagement für Broadcast, OTT und DVR.
TRM -Schnittstelle
TRM enthält AIDL -Schnittstellen in ITunerResourceManager.aidl
für das Tuner Framework, MediaCas
und TvInputHardwareManager
, um Ressourcen zu registrieren, zu fordern oder zu veröffentlichen.
Schnittstellen für die Kundenverwaltung sind unten aufgeführt.
-
registerClientProfile(in ResourceClientProfile profile, IResourcesReclaimListener listener, out int[] clientId)
-
unregisterClientProfile(in int clientId)
Die Schnittstellen zum Anfordern und Freigeben von Ressourcen sind unten aufgeführt.
-
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
Client- und Anforderungsklassen sind unten aufgeführt.
-
ResourceClientProfile
-
ResourcesReclaimListener
-
TunerFrontendRequest
-
TunerDemuxRequest
-
TunerDescramblerRequest
-
CasSessionRequest
-
TunerLnbRequest
Kundenpriorität
TRM berechnet die Priorität des Clients, indem sie Parameter aus dem Profil des Clients und den Prioritätswert aus der Konfigurationsdatei verwendet. Die Priorität kann auch durch einen willkürlichen Prioritätswert des Kunden aktualisiert werden.
Parameter im Profil des Clients
TRM ruft die Prozess -ID von mTvInputSessionId
ab, um zu entscheiden, ob eine App eine Vordergrund- oder Hintergrund -App ist. So erstellen Sie mTvInputSessionId
, TvInputService.onCreateSession
oder TvInputService.onCreateRecordingSession
initialisiert eine TIS -Sitzung.
mUseCase
gibt den Anwendungsfall der Sitzung an. Die vordefinierten Anwendungsfälle sind unten aufgeführt.
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
}
Konfigurationsdatei
Standardkonfigurationsdatei
Die folgende Standardkonfigurationsdatei bietet Prioritätswerte für vordefinierte Anwendungsfälle. Benutzer können die Werte mithilfe einer benutzerdefinierten Konfigurationsdatei ändern.
Anwendungsfall | Vordergrund | Hintergrund |
---|---|---|
LIVE | 490 | 400 |
PLAYBACK | 480 | 300 |
RECORD | 600 | 500 |
SCAN | 450 | 200 |
BACKGROUND | 180 | 100 |
Customisierte Konfigurationsdatei
Anbieter können die Konfigurationsdatei /vendor/etc/tunerResourceManagerUseCaseConfig.xml
anpassen. Diese Datei wird verwendet, um die Anwendungsfalltypen und die Anwendungsfallprioritätswerte hinzuzufügen, zu entfernen oder zu aktualisieren. Die benutzerdefinierte Datei kann platform/hardware/interfaces/tv/tuner/1.0/config/tunerResourceManagerUseCaseConfigSample.xml
als Vorlage verwenden.
Beispielsweise ist ein neuer Anbieter-Anwendungsfall VENDOR_USE_CASE__[A-Z0-9]+, [0 - 1000]
. Das Format sollte platform/hardware/interfaces/tv/tuner/1.0/config/tunerResourceManagerUseCaseConfig.xsd
folgen.
Willkürlicher Prioritätswert und netter Wert
TRM bietet dem Client updateClientPriority
, um den willkürlichen Prioritätswert und den guten Wert zu aktualisieren. Der willkürliche Prioritätswert überschreibt den aus Anwendungsfalltyp und Sitzungs -ID berechneten Prioritätswert.
Der nette Wert zeigt an, wie milder das Verhalten des Kunden ist, wenn er mit einem anderen Kunden in Konflikt steht. Der nette Wert verringert den Prioritätswert des Kunden, bevor der Prioritätswert mit dem herausfordernden Kunden verglichen wird.
Mechanismus zurückerobern
Das folgende Diagramm zeigt, wie Ressourcen zurückgefordert und zugewiesen werden, wenn ein Ressourcenkonflikt auftritt.
Abbildung 15. Diagramm des Rückgewinnungsmechanismus für einen Konflikt zwischen Tuner -Ressourcen
,Für Android 11 oder höher können Sie das Android -Tuner -Framework verwenden, um A/V -Inhalte zu liefern. Das Framework verwendet die Hardware-Pipeline von Anbietern, wodurch sie sowohl für Low-End- als auch für High-End-SOC geeignet ist. Das Framework bietet eine sichere Möglichkeit, A/V -Inhalte zu liefern, die durch eine vertrauenswürdige Ausführungsumgebung (TEE) und Secure Media Path (SMP) geschützt sind und es ermöglicht, in einer stark eingeschränkten Inhaltsschutzumgebung verwendet zu werden.
Die standardisierte Schnittstelle zwischen Tuner und Android CAS führt zu einer schnelleren Integration zwischen Tuner -Anbietern und CAS -Anbietern. Die Tuner -Schnittstelle arbeitet mit MediaCodec
und AudioTrack
zusammen, um eine One -World -Lösung für Android TV aufzubauen. Die Tuner -Schnittstelle unterstützt sowohl digitales TV als auch analoges Fernsehen basierend auf den wichtigsten Sendungsstandards.
Komponenten
Für Android 11 sind drei Komponenten speziell für die TV -Plattform ausgelegt.
- Tuner Hal: Eine Schnittstelle zwischen Framework und Anbietern
- Tuner SDK -API: Eine Schnittstelle zwischen Framework und Apps
- Tuner Resource Manager (TRM): Koordiniert Tuner HW -Ressourcen
Für Android 11 wurden die folgenden Komponenten verbessert.
- Cas v2
-
TvInputService
oder TV -Eingangsdienst (TIS) -
TvInputManagerService
oder TV -Input Manager Service (TIMS) -
MediaCodec
oder Media Codec -
AudioTrack
oder Audiospur -
MediaResourceManager
oder Media Resource Manager (MRM)
Abbildung 1. Wechselwirkungen zwischen Android -TV -Komponenten
Merkmale
Frontend unterstützt die folgenden DTV -Standards.
- ATSC
- ATSC3
- DVB c/s/t
- ISDB S/S3/T
- Analog
Das Frontend in Android 12 mit Tuner HAL 1.1 oder höher unterstützt den unten stehenden DTV -Standard.
- DTMB
Demux unterstützt die folgenden Stream -Protokolle.
- Transportstrom (TS)
- MPEG Media Transport Protocol (MMTP)
- Internetprotokoll (IP)
- Typ Längenwert (TLV)
- ATSC Link-Layer-Protokoll (ALP)
Descrambler unterstützt den folgenden Inhaltsschutz.
- Sichere Medienpfad
- Klarer Medienweg
- Sichere lokale Aufzeichnung
- Sichern Sie die lokale Wiedergabe
Tuner -APIs unterstützen die unten stehenden Anwendungsfälle.
- Scan
- Live
- Wiedergabe
- Aufzeichnen
Tuner, MediaCodec
und AudioTrack
unterstützen die folgenden Datenflussmodi.
- ES Nutzlast mit klarem Speicherpuffer
- ES Nutzlast mit sicherem Speicherhandle
- Passthrough
Gesamtkonzept
Der Tuner Hal wird zwischen dem Android -Framework und der Hardware des Anbieters definiert.
- Beschreibt, was der Framework vom Verkäufer erwartet und wie der Verkäufer dies kann.
- Exportiert die Funktionen von Frontend-, Demux- und Descrambler in das Framework durch
IFrontend
,IDemux
,IDescrambler
,IFilter
,IDvr
undILnb
-Schnittstellen. - Enthält die Funktionen zur Integration des Tuner HAL in andere Framework -Komponenten wie
MediaCodec
undAudioTrack
.
Eine Tuner -Java -Klasse und eine native Klasse werden erstellt.
- Mit der Tuner Java API können Apps über öffentliche APIs auf den Tuner Hal zugreifen.
- Die native Klasse ermöglicht die Berechtigungssteuerung und den Umgang mit großen Mengen an Aufzeichnungs- oder Wiedergabedaten mit dem Tuner HAL.
- Das native Tunermodul ist eine Brücke zwischen der Tuner Java -Klasse und der Tuner Hal.
Eine TRM -Klasse wird erstellt.
- Verwaltet begrenzte Tuner -Ressourcen wie Frontend-, LNB-, CAS -Sitzungen und ein TV -Eingabegerät aus dem TV -Eingang HAL.
- Wendet Regeln an, um unzureichende Ressourcen aus Apps zurückzugewinnen. Die Standardregel ist der Vordergrundgewinn.
Medien CAS und CAS HAL werden mit den folgenden Funktionen verbessert.
- Öffnet CAS -Sitzungen für verschiedene Verwendungen und Algorithmen.
- Unterstützt dynamische CAS -Systeme wie Cicam -Entfernung und -insertion.
- Integriert sich in den Tuner Hal, indem Sie wichtige Token bereitstellen.
MediaCodec
und AudioTrack
werden mit den folgenden Funktionen verbessert.
- Nimmt einen sicheren A/V -Speicher als Inhaltseingang.
- Konfiguriert für Hardware A/V Sync in Tunneled Playback.
- Konfigurierte Unterstützung für
ES_payload
und Passthrough -Modus.
Abbildung 2. Diagramm der Komponenten innerhalb des Tuner HAL
Gesamt -Workflow
Die folgenden Diagramme veranschaulichen Anrufsequenzen für die Live -Broadcast -Wiedergabe.
Aufstellen
Abbildung 3. Setup -Sequenz für Live -Broadcast -Wiedergabe
Handling A/V.
Abbildung 4. Umgang mit A/V für Live -Broadcast -Wiedergabe
Umgang mit durcheinandergebrachten Inhalten
Abbildung 5. Umgang mit durcheinandergebrachten Inhalten für Live -Broadcast -Wiedergabe
Verarbeitung von A/V -Daten verarbeiten
Abbildung 6. Verarbeitung von A/V für Live -Broadcast -Wiedergabe
Tuner SDK API
Die Tuner SDK -API verarbeitet die Interaktionen mit dem Tuner JNI, dem Tuner Hal und TunerResourceManager
. Die TIS -App verwendet die Tuner SDK -API, um auf Tuner -Ressourcen und Unterkomponenten wie Filter und Descrambler zuzugreifen. Frontend und Demux sind interne Komponenten.
Abbildung 7. Wechselwirkungen mit der Tuner SDK -API
Versionen
Aus Android 12 unterstützt die Tuner SDK-API eine neue Funktion in Tuner HAL 1.1, ein Upgrade von Tuner 1.0.
Verwenden Sie die folgende API, um die laufende HAL -Version zu überprüfen.
-
android.media.tv.tuner.TunerVersionChecker.getTunerVersion()
Die minimal erforderliche Halversion finden Sie in der Dokumentation der neuen Android 12 -APIs.
Pakete
Die Tuner SDK -API enthält die vier folgenden Pakete.
-
android.media.tv.tuner
-
android.media.tv.tuner.frontend
-
android.media.tv.tuner.filter
-
android.media.tv.tuner.dvr
Abbildung 8. Tuner SDK -API -Pakete
Android.media.tv.tuner
Das Tuner -Paket ist ein Einstiegspunkt für das Tuner -Framework. Die TIS -App verwendet das Paket, um Ressourceninstanzen zu initialisieren und zu erwerben, indem die anfängliche Einstellung und der Rückruf angeben.
-
tuner()
: Initialisiert eine Tuner -Instanz, indem Sie die ParameteruseCase
undsessionId
angeben. -
tune()
: Erfasst eine Frontend -Ressource und eine Einstellung, indem Sie denFrontendSetting
-Parameter angeben. -
openFilter()
: Erfasst eine Filterinstanz, indem Sie den Filtertyp angeben. -
openDvrRecorder()
: Erfasst eine Aufzeichnungsinstanz, indem Sie die Puffergröße angeben. -
openDvrPlayback()
: Erfasst eine Wiedergabeinstanz, indem Sie die Puffergröße angeben. -
openDescrambler()
: Erfasst eine Descrambler -Instanz. -
openLnb()
: Erhält eine interne LNB -Instanz. -
openLnbByName()
: Erfasst eine externe LNB -Instanz. -
openTimeFilter()
: Erhält eine Zeitfilterinstanz.
Das Tuner -Paket bietet Funktionen, die nicht unter die Pakete Filter, DVR und Frontend abgedeckt sind. Die Funktionen sind unten aufgeführt.
-
cancelTuning
-
scan
/cancelScanning
-
getAvSyncHwId
-
getAvSyncTime
-
connectCiCam1
/disconnectCiCam
-
shareFrontendFromTuner
-
updateResourcePriority
-
setOnTuneEventListener
-
setResourceLostListener
Android.media.tv.tuner.frontend
Das Frontend-Paket enthält Sammlungen von Frontend-Einstellungen, Informationen, Status, Ereignissen und Funktionen.
Klassen
FrontendSettings
wird für verschiedene DTV -Standards nach den folgenden Klassen abgeleitet.
-
AnalogFrontendSettings
-
Atsc3FrontendSettings
-
AtscFrontendSettings
-
DvbcFrontendSettings
-
DvbsFrontendSettings
-
DvbtFrontendSettings
-
Isdbs3FrontendSettings
-
IsdbsFrontendSettings
-
IsdbtFrontendSettings
Von Android 12 mit Tuner HAL 1.1 oder höher wird der folgende DTV -Standard unterstützt.
-
DtmbFrontendSettings
FrontendCapabilities
wird für verschiedene DTV -Standards nach den folgenden Klassen abgeleitet.
-
AnalogFrontendCapabilities
-
Atsc3FrontendCapabilities
-
AtscFrontendCapabilities
-
DvbcFrontendCapabilities
-
DvbsFrontendCapabilities
-
DvbtFrontendCapabilities
-
Isdbs3FrontendCapabilities
-
IsdbsFrontendCapabilities
-
IsdbtFrontendCapabilities
Von Android 12 mit Tuner HAL 1.1 oder höher wird der folgende DTV -Standard unterstützt.
-
DtmbFrontendCapabilities
FrontendInfo
ruft die Informationen des Frontend ab. FrontendStatus
ruft den aktuellen Status des Frontend ab. OnTuneEventListener
hört die Ereignisse an der Frontend an. Die TIS -App verwendet ScanCallback
um Scan -Nachrichten aus dem Frontend zu verarbeiten.
Kanal -Scan
Um einen Fernseher einzurichten, scannt die App mögliche Frequenzen und erstellt eine Kanalaufstellung, mit der Benutzer zugreifen können. TIS könnte Tuner.tune
, Tuner.scan(BLIND_SCAN)
oder Tuner.scan(AUTO_SCAN)
verwenden, um das Kanal -Scan zu vervollständigen.
Wenn TIS über genaue Lieferungsinformationen für das Signal wie Frequenz, Standard (z. B. T/T2, S/S2) und zusätzliche erforderliche Informationen (z Tuner.tune
B. PLD -ID) enthält .
Wenn der Benutzer Tuner.tune
anruft, ereignen sich die folgenden Aktionen:
- TIS bevölkert
FrontendSettings
mit den erforderlichen Informationen mitTuner.tune
. - Die HAL -Berichte melden
LOCKED
Nachrichten, wenn das Signal gesperrt ist. - TIS verwendet
Frontend.getStatus
um die erforderlichen Informationen zu sammeln. - TIS wechselt zur nächsten verfügbaren Frequenz in seiner Frequenzliste.
Tis ruft Tuner.tune
wieder auf, bis alle Frequenzen erschöpft sind.
Während des Tunings können Sie stopTune()
oder close()
anrufen, um den Tuner.tune
-Anruf zu pausieren oder zu beenden.
Tuner.scan (Auto_Scan)
Wenn TIS nicht über genügend Informationen verfügt, um Tuner.tune
zu verwenden, aber über eine Frequenzliste und einen Standardtyp (z. B. DVB T/C/s) verfügt, wird Tuner.scan(AUTO_SCAN)
empfohlen.
Wenn der Benutzer Tuner.scan(AUTO_SCAN)
aufruft, ereignen sich die folgenden Aktionen:
TIS verwendet
Tuner.scan(AUTO_SCAN)
mitFrontendSettings
mit Frequenz.Die HAL meldet
LOCKED
Nachrichten, wenn das Signal gesperrt ist. Der HAL kann auch andere Scan -Nachrichten melden, um zusätzliche Informationen zum Signal bereitzustellen.TIS verwendet
Frontend.getStatus
, um die erforderlichen Informationen zu sammeln.TIS ruft
Tuner.scan
auf, damit der HAL die nächste Einstellung auf derselben Frequenz fortsetzt. Wenn dieFrontendSettings
-Struktur leer ist, verwendet der HAL die nächste verfügbare Einstellung. Andernfalls verwendet HalFrontendSettings
für einen einmaligen Scan und sendetEND
, um anzuzeigen, dass der Scan-Betrieb abgeschlossen ist.TIS wiederholt die obigen Aktionen, bis alle Einstellungen auf der Frequenz erschöpft sind.
Das Hal sendet
END
, um anzuzeigen, dass der Scanvorgang abgeschlossen ist.TIS wechselt zur nächsten verfügbaren Frequenz in seiner Frequenzliste.
TIS ruft Tuner.scan(AUTO_SCAN)
erneut auf, bis alle Frequenzen erschöpft sind.
Während des Scans können Sie stopScan()
oder close()
anrufen, um den Scan innehalten oder zu beenden.
Tuner.scan (blind_scan)
Wenn TIS keine Frequenzliste hat und der Anbieter Hal nach der Häufigkeit des benutzerdefinierten Frontends suchen kann, um die Frontend-Ressource zu erhalten, wird Tuner.scan(BLIND_SCAN)
empfohlen.
- TIS verwendet
Tuner.scan(BLIND_SCAN)
. Eine Frequenz kann inFrontendSettings
für die Startfrequenz angegeben werden, aber TIS ignoriert andere Einstellungen inFrontendSettings
. - Die HAL meldet eine Scan
LOCKED
Nachricht, wenn das Signal gesperrt ist. - TIS verwendet
Frontend.getStatus
, um die erforderlichen Informationen zu sammeln. - TIS ruft
Tuner.scan
erneut auf, um weiter zu scannen. (FrontendSettings
wird ignoriert.) - TIS wiederholt die obigen Aktionen, bis alle Einstellungen auf der Frequenz erschöpft sind. Die HAL erhöht die Frequenz ohne Aktion, die von TIS erforderlich ist. Die Hal berichtet
PROGRESS
.
TIS ruft Tuner.scan(AUTO_SCAN)
erneut auf, bis alle Frequenzen erschöpft sind. Die HAL -Berichte END
darauf, dass der Scanvorgang abgeschlossen ist.
Während des Scans können Sie stopScan()
oder close()
anrufen, um den Scan innehalten oder zu beenden.
Abbildung 9. Durchflussdiagramm eines TIS -Scans
Android.media.tv.tuner.filter
Das Filterpaket ist eine Sammlung von Filtervorgängen sowie Konfiguration, Einstellungen, Rückrufe und Ereignisse. Das Paket enthält die folgenden Vorgänge. Der Android -Quellcode finden Sie in der vollständigen Operationsliste.
-
configure()
-
start()
-
stop()
-
flush()
-
read()
Informationen zur vollständigen Liste finden Sie im Android -Quellcode.
FilterConfiguration
wird aus den folgenden Klassen abgeleitet. Die Konfigurationen beziehen sich auf den Hauptfiltertyp und geben an, welches Protokoll der Filter zum Extrahieren von Daten verwendet.
-
AlpFilterConfiguration
-
IpFilterConfiguration
-
MmtpFilterConfiguration
-
TlvFilterConfiguration
-
TsFilterConfiguration
Die Einstellungen stammen aus den folgenden Klassen. Die Einstellungen gelten für den Filter -Subtyp und geben an, welche Arten von Daten der Filter ausschließen kann.
-
SectionSettings
-
AvSettings
-
PesSettings
-
RecordSettings
-
DownloadSettings
FilterEvent
wird aus den folgenden Klassen abgeleitet, um Ereignisse für verschiedene Arten von Daten zu melden.
-
SectionEvent
-
MediaEvent
-
PesEvent
-
TsRecordEvent
-
MmtpRecordEvent
-
TemiEvent
-
DownloadEvent
-
IpPayloadEvent
Von Android 12 mit Tuner HAL 1.1 oder höher werden die folgenden Ereignisse unterstützt.
-
IpCidChangeEvent
-
RestartEvent
-
ScramblingStatusEvent
Ereignisse und Datenformat aus Filter
Filter Typ | Flaggen | Veranstaltungen | Datenbetrieb | Datei Format |
---|---|---|---|---|
TS.SECTION MMTP.SECTION IP.SECTION TLV.SECTION ALP.SECTION | isRaw: | Obligatorisch:DemuxFilterStatus::DATA_READY DemuxFilterStatus::DATA_OVERFLOW Empfohlen: DemuxFilterStatus::LOW_WATER DemuxFilterStatus::HIGH_WATER | Nach Ereignis und dem internen Zeitplan laufenFilter.read(buffer, offset, adjustedSize) eins oder mehrmals.Die Daten werden vom MQ von HAL in den Clientpuffer kopiert. | Ein zusammengebautes Sitzungspaket wird von einem anderen Sitzungspaket FMQ ausgefüllt. |
isRaw: | Obligatorisch:DemuxFilterEvent::DemuxFilterSectionEvent[n] DemuxFilterStatus::DATA_READY DemuxFilterStatus::DATA_OVERFLOW Optional: DemuxFilterStatus::LOW_WATER DemuxFilterStatus::HIGH_WATER | for i=0; i<n; i++ Die Daten werden vom MQ von HAL in den Clientpuffer kopiert. | ||
TS.PES | isRaw: | Obligatorisch:DemuxFilterStatus::DATA_READY DemuxFilterStatus::DATA_OVERFLOW Empfohlen: DemuxFilterStatus::LOW_WATER DemuxFilterStatus::HIGH_WATER | Nach Ereignis und dem internen Zeitplan laufenFilter.read(buffer, offset, adjustedSize) eins oder mehrmals.Die Daten werden vom MQ des Hals in den Clientpuffer kopiert. | Ein zusammengebautes PES -Paket wird in FMQ von einem anderen PES -Paket gefüllt. |
isRaw: | Obligatorisch:DemuxFilterEvent::DemuxFilterPesEvent[n] DemuxFilterStatus::DATA_READY DemuxFilterStatus::DATA_OVERFLOW Optional: DemuxFilterStatus::LOW_WATER DemuxFilterStatus::HIGH_WATER | for i=0; i<n; i++ Die Daten werden vom MQ von HAL in den Clientpuffer kopiert. | ||
MMTP.PES | isRaw: | Obligatorisch:DemuxFilterStatus::DATA_READY DemuxFilterStatus::DATA_OVERFLOW Empfohlen: DemuxFilterStatus::LOW_WATER DemuxFilterStatus::HIGH_WATER | Nach Ereignis und dem internen Zeitplan laufenFilter.read(buffer, offset, adjustedSize) eins oder mehrmals.Die Daten werden vom MQ des Hals in den Clientpuffer kopiert. | Ein zusammengebautes MFU -Paket wird in FMQ von einem anderen MFU -Paket gefüllt. |
isRaw: | Obligatorisch:DemuxFilterEvent::DemuxFilterPesEvent[n] DemuxFilterStatus::DATA_READY DemuxFilterStatus::DATA_OVERFLOW Optional: DemuxFilterStatus::LOW_WATER DemuxFilterStatus::HIGH_WATER | for i=0; i<n; i++ Die Daten werden vom MQ des Hals in den Clientpuffer kopiert. | ||
TS.TS | N / A | Obligatorisch:DemuxFilterStatus::DATA_READY DemuxFilterStatus::DATA_OVERFLOW Empfohlen: DemuxFilterStatus::LOW_WATER DemuxFilterStatus::HIGH_WATER | Nach Ereignis und dem internen Zeitplan laufenFilter.read(buffer, offset, adjustedSize) eins oder mehrmals.Die Daten werden vom MQ des Hals in den Clientpuffer kopiert. | ts mit ts -Header herausgefiltertist in fmq gefüllt. |
TS.Audio TS.Video MMTP.Audio MMTP.Video | isPassthrough: | Optional:DemuxFilterStatus::DATA_READY DemuxFilterStatus::DATA_OVERFLOW | Der Client kann MediaCodec starten, nachdem er DemuxFilterStatus::DATA_READY empfangen hat.Der Client kann Filter.flush aufrufen, nachdem er DemuxFilterStatus::DATA_OVERFLOW empfangen hat. | N / A |
isPassthrough: | Obligatorisch:DemuxFilterEvent::DemuxFilterMediaEvent[n] DemuxFilterStatus::DATA_READY DemuxFilterStatus::DATA_OVERFLOW Optional: DemuxFilterStatus::LOW_WATER DemuxFilterStatus::HIGH_WATER | MediaCodec verwenden:for i=0; i<n; i++ Direktes Audio AudioTrack -Audio zu verwenden:for i=0; i<n; i++ | Es oder partielle Daten im Ionenspeicher. | |
TS.PCR IP.NTP ALP.PTP | N / A | Obligatorisch: n/a Optional: n/a | N / A | N / A |
TS.RECORD | N / A | Obligatorisch:DemuxFilterEvent::DemuxFilterTsRecordEvent[n] RecordStatus::DATA_READY RecordStatus::DATA_OVERFLOW RecordStatus::LOW_WATER RecordStatus::HIGH_WATER Optional: DemuxFilterStatus::DATA_READY DemuxFilterStatus::DATA_OVERFLOW DemuxFilterStatus::LOW_WATER DemuxFilterStatus::HIGH_WATER | Für Indexdaten:for i=0; i<n; i++ Führen Sie für aufgezeichnete Inhalte gemäß RecordStatus::* und internem Zeitplan einen der folgenden:
| Für Indexdaten: in der Ereignisnutzlast getragen. Für aufgezeichnete Inhalte: Muxed TS Stream füllte FMQ. |
TS.TEMI | N / A | Obligatorisch:DemuxFilterEvent::DemuxFilterTemiEvent[n] Optional: DemuxFilterStatus::DATA_READY DemuxFilterStatus::DATA_OVERFLOW DemuxFilterStatus::LOW_WATER DemuxFilterStatus::HIGH_WATER | for i=0; i<n; i++ | N / A |
MMTP.MMTP | N / A | Obligatorisch:DemuxFilterStatus::DATA_READY DemuxFilterStatus::DATA_OVERFLOW Empfohlen: DemuxFilterStatus::LOW_WATER DemuxFilterStatus::HIGH_WATER | Nach Ereignis und dem internen Zeitplan laufenFilter.read(buffer, offset, adjustedSize) eins oder mehrmals.Die Daten werden vom MQ des Hals in den Clientpuffer kopiert. | mmtp mit mmtp -Header herausgefiltertist in fmq gefüllt. |
MMTP.RECORD | N / A | Obligatorisch:DemuxFilterEvent::DemuxFilterMmtpRecordEvent[n] RecordStatus::DATA_READY RecordStatus::DATA_OVERFLOW RecordStatus::LOW_WATER RecordStatus::HIGH_WATER Optional: DemuxFilterStatus::DATA_READY DemuxFilterStatus::DATA_OVERFLOW DemuxFilterStatus::LOW_WATER DemuxFilterStatus::HIGH_WATER | Für Indexdaten: for i=0; i<n; i++ Führen Sie für aufgezeichnete Inhalte gemäß RecordStatus::* und internem Zeitplan einen der folgenden:
| Für Indexdaten: in der Ereignisnutzlast getragen. Für aufgezeichnete Inhalte: Muxed aufgezeichneter Stream füllte FMQ. Wenn die Filterquelle für die Aufzeichnung von TLV.TLV zu IP.IP mit Passthrough ist, verfügt der aufgenommene Stream über einen TLV- und IP -Header. |
MMTP.DOWNLOAD | N / A | Obligatorisch:DemuxFilterEvent::DemuxFilterDownloadEvent[n] DemuxFilterStatus::DATA_READY DemuxFilterStatus::DATA_OVERFLOW Optional: DemuxFilterStatus::LOW_WATER DemuxFilterStatus::HIGH_WATER | for i=0; i<n; i++ Filter.read(buffer, offset, DemuxFilterDownloadEvent[i].size) Die Daten werden vom MQ von HAL in den Clientpuffer kopiert. | Das Download -Paket wird in FMQ von einem anderen IP -Download -Paket ausgefüllt. |
IP.IP_PAYLOAD | N / A | Obligatorisch:DemuxFilterEvent::DemuxFilterIpPayloadEvent[n] DemuxFilterStatus::DATA_READY DemuxFilterStatus::DATA_OVERFLOW Optional: DemuxFilterStatus::LOW_WATER DemuxFilterStatus::HIGH_WATER | for i=0; i<n; i++ Filter.read(buffer, offset, DemuxFilterIpPayloadEvent[i].size) Die Daten werden vom MQ von HAL in den Clientpuffer kopiert. | Das IP -Payload -Paket wird in FMQ durch ein anderes IP -Nutzlastpaket ausgefüllt. |
IP.IP TLV.TLV ALP.ALP | isPassthrough: | Optional:DemuxFilterStatus::DATA_READY DemuxFilterStatus::DATA_OVERFLOW | Das herausgefilterte Protokoll -Substrom füttert den nächsten Filter in der Filterkette. | N / A |
isPassthrough: | Obligatorisch:DemuxFilterStatus::DATA_READY DemuxFilterStatus::DATA_OVERFLOW Empfohlen: DemuxFilterStatus::LOW_WATER DemuxFilterStatus::HIGH_WATER | Nach Ereignis und dem internen Zeitplan laufenFilter.read(buffer, offset, adjustedSize) eins oder mehrmals.Die Daten werden vom MQ des Hals in den Clientpuffer kopiert. | Der herausgefilterte Protokoll -Substrom mit Protokollheader wird in FMQ gefüllt. | |
IP.PAYLOAD_THROUGH TLV.PAYLOAD_THROUGH ALP.PAYLOAD_THROUGH | N / A | Optional:DemuxFilterStatus::DATA_READY DemuxFilterStatus::DATA_OVERFLOW | Die Protokollnutzlast füttert den nächsten Filter in der Filterkette. | N / A |
Beispielfluss, um den Filter zum Erstellen von PSI/Si zu verwenden
Abbildung 10. Fluss, um PSI/Si zu bauen
Einen Filter öffnen.
Filter filter = tuner.openFilter( Filter.TYPE_TS, Filter.SUBTYPE_SECTION, /* bufferSize */1000, executor, filterCallback );
Konfigurieren und starten Sie den Filter.
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();
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); } } } };
Beispielfluss zur Verwendung von MediaEvent vom Filter
Abbildung 11. Fluss zur Verwendung von Medien vom Filter
- Öffnen Sie, konfigurieren und starten Sie die A/V -Filter.
- Verarbeitung
MediaEvent
. -
MediaEvent
erhalten. - Warten Sie den linearen Block nach
codec
. - Lassen Sie den A/V -Handle frei, wenn die Daten konsumiert wurden.
Android.media.tv.tuner.dvr
DvrRecorder
bietet diese Methoden für die Aufzeichnung.
-
configure
-
attachFilter
-
detachFilter
-
start
-
flush
-
stop
-
setFileDescriptor
-
write
DvrPlayback
bietet diese Methoden für die Wiedergabe.
-
configure
-
start
-
flush
-
stop
-
setFileDescriptor
-
read
DvrSettings
wird verwendet, um DvrRecorder
und DvrPlayback
zu konfigurieren. OnPlaybackStatusChangedListener
und OnRecordStatusChangedListener
werden verwendet, um den Status einer DVR -Instanz zu melden.
Beispielfluss, um einen Datensatz zu starten
Abbildung 12. Fluss, um einen Datensatz zu starten
Öffnen Sie, konfigurieren und starten Sie
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();
Empfangen Sie
RecordEvent
und abrufen die Indexinformationen.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. } } } };
Initialisieren Sie
OnRecordStatusChangedListener
und speichern Sie die Datensatzdaten.OnRecordStatusChangedListener listener = new OnRecordStatusChangedListener() { @Override public void onRecordStatusChanged(int status) { // a customized way to consume data efficiently by using status as a hint. if (status == Filter.STATUS_DATA_READY) { recorder.write(size); } } };
Tuner Hal
Der Tuner HAL folgt HIDL und definiert die Schnittstelle zwischen Framework- und Lieferantenhardware. Anbieter verwenden die Schnittstelle, um den Tuner Hal zu implementieren, und das Framework nutzt sie, um mit der Tuner HAL -Implementierung zu kommunizieren.
Module
Tuner HAL 1.0
Module | Grundlegende Steuerelemente | Modulspezifische Steuerelemente | HAL Dateien |
---|---|---|---|
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 (abgeleitet von Tuner HAL 1.0)
Module | Grundlegende Steuerelemente | Modulspezifische Steuerelemente | HAL Dateien |
---|---|---|---|
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 |
Abbildung 13. Diagramm der Wechselwirkungen zwischen den Tuner HAL -Modulen
Filterverknüpfung
Der Tuner HAL unterstützt die Filterverbindung so, dass Filter mit anderen Filtern für mehrere Ebenen verknüpft werden können. Die Filter befolgen die folgenden Regeln.
- Filter sind als Baum verknüpft, der enge Pfad ist nicht zulässig.
- Der Stammknoten ist Demux.
- Filter arbeiten unabhängig.
- Alle Filter beginnen, Daten zu erhalten.
- Die Filterverknüpfung spügt den letzten Filter.
Der Codeblock unten und Abbildung 14 veranschaulichen ein Beispiel für das Filtern mehrerer Ebenen.
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>)
}
Abbildung 14. Durchflussdiagramm einer Filterverbindung für mehrere Ebenen
Tuner Resource Manager
Vor dem Tuner Resource Manager (TRM) erforderte das Umschalten zwischen zwei Apps dieselbe Tuner -Hardware. TV Input Framework (TIF) verwendete einen Mechanismus für den ersten zugänglichen Sieg, was bedeutet, dass die App die Ressource zuerst erhält die Ressource. Dieser Mechanismus ist jedoch möglicherweise nicht ideal für einige komplizierte Anwendungsfälle.
TRM wird als Systemdienst ausgeführt, um die Ressourcen Tuner, TVInput
und CAS für Apps zu verwalten. TRM verwendet einen "Vordergrundgewinn" -Mechanismus, der die Priorität der App basierend auf dem Vordergrund oder Hintergrundstatus und Anwendungsfall der App berechnet. TRM gewährt die Ressource basierend auf der Priorität. TRM zentralisiert das ATV -Ressourcenmanagement für Broadcast, OTT und DVR.
TRM -Schnittstelle
TRM enthält AIDL -Schnittstellen in ITunerResourceManager.aidl
für das Tuner Framework, MediaCas
und TvInputHardwareManager
, um Ressourcen zu registrieren, zu fordern oder zu veröffentlichen.
Schnittstellen für die Kundenverwaltung sind unten aufgeführt.
-
registerClientProfile(in ResourceClientProfile profile, IResourcesReclaimListener listener, out int[] clientId)
-
unregisterClientProfile(in int clientId)
Die Schnittstellen zum Anfordern und Freigeben von Ressourcen sind unten aufgeführt.
-
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
Client- und Anforderungsklassen sind unten aufgeführt.
-
ResourceClientProfile
-
ResourcesReclaimListener
-
TunerFrontendRequest
-
TunerDemuxRequest
-
TunerDescramblerRequest
-
CasSessionRequest
-
TunerLnbRequest
Kundenpriorität
TRM berechnet die Priorität des Clients, indem sie Parameter aus dem Profil des Clients und den Prioritätswert aus der Konfigurationsdatei verwendet. Die Priorität kann auch durch einen willkürlichen Prioritätswert des Kunden aktualisiert werden.
Parameter im Profil des Clients
TRM ruft die Prozess -ID von mTvInputSessionId
ab, um zu entscheiden, ob eine App eine Vordergrund- oder Hintergrund -App ist. So erstellen Sie mTvInputSessionId
, TvInputService.onCreateSession
oder TvInputService.onCreateRecordingSession
initialisiert eine TIS -Sitzung.
mUseCase
gibt den Anwendungsfall der Sitzung an. Die vordefinierten Anwendungsfälle sind unten aufgeführt.
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
}
Konfigurationsdatei
Standardkonfigurationsdatei
Die folgende Standardkonfigurationsdatei bietet Prioritätswerte für vordefinierte Anwendungsfälle. Benutzer können die Werte mithilfe einer benutzerdefinierten Konfigurationsdatei ändern.
Anwendungsfall | Vordergrund | Hintergrund |
---|---|---|
LIVE | 490 | 400 |
PLAYBACK | 480 | 300 |
RECORD | 600 | 500 |
SCAN | 450 | 200 |
BACKGROUND | 180 | 100 |
Customisierte Konfigurationsdatei
Anbieter können die Konfigurationsdatei /vendor/etc/tunerResourceManagerUseCaseConfig.xml
anpassen. Diese Datei wird verwendet, um die Anwendungsfalltypen und die Anwendungsfallprioritätswerte hinzuzufügen, zu entfernen oder zu aktualisieren. Die benutzerdefinierte Datei kann platform/hardware/interfaces/tv/tuner/1.0/config/tunerResourceManagerUseCaseConfigSample.xml
als Vorlage verwenden.
Beispielsweise ist ein neuer Anbieter-Anwendungsfall VENDOR_USE_CASE__[A-Z0-9]+, [0 - 1000]
. Das Format sollte platform/hardware/interfaces/tv/tuner/1.0/config/tunerResourceManagerUseCaseConfig.xsd
folgen.
Willkürlicher Prioritätswert und netter Wert
TRM bietet dem Client updateClientPriority
, um den willkürlichen Prioritätswert und den guten Wert zu aktualisieren. Der willkürliche Prioritätswert überschreibt den aus Anwendungsfalltyp und Sitzungs -ID berechneten Prioritätswert.
Der nette Wert zeigt an, wie milder das Verhalten des Kunden ist, wenn er mit einem anderen Kunden in Konflikt steht. Der nette Wert verringert den Prioritätswert des Kunden, bevor der Prioritätswert mit dem herausfordernden Kunden verglichen wird.
Mechanismus zurückerobern
Das folgende Diagramm zeigt, wie Ressourcen zurückgefordert und zugewiesen werden, wenn ein Ressourcenkonflikt auftritt.
Abbildung 15. Diagramm des Rückgewinnungsmechanismus für einen Konflikt zwischen Tuner -Ressourcen