Tuner-Framework

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)

Flussdiagramm der Tuner-Framework-Komponenten.

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 und ILnb in das Framework.
  • Enthält die Funktionen zur Integration des Tuner HAL mit anderen Framework-Komponenten wie MediaCodec und AudioTrack .

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.

Gesamtdesign des Tuner HAL.

Abbildung 2. Diagramm der Komponenten im Tuner HAL

Gesamtworkflow

Die folgenden Diagramme veranschaulichen Anrufsequenzen für die Live-Übertragungswiedergabe.

Aufstellen

Setup-Sequenz des Live-Wiedergabediagramms.

Abbildung 3. Setup-Sequenz für die Live-Übertragungswiedergabe

Umgang mit A/V

Diagramm zur Handhabung von A/V für die Wiedergabe von Live-Übertragungen.

Abbildung 4. Handhabung von A/V für die Wiedergabe von Live-Übertragungen

Umgang mit verschlüsselten Inhalten

Diagramm zur Handhabung verschlüsselter Inhalte für die Wiedergabe von Live-Übertragungen.

Abbildung 5. Umgang mit verschlüsselten Inhalten für die Live-Übertragungswiedergabe

Verarbeitung von A/V-Daten

Verarbeiten Sie A/V-Daten für das Wiedergabediagramm einer Live-Übertragung.

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.

Flussdiagramm der Tuner SDK API.

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

Flussdiagramm der Tuner SDK API-Pakete.

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 Parameter useCase und sessionId .
  • tune() : Erhält eine Frontend-Ressource und optimiert sie durch Angabe des FrontendSetting -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 von Tuner.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üllten FrontendSettings .

  • 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 die FrontendSettings Struktur leer ist, verwendet die HAL die nächste verfügbare Einstellung. Andernfalls verwendet HAL FrontendSettings für einen einmaligen Scan und sendet END , 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) . In FrontendSettings kann eine Häufigkeit für die Starthäufigkeit angegeben werden, TIS ignoriert jedoch andere Einstellungen in FrontendSettings .
  • 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.

Flussdiagramm des TIS-Scan-Prozesses.

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:
true
Obligatorisch:
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW

Empfohlen:
DemuxFilterStatus::LOW_WATER
DemuxFilterStatus::HIGH_WATER
Je nach Veranstaltung und internem Zeitplan ausführen
Filter.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:
false
Obligatorisch:
DemuxFilterEvent::DemuxFilterSectionEvent[n]
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW

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


Die Daten werden vom MQ von HAL in den Client-Puffer kopiert.
TS.PES isRaw:
true
Obligatorisch:
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW

Empfohlen:
DemuxFilterStatus::LOW_WATER
DemuxFilterStatus::HIGH_WATER
Je nach Veranstaltung und internem Zeitplan ausführen
Filter.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:
false
Obligatorisch:
DemuxFilterEvent::DemuxFilterPesEvent[n]
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW

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


Die Daten werden vom MQ von HAL in den Client-Puffer kopiert.
MMTP.PES isRaw:
true
Obligatorisch:
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW

Empfohlen:
DemuxFilterStatus::LOW_WATER
DemuxFilterStatus::HIGH_WATER
Je nach Veranstaltung und internem Zeitplan ausführen
Filter.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:
false
Obligatorisch:
DemuxFilterEvent::DemuxFilterPesEvent[n]
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW

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


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ühren
Filter.read(buffer, offset, adjustedSize) einmal oder mehrmals.

Daten werden vom MQ des HAL in den Client-Puffer kopiert.
ts mit ts -Header herausgefiltert
wird im FMQ ausgefüllt.
TS.Audio
TS.Video
MMTP.Audio
MMTP.Video
isPassthrough:
true
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:
false
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++
linearblock = MediaEvent[i].getLinearBlock();
codec.startQueueLinearBlock(linearblock)
linearblock.recycle()


So verwenden Sie Direct Audio von AudioTrack :
for i=0; i<n; i++
audioHandle = MediaEvent[i].getAudioHandle();
audiotrack.write(encapsulated(audiohandle))
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++
DemuxFilterTsRecordEvent[i];


