I am writing a Video player application using MediaCodec API. I have to show blank screen before video decoding started. So i am using following code to show blank screen.
Canvas c=null;
c = surfaceView.getHolder().lockCanvas();
c.drawColor(Color.BLACK);
surfaceView.getHolder().unlockCanvasAndPost(c);
After this Video decoding will start. But at configure time
videoDecoder.configure(format, surfaceView.getHolder().getSurface(), null, 0);
it giving following errors
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
So my app crash with that error. Without that blank screen code decoder is working fine. How can i resolve this problem?
Here's my theory, based on a quick look through the framework code.
The Canvas lock operation is (eventually) calling into Surface::lock()
(code here). That has a piece of code that says:
if (!mConnectedToCpu) {
int err = Surface::connect(NATIVE_WINDOW_API_CPU);
This is connecting a "CPU producer", i.e. code that runs on the CPU and generates graphic data, to the producer side of the buffer queue that feeds into the Surface. That producer is not disconnected in unlockAndPost()
. You can actually find the disconnect call in the Surface destructor, which is a bit late for your purposes.
You can't have two producers on one buffer queue, so when you hand the Surface to the MediaCodec decoder it's unable to connect.
I believe you have a couple of options:
EGLSurface
it will disconnect. This requires setting up EGL/GLES and getting the EGL release code right.SurfaceView
itself (h/t my office-mate).For approach #2, you just need a second view (maybe an ImageView
) with the same position and dimensions as the SurfaceView
, and fill it with opaque black. The SurfaceView
layer is always under everything else (assuming you haven't configured it to be on top), so the UI elements will draw on top of it. When it's time to start the movie playing, you disable the other view.
Update: you can now see approach #1 in Grafika. In the "Play movie (SurfaceView)" activity, it creates an EGL context, clears the surface, and destroys the context. (It's necessary to destroy the EGL context and surface immediately to avoid the "two producer" problem.)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With