我正在使用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
所以我的应用程序因该错误而崩溃。没有那个空白屏幕代码解码器工作正常。我该如何解决这个问题?
答案 0 :(得分:6)
这是我的理论,基于对框架代码的快速浏览。
Canvas锁定操作(最终)调用Surface::lock()
(code here)。这有一段代码说:
if (!mConnectedToCpu) {
int err = Surface::connect(NATIVE_WINDOW_API_CPU);
这是将“CPU生产者”(即在CPU上运行并生成图形数据的代码)连接到提供给Surface的缓冲区队列的生产者端。该生产者未在unlockAndPost()
中断开连接。您实际上可以在Surface析构函数中找到断开调用,这对于您的目的来说有点晚了。
在一个缓冲区队列中不能有两个生成器,因此当您将Surface传递给MediaCodec解码器时,它无法连接。
我相信你有几个选择:
EGLSurface
时,它将断开连接。这需要设置EGL / GLES并获得正确的EGL版本代码。SurfaceView
本身之外的方法(h / t我的办公室伙伴)以外的方法建立一个空白矩形。对于方法#2,您只需要第二个视图(可能是ImageView
),其位置和尺寸与SurfaceView
相同,并用不透明的黑色填充。 SurfaceView
图层始终位于其他所有图层(假设您尚未将其配置为顶部),因此UI元素将在其上绘制。当开始播放电影时,您将禁用其他视图。
更新:您现在可以在Grafika中看到方法#1。在“播放电影(SurfaceView)”活动中,它会创建EGL上下文,清除曲面并破坏上下文。 (有必要立即销毁EGL上下文并避免出现“两个生产者”问题。)