Führen Sie für aufgezeichnete Inhalte gemäß RecordStatus::* und internem Zeitplan einen der folgenden Schritte aus:
  • Führen Sie DvrRecord.write(adustedSize) einmal oder mehrmals zum Speichern aus.
    Die Daten werden vom MQ des HAL in den Speicher übertragen.
  • Führen Sie DvrRecord.write(buffer, adustedSize) einmal oder mehrmals aus, um zu puffern.
    Die Daten werden vom MQ des HAL in den Client-Puffer kopiert.
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++
DemuxFilterTemiEvent[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ühren
Filter.read(buffer, offset, adjustedSize) einmal oder mehrmals.

Daten werden vom MQ des HAL in den Client-Puffer kopiert.
mmtp mit mmtp -Header herausgefiltert
wird 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++
DemuxFilterMmtpRecordEvent[i];


Führen Sie für aufgezeichnete Inhalte gemäß RecordStatus::* und internem Zeitplan einen der folgenden Schritte aus:
  • Führen Sie DvrRecord.write(adjustedSize) einmal oder mehrmals zum Speichern aus.
    Die Daten werden vom MQ des HAL in den Speicher übertragen.
  • Führen Sie DvrRecord.write(buffer, adjustedSize) einmal oder mehrmals aus, um zu puffern.
    Die Daten werden vom MQ des HAL in den Client-Puffer kopiert.
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:
true
Optional:
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW
Der herausgefilterte Protokoll-Substream speist den nächsten Filter in der Filterkette. N / A
isPassthrough:
false
Obligatorisch:
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW

Empfohlen:
DemuxFilterStatus::LOW_WATER
DemuxFilterStatus::HIGH_WATER
Je nach Veranstaltung und internem Zeitplan ausführen
Filter.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

Beispielablauf für die Verwendung eines Filters zum Erstellen von PSI/SI.

Abbildung 10. Ablauf zum Aufbau von PSI/SI

  1. Öffnen Sie einen Filter.

    Filter filter = tuner.openFilter(
      Filter.TYPE_TS,
      Filter.SUBTYPE_SECTION,
      /* bufferSize */1000,
      executor,
      filterCallback
    );
    
  2. 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();
    
  3. 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

Beispielablauf zur Verwendung von MediaEvent aus dem Filter.

Abbildung 11. Ablauf zur Verwendung von MediaEvent aus dem Filter

  1. Öffnen, konfigurieren und starten Sie die A/V-Filter.
  2. MediaEvent verarbeiten.
  3. MediaEvent empfangen.
  4. Stellen Sie den linearen Block in die codec .
  5. 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

Beispielablauf zum Starten eines Datensatzes.

Abbildung 12. Ablauf zum Starten einer Aufzeichnung

  1. Ö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();
    
  2. 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. }
          }
        }
    };
    
  3. 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

Flussdiagramm der Interaktionen zwischen den Modulen des Tuner 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>)
}

Diagramm eines Beispiels für die Filterverknüpfung.

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.

Diagramm des Prozesses des Rückforderungsmechanismus.

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)

Flussdiagramm der Tuner-Framework-Komponenten.

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 und ILnb in das Framework.
  • Enthält die Funktionen zur Integration des Tuner HAL mit anderen Framework-Komponenten wie MediaCodec und AudioTrack .

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.

Gesamtdesign des Tuner HAL.

Abbildung 2. Diagramm der Komponenten im Tuner HAL

Gesamtworkflow

Die folgenden Diagramme veranschaulichen Anrufsequenzen für die Live-Übertragungswiedergabe.

Aufstellen

Setup-Sequenz des Live-Wiedergabediagramms.

Abbildung 3. Setup-Sequenz für die Live-Übertragungswiedergabe

Umgang mit A/V

Diagramm zur Handhabung von A/V für die Wiedergabe von Live-Übertragungen.

Abbildung 4. Handhabung von A/V für die Wiedergabe von Live-Übertragungen

Umgang mit verschlüsselten Inhalten

Diagramm zur Handhabung verschlüsselter Inhalte für die Wiedergabe von Live-Übertragungen.

Abbildung 5. Umgang mit verschlüsselten Inhalten für die Live-Übertragungswiedergabe

Verarbeitung von A/V-Daten

Verarbeiten Sie A/V-Daten für das Wiedergabediagramm einer Live-Übertragung.

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.

Flussdiagramm der Tuner SDK API.

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

