【发布时间】:2016-11-07 01:11:02
【问题描述】:
我正在手动读取 RTP/H264 流并将 H264 帧传递给 Android MediaCodec。我使用“markerBit”作为框架的边框。 MediaCodec 绑定到 OpenGL 纹理 (SurfaceTexture)。 一般来说,一切正常。但解码器似乎缓冲帧。如果我在解码器中放置一个帧,它不会立即渲染到纹理中。在我在解码器中多放 2-3 帧后,第一帧被渲染到纹理上。
我正在针对 Android 4.4.4 实施。
private static final int INFINITE_TIMEOUT = -1;
private static final int TIMEOUT_OUTPUT_BUFFER_MEDIA_CODEC = 1000;
...
int bufferIndex = codec.dequeueInputBuffer(INFINITE_TIMEOUT);
if (bufferIndex < 0) {
throw new RuntimeException("Error");
}
ByteBuffer inputBuffer = inputBuffers[bufferIndex];
inputBuffer.clear();
// Copy H264 data to inputBuffer
h264Frame.fill(inputBuffer);
codec.queueInputBuffer(bufferIndex, 0, inputBuffer.position(), 0, 0);
drainOutputBuffers();
...
和
private boolean drainOutputBuffers() {
MediaCodec.BufferInfo buffInfo = new MediaCodec.BufferInfo();
int outputBufferIndex = codec.dequeueOutputBuffer(buffInfo, TIMEOUT_OUTPUT_BUFFER_MEDIA_CODEC);
if (outputBufferIndex >= 0) {
codec.releaseOutputBuffer(outputBufferIndex, true);
return true;
}
switch (outputBufferIndex) {
case MediaCodec.INFO_TRY_AGAIN_LATER:
LOG.debug("Could not dequeue output buffer. Try again later");
break;
case MediaCodec.INFO_OUTPUT_FORMAT_CHANGED:
LOG.warn("The output format has changed.");
break;
case MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED:
LOG.warn("The output buffers has changed.");
break;
default:
LOG.warn("The output buffer index was negative: {}", outputBufferIndex);
}
return false;
}
在渲染方面,我使用“onFrameAvailable”回调来检查是否必须更新 openGl 线程上的纹理。我用于检查的标志由锁(同步)保护。
我怀疑演示时间戳可能会影响渲染。但我将它设置为 0。因此我假设应该立即渲染帧。
我想将帧渲染到纹理上,而不必放置额外的帧。
【问题讨论】:
-
我认为这不是 h264 解码器的本质,它很可能是 MediaCodec 中的一个缺陷。如果我在使用 ffmpeg 的 PC 上执行此操作,则没有延迟。
标签: android opengl-es h.264 android-mediacodec