Tuner-Framework

Ab Android 11 kannst du die Tuner-Framework zur Bereitstellung von A/V-Inhalten. Das Framework nutzt die Hardware, von Anbietern und eignet sich damit sowohl für Low-End- als auch für High-End-SoC. Das Framework bietet eine sichere Möglichkeit, A/V-Inhalte bereitzustellen, die durch eine TEE und Secure Media Path (SMP) nutzen, in einer stark eingeschränkten Umgebung zum Schutz von Inhalten verwendet werden dürfen.

Die standardisierte Schnittstelle zwischen Tuner und Android CAS ermöglicht eine schnellere Integration zwischen Tuner- und CAS-Anbietern. Die Tuner-Oberfläche funktioniert mit MediaCodec und AudioTrack, um eine universelle Lösung für Android TV zu entwickeln. Die Benutzeroberfläche des Tuner unterstützt sowohl digitales als auch analoges Fernsehen auf Basis der wichtigsten Broadcast-Standards.

Komponenten

Für Android 11 sind drei Komponenten TV-Plattform entwickelt.

  • Tuner HAL: Eine Schnittstelle zwischen dem Framework und den Anbietern.
  • Tuner SDK API:Eine Schnittstelle zwischen dem Framework und den Apps
  • Tuner Resource Manager (TRM): HW-Ressourcen für Koordinaten-Tuner

Für Android 11 wurden die folgenden Komponenten optimiert.

  • CAS V2
  • TvInputService oder TV Input Service (TIS)
  • TvInputManagerService oder TV Input Manager Service (TIMS)
  • MediaCodec oder Medien-Codec
  • AudioTrack oder Audiotrack
  • MediaResourceManager oder Media Resource Manager (MRM)

Flussdiagramm der Komponenten des Tuner-Frameworks.

Abbildung 1: Interaktionen zwischen Android TV-Komponenten

Funktionen

Das Front-End unterstützt die folgenden DTV-Standards.

  • ATSC
  • ATSC3
  • DVB C/S/T
  • ISDB S/S3/T
  • Analog

Das Front-End in Android 12 mit Tuner HAL 1.1 oder höher unterstützt den unten stehenden DTV-Standard.

  • DTMB

Demux unterstützt die unten aufgeführten Stream-Protokolle.

  • Transport stream (TS)
  • MPEG Media Transport Protocol (MMTP)
  • Internet Protocol (IP)
  • Wert der Typlänge (TLV)
  • ATSC-Link-Layer-Protokoll (ALP)

Descrambler unterstützt die unten aufgeführten Schutzmaßnahmen für Inhalte.

  • Sicherer Medienpfad
  • Medienpfad löschen
  • Sicherer lokaler Eintrag
  • Sichere lokale Wiedergabe

Tuner-APIs unterstützen die folgenden Anwendungsfälle.

  • Scannen
  • Live
  • Wiedergabe
  • Aufnehmen

Der Tuner, MediaCodec und AudioTrack unterstützen die folgenden Datenflussmodi.

  • ES-Nutzlast mit leerem Zwischenspeicher des Arbeitsspeichers
  • ES-Nutzlast mit sicherem Speicher-Handle
  • Passthrough

Design allgemein

Der Tuner-HAL wird zwischen dem Android-Framework und dem Hardware.

  • Beschreibt, was das Framework vom Anbieter erwartet und wie er möglicherweise Tu es.
  • Exportiert die Funktionen von Frontend, Demux und Descrambler in den über IFrontend, IDemux, IDescrambler, IFilter, IDvr, und ILnb.
  • Enthält die Funktionen zur Integration des Tuner HAL in ein anderes Framework wie MediaCodec und AudioTrack.

Es werden eine Tuner-Java-Klasse und eine native Klasse erstellt.

  • Die Tuner Java API ermöglicht Apps, über öffentliche APIs auf den Tuner HAL zuzugreifen.
  • Die native Klasse ermöglicht die Steuerung von Berechtigungen und die Verarbeitung großer Mengen von mit dem Tuner HAL Daten aufzeichnen oder wiedergeben.
  • Das native Tuner-Modul ist eine Brücke zwischen der Tuner Java-Klasse und dem Tuner HAL.