Flussdiagramm der Tuner SDK API-Pakete.

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 Parameter useCase und sessionId .
  • tune() : Erhält eine Frontend-Ressource und optimiert sie durch Angabe des FrontendSetting -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 von Tuner.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üllten FrontendSettings .

  • 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 die FrontendSettings Struktur leer ist, verwendet die HAL die nächste verfügbare Einstellung. Andernfalls verwendet HAL FrontendSettings für einen einmaligen Scan und sendet END , 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) . In FrontendSettings kann eine Häufigkeit für die Starthäufigkeit angegeben werden, TIS ignoriert jedoch andere Einstellungen in FrontendSettings .
  • 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.

Flussdiagramm des TIS-Scan-Prozesses.

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:
true
Obligatorisch:
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW

Empfohlen:
DemuxFilterStatus::LOW_WATER
DemuxFilterStatus::HIGH_WATER
Nach Ereignis und dem internen Zeitplan laufen
Filter.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:
false
Obligatorisch:
DemuxFilterEvent::DemuxFilterSectionEvent[n]
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW

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


Die Daten werden vom MQ von HAL in den Clientpuffer kopiert.
TS.PES isRaw:
true
Obligatorisch:
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW

Empfohlen:
DemuxFilterStatus::LOW_WATER
DemuxFilterStatus::HIGH_WATER
Nach Ereignis und dem internen Zeitplan laufen
Filter.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:
false
Obligatorisch:
DemuxFilterEvent::DemuxFilterPesEvent[n]
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW

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


Die Daten werden vom MQ von HAL in den Clientpuffer kopiert.
MMTP.PES isRaw:
true
Obligatorisch:
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW

Empfohlen:
DemuxFilterStatus::LOW_WATER
DemuxFilterStatus::HIGH_WATER
Nach Ereignis und dem internen Zeitplan laufen
Filter.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:
false
Obligatorisch:
DemuxFilterEvent::DemuxFilterPesEvent[n]
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW

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


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 laufen
Filter.read(buffer, offset, adjustedSize) eins oder mehrmals.

Die Daten werden vom MQ des Hals in den Clientpuffer kopiert.
ts mit ts -Header herausgefiltert
ist in fmq gefüllt.
TS.Audio
TS.Video
MMTP.Audio
MMTP.Video
isPassthrough:
true
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:
false
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++
linearblock = MediaEvent[i].getLinearBlock();
codec.startQueueLinearBlock(linearblock)
linearblock.recycle()


Direktes Audio AudioTrack -Audio zu verwenden:
for i=0; i<n; i++
audioHandle = MediaEvent[i].getAudioHandle();
audiotrack.write(encapsulated(audiohandle))
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++
DemuxFilterTsRecordEvent[i];


Führen Sie für aufgezeichnete Inhalte gemäß RecordStatus::* und internem Zeitplan einen der folgenden:
  • Führen Sie DvrRecord.write(adustedSize) eins oder mehrmals zur Speicherung aus.
    Die Daten werden vom MQ des HAL in Speicher übertragen.
  • Führen Sie DvrRecord.write(buffer, adustedSize) eins oder mehrmals zum Puffer aus.
    Die Daten werden vom MQ des Hals in den Clientpuffer kopiert.
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++
DemuxFilterTemiEvent[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 laufen
Filter.read(buffer, offset, adjustedSize) eins oder mehrmals.

Die Daten werden vom MQ des Hals in den Clientpuffer kopiert.
mmtp mit mmtp -Header herausgefiltert
ist 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++
DemuxFilterMmtpRecordEvent[i];


Führen Sie für aufgezeichnete Inhalte gemäß RecordStatus::* und internem Zeitplan einen der folgenden:
  • Führen Sie DvrRecord.write(adjustedSize) eins oder mehrmals zum Speicher aus.
    Die Daten werden vom MQ des HAL in Speicher übertragen.
  • Führen Sie DvrRecord.write(buffer, adjustedSize) ein oder mehrmals zum Puffer aus.
    Die Daten werden vom MQ des Hals in den Clientpuffer kopiert.
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:
true
Optional:
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW
Das herausgefilterte Protokoll -Substrom füttert den nächsten Filter in der Filterkette. N / A
isPassthrough:
false
Obligatorisch:
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW

Empfohlen:
DemuxFilterStatus::LOW_WATER
DemuxFilterStatus::HIGH_WATER
Nach Ereignis und dem internen Zeitplan laufen
Filter.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

Beispielfluss für die Verwendung von Filter zum Erstellen von PSI/Si.

Abbildung 10. Fluss, um PSI/Si zu bauen

  1. Einen Filter öffnen.

    Filter filter = tuner.openFilter(
      Filter.TYPE_TS,
      Filter.SUBTYPE_SECTION,
      /* bufferSize */1000,
      executor,
      filterCallback
    );
    
  2. 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();
    
  3. 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

Beispielfluss zur Verwendung von Medien vom Filter.

Abbildung 11. Fluss zur Verwendung von Medien vom Filter

  1. Öffnen Sie, konfigurieren und starten Sie die A/V -Filter.
  2. Verarbeitung MediaEvent .
  3. MediaEvent erhalten.
  4. Warten Sie den linearen Block nach codec .
  5. 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

Beispielfluss, um einen Datensatz zu starten.

Abbildung 12. Fluss, um einen Datensatz zu starten

  1. Ö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();
    
  2. 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. }
          }
        }
    };
    
  3. 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

