diff options
Diffstat (limited to 'media/libmediaplayerservice/nuplayer/NuPlayerRenderer.h')
-rw-r--r-- | media/libmediaplayerservice/nuplayer/NuPlayerRenderer.h | 115 |
1 files changed, 97 insertions, 18 deletions
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.h b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.h index 9124e03..b15a266 100644 --- a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.h +++ b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.h @@ -23,16 +23,22 @@ namespace android { struct ABuffer; -class SoftwareRenderer; +struct VideoFrameScheduler; struct NuPlayer::Renderer : public AHandler { enum Flags { FLAG_REAL_TIME = 1, + FLAG_OFFLOAD_AUDIO = 2, }; Renderer(const sp<MediaPlayerBase::AudioSink> &sink, const sp<AMessage> ¬ify, uint32_t flags = 0); + static size_t AudioSinkCallback( + MediaPlayerBase::AudioSink *audioSink, + void *data, size_t size, void *me, + MediaPlayerBase::AudioSink::cb_event_t event); + void queueBuffer( bool audio, const sp<ABuffer> &buffer, @@ -46,18 +52,45 @@ struct NuPlayer::Renderer : public AHandler { void signalAudioSinkChanged(); + void signalDisableOffloadAudio(); + void pause(); void resume(); + void setVideoFrameRate(float fps); + + // Following setters and getters are protected by mTimeLock. + status_t getCurrentPosition(int64_t *mediaUs); + status_t getCurrentPosition(int64_t *mediaUs, int64_t nowUs); + void setHasMedia(bool audio); + void setAudioFirstAnchorTime(int64_t mediaUs); + void setAudioFirstAnchorTimeIfNeeded(int64_t mediaUs); + void setAnchorTime(int64_t mediaUs, int64_t realUs, bool resume = false); + void setVideoLateByUs(int64_t lateUs); + int64_t getVideoLateByUs(); + void setPauseStartedTimeRealUs(int64_t realUs); + + bool openAudioSink( + const sp<AMessage> &format, + bool offloadOnly, + bool hasVideo, + uint32_t flags); + void closeAudioSink(); + enum { kWhatEOS = 'eos ', kWhatFlushComplete = 'fluC', kWhatPosition = 'posi', kWhatVideoRenderingStart = 'vdrd', kWhatMediaRenderingStart = 'mdrd', + kWhatAudioOffloadTearDown = 'aOTD', + kWhatAudioOffloadPauseTimeout = 'aOPT', }; - void setSoftRenderer(SoftwareRenderer *softRenderer); + enum AudioOffloadTearDownReason { + kDueToError = 0, + kDueToTimeout, + }; protected: virtual ~Renderer(); @@ -66,14 +99,20 @@ protected: private: enum { - kWhatDrainAudioQueue = 'draA', - kWhatDrainVideoQueue = 'draV', - kWhatQueueBuffer = 'queB', - kWhatQueueEOS = 'qEOS', - kWhatFlush = 'flus', - kWhatAudioSinkChanged = 'auSC', - kWhatPause = 'paus', - kWhatResume = 'resm', + kWhatDrainAudioQueue = 'draA', + kWhatDrainVideoQueue = 'draV', + kWhatPostDrainVideoQueue = 'pDVQ', + kWhatQueueBuffer = 'queB', + kWhatQueueEOS = 'qEOS', + kWhatFlush = 'flus', + kWhatAudioSinkChanged = 'auSC', + kWhatPause = 'paus', + kWhatResume = 'resm', + kWhatOpenAudioSink = 'opnA', + kWhatCloseAudioSink = 'clsA', + kWhatStopAudioSink = 'stpA', + kWhatDisableOffloadAudio = 'noOA', + kWhatSetVideoFrameRate = 'sVFR', }; struct QueueEntry { @@ -81,44 +120,69 @@ private: sp<AMessage> mNotifyConsumed; size_t mOffset; status_t mFinalResult; + int32_t mBufferOrdinal; }; static const int64_t kMinPositionUpdateDelayUs; sp<MediaPlayerBase::AudioSink> mAudioSink; - SoftwareRenderer *mSoftRenderer; sp<AMessage> mNotify; + Mutex mLock; uint32_t mFlags; List<QueueEntry> mAudioQueue; List<QueueEntry> mVideoQueue; uint32_t mNumFramesWritten; + sp<VideoFrameScheduler> mVideoScheduler; bool mDrainAudioQueuePending; bool mDrainVideoQueuePending; int32_t mAudioQueueGeneration; int32_t mVideoQueueGeneration; + 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. + int64_t mAudioFirstAnchorTimeMediaUs; int64_t mAnchorTimeMediaUs; int64_t mAnchorTimeRealUs; + int64_t mVideoLateByUs; + bool mHasAudio; + bool mHasVideo; + int64_t mPauseStartedTimeRealUs; Mutex mFlushLock; // protects the following 2 member vars. bool mFlushingAudio; bool mFlushingVideo; - bool mHasAudio; - bool mHasVideo; bool mSyncQueues; bool mPaused; + bool mVideoSampleReceived; bool mVideoRenderingStarted; int32_t mVideoRenderingStartGeneration; int32_t mAudioRenderingStartGeneration; int64_t mLastPositionUpdateUs; - int64_t mVideoLateByUs; + + int32_t mAudioOffloadPauseTimeoutGeneration; + bool mAudioOffloadTornDown; + audio_offload_info_t mCurrentOffloadInfo; + + int32_t mTotalBuffersQueued; + int32_t mLastAudioBufferDrained; + + size_t fillAudioBuffer(void *buffer, size_t size); bool onDrainAudioQueue(); - void postDrainAudioQueue(int64_t delayUs = 0); + int64_t getPendingAudioPlayoutDurationUs(int64_t nowUs); + int64_t getPlayedOutAudioDurationUs(int64_t nowUs); + void postDrainAudioQueue_l(int64_t delayUs = 0); + + void onNewAudioMediaTime(int64_t mediaTimeUs); + int64_t getRealTimeUs(int64_t mediaTimeUs, int64_t nowUs); void onDrainVideoQueue(); void postDrainVideoQueue(); @@ -130,18 +194,33 @@ private: void onQueueEOS(const sp<AMessage> &msg); void onFlush(const sp<AMessage> &msg); void onAudioSinkChanged(); + void onDisableOffloadAudio(); void onPause(); void onResume(); - - void notifyEOS(bool audio, status_t finalResult); + void onSetVideoFrameRate(float fps); + void onAudioOffloadTearDown(AudioOffloadTearDownReason reason); + bool onOpenAudioSink( + const sp<AMessage> &format, + bool offloadOnly, + bool hasVideo, + uint32_t flags); + void onCloseAudioSink(); + + void notifyEOS(bool audio, status_t finalResult, int64_t delayUs = 0); void notifyFlushComplete(bool audio); void notifyPosition(); void notifyVideoLateBy(int64_t lateByUs); void notifyVideoRenderingStart(); + void notifyAudioOffloadTearDown(); void flushQueue(List<QueueEntry> *queue); bool dropBufferWhileFlushing(bool audio, const sp<AMessage> &msg); - void syncQueuesDone(); + void syncQueuesDone_l(); + + bool offloadingAudio() const { return (mFlags & FLAG_OFFLOAD_AUDIO) != 0; } + + void startAudioOffloadPauseTimeout(); + void cancelAudioOffloadPauseTimeout(); DISALLOW_EVIL_CONSTRUCTORS(Renderer); }; |