diff --git a/decoder-errata.txt b/decoder-errata.txt new file mode 100644 index 00000000..24c37a21 --- /dev/null +++ b/decoder-errata.txt @@ -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 \ No newline at end of file diff --git a/libs/limelight-common.jar b/libs/limelight-common.jar index 6308c5f9..1d597abe 100644 Binary files a/libs/limelight-common.jar and b/libs/limelight-common.jar differ diff --git a/src/com/limelight/binding/video/MediaCodecDecoderRenderer.java b/src/com/limelight/binding/video/MediaCodecDecoderRenderer.java index a852a18e..7d5afc5c 100644 --- a/src/com/limelight/binding/video/MediaCodecDecoderRenderer.java +++ b/src/com/limelight/binding/video/MediaCodecDecoderRenderer.java @@ -237,15 +237,25 @@ public class MediaCodecDecoderRenderer implements VideoDecoderRenderer { // Clear old input data 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); if (header.data[header.offset+4] == 0x67) { // TI OMAP4 requires a reference frame count of 1 to decode successfully if (needsSpsNumRefFixup) { LimeLog.info("Fixing up num ref frames"); this.replace(header, 80, 9, new byte[] {0x40}, 3); - } + } // 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. @@ -285,7 +295,7 @@ public class MediaCodecDecoderRenderer implements VideoDecoderRenderer { videoDecoder.queueInputBuffer(inputIndex, 0, spsLength, - 0, 0); + 0, codecFlags); return true; } } @@ -298,7 +308,7 @@ public class MediaCodecDecoderRenderer implements VideoDecoderRenderer { videoDecoder.queueInputBuffer(inputIndex, 0, decodeUnit.getDataLength(), - 0, 0); + 0, codecFlags); } return true;