Native_window_api_connect devolvió un error: argumento no válido (-22)

Estoy escribiendo una aplicación de reproductor de video usando la API de MediaCodec. Tengo que mostrar la pantalla en blanco antes de decodificación de vídeo comenzó. Así que estoy usando código siguiente para mostrar la pantalla en blanco.

Canvas c=null; c = surfaceView.getHolder().lockCanvas(); c.drawColor(Color.BLACK); surfaceView.getHolder().unlockCanvasAndPost(c); 

Después de que comience la decodificación de vídeo. Pero en el momento de configurar

 videoDecoder.configure(format, surfaceView.getHolder().getSurface(), null, 0); 

Dando los siguientes errores

 02-03 03:52:37.542: E/MediaCodec(9655): native_window_api_connect returned an error: Invalid argument (-22) 02-03 03:52:37.542: E/Video Decoder Configuration(9655): java.lang.IllegalStateException 

Así que mi aplicación falla con ese error. Sin que el decodificador de código de pantalla en blanco está funcionando bien. como puedo resolver este problema?

Aquí está mi teoría, basada en una mirada rápida a través del código del marco.

La operación de bloqueo de lienzo es (eventualmente) llamar a Surface::lock() ( código aquí ). Que tiene un pedazo de código que dice:

 if (!mConnectedToCpu) { int err = Surface::connect(NATIVE_WINDOW_API_CPU); 

Esto está conectando un "productor de CPU", es decir, un código que se ejecuta en la CPU y genera datos gráficos, al lado del productor de la cola de búfer que se alimenta en la superficie. Ese productor no está desconectado en unlockAndPost() . Usted puede encontrar la llamada de desconexión en el destructor de superficie, que es un poco tarde para sus propósitos.

No puede tener dos productores en una cola de búfer, por lo que cuando entregue el decodificador de Surface al MediaCodec no puede conectarse.

Creo que tienes un par de opciones:

  1. En blanco la superficie con OpenGL ES. Cuando destruye la EGLSurface , se desconectará. Esto requiere configurar EGL / GLES y obtener el código de liberación de EGL correcto.
  2. Ponga un rectángulo en blanco usando un enfoque distinto a dibujar en el SurfaceView mismo (h / t mi compañero de oficina).

Para el enfoque # 2, sólo necesita una segunda vista (tal vez un ImageView ) con la misma posición y dimensiones que SurfaceView , y llenarlo con negro opaco. La capa SurfaceView siempre está bajo todo lo demás (suponiendo que no lo hayas configurado para que esté en la parte superior), por lo que los elementos de la interfaz de usuario se dibujarán encima de él. Cuando es el momento de iniciar la reproducción de la película, desactiva la otra vista.

Actualización: ahora se puede ver el enfoque # 1 en Grafika . En la actividad "Reproducir película (SurfaceView)", crea un contexto EGL, borra la superficie y destruye el contexto. (Es necesario destruir el contexto EGL y la superficie inmediatamente para evitar el problema de "dos productores").

  • Codificación y muxing de vídeo mediante MediaCodec y MediaMuxer
  • Android MediaCodec y la cámara: ¿cómo lograr una mayor velocidad de fotogramas para obtener datos de marco de la cámara?
  • No puedo capturar la pantalla de Android con la herramienta de registro de pantalla adb
  • Android muestra flujo de vídeo en MediaPlayer y codifica con MediaCodec
  • Cómo salvar SurfaceTexture como bitmap
  • Android MediaCodec: Reduce el tamaño del video mp4
  • El archivo convertido de MediaCodec de WAV a AMR no se reproduce
  • Error de codificación de vídeo que utiliza datos OnAudioFilterRead
  • Conseguir que los codificadores QualComm funcionen a través de la API de MediaCodec
  • MediaExtractor, MediaMetadataRetriever con archivo Raw / Asset
  • Cómo transmitir datos de MediaCodec a AudioTrack con Xamarin para Android
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.