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

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

media-transcoding-architecture

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

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.

Arquitectura del complemento de filtro

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 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 muestra true 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).

Consulta y configuración

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

Manejo del búfer

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:

  1. Implementa la interfaz FilterPlugin en una biblioteca y colócala 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 en el dispositivo.
  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ó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