From d65535053dadd02412c3ec1cb46bc66bdb1a76ac Mon Sep 17 00:00:00 2001 From: John Lin Date: Fri, 17 Mar 2017 15:06:39 +0800 Subject: [PATCH] Bug 1346235 - part 4: recycle unpopulated input samples. r=jchen MozReview-Commit-ID: Lr0aSQ0OfRg --HG-- extra : rebase_source : 71f37d29c5d3a08e63171956fa5a02e716bcec0a --- .../java/org/mozilla/gecko/media/Codec.java | 22 +++++++--- .../org/mozilla/gecko/media/CodecProxy.java | 44 +++++++++++-------- 2 files changed, 40 insertions(+), 26 deletions(-) diff --git a/mobile/android/base/java/org/mozilla/gecko/media/Codec.java b/mobile/android/base/java/org/mozilla/gecko/media/Codec.java index 58deb8ebfb7b..fa9b8ecaa3b2 100644 --- a/mobile/android/base/java/org/mozilla/gecko/media/Codec.java +++ b/mobile/android/base/java/org/mozilla/gecko/media/Codec.java @@ -66,18 +66,26 @@ import java.util.concurrent.ConcurrentLinkedQueue; private synchronized void onSample(Sample sample) { if (sample == null) { - Log.w(LOGTAG, "WARN: null input sample"); + // Ignore empty input. + mSamplePool.recycleInput(mDequeuedSamples.remove()); + Log.w(LOGTAG, "WARN: empty input sample"); return; } - if (!sample.isEOS()) { - Sample temp = sample; - sample = mDequeuedSamples.remove(); - sample.info = temp.info; - sample.cryptoInfo = temp.cryptoInfo; - temp.dispose(); + if (sample.isEOS()) { + queueSample(sample); + return; } + Sample dequeued = mDequeuedSamples.remove(); + dequeued.info = sample.info; + dequeued.cryptoInfo = sample.cryptoInfo; + queueSample(dequeued); + + sample.dispose(); + } + + private void queueSample(Sample sample) { if (!mInputSamples.offer(sample)) { reportError(Error.FATAL, new Exception("FAIL: input sample queue is full")); return; diff --git a/mobile/android/base/java/org/mozilla/gecko/media/CodecProxy.java b/mobile/android/base/java/org/mozilla/gecko/media/CodecProxy.java index b3d95015725d..765689325d17 100644 --- a/mobile/android/base/java/org/mozilla/gecko/media/CodecProxy.java +++ b/mobile/android/base/java/org/mozilla/gecko/media/CodecProxy.java @@ -170,34 +170,40 @@ public final class CodecProxy { Log.e(LOGTAG, "cannot send input to an ended codec"); return false; } + + boolean eos = info.flags == MediaCodec.BUFFER_FLAG_END_OF_STREAM; + mCallbacks.setEndOfInput(eos); + + if (eos) { + return sendInput(Sample.EOS); + } + + try { + return sendInput(mRemote.dequeueInput(info.size).set(bytes, info, cryptoInfo)); + } catch (RemoteException e) { + Log.e(LOGTAG, "fail to dequeue input buffer", e); + return false; + } catch (IOException e) { + Log.e(LOGTAG, "fail to copy input data.", e); + // Balance dequeue/queue. + return sendInput(null); + } + } + + private boolean sendInput(Sample sample) { try { - Sample sample = processInput(bytes, info, cryptoInfo); - if (sample == null) { - return false; - } mRemote.queueInput(sample); - sample.dispose(); + if (sample != null) { + sample.dispose(); + } } catch (Exception e) { - Log.e(LOGTAG, "fail to input sample: size=" + info.size + - ", pts=" + info.presentationTimeUs + - ", flags=" + Integer.toHexString(info.flags), e); + Log.e(LOGTAG, "fail to queue input:" + sample, e); return false; } return true; } - private Sample processInput(ByteBuffer bytes, BufferInfo info, CryptoInfo cryptoInfo) - throws RemoteException, IOException { - if (info.flags == MediaCodec.BUFFER_FLAG_END_OF_STREAM) { - mCallbacks.setEndOfInput(true); - return Sample.EOS; - } else { - mCallbacks.setEndOfInput(false); - return mRemote.dequeueInput(info.size).set(bytes, info, cryptoInfo); - } - } - @WrapForJNI public synchronized boolean flush() { if (mRemote == null) {