此问题可能与SurfaceTexture's onFrameAvailable() method always called too late类似,但我认为它有所不同。同样,我正在使用的代码与http://bigflake.com/mediacodec/ExtractMpegFramesTest_egl14.java.txt
非常相似我需要将视频导入应用程序并对其进行转码。转码过程是异步任务。在异步任务中,创建了一个实现SurfaceTexture.OnFrameAvailableListner的OutputSurface(非常类似于bigflake示例中的CodecOutputSurface)。问题是,有时候,在等待TIMEOUT_MS之后,onFrameAvailable仍然没有被调用,因此抛出了RuntimeException:
/**
* 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();
}
}
我知道onFrameAvailable事件只会被传递给looper线程,并且不能与awaitNewImage所在的线程相同。我证实情况并非如此。
OutputSurface是在UI线程的AsyncTask中创建的,因此onFrameAvailable事件被传递到主UI Looper。当我调试时,我可以看到这两个方法的断点正在不同的线程中被击中。
那么我就不知道为什么有时会出现超时的原因。大约30%的试验超时。它并非特定于一个设备或一个API。我不想增加TIMEOUT_MS,因为这会使转码过程更慢(它已经非常慢)。任何帮助,如果赞赏!谢谢!