Eine TRM-Klasse wird erstellt.

  • Verwaltet eingeschränkte Tuner-Ressourcen wie Frontend, LNB, CAS-Sitzungen und ein TV-Eingabegerät vom TV-Eingabe-HAL.
  • Es werden Regeln angewendet, um unzureichende Ressourcen zurückzufordern von Apps. Die Standardregel ist der Sieg im Vordergrund.

Media CAS und CAS HAL wurden mit den folgenden Funktionen erweitert.

  • Öffnet CAS-Sitzungen für verschiedene Verwendungen und Algorithmen.
  • Unterstützt dynamische CAS-Systeme wie das Entfernen und Einfügen von CICAM.
  • Lässt sich in den Tuner HAL einbinden, indem Schlüsseltokens bereitgestellt werden.

MediaCodec und AudioTrack sind durch die folgenden Funktionen erweitert.

  • Verwendet sicheren A/V-Speicher als Inhaltseingabe.
  • Konfiguriert für die A/V-Synchronisation der Hardware bei getunnelter Wiedergabe
  • Die Unterstützung für ES_payload und den Passthrough-Modus wurde konfiguriert.

Gesamtdesign des Tuner HAL.

Abbildung 2: Diagramm der Komponenten in der Tuner-HAL

Allgemeiner Workflow

Die folgenden Diagramme zeigen Aufrufsequenzen für die Wiedergabe von Liveübertragungen.

Einrichten

Diagramm für die Wiedergabe von Liveübertragungen einrichten

Abbildung 3: Sequenz für die Wiedergabe von Liveübertragungen einrichten

Umgang mit Audio/Video

Diagramm zur Handhabung des Audio-/Video-Videostreams für die Wiedergabe von Liveübertragungen.

Abbildung 4: Umgang mit dem A/V bei der Wiedergabe von Live-Übertragungen

Umgang mit verschlüsselten Inhalten

Umgang mit verschlüsselten Inhalten für das Diagramm zur Wiedergabe von Liveübertragungen

Abbildung 5: Verschlüsselte Inhalte bei der Wiedergabe von Liveübertragungen verarbeiten

A/V-Daten werden verarbeitet

A/V-Daten für ein Diagramm zur Wiedergabe von Liveübertragungen verarbeiten

Abbildung 6: Verarbeitung des Audio-/Video-Contents für die Wiedergabe von Live-Übertragungen

Tuner SDK API

Die Tuner SDK API verarbeitet die Interaktionen mit der Tuner JNI, dem Tuner-HAL, und TunerResourceManager. Die TIS App verwendet die Tuner SDK API, um auf Tuner zuzugreifen und Unterkomponenten wie Filter und Descrambler erstellen. 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 neue Funktionen in Tuner HAL 1.1, die ist ein abwärtskompatibles Versionsupgrade von Tuner 1.0.

Verwenden Sie die folgende API, um die ausgeführte HAL-Version zu prüfen.

  • android.media.tv.tuner.TunerVersionChecker.getTunerVersion()

Die mindestens erforderliche HAL-Version finden Sie in der Dokumentation zu den 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. TIS App verwendet das -Paket, um Ressourceninstanzen zu initialisieren und zu erwerben. Dazu wird angegeben, die anfängliche Einstellung und den Callback.

  • tuner(): Initialisiert eine Tuner-Instanz, indem useCase und sessionId-Parameter.
  • tune(): Bezieht eine Frontend-Ressource und stimmt durch Angabe der FrontendSetting-Parameter.
  • openFilter(): Erhält eine Filterinstanz, indem der Filtertyp angegeben wird.
  • openDvrRecorder(): Erhält eine Aufzeichnungsinstanz durch Angabe des Zwischenspeichers Größe.
  • openDvrPlayback(): Erhält eine Wiedergabeinstanz durch Angabe des Zwischenspeichers Größe.
  • openDescrambler(): Erhält eine Descrambler-Instanz.
  • openLnb(): Bezieht eine interne LNB-Instanz.
  • openLnbByName(): Bezieht eine externe LNB-Instanz.
  • openTimeFilter(): Bezieht eine Zeitfilterinstanz.

