Google se compromete a impulsar la igualdad racial para las comunidades afrodescendientes. Obtén información al respecto.

Textura de superficie

SurfaceTexture es una combinación de una superficie y una textura OpenGL ES (GLES) . SurfaceTexture instancias de SurfaceTexture se utilizan para proporcionar superficies que dan salida a texturas GLES.

SurfaceTexture contiene una instancia de BufferQueue para la cual las aplicaciones son el consumidor. La devolución de llamada onFrameAvailable() notifica a las aplicaciones cuando el productor onFrameAvailable() cola un nuevo búfer. Luego, las aplicaciones llaman a updateTexImage() , que libera el búfer previamente almacenado, adquiere el nuevo búfer de la cola y realiza llamadas EGL para que el búfer esté disponible para GLES como una textura externa.

Texturas GLES externas

Las texturas GLES externas ( GL_TEXTURE_EXTERNAL_OES ) difieren de las texturas GLES tradicionales ( GL_TEXTURE_2D ) de las siguientes maneras:

  • Las texturas externas representan polígonos texturizados directamente a partir de los datos recibidos de BufferQueue .
  • Los renderizadores de texturas externos se configuran de forma diferente a los renderizadores de texturas GLES tradicionales.
  • Las texturas externas no pueden realizar todas las actividades de textura GLES tradicionales.

El principal beneficio de las texturas externas es su capacidad para renderizar directamente desde los datos de BufferQueue . SurfaceTexture instancias de SurfaceTexture establecen los indicadores de uso del consumidor en GRALLOC_USAGE_HW_TEXTURE cuando crea instancias de BufferQueue para texturas externas para garantizar que los datos en el búfer sean reconocibles por GLES.

Debido a que SurfaceTexture instancias de SurfaceTexture interactúan con un contexto EGL, una aplicación solo puede llamar a sus métodos mientras el contexto EGL que posee la textura está actual en el hilo de llamada. Para obtener más información, consulte la documentación de la clase SurfaceTexture .

Marcas de tiempo y transformaciones

SurfaceTexture instancias de SurfaceTexture incluyen el método getTimeStamp() , que recupera una marca de tiempo, y el método getTransformMatrix() , que recupera una matriz de transformación. Llamar a updateTexImage() establece tanto la marca de tiempo como la matriz de transformación. Cada búfer que pasa BufferQueue incluye parámetros de transformación y una marca de tiempo.

Los parámetros de transformación son útiles para la eficiencia. En algunos casos, los datos de origen pueden tener una orientación incorrecta para el consumidor. En lugar de rotar los datos antes de enviarlos al consumidor, envíe los datos en su orientación con una transformación que los corrija. La matriz de transformación se puede fusionar con otras transformaciones cuando se utilizan los datos, minimizando la sobrecarga.

La marca de tiempo es útil para fuentes de búfer que dependen del tiempo. Por ejemplo, cuando setPreviewTexture() conecta la interfaz del productor a la salida de la cámara, los fotogramas de la cámara se pueden usar para crear un video. Cada fotograma debe tener una marca de tiempo de presentación desde el momento en que se capturó el fotograma, no desde el momento en que la aplicación lo recibió. El código de la cámara establece la marca de tiempo proporcionada con el búfer, lo que da como resultado una serie de marcas de tiempo más coherente.

Estudio de caso: captura continua de Grafika

La captura continua de Grafika implica grabar fotogramas de la cámara de un dispositivo y mostrar esos fotogramas en la pantalla. Para grabar fotogramas, cree una superficie con el método createInputSurface() la clase MediaCodec y pase la superficie a la cámara. Para mostrar marcos, cree una instancia de SurfaceView y pase la superficie a setPreviewDisplay() . Tenga en cuenta que grabar fotogramas y mostrarlos al mismo tiempo es un proceso más complicado.

La actividad de captura continua muestra el video de la cámara mientras se graba el video. En este caso, el video codificado se escribe en un búfer circular en la memoria que se puede guardar en el disco en cualquier momento.

