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
- PCM -> AAC (Encoder) -> PCM (Decodificador) en tiempo real con optimización correcta
- Buffer de vídeo circular Android con sonido
- ¿Podemos volver a escribir la API de MediaCodec en C?
- Entrada de superficie de búfer en MediaCodec
- MediaCodec KEY_FRAME_RATE parece ser ignorado
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?
- MediaExtractor.setDataSource lanza IOException "no se pudo instanciar el extractor"
- ¿Cómo usar MediaCodec para decodificar datos del servidor RTSP?
- Problemas de framerate de GLSurfaceView en Nexus 5
- Codificación de audio AAC utilizando AudioRecord y MediaCodec en Android
- Causa del codificador en Adreno GPU mientras se codifica desde Surface
- MediaCodec con entrada de superficie: Producción de salida en trozos
- ¿Qué significa el código de error -1010 en Android MediaCodec?
- ¿MediaCodec siempre da salida de audio de 16 bits?
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:
- 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. - 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").
- Hacer scrollbars flash de código (como iOS flashScrollIndicators)
- ADT (Eclipse) vs. Android Studio: ¿Cuánta diferencia de tamaño de archivo APK es normal?