This problem might look similar to SurfaceTexture's onFrameAvailable() method always called too late but I think it is different. Similarly, the code I am working with is very similar to http://bigflake.com/mediacodec/ExtractMpegFramesTest_egl14.java.txt
I need to import a video into the application and transcode it. The transcoding process is an async task. In the async task an OutputSurface (very similar to CodecOutputSurface in the bigflake example) which implements SurfaceTexture.OnFrameAvailableListner is created. The problem is, sometimes, after waited for TIMEOUT_MS, onFrameAvailable is still not called and hence a RuntimeException is thrown:
/**
* Latches the next buffer into the texture. Must be called from the thread that created
* the OutputSurface object, after the onFrameAvailable callback has signaled that new
* data is available.
*/
public void awaitNewImage() {
final int TIMEOUT_MS = 500;
synchronized (mFrameSyncObject) {
while (!mFrameAvailable) {
try {
mFrameSyncObject.wait(TIMEOUT_MS);
if (!mFrameAvailable) {
// TODO: if "spurious wakeup", continue while loop
throw new RuntimeException("Surface frame wait timed out");
}
} catch (InterruptedException ie) {
// shouldn't happen
throw new RuntimeException(ie);
}
}
mFrameAvailable = false;
}
// Latch the data.
mTextureRender.checkGlError("before updateTexImage");
mSurfaceTexture.updateTexImage();
}
@Override
public void onFrameAvailable(SurfaceTexture st) {
if (VERBOSE) Log.d(TAG, "new frame available");
synchronized (mFrameSyncObject) {
if (mFrameAvailable) {
throw new RuntimeException("mFrameAvailable already set, frame could be dropped");
}
mFrameAvailable = true;
mFrameSyncObject.notifyAll();
}
}
I know the onFrameAvailable event will only be delivered to a looper thread and cannot be the same thread as the one that awaitNewImage sits. And I verified that this is not the case.
OutputSurface is created in an AsyncTask from a UI thread, hence onFrameAvailable event is delivered to the main UI Looper. When I debug, I can see that breakpoints on these two methods are being hit in different thread.
So then I don't know why the time out would still happen sometimes. About 30% of my trials it times out. It's not specific to one device or one API. I don't want to increase the TIMEOUT_MS because that will make the transcoding process even slower (it is already pretty slow). Any help if appreciated! Thank you!