| Index: media/base/android/java/src/org/chromium/media/MediaCodecBridge.java
|
| diff --git a/media/base/android/java/src/org/chromium/media/MediaCodecBridge.java b/media/base/android/java/src/org/chromium/media/MediaCodecBridge.java
|
| index 0433a471ab7761edb371034623150fee010660fd..c639d4b634b5a085b466afce2f2d04a753f9f74e 100644
|
| --- a/media/base/android/java/src/org/chromium/media/MediaCodecBridge.java
|
| +++ b/media/base/android/java/src/org/chromium/media/MediaCodecBridge.java
|
| @@ -74,6 +74,7 @@ class MediaCodecBridge {
|
|
|
| private MediaCodec mMediaCodec;
|
| private AudioTrack mAudioTrack;
|
| + private byte[] mPendingAudioBuffer;
|
| private boolean mFlushed;
|
| private long mLastPresentationTimeUs;
|
| private String mMime;
|
| @@ -302,6 +303,7 @@ class MediaCodecBridge {
|
| MediaCodec mediaCodec, String mime, boolean adaptivePlaybackSupported) {
|
| assert mediaCodec != null;
|
| mMediaCodec = mediaCodec;
|
| + mPendingAudioBuffer = null;
|
| mMime = mime;
|
| mLastPresentationTimeUs = 0;
|
| mFlushed = true;
|
| @@ -366,6 +368,7 @@ class MediaCodecBridge {
|
| if (mAudioTrack != null) {
|
| mAudioTrack.release();
|
| }
|
| + mPendingAudioBuffer = null;
|
| }
|
|
|
| @SuppressWarnings("deprecation")
|
| @@ -413,6 +416,7 @@ class MediaCodecBridge {
|
| // Need to call pause() here, or otherwise flush() is a no-op.
|
| mAudioTrack.pause();
|
| mAudioTrack.flush();
|
| + mPendingAudioBuffer = null;
|
| }
|
| mMediaCodec.flush();
|
| } catch (IllegalStateException e) {
|
| @@ -722,19 +726,39 @@ class MediaCodecBridge {
|
| * Play the audio buffer that is passed in.
|
| *
|
| * @param buf Audio buffer to be rendered.
|
| + * @param postpone If true, save audio buffer for playback with the next
|
| + * audio buffer. Must be followed by playOutputBuffer() without postpone,
|
| + * flush() or release().
|
| * @return The number of frames that have already been consumed by the
|
| * hardware. This number resets to 0 after each flush call.
|
| */
|
| @CalledByNative
|
| - private long playOutputBuffer(byte[] buf) {
|
| + private long playOutputBuffer(byte[] buf, boolean postpone) {
|
| if (mAudioTrack == null) {
|
| return 0;
|
| }
|
|
|
| + if (postpone) {
|
| + assert mPendingAudioBuffer == null;
|
| + mPendingAudioBuffer = buf;
|
| + return 0;
|
| + }
|
| +
|
| if (AudioTrack.PLAYSTATE_PLAYING != mAudioTrack.getPlayState()) {
|
| mAudioTrack.play();
|
| }
|
| - int size = mAudioTrack.write(buf, 0, buf.length);
|
| +
|
| + int size = 0;
|
| + if (mPendingAudioBuffer != null) {
|
| + size = mAudioTrack.write(mPendingAudioBuffer, 0, mPendingAudioBuffer.length);
|
| + if (mPendingAudioBuffer.length != size) {
|
| + Log.i(TAG, "Failed to send all data to audio output, expected size: "
|
| + + mPendingAudioBuffer.length + ", actual size: " + size);
|
| + }
|
| + mPendingAudioBuffer = null;
|
| + }
|
| +
|
| + size = mAudioTrack.write(buf, 0, buf.length);
|
| if (buf.length != size) {
|
| Log.i(TAG, "Failed to send all data to audio output, expected size: "
|
| + buf.length + ", actual size: " + size);
|
|
|