Die in Android 12 eingeführte kompatible Medien-Transcodierung ist eine Funktion, mit der Geräte modernere, speichereffizientere Medienformate für die Videoaufnahme verwenden können, z. B. HEVC, und gleichzeitig die Kompatibilität mit Apps beibehalten. Mit dieser Funktion können Gerätehersteller standardmäßig HEVC anstelle von AVC verwenden, um die Videoqualität zu verbessern und gleichzeitig die Speicher- und Bandbreitenanforderungen zu reduzieren. Auf Geräten, auf denen die kompatible Medienumcodierung aktiviert ist, kann Android Videos (mit einer Länge von bis zu einer Minute), die in Formaten wie HEVC oder HDR aufgenommen wurden, automatisch konvertieren, wenn sie von einer App geöffnet werden, die das Format nicht unterstützt. So können Apps auch dann funktionieren, wenn Videos auf dem Gerät in neueren Formaten aufgenommen werden.
Die Funktion zur Transcodierung in kompatible Medienformate ist standardmäßig deaktiviert. Wenn Apps die Media-Transcodierung anfordern möchten, müssen sie ihre Media-Funktionen deklarieren. Weitere Informationen zum Deklarieren von Media-Funktionen finden Sie auf der Website für Android-Entwickler unter Kompatible Media-Transcodierung.
Funktionsweise
Das Feature zur kompatiblen Medien-Transcodierung besteht aus zwei Hauptteilen:
- Transcodierungsdienste im Media Framework:Mit diesen Diensten werden Dateien mithilfe von Hardware in ein anderes Format konvertiert. Das Ergebnis ist eine niedrige Latenz und eine hohe Qualität. Dazu gehören die Transcoding API, der Transcoding-Dienst, ein OEM-Plug-in für benutzerdefinierte Filter und Hardware. Weitere Informationen finden Sie unter Architekturübersicht.
- Funktion zum Transcodieren kompatibler Medien in Media-Providern:Diese Komponente in Media-Providern fängt Apps ab, die auf Mediendateien zugreifen, und stellt entweder die Originaldatei oder eine transcodierte Datei bereit, je nach den deklarierten Funktionen der App. Wenn eine App das Format der Mediendatei unterstützt, ist keine spezielle Verarbeitung erforderlich. Wenn eine App das Format nicht unterstützt, konvertiert das Framework die Datei in ein älteres Format wie AVC, wenn die App auf die Datei zugreift.
Abbildung 1 zeigt eine Übersicht über den Medientranscodierungsprozess.
Abbildung 1. Übersicht über die Transcodierung in kompatibles Medienformat.
Unterstützte Formate
Die Funktion zur kompatiblen Medien-Transcodierung unterstützt die folgenden Formatkonvertierungen:
- HEVC (8 Bit) zu AVC:Codec-Konvertierungen werden durch Verbinden eines MediaCodec-Decoders und eines MediaCodec-Encoders durchgeführt.
- HDR10+ (10‑Bit) zu AVC (SDR): HDR‑zu‑SDR-Konvertierungen werden mit mediacodec-Instanzen und einem Anbieter-Plugin-Hook in den Decoder-Instanzen durchgeführt. Weitere Informationen finden Sie unter HDR-zu-SDR-Codierung.
Unterstützte Inhaltsquellen
Die Funktion zur Media-Transcodierung unterstützt auf dem Gerät generierte Medien, die von der nativen OEM-Kamera-App erstellt und im Ordner DCIM/Camera/ auf dem primären externen Volume gespeichert wurden. Die Funktion unterstützt keine Medien auf sekundären Speichermedien.
Inhalte, die per E-Mail oder SD-Karte an Geräte gesendet werden, werden nicht unterstützt.
Apps greifen über verschiedene Dateipfade auf die Dateien zu. Im Folgenden werden die Dateipfade beschrieben, in denen die Transcodierung aktiviert oder umgangen wird:
Transcodierung aktiviert:
- App-Zugriff über MediaStore-APIs
- App-Zugriff über APIs für direkte Dateipfade, einschließlich Java- und nativem Code
- App-Zugriff über das Storage Access Framework (SAF)
- App-Zugriff über die Intents des Betriebssystems. (nur MediaStore-URI)
- MTP-/PTP-Dateiübertragung vom Smartphone auf den PC
Transcodierung umgangen:
- Dateien von einem Gerät übertragen, indem die SD-Karte ausgeworfen wird
- Dateien mit Optionen wie Nearby Share oder Bluetooth-Übertragung von Gerät zu Gerät übertragen.
Benutzerdefinierte Dateipfade für die Transcodierung hinzufügen
Gerätehersteller können optional Dateipfade für die Media-Transcodierung im Verzeichnis DCIM/ hinzufügen. Alle Pfade außerhalb des DCIM/-Verzeichnisses werden abgelehnt.
Das Hinzufügen solcher Dateipfade kann erforderlich sein, um die Anforderungen von Mobilfunkanbietern oder lokale Vorschriften zu erfüllen.
Wenn Sie einen Dateipfad hinzufügen möchten, verwenden Sie das RRO (Runtime Resource Overlay) für den Transcodierungspfad: config_supported_transcoding_relative_paths. Hier ein Beispiel dafür, wie Sie einen Dateipfad hinzufügen:
<string-array name="config_supported_transcoding_relative_paths" translatable="false">
<item>DCIM/JCF/</item>
</string-array>
So prüfen Sie die konfigurierten Dateipfade:
adb shell dumpsys activity provider com.google.android.providers.media.module/com.android.providers.media.MediaProvider | head -n 20Architektur
In diesem Abschnitt wird die Architektur der Funktion zur Medientranskodierung beschrieben.
Abbildung 2: Architektur der Medientranscodierung.
Die Architektur für die Medien-Transcodierung besteht aus den folgenden Komponenten:
- MediaTranscodingManager-System-API:Schnittstelle, über die der Client mit dem MediaTranscoding-Dienst kommunizieren kann. Das Modul MediaProvider verwendet diese API.
- MediaTranscodingService:Nativer Dienst, der Clientverbindungen verwaltet, Transcodierungsanfragen plant und die Buchhaltung für
TranscodingSessionsverwaltet. - MediaTranscoder:Native Bibliothek, die die Transcodierung ausführt. Diese Bibliothek basiert auf dem Media Framework NDK, um mit Modulen kompatibel zu sein.
Bei der Transcodierung in kompatibles Medienformat werden Transcodierungsstatistiken sowohl im Dienst als auch im Medientranscoder protokolliert. Der clientseitige und der dienstseitige Code befinden sich im MediaProvider-Modul, um zeitnahe Fehlerkorrekturen und Updates zu ermöglichen.
Dateizugriff
Die Transcodierung in kompatibles Medienformat basiert auf dem FUSE-Dateisystem (Filesystem in Userspace), das für den begrenzten Speicher verwendet wird. FUSE ermöglicht es dem MediaProvider-Modul, Dateivorgänge im Nutzerbereich zu untersuchen und den Zugriff auf Dateien basierend auf der Richtlinie zu steuern, um den Zugriff zuzulassen, zu verweigern oder zu entfernen.
Wenn eine App versucht, auf eine Datei zuzugreifen, fängt der FUSE-Daemon den Lesezugriff der App auf die Datei ab. Wenn die App ein neueres Format (z. B. HEVC) unterstützt, wird die Originaldatei zurückgegeben. Wenn die App das Format nicht unterstützt, wird die Datei in ein älteres Format (z. B. AVC) transcodiert oder aus dem Cache zurückgegeben, falls eine transcodierte Version verfügbar ist.
Transcodierte Dateien anfordern
Die Funktion zur Transcodierung in kompatibles Medienformat ist standardmäßig deaktiviert. Apps können transkodierte Assets mit den folgenden Optionen anfordern:
- Nicht unterstützte Formate in der Manifestdatei deklarieren Weitere Informationen finden Sie unter Funktionen in einer Ressource deklarieren und Funktionen im Code deklarieren.
- Unterstützte Formate mit dem App-Kompatibilitäts-Framework zur Laufzeit deaktivieren (Nutzer können dies auch für jede App in den Einstellungen deaktivieren).
- Eine Datei mit
MediaStoreöffnen und dabei explizit nicht unterstützte Formate mit deropenTypedAssetFileDescriptorAPI angeben.
Bei USB-Übertragungen (Gerät zu PC) ist die Transcodierung standardmäßig deaktiviert. Nutzer können sie jedoch auf dem Einstellungsbildschirm USB-Einstellungen aktivieren, indem sie den Schalter Videos in AVC konvertieren auf „Ein“ stellen (siehe Abbildung 3).
Abbildung 3: Ein-/Aus-Schalter zum Aktivieren der Medien-Transcodierung auf dem Bildschirm „USB-Einstellungen“.
Einschränkungen beim Anfordern transkodierter Dateien
Damit Transcodierungsanfragen Systemressourcen nicht über einen längeren Zeitraum blockieren, sind Apps, die Transcodierungssitzungen anfordern, auf Folgendes beschränkt:
- 10 aufeinanderfolgende Sitzungen
- eine Gesamtlaufzeit von drei Minuten
Wenn eine App alle diese Einschränkungen überschreitet, gibt das Framework den ursprünglichen Dateideskriptor zurück.
Geräteanforderungen
Damit die Funktion zur Transcodierung kompatibler Medien unterstützt wird, müssen Geräte die folgenden Anforderungen erfüllen:
- Auf dem Gerät ist die HEVC-Codierung standardmäßig in der nativen Kamera-App aktiviert.
- (Geräte, die HDR-zu-SDR-Transcodierung unterstützen) Gerät unterstützt HDR-Videoaufnahmen
Um die Geräteleistung für die Medientranscodierung zu optimieren, müssen die Leistung der Videohardware und die Lese-/Schreibzugriffsleistung des Speichers optimiert werden. Wenn Media-Codecs mit der Priorität 1 konfiguriert sind, müssen sie mit dem höchstmöglichen Durchsatz arbeiten. Wir empfehlen, dass die Transcodierungsleistung mindestens 200 fps erreicht. Wenn Sie die Hardwareleistung testen möchten, führen Sie den Media Transcoder-Benchmark unter frameworks/av/media/libmediatranscoding/transcoder/benchmark aus.
Validierung
Führen Sie die folgenden CTS-Tests aus, um die Funktion für die kompatible Media-Transcodierung zu validieren:
android.media.mediatranscoding.ctsandroid.mediaprovidertranscode.cts
Globale Medien-Transcodierung aktivieren
Wenn Sie das Media Transcoding Framework oder das App-Verhalten mit Transcodierung testen möchten, können Sie die Funktion „Transcodierung in kompatibles Medienformat“ global aktivieren oder deaktivieren. Stelle auf der Seite mit den Entwickleroptionen Einstellungen > System > Entwickler > Media-Transcodierung den Schalter Standardeinstellungen für die Transcodierung überschreiben auf Ein und dann den Schalter Transcodierung aktivieren auf Ein oder Aus. Wenn diese Einstellung aktiviert ist, kann die Media-Transcodierung im Hintergrund für andere Apps als die von dir entwickelte App erfolgen.
Transcodierungsstatus prüfen
Während des Tests können Sie den folgenden ADB-Shell-Befehl verwenden, um den Transcodierungsstatus zu prüfen, einschließlich aktueller und vergangener Transcodierungssitzungen:
adb shell dumpsys media.transcodingLimit für die Videolänge erhöhen
Zu Testzwecken können Sie die Beschränkung der Videolänge von einer Minute für die Transcodierung mit dem folgenden Befehl aufheben. Nach dem Ausführen dieses Befehls ist möglicherweise ein Neustart erforderlich.
adb shell device_config put storage_native_boot transcode_max_duration_ms <LARGE_NUMBER_IN_MS>AOSP-Quellcode und ‑Referenzen
Im Folgenden finden Sie AOSP-Quellcode, der sich auf die Transcodierung in kompatibles Medienformat bezieht.
Transcoding System API (wird nur von MediaProvider verwendet)
ApplicationMediaCapabilities API
frameworks/base/apex/media/framework/java/android/media/ApplicationMediaCapabilities.javaMediaTranscoding Service
frameworks/av/services/mediatranscoding/frameworks/av/media/libmediatranscoding/
Native MediaTranscoder
frameworks/av/media/libmediatranscoding/transcoder
HDR-Beispiel-Plug-in für MediaTranscoder
MediaProvider-Code für das Abfangen von Dateien und die Transcodierung
MediaTranscoder-Benchmark
frameworks/av/media/libmediatranscoding/transcoder/benchmark
CTS-Tests
cts/tests/tests/mediatranscoding/
HDR-zu-SDR-Codierung
Um die HDR-zu-SDR-Codierung zu unterstützen, können Gerätehersteller das AOSP-Beispiel-Codec 2.0-Filter-Plug-in verwenden, das sich unter /platform/frameworks/av/media/codec2/hidl/plugin/ befindet.
In diesem Abschnitt wird beschrieben, wie das Filter-Plug-in funktioniert, wie Sie es implementieren und wie Sie es testen.
Wenn ein Gerät kein Plug-in enthält, das die HDR-zu-SDR-Codierung unterstützt, erhält eine App, die auf ein HDR-Video zugreift, den ursprünglichen Dateideskriptor, unabhängig von den im Manifest deklarierten Media-Funktionen der App.
Funktionsweise
In diesem Abschnitt wird das allgemeine Verhalten des Codec 2.0-Filter-Plug-ins beschrieben.
Hintergrund
Android bietet eine Implementierung der Anpassungsschicht zwischen der Codec 2.0-Schnittstelle und der android.hardware.media.c2-HAL-Schnittstelle unter android::hardware::media::c2. Für Filter-Plug-ins enthält AOSP einen Wrapper-Mechanismus, der Decoder zusammen mit Filter-Plug-ins umschließt.
MediaCodec
erkennt diese umschlossenen Komponenten als Decoder mit Filterfunktionen.
Übersicht
Die FilterWrapper-Klasse verwendet Anbieter-Codecs und gibt umschlossene Codecs an die media.c2-Anpassungsebene zurück. Die Klasse FilterWrapper lädt libc2filterplugin.so über die FilterWrapper::Plugin API und erfasst verfügbare Filter aus dem Plug-in. Bei der Erstellung instanziiert FilterWrapper alle verfügbaren Filter. Nur Filter, die den Puffer ändern, werden beim Start ausgeführt.
Abbildung 4: Architektur von Filter-Plug-ins
Filterschnittstelle für Plug-ins
Die Schnittstelle
FilterPlugin.h> definiert die folgenden APIs zum Bereitstellen der Filter:
std::shared_ptr<C2ComponentStore>getComponentStore()Gibt ein
C2ComponentStore-Objekt mit Filtern zurück. Dies ist unabhängig davon, was die Codec 2.0-Implementierung des Anbieters bereitstellt. Normalerweise enthält dieser Speicher nur die Filter, die von der KlasseFilterWrapperverwendet werden.bool describe(C2String name, Descriptor *desc)Beschreibt die Filter zusätzlich zu den Informationen unter
C2ComponentStore. Die folgenden Beschreibungen sind definiert:controlParam: Parameter, die das Verhalten der Filter steuern. Für einen HDR-zu-SDR-Tone-Mapper ist der Steuerparameter beispielsweise die Zielübertragungsfunktion.affectedParams: Parameter, die von den Filtervorgängen betroffen sind. Beim HDR-zu-SDR-Tone-Mapper sind beispielsweise die Farbparameter betroffen.
bool isFilteringEnabled(const std::shared_ptr<C2ComponentInterface> &intf)Gibt
truezurück, wenn die Filterkomponente den Puffer ändert. Der Tone-Mapping-Filter gibt beispielsweisetruezurück, wenn die Ziel-Transferfunktion SDR und die Eingabe-Transferfunktion HDR (HLG oder PQ) ist.
FilterWrapper-Details
In diesem Abschnitt werden Details zur Klasse FilterWrapper beschrieben.
Erstellung
Die umschlossene Komponente instanziiert den zugrunde liegenden Decoder und alle definierten Filter bei der Erstellung.
Abfrage und Konfiguration
Die umschlossene Komponente trennt eingehende Parameter gemäß der Filterbeschreibung von Anfragen oder Konfigurationsanfragen. Die Konfiguration des Filtersteuerungsparameters wird beispielsweise an den entsprechenden Filter weitergeleitet und die betroffenen Parameter aus den Filtern sind in den Anfragen vorhanden (anstatt aus dem Decoder mit nicht betroffenen Parametern gelesen zu werden).
Abbildung 5: Abfrage und Konfiguration.
Starten
Zu Beginn startet die umschlossene Komponente den Decoder und alle Filter, die die Puffer ändern. Wenn kein Filter aktiviert ist, startet die umschlossene Komponente den Decoder und die Pass-Through-Puffer und sendet Befehle an den Decoder selbst.
Pufferverwaltung
Abbildung 6. Pufferverwaltung
Gepufferte Daten, die in die Warteschlange des umschlossenen Decoders gestellt werden, werden an den zugrunde liegenden Decoder weitergeleitet. Die umschlossene Komponente ruft den Ausgabepuffer vom Decoder über einen onWorkDone_nb()-Callback ab und stellt ihn dann in die Warteschlange der Filter. Der endgültige Ausgabepuffer des letzten Filters wird an den Client gemeldet.
Damit diese Pufferverarbeitung funktioniert, muss die umschlossene Komponente C2PortBlockPoolsTuning für den letzten Filter konfigurieren, damit die Framework-Ausgabepuffer aus dem erwarteten Blockpool stammen.
Stoppen, zurücksetzen und freigeben
Beim Stoppen beendet die umschlossene Komponente den Decoder und alle aktivierten Filter, die gestartet wurden. Beim Zurücksetzen und Freigeben werden alle Komponenten zurückgesetzt oder freigegeben, unabhängig davon, ob sie aktiviert sind oder nicht.
Beispielfilter-Plug-in implementieren
So aktivieren Sie das Plug-in:
- Implementieren Sie die
FilterPlugin-Schnittstelle in einer Bibliothek und legen Sie sie unter/vendor/lib[64]/libc2filterplugin.so.ab. - Fügen Sie bei Bedarf zusätzliche Berechtigungen für
mediacodec.tehinzu. - Aktualisieren Sie die Anpassungsebene auf Android 12 und erstellen Sie den
media.c2-Dienst neu.
Plug-in testen
So testen Sie das Beispiel-Plug-in:
- Erstelle das Gerät neu und flashe es.
Erstellen Sie das Beispiel-Plug-in mit dem folgenden Befehl:
m sample-codec2-filter-pluginBringen Sie das Gerät wieder an der Halterung an und benennen Sie das Anbieter-Plug-in so um, dass es vom Codec-Dienst erkannt wird.
adb root adb remount adb reboot adb wait-for-device adb root adb remount adb push /out/target/<...>/lib64/sample-codec2-filter-plugin.so \ /vendor/lib64/libc2filterplugin.so adb push /out/target/<...>/lib/sample-codec2-filter-plugin.so \ /vendor/lib/libc2filterplugin.so adb reboot