Loading media/libmediaplayerservice/nuplayer/Android.mk +1 −0 Original line number Diff line number Diff line Loading @@ -4,6 +4,7 @@ include $(CLEAR_VARS) LOCAL_SRC_FILES:= \ GenericSource.cpp \ HTTPLiveSource.cpp \ MediaClock.cpp \ NuPlayer.cpp \ NuPlayerCCDecoder.cpp \ NuPlayerDecoder.cpp \ Loading media/libmediaplayerservice/nuplayer/MediaClock.cpp 0 → 100644 +135 −0 Original line number Diff line number Diff line /* * Copyright (C) 2015 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ //#define LOG_NDEBUG 0 #define LOG_TAG "MediaClock" #include <utils/Log.h> #include "MediaClock.h" #include <media/stagefright/foundation/ALooper.h> namespace android { // Maximum time change between two updates. static const int64_t kMaxAnchorFluctuationUs = 1000ll; MediaClock::MediaClock() : mAnchorTimeMediaUs(-1), mAnchorTimeRealUs(-1), mMaxTimeMediaUs(INT64_MAX), mStartingTimeMediaUs(-1), mPaused(false) { } MediaClock::~MediaClock() { } void MediaClock::setStartingTimeMedia(int64_t startingTimeMediaUs) { Mutex::Autolock autoLock(mLock); mStartingTimeMediaUs = startingTimeMediaUs; } void MediaClock::clearAnchor() { Mutex::Autolock autoLock(mLock); mAnchorTimeMediaUs = -1; mAnchorTimeRealUs = -1; } void MediaClock::updateAnchor( int64_t anchorTimeMediaUs, int64_t anchorTimeRealUs, int64_t maxTimeMediaUs) { if (anchorTimeMediaUs < 0 || anchorTimeRealUs < 0) { ALOGW("reject anchor time since it is negative."); return; } int64_t nowUs = ALooper::GetNowUs(); int64_t nowMediaUs = anchorTimeMediaUs + nowUs - anchorTimeRealUs; if (nowMediaUs < 0) { ALOGW("reject anchor time since it leads to negative media time."); return; } Mutex::Autolock autoLock(mLock); mAnchorTimeRealUs = nowUs; mAnchorTimeMediaUs = nowMediaUs; mMaxTimeMediaUs = maxTimeMediaUs; } void MediaClock::updateMaxTimeMedia(int64_t maxTimeMediaUs) { Mutex::Autolock autoLock(mLock); mMaxTimeMediaUs = maxTimeMediaUs; } void MediaClock::pause() { Mutex::Autolock autoLock(mLock); if (mPaused) { return; } mPaused = true; if (mAnchorTimeRealUs == -1) { return; } int64_t nowUs = ALooper::GetNowUs(); mAnchorTimeMediaUs += nowUs - mAnchorTimeRealUs; if (mAnchorTimeMediaUs < 0) { ALOGW("anchor time should not be negative, set to 0."); mAnchorTimeMediaUs = 0; } mAnchorTimeRealUs = nowUs; } void MediaClock::resume() { Mutex::Autolock autoLock(mLock); if (!mPaused) { return; } mPaused = false; if (mAnchorTimeRealUs == -1) { return; } mAnchorTimeRealUs = ALooper::GetNowUs(); } int64_t MediaClock::getTimeMedia(int64_t realUs, bool allowPastMaxTime) { Mutex::Autolock autoLock(mLock); if (mAnchorTimeRealUs == -1) { return -1ll; } if (mPaused) { realUs = mAnchorTimeRealUs; } int64_t currentMediaUs = mAnchorTimeMediaUs + realUs - mAnchorTimeRealUs; if (currentMediaUs > mMaxTimeMediaUs && !allowPastMaxTime) { currentMediaUs = mMaxTimeMediaUs; } if (currentMediaUs < mStartingTimeMediaUs) { currentMediaUs = mStartingTimeMediaUs; } if (currentMediaUs < 0) { currentMediaUs = 0; } return currentMediaUs; } } // namespace android media/libmediaplayerservice/nuplayer/MediaClock.h 0 → 100644 +68 −0 Original line number Diff line number Diff line /* * Copyright (C) 2015 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef MEDIA_CLOCK_H_ #define MEDIA_CLOCK_H_ #include <media/stagefright/foundation/ABase.h> #include <utils/Mutex.h> #include <utils/RefBase.h> namespace android { struct AMessage; struct MediaClock : public RefBase { MediaClock(); void setStartingTimeMedia(int64_t startingTimeMediaUs); void clearAnchor(); // It's highly recommended to use timestamp of just rendered frame as // anchor time, especially in paused state. Such restriction will be // required when dynamic playback rate is supported in the future. void updateAnchor( int64_t anchorTimeMediaUs, int64_t anchorTimeRealUs, int64_t maxTimeMediaUs = INT64_MAX); void updateMaxTimeMedia(int64_t maxTimeMediaUs); void pause(); void resume(); int64_t getTimeMedia(int64_t realUs, bool allowPastMaxTime = false); protected: virtual ~MediaClock(); private: Mutex mLock; int64_t mAnchorTimeMediaUs; int64_t mAnchorTimeRealUs; int64_t mMaxTimeMediaUs; int64_t mStartingTimeMediaUs; bool mPaused; DISALLOW_EVIL_CONSTRUCTORS(MediaClock); }; } // namespace android #endif // MEDIA_CLOCK_H_ media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp +176 −262 File changed.Preview size limit exceeded, changes collapsed. Show changes media/libmediaplayerservice/nuplayer/NuPlayerRenderer.h +16 −33 Original line number Diff line number Diff line Loading @@ -23,6 +23,7 @@ namespace android { struct ABuffer; struct MediaClock; struct VideoFrameScheduler; struct NuPlayer::Renderer : public AHandler { Loading Loading @@ -60,16 +61,8 @@ struct NuPlayer::Renderer : public AHandler { void setVideoFrameRate(float fps); // Following setters and getters are protected by mTimeLock. status_t getCurrentPosition(int64_t *mediaUs); void setHasMedia(bool audio); void setAudioFirstAnchorTime(int64_t mediaUs); void setAudioFirstAnchorTimeIfNeeded(int64_t mediaUs); void setAnchorTime( int64_t mediaUs, int64_t realUs, int64_t numFramesWritten = -1, bool resume = false); void setVideoLateByUs(int64_t lateUs); int64_t getVideoLateByUs(); void setPauseStartedTimeRealUs(int64_t realUs); status_t openAudioSink( const sp<AMessage> &format, Loading Loading @@ -107,7 +100,6 @@ private: kWhatQueueBuffer = 'queB', kWhatQueueEOS = 'qEOS', kWhatFlush = 'flus', kWhatAudioSinkChanged = 'auSC', kWhatPause = 'paus', kWhatResume = 'resm', kWhatOpenAudioSink = 'opnA', Loading Loading @@ -141,26 +133,17 @@ private: bool mDrainVideoQueuePending; int32_t mAudioQueueGeneration; int32_t mVideoQueueGeneration; int32_t mAudioDrainGeneration; int32_t mVideoDrainGeneration; Mutex mTimeLock; // |mTimeLock| protects the following 7 member vars that are related to time. // Note: those members are only written on Renderer thread, so reading on Renderer thread // doesn't need to be protected. Otherwise accessing those members must be protected by // |mTimeLock|. // TODO: move those members to a seperated media clock class. sp<MediaClock> mMediaClock; int64_t mAudioFirstAnchorTimeMediaUs; int64_t mAnchorTimeMediaUs; int64_t mAnchorTimeRealUs; int64_t mAnchorNumFramesWritten; int64_t mAnchorMaxMediaUs; int64_t mVideoLateByUs; bool mHasAudio; bool mHasVideo; int64_t mPauseStartedTimeRealUs; Mutex mFlushLock; // protects the following 2 member vars. bool mFlushingAudio; bool mFlushingVideo; bool mNotifyCompleteAudio; bool mNotifyCompleteVideo; Loading @@ -168,7 +151,6 @@ private: // modified on only renderer's thread. bool mPaused; int64_t mPausePositionMediaTimeUs; bool mVideoSampleReceived; bool mVideoRenderingStarted; Loading @@ -194,13 +176,6 @@ private: int32_t mTotalBuffersQueued; int32_t mLastAudioBufferDrained; status_t getCurrentPositionOnLooper(int64_t *mediaUs); status_t getCurrentPositionOnLooper( int64_t *mediaUs, int64_t nowUs, bool allowPastQueuedVideo = false); bool getCurrentPositionIfPaused_l(int64_t *mediaUs); status_t getCurrentPositionFromAnchor( int64_t *mediaUs, int64_t nowUs, bool allowPastQueuedVideo = false); size_t fillAudioBuffer(void *buffer, size_t size); bool onDrainAudioQueue(); Loading @@ -208,14 +183,19 @@ private: int64_t getPlayedOutAudioDurationUs(int64_t nowUs); void postDrainAudioQueue_l(int64_t delayUs = 0); void clearAnchorTime_l(); void clearAudioFirstAnchorTime_l(); void setAudioFirstAnchorTimeIfNeeded_l(int64_t mediaUs); void setVideoLateByUs(int64_t lateUs); void onNewAudioMediaTime(int64_t mediaTimeUs); int64_t getRealTimeUs(int64_t mediaTimeUs, int64_t nowUs); void onDrainVideoQueue(); void postDrainVideoQueue_l(); void postDrainVideoQueue(); void prepareForMediaRenderingStart(); void notifyIfMediaRenderingStarted(); void prepareForMediaRenderingStart_l(); void notifyIfMediaRenderingStarted_l(); void onQueueBuffer(const sp<AMessage> &msg); void onQueueEOS(const sp<AMessage> &msg); Loading @@ -226,6 +206,9 @@ private: void onPause(); void onResume(); void onSetVideoFrameRate(float fps); int32_t getQueueGeneration(bool audio); int32_t getDrainGeneration(bool audio); bool getSyncQueues(); void onAudioOffloadTearDown(AudioOffloadTearDownReason reason); status_t onOpenAudioSink( const sp<AMessage> &format, Loading @@ -242,7 +225,7 @@ private: void notifyAudioOffloadTearDown(); void flushQueue(List<QueueEntry> *queue); bool dropBufferWhileFlushing(bool audio, const sp<AMessage> &msg); bool dropBufferIfStale(bool audio, const sp<AMessage> &msg); void syncQueuesDone_l(); bool offloadingAudio() const { return (mFlags & FLAG_OFFLOAD_AUDIO) != 0; } Loading Loading
media/libmediaplayerservice/nuplayer/Android.mk +1 −0 Original line number Diff line number Diff line Loading @@ -4,6 +4,7 @@ include $(CLEAR_VARS) LOCAL_SRC_FILES:= \ GenericSource.cpp \ HTTPLiveSource.cpp \ MediaClock.cpp \ NuPlayer.cpp \ NuPlayerCCDecoder.cpp \ NuPlayerDecoder.cpp \ Loading
media/libmediaplayerservice/nuplayer/MediaClock.cpp 0 → 100644 +135 −0 Original line number Diff line number Diff line /* * Copyright (C) 2015 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ //#define LOG_NDEBUG 0 #define LOG_TAG "MediaClock" #include <utils/Log.h> #include "MediaClock.h" #include <media/stagefright/foundation/ALooper.h> namespace android { // Maximum time change between two updates. static const int64_t kMaxAnchorFluctuationUs = 1000ll; MediaClock::MediaClock() : mAnchorTimeMediaUs(-1), mAnchorTimeRealUs(-1), mMaxTimeMediaUs(INT64_MAX), mStartingTimeMediaUs(-1), mPaused(false) { } MediaClock::~MediaClock() { } void MediaClock::setStartingTimeMedia(int64_t startingTimeMediaUs) { Mutex::Autolock autoLock(mLock); mStartingTimeMediaUs = startingTimeMediaUs; } void MediaClock::clearAnchor() { Mutex::Autolock autoLock(mLock); mAnchorTimeMediaUs = -1; mAnchorTimeRealUs = -1; } void MediaClock::updateAnchor( int64_t anchorTimeMediaUs, int64_t anchorTimeRealUs, int64_t maxTimeMediaUs) { if (anchorTimeMediaUs < 0 || anchorTimeRealUs < 0) { ALOGW("reject anchor time since it is negative."); return; } int64_t nowUs = ALooper::GetNowUs(); int64_t nowMediaUs = anchorTimeMediaUs + nowUs - anchorTimeRealUs; if (nowMediaUs < 0) { ALOGW("reject anchor time since it leads to negative media time."); return; } Mutex::Autolock autoLock(mLock); mAnchorTimeRealUs = nowUs; mAnchorTimeMediaUs = nowMediaUs; mMaxTimeMediaUs = maxTimeMediaUs; } void MediaClock::updateMaxTimeMedia(int64_t maxTimeMediaUs) { Mutex::Autolock autoLock(mLock); mMaxTimeMediaUs = maxTimeMediaUs; } void MediaClock::pause() { Mutex::Autolock autoLock(mLock); if (mPaused) { return; } mPaused = true; if (mAnchorTimeRealUs == -1) { return; } int64_t nowUs = ALooper::GetNowUs(); mAnchorTimeMediaUs += nowUs - mAnchorTimeRealUs; if (mAnchorTimeMediaUs < 0) { ALOGW("anchor time should not be negative, set to 0."); mAnchorTimeMediaUs = 0; } mAnchorTimeRealUs = nowUs; } void MediaClock::resume() { Mutex::Autolock autoLock(mLock); if (!mPaused) { return; } mPaused = false; if (mAnchorTimeRealUs == -1) { return; } mAnchorTimeRealUs = ALooper::GetNowUs(); } int64_t MediaClock::getTimeMedia(int64_t realUs, bool allowPastMaxTime) { Mutex::Autolock autoLock(mLock); if (mAnchorTimeRealUs == -1) { return -1ll; } if (mPaused) { realUs = mAnchorTimeRealUs; } int64_t currentMediaUs = mAnchorTimeMediaUs + realUs - mAnchorTimeRealUs; if (currentMediaUs > mMaxTimeMediaUs && !allowPastMaxTime) { currentMediaUs = mMaxTimeMediaUs; } if (currentMediaUs < mStartingTimeMediaUs) { currentMediaUs = mStartingTimeMediaUs; } if (currentMediaUs < 0) { currentMediaUs = 0; } return currentMediaUs; } } // namespace android
media/libmediaplayerservice/nuplayer/MediaClock.h 0 → 100644 +68 −0 Original line number Diff line number Diff line /* * Copyright (C) 2015 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef MEDIA_CLOCK_H_ #define MEDIA_CLOCK_H_ #include <media/stagefright/foundation/ABase.h> #include <utils/Mutex.h> #include <utils/RefBase.h> namespace android { struct AMessage; struct MediaClock : public RefBase { MediaClock(); void setStartingTimeMedia(int64_t startingTimeMediaUs); void clearAnchor(); // It's highly recommended to use timestamp of just rendered frame as // anchor time, especially in paused state. Such restriction will be // required when dynamic playback rate is supported in the future. void updateAnchor( int64_t anchorTimeMediaUs, int64_t anchorTimeRealUs, int64_t maxTimeMediaUs = INT64_MAX); void updateMaxTimeMedia(int64_t maxTimeMediaUs); void pause(); void resume(); int64_t getTimeMedia(int64_t realUs, bool allowPastMaxTime = false); protected: virtual ~MediaClock(); private: Mutex mLock; int64_t mAnchorTimeMediaUs; int64_t mAnchorTimeRealUs; int64_t mMaxTimeMediaUs; int64_t mStartingTimeMediaUs; bool mPaused; DISALLOW_EVIL_CONSTRUCTORS(MediaClock); }; } // namespace android #endif // MEDIA_CLOCK_H_
media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp +176 −262 File changed.Preview size limit exceeded, changes collapsed. Show changes
media/libmediaplayerservice/nuplayer/NuPlayerRenderer.h +16 −33 Original line number Diff line number Diff line Loading @@ -23,6 +23,7 @@ namespace android { struct ABuffer; struct MediaClock; struct VideoFrameScheduler; struct NuPlayer::Renderer : public AHandler { Loading Loading @@ -60,16 +61,8 @@ struct NuPlayer::Renderer : public AHandler { void setVideoFrameRate(float fps); // Following setters and getters are protected by mTimeLock. status_t getCurrentPosition(int64_t *mediaUs); void setHasMedia(bool audio); void setAudioFirstAnchorTime(int64_t mediaUs); void setAudioFirstAnchorTimeIfNeeded(int64_t mediaUs); void setAnchorTime( int64_t mediaUs, int64_t realUs, int64_t numFramesWritten = -1, bool resume = false); void setVideoLateByUs(int64_t lateUs); int64_t getVideoLateByUs(); void setPauseStartedTimeRealUs(int64_t realUs); status_t openAudioSink( const sp<AMessage> &format, Loading Loading @@ -107,7 +100,6 @@ private: kWhatQueueBuffer = 'queB', kWhatQueueEOS = 'qEOS', kWhatFlush = 'flus', kWhatAudioSinkChanged = 'auSC', kWhatPause = 'paus', kWhatResume = 'resm', kWhatOpenAudioSink = 'opnA', Loading Loading @@ -141,26 +133,17 @@ private: bool mDrainVideoQueuePending; int32_t mAudioQueueGeneration; int32_t mVideoQueueGeneration; int32_t mAudioDrainGeneration; int32_t mVideoDrainGeneration; Mutex mTimeLock; // |mTimeLock| protects the following 7 member vars that are related to time. // Note: those members are only written on Renderer thread, so reading on Renderer thread // doesn't need to be protected. Otherwise accessing those members must be protected by // |mTimeLock|. // TODO: move those members to a seperated media clock class. sp<MediaClock> mMediaClock; int64_t mAudioFirstAnchorTimeMediaUs; int64_t mAnchorTimeMediaUs; int64_t mAnchorTimeRealUs; int64_t mAnchorNumFramesWritten; int64_t mAnchorMaxMediaUs; int64_t mVideoLateByUs; bool mHasAudio; bool mHasVideo; int64_t mPauseStartedTimeRealUs; Mutex mFlushLock; // protects the following 2 member vars. bool mFlushingAudio; bool mFlushingVideo; bool mNotifyCompleteAudio; bool mNotifyCompleteVideo; Loading @@ -168,7 +151,6 @@ private: // modified on only renderer's thread. bool mPaused; int64_t mPausePositionMediaTimeUs; bool mVideoSampleReceived; bool mVideoRenderingStarted; Loading @@ -194,13 +176,6 @@ private: int32_t mTotalBuffersQueued; int32_t mLastAudioBufferDrained; status_t getCurrentPositionOnLooper(int64_t *mediaUs); status_t getCurrentPositionOnLooper( int64_t *mediaUs, int64_t nowUs, bool allowPastQueuedVideo = false); bool getCurrentPositionIfPaused_l(int64_t *mediaUs); status_t getCurrentPositionFromAnchor( int64_t *mediaUs, int64_t nowUs, bool allowPastQueuedVideo = false); size_t fillAudioBuffer(void *buffer, size_t size); bool onDrainAudioQueue(); Loading @@ -208,14 +183,19 @@ private: int64_t getPlayedOutAudioDurationUs(int64_t nowUs); void postDrainAudioQueue_l(int64_t delayUs = 0); void clearAnchorTime_l(); void clearAudioFirstAnchorTime_l(); void setAudioFirstAnchorTimeIfNeeded_l(int64_t mediaUs); void setVideoLateByUs(int64_t lateUs); void onNewAudioMediaTime(int64_t mediaTimeUs); int64_t getRealTimeUs(int64_t mediaTimeUs, int64_t nowUs); void onDrainVideoQueue(); void postDrainVideoQueue_l(); void postDrainVideoQueue(); void prepareForMediaRenderingStart(); void notifyIfMediaRenderingStarted(); void prepareForMediaRenderingStart_l(); void notifyIfMediaRenderingStarted_l(); void onQueueBuffer(const sp<AMessage> &msg); void onQueueEOS(const sp<AMessage> &msg); Loading @@ -226,6 +206,9 @@ private: void onPause(); void onResume(); void onSetVideoFrameRate(float fps); int32_t getQueueGeneration(bool audio); int32_t getDrainGeneration(bool audio); bool getSyncQueues(); void onAudioOffloadTearDown(AudioOffloadTearDownReason reason); status_t onOpenAudioSink( const sp<AMessage> &format, Loading @@ -242,7 +225,7 @@ private: void notifyAudioOffloadTearDown(); void flushQueue(List<QueueEntry> *queue); bool dropBufferWhileFlushing(bool audio, const sp<AMessage> &msg); bool dropBufferIfStale(bool audio, const sp<AMessage> &msg); void syncQueuesDone_l(); bool offloadingAudio() const { return (mFlags & FLAG_OFFLOAD_AUDIO) != 0; } Loading