Das Tuner-Paket bietet Funktionen, die nicht durch die den Filter, den digitalen Videorekorder und das Frontend-Paket. 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, Ereignisse und Funktionen.

Klassen

FrontendSettings wird durch die folgenden Klassen für verschiedene DTV-Standards 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 von den Klassen für verschiedene DTV-Standards abgeleitet. unten.

  • 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 Frontend-Informationen ab. FrontendStatus ruft den aktuellen Status des Front-Ends ab. OnTuneEventListener überwacht die Ereignisse am Front-End. Die TIS-Anwendung verwendet ScanCallback, um Scannachrichten vom Front-End zu verarbeiten.

Kanalsuche

Zum Einrichten eines Fernsehers scannt die App mögliche Frequenzen und erstellt einen Kanal Paket, auf das Nutzer zugreifen können. TIS verwendet möglicherweise Tuner.tune, Tuner.scan(BLIND_SCAN) oder Tuner.scan(AUTO_SCAN), um den Kanal abzuschließen Scannen.

Wenn TIS über genaue Lieferinformationen für das Signal verfügt, z. B. Häufigkeit, Standard (z. B. T/T2, S/S2) und zusätzliche erforderliche Informationen (z. B. PLD ID), dann Tuner.tune wird als schnellere Option empfohlen.

Wenn der Nutzer Tuner.tune aufruft, werden die folgenden Aktionen ausgeführt:

  • TIS füllt FrontendSettings mithilfe von Tuner.tune mit den erforderlichen Informationen.
  • Die HAL-Berichte stimmen LOCKED-Nachrichten ab, wenn das Signal gesperrt ist.
  • TIS verwendet Frontend.getStatus, um die erforderlichen Informationen zu erheben.
  • Mit TIS wird die nächste verfügbare Frequenz in der entsprechenden Häufigkeitsliste ausgewählt.

TIS ruft Tuner.tune noch einmal auf, bis alle Frequenzen ausgeschöpft sind.

Während der Abstimmung kannst du stopTune() oder close() aufrufen, um den Tuner.tune-Anruf.

Tuner.scan(AUTO_SCAN)

Wenn TIS nicht genügend Informationen zur Verwendung von Tuner.tune hat, aber eine Häufigkeit Liste und Standardtyp (z. B. DVB T/C/S) wird Tuner.scan(AUTO_SCAN) empfohlen.

Wenn der Nutzer Tuner.scan(AUTO_SCAN) aufruft, werden die folgenden Aktionen ausgeführt:

  • Bei TIS wird Tuner.scan(AUTO_SCAN) mit der Häufigkeit FrontendSettings verwendet.

  • Die HAL-Berichte scannen LOCKED-Nachrichten, wenn das Signal gesperrt ist. Der HAL könnte auch andere Scan-Nachrichten melden, um zusätzliche Informationen an das Signal senden.

  • TIS verwendet Frontend.getStatus, um notwendige Informationen zu erheben.

  • TIS ruft Tuner.scan für den HAL auf, um mit der nächsten Einstellung auf derselben Häufigkeit. Wenn die FrontendSettings-Struktur leer ist, verwendet der HAL das nächste Einstellung verfügbar. Andernfalls verwendet HAL FrontendSettings einmalig und sendet END, um anzugeben, dass der Scanvorgang abgeschlossen ist.

  • TIS wiederholt die oben genannten Aktionen, bis alle Einstellungen für die Häufigkeit erreicht sind Erschöpft ist.

  • Der HAL sendet END, um anzugeben, dass der Scanvorgang abgeschlossen ist.

  • Mit TIS wird die nächste verfügbare Frequenz in der entsprechenden Häufigkeitsliste ausgewählt.

TIS ruft Tuner.scan(AUTO_SCAN) noch einmal auf, bis alle Frequenzen ausgeschöpft sind.

