From 27ce6fa203ce301227d1df5b20c00b9918c6802e Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Sat, 11 Oct 2014 21:47:58 -0700 Subject: [PATCH] Always patch num_ref_frames in the SPS to increase compatibility (read: attempt to fix some crashes on various Chinese SoCs) --- .../video/MediaCodecDecoderRenderer.java | 96 +++++++++---------- 1 file changed, 43 insertions(+), 53 deletions(-) diff --git a/src/com/limelight/binding/video/MediaCodecDecoderRenderer.java b/src/com/limelight/binding/video/MediaCodecDecoderRenderer.java index 57c4516c..c1c92c51 100644 --- a/src/com/limelight/binding/video/MediaCodecDecoderRenderer.java +++ b/src/com/limelight/binding/video/MediaCodecDecoderRenderer.java @@ -32,7 +32,6 @@ public class MediaCodecDecoderRenderer implements VideoDecoderRenderer { private MediaCodec videoDecoder; private Thread rendererThread; private boolean needsSpsBitstreamFixup; - private boolean needsSpsNumRefFixup; private VideoDepacketizer depacketizer; private boolean adaptivePlayback; @@ -49,7 +48,6 @@ public class MediaCodecDecoderRenderer implements VideoDecoderRenderer { public static final List blacklistedDecoderPrefixes; public static final List spsFixupBitstreamFixupDecoderPrefixes; - public static final List spsFixupNumRefFixupDecoderPrefixes; public static final List whitelistedAdaptiveResolutionPrefixes; static { @@ -70,11 +68,6 @@ public class MediaCodecDecoderRenderer implements VideoDecoderRenderer { spsFixupBitstreamFixupDecoderPrefixes.add("omx.qcom"); spsFixupBitstreamFixupDecoderPrefixes.add("omx.sec"); - spsFixupNumRefFixupDecoderPrefixes = new LinkedList(); - spsFixupNumRefFixupDecoderPrefixes.add("omx.TI"); - spsFixupNumRefFixupDecoderPrefixes.add("omx.qcom"); - spsFixupNumRefFixupDecoderPrefixes.add("omx.sec"); - whitelistedAdaptiveResolutionPrefixes = new LinkedList(); whitelistedAdaptiveResolutionPrefixes.add("omx.nvidia"); whitelistedAdaptiveResolutionPrefixes.add("omx.qcom"); @@ -120,13 +113,9 @@ public class MediaCodecDecoderRenderer implements VideoDecoderRenderer { } needsSpsBitstreamFixup = isDecoderInList(spsFixupBitstreamFixupDecoderPrefixes, decoderName); - needsSpsNumRefFixup = isDecoderInList(spsFixupNumRefFixupDecoderPrefixes, decoderName); if (needsSpsBitstreamFixup) { LimeLog.info("Decoder "+decoderName+" needs SPS bitstream restrictions fixup"); } - if (needsSpsNumRefFixup) { - LimeLog.info("Decoder "+decoderName+" needs SPS ref num fixup"); - } } private static boolean isDecoderInList(List decoderList, String decoderName) { @@ -485,52 +474,53 @@ public class MediaCodecDecoderRenderer implements VideoDecoderRenderer { if (header.data[header.offset+4] == 0x67) { numSpsIn++; - if (needsSpsBitstreamFixup || needsSpsNumRefFixup) { - ByteBuffer spsBuf = ByteBuffer.wrap(header.data); - - // Skip to the start of the NALU data - spsBuf.position(header.offset+5); - - SeqParameterSet sps = SeqParameterSet.read(spsBuf); - - // TI OMAP4 requires a reference frame count of 1 to decode successfully - if (needsSpsNumRefFixup) { - LimeLog.info("Fixing up num ref frames"); - sps.num_ref_frames = 1; - } - + ByteBuffer spsBuf = ByteBuffer.wrap(header.data); + + // Skip to the start of the NALU data + spsBuf.position(header.offset+5); + + SeqParameterSet sps = SeqParameterSet.read(spsBuf); + + // TI OMAP4 requires a reference frame count of 1 to decode successfully. Exynos 4 + // also requires this fixup. + // + // I'm doing this fixup for all devices because I haven't seen any devices that + // this causes issues for. At worst, it seems to do nothing and at best it fixes + // issues with video lag, hangs, and crashes. + LimeLog.info("Patching num_ref_frames in SPS"); + sps.num_ref_frames = 1; + + if (needsSpsBitstreamFixup) { // 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. - if (needsSpsBitstreamFixup) { - LimeLog.info("Adding bitstream restrictions"); + LimeLog.info("Adding bitstream restrictions"); - sps.vuiParams.bitstreamRestriction = new VUIParameters.BitstreamRestriction(); - sps.vuiParams.bitstreamRestriction.motion_vectors_over_pic_boundaries_flag = true; - sps.vuiParams.bitstreamRestriction.max_bytes_per_pic_denom = 2; - sps.vuiParams.bitstreamRestriction.max_bits_per_mb_denom = 1; - sps.vuiParams.bitstreamRestriction.log2_max_mv_length_horizontal = 16; - sps.vuiParams.bitstreamRestriction.log2_max_mv_length_vertical = 16; - sps.vuiParams.bitstreamRestriction.num_reorder_frames = 0; - sps.vuiParams.bitstreamRestriction.max_dec_frame_buffering = 1; - } - - // Write the annex B header - buf.put(header.data, header.offset, 5); - - // Write the modified SPS to the input buffer - sps.write(buf); - - try { - videoDecoder.queueInputBuffer(inputBufferIndex, - 0, buf.position(), - currentTime * 1000, codecFlags); - } catch (Exception e) { - throw new RendererException(this, e, buf, codecFlags); - } - - depacketizer.freeDecodeUnit(decodeUnit); - return; + sps.vuiParams.bitstreamRestriction = new VUIParameters.BitstreamRestriction(); + sps.vuiParams.bitstreamRestriction.motion_vectors_over_pic_boundaries_flag = true; + sps.vuiParams.bitstreamRestriction.max_bytes_per_pic_denom = 2; + sps.vuiParams.bitstreamRestriction.max_bits_per_mb_denom = 1; + sps.vuiParams.bitstreamRestriction.log2_max_mv_length_horizontal = 16; + sps.vuiParams.bitstreamRestriction.log2_max_mv_length_vertical = 16; + sps.vuiParams.bitstreamRestriction.num_reorder_frames = 0; + sps.vuiParams.bitstreamRestriction.max_dec_frame_buffering = 1; } + + // Write the annex B header + buf.put(header.data, header.offset, 5); + + // Write the modified SPS to the input buffer + sps.write(buf); + + try { + videoDecoder.queueInputBuffer(inputBufferIndex, + 0, buf.position(), + currentTime * 1000, codecFlags); + } catch (Exception e) { + throw new RendererException(this, e, buf, codecFlags); + } + + depacketizer.freeDecodeUnit(decodeUnit); + return; } else if (header.data[header.offset+4] == 0x68) { numPpsIn++; }