summaryrefslogtreecommitdiffstats
path: root/media/libstagefright/AwesomePlayer.cpp
diff options
context:
space:
mode:
authorSteve Kondik <steve@cyngn.com>2014-01-31 22:08:54 +0800
committerSteve Kondik <steve@cyngn.com>2015-11-07 12:03:16 -0800
commite79ee6494c2a1f2d3b1f1b1393ca85beee41a29d (patch)
tree26430e8fe59a53da3d0161b6123b575bef05b49e /media/libstagefright/AwesomePlayer.cpp
parent5d9ec7585ad39f73690fddbd864f3e3f5c1bde4d (diff)
downloadframeworks_av-e79ee6494c2a1f2d3b1f1b1393ca85beee41a29d.zip
frameworks_av-e79ee6494c2a1f2d3b1f1b1393ca85beee41a29d.tar.gz
frameworks_av-e79ee6494c2a1f2d3b1f1b1393ca85beee41a29d.tar.bz2
stagefright: Squashed commit of pause/resume features
Add 2 APIs (suspend/resume) in MediaPlayer - API:suspend() will just pause the player and release all the decoders to replace release() which will release the whole player - API:resume() will just init the decoders again, then start() will be called to restart streaming playback - Add a check in AwesomePlayer::onVideoEvent() to make sure the first seek operation will always seek to the next i-frame Change-Id: Ie4c82906a2a056378119921a656128ebdc1007c4 audio: Add pause support for hardware omx component - ADSP doesn't enter sleep state after wma playback is paused and power suspended. - No support for NT session pause in case of hardware component. NT session need to be paused to put ADSP into power collapse. - Add support of pause in stagefright to ensure device enters suspend mode. Also add intermediate states to avoid concurrency issues between read and pause. Change-Id: I41b946b8c8805e6ee303646b63513b5b16514ef6 libstagefright: Drain input buffer on resume - Buffers returned from codec in paused state are not drained. When codec is resumed these buffers are not drained until the next flush, and may cause timed out issue. - Added change to drain input buffers for sw decoders when resuming. Change-Id: Ida2ab1d5dc3a1910accdd6fb89548262a912d8e7 CRs-Fixed: 569585, 574967 libstagefright: camcorder pause-resume implementation - Add pause resume feature in camcorder app. So that user can pause recording and resume later which results in a single recorded clip. Change-Id: Id19c45ae5bb85265aa4d5304b160ebf119d9575a libstagefright: support pause/resume for timelapse recording Modify the timestamp calculation mechanism in CameraSourceTimeLapse in order to support pause/resume. Change-Id: Icb02ea798b0b807ffb7ada2d1ef5b2414b74edfb
Diffstat (limited to 'media/libstagefright/AwesomePlayer.cpp')
-rw-r--r--media/libstagefright/AwesomePlayer.cpp98
1 files changed, 94 insertions, 4 deletions
diff --git a/media/libstagefright/AwesomePlayer.cpp b/media/libstagefright/AwesomePlayer.cpp
index 3cd0b0e..778dfa5 100644
--- a/media/libstagefright/AwesomePlayer.cpp
+++ b/media/libstagefright/AwesomePlayer.cpp
@@ -216,7 +216,8 @@ AwesomePlayer::AwesomePlayer()
mLastVideoTimeUs(-1),
mTextDriver(NULL),
mOffloadAudio(false),
- mAudioTearDown(false) {
+ mAudioTearDown(false),
+ mIsFirstFrameAfterResume(false) {
CHECK_EQ(mClient.connect(), (status_t)OK);
DataSource::RegisterDefaultSniffers();
@@ -1804,11 +1805,18 @@ void AwesomePlayer::onVideoEvent() {
if (mSeeking != NO_SEEK) {
ALOGV("seeking to %" PRId64 " us (%.2f secs)", mSeekTimeUs, mSeekTimeUs / 1E6);
+ MediaSource::ReadOptions::SeekMode seekmode = (mSeeking == SEEK_VIDEO_ONLY)
+ ? MediaSource::ReadOptions::SEEK_NEXT_SYNC
+ : MediaSource::ReadOptions::SEEK_CLOSEST_SYNC;
+ // Seek to the next key-frame after resume for http streaming
+ if (mCachedSource != NULL && mIsFirstFrameAfterResume) {
+ seekmode = MediaSource::ReadOptions::SEEK_NEXT_SYNC;
+ mIsFirstFrameAfterResume = false;
+ }
+
options.setSeekTo(
mSeekTimeUs,
- mSeeking == SEEK_VIDEO_ONLY
- ? MediaSource::ReadOptions::SEEK_NEXT_SYNC
- : MediaSource::ReadOptions::SEEK_CLOSEST_SYNC);
+ seekmode);
}
for (;;) {
status_t err = mVideoSource->read(&mVideoBuffer, &options);
@@ -3044,4 +3052,86 @@ void AwesomePlayer::onAudioTearDownEvent() {
beginPrepareAsync_l();
}
+// suspend() will release the decoders, the renderers and the buffers allocated for decoders
+// Releasing decoders eliminates draining power in suspended state.
+status_t AwesomePlayer::suspend() {
+ ALOGV("suspend()");
+ Mutex::Autolock autoLock(mLock);
+
+ // Set PAUSE to DrmManagerClient which will be set START in play_l()
+ if (mDecryptHandle != NULL) {
+ mDrmManagerClient->setPlaybackStatus(mDecryptHandle,
+ Playback::PAUSE, 0);
+ }
+
+ cancelPlayerEvents();
+ if (mQueueStarted) {
+ mQueue.stop();
+ mQueueStarted = false;
+ }
+
+ // Shutdown audio decoder first
+ if ((mAudioPlayer == NULL || !(mFlags & AUDIOPLAYER_STARTED))
+ && mAudioSource != NULL) {
+ mAudioSource->stop();
+ }
+ mAudioSource.clear();
+ mOmxSource.clear();
+ delete mAudioPlayer;
+ mAudioPlayer = NULL;
+ modifyFlags(AUDIO_RUNNING | AUDIOPLAYER_STARTED, CLEAR);
+
+ // Shutdown the video decoder
+ mVideoRenderer.clear();
+ if (mVideoSource != NULL) {
+ shutdownVideoDecoder_l();
+ }
+ modifyFlags(PLAYING, CLEAR);
+ mVideoRenderingStarted = false;
+
+ // Disconnect the source
+ if (mCachedSource != NULL) {
+ status_t err = mCachedSource->disconnectWhileSuspend();
+ if (err != OK) {
+ return err;
+ }
+ }
+
+ return OK;
+}
+
+status_t AwesomePlayer::resume() {
+ ALOGV("resume()");
+ Mutex::Autolock autoLock(mLock);
+
+ // Reconnect the source
+ status_t err = mCachedSource->connectWhileResume();
+ if (err != OK) {
+ return err;
+ }
+
+ if (mVideoTrack != NULL && mVideoSource == NULL) {
+ status_t err = initVideoDecoder();
+ if (err != OK) {
+ return err;
+ }
+ }
+
+ if (mAudioTrack != NULL && mAudioSource == NULL) {
+ status_t err = initAudioDecoder();
+ if (err != OK) {
+ return err;
+ }
+ }
+
+ mIsFirstFrameAfterResume = true;
+
+ if (!mQueueStarted) {
+ mQueue.start();
+ mQueueStarted = true;
+ }
+
+ return OK;
+}
+
} // namespace android