Während des Scanvorgangs kannst du stopScan() oder close() aufrufen, um den zu überprüfen.

Tuner.scan(BLIND_SCAN)

Wenn TIS keine Häufigkeitsliste hat und der Anbieter HAL nach die Häufigkeit des vom Nutzer angegebenen Front-Ends, um die Front-End-Ressource abzurufen, dann Empfohlen wird Tuner.scan(BLIND_SCAN).

  • TIS verwendet Tuner.scan(BLIND_SCAN). Eine Häufigkeit kann in FrontendSettings für die Starthäufigkeit, aber TIS ignoriert andere Einstellungen in „FrontendSettings“.
  • Der HAL meldet eine LOCKED-Meldung zum Scannen, wenn das Signal gesperrt ist.
  • TIS verwendet Frontend.getStatus, um notwendige Informationen zu erheben.
  • TIS ruft Tuner.scan noch einmal auf, um mit dem Scannen fortzufahren. (FrontendSettings ist ignoriert werden.)
  • TIS wiederholt die oben genannten Aktionen, bis alle Einstellungen für die Häufigkeit erreicht sind Erschöpft ist. Der HAL erhöht die Häufigkeit, ohne dass TIS etwas unternehmen muss. Der HAL meldet PROGRESS.

TIS ruft Tuner.scan(AUTO_SCAN) noch einmal auf, bis alle Frequenzen ausgeschöpft sind. Der HAL meldet END, um anzuzeigen, dass der Scanvorgang abgeschlossen ist.

Während des Scans kannst du stopScan() oder close() aufrufen, um den Scan zu pausieren oder zu beenden.

Flussdiagramm des TIS-Scanvorgangs.

Abbildung 9: Flussdiagramm eines TIS-Scans

Android.media.tv.tuner.filter

Das Filterpaket umfasst eine Sammlung von Filtervorgängen sowie die Konfiguration, Einstellungen, Rückrufe und Ereignisse. Das Paket enthält die folgenden Vorgänge. Die vollständige Liste der Vorgänge finden Sie im Android-Quellcode.

  • configure()
  • start()
  • stop()
  • flush()
  • read()

Eine vollständige Liste finden Sie im Android-Quellcode.

FilterConfiguration wird von den folgenden Klassen abgeleitet. Die Konfigurationen sind für den Hauptfiltertyp und geben an, welches Protokoll der Filter zu extrahieren.

  • AlpFilterConfiguration
  • IpFilterConfiguration
  • MmtpFilterConfiguration
  • TlvFilterConfiguration
  • TsFilterConfiguration

Die Einstellungen werden aus den folgenden Klassen abgeleitet. Die Einstellungen gelten für den Filter 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.

  • SectionEvent
  • MediaEvent
  • PesEvent
  • TsRecordEvent
  • MmtpRecordEvent
  • TemiEvent
  • DownloadEvent
  • IpPayloadEvent

Ab Android 12 mit Tuner HAL 1.1 oder höher werden die folgenden Ereignisse unterstützt.

  • IpCidChangeEvent
  • RestartEvent
  • ScramblingStatusEvent
Ereignisse und Datenformat aus Filter
Filtertyp Flaggen Ereignisse Datenoperation Datenformat
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
Führen Sie gemäß der Veranstaltung und dem internen Zeitplan
aus. Filter.read(buffer, offset, adjustedSize) mindestens eine Mal.

Daten werden aus dem MQ von HAL in den Client-Zwischenspeicher kopiert.
Ein zusammengestelltes Sitzungspaket wird in FMQ von einem anderen gefüllt Sitzungspaket.
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)


Daten werden aus dem MQ von HAL in den Client-Zwischenspeicher kopiert.
TS.PES isRaw:
true
Obligatorisch:

DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW
Empfohlen:
DemuxFilterStatus::LOW_WATER
DemuxFilterStatus::HIGH_WATER
Führen Sie gemäß der Veranstaltung und dem internen Zeitplan
aus. Filter.read(buffer, offset, adjustedSize) mindestens eine Mal.