Flussdiagramm der Wechselwirkungen zwischen den Modulen des Tuner 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>)
}

Diagramm des Filterverbindungsbeispiels.

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.

Diagramm des Reclaim -Mechanismus -Prozesses.

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)

Flussdiagramm der Tuner -Framework -Komponenten.

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 und ILnb -Schnittstellen.
  • Enthält die Funktionen zur Integration des Tuner HAL in andere Framework -Komponenten wie MediaCodec und AudioTrack .

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.

Gesamtdesign des Tuner Hal.

Abbildung 2. Diagramm der Komponenten innerhalb des Tuner HAL

Gesamt -Workflow

Die folgenden Diagramme veranschaulichen Anrufsequenzen für die Live -Broadcast -Wiedergabe.

Aufstellen

Setup -Sequenz des Live -Broadcast -Playback -Diagramms.

Abbildung 3. Setup -Sequenz für Live -Broadcast -Wiedergabe

Handling A/V.

Umgang mit A/V für Live -Broadcast -Playback -Diagramm.

Abbildung 4. Umgang mit A/V für Live -Broadcast -Wiedergabe

Umgang mit durcheinandergebrachten Inhalten

Umgang mit durcheinandergebrachten Inhalten für Live -Broadcast -Playback -Diagramm.

Abbildung 5. Umgang mit durcheinandergebrachten Inhalten für Live -Broadcast -Wiedergabe

Verarbeitung von A/V -Daten verarbeiten

Verarbeiten Sie A/V -Daten für Live -Broadcast -Wiedergabediagramm.

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.

Flussdiagramm der Tuner SDK -API.

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

Flussdiagramm der Tuner SDK -API -Pakete.

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 Parameter useCase und sessionId angeben.
  • tune() : Erfasst eine Frontend -Ressource und eine Einstellung, indem Sie den FrontendSetting -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 mit Tuner.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) mit FrontendSettings 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 die FrontendSettings -Struktur leer ist, verwendet der HAL die nächste verfügbare Einstellung. Andernfalls verwendet Hal FrontendSettings für einen einmaligen Scan und sendet END , 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 in FrontendSettings für die Startfrequenz angegeben werden, aber TIS ignoriert andere Einstellungen in FrontendSettings .
  • 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.

Flussdiagramm des TIS -Scanprozesses.

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:
true
Obligatorisch:
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW

Empfohlen:
DemuxFilterStatus::LOW_WATER
DemuxFilterStatus::HIGH_WATER
Nach Ereignis und dem internen Zeitplan laufen
Filter.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:
false
Obligatorisch:
DemuxFilterEvent::DemuxFilterSectionEvent[n]
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW

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


Die Daten werden vom MQ von HAL in den Clientpuffer kopiert.
TS.PES isRaw:
true
Obligatorisch:
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW

Empfohlen:
DemuxFilterStatus::LOW_WATER
DemuxFilterStatus::HIGH_WATER
Nach Ereignis und dem internen Zeitplan laufen
Filter.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:
false
Obligatorisch:
DemuxFilterEvent::DemuxFilterPesEvent[n]
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW

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


