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); |