Tuner-Framework

Für Android 11 oder höher können Sie das Android Tuner-Framework verwenden, um A/V-Inhalte bereitzustellen. Das Framework verwendet 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, sodass sie in einer stark eingeschränkten Inhaltsschutzumgebung verwendet werden können.

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 eine Eine - Welt - Lösung für Android TV zu bauen. Die Tuner-Schnittstelle unterstützt sowohl digitales als auch analoges Fernsehen basierend auf den wichtigsten Sendestandards.

Komponenten

Für Android 11 wurden drei Komponenten speziell für die TV-Plattform entwickelt.

  • Tuner HAL: Eine Schnittstelle zwischen Rahmen und Lieferanten
  • Tuner SDK API: Eine Schnittstelle zwischen Rahmen und Anwendungen
  • Tuner Resource Manager (TRM): Koordinaten Tuner HW Ressourcen

Für Android 11 wurden die folgenden Komponenten verbessert.

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

Flussdiagramm der Tuner-Framework-Komponenten.

Abbildung 1. Wechselwirkungen 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
  • Medienpfad löschen
  • Lokale Aufzeichnung sichern
  • Sichere lokale Wiedergabe

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

  • Scan
  • Live
  • Wiedergabe
  • Aufzeichnen

Tuner, MediaCodec und AudioTrack unterstützt die Datenfluss - Modi unten.

  • ES-Nutzlast mit klarem Speicherpuffer
  • ES-Nutzlast mit sicherem Speicherhandle
  • Passthrough

Gesamtkonzept

Die Tuner-HAL wird zwischen dem Android-Framework und der Hardware des Herstellers definiert.

  • Beschreibt, was das Framework vom Anbieter erwartet und wie der Anbieter dies tun könnte.
  • Die Exporte , die Funktionalitäten von Frontend, demux und Descrambler auf den Rahmen durch IFrontend , IDemux , IDescrambler , IFilter , IDvr und ILnb Schnittstellen.
  • Enthält die Funktionen des Tuners HAL mit anderen Framework - Komponenten, wie zum Beispiel die Integration MediaCodec und AudioTrack .

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

  • Die Tuner-Java-API ermöglicht Apps den Zugriff auf die Tuner-HAL über öffentliche APIs.
  • Die native Klasse ermöglicht die Berechtigungskontrolle und den Umgang mit großen Mengen von 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 die TV-Eingangs-HAL.
  • Wendet Regeln an, um unzureichende Ressourcen von Apps zurückzufordern. Die Standardregel ist der Vordergrundgewinn.

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

  • Öffnet CAS-Sitzungen für verschiedene Verwendungen und Algorithmen.
  • Unterstützt dynamische CAS-Systeme, wie z. B. das Entfernen und Einfügen von CICAM.
  • Integriert sich in den Tuner HAL durch Bereitstellung von Schlüsseltoken.

MediaCodec und AudioTrack sind unten mit den Funktionen erweitert.

  • Nimmt sicheren A/V-Speicher als Inhaltseingang.
  • Konfiguriert für die Hardware-A/V-Synchronisierung bei getunnelter Wiedergabe.
  • Konfiguriert Unterstützung für ES_payload und Pass - Through - Modus.

Gesamtdesign des Tuner HAL.

Abbildung 2. Schematische Darstellung der Komponenten innerhalb der Tuner HAL

Gesamtworkflow

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

Aufstellen

Setup-Sequenz des Wiedergabediagramms für Live-Übertragungen.

Abbildung 3. Setup - Sequenz , die für Live - Übertragung der Wiedergabe

Umgang mit A/V

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

Abbildung 4. Umgang mit A / V für Live - Übertragung der Wiedergabe

Umgang mit verschlüsselten Inhalten

Diagramm zum Umgang mit verschlüsseltem Inhalt für die Wiedergabe von Live-Übertragungen.

Abbildung 5. Umgang mit verschlüsselten Inhalten für Live - Übertragung der Wiedergabe

A/V-Daten verarbeiten

A/V-Daten für das Wiedergabediagramm für Live-Übertragungen verarbeiten.

Abbildung 6. Die Verarbeitung A / V für die Live - Übertragung der Wiedergabe

Tuner-SDK-API

Der Tuner SDK API behandelt die Interaktionen mit dem Tuner JNI, der 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 dem Tuner SDK API

Versionen

