Ich lese manuell einen RTP/H264-Stream und übergebe die H264-Frames an den Android MediaCodec. Ich benutze den "markerBit" als Rahmen für die Frames. Der MediaCodec ist an eine OpenGL-Textur (SurfaceTexture) gebunden. Im Allgemeinen funktioniert alles gut. Der Decoder scheint jedoch Frames zu puffern. Wenn ich einen Frame in den Decoder lege, wird er nicht sofort auf die Textur gerendert. Nachdem ich 2-3 Frames mehr in den Decoder gesteckt habe, wird der erste Frame in die Textur gerendert.Android MediaCodec scheint H264-Frames zu puffern
Ich implementiere gegen 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();
...
und
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;
}
Auf der Rendering-Seite ich den „onFrameAvailable“ Rückruf verwenden, um zu überprüfen, ob ich die Textur auf dem OPENGL Thema habe zu aktualisieren. Das Flag, das ich für die Überprüfung verwende, wird durch eine Sperre geschützt (synchronisiert).
Ich vermute, dass der Präsentationszeitstempel das Rendering beeinflussen kann. Aber ich setze es auf 0. Daher nehme ich an, dass der Rahmen ohne Verzögerung gerendert werden soll.
Ich möchte das Bild auf die Textur gerendert haben, ohne zusätzliche Frames zu setzen.
Ich glaube nicht, dass es die Natur für h264 Decoder ist, ist es wahrscheinlich ein Fehler in MediaCodec. Wenn ich dies auf einem PC mit ffmpeg mache, gibt es keine Verzögerung. – user3667089