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 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. Para obtener más información sobre cómo declarar capacidades 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ódecs 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 complemento de proveedor conectado a las instancias de 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 contenido multimedia integrado en el dispositivo que genera la app de cámara nativa del OEM y que se almacena en la carpeta DCIM/Camera/
del 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 acceso 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 apps a través de APIs de ruta de acceso directa, incluido Java y código nativo
- Acceso de apps a través del framework de acceso al 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
Se omitió la transcodificación:
- 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 rechazan las rutas de acceso fuera del directorio DCIM/
.
Es posible que debas agregar esas rutas de acceso para cumplir con los requisitos del operador 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:
<string-array name="config_supported_transcoding_relative_paths" translatable="false">
<item>DCIM/JCF/</item>
</string-array>
Para verificar las rutas de acceso 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 de contenido multimedia.
La arquitectura de transcodificación de contenido multimedia consta de los siguientes componentes:
- API del sistema MediaTranscodingManager: Es la interfaz que permite que el cliente se comunique con el servicio 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 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 de contenido 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 archivos en el espacio del usuario y controle el acceso a los archivos según la política para permitir, denegar o ocultar 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:
- Declarar formatos no compatibles 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 habilita la transcodificación para las apps que no actualizaron 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 framework de compatibilidad de apps en 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
mientras especificas de forma explícita los formatos que no se admiten con la API deopenTypedAssetFileDescriptor
.
En el caso de las transferencias por USB (dispositivo a PC), la transcodificación está inhabilitada de forma predeterminada, pero los usuarios pueden 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 transcodificación de contenido multimedia en la pantalla de preferencias de 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.
- (Dispositivos compatibles con la transcodificación de HDR a SDR) El dispositivo admite la captura de video HDR
Para garantizar el rendimiento del dispositivo para la transcodificación de contenido multimedia, se debe optimizar el rendimiento del acceso de lectura y escritura del hardware de video y el 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 la comparativa 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 de forma 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 el botón de activación Anular valores predeterminados de transcodificación y, luego, activa o desactiva el botón de activación Habilitar transcodificación. Si este parámetro de configuración está habilitado, es posible que la transcodificación de contenido multimedia se realice en segundo plano para apps que no sean la que estás desarrollando.
Cómo verificar el estado de 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 de transcodificación actuales y anteriores:
adb shell dumpsys media.transcoding
Extensión de 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 del sistema de transcodificación (solo la usa MediaProvider)
API de ApplicationMediaCapabilities
frameworks/base/apex/media/framework/java/android/media/ApplicationMediaCapabilities.java
Servicio de MediaTranscoding
frameworks/av/services/mediatranscoding/
frameworks/av/media/libmediatranscoding/
Native MediaTranscoder
frameworks/av/media/libmediatranscoding/transcoder
Complemento de muestra de HDR para MediaTranscoder
Código de intercepción y transcodificación de archivos de MediaProvider
Comparativa de MediaTranscoder
frameworks/av/media/libmediatranscoding/transcoder/benchmark
Pruebas de 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 que admita la codificación de HDR a SDR, una app que accede a un video HDR obtiene el descriptor de archivo original, independientemente de las capacidades 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.
Información general
Android proporciona una implementación de capa de adaptación entre la interfaz de Codec 2.0 y la interfaz de 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 se inician los filtros que alteran el búfer al principio.
Figura 4: Arquitectura del complemento de filtro.
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 objetivo.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 del decodificador que tiene parámetros no afectados).
Figura 5: Consulta y configuración.
Iniciar
Al principio, el componente unido inicia el decodificador y todos los filtros que modifican los búferes. Si no se habilita ningún filtro, el componente unido inicia el decodificador y los búferes de transferencia, y envía comandos al decodificador.
Manejo de búferes
Figura 6: Manejo de búferes.
Los búferes en cola para el 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 de búfer funcione, el componente unido debe configurar C2PortBlockPoolsTuning
en el último filtro para que los búferes de salida del framework se tomen 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. Durante el restablecimiento y la liberación, todos los componentes se restablecen o liberan, independientemente de 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.
. - Agrega permisos adicionales a
mediacodec.te
si es necesario. - 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 ejemplo 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