Ab Android 12 unterstützt die Tuner SDK API neue Funktionen 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 bietet die folgenden vier 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 die Verwendung des Tuner-Frameworks. Die TIS-App verwendet das Paket zum Initialisieren und Abrufen von Ressourceninstanzen durch Angabe der Anfangseinstellung und des Rückrufs.

  • tuner() : Initialisiert eine Tuner - Instanz durch die Spezifizierungs useCase und sessionId Parameter.
  • tune() : erhält eine Frontend - Ressource und Melodie durch die Angabe FrontendSetting Parameter.
  • openFilter() : erhält eine Filterinstanz durch den Filtertyp angeben.
  • openDvrRecorder() : erhält eine Aufzeichnungsweise durch die Puffergröße angibt.
  • openDvrPlayback() : erhält eine Wiedergabe - Instanz durch die Puffergröße angibt.
  • openDescrambler() : erhält eine Descrambler - Instanz.
  • openLnb() : Ermittelt eine interne LNB - Instanz.
  • openLnbByName() : Ermittelt eine externe LNB - Instanz.
  • openTimeFilter() : erhält eine Filterinstanz Zeit.

Das Tuner-Paket bietet Funktionen, 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 enthält Sammlungen von Frontend-bezogenen Einstellungen, Informationen, Status, Ereignissen und Funktionen.

Klassen

FrontendSettings ist unten für verschiedene DTV - Standards durch die 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 ist unten für verschiedene DTV - Standards durch die 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 Frontend. FrontendStatus ruft den aktuellen Status des Frontends. OnTuneEventListener Streams auf die Ereignisse auf dem Frontend. Die TIS App nutzt ScanCallback Scan Nachrichten vom Frontend zu verarbeiten.

Kanalsuchlauf

Um einen Fernseher einzurichten, scannt die App mögliche Frequenzen und baut eine Kanalliste auf, auf die Benutzer zugreifen können. TIS verwenden könnte Tuner.tune , Tuner.scan(BLIND_SCAN) oder Tuner.scan(AUTO_SCAN) , um eine vollständige Kanalabtastung.

Wenn TIS genaue Lieferinformationen für das Signal hat, wie Frequenz, Standard (beispielsweise T / T2, S / S2), und weitere notwendige Informationen (beispielsweise PLD ID), dann Tuner.tune wird als die schnellere Möglichkeit empfohlen .

Wenn der Benutzer ruft Tuner.tune , passieren die folgenden Aktionen:

  • TIS auffüllt FrontendSettings mit den erforderlichen Informationen mit Tuner.tune .
  • Die HAL - Berichte stimmen LOCKED - Meldungen , wenn das Signal gesperrt ist.
  • TIS verwendet Frontend.getStatus die notwendigen Informationen zu sammeln.
  • TIS wechselt zur nächsten verfügbaren Frequenz in seiner Frequenzliste.

TIS ruft Tuner.tune wieder , bis alle Frequenzen erschöpft sind.

Während Tuning, können Sie anrufen stopTune() oder close() zu unterbrechen oder das Ende Tuner.tune Anruf.

Tuner.scan(AUTO_SCAN)

Wenn TIS nicht genug Informationen zu verwenden , hat Tuner.tune , sondern eine Frequenzliste und Standardtyp hat (zB DVB - T / C / S), dann Tuner.scan(AUTO_SCAN) wird empfohlen.

Wenn der Benutzer ruft Tuner.scan(AUTO_SCAN) treten die folgenden Aktionen:

  • TIS verwendet Tuner.scan(AUTO_SCAN) mit FrontendSettings mit der Frequenz gefüllt.

  • Die HAL Berichte Scan LOCKED - Nachrichten , wenn das Signal gesperrt ist. Die HAL kann auch andere Scannachrichten melden, um zusätzliche Informationen über das Signal bereitzustellen.

  • TIS verwendet Frontend.getStatus notwendige Informationen zu sammeln.

  • TIS ruft Tuner.scan für die HAL in die nächste Einstellung auf der gleichen Frequenz fortzusetzen. Wenn die FrontendSettings Struktur leer ist, verwendet der HAL die nächste verfügbare Einstellung. Andernfalls verwendet HAL FrontendSettings für eine einmalige Scan und sendet END , um anzuzeigen , dass der Scanvorgang beendet ist.

  • TIS wiederholt die oben genannten Aktionen, bis alle Einstellungen auf der Frequenz erschöpft sind.

  • Der HAL sendet END , um anzuzeigen , dass der Scanvorgang beendet ist.

  • TIS wechselt zur nächsten verfügbaren Frequenz in seiner Frequenzliste.

TIS ruft Tuner.scan(AUTO_SCAN) wieder , bis alle Frequenzen erschöpft sind.

Während des Scannens können Sie anrufen stopScan() oder close() zu unterbrechen oder den Scan zu beenden.

Tuner.scan(BLIND_SCAN)

