我使用的代码来自此代表:https://github.com/DrKLO/Telegram/
在实例化编码器和解码器的〜/ src / main / java / org / telegram / android / video / MediaController类中,我得到了" Sufrace等待超时异常"在OutputSurface类中,无论我选择什么视频。
尝试使用设备:Nexus 4(Lollipop),Asus Zenfone 5(Kitkat),Moto G(Kitkat)。
我有什么遗失的吗?我根本没有改变代码。
- MediaController.java的代码片段 -
if (!decoderDone) {
int decoderStatus = decoder.dequeueOutputBuffer(info, TIMEOUT_USEC);
if (decoderStatus == MediaCodec.INFO_TRY_AGAIN_LATER) {
decoderOutputAvailable = false;
} else if (decoderStatus == MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED) {
} else if (decoderStatus == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) {
MediaFormat newFormat = decoder.getOutputFormat();
Log.e("tmessages", "newFormat = " + newFormat);
} else if (decoderStatus < 0) {
throw new RuntimeException("unexpected result from decoder.dequeueOutputBuffer: " + decoderStatus);
} else {
boolean doRender = false;
if (Build.VERSION.SDK_INT >= 18) {
doRender = info.size != 0;
} else {
doRender = info.size != 0 || info.presentationTimeUs != 0;
}
if (endTime > 0 && info.presentationTimeUs >= endTime) {
inputDone = true;
decoderDone = true;
doRender = false;
info.flags |= MediaCodec.BUFFER_FLAG_END_OF_STREAM;
}
if (startTime > 0 && videoTime == -1) {
if (info.presentationTimeUs < startTime) {
doRender = false;
Log.e("tmessages", "drop frame startTime = " + startTime + " present time = " + info.presentationTimeUs);
} else {
videoTime = info.presentationTimeUs;
}
}
decoder.releaseOutputBuffer(decoderStatus, doRender);
if (doRender) {
boolean errorWait = false;
try {
outputSurface.awaitNewImage();
} catch (Exception e) {
Log.e("wait",""+true);
errorWait = true;
Log.e("tmessages", e.getMessage());
}
if (!errorWait) {
if (Build.VERSION.SDK_INT >= 18) {
outputSurface.drawImage(false);
inputSurface.setPresentationTime(info.presentationTimeUs * 1000);
inputSurface.swapBuffers();
} else {
int inputBufIndex = encoder.dequeueInputBuffer(TIMEOUT_USEC);
if (inputBufIndex >= 0) {
outputSurface.drawImage(true);
ByteBuffer rgbBuf = outputSurface.getFrame();
ByteBuffer yuvBuf = encoderInputBuffers[inputBufIndex];
yuvBuf.clear();
convertVideoFrame(rgbBuf, yuvBuf, colorFormat, resultWidth, resultHeight, padding, swapUV);
encoder.queueInputBuffer(inputBufIndex, 0, bufferSize, info.presentationTimeUs, 0);
} else {
Log.e("tmessages", "input buffer not available");
}
}
}
}
if ((info.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0) {
decoderOutputAvailable = false;
Log.e("tmessages", "decoder stream end");
if (Build.VERSION.SDK_INT >= 18) {
encoder.signalEndOfInputStream();
} else {
int inputBufIndex = encoder.dequeueInputBuffer(TIMEOUT_USEC);
if (inputBufIndex >= 0) {
encoder.queueInputBuffer(inputBufIndex, 0, 1, info.presentationTimeUs, MediaCodec.BUFFER_FLAG_END_OF_STREAM);
}
}
}
}
}
- 来自OutputSurface.java的代码片段 -
public void awaitNewImage() {
final int TIMEOUT_MS = 2500;
synchronized (mFrameSyncObject) {
while (!mFrameAvailable) {
try {
mFrameSyncObject.wait(TIMEOUT_MS);
if (!mFrameAvailable) {
throw new RuntimeException("Surface frame wait timed out");
}
} catch (InterruptedException ie) {
throw new RuntimeException(ie);
}
}
mFrameAvailable = false;
}
mTextureRender.checkGlError("before updateTexImage");
mSurfaceTexture.updateTexImage();
}
public void drawImage(boolean invert) {
mTextureRender.drawFrame(mSurfaceTexture, invert);
}
@Override
public void onFrameAvailable(SurfaceTexture st) {
Log.d("frame ","new frame");
synchronized (mFrameSyncObject) {
if (mFrameAvailable) {
throw new RuntimeException("mFrameAvailable already set, frame could be dropped");
}
mFrameAvailable = true;
mFrameSyncObject.notifyAll();
}
}
这些代码段可能没有多大意义,并且无法在此处发布完整代码,因为它非常庞大。您可以在此处找到完整的代码:https://github.com/316karan/mediacodec-tele
问题是我从未在OutputSurface上收到任何帧,并且它会进入一个带有超时的无限循环。