Submit codec config frames with the corresponding flag to work around an TI OMAP 4 errata. Also add a file that documents the currently known codec errata.

This commit is contained in:
Cameron Gutman 2014-06-30 21:05:10 -07:00
parent ddf9284ece
commit b3c78ce1b1
3 changed files with 25 additions and 5 deletions

10
decoder-errata.txt Normal file
View File

@ -0,0 +1,10 @@
This file serves to document some of the decoder errata when using MediaCodec hardware decoders on certain devices.
1. num_ref_frames is set to 16 by NVENC which causes decoders to allocate 16+ buffers. This can cause an OOM error on some devices.
- Affected decoders: TI OMAP4, possibly some Qualcomm chips too (Galaxy S3 on 4.3+)
2. Some decoders have a huge per-frame latency with the unmodified SPS sent from NVENC. Setting max_dec_frame_buffering fixes this latency issue.
- Affected decoders: NVIDIA Tegra 3 and 4
3. Some decoders strictly require that you pass BUFFER_FLAG_CODEC_CONFIG and crash upon the IDR frame if you don't
- Affected decoders: TI OMAP4

Binary file not shown.

View File

@ -237,15 +237,25 @@ public class MediaCodecDecoderRenderer implements VideoDecoderRenderer {
// Clear old input data // Clear old input data
buf.clear(); buf.clear();
if (needsSpsBitstreamFixup || needsSpsNumRefFixup) { int codecFlags = 0;
int decodeUnitFlags = decodeUnit.getFlags();
if ((decodeUnitFlags & DecodeUnit.DU_FLAG_CODEC_CONFIG) != 0) {
codecFlags |= MediaCodec.BUFFER_FLAG_CODEC_CONFIG;
}
if ((decodeUnitFlags & DecodeUnit.DU_FLAG_SYNC_FRAME) != 0) {
codecFlags |= MediaCodec.BUFFER_FLAG_SYNC_FRAME;
}
if ((decodeUnitFlags & DecodeUnit.DU_FLAG_CODEC_CONFIG) != 0 &&
(needsSpsBitstreamFixup || needsSpsNumRefFixup)) {
ByteBufferDescriptor header = decodeUnit.getBufferList().get(0); ByteBufferDescriptor header = decodeUnit.getBufferList().get(0);
if (header.data[header.offset+4] == 0x67) { if (header.data[header.offset+4] == 0x67) {
// TI OMAP4 requires a reference frame count of 1 to decode successfully // TI OMAP4 requires a reference frame count of 1 to decode successfully
if (needsSpsNumRefFixup) { if (needsSpsNumRefFixup) {
LimeLog.info("Fixing up num ref frames"); LimeLog.info("Fixing up num ref frames");
this.replace(header, 80, 9, new byte[] {0x40}, 3); this.replace(header, 80, 9, new byte[] {0x40}, 3);
} }
// The SPS that comes in the current H264 bytestream doesn't set bitstream_restriction_flag // The SPS that comes in the current H264 bytestream doesn't set bitstream_restriction_flag
// or max_dec_frame_buffering which increases decoding latency on Tegra. // or max_dec_frame_buffering which increases decoding latency on Tegra.
@ -285,7 +295,7 @@ public class MediaCodecDecoderRenderer implements VideoDecoderRenderer {
videoDecoder.queueInputBuffer(inputIndex, videoDecoder.queueInputBuffer(inputIndex,
0, spsLength, 0, spsLength,
0, 0); 0, codecFlags);
return true; return true;
} }
} }
@ -298,7 +308,7 @@ public class MediaCodecDecoderRenderer implements VideoDecoderRenderer {
videoDecoder.queueInputBuffer(inputIndex, videoDecoder.queueInputBuffer(inputIndex,
0, decodeUnit.getDataLength(), 0, decodeUnit.getDataLength(),
0, 0); 0, codecFlags);
} }
return true; return true;