Android 本机\u窗口\u api\u连接返回错误:参数无效(-22)
我正在使用MediaCodec API编写一个视频播放器应用程序。我必须在视频解码开始前显示空白屏幕。所以我使用下面的代码来显示空白屏幕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); 在此之后,视频解码将开始。
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解码器时,它无法连接
我相信你有两个选择:
EGLSurface
时,它将断开连接。这需要设置EGL/GLES并获得正确的EGL发布代码表面视图
本身(h/t我的办公室伙伴)上绘制外的其他方法放置一个空白矩形图像视图
),其位置和尺寸与表面视图
相同,并用不透明黑色填充。SurfaceView
层始终位于其他所有层的下方(假设您没有将其配置为位于顶部),因此UI元素将在其上方绘制。开始播放电影时,禁用其他视图
更新:您现在可以在中看到方法1。在“播放电影(SurfaceView)”活动中,它创建EGL上下文,清除曲面,并销毁上下文。(有必要立即销毁EGL上下文和表面,以避免“两个生产者”问题。)您是否在日志中也看到关于“连接:已连接”的日志消息?嗨,fadden,我的日志中没有这样一行。我已经让它工作了。非常感谢!我写了一段代码来做这件事,并把它留在这里。我希望这对其他人有帮助。我可以写一本书,讲述我的一个问题通过阅读you@fadden的答案而得到解决的所有时间。您的贡献和工作是无价的资源,谢谢分享!我喜欢有时你的同事在这些答案中突然出现,通常会带来一些棘手的解决方案或不同的观点。好像我认识你们两个。谢谢画布由于先前的绘图/多个生产者而被锁定。非常感谢。