Fixes for Android L and some weird codec exceptions

This commit is contained in:
Cameron Gutman 2014-06-29 11:49:42 -07:00
parent 37cf572c0c
commit 7142db3fac
5 changed files with 39 additions and 24 deletions

Binary file not shown.

View File

@ -14,7 +14,7 @@ public class AndroidAudioRenderer implements AudioRenderer {
private AudioTrack track; private AudioTrack track;
@Override @Override
public void streamInitialized(int channelCount, int sampleRate) { public boolean streamInitialized(int channelCount, int sampleRate) {
int channelConfig; int channelConfig;
int bufferSize; int bufferSize;
@ -27,7 +27,8 @@ public class AndroidAudioRenderer implements AudioRenderer {
channelConfig = AudioFormat.CHANNEL_OUT_STEREO; channelConfig = AudioFormat.CHANNEL_OUT_STEREO;
break; break;
default: default:
throw new IllegalArgumentException("Decoder returned unhandled channel count"); LimeLog.severe("Decoder returned unhandled channel count");
return false;
} }
bufferSize = Math.max(AudioTrack.getMinBufferSize(sampleRate, bufferSize = Math.max(AudioTrack.getMinBufferSize(sampleRate,
@ -47,6 +48,7 @@ public class AndroidAudioRenderer implements AudioRenderer {
AudioTrack.MODE_STREAM); AudioTrack.MODE_STREAM);
track.play(); track.play();
return true;
} }
@Override @Override

View File

@ -81,7 +81,7 @@ public class AndroidCpuDecoderRenderer implements VideoDecoderRenderer {
} }
@Override @Override
public void setup(int width, int height, int redrawRate, Object renderTarget, int drFlags) { public boolean setup(int width, int height, int redrawRate, Object renderTarget, int drFlags) {
this.targetFps = redrawRate; this.targetFps = redrawRate;
int perfLevel = findOptimalPerformanceLevel(); int perfLevel = findOptimalPerformanceLevel();
@ -139,10 +139,12 @@ public class AndroidCpuDecoderRenderer implements VideoDecoderRenderer {
decoderBuffer = ByteBuffer.allocate(DECODER_BUFFER_SIZE + AvcDecoder.getInputPaddingSize()); decoderBuffer = ByteBuffer.allocate(DECODER_BUFFER_SIZE + AvcDecoder.getInputPaddingSize());
LimeLog.info("Using software decoding (performance level: "+perfLevel+")"); LimeLog.info("Using software decoding (performance level: "+perfLevel+")");
return true;
} }
@Override @Override
public void start(final VideoDepacketizer depacketizer) { public boolean start(final VideoDepacketizer depacketizer) {
rendererThread = new Thread() { rendererThread = new Thread() {
@Override @Override
public void run() { public void run() {
@ -169,6 +171,7 @@ public class AndroidCpuDecoderRenderer implements VideoDecoderRenderer {
rendererThread.setName("Video - Renderer (CPU)"); rendererThread.setName("Video - Renderer (CPU)");
rendererThread.setPriority(Thread.MAX_PRIORITY); rendererThread.setPriority(Thread.MAX_PRIORITY);
rendererThread.start(); rendererThread.start();
return true;
} }
private long computePresentationTimeMs(int frameRate) { private long computePresentationTimeMs(int frameRate) {

View File

@ -13,7 +13,7 @@ public class ConfigurableDecoderRenderer implements VideoDecoderRenderer {
} }
@Override @Override
public void setup(int width, int height, int redrawRate, Object renderTarget, int drFlags) { public boolean setup(int width, int height, int redrawRate, Object renderTarget, int drFlags) {
if ((drFlags & VideoDecoderRenderer.FLAG_FORCE_HARDWARE_DECODING) != 0 || if ((drFlags & VideoDecoderRenderer.FLAG_FORCE_HARDWARE_DECODING) != 0 ||
((drFlags & VideoDecoderRenderer.FLAG_FORCE_SOFTWARE_DECODING) == 0 && ((drFlags & VideoDecoderRenderer.FLAG_FORCE_SOFTWARE_DECODING) == 0 &&
MediaCodecDecoderRenderer.findSafeDecoder() != null)) { MediaCodecDecoderRenderer.findSafeDecoder() != null)) {
@ -22,12 +22,12 @@ public class ConfigurableDecoderRenderer implements VideoDecoderRenderer {
else { else {
decoderRenderer = new AndroidCpuDecoderRenderer(); decoderRenderer = new AndroidCpuDecoderRenderer();
} }
decoderRenderer.setup(width, height, redrawRate, renderTarget, drFlags); return decoderRenderer.setup(width, height, redrawRate, renderTarget, drFlags);
} }
@Override @Override
public void start(VideoDepacketizer depacketizer) { public boolean start(VideoDepacketizer depacketizer) {
decoderRenderer.start(depacketizer); return decoderRenderer.start(depacketizer);
} }
@Override @Override

View File

@ -119,25 +119,32 @@ public class MediaCodecDecoderRenderer implements VideoDecoderRenderer {
} }
@Override @Override
public void setup(int width, int height, int redrawRate, Object renderTarget, int drFlags) { public boolean setup(int width, int height, int redrawRate, Object renderTarget, int drFlags) {
//dumpDecoders(); //dumpDecoders();
MediaCodecInfo safeDecoder = findSafeDecoder(); // It's nasty to put all this in a try-catch block,
if (safeDecoder != null) { // but codecs have been known to throw all sorts of crazy runtime exceptions
videoDecoder = MediaCodec.createByCodecName(safeDecoder.getName()); // due to implementation problems
needsSpsBitstreamFixup = isDecoderInList(spsFixupBitsreamFixupDecoderPrefixes, safeDecoder.getName()); try {
needsSpsNumRefFixup = isDecoderInList(spsFixupNumRefFixupDecoderPrefixes, safeDecoder.getName()); MediaCodecInfo safeDecoder = findSafeDecoder();
if (needsSpsBitstreamFixup) { if (safeDecoder != null) {
LimeLog.info("Decoder "+safeDecoder.getName()+" needs SPS bitstream restrictions fixup"); videoDecoder = MediaCodec.createByCodecName(safeDecoder.getName());
needsSpsBitstreamFixup = isDecoderInList(spsFixupBitsreamFixupDecoderPrefixes, safeDecoder.getName());
needsSpsNumRefFixup = isDecoderInList(spsFixupNumRefFixupDecoderPrefixes, safeDecoder.getName());
if (needsSpsBitstreamFixup) {
LimeLog.info("Decoder "+safeDecoder.getName()+" needs SPS bitstream restrictions fixup");
}
if (needsSpsNumRefFixup) {
LimeLog.info("Decoder "+safeDecoder.getName()+" needs SPS ref num fixup");
}
} }
if (needsSpsNumRefFixup) { else {
LimeLog.info("Decoder "+safeDecoder.getName()+" needs SPS ref num fixup"); videoDecoder = MediaCodec.createDecoderByType("video/avc");
needsSpsBitstreamFixup = false;
needsSpsNumRefFixup = false;
} }
} } catch (Exception e) {
else { return false;
videoDecoder = MediaCodec.createDecoderByType("video/avc");
needsSpsBitstreamFixup = false;
needsSpsNumRefFixup = false;
} }
MediaFormat videoFormat = MediaFormat.createVideoFormat("video/avc", width, height); MediaFormat videoFormat = MediaFormat.createVideoFormat("video/avc", width, height);
@ -148,6 +155,8 @@ public class MediaCodecDecoderRenderer implements VideoDecoderRenderer {
videoDecoderInputBuffers = videoDecoder.getInputBuffers(); videoDecoderInputBuffers = videoDecoder.getInputBuffers();
LimeLog.info("Using hardware decoding"); LimeLog.info("Using hardware decoding");
return true;
} }
private void startRendererThread() private void startRendererThread()
@ -198,9 +207,10 @@ public class MediaCodecDecoderRenderer implements VideoDecoderRenderer {
} }
@Override @Override
public void start(VideoDepacketizer depacketizer) { public boolean start(VideoDepacketizer depacketizer) {
this.depacketizer = depacketizer; this.depacketizer = depacketizer;
startRendererThread(); startRendererThread();
return true;
} }
@Override @Override