Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(23)

Side by Side Diff: media/base/android/java/src/org/chromium/media/MediaCodecBridge.java

Issue 1254293003: MediaCodecPlayer implementation (stage 4 - preroll) (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@mtplayer-browserseek
Patch Set: Added unit test for video-only preroll Created 5 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 package org.chromium.media; 5 package org.chromium.media;
6 6
7 import android.annotation.TargetApi; 7 import android.annotation.TargetApi;
8 import android.media.AudioFormat; 8 import android.media.AudioFormat;
9 import android.media.AudioManager; 9 import android.media.AudioManager;
10 import android.media.AudioTrack; 10 import android.media.AudioTrack;
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
67 private static final String KEY_CROP_LEFT = "crop-left"; 67 private static final String KEY_CROP_LEFT = "crop-left";
68 private static final String KEY_CROP_RIGHT = "crop-right"; 68 private static final String KEY_CROP_RIGHT = "crop-right";
69 private static final String KEY_CROP_BOTTOM = "crop-bottom"; 69 private static final String KEY_CROP_BOTTOM = "crop-bottom";
70 private static final String KEY_CROP_TOP = "crop-top"; 70 private static final String KEY_CROP_TOP = "crop-top";
71 71
72 private ByteBuffer[] mInputBuffers; 72 private ByteBuffer[] mInputBuffers;
73 private ByteBuffer[] mOutputBuffers; 73 private ByteBuffer[] mOutputBuffers;
74 74
75 private MediaCodec mMediaCodec; 75 private MediaCodec mMediaCodec;
76 private AudioTrack mAudioTrack; 76 private AudioTrack mAudioTrack;
77 private ArrayList<byte[]> mPendingAudioBuffers;
77 private boolean mFlushed; 78 private boolean mFlushed;
78 private long mLastPresentationTimeUs; 79 private long mLastPresentationTimeUs;
79 private String mMime; 80 private String mMime;
80 private boolean mAdaptivePlaybackSupported; 81 private boolean mAdaptivePlaybackSupported;
81 82
82 private static class DequeueInputResult { 83 private static class DequeueInputResult {
83 private final int mStatus; 84 private final int mStatus;
84 private final int mIndex; 85 private final int mIndex;
85 86
86 private DequeueInputResult(int status, int index) { 87 private DequeueInputResult(int status, int index) {
(...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after
295 } 296 }
296 } 297 }
297 298
298 return null; 299 return null;
299 } 300 }
300 301
301 private MediaCodecBridge( 302 private MediaCodecBridge(
302 MediaCodec mediaCodec, String mime, boolean adaptivePlaybackSupporte d) { 303 MediaCodec mediaCodec, String mime, boolean adaptivePlaybackSupporte d) {
303 assert mediaCodec != null; 304 assert mediaCodec != null;
304 mMediaCodec = mediaCodec; 305 mMediaCodec = mediaCodec;
306 mPendingAudioBuffers = new ArrayList<byte[]>();
305 mMime = mime; 307 mMime = mime;
306 mLastPresentationTimeUs = 0; 308 mLastPresentationTimeUs = 0;
307 mFlushed = true; 309 mFlushed = true;
308 mAdaptivePlaybackSupported = adaptivePlaybackSupported; 310 mAdaptivePlaybackSupported = adaptivePlaybackSupported;
309 } 311 }
310 312
311 @CalledByNative 313 @CalledByNative
312 private static MediaCodecBridge create(String mime, boolean isSecure, int di rection) { 314 private static MediaCodecBridge create(String mime, boolean isSecure, int di rection) {
313 // Creation of ".secure" codecs sometimes crash instead of throwing exce ptions 315 // Creation of ".secure" codecs sometimes crash instead of throwing exce ptions
314 // on pre-JBMR2 devices. 316 // on pre-JBMR2 devices.
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
358 mMediaCodec.release(); 360 mMediaCodec.release();
359 } catch (IllegalStateException e) { 361 } catch (IllegalStateException e) {
360 // The MediaCodec is stuck in a wrong state, possibly due to losing 362 // The MediaCodec is stuck in a wrong state, possibly due to losing
361 // the surface. 363 // the surface.
362 Log.e(TAG, "Cannot release media codec", e); 364 Log.e(TAG, "Cannot release media codec", e);
363 } 365 }
364 mMediaCodec = null; 366 mMediaCodec = null;
365 if (mAudioTrack != null) { 367 if (mAudioTrack != null) {
366 mAudioTrack.release(); 368 mAudioTrack.release();
367 } 369 }
370 mPendingAudioBuffers.clear();
368 } 371 }
369 372
370 @SuppressWarnings("deprecation") 373 @SuppressWarnings("deprecation")
371 @CalledByNative 374 @CalledByNative
372 private boolean start() { 375 private boolean start() {
373 try { 376 try {
374 mMediaCodec.start(); 377 mMediaCodec.start();
375 if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.KITKAT) { 378 if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.KITKAT) {
376 mInputBuffers = mMediaCodec.getInputBuffers(); 379 mInputBuffers = mMediaCodec.getInputBuffers();
377 mOutputBuffers = mMediaCodec.getOutputBuffers(); 380 mOutputBuffers = mMediaCodec.getOutputBuffers();
(...skipping 28 matching lines...) Expand all
406 } 409 }
407 410
408 @CalledByNative 411 @CalledByNative
409 private int flush() { 412 private int flush() {
410 try { 413 try {
411 mFlushed = true; 414 mFlushed = true;
412 if (mAudioTrack != null) { 415 if (mAudioTrack != null) {
413 // Need to call pause() here, or otherwise flush() is a no-op. 416 // Need to call pause() here, or otherwise flush() is a no-op.
414 mAudioTrack.pause(); 417 mAudioTrack.pause();
415 mAudioTrack.flush(); 418 mAudioTrack.flush();
419 mPendingAudioBuffers.clear();
416 } 420 }
417 mMediaCodec.flush(); 421 mMediaCodec.flush();
418 } catch (IllegalStateException e) { 422 } catch (IllegalStateException e) {
419 Log.e(TAG, "Failed to flush MediaCodec", e); 423 Log.e(TAG, "Failed to flush MediaCodec", e);
420 return MEDIA_CODEC_ERROR; 424 return MEDIA_CODEC_ERROR;
421 } 425 }
422 return MEDIA_CODEC_OK; 426 return MEDIA_CODEC_OK;
423 } 427 }
424 428
425 @CalledByNative 429 @CalledByNative
(...skipping 292 matching lines...) Expand 10 before | Expand all | Expand 10 after
718 } 722 }
719 723
720 /** 724 /**
721 * Play the audio buffer that is passed in. 725 * Play the audio buffer that is passed in.
722 * 726 *
723 * @param buf Audio buffer to be rendered. 727 * @param buf Audio buffer to be rendered.
724 * @return The number of frames that have already been consumed by the 728 * @return The number of frames that have already been consumed by the
725 * hardware. This number resets to 0 after each flush call. 729 * hardware. This number resets to 0 after each flush call.
726 */ 730 */
727 @CalledByNative 731 @CalledByNative
728 private long playOutputBuffer(byte[] buf) { 732 private long playOutputBuffer(byte[] buf, boolean postpone) {
733 if (postpone) {
734 Log.v(TAG, "Saving pending buffer");
735 mPendingAudioBuffers.add(buf);
736 return 0;
737 }
738
729 if (mAudioTrack == null) { 739 if (mAudioTrack == null) {
730 return 0; 740 return 0;
731 } 741 }
732 742
733 if (AudioTrack.PLAYSTATE_PLAYING != mAudioTrack.getPlayState()) { 743 if (AudioTrack.PLAYSTATE_PLAYING != mAudioTrack.getPlayState()) {
734 mAudioTrack.play(); 744 mAudioTrack.play();
735 } 745 }
736 int size = mAudioTrack.write(buf, 0, buf.length); 746
747 int size = 0;
748 for (byte[] pbuf : mPendingAudioBuffers) {
749 Log.v(TAG, "Writing pending buffer");
750 size = mAudioTrack.write(pbuf, 0, pbuf.length);
751 if (pbuf.length != size) {
752 Log.i(TAG, "Failed to send all data to audio output, expected si ze: " + pbuf.length
753 + ", actual size: " + size);
754 }
755 }
756
757 mPendingAudioBuffers.clear();
758
759 size = mAudioTrack.write(buf, 0, buf.length);
737 if (buf.length != size) { 760 if (buf.length != size) {
738 Log.i(TAG, "Failed to send all data to audio output, expected size: " 761 Log.i(TAG, "Failed to send all data to audio output, expected size: "
739 + buf.length + ", actual size: " + size); 762 + buf.length + ", actual size: " + size);
740 } 763 }
741 // TODO(qinmin): Returning the head position allows us to estimate 764 // TODO(qinmin): Returning the head position allows us to estimate
742 // the current presentation time in native code. However, it is 765 // the current presentation time in native code. However, it is
743 // better to use AudioTrack.getCurrentTimestamp() to get the last 766 // better to use AudioTrack.getCurrentTimestamp() to get the last
744 // known time when a frame is played. However, we will need to 767 // known time when a frame is played. However, we will need to
745 // convert the java nano time to C++ timestamp. 768 // convert the java nano time to C++ timestamp.
746 // If the stream runs too long, getPlaybackHeadPosition() could 769 // If the stream runs too long, getPlaybackHeadPosition() could
(...skipping 28 matching lines...) Expand all
775 return AudioFormat.CHANNEL_OUT_QUAD; 798 return AudioFormat.CHANNEL_OUT_QUAD;
776 case 6: 799 case 6:
777 return AudioFormat.CHANNEL_OUT_5POINT1; 800 return AudioFormat.CHANNEL_OUT_5POINT1;
778 case 8: 801 case 8:
779 return AudioFormat.CHANNEL_OUT_7POINT1; 802 return AudioFormat.CHANNEL_OUT_7POINT1;
780 default: 803 default:
781 return AudioFormat.CHANNEL_OUT_DEFAULT; 804 return AudioFormat.CHANNEL_OUT_DEFAULT;
782 } 805 }
783 } 806 }
784 } 807 }
OLDNEW
« no previous file with comments | « no previous file | media/base/android/media_codec_audio_decoder.h » ('j') | media/base/android/media_codec_audio_decoder.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698