Wenn TIS keine Frequenzliste hat und der Verkäufer HAL kann für die Frequenz des vom Benutzer angegebenen Frontend - Suche Frontend - Ressource zu erhalten, dann Tuner.scan(BLIND_SCAN) wird empfohlen.

  • TIS verwendet Tuner.scan(BLIND_SCAN) . Eine Frequenz kann in angegeben werden FrontendSettings für Startfrequenz, aber TIS ignoriert andere Einstellungen in FrontendSettings .
  • Der HAL meldet einen Scan LOCKED Nachricht , wenn Signal gesperrt ist.
  • TIS verwendet Frontend.getStatus notwendige Informationen zu sammeln.
  • TIS ruft Tuner.scan wieder den Scanvorgang fortzusetzen. ( FrontendSettings wird ignoriert.)
  • TIS wiederholt die oben genannten Aktionen, bis alle Einstellungen auf der Frequenz erschöpft sind. Die HAL erhöht die Frequenz, ohne dass eine Aktion von TIS erforderlich ist. Der HAL berichtet PROGRESS .

TIS ruft Tuner.scan(AUTO_SCAN) wieder , bis alle Frequenzen erschöpft sind. Der HAL berichtet END , um anzuzeigen , dass der Scanvorgang beendet ist.

Während des Scannens können Sie anrufen stopScan() oder close() zu unterbrechen oder den Scan zu beenden.

Flussdiagramm des TIS Scan-Prozesses.

Abbildung 9. Flussdiagramm eines Scan TIS

Android.media.tv.tuner.filter

Das Filterpaket ist eine Sammlung von Filtervorgängen zusammen mit Konfiguration, Einstellungen, Rückrufen und Ereignissen. Das Paket enthält die folgenden Operationen. Die vollständige Liste der Operationen finden Sie im Android-Quellcode.

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

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

FilterConfiguration wird unten aus den 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 werden aus den folgenden Klassen abgeleitet. 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 für verschiedene Arten von Daten aus den Klassen unten an Bericht Ereignisse abgeleitet.

  • 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
Filter Typ Flaggen Veranstaltungen Datenbetrieb Datei Format
TS.SECTION
MMTP.SECTION
IP.SECTION
TLV.SECTION
ALP.SECTION
isRaw:
true
Verpflichtend:
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW

Empfohlen:
DemuxFilterStatus::LOW_WATER
DemuxFilterStatus::HIGH_WATER
Je nach Veranstaltung und internem Zeitplan laufen
Filter.read(buffer, offset, adjustedSize) ein oder mehrere Male.

Die Daten werden aus der MQ von HAL in den Clientpuffer kopiert.
Ein zusammengestelltes Sitzungspaket wird in FMQ durch ein anderes Sitzungspaket gefüllt.
isRaw:
false
Verpflichtend:
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 aus der MQ von HAL in den Clientpuffer kopiert.
TS.PES isRaw:
true
Verpflichtend:
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW

Empfohlen:
DemuxFilterStatus::LOW_WATER
DemuxFilterStatus::HIGH_WATER
Je nach Veranstaltung und internem Zeitplan laufen
Filter.read(buffer, offset, adjustedSize) ein oder mehrere Male.

Daten werden aus der MQ der HAL in den Clientpuffer kopiert.
Ein zusammengestelltes PES-Paket wird in FMQ von einem anderen PES-Paket gefüllt.
isRaw:
false
Verpflichtend:
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 aus der MQ von HAL in den Clientpuffer kopiert.
MMTP.PES isRaw:
true
Verpflichtend:
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW

Empfohlen:
DemuxFilterStatus::LOW_WATER
DemuxFilterStatus::HIGH_WATER
Je nach Veranstaltung und internem Zeitplan laufen
Filter.read(buffer, offset, adjustedSize) ein oder mehrere Male.

Daten werden aus der MQ der HAL in den Clientpuffer kopiert.
Ein zusammengestelltes MFU-Paket wird im FMQ durch ein anderes MFU-Paket gefüllt.
isRaw:
false
Verpflichtend:
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 der MQ der HAL in den Clientpuffer kopiert.
TS.TS
N / A Verpflichtend:
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW

Empfohlen:
DemuxFilterStatus::LOW_WATER
DemuxFilterStatus::HIGH_WATER
Je nach Veranstaltung und internem Zeitplan laufen
Filter.read(buffer, offset, adjustedSize) ein oder mehrere Male.