Daten werden aus dem MQ des HAL in den Client-Zwischenspeicher kopiert.
Ein zusammengestelltes PES-Paket wird in FMQ von einem anderen ausgefüllt. PES-Paket
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 aus dem MQ von HAL in den Client-Zwischenspeicher kopiert.
MMTP.PES isRaw:
true
Obligatorisch:

DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW
Empfohlen:
DemuxFilterStatus::LOW_WATER
DemuxFilterStatus::HIGH_WATER
Führen Sie gemäß der Veranstaltung und dem internen Zeitplan
aus. Filter.read(buffer, offset, adjustedSize) mindestens eine Mal.

Daten werden aus dem MQ des HAL in den Client-Zwischenspeicher kopiert.
Ein zusammengestelltes MFU-Paket wird in FMQ von einem anderen ausgefüllt. MFU-Paket
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 aus dem MQ des HAL in den Client-Zwischenspeicher kopiert.
TS.TS
Obligatorisch:

DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW
Empfohlen:
DemuxFilterStatus::LOW_WATER
DemuxFilterStatus::HIGH_WATER
Führen Sie gemäß der Veranstaltung und dem internen Zeitplan
aus. Filter.read(buffer, offset, adjustedSize) mindestens eine Mal.

Daten werden aus dem MQ des HAL in den Client-Zwischenspeicher kopiert.
ts mit ts-Header
herausgefiltert 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 DemuxFilterStatus::DATA_OVERFLOW empfangen wurde.
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 verwendest du Direct Audio von AudioTrack:
for i=0; i<n; i++
audioHandle = MediaEvent[i].getAudioHandle();
audiotrack.write(encapsulated(audiohandle))
ES- oder partielle ES-Daten im ION-Speicher.
TS.PCR
IP.NTP
ALP.PTP
Obligatorisch: –
Optional: –
TS.RECORD 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ür aufgenommene Inhalte: gemäß RecordStatus::* und dem internen Zeitplan eines der folgenden:
    .
  • DvrRecord.write(adustedSize) laufen einmal oder mehrmals speichern.
    Die Daten werden aus dem MQ des HAL in den Speicher übertragen.
  • DvrRecord.write(buffer, adustedSize) laufen zur Pufferung ein- oder mehrmals.
    Die Daten werden aus dem MQ des HAL in den Client-Zwischenspeicher kopiert.
Für Indexdaten: Werden in Ereignisnutzlast übertragen.

Für aufgenommene Inhalte:Gemeinsamer TS-Stream in FMQ gefüllt.
TS.TEMI 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];
MMTP.MMTP Obligatorisch:

DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW
Empfohlen:
DemuxFilterStatus::LOW_WATER
DemuxFilterStatus::HIGH_WATER
Führen Sie gemäß der Veranstaltung und dem internen Zeitplan
aus. Filter.read(buffer, offset, adjustedSize) mindestens eine Mal.

Daten werden aus dem MQ des HAL in den Client-Zwischenspeicher kopiert.
mmtp mit mmtp-Header
herausgefiltert im FMQ ausgefüllt.
MMTP.RECORD 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ür aufgezeichnete Inhalte gemäß RecordStatus::* und interner Zeitplan, führen Sie einen der Folgendes:
    .
  • DvrRecord.write(adjustedSize) einmal oder mehrmals ausführen zu speichern.
    Die Daten werden aus dem MQ des HAL in den Speicher übertragen.
  • DvrRecord.write(buffer, adjustedSize)1 oder zum Puffern.
    Die Daten werden aus dem MQ des HAL in den Client-Zwischenspeicher kopiert.
Für Indexdaten: Werden in Ereignisnutzlast übertragen.

Für aufgenommene Inhalte:Stummgeschalteter Stream wurde ausgefüllt FMQ

Wenn die Filterquelle für die Aufzeichnung TLV.TLV ist, IP.IP mit Passthrough hat, hat der aufgezeichnete Stream eine TLV und IP-Header.
MMTP.DOWNLOAD 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)

