Transcodificación de contenido multimedia compatible

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 que tengan habilitada la transcodificación de contenido multimedia compatible, Android puede convertir automáticamente videos (de hasta un minuto de duración) grabados en formatos como HEVC o HDR cuando los abre una app que no admite el formato. 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 marco de trabajo de medios: Estos servicios convierten archivos de un formato a otro mediante hardware para obtener conversiones de baja latencia y alta calidad. 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 con los proveedores de contenido multimedia: Este componente se encuentra en los proveedores de contenido multimedia intercepta las apps que acceden a archivos multimedia y entrega el archivo original o un archivo 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 convierte el archivo 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.

Proceso de transcodificación de contenido multimedia compatible

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 mediante instancias de Mediacodec y un hook de complemento de proveedor 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 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 transmite a dispositivos por correo electrónico o tarjetas SD.

Las apps acceden a los archivos en función de varias rutas de acceso a archivos. 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 a la app a través del framework de acceso al almacenamiento (SAF)
    • Acceso a la app mediante los intents de la hoja de uso compartido del SO (solo URI de MediaStore)
    • Transferencia de archivos MTP/PTP del teléfono a la PC
  • Transcodificación omitido:

    • Transferir un archivo de un dispositivo al expulsar la tarjeta SD
    • Transferir archivos de un dispositivo a otro por medio de opciones como Compartir con Nearby o Transferencia por Bluetooth

Agrega rutas de archivo personalizadas para la transcodificación

De manera opcional, los fabricantes de dispositivos pueden agregar rutas de archivo 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 a archivos para cumplir con los requisitos del proveedor o las reglamentaciones locales.

Para agregar una ruta de acceso al archivo, usa la superposición de recursos del entorno de ejecución (RRO) de la ruta de transcodificación, 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.

arquitectura-de-transcodificación-de-medios

Figura 2: Arquitectura de transcodificación multimedia.

La arquitectura de transcodificación de contenido multimedia consta de los siguientes componentes:

  • API del sistema MediaTranscodingManager: Interfaz que permite al cliente comunicarse con el servicio de MediaTranscoding El módulo MediaProvider usa esta API.
  • MediaTranscodingService: Servicio nativo que administra conexiones de clientes, programa solicitudes de transcodificación y administra la contabilidad de TranscodingSessions.
  • MediaTranscoder: Biblioteca nativa que realiza 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 servicio están en el módulo MediaProvider para permitir correcciones de errores y actualizaciones oportunas.

Acceso a archivos

La transcodificación de contenido multimedia compatible se basa en el sistema de archivos del 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 FUSE intercepta el acceso de lectura al 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 elementos 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 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, debe quitarse 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 esta.
  • 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 de openTypedAssetFileDescriptor.

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.

Botón de activación para habilitar la transcodificación de contenido multimedia

Figura 3: Activa o desactiva la opción para habilitar la transcodificación de contenido multimedia en la pantalla de preferencias USB.

Restricciones para la solicitud de 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 excede todas estas restricciones, el framework muestra el descriptor de archivos original.

Requisitos de los dispositivos

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 nativa de la cámara
  • 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 se configuran los códecs multimedia con una prioridad igual a 1, los códecs deben funcionar 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 framework de transcodificación de contenido multimedia o el comportamiento de la app con la transcodificación, puedes habilitar o inhabilitar la función compatible de transcodificación de contenido multimedia a nivel global. En la página de opciones para desarrolladores de 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.

Comprobar 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 la duración del video

Con fines de prueba, puedes extender la limitación de un minuto de duración del video para la transcodificación con el siguiente comando. Es posible que debas reiniciar 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 del AOSP

A continuación, se incluye código fuente de AOSP relacionado con la transcodificación de contenido multimedia compatible.

Codificación HDR a SDR

Para admitir la codificación HDR a SDR, los fabricantes de dispositivos pueden usar el complemento de filtro Codec 2.0 de muestra de AOSP ubicado 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.

Información general

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. Para los complementos de filtro, AOSP incluye un mecanismo de wrapper que une decodificadores con complementos de filtro. MediaCodec reconoce estos componentes unidos como decodificadores con funciones de filtrado.

Descripción general

La clase FilterWrapper toma códecs de proveedores y devuelve 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. Durante la creación, FilterWrapper crea una instancia de todos los filtros disponibles. Solo los filtros que alteran el búfer se inician al inicio.

Filtrar la arquitectura de complementos

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 clase FilterWrapper.

  • 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 tonos de HDR a SDR, los parámetros afectados son los aspectos del color.
  • bool isFilteringEnabled(const std::shared_ptr<C2ComponentInterface> &intf)

    Muestra true si el componente de filtro altera el búfer. Por ejemplo, el filtro de asignación de tonos muestra true si la función de transferencia de destino es SDR y la función de transferencia de entrada es HDR (HLG o PQ).

Detalles de FilterWrapper

En esta 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 en 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).

Consulta y configuración

Figura 2: Consulta y configuración.

Inicio

Al comienzo, el componente unido inicia el decodificador y todos los filtros que alteran 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 del búfer

Manejo del búfer

Figura 3: Manejo del búfer.

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 onWorkDone_nb() y, luego, lo pone en cola en 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. Durante el restablecimiento y el lanzamiento, 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:

  1. Implementa la interfaz FilterPlugin en una biblioteca y suéltala en /vendor/lib[64]/libc2filterplugin.so..
  2. Si es necesario, agrega permisos adicionales a mediacodec.te.
  3. 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:

  1. Vuelve a compilar y escribe el dispositivo en la memoria flash.
  2. Compila el complemento de muestra con el siguiente comando:

    m sample-codec2-filter-plugin
    
  3. Vuelve a activar el dispositivo y cambia el nombre del complemento del proveedor para que el servicio de códecs 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