Este flujo implica tres colas de búfer:

  • App : la aplicación utiliza una instancia de SurfaceTexture para recibir fotogramas de la cámara y convertirlos en una textura GLES externa.
  • SurfaceFlinger : la aplicación declara una instancia de SurfaceView para mostrar los marcos.
  • MediaServer : configure un codificador MediaCodec con una superficie de entrada para crear el video.

En la siguiente figura, las flechas indican la propagación de datos desde la cámara. BufferQueue instancias de BufferQueue están en color (los productores son verde azulado, los consumidores son verdes).

Actividad de captura continua de Grafika

Figura 1. Actividad de captura continua de Grafika

El video codificado H.264 va a un búfer circular en la RAM en el proceso de la aplicación. Cuando un usuario presiona el botón de captura, la clase MediaMuxer escribe el video codificado en un archivo MP4 en el disco.

Todas BufferQueue instancias de BufferQueue se manejan con un único contexto EGL en la aplicación, mientras que las operaciones GLES se realizan en el subproceso de la interfaz de usuario. El manejo de datos codificados (administrar un búfer circular y escribirlo en el disco) se realiza en un hilo separado.

Cuando se usa la clase SurfaceView , la devolución de llamada surfaceCreated() crea las instancias EGLContext y EGLSurface para la pantalla y el codificador de video. Cuando llega un nuevo marco, SurfaceTexture realiza cuatro actividades:
  1. Adquiere el marco.
  2. Hace que el marco esté disponible como textura GLES.
  3. Renderiza el marco con comandos GLES.
  4. Reenvía la transformación y la marca de tiempo para cada instancia de EGLSurface .

Luego, el subproceso del codificador extrae la salida codificada de MediaCodec y la almacena en la memoria.

Reproducción de video de textura segura

Android admite el posprocesamiento por GPU de contenido de video protegido. Esto permite que las aplicaciones usen la GPU para efectos de video complejos y no lineales (como deformaciones), mapeando contenido de video protegido en texturas para usar en escenas de gráficos generales (por ejemplo, usando GLES) y realidad virtual (VR).

Reproducción de video de textura segura

Figura 2. Reproducción de video de textura segura

El soporte se habilita usando las siguientes dos extensiones:

  • Extensión EGL : ( EGL_EXT_protected_content ) Permite la creación de contextos y superficies GL protegidos, que pueden operar en contenido protegido.
  • Extensión GLES - ( GL_EXT_protected_textures ) Habilita el etiquetado de texturas como protegidas para que puedan usarse como adjuntos de textura de framebuffer.

Android permite que SurfaceTexture y ACodec ( libstagefright.so ) envíen contenido protegido incluso si la superficie de la ventana no hace cola en SurfaceFlinger y proporciona una superficie de video protegida para usar dentro de un contexto protegido. Esto se hace estableciendo el bit de consumidor protegido ( GRALLOC_USAGE_PROTECTED ) en superficies creadas en un contexto protegido (verificado por ACodec).

La reproducción de video de textura segura sienta las bases para una implementación sólida de DRM en el entorno OpenGL ES. Sin una implementación sólida de DRM, como Widevine Level 1, muchos proveedores de contenido no permiten la representación de su contenido de alto valor en el entorno OpenGL ES, lo que evita casos de uso importantes de realidad virtual, como ver contenido protegido por DRM en realidad virtual.

AOSP incluye un código de marco para la reproducción segura de videos de texturas. El soporte del controlador depende de los OEM. Los implementadores de dispositivos deben implementar las EGL_EXT_protected_content y GL_EXT_protected_textures extensions . Cuando utilice su propia biblioteca de códecs (para reemplazar libstagefright ), tenga en cuenta los cambios en /frameworks/av/media/libstagefright/SurfaceUtils.cpp que permiten que los búferes marcados con GRALLOC_USAGE_PROTECTED se envíen a ANativeWindow (incluso si ANativeWindow no se pone en cola directamente al compositor de ventana) siempre que los bits de uso del consumidor contengan GRALLOC_USAGE_PROTECTED . Para obtener documentación detallada sobre la implementación de las extensiones, consulte los registros de Khronos ( EGL_EXT_protected_content y GL_EXT_protected_textures ).