From: Lajos Molnar Date: Thu, 15 Aug 2013 01:30:38 +0000 (-0700) Subject: Add MEDIA_STARTED/PAUSED/STOPPED events to media players X-Git-Tag: android-x86-4.4-r1~191^2 X-Git-Url: http://git.osdn.net/view?a=commitdiff_plain;h=cbaffcffee6418d678806e63097c19fe26d48fe0;p=android-x86%2Fframeworks-av.git Add MEDIA_STARTED/PAUSED/STOPPED events to media players This is needed for the MediaTimeProvider java interface, so it does not continually poll for current media time. Note: NuPlayer and AwesomePlayer do not correctly handle stop (pause instead), so for those we will signal PAUSED. Signed-off-by: Lajos Molnar Change-Id: I3c61e1bda475f131323f475c18a42e3ec66c9ae1 Bug: 10326117 --- diff --git a/include/media/mediaplayer.h b/include/media/mediaplayer.h index 14381c78ba..1afd7f7e9a 100644 --- a/include/media/mediaplayer.h +++ b/include/media/mediaplayer.h @@ -42,6 +42,9 @@ enum media_event_type { MEDIA_BUFFERING_UPDATE = 3, MEDIA_SEEK_COMPLETE = 4, MEDIA_SET_VIDEO_SIZE = 5, + MEDIA_STARTED = 6, + MEDIA_PAUSED = 7, + MEDIA_STOPPED = 8, MEDIA_TIMED_TEXT = 99, MEDIA_ERROR = 100, MEDIA_INFO = 200, diff --git a/media/libmediaplayerservice/MidiFile.cpp b/media/libmediaplayerservice/MidiFile.cpp index 270b872505..0a6aa902e3 100644 --- a/media/libmediaplayerservice/MidiFile.cpp +++ b/media/libmediaplayerservice/MidiFile.cpp @@ -220,6 +220,9 @@ status_t MidiFile::start() } mRender = true; + if (mState == EAS_STATE_PLAY) { + sendEvent(MEDIA_STARTED); + } // wake up render thread ALOGV(" wakeup render thread"); @@ -242,6 +245,7 @@ status_t MidiFile::stop() } } mPaused = false; + sendEvent(MEDIA_STOPPED); return NO_ERROR; } @@ -279,6 +283,7 @@ status_t MidiFile::pause() return ERROR_EAS_FAILURE; } mPaused = true; + sendEvent(MEDIA_PAUSED); return NO_ERROR; } @@ -382,6 +387,7 @@ status_t MidiFile::reset() status_t MidiFile::reset_nosync() { ALOGV("MidiFile::reset_nosync"); + sendEvent(MEDIA_STOPPED); // close file if (mEasHandle) { EAS_CloseFile(mEasData, mEasHandle); diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp index 7e81035ae1..b411f3453b 100644 --- a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp +++ b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp @@ -731,6 +731,9 @@ void NuPlayer::onMessageReceived(const sp &msg) { ALOGV("renderer %s flush completed.", audio ? "audio" : "video"); } else if (what == Renderer::kWhatVideoRenderingStart) { notifyListener(MEDIA_INFO, MEDIA_INFO_RENDERING_START, 0); + } else if (what == Renderer::kWhatMediaRenderingStart) { + ALOGV("media rendering started"); + notifyListener(MEDIA_STARTED, 0, 0); } break; } diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp index 68b96230dd..cf0373c75b 100644 --- a/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp +++ b/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp @@ -255,6 +255,7 @@ status_t NuPlayerDriver::pause() { return OK; case STATE_RUNNING: + notifyListener(MEDIA_PAUSED); mPlayer->pause(); break; @@ -287,6 +288,8 @@ status_t NuPlayerDriver::seekTo(int msec) { case STATE_PAUSED: { mAtEOS = false; + // seeks can take a while, so we essentially paused + notifyListener(MEDIA_PAUSED); mPlayer->seekToAsync(seekTimeUs); break; } @@ -345,6 +348,8 @@ status_t NuPlayerDriver::reset() { break; } + notifyListener(MEDIA_STOPPED); + mState = STATE_RESET_IN_PROGRESS; mPlayer->resetAsync(); diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp index b543d9dd07..3b2784bd6f 100644 --- a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp +++ b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp @@ -50,6 +50,8 @@ NuPlayer::Renderer::Renderer( mSyncQueues(false), mPaused(false), mVideoRenderingStarted(false), + mVideoRenderingStartGeneration(0), + mAudioRenderingStartGeneration(0), mLastPositionUpdateUs(-1ll), mVideoLateByUs(0ll) { } @@ -220,6 +222,23 @@ void NuPlayer::Renderer::signalAudioSinkChanged() { (new AMessage(kWhatAudioSinkChanged, id()))->post(); } +void NuPlayer::Renderer::prepareForMediaRenderingStart() { + mAudioRenderingStartGeneration = mAudioQueueGeneration; + mVideoRenderingStartGeneration = mVideoQueueGeneration; +} + +void NuPlayer::Renderer::notifyIfMediaRenderingStarted() { + if (mVideoRenderingStartGeneration == mVideoQueueGeneration && + mAudioRenderingStartGeneration == mAudioQueueGeneration) { + mVideoRenderingStartGeneration = -1; + mAudioRenderingStartGeneration = -1; + + sp notify = mNotify->dup(); + notify->setInt32("what", kWhatMediaRenderingStart); + notify->post(); + } +} + bool NuPlayer::Renderer::onDrainAudioQueue() { uint32_t numFramesPlayed; if (mAudioSink->getPosition(&numFramesPlayed) != OK) { @@ -299,6 +318,8 @@ bool NuPlayer::Renderer::onDrainAudioQueue() { numBytesAvailableToWrite -= copy; size_t copiedFrames = copy / mAudioSink->frameSize(); mNumFramesWritten += copiedFrames; + + notifyIfMediaRenderingStarted(); } notifyPosition(); @@ -405,6 +426,8 @@ void NuPlayer::Renderer::onDrainVideoQueue() { notifyVideoRenderingStart(); } + notifyIfMediaRenderingStarted(); + notifyPosition(); } @@ -552,6 +575,7 @@ void NuPlayer::Renderer::onFlush(const sp &msg) { // is flushed. syncQueuesDone(); + ALOGV("flushing %s", audio ? "audio" : "video"); if (audio) { flushQueue(&mAudioQueue); @@ -560,6 +584,8 @@ void NuPlayer::Renderer::onFlush(const sp &msg) { mDrainAudioQueuePending = false; ++mAudioQueueGeneration; + + prepareForMediaRenderingStart(); } else { flushQueue(&mVideoQueue); @@ -568,6 +594,8 @@ void NuPlayer::Renderer::onFlush(const sp &msg) { mDrainVideoQueuePending = false; ++mVideoQueueGeneration; + + prepareForMediaRenderingStart(); } notifyFlushComplete(audio); @@ -658,6 +686,8 @@ void NuPlayer::Renderer::onPause() { mDrainVideoQueuePending = false; ++mVideoQueueGeneration; + prepareForMediaRenderingStart(); + if (mHasAudio) { mAudioSink->pause(); } diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.h b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.h index c9796e20a1..94a05ea25e 100644 --- a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.h +++ b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.h @@ -53,6 +53,7 @@ struct NuPlayer::Renderer : public AHandler { kWhatFlushComplete = 'fluC', kWhatPosition = 'posi', kWhatVideoRenderingStart = 'vdrd', + kWhatMediaRenderingStart = 'mdrd', }; protected: @@ -106,6 +107,8 @@ private: bool mPaused; bool mVideoRenderingStarted; + int32_t mVideoRenderingStartGeneration; + int32_t mAudioRenderingStartGeneration; int64_t mLastPositionUpdateUs; int64_t mVideoLateByUs; @@ -116,6 +119,9 @@ private: void onDrainVideoQueue(); void postDrainVideoQueue(); + void prepareForMediaRenderingStart(); + void notifyIfMediaRenderingStarted(); + void onQueueBuffer(const sp &msg); void onQueueEOS(const sp &msg); void onFlush(const sp &msg); diff --git a/media/libstagefright/AwesomePlayer.cpp b/media/libstagefright/AwesomePlayer.cpp index 79f2c91378..52e178e0dd 100644 --- a/media/libstagefright/AwesomePlayer.cpp +++ b/media/libstagefright/AwesomePlayer.cpp @@ -191,6 +191,8 @@ AwesomePlayer::AwesomePlayer() mTimeSource(NULL), mVideoRenderingStarted(false), mVideoRendererIsPreview(false), + mMediaRenderingStartGeneration(0), + mStartGeneration(0), mAudioPlayer(NULL), mDisplayWidth(0), mDisplayHeight(0), @@ -491,6 +493,8 @@ void AwesomePlayer::reset_l() { mDisplayWidth = 0; mDisplayHeight = 0; + notifyListener_l(MEDIA_STOPPED); + if (mDecryptHandle != NULL) { mDrmManagerClient->setPlaybackStatus(mDecryptHandle, Playback::STOP, 0); @@ -1025,6 +1029,13 @@ void AwesomePlayer::createAudioPlayer_l() seekAudioIfNecessary_l(); } +void AwesomePlayer::notifyIfMediaStarted_l() { + if (mMediaRenderingStartGeneration == mStartGeneration) { + mMediaRenderingStartGeneration = -1; + notifyListener_l(MEDIA_STARTED); + } +} + status_t AwesomePlayer::startAudioPlayer_l(bool sendErrorNotification) { CHECK(!(mFlags & AUDIO_RUNNING)); status_t err = OK; @@ -1061,6 +1072,8 @@ status_t AwesomePlayer::startAudioPlayer_l(bool sendErrorNotification) { // We will have finished the seek while starting the audio player. postAudioSeekComplete(); + } else { + notifyIfMediaStarted_l(); } } else { err = mAudioPlayer->resume(); @@ -1201,6 +1214,9 @@ status_t AwesomePlayer::pause_l(bool at_eos) { return OK; } + notifyListener_l(MEDIA_PAUSED); + mMediaRenderingStartGeneration = ++mStartGeneration; + cancelPlayerEvents(true /* keepNotifications */); if (mAudioPlayer != NULL && (mFlags & AUDIO_RUNNING)) { @@ -1389,6 +1405,9 @@ status_t AwesomePlayer::seekTo_l(int64_t timeUs) { mSeekTimeUs = timeUs; modifyFlags((AT_EOS | AUDIO_AT_EOS | VIDEO_AT_EOS), CLEAR); + notifyListener_l(MEDIA_PAUSED); + mMediaRenderingStartGeneration = ++mStartGeneration; + seekAudioIfNecessary_l(); if (mFlags & TEXTPLAYER_INITIALIZED) { @@ -1903,6 +1922,7 @@ void AwesomePlayer::onVideoEvent() { notifyListener_l(MEDIA_INFO, MEDIA_INFO_RENDERING_START); } + notifyIfMediaStarted_l(); } mVideoBuffer->release(); @@ -1998,6 +2018,8 @@ void AwesomePlayer::onCheckAudioStatus() { } mSeeking = NO_SEEK; + + notifyIfMediaStarted_l(); } status_t finalStatus; diff --git a/media/libstagefright/include/AwesomePlayer.h b/media/libstagefright/include/AwesomePlayer.h index d3c74e26de..b001cf4d27 100644 --- a/media/libstagefright/include/AwesomePlayer.h +++ b/media/libstagefright/include/AwesomePlayer.h @@ -169,6 +169,8 @@ private: sp mVideoRenderer; bool mVideoRenderingStarted; bool mVideoRendererIsPreview; + int32_t mMediaRenderingStartGeneration; + int32_t mStartGeneration; ssize_t mActiveAudioTrackIndex; sp mAudioTrack; @@ -294,6 +296,7 @@ private: void finishSeekIfNecessary(int64_t videoTimeUs); void ensureCacheIsFetching_l(); + void notifyIfMediaStarted_l(); void createAudioPlayer_l(); status_t startAudioPlayer_l(bool sendErrorNotification = true);