Daten werden aus der MQ der HAL in den Clientpuffer kopiert.
Herausgefiltert ts mit ts Kopf
wird in FMQ ausgefüllt.
TS.Audio
TS.Video
MMTP.Audio
MMTP.Video
isPassthrough:
true
Optional:
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW
Der Kunde kann beginnen MediaCodec nach dem Empfang DemuxFilterStatus::DATA_READY .
Der Kunde kann sich nennen Filter.flush nach dem Empfang DemuxFilterStatus::DATA_OVERFLOW .
N / A
isPassthrough:
false
Verpflichtend:
DemuxFilterEvent::DemuxFilterMediaEvent[n]
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW

Optional:
DemuxFilterStatus::LOW_WATER
DemuxFilterStatus::HIGH_WATER
Zur Nutzung 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 partielle 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 Verpflichtend:
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 aufgezeichnete Inhalte, nach RecordStatus::* und internem Zeitplan, wählen Sie eine der folgenden Möglichkeiten :
  • Run DvrRecord.write(adustedSize) ein oder mehrere Male , um die Lagerung.
    Die Daten werden von der MQ des HAL in den Speicher übertragen.
  • Run DvrRecord.write(buffer, adustedSize) ein oder mehrere Male zu puffern.
    Die Daten werden aus der MQ der HAL in den Clientpuffer kopiert.
Für Indexdaten: in Ereignisnutzlast getragen.

Für aufgezeichneten Inhalt: Muxed TS in FMQ gefüllt Stream.
TS.TEMI N / A Verpflichtend:
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 Verpflichtend:
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW

Empfohlen:
DemuxFilterStatus::LOW_WATER
DemuxFilterStatus::HIGH_WATER
Je nach Veranstaltung und internem Zeitplan laufen
Filter.read(buffer, offset, adjustedSize) ein oder mehrere Male.

Daten werden aus der MQ der HAL in den Clientpuffer kopiert.
Filtert mmtp mit mmtp Kopf
wird in FMQ ausgefüllt.
MMTP.RECORD N / A Verpflichtend:
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, nach RecordStatus::* und internem Zeitplan, wählen Sie eine der folgenden Möglichkeiten :
  • Run DvrRecord.write(adjustedSize) ein oder mehrere Male , um die Lagerung.
    Die Daten werden von der MQ des HAL in den Speicher übertragen.
  • Run DvrRecord.write(buffer, adjustedSize) ein oder mehrere Male zu puffern.
    Die Daten werden aus der MQ der HAL in den Clientpuffer kopiert.
Für Indexdaten: in Ereignisnutzlast getragen.

Für aufgezeichneten Inhalt: Muxed Strom in FMQ gefüllt aufgezeichnet.

Wenn der Filter Quelle für die Aufnahme ist TLV.TLV zu IP.IP mit Pass - Through, hat das aufgezeichnete Stream einen TLV und IP - Header.
MMTP.DOWNLOAD N / A Verpflichtend:
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 aus der MQ von HAL in den Clientpuffer kopiert.
Download-Paket wird in FMQ von einem anderen IP-Download-Paket gefüllt.
IP.IP_PAYLOAD N / A Verpflichtend:
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 aus der MQ von HAL in den Clientpuffer kopiert.
Das IP-Nutzlastpaket wird in FMQ durch ein anderes IP-Nutzlastpaket gefüllt.
IP.IP
TLV.TLV
ALP.ALP
isPassthrough:
true
Optional:
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW
Ausgefilterter Protokoll-Substream speist den nächsten Filter in der Filterkette. N / A
isPassthrough:
false
Verpflichtend:
DemuxFilterStatus::DATA_READY
DemuxFilterStatus::DATA_OVERFLOW

Empfohlen:
DemuxFilterStatus::LOW_WATER
DemuxFilterStatus::HIGH_WATER
Je nach Veranstaltung und internem Zeitplan laufen
Filter.read(buffer, offset, adjustedSize) ein oder mehrere Male.

Daten werden aus der MQ der HAL in den Clientpuffer kopiert.
Ausgefilterter Protokoll-Substream 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
Ausgefilterte Protokollnutzlast speist den nächsten Filter in der Filterkette. N / A
Beispielablauf zur Verwendung von Filtern zum Erstellen von PSI/SI

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

Abbildung 10. Durchfluss zu bauen 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. Verarbeiten 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); }
          }
        }
    };
    
Beispielablauf zur Verwendung von MediaEvent aus Filter

Beispielablauf zur Verwendung von MediaEvent aus dem Filter.

