Backed out changeset b7cdc8cfc61f (bug 1353459) for android test failures
authorCarsten "Tomcat" Book <cbook@mozilla.com>
Tue, 18 Apr 2017 10:50:45 +0200
changeset 375964 665b9de58dee
parent 375963 4b43e1c02d4f
child 375965 bd935f8a9fee
push id11068
push usercbook@mozilla.com
push dateTue, 18 Apr 2017 08:51:03 +0000
treeherdermozilla-aurora@665b9de58dee [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs1353459
milestone54.0a2
backs outb7cdc8cfc61f
Backed out changeset b7cdc8cfc61f (bug 1353459) for android test failures
mobile/android/geckoview/src/main/java/org/mozilla/gecko/media/Codec.java
mobile/android/geckoview/src/main/java/org/mozilla/gecko/media/CodecProxy.java
deleted file mode 100644
--- a/mobile/android/geckoview/src/main/java/org/mozilla/gecko/media/Codec.java
+++ /dev/null
@@ -1,551 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-package org.mozilla.gecko.media;
-
-import android.media.MediaCodec;
-import android.media.MediaCodecInfo;
-import android.media.MediaCodecList;
-import android.media.MediaCrypto;
-import android.media.MediaFormat;
-import android.os.IBinder;
-import android.os.RemoteException;
-import android.util.Log;
-import android.view.Surface;
-
-import java.io.IOException;
-import java.nio.ByteBuffer;
-import java.util.LinkedList;
-import java.util.Queue;
-import java.util.concurrent.ConcurrentLinkedQueue;
-
-/* package */ final class Codec extends ICodec.Stub implements IBinder.DeathRecipient {
-    private static final String LOGTAG = "GeckoRemoteCodec";
-    private static final boolean DEBUG = false;
-
-    public enum Error {
-        DECODE, FATAL
-    }
-
-    private final class Callbacks implements AsyncCodec.Callbacks {
-        @Override
-        public void onInputBufferAvailable(AsyncCodec codec, int index) {
-            mInputProcessor.onBuffer(index);
-        }
-
-        @Override
-        public void onOutputBufferAvailable(AsyncCodec codec, int index, MediaCodec.BufferInfo info) {
-            mOutputProcessor.onBuffer(index, info);
-        }
-
-        @Override
-        public void onError(AsyncCodec codec, int error) {
-            reportError(Error.FATAL, new Exception("codec error:" + error));
-        }
-
-        @Override
-        public void onOutputFormatChanged(AsyncCodec codec, MediaFormat format) {
-            mOutputProcessor.onFormatChanged(format);
-        }
-    }
-
-    private static final class Input {
-        public final Sample sample;
-        public boolean reported;
-
-        public Input(final Sample sample) {
-            this.sample = sample;
-        }
-    }
-
-    private final class InputProcessor {
-        private boolean mHasInputCapacitySet;
-        private Queue<Integer> mAvailableInputBuffers = new LinkedList<>();
-        private Queue<Sample> mDequeuedSamples = new LinkedList<>();
-        private Queue<Input> mInputSamples = new LinkedList<>();
-        private boolean mStopped;
-
-        private synchronized Sample onAllocate(int size) {
-            Sample sample = mSamplePool.obtainInput(size);
-            mDequeuedSamples.add(sample);
-            return sample;
-        }
-
-        private synchronized void onSample(Sample sample) {
-            if (sample == null) {
-                // Ignore empty input.
-                mSamplePool.recycleInput(mDequeuedSamples.remove());
-                Log.w(LOGTAG, "WARN: empty input sample");
-                return;
-            }
-
-            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(new Input(sample))) {
-                reportError(Error.FATAL, new Exception("FAIL: input sample queue is full"));
-                return;
-            }
-
-            try {
-                feedSampleToBuffer();
-            } catch (Exception e) {
-                reportError(Error.FATAL, e);
-            }
-        }
-
-        private synchronized void onBuffer(int index) {
-            if (mStopped) {
-                return;
-            }
-
-            if (!mHasInputCapacitySet) {
-                int capacity = mCodec.getInputBuffer(index).capacity();
-                if (capacity > 0) {
-                    mSamplePool.setInputBufferSize(capacity);
-                    mHasInputCapacitySet = true;
-                }
-            }
-
-            if (mAvailableInputBuffers.offer(index)) {
-                feedSampleToBuffer();
-            } else {
-                reportError(Error.FATAL, new Exception("FAIL: input buffer queue is full"));
-            }
-
-        }
-
-        private void feedSampleToBuffer() {
-            while (!mAvailableInputBuffers.isEmpty() && !mInputSamples.isEmpty()) {
-                int index = mAvailableInputBuffers.poll();
-                int len = 0;
-                final Sample sample = mInputSamples.poll().sample;
-                long pts = sample.info.presentationTimeUs;
-                int flags = sample.info.flags;
-                MediaCodec.CryptoInfo cryptoInfo = sample.cryptoInfo;
-                if (!sample.isEOS() && sample.buffer != null) {
-                    len = sample.info.size;
-                    ByteBuffer buf = mCodec.getInputBuffer(index);
-                    try {
-                        sample.writeToByteBuffer(buf);
-                    } catch (IOException e) {
-                        e.printStackTrace();
-                        len = 0;
-                    }
-                    mSamplePool.recycleInput(sample);
-                }
-
-                try {
-                    if (cryptoInfo != null && len > 0) {
-                        mCodec.queueSecureInputBuffer(index, 0, cryptoInfo, pts, flags);
-                    } else {
-                        mCodec.queueInputBuffer(index, 0, len, pts, flags);
-                    }
-                    mCallbacks.onInputQueued(pts);
-                } catch (RemoteException e) {
-                    e.printStackTrace();
-                } catch (Exception e) {
-                    reportError(Error.FATAL, e);
-                    return;
-                }
-            }
-            reportPendingInputs();
-        }
-
-        private void reportPendingInputs() {
-            try {
-                for (Input i : mInputSamples) {
-                    if (!i.reported) {
-                        i.reported = true;
-                        mCallbacks.onInputPending(i.sample.info.presentationTimeUs);
-                    }
-                }
-            } catch (RemoteException e) {
-                e.printStackTrace();
-            }
-        }
-
-        private synchronized void reset() {
-            for (Input i : mInputSamples) {
-                if (!i.sample.isEOS()) {
-                    mSamplePool.recycleInput(i.sample);
-                }
-            }
-            mInputSamples.clear();
-
-            for (Sample s : mDequeuedSamples) {
-                mSamplePool.recycleInput(s);
-            }
-            mDequeuedSamples.clear();
-
-            mAvailableInputBuffers.clear();
-        }
-
-        private synchronized void start() {
-            if (!mStopped) {
-                return;
-            }
-            mStopped = false;
-        }
-
-        private synchronized void stop() {
-            if (mStopped) {
-                return;
-            }
-            mStopped = true;
-            reset();
-        }
-    }
-
-    private static final class Output {
-        public final Sample sample;
-        public final int index;
-
-        public Output(final Sample sample, int index) {
-            this.sample = sample;
-            this.index = index;
-        }
-    }
-
-    private class OutputProcessor {
-        private final boolean mRenderToSurface;
-        private boolean mHasOutputCapacitySet;
-        private Queue<Output> mSentOutputs = new LinkedList<>();
-        private boolean mStopped;
-
-        private OutputProcessor(boolean renderToSurface) {
-            mRenderToSurface = renderToSurface;
-        }
-
-        private synchronized void onBuffer(int index, MediaCodec.BufferInfo info) {
-            if (mStopped) {
-                return;
-            }
-
-            try {
-                Sample output = obtainOutputSample(index, info);
-                mSentOutputs.add(new Output(output, index));
-                mCallbacks.onOutput(output);
-            } catch (Exception e) {
-                e.printStackTrace();
-                mCodec.releaseOutputBuffer(index, false);
-            }
-
-            boolean eos = (info.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0;
-            if (DEBUG && eos) {
-                Log.d(LOGTAG, "output EOS");
-            }
-        }
-
-        private Sample obtainOutputSample(int index, MediaCodec.BufferInfo info) {
-            Sample sample = mSamplePool.obtainOutput(info);
-
-            if (mRenderToSurface) {
-                return sample;
-            }
-
-            ByteBuffer output = mCodec.getOutputBuffer(index);
-            if (!mHasOutputCapacitySet) {
-                int capacity = output.capacity();
-                if (capacity > 0) {
-                    mSamplePool.setOutputBufferSize(capacity);
-                    mHasOutputCapacitySet = true;
-                }
-            }
-
-            if (info.size > 0) {
-                try {
-                    sample.buffer.readFromByteBuffer(output, info.offset, info.size);
-                } catch (IOException e) {
-                    Log.e(LOGTAG, "Fail to read output buffer:" + e.getMessage());
-                }
-            }
-
-            return sample;
-        }
-
-        private synchronized void onRelease(Sample sample, boolean render) {
-            final Output output = mSentOutputs.poll();
-            if (output == null) {
-                if (DEBUG) { Log.d(LOGTAG, sample + " already released"); }
-                return;
-            }
-            mCodec.releaseOutputBuffer(output.index, render);
-            mSamplePool.recycleOutput(output.sample);
-
-            sample.dispose();
-        }
-
-        private void onFormatChanged(MediaFormat format) {
-            try {
-                mCallbacks.onOutputFormatChanged(new FormatParam(format));
-            } catch (RemoteException re) {
-                // Dead recipient.
-                re.printStackTrace();
-            }
-        }
-
-        private synchronized void reset() {
-            for (final Output o : mSentOutputs) {
-                mCodec.releaseOutputBuffer(o.index, false);
-                mSamplePool.recycleOutput(o.sample);
-            }
-            mSentOutputs.clear();
-        }
-
-        private synchronized void start() {
-            if (!mStopped) {
-                return;
-            }
-            mStopped = false;
-        }
-
-        private synchronized void stop() {
-            if (mStopped) {
-                return;
-            }
-            mStopped = true;
-            reset();
-        }
-    }
-
-    private volatile ICodecCallbacks mCallbacks;
-    private AsyncCodec mCodec;
-    private InputProcessor mInputProcessor;
-    private OutputProcessor mOutputProcessor;
-    private SamplePool mSamplePool;
-    // Value will be updated after configure called.
-    private volatile boolean mIsAdaptivePlaybackSupported = false;
-
-    public synchronized void setCallbacks(ICodecCallbacks callbacks) throws RemoteException {
-        mCallbacks = callbacks;
-        callbacks.asBinder().linkToDeath(this, 0);
-    }
-
-    // IBinder.DeathRecipient
-    @Override
-    public synchronized void binderDied() {
-        Log.e(LOGTAG, "Callbacks is dead");
-        try {
-            release();
-        } catch (RemoteException e) {
-            // Nowhere to report the error.
-        }
-    }
-
-    @Override
-    public synchronized boolean configure(FormatParam format,
-                                          Surface surface,
-                                          int flags,
-                                          String drmStubId) throws RemoteException {
-        if (mCallbacks == null) {
-            Log.e(LOGTAG, "FAIL: callbacks must be set before calling configure()");
-            return false;
-        }
-
-        if (mCodec != null) {
-            if (DEBUG) { Log.d(LOGTAG, "release existing codec: " + mCodec); }
-            releaseCodec();
-        }
-
-        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);
-
-            MediaCrypto crypto = RemoteMediaDrmBridgeStub.getMediaCrypto(drmStubId);
-            if (DEBUG) {
-                boolean hasCrypto = crypto != null;
-                Log.d(LOGTAG, "configure mediacodec with crypto(" + hasCrypto + ") / Id :" + drmStubId);
-            }
-
-            codec.setCallbacks(new Callbacks(), null);
-
-            boolean renderToSurface = surface != null;
-            // Video decoder should config with adaptive playback capability.
-            if (renderToSurface) {
-                mIsAdaptivePlaybackSupported = codec.isAdaptivePlaybackSupported(
-                                                   fmt.getString(MediaFormat.KEY_MIME));
-                if (mIsAdaptivePlaybackSupported) {
-                    if (DEBUG) { Log.d(LOGTAG, "codec supports adaptive playback  = " + mIsAdaptivePlaybackSupported); }
-                    // TODO: may need to find a way to not use hard code to decide the max w/h.
-                    fmt.setInteger(MediaFormat.KEY_MAX_WIDTH, 1920);
-                    fmt.setInteger(MediaFormat.KEY_MAX_HEIGHT, 1080);
-                }
-            }
-
-            codec.configure(fmt, surface, crypto, flags);
-            mCodec = codec;
-            mInputProcessor = new InputProcessor();
-            mOutputProcessor = new OutputProcessor(renderToSurface);
-            mSamplePool = new SamplePool(codecName, 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();
-            return false;
-        }
-    }
-
-    @Override
-    public synchronized boolean isAdaptivePlaybackSupported() {
-        return mIsAdaptivePlaybackSupported;
-    }
-
-    private void releaseCodec() {
-        try {
-            // In case Codec.stop() is not called yet.
-            mInputProcessor.stop();
-            mOutputProcessor.stop();
-
-            mCodec.release();
-        } catch (Exception e) {
-            reportError(Error.FATAL, e);
-        }
-        mCodec = null;
-    }
-
-    private String getCodecForFormat(MediaFormat format, boolean isEncoder) {
-        String mime = format.getString(MediaFormat.KEY_MIME);
-        if (mime == null) {
-            return null;
-        }
-        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();
-                }
-            }
-        }
-        return null;
-        // TODO: API 21+ is simpler.
-        //static MediaCodecList sCodecList = new MediaCodecList(MediaCodecList.ALL_CODECS);
-        //return sCodecList.findDecoderForFormat(format);
-    }
-
-    @Override
-    public synchronized void start() throws RemoteException {
-        if (DEBUG) { Log.d(LOGTAG, "start " + this); }
-        mInputProcessor.start();
-        mOutputProcessor.start();
-        try {
-            mCodec.start();
-        } catch (Exception e) {
-            reportError(Error.FATAL, e);
-        }
-    }
-
-    private void reportError(Error error, Exception e) {
-        if (e != null) {
-            e.printStackTrace();
-        }
-        try {
-            mCallbacks.onError(error == Error.FATAL);
-        } catch (RemoteException re) {
-            re.printStackTrace();
-        }
-    }
-
-    @Override
-    public synchronized void stop() throws RemoteException {
-        if (DEBUG) { Log.d(LOGTAG, "stop " + this); }
-        try {
-            mInputProcessor.stop();
-            mOutputProcessor.stop();
-
-            mCodec.stop();
-        } catch (Exception e) {
-            reportError(Error.FATAL, e);
-        }
-    }
-
-    @Override
-    public synchronized void flush() throws RemoteException {
-        if (DEBUG) { Log.d(LOGTAG, "flush " + this); }
-        try {
-            mInputProcessor.stop();
-            mOutputProcessor.stop();
-
-            mCodec.flush();
-            if (DEBUG) { Log.d(LOGTAG, "flushed " + this); }
-            mInputProcessor.start();
-            mOutputProcessor.start();
-            mCodec.resumeReceivingInputs();
-        } catch (Exception e) {
-            reportError(Error.FATAL, e);
-        }
-    }
-
-    @Override
-    public synchronized Sample dequeueInput(int size) throws RemoteException {
-        try {
-            return mInputProcessor.onAllocate(size);
-        } catch (Exception e) {
-            // Translate allocation error to remote exception.
-            throw new RemoteException(e.getMessage());
-        }
-    }
-
-    @Override
-    public synchronized void queueInput(Sample sample) throws RemoteException {
-        try {
-            mInputProcessor.onSample(sample);
-        } catch (Exception e) {
-            throw new RemoteException(e.getMessage());
-        }
-    }
-
-    @Override
-    public synchronized void setRates(int newBitRate) {
-        try {
-            mCodec.setRates(newBitRate);
-        } catch (Exception e) {
-            reportError(Error.FATAL, e);
-        }
-    }
-
-    @Override
-    public synchronized void releaseOutput(Sample sample, boolean render) {
-        try {
-            mOutputProcessor.onRelease(sample, render);
-        } catch (Exception e) {
-            reportError(Error.FATAL, e);
-        }
-    }
-
-    @Override
-    public synchronized void release() throws RemoteException {
-        if (DEBUG) { Log.d(LOGTAG, "release " + this); }
-        releaseCodec();
-        mSamplePool.reset();
-        mSamplePool = null;
-        mCallbacks.asBinder().unlinkToDeath(this, 0);
-        mCallbacks = null;
-    }
-}
deleted file mode 100644
--- a/mobile/android/geckoview/src/main/java/org/mozilla/gecko/media/CodecProxy.java
+++ /dev/null
@@ -1,326 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-package org.mozilla.gecko.media;
-
-import android.media.MediaCodec;
-import android.media.MediaCodec.BufferInfo;
-import android.media.MediaCodec.CryptoInfo;
-import android.media.MediaFormat;
-import android.os.DeadObjectException;
-import android.os.RemoteException;
-import android.util.Log;
-import android.view.Surface;
-
-import org.mozilla.gecko.annotation.WrapForJNI;
-import org.mozilla.gecko.mozglue.JNIObject;
-
-import java.io.IOException;
-import java.nio.ByteBuffer;
-import java.util.Queue;
-import java.util.concurrent.ConcurrentLinkedQueue;
-
-// Proxy class of ICodec binder.
-public final class CodecProxy {
-    private static final String LOGTAG = "GeckoRemoteCodecProxy";
-    private static final boolean DEBUG = false;
-
-    private ICodec mRemote;
-    private boolean mIsEncoder;
-    private FormatParam mFormat;
-    private Surface mOutputSurface;
-    private CallbacksForwarder mCallbacks;
-    private String mRemoteDrmStubId;
-    private Queue<Sample> mSurfaceOutputs = new ConcurrentLinkedQueue<>();
-
-    public interface Callbacks {
-        void onInputStatus(long timestamp, boolean processed);
-        void onOutputFormatChanged(MediaFormat format);
-        void onOutput(Sample output);
-        void onError(boolean fatal);
-    }
-
-    @WrapForJNI
-    public static class NativeCallbacks extends JNIObject implements Callbacks {
-        public native void onInputStatus(long timestamp, boolean processed);
-        public native void onOutputFormatChanged(MediaFormat format);
-        public native void onOutput(Sample output);
-        public native void onError(boolean fatal);
-
-        @Override // JNIObject
-        protected void disposeNative() {
-            throw new UnsupportedOperationException();
-        }
-    }
-
-    private class CallbacksForwarder extends ICodecCallbacks.Stub {
-        private final Callbacks mCallbacks;
-        private boolean mEndOfInput;
-
-        CallbacksForwarder(Callbacks callbacks) {
-            mCallbacks = callbacks;
-        }
-
-        @Override
-        public synchronized void onInputQueued(long timestamp) throws RemoteException {
-            if (!mEndOfInput) {
-                mCallbacks.onInputStatus(timestamp, true /* processed */);
-            }
-        }
-
-        @Override
-        public synchronized void onInputPending(long timestamp) throws RemoteException {
-            if (!mEndOfInput) {
-                mCallbacks.onInputStatus(timestamp, false /* processed */);
-            }
-        }
-
-        @Override
-        public void onOutputFormatChanged(FormatParam format) throws RemoteException {
-            mCallbacks.onOutputFormatChanged(format.asFormat());
-        }
-
-        @Override
-        public void onOutput(Sample sample) throws RemoteException {
-            if (mOutputSurface != null) {
-                // Don't render to surface just yet. Callback will make that happen when it's time.
-                mSurfaceOutputs.offer(sample);
-                mCallbacks.onOutput(sample);
-            } else {
-                // Non-surface output needs no rendering.
-                mCallbacks.onOutput(sample);
-                mRemote.releaseOutput(sample, false);
-                sample.dispose();
-            }
-        }
-
-        @Override
-        public void onError(boolean fatal) throws RemoteException {
-            reportError(fatal);
-        }
-
-        private void reportError(boolean fatal) {
-            mCallbacks.onError(fatal);
-        }
-
-        private void setEndOfInput(boolean end) {
-            mEndOfInput = end;
-        }
-    }
-
-    @WrapForJNI
-    public static CodecProxy create(boolean isEncoder,
-                                    MediaFormat format,
-                                    Surface surface,
-                                    Callbacks callbacks,
-                                    String drmStubId) {
-        return RemoteManager.getInstance().createCodec(isEncoder, format, surface, callbacks, drmStubId);
-    }
-
-    public static CodecProxy createCodecProxy(boolean isEncoder,
-                                              MediaFormat format,
-                                              Surface surface,
-                                              Callbacks callbacks,
-                                              String drmStubId) {
-        return new CodecProxy(isEncoder, format, surface, callbacks, drmStubId);
-    }
-
-    private CodecProxy(boolean isEncoder, MediaFormat format, Surface surface, Callbacks callbacks, String drmStubId) {
-        mIsEncoder = isEncoder;
-        mFormat = new FormatParam(format);
-        mOutputSurface = surface;
-        mRemoteDrmStubId = drmStubId;
-        mCallbacks = new CallbacksForwarder(callbacks);
-    }
-
-    boolean init(ICodec remote) {
-        try {
-            remote.setCallbacks(mCallbacks);
-            if (!remote.configure(mFormat, mOutputSurface, mIsEncoder ? MediaCodec.CONFIGURE_FLAG_ENCODE : 0, mRemoteDrmStubId)) {
-                return false;
-            }
-            remote.start();
-        } catch (RemoteException e) {
-            e.printStackTrace();
-            return false;
-        }
-
-        mRemote = remote;
-        return true;
-    }
-
-    boolean deinit() {
-        try {
-            mRemote.stop();
-            mRemote.release();
-            mRemote = null;
-            return true;
-        } catch (RemoteException e) {
-            e.printStackTrace();
-            return false;
-        }
-    }
-
-    @WrapForJNI
-    public synchronized boolean isAdaptivePlaybackSupported()
-    {
-      if (mRemote == null) {
-          Log.e(LOGTAG, "cannot check isAdaptivePlaybackSupported with an ended codec");
-          return false;
-      }
-      try {
-            return mRemote.isAdaptivePlaybackSupported();
-        } catch (RemoteException e) {
-            e.printStackTrace();
-            return false;
-        }
-    }
-
-    @WrapForJNI
-    public synchronized boolean input(ByteBuffer bytes, BufferInfo info, CryptoInfo cryptoInfo) {
-        if (mRemote == null) {
-            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 | NullPointerException 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 {
-            mRemote.queueInput(sample);
-            if (sample != null) {
-                sample.dispose();
-            }
-        } catch (Exception e) {
-            Log.e(LOGTAG, "fail to queue input:" + sample, e);
-            return false;
-        }
-
-        return true;
-    }
-
-    @WrapForJNI
-    public synchronized boolean flush() {
-        if (mRemote == null) {
-            Log.e(LOGTAG, "cannot flush an ended codec");
-            return false;
-        }
-        try {
-            if (DEBUG) { Log.d(LOGTAG, "flush " + this); }
-            mRemote.flush();
-        } catch (DeadObjectException e) {
-            return false;
-        } catch (RemoteException e) {
-            e.printStackTrace();
-            return false;
-        }
-        return true;
-    }
-
-    @WrapForJNI
-    public synchronized boolean release() {
-        if (mRemote == null) {
-            Log.w(LOGTAG, "codec already ended");
-            return true;
-        }
-        if (DEBUG) { Log.d(LOGTAG, "release " + this); }
-
-        if (!mSurfaceOutputs.isEmpty()) {
-            // Flushing output buffers to surface may cause some frames to be skipped and
-            // should not happen unless caller release codec before processing all buffers.
-            Log.w(LOGTAG, "release codec when " + mSurfaceOutputs.size() + " output buffers unhandled");
-            try {
-                for (Sample s : mSurfaceOutputs) {
-                    mRemote.releaseOutput(s, true);
-                }
-            } catch (RemoteException e) {
-                e.printStackTrace();
-            }
-            mSurfaceOutputs.clear();
-        }
-
-        try {
-            RemoteManager.getInstance().releaseCodec(this);
-        } catch (DeadObjectException e) {
-            return false;
-        } catch (RemoteException e) {
-            e.printStackTrace();
-            return false;
-        }
-        return true;
-    }
-
-    @WrapForJNI
-    public synchronized boolean setRates(int newBitRate) {
-        if (!mIsEncoder) {
-            Log.w(LOGTAG, "this api is encoder-only");
-            return false;
-        }
-
-        if (android.os.Build.VERSION.SDK_INT < 19) {
-            Log.w(LOGTAG, "this api was added in API level 19");
-            return false;
-        }
-
-        if (mRemote == null) {
-            Log.w(LOGTAG, "codec already ended");
-            return true;
-        }
-
-        try {
-            mRemote.setRates(newBitRate);
-        } catch (RemoteException e) {
-            Log.e(LOGTAG, "remote fail to set rates:" + newBitRate);
-            e.printStackTrace();
-        }
-        return true;
-    }
-
-    @WrapForJNI
-    public synchronized boolean releaseOutput(Sample sample, boolean render) {
-        if (!mSurfaceOutputs.remove(sample)) {
-            if (mRemote != null) Log.w(LOGTAG, "already released: " + sample);
-            return true;
-        }
-
-        if (mRemote == null) {
-            Log.w(LOGTAG, "codec already ended");
-            sample.dispose();
-            return true;
-        }
-
-        if (DEBUG && !render) { Log.d(LOGTAG, "drop output:" + sample.info.presentationTimeUs); }
-
-        try {
-            mRemote.releaseOutput(sample, render);
-        } catch (RemoteException e) {
-            Log.e(LOGTAG, "remote fail to render output:" + sample.info.presentationTimeUs);
-            e.printStackTrace();
-        }
-        sample.dispose();
-
-        return true;
-    }
-
-    /* package */ void reportError(boolean fatal) {
-        mCallbacks.reportError(fatal);
-    }
-}