summaryrefslogtreecommitdiffstats
path: root/media/libmediaplayerservice
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/libmediaplayerservice
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/libmediaplayerservice')
-rw-r--r--media/libmediaplayerservice/MediaPlayerService.cpp16
-rw-r--r--media/libmediaplayerservice/MediaPlayerService.h3
-rw-r--r--media/libmediaplayerservice/MediaRecorderClient.cpp11
-rw-r--r--media/libmediaplayerservice/MediaRecorderClient.h1
-rw-r--r--media/libmediaplayerservice/StagefrightRecorder.cpp111
-rw-r--r--media/libmediaplayerservice/StagefrightRecorder.h5
6 files changed, 145 insertions, 2 deletions
diff --git a/media/libmediaplayerservice/MediaPlayerService.cpp b/media/libmediaplayerservice/MediaPlayerService.cpp
index 6e104a4..de51b3c 100644
--- a/media/libmediaplayerservice/MediaPlayerService.cpp
+++ b/media/libmediaplayerservice/MediaPlayerService.cpp
@@ -1306,6 +1306,22 @@ void MediaPlayerService::Client::addNewMetadataUpdate(media::Metadata::Type meta
}
}
+status_t MediaPlayerService::Client::suspend()
+{
+ ALOGV("[%d] suspend", mConnId);
+ sp<MediaPlayerBase> p = getPlayer();
+ if (p == NULL) return NO_INIT;
+ return p->suspend();
+}
+
+status_t MediaPlayerService::Client::resume()
+{
+ ALOGV("[%d] resume", mConnId);
+ sp<MediaPlayerBase> p = getPlayer();
+ if (p == NULL) return NO_INIT;
+ return p->resume();
+}
+
#if CALLBACK_ANTAGONIZER
const int Antagonizer::interval = 10000; // 10 msecs
diff --git a/media/libmediaplayerservice/MediaPlayerService.h b/media/libmediaplayerservice/MediaPlayerService.h
index 748b25f..ff8f550 100644
--- a/media/libmediaplayerservice/MediaPlayerService.h
+++ b/media/libmediaplayerservice/MediaPlayerService.h
@@ -334,6 +334,9 @@ private:
int getAudioSessionId() { return mAudioSessionId; }
+ virtual status_t suspend();
+ virtual status_t resume();
+
private:
friend class MediaPlayerService;
Client( const sp<MediaPlayerService>& service,
diff --git a/media/libmediaplayerservice/MediaRecorderClient.cpp b/media/libmediaplayerservice/MediaRecorderClient.cpp
index 6f242e5..1e112c8 100644
--- a/media/libmediaplayerservice/MediaRecorderClient.cpp
+++ b/media/libmediaplayerservice/MediaRecorderClient.cpp
@@ -244,6 +244,17 @@ status_t MediaRecorderClient::start()
}
+status_t MediaRecorderClient::pause()
+{
+ ALOGV("pause");
+ Mutex::Autolock lock(mLock);
+ if (mRecorder == NULL) {
+ ALOGE("recorder is not initialized");
+ return NO_INIT;
+ }
+ return mRecorder->pause();
+}
+
status_t MediaRecorderClient::stop()
{
ALOGV("stop");
diff --git a/media/libmediaplayerservice/MediaRecorderClient.h b/media/libmediaplayerservice/MediaRecorderClient.h
index 05130d4..2e77d21 100644
--- a/media/libmediaplayerservice/MediaRecorderClient.h
+++ b/media/libmediaplayerservice/MediaRecorderClient.h
@@ -49,6 +49,7 @@ public:
virtual status_t prepare();
virtual status_t getMaxAmplitude(int* max);
virtual status_t start();
+ virtual status_t pause();
virtual status_t stop();
virtual status_t reset();
virtual status_t init();
diff --git a/media/libmediaplayerservice/StagefrightRecorder.cpp b/media/libmediaplayerservice/StagefrightRecorder.cpp
index 4257b41..b1f0742 100644
--- a/media/libmediaplayerservice/StagefrightRecorder.cpp
+++ b/media/libmediaplayerservice/StagefrightRecorder.cpp
@@ -79,7 +79,8 @@ StagefrightRecorder::StagefrightRecorder(const String16 &opPackageName)
mOutputFd(-1),
mAudioSource(AUDIO_SOURCE_CNT),
mVideoSource(VIDEO_SOURCE_LIST_END),
- mStarted(false) {
+ mStarted(false),
+ mRecPaused(false) {
ALOGV("Constructor");
reset();
@@ -846,6 +847,22 @@ status_t StagefrightRecorder::start() {
return INVALID_OPERATION;
}
+ if (mRecPaused == true) {
+ status_t err = mWriter->start();
+ if (err != OK) {
+ ALOGE("Writer start in StagefrightRecorder pause failed");
+ return err;
+ }
+
+ err = setSourcePause(false);
+ if (err != OK) {
+ ALOGE("Source start after pause failed");
+ return err;
+ }
+
+ mRecPaused = false;
+ return OK;
+ }
status_t status = OK;
if (mVideoSource != VIDEO_SOURCE_SURFACE) {
@@ -1010,6 +1027,7 @@ sp<MediaSource> StagefrightRecorder::createAudioSource() {
ALOGE("Failed to create audio encoder");
}
+ mAudioEncoderOMX = audioEncoder;
return audioEncoder;
}
@@ -1625,6 +1643,8 @@ status_t StagefrightRecorder::setupVideoEncoder(
mGraphicBufferProducer = encoder->getGraphicBufferProducer();
}
+ mVideoSourceNode = cameraSource;
+ mVideoEncoderOMX = encoder;
*source = encoder;
return OK;
@@ -1759,10 +1779,23 @@ void StagefrightRecorder::setupMPEG4orWEBMMetaData(sp<MetaData> *meta) {
status_t StagefrightRecorder::pause() {
ALOGV("pause");
+ status_t err = OK;
if (mWriter == NULL) {
return UNKNOWN_ERROR;
}
- mWriter->pause();
+ err = setSourcePause(true);
+ if (err != OK) {
+ ALOGE("StagefrightRecorder pause failed");
+ return err;
+ }
+
+ err = mWriter->pause();
+ if (err != OK) {
+ ALOGE("Writer pause failed");
+ return err;
+ }
+
+ mRecPaused = true;
if (mStarted) {
mStarted = false;
@@ -1791,6 +1824,16 @@ status_t StagefrightRecorder::stop() {
mCameraSourceTimeLapse = NULL;
}
+ if (mRecPaused) {
+ status_t err = setSourcePause(false);
+ if (err != OK) {
+ ALOGE("Source start after pause in StagefrightRecorder stop failed");
+ return err;
+ }
+
+ mRecPaused = false;
+ }
+
if (mWriter != NULL) {
err = mWriter->stop();
mWriter.clear();
@@ -1960,4 +2003,68 @@ status_t StagefrightRecorder::dump(
::write(fd, result.string(), result.size());
return OK;
}
+
+status_t StagefrightRecorder::setSourcePause(bool pause) {
+ status_t err = OK;
+ if (pause) {
+ if (mVideoEncoderOMX != NULL) {
+ err = mVideoEncoderOMX->pause();
+ if (err != OK) {
+ ALOGE("OMX VideoEncoder pause failed");
+ return err;
+ }
+ }
+ if (mAudioEncoderOMX != NULL) {
+ err = mAudioEncoderOMX->pause();
+ if (err != OK) {
+ ALOGE("OMX AudioEncoder pause failed");
+ return err;
+ }
+ }
+ if (mVideoSourceNode != NULL) {
+ err = mVideoSourceNode->pause();
+ if (err != OK) {
+ ALOGE("OMX VideoSourceNode pause failed");
+ return err;
+ }
+ }
+ if (mAudioSourceNode != NULL) {
+ err = mAudioSourceNode->pause();
+ if (err != OK) {
+ ALOGE("OMX AudioSourceNode pause failed");
+ return err;
+ }
+ }
+ } else {
+ if (mVideoSourceNode != NULL) {
+ err = mVideoSourceNode->start();
+ if (err != OK) {
+ ALOGE("OMX VideoSourceNode start failed");
+ return err;
+ }
+ }
+ if (mAudioSourceNode != NULL) {
+ err = mAudioSourceNode->start();
+ if (err != OK) {
+ ALOGE("OMX AudioSourceNode start failed");
+ return err;
+ }
+ }
+ if (mVideoEncoderOMX != NULL) {
+ err = mVideoEncoderOMX->start();
+ if (err != OK) {
+ ALOGE("OMX VideoEncoder start failed");
+ return err;
+ }
+ }
+ if (mAudioEncoderOMX != NULL) {
+ err = mAudioEncoderOMX->start();
+ if (err != OK) {
+ ALOGE("OMX AudioEncoder start failed");
+ return err;
+ }
+ }
+ }
+ return err;
+}
} // namespace android
diff --git a/media/libmediaplayerservice/StagefrightRecorder.h b/media/libmediaplayerservice/StagefrightRecorder.h
index d2ff62d..26c5582 100644
--- a/media/libmediaplayerservice/StagefrightRecorder.h
+++ b/media/libmediaplayerservice/StagefrightRecorder.h
@@ -60,6 +60,7 @@ struct StagefrightRecorder : public MediaRecorderBase {
virtual status_t setParameters(const String8& params);
virtual status_t setListener(const sp<IMediaRecorderClient>& listener);
virtual status_t setClientName(const String16& clientName);
+ virtual status_t setSourcePause(bool pause);
virtual status_t prepare();
virtual status_t start();
virtual status_t pause();
@@ -80,6 +81,9 @@ protected:
String16 mClientName;
uid_t mClientUid;
sp<MediaWriter> mWriter;
+ sp<MediaSource> mVideoEncoderOMX;
+ sp<MediaSource> mAudioEncoderOMX;
+ sp<MediaSource> mVideoSourceNode;
int mOutputFd;
sp<AudioSource> mAudioSourceNode;
@@ -123,6 +127,7 @@ protected:
MediaProfiles *mEncoderProfiles;
bool mStarted;
+ bool mRecPaused;
// Needed when GLFrames are encoded.
// An <IGraphicBufferProducer> pointer
// will be sent to the client side using which the