Daten werden aus dem MQ von HAL in den Client-Zwischenspeicher kopiert.
Das Downloadpaket wird in FMQ von einem anderen IP-Downloadpaket gefüllt.
IP.IP_PAYLOAD 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)

Daten werden aus dem MQ von HAL in den Client-Zwischenspeicher kopiert.
Das IP-Nutzlastpaket wird in FMQ von einem anderen IP-Nutzlastpaket gefüllt.
IP.IP
TLV.TLV
ALP.ALP
isPassthrough:
true
Optional:

DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW
Durch den herausgefilterten Protokoll-Substream wird der nächste Filter im Filter hinzugefügt Kette hinzufügen.
isPassthrough:
false
Obligatorisch:

DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW
Empfohlen:
DemuxFilterStatus::LOW_WATER
DemuxFilterStatus::HIGH_WATER
Führen Sie gemäß der Veranstaltung und dem internen Zeitplan
aus. Filter.read(buffer, offset, adjustedSize) mindestens eine Mal.

Daten werden aus dem MQ des HAL in den Client-Zwischenspeicher kopiert.
Ausgefilterter Protokoll-Substream mit Protokollheader wird ausgefüllt FMQ
IP.PAYLOAD_THROUGH
TLV.PAYLOAD_THROUGH
ALP.PAYLOAD_THROUGH
Optional:

DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW
Ausgefilterte Protokollnutzlasten werden in den nächsten Filter im Filter eingespeist Kette hinzufügen.
Beispielablauf zur Verwendung eines Filters zum Erstellen von PSI/SI

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

Abbildung 10. Vorgang zum Erstellen 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 für die Verwendung von MediaEvent aus einem Filter

Beispielablauf für die Verwendung von MediaEvent aus einem 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 erhalten.
  4. Stellen Sie den linearen Block an codec in die Warteschlange.
  5. Lassen Sie den A/V-Handle los, wenn die Daten verbraucht sind.

Android.media.tv.tuner.dvr

DvrRecorder bietet folgende Aufnahmemethoden.

  • configure
  • attachFilter
  • detachFilter
  • start
  • flush
  • stop
  • setFileDescriptor
  • write

DvrPlayback bietet folgende Wiedergabemethoden.

  • configure
  • start
  • flush
  • stop
  • setFileDescriptor
  • read

Mit DvrSettings werden DvrRecorder und DvrPlayback konfiguriert. OnPlaybackStatusChangedListener und OnRecordStatusChangedListener werden verwendet um den Status einer DVR-Instanz zu melden.

Beispielablauf zum Starten eines Eintrags

Beispielablauf zum Starten eines Eintrags.

Abbildung 12. Ablauf zum Starten eines Eintrags

  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. Sie erhalten RecordEvent und rufen 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 Eintragsdaten.

      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 dem HIDL und definiert die Schnittstelle zwischen dem Framework und der Hardware von Anbietern. Anbieter nutzen die Schnittstelle, um den Tuner-HAL und den verwendet es für die Kommunikation mit der Tuner-HAL-Implementierung.

Module

Tuner HAL 1.0

Module Grundlegende Bedienelemente Modulspezifische Steuerelemente HAL-Dateien
ITuner 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 (von Tuner HAL 1.0)

Module Grundlegende Bedienelemente Modulspezifische Steuerelemente HAL-Dateien
ITuner 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 Filterverknüpfungen, sodass Filter mit anderen Filter für mehrere Ebenen. Für die Filter gelten die folgenden Regeln.

  • Filter sind als Baumstruktur verknüpft, Schließpfad ist nicht zulässig.
  • Der Root-Knoten ist demux.
  • Filter funktionieren unabhängig voneinander.
  • Mit allen Filtern werden jetzt Daten abgerufen.
  • Durch die Filterverknüpfung wird der letzte Filter ausgeblendet.

Der Codeblock unten und Abbildung 14 zeigen 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 mit einem Beispiel für eine Filterverknüpfung.

Abbildung 14: Flussdiagramm einer Filterverknüpfung für mehrere Ebenen