Die Daten werden vom MQ von HAL in den Clientpuffer kopiert.
MMTP.PES isRaw:
true
Obligatorisch:
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW

Empfohlen:
DemuxFilterStatus::LOW_WATER
DemuxFilterStatus::HIGH_WATER
Nach Ereignis und dem internen Zeitplan laufen
Filter.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:
false
Obligatorisch:
DemuxFilterEvent::DemuxFilterPesEvent[n]
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW

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


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 laufen
Filter.read(buffer, offset, adjustedSize) eins oder mehrmals.

Die Daten werden vom MQ des Hals in den Clientpuffer kopiert.
ts mit ts -Header herausgefiltert
ist in fmq gefüllt.
TS.Audio
TS.Video
MMTP.Audio
MMTP.Video
isPassthrough:
true
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:
false
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++
linearblock = MediaEvent[i].getLinearBlock();
codec.startQueueLinearBlock(linearblock)
linearblock.recycle()


Direktes Audio AudioTrack -Audio zu verwenden:
for i=0; i<n; i++
audioHandle = MediaEvent[i].getAudioHandle();
audiotrack.write(encapsulated(audiohandle))
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++
DemuxFilterTsRecordEvent[i];


Führen Sie für aufgezeichnete Inhalte gemäß RecordStatus::* und internem Zeitplan einen der folgenden:
  • Führen Sie DvrRecord.write(adustedSize) eins oder mehrmals zur Speicherung aus.
    Die Daten werden vom MQ des HAL in Speicher übertragen.
  • Führen Sie DvrRecord.write(buffer, adustedSize) eins oder mehrmals zum Puffer aus.
    Die Daten werden vom MQ des Hals in den Clientpuffer kopiert.
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++
DemuxFilterTemiEvent[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 laufen
Filter.read(buffer, offset, adjustedSize) eins oder mehrmals.

Die Daten werden vom MQ des Hals in den Clientpuffer kopiert.
mmtp mit mmtp -Header herausgefiltert
ist 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++
DemuxFilterMmtpRecordEvent[i];


Führen Sie für aufgezeichnete Inhalte gemäß RecordStatus::* und internem Zeitplan einen der folgenden:
  • Führen Sie DvrRecord.write(adjustedSize) eins oder mehrmals zum Speicher aus.
    Die Daten werden vom MQ des HAL in Speicher übertragen.
  • Führen Sie DvrRecord.write(buffer, adjustedSize) ein oder mehrmals zum Puffer aus.
    Die Daten werden vom MQ des Hals in den Clientpuffer kopiert.
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:
true
Optional:
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW
Das herausgefilterte Protokoll -Substrom füttert den nächsten Filter in der Filterkette. N / A
isPassthrough:
false
Obligatorisch:
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW

Empfohlen:
DemuxFilterStatus::LOW_WATER
DemuxFilterStatus::HIGH_WATER
Nach Ereignis und dem internen Zeitplan laufen
Filter.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

Beispielfluss für die Verwendung von Filter zum Erstellen von PSI/Si.

Abbildung 10. Fluss, um PSI/Si zu bauen

  1. Einen Filter öffnen.

    Filter filter = tuner.openFilter(
      Filter.TYPE_TS,
      Filter.SUBTYPE_SECTION,
      /* bufferSize */1000,
      executor,
      filterCallback
    );
    
  2. 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();
    
  3. 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

Beispielfluss zur Verwendung von Medien vom Filter.

Abbildung 11. Fluss zur Verwendung von Medien vom Filter

  1. Öffnen Sie, konfigurieren und starten Sie die A/V -Filter.
  2. Verarbeitung MediaEvent .
  3. MediaEvent erhalten.
  4. Warten Sie den linearen Block nach codec .
  5. 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

Beispielfluss, um einen Datensatz zu starten.

Abbildung 12. Fluss, um einen Datensatz zu starten

  1. Ö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();
    
  2. 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. }
          }
        }
    };
    
  3. 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

Flussdiagramm der Wechselwirkungen zwischen den Modulen des Tuner 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>)
}

Diagramm des Filterverbindungsbeispiels.

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.

Diagramm des Reclaim -Mechanismus -Prozesses.

Abbildung 15. Diagramm des Rückgewinnungsmechanismus für einen Konflikt zwischen Tuner -Ressourcen