La transcodificación de contenido multimedia compatible, que se introdujo en Android 12, es una función que permite que los dispositivos usen formatos multimedia más modernos y eficientes en cuanto al almacenamiento para la captura de video, como HEVC, sin perder la compatibilidad con las apps. Con esta función, los fabricantes de dispositivos pueden usar HEVC en lugar de AVC de forma predeterminada para mejorar la calidad de video y, al mismo tiempo, reducir los requisitos de almacenamiento y ancho de banda. En el caso de los dispositivos con transcodificación de contenido multimedia compatible habilitada, Android puede convertir automáticamente videos (de hasta un minuto de duración) grabados en formatos como HEVC o HDR cuando una app que no admite el formato los abre. Esto permite que las apps funcionen incluso cuando los videos se capturan en formatos más nuevos en el dispositivo.
La función de transcodificación de contenido multimedia compatible está desactivada de forma predeterminada. Para solicitar la transcodificación de contenido multimedia, las apps deben declarar sus capacidades de contenido multimedia. Si quieres obtener más información para declarar capacidades de contenido multimedia, consulta Transcodificación de contenido multimedia compatible en el sitio para desarrolladores de Android.
Cómo funciona
La función de transcodificación de contenido multimedia compatible consta de dos partes principales:
- Servicios de transcodificación en el framework multimedia: Estos servicios convierten archivos de un formato a otro con hardware para obtener conversiones de alta calidad y baja latencia. Esto incluye la API de transcodificación, el servicio de transcodificación, un complemento de OEM para filtros personalizados y hardware. Para obtener más detalles, consulta Descripción general de la arquitectura.
- Función de transcodificación de contenido multimedia compatible en proveedores de contenido multimedia: Este componente que se encuentra en los proveedores de contenido multimedia intercepta las apps que acceden a los archivos multimedia y entrega el archivo original o uno transcodificado según las capacidades declaradas de la app. Si una app admite el formato del archivo multimedia, no se requiere un manejo especial. Si una app no admite el formato, el framework lo convierte a un formato anterior, como AVC, cuando la app accede al archivo.
En la Figura 1, se muestra una descripción general del proceso de transcodificación de contenido multimedia.
Figura 1: Descripción general de la transcodificación de contenido multimedia compatible
Formatos compatibles
La función de transcodificación de contenido multimedia compatible admite las siguientes conversiones de formato:
- HEVC (8 bits) a AVC: Las conversiones de códec se realizan a través de la conexión de un decodificador de Mediacodec y un codificador de mediacode.
- HDR10+ (10 bits) a AVC (SDR): Las conversiones de HDR a SDR se realizan con instancias de mediacodec y un hook de complemento del proveedor en las instancias del decodificador. Para obtener más información, consulta Codificación de HDR a SDR.
Fuentes de contenido compatibles
La función de transcodificación de contenido multimedia compatible admite el contenido multimedia integrado en el dispositivo generado por la app nativa de cámara del OEM que se almacena en la carpeta DCIM/Camera/
en el volumen externo principal. La función no admite contenido multimedia en el almacenamiento secundario.
No se admite el contenido que se pasa a los dispositivos por correo electrónico o tarjetas SD.
Las apps acceden a los archivos en función de varias rutas de acceso. A continuación, se describen las rutas de archivo en las que se habilita o se omite la transcodificación:
Transcodificación habilitada:
- Acceso de apps a través de las APIs de MediaStore
- Acceso de la app a través de APIs de ruta de archivo directa, incluidos Java y código nativo
- Acceso de apps a través del framework de acceso a almacenamiento (SAF)
- Acceso de apps a través de intents de la hoja para compartir del SO (solo URI de MediaStore)
- Transferencia de archivos MTP/PTP del teléfono a la PC
Transcodificación omitido:
- Cómo transferir archivos de un dispositivo expulsando la tarjeta SD
- Transferir archivos de un dispositivo a otro con opciones como Compartir con Nearby o la transferencia por Bluetooth
Agrega rutas de archivo personalizadas para la transcodificación
De forma opcional, los fabricantes de dispositivos pueden agregar rutas de acceso para la transcodificación de contenido multimedia en el directorio DCIM/
. Se rechaza cualquier ruta fuera del directorio DCIM/
.
Es posible que debas agregar esas rutas de acceso para cumplir con los requisitos de las empresas de transporte o las reglamentaciones locales.
Para agregar una ruta de acceso de archivo, usa la ruta de acceso de transcodificación de la superposición de recursos del entorno de ejecución (RRO), config_supported_transcoding_relative_paths
. El siguiente es un ejemplo de cómo agregar una ruta de acceso al archivo:
<string-array name="config_supported_transcoding_relative_paths" translatable="false">
<item>DCIM/JCF/</item>
</string-array>
Para verificar las rutas de archivo configuradas, usa lo siguiente:
adb shell dumpsys activity provider com.google.android.providers.media.module/com.android.providers.media.MediaProvider | head -n 20
Descripción general de la arquitectura
En esta sección, se describe la arquitectura de la función de transcodificación de contenido multimedia.
Figura 2: Arquitectura de transcodificación multimedia.
La arquitectura de transcodificación de contenido multimedia consta de los siguientes componentes:
- API del sistema MediaTranscodingManager: Es la interfaz que permite al cliente comunicarse con el servicio de MediaTranscoding. El módulo MediaProvider usa esta API.
- MediaTranscodingService: Es un servicio nativo que administra las conexiones de los clientes, programa solicitudes de transcodificación y administra la contabilización de
TranscodingSessions
. - MediaTranscoder: Es una biblioteca nativa que realiza la transcodificación. Esta biblioteca se compila sobre el NDK del framework de contenido multimedia para ser compatible con los módulos.
La función de transcodificación de contenido multimedia compatible registra las métricas de transcodificación en el servicio y en el transcodificador multimedia. El código del cliente y del servidor se encuentra en el módulo MediaProvider para permitir correcciones de errores y actualizaciones oportunas.
Acceso a archivos
La transcodificación de contenido multimedia compatible se compila sobre el sistema de archivos en el espacio del usuario (FUSE), que se usa para el almacenamiento específico. FUSE permite que el módulo MediaProvider examine las operaciones de archivo en el espacio del usuario y restrinja el acceso a los archivos en función de la política para permitir, ocultar o denegar el acceso.
Cuando una app intenta acceder a un archivo, el daemon de FUSE intercepta el acceso de lectura del archivo desde la app. Si la app admite un formato más reciente (como HEVC), se muestra el archivo original. Si la app no admite el formato, el archivo se transcodifica a un formato anterior (como AVC) o se muestra desde la caché si hay una versión transcodificada disponible.
Cómo solicitar archivos transcodificados
La función de transcodificación de contenido multimedia compatible está inhabilitada de forma predeterminada, lo que significa que, si el dispositivo admite HEVC, Android no transcodifica archivos, a menos que una app lo especifique en un archivo de manifiesto o en la lista de transcodificación forzada.
Las apps pueden solicitar recursos transcodificados con las siguientes opciones:
- Declara formatos no admitidos en el archivo de manifiesto. Para obtener más información, consulta Cómo declarar capacidades en un recurso y Cómo declarar capacidades en el código.
- Agrega apps a la lista de transcodificación forzada que se incluye en el módulo MediaProvider. Esto permite la transcodificación para las apps que no hayan actualizado su archivo de manifiesto. Una vez que una app actualiza su archivo de manifiesto con formatos no compatibles, se debe quitar de la lista de transcodificación forzada. Los fabricantes de dispositivos pueden nominar sus apps para que se agreguen o quiten de la lista de transcodificación forzada. Para ello, deben enviar un parche o informar un error. El equipo de Android revisa la lista periódicamente y puede quitar apps de ella.
- Inhabilita los formatos compatibles con el marco de compatibilidad de apps durante el tiempo de ejecución (los usuarios también pueden inhabilitar esta opción para cada app en Configuración).
- Abre un archivo con
MediaStore
y especifica de forma explícita los formatos no compatibles con la API deopenTypedAssetFileDescriptor
.
Para las transferencias USB (de dispositivo a PC), la transcodificación está inhabilitada de forma predeterminada, pero los usuarios pueden elegir habilitarla con el botón de activación Convertir videos a AVC en la pantalla de configuración Preferencias de USB, como se muestra en la Figura 3.
Figura 3: Activa o desactiva la opción para habilitar la transcodificación de contenido multimedia en la pantalla de preferencias USB.
Restricciones para solicitar archivos transcodificados
Para evitar que las solicitudes de transcodificación bloqueen los recursos del sistema durante períodos prolongados, las apps que solicitan sesiones de transcodificación se limitan a lo siguiente:
- 10 sesiones consecutivas
- un tiempo de ejecución total de tres minutos
Si una app supera todas estas restricciones, el framework muestra el descriptor de archivo original.
Requisitos del dispositivo
Para admitir la función de transcodificación de contenido multimedia compatible, los dispositivos deben cumplir con los siguientes requisitos:
- El dispositivo tiene la codificación HEVC habilitada de forma predeterminada en la app de cámara nativa.
- El dispositivo admite la captura de video HDR (dispositivos compatibles con la transcodificación HDR a SDR).
Para garantizar el rendimiento del dispositivo para la transcodificación de contenido multimedia, se deben optimizar el hardware de video y el rendimiento del acceso de lectura y escritura de almacenamiento. Cuando los códecs multimedia se configuran con una prioridad igual a 1
, los códecs deben operar con la capacidad de procesamiento más alta posible. Recomendamos que el rendimiento de la transcodificación alcance un mínimo de 200 FPS. Para probar el rendimiento del hardware, ejecuta las comparativas del transcodificador de contenido multimedia en frameworks/av/media/libmediatranscoding/transcoder/benchmark
.
Validación
Para validar la función de transcodificación de contenido multimedia compatible, ejecuta las siguientes pruebas de CTS:
android.media.mediatranscoding.cts
android.mediaprovidertranscode.cts
Habilita la transcodificación de contenido multimedia a nivel global
Para probar el comportamiento del marco de transcodificación de contenido multimedia o de la app con transcodificación, puedes habilitar o inhabilitar la función de transcodificación de contenido multimedia compatible de forma global. En la página de opciones para desarrolladores Configuración > Sistema > Desarrollador > Transcodificación de contenido multimedia, activa la opción Anular los valores predeterminados de transcodificación y, luego, activa o desactiva esta opción. Si se habilita esta configuración, es posible que se realice la transcodificación de contenido multimedia en segundo plano para apps que no sean la que estás desarrollando.
Verifica el estado de la transcodificación
Durante las pruebas, puedes usar el siguiente comando de shell de ADB para verificar el estado de la transcodificación, incluidas las sesiones actuales y anteriores:
adb shell dumpsys media.transcoding
Extender la limitación de duración de los videos
Para realizar pruebas, puedes extender la limitación de duración de un minuto de los videos para la transcodificación con el siguiente comando. Es posible que debas reiniciar el dispositivo después de ejecutar este comando.
adb shell device_config put storage_native_boot transcode_max_duration_ms <LARGE_NUMBER_IN_MS>
Fuente y referencias de AOSP
A continuación, se muestra el código fuente de AOSP relacionado con la transcodificación de contenido multimedia compatible.
API de Transcoding System (solo usada por MediaProvider)
API de ApplicationMediaCapabilities
frameworks/base/apex/media/framework/java/android/media/ApplicationMediaCapabilities.java
Servicio de transcodificación de medios
frameworks/av/services/mediatranscoding/
frameworks/av/media/libmediatranscoding/
Native MediaTranscoder
frameworks/av/media/libmediatranscoding/transcoder
Complemento de muestra HDR para MediaTranscoder
Código de intercepción y transcodificación de archivos MediaProvider
Comparativas de MediaTranscoder
frameworks/av/media/libmediatranscoding/transcoder/benchmark
Pruebas del CTS
cts/tests/tests/mediatranscoding/
Codificación de HDR a SDR
Para admitir la codificación de HDR a SDR, los fabricantes de dispositivos pueden usar el complemento de filtro de muestra de Codec 2.0 de AOSP que se encuentra en /platform/frameworks/av/media/codec2/hidl/plugin/
.
En esta sección, se describe cómo funciona el complemento de filtro, cómo implementarlo y cómo probarlo.
Si un dispositivo no incluye un complemento compatible con la codificación HDR a SDR, una app que acceda a un video HDR obtendrá el descriptor de archivos original, independientemente de las capacidades de contenido multimedia de la app declaradas en el manifiesto.
Cómo funciona
En esta sección, se describe el comportamiento general del complemento de filtro Codec 2.0.
Segundo plano
Android proporciona una implementación de capa de adaptación entre la interfaz Códec 2.0 y la interfaz de la HAL de android.hardware.media.c2
en android::hardware::media::c2
. En el caso de los complementos de filtro, AOSP incluye un mecanismo de wrapper que une los decodificadores con los complementos de filtro.
MediaCodec
reconoce estos componentes unidos como decodificadores con funciones de filtrado.
Descripción general
La clase FilterWrapper
toma los códecs del proveedor y muestra los códecs unidos a la capa de adaptación media.c2
. La clase FilterWrapper
carga libc2filterplugin.so
a través de la API de FilterWrapper::Plugin
y registra los filtros disponibles del complemento. Cuando se crea, FilterWrapper
crea instancias de todos los filtros disponibles. Solo los filtros que alteran el búfer se inician al inicio.
Figura 1: Filtrar la arquitectura de complementos
Interfaz del complemento de filtro
La interfaz FilterPlugin.h
define las siguientes APIs para exponer los filtros:
std::shared_ptr<C2ComponentStore>getComponentStore()
Muestra un objeto
C2ComponentStore
que contiene filtros. Esto es independiente de lo que expone la implementación del códec 2.0 del proveedor. Por lo general, este almacén solo contiene los filtros que usa la claseFilterWrapper
.bool describe(C2String name, Descriptor *desc)
Describe los filtros, además de lo que está disponible en
C2ComponentStore
. Se definen las siguientes descripciones:controlParam
: Son parámetros que controlan el comportamiento de los filtros. Por ejemplo, para el asignador de tonos de HDR a SDR, el parámetro de control es la función de transferencia de destino.affectedParams
: Son los parámetros que se ven afectados por las operaciones de filtrado. Por ejemplo, para el asignador de tono de HDR a SDR, los parámetros afectados son los aspectos de color.
bool isFilteringEnabled(const std::shared_ptr<C2ComponentInterface> &intf)
Muestra
true
si el componente del filtro altera el búfer. Por ejemplo, el filtro de asignación de tonos muestratrue
si la función de transferencia objetivo es SDR y la función de transferencia de entrada es HDR (HLG o PQ).
Detalles de FilterWrapper
En la sección, se describen los detalles de la clase FilterWrapper
.
Creación
El componente unido crea una instancia del decodificador subyacente y todos los filtros definidos durante la creación.
Consulta y configuración
El componente unido separa los parámetros entrantes de las consultas o solicitudes de configuración según la descripción del filtro. Por ejemplo, la configuración del parámetro de control de filtro se enruta al filtro correspondiente, y los parámetros afectados de los filtros están presentes en las consultas (en lugar de leer desde el decodificador que no tiene parámetros afectados).
Figura 2: Consulta y configuración.
Iniciar
Al principio, el componente unido inicia el decodificador y todos los filtros que modifican los búferes. Si no hay ningún filtro habilitado, el componente unido inicia el decodificador, los búferes de transferencia y envía comandos al decodificador.
Manejo de búferes
Figura 3: Manejo de búferes.
Los búferes en cola al decodificador unido van al decodificador subyacente. El componente unido toma el búfer de salida del decodificador a través de una devolución de llamada de onWorkDone_nb()
y, luego, lo pone en cola para los filtros. El búfer de salida final del último filtro se informa al cliente.
Para que este manejo del búfer funcione, el componente unido debe configurar C2PortBlockPoolsTuning
en el último filtro, de modo que los búferes de salida del framework del grupo de bloques esperado
Detener, restablecer y liberar
Cuando se detiene, el componente unido detiene el decodificador y todos los filtros habilitados que se iniciaron. En el restablecimiento y la liberación, todos los componentes se restablecen o liberan, sin importar si están habilitados o no.
Implementa el complemento de filtro de muestra
Para habilitar el complemento, haz lo siguiente:
- Implementa la interfaz
FilterPlugin
en una biblioteca y colócala en/vendor/lib[64]/libc2filterplugin.so.
. - Si es necesario, agrega permisos adicionales a
mediacodec.te
. - Actualiza la capa de adaptación a Android 12 y vuelve a compilar el servicio
media.c2
.
Prueba el complemento
Para probar el complemento de muestra, haz lo siguiente:
- Vuelve a compilar y escribe en el dispositivo.
Compila el complemento de muestra con el siguiente comando:
m sample-codec2-filter-plugin
Vuelve a activar el dispositivo y cambia el nombre del complemento del proveedor para que el servicio de códec lo reconozca.
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