Loading media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp +2 −0 Original line number Diff line number Diff line Loading @@ -78,6 +78,8 @@ NuPlayerDriver::NuPlayerDriver(pid_t pid) ALOGD("NuPlayerDriver(%p) created, clientPid(%d)", this, pid); mLooper->setName("NuPlayerDriver Looper"); mMediaClock->init(); // set up an analytics record mAnalyticsItem = new MediaAnalyticsItem(kKeyPlayer); mAnalyticsItem->generateSessionID(); Loading media/libstagefright/MediaClock.cpp +101 −2 Original line number Diff line number Diff line Loading @@ -21,7 +21,7 @@ #include <media/stagefright/MediaClock.h> #include <media/stagefright/foundation/ADebug.h> #include <media/stagefright/foundation/ALooper.h> #include <media/stagefright/foundation/AMessage.h> namespace android { Loading @@ -34,10 +34,41 @@ MediaClock::MediaClock() mAnchorTimeRealUs(-1), mMaxTimeMediaUs(INT64_MAX), mStartingTimeMediaUs(-1), mPlaybackRate(1.0) { mPlaybackRate(1.0), mGeneration(0) { mLooper = new ALooper; mLooper->setName("MediaClock"); mLooper->start(false /* runOnCallingThread */, false /* canCallJava */, ANDROID_PRIORITY_AUDIO); } void MediaClock::init() { mLooper->registerHandler(this); } MediaClock::~MediaClock() { reset(); if (mLooper != NULL) { mLooper->unregisterHandler(id()); mLooper->stop(); } } void MediaClock::reset() { Mutex::Autolock autoLock(mLock); auto it = mTimers.begin(); while (it != mTimers.end()) { it->second->setInt32("reason", TIMER_REASON_RESET); it->second->post(); it = mTimers.erase(it); } mAnchorTimeMediaUs = -1; mAnchorTimeRealUs = -1; mMaxTimeMediaUs = INT64_MAX; mStartingTimeMediaUs = -1; mPlaybackRate = 1.0; ++mGeneration; } void MediaClock::setStartingTimeMedia(int64_t startingTimeMediaUs) { Loading Loading @@ -82,6 +113,9 @@ void MediaClock::updateAnchor( } mAnchorTimeRealUs = nowUs; mAnchorTimeMediaUs = nowMediaUs; ++mGeneration; processTimers_l(); } void MediaClock::updateMaxTimeMedia(int64_t maxTimeMediaUs) { Loading @@ -105,6 +139,11 @@ void MediaClock::setPlaybackRate(float rate) { } mAnchorTimeRealUs = nowUs; mPlaybackRate = rate; if (rate > 0.0) { ++mGeneration; processTimers_l(); } } float MediaClock::getPlaybackRate() const { Loading Loading @@ -165,4 +204,64 @@ status_t MediaClock::getRealTimeFor( return OK; } void MediaClock::addTimer(const sp<AMessage> ¬ify, int64_t mediaTimeUs) { Mutex::Autolock autoLock(mLock); int64_t nextMediaTimeUs = INT64_MAX; if (!mTimers.empty()) { nextMediaTimeUs = mTimers.begin()->first; } mTimers.emplace(mediaTimeUs, notify); if (mediaTimeUs < nextMediaTimeUs) { ++mGeneration; processTimers_l(); } } void MediaClock::onMessageReceived(const sp<AMessage> &msg) { switch (msg->what()) { case kWhatTimeIsUp: { int32_t generation; CHECK(msg->findInt32("generation", &generation)); Mutex::Autolock autoLock(mLock); if (generation != mGeneration) { break; } processTimers_l(); break; } default: TRESPASS(); break; } } void MediaClock::processTimers_l() { int64_t nowMediaTimeUs; status_t status = getMediaTime_l( ALooper::GetNowUs(), &nowMediaTimeUs, false /* allowPastMaxTime */); if (status != OK) { return; } auto it = mTimers.begin(); while (it != mTimers.end() && it->first <= nowMediaTimeUs) { it->second->setInt32("reason", TIMER_REASON_REACHED); it->second->post(); it = mTimers.erase(it); } if (it == mTimers.end() || mPlaybackRate == 0.0 || mAnchorTimeMediaUs < 0) { return; } sp<AMessage> msg = new AMessage(kWhatTimeIsUp, this); msg->setInt32("generation", mGeneration); msg->post((it->first - nowMediaTimeUs) / (double)mPlaybackRate); } } // namespace android media/libstagefright/MediaSync.cpp +1 −0 Original line number Diff line number Diff line Loading @@ -61,6 +61,7 @@ MediaSync::MediaSync() mNextBufferItemMediaUs(-1), mPlaybackRate(0.0) { mMediaClock = new MediaClock; mMediaClock->init(); // initialize settings mPlaybackSettings = AUDIO_PLAYBACK_RATE_DEFAULT; Loading media/libstagefright/include/media/stagefright/MediaClock.h +26 −2 Original line number Diff line number Diff line Loading @@ -18,7 +18,8 @@ #define MEDIA_CLOCK_H_ #include <media/stagefright/foundation/ABase.h> #include <map> #include <media/stagefright/foundation/AHandler.h> #include <utils/Mutex.h> #include <utils/RefBase.h> Loading @@ -26,8 +27,15 @@ namespace android { struct AMessage; struct MediaClock : public RefBase { struct MediaClock : public AHandler { enum { TIMER_REASON_REACHED = 0, TIMER_REASON_NO_CLOCK = 1, TIMER_REASON_RESET = 2, }; MediaClock(); void init(); void setStartingTimeMedia(int64_t startingTimeMediaUs); Loading @@ -54,15 +62,28 @@ struct MediaClock : public RefBase { // The result is saved in |outRealUs|. status_t getRealTimeFor(int64_t targetMediaUs, int64_t *outRealUs) const; void addTimer(const sp<AMessage> ¬ify, int64_t mediaTimeUs); void reset(); protected: virtual ~MediaClock(); virtual void onMessageReceived(const sp<AMessage> &msg); private: enum { kWhatTimeIsUp = 'tIsU', }; status_t getMediaTime_l( int64_t realUs, int64_t *outMediaUs, bool allowPastMaxTime) const; void processTimers_l(); sp<ALooper> mLooper; mutable Mutex mLock; int64_t mAnchorTimeMediaUs; Loading @@ -72,6 +93,9 @@ private: float mPlaybackRate; int32_t mGeneration; std::multimap<int64_t, sp<AMessage> > mTimers; DISALLOW_EVIL_CONSTRUCTORS(MediaClock); }; Loading Loading
media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp +2 −0 Original line number Diff line number Diff line Loading @@ -78,6 +78,8 @@ NuPlayerDriver::NuPlayerDriver(pid_t pid) ALOGD("NuPlayerDriver(%p) created, clientPid(%d)", this, pid); mLooper->setName("NuPlayerDriver Looper"); mMediaClock->init(); // set up an analytics record mAnalyticsItem = new MediaAnalyticsItem(kKeyPlayer); mAnalyticsItem->generateSessionID(); Loading
media/libstagefright/MediaClock.cpp +101 −2 Original line number Diff line number Diff line Loading @@ -21,7 +21,7 @@ #include <media/stagefright/MediaClock.h> #include <media/stagefright/foundation/ADebug.h> #include <media/stagefright/foundation/ALooper.h> #include <media/stagefright/foundation/AMessage.h> namespace android { Loading @@ -34,10 +34,41 @@ MediaClock::MediaClock() mAnchorTimeRealUs(-1), mMaxTimeMediaUs(INT64_MAX), mStartingTimeMediaUs(-1), mPlaybackRate(1.0) { mPlaybackRate(1.0), mGeneration(0) { mLooper = new ALooper; mLooper->setName("MediaClock"); mLooper->start(false /* runOnCallingThread */, false /* canCallJava */, ANDROID_PRIORITY_AUDIO); } void MediaClock::init() { mLooper->registerHandler(this); } MediaClock::~MediaClock() { reset(); if (mLooper != NULL) { mLooper->unregisterHandler(id()); mLooper->stop(); } } void MediaClock::reset() { Mutex::Autolock autoLock(mLock); auto it = mTimers.begin(); while (it != mTimers.end()) { it->second->setInt32("reason", TIMER_REASON_RESET); it->second->post(); it = mTimers.erase(it); } mAnchorTimeMediaUs = -1; mAnchorTimeRealUs = -1; mMaxTimeMediaUs = INT64_MAX; mStartingTimeMediaUs = -1; mPlaybackRate = 1.0; ++mGeneration; } void MediaClock::setStartingTimeMedia(int64_t startingTimeMediaUs) { Loading Loading @@ -82,6 +113,9 @@ void MediaClock::updateAnchor( } mAnchorTimeRealUs = nowUs; mAnchorTimeMediaUs = nowMediaUs; ++mGeneration; processTimers_l(); } void MediaClock::updateMaxTimeMedia(int64_t maxTimeMediaUs) { Loading @@ -105,6 +139,11 @@ void MediaClock::setPlaybackRate(float rate) { } mAnchorTimeRealUs = nowUs; mPlaybackRate = rate; if (rate > 0.0) { ++mGeneration; processTimers_l(); } } float MediaClock::getPlaybackRate() const { Loading Loading @@ -165,4 +204,64 @@ status_t MediaClock::getRealTimeFor( return OK; } void MediaClock::addTimer(const sp<AMessage> ¬ify, int64_t mediaTimeUs) { Mutex::Autolock autoLock(mLock); int64_t nextMediaTimeUs = INT64_MAX; if (!mTimers.empty()) { nextMediaTimeUs = mTimers.begin()->first; } mTimers.emplace(mediaTimeUs, notify); if (mediaTimeUs < nextMediaTimeUs) { ++mGeneration; processTimers_l(); } } void MediaClock::onMessageReceived(const sp<AMessage> &msg) { switch (msg->what()) { case kWhatTimeIsUp: { int32_t generation; CHECK(msg->findInt32("generation", &generation)); Mutex::Autolock autoLock(mLock); if (generation != mGeneration) { break; } processTimers_l(); break; } default: TRESPASS(); break; } } void MediaClock::processTimers_l() { int64_t nowMediaTimeUs; status_t status = getMediaTime_l( ALooper::GetNowUs(), &nowMediaTimeUs, false /* allowPastMaxTime */); if (status != OK) { return; } auto it = mTimers.begin(); while (it != mTimers.end() && it->first <= nowMediaTimeUs) { it->second->setInt32("reason", TIMER_REASON_REACHED); it->second->post(); it = mTimers.erase(it); } if (it == mTimers.end() || mPlaybackRate == 0.0 || mAnchorTimeMediaUs < 0) { return; } sp<AMessage> msg = new AMessage(kWhatTimeIsUp, this); msg->setInt32("generation", mGeneration); msg->post((it->first - nowMediaTimeUs) / (double)mPlaybackRate); } } // namespace android
media/libstagefright/MediaSync.cpp +1 −0 Original line number Diff line number Diff line Loading @@ -61,6 +61,7 @@ MediaSync::MediaSync() mNextBufferItemMediaUs(-1), mPlaybackRate(0.0) { mMediaClock = new MediaClock; mMediaClock->init(); // initialize settings mPlaybackSettings = AUDIO_PLAYBACK_RATE_DEFAULT; Loading
media/libstagefright/include/media/stagefright/MediaClock.h +26 −2 Original line number Diff line number Diff line Loading @@ -18,7 +18,8 @@ #define MEDIA_CLOCK_H_ #include <media/stagefright/foundation/ABase.h> #include <map> #include <media/stagefright/foundation/AHandler.h> #include <utils/Mutex.h> #include <utils/RefBase.h> Loading @@ -26,8 +27,15 @@ namespace android { struct AMessage; struct MediaClock : public RefBase { struct MediaClock : public AHandler { enum { TIMER_REASON_REACHED = 0, TIMER_REASON_NO_CLOCK = 1, TIMER_REASON_RESET = 2, }; MediaClock(); void init(); void setStartingTimeMedia(int64_t startingTimeMediaUs); Loading @@ -54,15 +62,28 @@ struct MediaClock : public RefBase { // The result is saved in |outRealUs|. status_t getRealTimeFor(int64_t targetMediaUs, int64_t *outRealUs) const; void addTimer(const sp<AMessage> ¬ify, int64_t mediaTimeUs); void reset(); protected: virtual ~MediaClock(); virtual void onMessageReceived(const sp<AMessage> &msg); private: enum { kWhatTimeIsUp = 'tIsU', }; status_t getMediaTime_l( int64_t realUs, int64_t *outMediaUs, bool allowPastMaxTime) const; void processTimers_l(); sp<ALooper> mLooper; mutable Mutex mLock; int64_t mAnchorTimeMediaUs; Loading @@ -72,6 +93,9 @@ private: float mPlaybackRate; int32_t mGeneration; std::multimap<int64_t, sp<AMessage> > mTimers; DISALLOW_EVIL_CONSTRUCTORS(MediaClock); }; Loading