¿Cuál es el mejor método para hacer marcos de video?

¿Cuál es la mejor opción para renderizar marcos de vídeo obtenidos de un decodificador incluido en mi aplicación (FFmpeg, etc.)?

Tendría naturalmente a elegir OpenGL como se menciona en Android Video Player utilizando NDK, OpenGL ES, y FFmpeg .

Pero en OpenGL en Android para la visualización de vídeo , un comentario señala que OpenGL no es el mejor método para renderizar vídeo.

¿Entonces que? ¿La biblioteca nativa de jnigraphics? ¿Y un SurfaceView no-GL?

Tenga en cuenta que me gustaría utilizar una API nativa para procesar los marcos, como OpenGL o jnigraphics. Pero el código Java para configurar un SurfaceView y tal está bien.

PS: MediaPlayer es irrelevante aquí, estoy hablando de la decodificación y la visualización de los marcos por mí mismo. No puedo confiar en los codecs Android predeterminados.

Voy a tratar de elaborar y consolidar las respuestas aquí basadas en mis propias experiencias.

Por qué openGL

Cuando la gente piensa en renderizar video con openGL, la mayoría está intentando explotar la GPU para hacer conversión de espacio de color y mezcla alfa.

Por ejemplo, convertir los marcos de video YV12 a RGB. Las conversiones de espacio de color como YV12 -> RGB requieren que se calcule el valor de cada píxel individualmente. Imagine para un marco de 1280 x 720 píxeles cuántas operaciones esto termina siendo.

Lo que acabo de describir es realmente lo que SIMD fue hecho para – realizar la misma operación en múltiples piezas de datos en paralelo. La GPU es un ajuste natural para la conversión del espacio de color.

Por qué! OpenGL

La desventaja es el proceso por el cual usted consigue datos de la textura en la GPU. Tenga en cuenta que para cada trama tiene que cargar los datos de textura en la memoria (operación de la CPU) y luego tiene que copiar estos datos de textura en la GPU (operación de la CPU). Es esta carga / copia que puede hacer usando openGL más lento que las alternativas.

Si estás reproduciendo videos de baja resolución entonces supongo que es posible que no veas la diferencia de velocidad, porque tu CPU no va a cerrar el cuello de botella. Sin embargo, si intenta con HD, más que probable que golpear este cuello de botella y notar un golpe de rendimiento significativo.

La forma en que este cuello de botella se ha trabajado tradicionalmente es mediante el uso de objetos de búfer de píxeles (asignación de memoria GPU para almacenar cargas de textura). Desafortunadamente GLES2 no tiene objetos del almacenador intermediario del pixel.

Otras opciones

Por las razones anteriores, muchos han optado por utilizar decodificación de software combinado con extensiones de CPU disponibles como NEON para conversión de espacio de color. Una implementación de YUV 2 RGB para NEON existe aquí . El medio por el que dibuja los marcos, SDL vs openGL no debería importar para RGB ya que está copiando el mismo número de píxeles en ambos casos.

Puede determinar si el dispositivo de destino admite mejoras de NEON ejecutando cat /proc/cpuinfo desde shell de adb y buscando NEON en la salida de características.

He ido por el camino FFmpeg / OpenGLES antes, y no es muy divertido.

Puede intentar portar ffplay.c desde el proyecto FFmpeg, que se ha hecho antes de usar un puerto Android de SDL. De esa manera no estás construyendo tu descodificador desde cero, y no tendrás que lidiar con las idiosincrasias de AudioTrack , que es una API de audio única para Android.

En cualquier caso, es una buena idea hacer el menor desarrollo de NDK posible y confiar en portar, ya que la experiencia de depuración de ndk-gdb es muy mala en este momento en mi opinión.

Dicho esto, creo que el rendimiento de OpenGLES es la menor de sus preocupaciones. Me pareció que el rendimiento estaba bien, aunque admito que sólo probado en algunos dispositivos. La decodificación en sí es bastante intensa, y no pude hacer un almacenamiento en búfer muy agresivo (desde la tarjeta SD) durante la reproducción del video.

En realidad he desplegado un sistema de reproductor de video personalizado y casi todo mi trabajo se realizó en el lado NDK. Estamos recibiendo video de cuadro completo 720P y superior incluyendo nuestro sistema de DRM personalizado. OpenGL no es su respuesta como en Android Pixbuffers no son compatibles, por lo que son bascially voladura de sus texturas cada marco y que los tornillos hasta el sistema de almacenamiento en caché OpenGLESs. Usted francamente necesidad de empujar los fotogramas de vídeo a través de la Native apoyado Bitmap en Froyo y superiores. Antes de Froyo su hosed. También escribí un montón de intrínsecas NEON para la conversión de color, reescalado, etc para aumentar el rendimiento. Puedo empujar 50-60 marcos a través de este modelo en vídeo de alta definición.

  • Android ffmpeg mala salida de video
  • YouTube Video no se reproduce en WebView - Android
  • Reproduce vídeos de Youtube en la vista de vídeo en android
  • Cómo implementar recorte de video en android como instagram o WhatsApp?
  • Envío de imágenes y videos al servidor en android
  • cómo encubrir las imágenes de vídeo en android
  • El elemento HTML5 <video> en Android no se reproduce
  • ¿Cómo puedo obtener la url correcta en el archivo de video de un video incrustado?
  • Codificación de vídeo para admitir varias pantallas
  • Android tira audio de vídeo
  • Rotación de vídeo en modo retrato
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.