Tuner-Ressourcenmanager

Vor dem Tuner Resource Manager (TRM) erforderte der Wechsel zwischen zwei Apps die mit derselben Tuner-Hardware. Beim TV Input Framework (TIF) wurde der Zuschlag für den Gewinn beim ersten Nutzer verwendet. Dies bedeutet, dass jede Anwendung, die die Ressource zuerst abruft, 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 den Tuner, die TVInput- und CAS-Hardware zu verwalten für Apps. TRM setzt sich durch einen „Vordergrundsieg“ ein einen Mechanismus einzurichten, Die Priorität der App wird anhand des Vorder- oder Hintergrunds der App berechnet und Anwendungsfalltyp. Der TRM erteilt oder widerruft die Ressource basierend auf Priorität hat. TRM zentralisiert ATV-Ressourcenverwaltung für Broadcasting, OTT, und DVR.

TRM-Schnittstelle

TRM stellt AIDL-Schnittstellen in ITunerResourceManager.aidl für den Tuner zur Verfügung Framework, MediaCas und TvInputHardwareManager, um sich zu registrieren, Ressourcen freigeben.

Oberflächen für die Clientverwaltung 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 Anfrageklassen sind unten aufgeführt.

  • ResourceClientProfile
  • ResourcesReclaimListener
  • TunerFrontendRequest
  • TunerDemuxRequest
  • TunerDescramblerRequest
  • CasSessionRequest
  • TunerLnbRequest

Clientpriorität

TRM berechnet die Priorität des Clients mithilfe von Parametern aus dem und den Prioritätswert aus der Konfigurationsdatei. Die Priorität könnte auch durch einen beliebigen Prioritätswert vom Client aktualisiert werden.

Parameter im Profil des Kunden

Der TRM ruft die Prozess-ID von mTvInputSessionId ab, um zu entscheiden, 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 (siehe unten).

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 enthält Prioritätswerte für vordefinierte Verwendungen Cases. Nutzende können die Werte mithilfe einer einer benutzerdefinierten Konfigurationsdatei.

Anwendungsfall Vordergrund Hintergrund
LIVE 490 400
PLAYBACK 480 300
RECORD 600 500
SCAN 450 200
BACKGROUND 180 100
Benutzerdefinierte Konfigurationsdatei

Anbieter können die Konfigurationsdatei anpassen /vendor/etc/tunerResourceManagerUseCaseConfig.xml Diese Datei wird verwendet um die Anwendungsfalltypen und die Prioritätswerte für Anwendungsfälle hinzuzufügen, zu entfernen oder zu aktualisieren. Die benutzerdefinierte Datei kann platform/hardware/interfaces/tv/tuner/1.0/config/tunerResourceManagerUseCaseConfigSample.xml als Vorlage verwenden.

Ein neuer Anwendungsfall für Anbieter ist beispielsweise VENDOR_USE_CASE__[A-Z0-9]+, [0 - 1000]. Das Format sollte platform/hardware/interfaces/tv/tuner/1.0/config/tunerResourceManagerUseCaseConfig.xsd

Beliebiger Prioritätswert und attraktiver Wert

TRM stellt dem Client updateClientPriority zur Verfügung, um willkürliche und einen schönen Wert haben. Der beliebige Prioritätswert überschreibt den berechneten Prioritätswert. aus Anwendungsfalltyp und Sitzungs-ID.

Der Wert gibt an, wie nachsichtig das Verhalten des Kunden ist, wenn er einen Konflikt mit einem anderen Client verursacht. Der Wert senkt die Priorität des Kunden. vor dem Prioritätswert mit dem herausfordernden Kunden verglichen wird.

Rückforderungsmechanismus

Das folgende Diagramm zeigt, wie Ressourcen zurückgefordert und zugewiesen werden, kommt es zu einem Ressourcenkonflikt.

Diagramm des Ablaufs des Rückforderungsmechanismus.

Abbildung 15. Diagramm des Reaktivierungsmechanismus für einen Konflikt zwischen dem Tuner Ressourcen