Update MediaCodec renderer to avoid deprecated features on Lollipop

This commit is contained in:
Cameron Gutman 2015-08-17 17:52:57 -07:00
parent 1187d9c78c
commit 792846ddad

View File

@ -13,7 +13,6 @@ import com.limelight.nvstream.av.DecodeUnit;
import com.limelight.nvstream.av.video.VideoDecoderRenderer; import com.limelight.nvstream.av.video.VideoDecoderRenderer;
import com.limelight.nvstream.av.video.VideoDepacketizer; import com.limelight.nvstream.av.video.VideoDepacketizer;
import android.annotation.TargetApi;
import android.media.MediaCodec; import android.media.MediaCodec;
import android.media.MediaCodecInfo; import android.media.MediaCodecInfo;
import android.media.MediaFormat; import android.media.MediaFormat;
@ -22,10 +21,11 @@ import android.media.MediaCodec.CodecException;
import android.os.Build; import android.os.Build;
import android.view.SurfaceHolder; import android.view.SurfaceHolder;
@SuppressWarnings("unused")
public class MediaCodecDecoderRenderer extends EnhancedDecoderRenderer { public class MediaCodecDecoderRenderer extends EnhancedDecoderRenderer {
private ByteBuffer[] videoDecoderInputBuffers; // Used on versions < 5.0
private ByteBuffer[] legacyInputBuffers;
private MediaCodec videoDecoder; private MediaCodec videoDecoder;
private Thread rendererThread; private Thread rendererThread;
private final boolean needsSpsBitstreamFixup, isExynos4; private final boolean needsSpsBitstreamFixup, isExynos4;
@ -46,7 +46,6 @@ public class MediaCodecDecoderRenderer extends EnhancedDecoderRenderer {
private int numPpsIn; private int numPpsIn;
private int numIframeIn; private int numIframeIn;
@TargetApi(Build.VERSION_CODES.KITKAT)
public MediaCodecDecoderRenderer() { public MediaCodecDecoderRenderer() {
//dumpDecoders(); //dumpDecoders();
@ -118,7 +117,6 @@ public class MediaCodecDecoderRenderer extends EnhancedDecoderRenderer {
return true; return true;
} }
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
private void handleDecoderException(Exception e, ByteBuffer buf, int codecFlags) { private void handleDecoderException(Exception e, ByteBuffer buf, int codecFlags) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
if (e instanceof CodecException) { if (e instanceof CodecException) {
@ -148,7 +146,6 @@ public class MediaCodecDecoderRenderer extends EnhancedDecoderRenderer {
private void startDirectSubmitRendererThread() private void startDirectSubmitRendererThread()
{ {
rendererThread = new Thread() { rendererThread = new Thread() {
@SuppressWarnings("deprecation")
@Override @Override
public void run() { public void run() {
BufferInfo info = new BufferInfo(); BufferInfo info = new BufferInfo();
@ -181,9 +178,6 @@ public class MediaCodecDecoderRenderer extends EnhancedDecoderRenderer {
switch (outIndex) { switch (outIndex) {
case MediaCodec.INFO_TRY_AGAIN_LATER: case MediaCodec.INFO_TRY_AGAIN_LATER:
break; break;
case MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED:
LimeLog.info("Output buffers changed");
break;
case MediaCodec.INFO_OUTPUT_FORMAT_CHANGED: case MediaCodec.INFO_OUTPUT_FORMAT_CHANGED:
LimeLog.info("Output format changed"); LimeLog.info("Output format changed");
LimeLog.info("New output Format: " + videoDecoder.getOutputFormat()); LimeLog.info("New output Format: " + videoDecoder.getOutputFormat());
@ -226,7 +220,6 @@ public class MediaCodecDecoderRenderer extends EnhancedDecoderRenderer {
private void startLegacyRendererThread() private void startLegacyRendererThread()
{ {
rendererThread = new Thread() { rendererThread = new Thread() {
@SuppressWarnings("deprecation")
@Override @Override
public void run() { public void run() {
BufferInfo info = new BufferInfo(); BufferInfo info = new BufferInfo();
@ -252,7 +245,7 @@ public class MediaCodecDecoderRenderer extends EnhancedDecoderRenderer {
break; break;
} }
submitDecodeUnit(du, videoDecoderInputBuffers[inputIndex], inputIndex); submitDecodeUnit(du, inputIndex);
du = null; du = null;
inputIndex = -1; inputIndex = -1;
@ -298,7 +291,7 @@ public class MediaCodecDecoderRenderer extends EnhancedDecoderRenderer {
LimeLog.warning("Receiving an input buffer took too long: "+(submissionTime - lastDuDequeueTime)+" ms"); LimeLog.warning("Receiving an input buffer took too long: "+(submissionTime - lastDuDequeueTime)+" ms");
} }
submitDecodeUnit(du, videoDecoderInputBuffers[inputIndex], inputIndex); submitDecodeUnit(du, inputIndex);
// DU and input buffer have both been consumed // DU and input buffer have both been consumed
du = null; du = null;
@ -338,9 +331,6 @@ public class MediaCodecDecoderRenderer extends EnhancedDecoderRenderer {
LockSupport.parkNanos(1); LockSupport.parkNanos(1);
} }
break; break;
case MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED:
LimeLog.info("Output buffers changed");
break;
case MediaCodec.INFO_OUTPUT_FORMAT_CHANGED: case MediaCodec.INFO_OUTPUT_FORMAT_CHANGED:
LimeLog.info("Output format changed"); LimeLog.info("Output format changed");
LimeLog.info("New output Format: " + videoDecoder.getOutputFormat()); LimeLog.info("New output Format: " + videoDecoder.getOutputFormat());
@ -368,7 +358,9 @@ public class MediaCodecDecoderRenderer extends EnhancedDecoderRenderer {
// Start the decoder // Start the decoder
videoDecoder.start(); videoDecoder.start();
videoDecoderInputBuffers = videoDecoder.getInputBuffers(); if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
legacyInputBuffers = videoDecoder.getInputBuffers();
}
if (directSubmit) { if (directSubmit) {
startDirectSubmitRendererThread(); startDirectSubmitRendererThread();
@ -409,7 +401,7 @@ public class MediaCodecDecoderRenderer extends EnhancedDecoderRenderer {
for (i = 0; i < 25; i++) { for (i = 0; i < 25; i++) {
try { try {
videoDecoder.queueInputBuffer(inputBufferIndex, videoDecoder.queueInputBuffer(inputBufferIndex,
0, length, offset, length,
timestampUs, codecFlags); timestampUs, codecFlags);
break; break;
} catch (Exception e) { } catch (Exception e) {
@ -423,8 +415,26 @@ public class MediaCodecDecoderRenderer extends EnhancedDecoderRenderer {
} }
} }
// Using the new getInputBuffer() API on Lollipop allows
// the framework to do some performance optimizations for us
private ByteBuffer getEmptyInputBuffer(int inputBufferIndex) {
ByteBuffer buf;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
buf = videoDecoder.getInputBuffer(inputBufferIndex);
}
else {
buf = legacyInputBuffers[inputBufferIndex];
// Clear old input data pre-Lollipop
buf.clear();
}
return buf;
}
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
private void submitDecodeUnit(DecodeUnit decodeUnit, ByteBuffer buf, int inputBufferIndex) { private void submitDecodeUnit(DecodeUnit decodeUnit, int inputBufferIndex) {
long timestampUs = System.currentTimeMillis() * 1000; long timestampUs = System.currentTimeMillis() * 1000;
if (timestampUs <= lastTimestampUs) { if (timestampUs <= lastTimestampUs) {
// We can't submit multiple buffers with the same timestamp // We can't submit multiple buffers with the same timestamp
@ -433,8 +443,7 @@ public class MediaCodecDecoderRenderer extends EnhancedDecoderRenderer {
} }
lastTimestampUs = timestampUs; lastTimestampUs = timestampUs;
// Clear old input data ByteBuffer buf = getEmptyInputBuffer(inputBufferIndex);
buf.clear();
int codecFlags = 0; int codecFlags = 0;
int decodeUnitFlags = decodeUnit.getFlags(); int decodeUnitFlags = decodeUnit.getFlags();
@ -582,7 +591,7 @@ public class MediaCodecDecoderRenderer extends EnhancedDecoderRenderer {
private void replaySps() { private void replaySps() {
int inputIndex = dequeueInputBuffer(true, true); int inputIndex = dequeueInputBuffer(true, true);
ByteBuffer inputBuffer = videoDecoderInputBuffers[inputIndex]; ByteBuffer inputBuffer = getEmptyInputBuffer(inputIndex);
inputBuffer.clear(); inputBuffer.clear();
@ -666,7 +675,7 @@ public class MediaCodecDecoderRenderer extends EnhancedDecoderRenderer {
} }
if (inputIndex >= 0) { if (inputIndex >= 0) {
submitDecodeUnit(du, videoDecoderInputBuffers[inputIndex], inputIndex); submitDecodeUnit(du, inputIndex);
} }
} }