Abbildung 11. Durchfluss verwenden Mediaevent aus Filter

  1. Öffnen, konfigurieren und starten Sie die A/V-Filter.
  2. Verarbeiten MediaEvent .
  3. Erhalten MediaEvent .
  4. Warteschlange des linearen Block - codec .
  5. Lassen Sie das A/V-Handle los, wenn die Daten verbraucht sind.

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 zu konfigurieren verwendet DvrRecorder und DvrPlayback . 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. Durchfluss eine Aufzeichnung zu starten

  1. Öffnen Sie , konfigurieren und starten 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. Erhalten RecordEvent und die Indexinformationen abzurufen.

    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 OnRecordStatusChangedListener und speichern Sie die Aufzeichnungsdaten.

      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);
          }
        }
      };
    

Stimmgerät HAL

Der Tuner HAL folgt HIDL und definiert die Schnittstelle zwischen dem Framework und der Herstellerhardware. Anbieter verwenden die Schnittstelle, um die Tuner-HAL zu implementieren, und das Framework verwendet sie, um mit der Tuner-HAL-Implementierung zu kommunizieren.

Module

Stimmgerät HAL 1.0

Module Grundlegende Bedienelemente Modulspezifische Steuerungen 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 Bedienelemente Modulspezifische Steuerungen 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. Schematische Darstellung der Wechselwirkungen zwischen den Tuner HAL - Module

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 folgenden Regeln.

  • Filter sind als Baum verknüpft, Pfad schließen ist nicht erlaubt.
  • Der Wurzelknoten ist demux.
  • Filter arbeiten unabhängig.
  • Alle Filter beginnen mit dem Abrufen von Daten.
  • Das Filtergestänge spült am 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. Ablaufdiagramm einer Filterkopplung für mehrere Schichten

Tuner-Ressourcen-Manager

Vor dem Tuner Resource Manager (TRM) war für den Wechsel zwischen zwei Apps dieselbe Tuner-Hardware erforderlich. TV Input Framework (TIF) verwendet einen "First-to-Acquire-Win"-Mechanismus, was bedeutet, dass die App, die die Ressource zuerst erhält, die Ressource behält. Dieser Mechanismus ist jedoch für einige komplizierte Anwendungsfälle möglicherweise nicht ideal.

TRM läuft als Systemdienst des Tuners, zu verwalten TVInput und CAS Hardware - Ressourcen für Anwendungen. TRM verwendet einen "Foreground Win"-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 das ATV-Ressourcenmanagement für Broadcast, OTT und DVR.

TRM-Schnittstelle

TRM Exposes AIDL Schnittstellen in ITunerResourceManager.aidl für die Tuner Rahmen, MediaCas und TvInputHardwareManager zu registrieren, Anfrage oder Release - Ressourcen.

Schnittstellen für das Client-Management 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 Request-Klassen 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 willkürlichen Prioritätswert vom Client aktualisiert werden.

Parameter im Kundenprofil

TRM ruft die Prozess - ID von mTvInputSessionId zu entscheiden , ob eine Anwendung ein Vordergrund- oder Hintergrund App ist. So erstellen mTvInputSessionId , TvInputService.onCreateSession oder TvInputService.onCreateRecordingSession eine TIS - Sitzung initialisiert.

mUseCase zeigt den Anwendungsfall der Sitzung. 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. Die Benutzer können die Werte ändern , um eine mit angepassten 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 der Anwendungsfälle hinzuzufügen, zu entfernen oder zu aktualisieren. Die angepasste Datei verwenden können , platform/hardware/interfaces/tv/tuner/1.0/config/tunerResourceManagerUseCaseConfigSample.xml als Vorlage.

Zum Beispiel ist ein neuer Anbieter Use Case VENDOR_USE_CASE__[A-Z0-9]+, [0 - 1000] . Das Format sollte folgen platform/hardware/interfaces/tv/tuner/1.0/config/tunerResourceManagerUseCaseConfig.xsd .

Beliebiger Prioritätswert und schöner Wert

TRM bietet updateClientPriority für die Kunden den willkürlichen Prioritätswert und schön Wert zu aktualisieren. Der beliebige Prioritätswert überschreibt den aus Anwendungsfalltyp und Sitzungs-ID berechneten Prioritätswert.

Der nette Wert gibt an, wie nachsichtig das Verhalten des Klienten ist, wenn er mit einem anderen Klienten in Konflikt steht. Der nette Wert verringert den Prioritätswert des Clients, bevor sein Prioritätswert mit dem des herausfordernden Clients verglichen wird.

Rückforderungsmechanismus

Das folgende Diagramm zeigt, wie Ressourcen zurückgefordert und zugewiesen werden, wenn ein Ressourcenkonflikt auftritt.

Diagramm des Rückforderungsmechanismus-Prozesses.

Abbildung 15. Schematische Darstellung des Rückforderungsmechanismus für einen Konflikt zwischen Tuner Ressourcen