Bug 1350279 - try other codecs when first one failed to create. r=esawin

Video fails to play on Sony Z3C when the media server is in a state that no hardware codec can be created unless reboot. Fallback to software codec when that happens to workaround the issue.

MozReview-Commit-ID: AaRIw7KPaF3

--HG--
extra : rebase_source : d5106d5c75c4430450a81bbe9cfd536f01ef4df9
This commit is contained in:
John Lin 2017-05-02 15:52:45 +08:00
Родитель 00a44a2499
Коммит 89eafb3c7e
1 изменённых файлов: 20 добавлений и 21 удалений

Просмотреть файл

@ -321,6 +321,7 @@ import java.util.concurrent.ConcurrentLinkedQueue;
}
}
private String mName;
private volatile ICodecCallbacks mCallbacks;
private AsyncCodec mCodec;
private InputProcessor mInputProcessor;
@ -362,16 +363,9 @@ import java.util.concurrent.ConcurrentLinkedQueue;
if (DEBUG) { Log.d(LOGTAG, "configure " + this); }
MediaFormat fmt = format.asFormat();
String codecName = getCodecForFormat(fmt, flags == MediaCodec.CONFIGURE_FLAG_ENCODE ? true : false);
if (codecName == null) {
Log.e(LOGTAG, "FAIL: cannot find codec");
return false;
}
try {
AsyncCodec codec = AsyncCodecFactory.create(codecName);
MediaFormat fmt = format.asFormat();
AsyncCodec codec = createCodecForFormat(fmt, flags == MediaCodec.CONFIGURE_FLAG_ENCODE ? true : false);
MediaCrypto crypto = RemoteMediaDrmBridgeStub.getMediaCrypto(drmStubId);
if (DEBUG) {
boolean hasCrypto = crypto != null;
@ -397,12 +391,11 @@ import java.util.concurrent.ConcurrentLinkedQueue;
mCodec = codec;
mInputProcessor = new InputProcessor();
mOutputProcessor = new OutputProcessor(renderToSurface);
mSamplePool = new SamplePool(codecName, renderToSurface);
mSamplePool = new SamplePool(mName, renderToSurface);
if (DEBUG) { Log.d(LOGTAG, codec.toString() + " created. Render to surface?" + renderToSurface); }
return true;
} catch (Exception e) {
Log.e(LOGTAG, "FAIL: cannot create codec -- " + codecName);
e.printStackTrace();
Log.e(LOGTAG, "codec creation error", e);
return false;
}
}
@ -425,28 +418,34 @@ import java.util.concurrent.ConcurrentLinkedQueue;
mCodec = null;
}
private String getCodecForFormat(MediaFormat format, boolean isEncoder) {
private AsyncCodec createCodecForFormat(MediaFormat format, boolean isEncoder) throws IOException {
String mime = format.getString(MediaFormat.KEY_MIME);
if (mime == null) {
return null;
if (mime == null || mime.isEmpty()) {
throw new IllegalArgumentException("invalid MIME type: " + mime);
}
int numCodecs = MediaCodecList.getCodecCount();
for (int i = 0; i < numCodecs; i++) {
MediaCodecInfo info = MediaCodecList.getCodecInfoAt(i);
if (info.isEncoder() == !isEncoder) {
continue;
}
String[] types = info.getSupportedTypes();
for (String t : types) {
if (t.equalsIgnoreCase(mime)) {
return info.getName();
if (!t.equalsIgnoreCase(mime)) {
continue;
}
try {
AsyncCodec codec = AsyncCodecFactory.create(info.getName());
mName = info.getName();
return codec;
} catch (IllegalArgumentException e) {
Log.w(LOGTAG, "unable to create " + info.getName() + ". Try next codec.");
}
}
}
return null;
// TODO: API 21+ is simpler.
//static MediaCodecList sCodecList = new MediaCodecList(MediaCodecList.ALL_CODECS);
//return sCodecList.findDecoderForFormat(format);
throw new RuntimeException("cannot create codec for " + mime);
}
@Override