¿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 .
- Reacciona el video Web de Android nativo
- Android VideoView: la vista de vídeo es mucho más oscura en una vista de diálogo
- No se reproduce el video de YouTube en WebView
- ¿Podemos volver a escribir la API de MediaCodec en C?
- Youtube Video en WebView no se carga
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.
- Android NDK. Cómo reproducir video.
- Envío de imágenes y videos al servidor en android
- Tasa de reproducción de vídeo variable en Android
- Cómo implementar el filtro de vídeo en Android como instagram
- ThumbnailUtils.createVideoThumbnail devuelve NULL al capturar un nuevo video
- Android: varias pistas de audio en un VideoView?
- SetPluginsEnabled no existe para WebView
- Envíe archivos grandes (de vídeo) desde Android a PHP Server
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.
- EXCEPCIÓN FATAL: main java.lang.RuntimeException: El contenido tiene vista con el atributo id 'android.R.id.list' que no es una clase ListView
- Recursos y Frameworks para el desarrollo móvil (iphone, android) usando HTML5