native_window_api_connect返回错误:参数无效(-22)

时间:2014-02-03 12:06:18

标签: android android-mediaplayer mediacodec

我正在使用MediaCodec API编写视频播放器应用程序。我必须在视频解码开始前显示空白屏幕。所以我使用以下代码显示空白屏幕。

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

此视频解码将开始。但是在配置时

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

它给出了以下错误

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

所以我的应用程序因该错误而崩溃。没有那个空白屏幕代码解码器工作正常。我该如何解决这个问题?

1 个答案:

答案 0 :(得分:6)

这是我的理论,基于对框架代码的快速浏览。

Canvas锁定操作(最终)调用Surface::lock()code here)。这有一段代码说:

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

这是将“CPU生产者”(即在CPU上运行并生成图形数据的代码)连接到提供给Surface的缓冲区队列的生产者端。该生产者未在unlockAndPost()中断开连接。您实际上可以在Surface析构函数中找到断开调用,这对于您的目的来说有点晚了。

在一个缓冲区队列中不能有两个生成器,因此当您将Surface传递给MediaCodec解码器时,它无法连接。

我相信你有几个选择:

  1. 使用OpenGL ES清空表面。当您销毁EGLSurface时,它将断开连接。这需要设置EGL / GLES并获得正确的EGL版本代码。
  2. 使用除了SurfaceView本身之外的方法(h / t我的办公室伙伴)以外的方法建立一个空白矩形。
  3. 对于方法#2,您只需要第二个视图(可能是ImageView),其位置和尺寸与SurfaceView相同,并用不透明的黑色填充。 SurfaceView图层始终位于其他所有图层(假设您尚未将其配置为顶部),因此UI元素将在其上绘制。当开始播放电影时,您将禁用其他视图。

    更新:您现在可以在Grafika中看到方法#1。在“播放电影(SurfaceView)”活动中,它会创建EGL上下文,清除曲面并破坏上下文。 (有必要立即销毁EGL上下文并避免出现“两个生产者”问题。)