@Override public void start() { MediaPlayerDataSource restartWithThisDataSource = null; synchronized (lock) { check(!mHasBeenReleased, "has been released, reset before use"); check(mIsPrepared, "must have prepared before you can start"); if (!mHasStartedPlayback) { // Playback has not started. Start it. mHasStartedPlayback = true; EngineParameters engineParameters = new EngineParameters.Builder() .initialRate(mCurrentPlaybackRate) .startPositionMillis(mStartPosition) .audioStreamType(mAudioStreamType) /// M: add more buffer to smooth audio ALPS00712496 and ALPS00723581 @{ .maxPlayBufferCount(8) .decodeBufferMaxSize(40960) /// @} .build(); VariableSpeedNative.initializeEngine(engineParameters); VariableSpeedNative.startPlayback(); mEngineInitializedLatch.countDown(); mExecutor.execute(new PlaybackRunnable(mDataSource)); } else { // Playback has already started. Restart it, without holding the // lock. restartWithThisDataSource = mDataSource; } } if (restartWithThisDataSource != null) { stopAndStartPlayingAgain(restartWithThisDataSource); } }
private VariableSpeed(Executor executor) throws UnsupportedOperationException { Preconditions.checkNotNull(executor); mExecutor = executor; try { VariableSpeedNative.loadLibrary(); } catch (UnsatisfiedLinkError e) { throw new UnsupportedOperationException("could not load library", e); } catch (SecurityException e) { throw new UnsupportedOperationException("could not load library", e); } reset(); }
public void setVariableSpeed(float rate) { // TODO: are there situations in which the engine has been destroyed, so // that this will segfault? synchronized (lock) { check(!mHasBeenReleased, "has been released, reset before use"); // TODO: This too is wrong, once we've started preparing the variable speed set // will not be enough. if (mHasStartedPlayback) { VariableSpeedNative.setVariableSpeed(rate); } mCurrentPlaybackRate = rate; } }
@Override public int getCurrentPosition() { synchronized (lock) { check(!mHasBeenReleased, "has been released, reset before use"); if (!mHasStartedPlayback) { return 0; } if (!hasEngineBeenInitialized()) { return 0; } if (!hasPlaybackFinished()) { return VariableSpeedNative.getCurrentPosition(); } return mDuration; } }
/** Stops the current playback, returns once it has stopped. */ private void stopCurrentPlayback() { boolean isPlaying; CountDownLatch engineInitializedLatch; CountDownLatch playbackFinishedLatch; synchronized (lock) { isPlaying = mHasStartedPlayback && !hasPlaybackFinished(); engineInitializedLatch = mEngineInitializedLatch; playbackFinishedLatch = mPlaybackFinishedLatch; if (isPlaying) { mSkipCompletionReport = true; } } if (isPlaying) { waitForLatch(engineInitializedLatch); VariableSpeedNative.stopPlayback(); waitForLatch(playbackFinishedLatch); } }
@Override public void release() { synchronized (lock) { if (mHasBeenReleased) { return; } mHasBeenReleased = true; } stopCurrentPlayback(); boolean requiresShutdown = false; synchronized (lock) { requiresShutdown = hasEngineBeenInitialized(); } if (requiresShutdown) { VariableSpeedNative.shutdownEngine(); } synchronized (lock) { mIsReadyToReUse = true; } }