Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/223.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 本机\u窗口\u api\u连接返回错误:参数无效(-22)_Android_Android Mediaplayer_Android Mediacodec - Fatal编程技术网

Android 本机\u窗口\u api\u连接返回错误:参数无效(-22)

Android 本机\u窗口\u api\u连接返回错误:参数无效(-22),android,android-mediaplayer,android-mediacodec,Android,Android Mediaplayer,Android Mediacodec,我正在使用MediaCodec API编写一个视频播放器应用程序。我必须在视频解码开始前显示空白屏幕。所以我使用下面的代码来显示空白屏幕 Canvas c=null; c = surfaceView.getHolder().lockCanvas(); c.drawColor(Color.BLACK); surfaceView.getHolder().unlockCanvasAndPost(c); 在此之后,视频解码将开始。

我正在使用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

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

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

画布锁定操作(最终)调用到
Surface::lock()
()。它有一段代码,上面写着:

if (!mConnectedToCpu) {
    int err = Surface::connect(NATIVE_WINDOW_API_CPU);
这是将一个“CPU生产者”(即在CPU上运行并生成图形数据的代码)连接到缓冲区队列的生产者端,后者馈送到曲面。在
unlockAndPost()
中未断开该生产者的连接。实际上,您可以在Surface析构函数中找到disconnect调用,这对于您来说有点晚了

一个缓冲队列上不能有两个生产者,因此当您将曲面交给MediaCodec解码器时,它无法连接

我相信你有两个选择:

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


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

    您是否在日志中也看到关于“连接:已连接”的日志消息?嗨,fadden,我的日志中没有这样一行。我已经让它工作了。非常感谢!我写了一段代码来做这件事,并把它留在这里。我希望这对其他人有帮助。我可以写一本书,讲述我的一个问题通过阅读you@fadden的答案而得到解决的所有时间。您的贡献和工作是无价的资源,谢谢分享!我喜欢有时你的同事在这些答案中突然出现,通常会带来一些棘手的解决方案或不同的观点。好像我认识你们两个。谢谢画布由于先前的绘图/多个生产者而被锁定。非常感谢。