我正在手动读取 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();
...
and
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。因此我假设帧应该毫无延迟地渲染。
我希望将帧渲染到纹理,而不必放置额外的帧。
来自媒体编解码器文档 https://developer.android.com/reference/android/media/MediaCodec.html
Executing 状态有 3 个子状态:Flushed、Running 和
流结束。之后立马start()
编解码器位于 Flushed 中
子状态,它保存所有缓冲区。一旦第一次输入
缓冲区出队,编解码器进入运行子状态,在该状态
度过了一生的大部分时间。当您使用以下命令对输入缓冲区进行排队时
流结束标记,编解码器转换到End-of-Stream
子状态。在此状态下,编解码器不再接受进一步的输入
缓冲区,但仍然生成输出缓冲区,直到流结束
达到输出。您可以返回到 Flushed 子状态:
在执行状态下的任何时间使用flush()。
您需要“使用以下命令对输入缓冲区进行排队end-of-stream
对您提供给解码器的第一帧执行此操作(确保它是关键帧)。
这一点是为了告诉解码器不要再期待更多帧,因此立即开始播放。否则,在看到任何东西之前喂 3 或 4 帧是正常的。这是所有 MPEG 解码器的期望,与 Android 无关。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)