Home | History | Annotate | Download | only in nuplayer
      1 /*
      2  * Copyright (C) 2010 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #ifndef NUPLAYER_RENDERER_H_
     18 
     19 #define NUPLAYER_RENDERER_H_
     20 
     21 #include "NuPlayer.h"
     22 
     23 namespace android {
     24 
     25 struct ABuffer;
     26 struct VideoFrameScheduler;
     27 
     28 struct NuPlayer::Renderer : public AHandler {
     29     enum Flags {
     30         FLAG_REAL_TIME = 1,
     31         FLAG_OFFLOAD_AUDIO = 2,
     32     };
     33     Renderer(const sp<MediaPlayerBase::AudioSink> &sink,
     34              const sp<AMessage> &notify,
     35              uint32_t flags = 0);
     36 
     37     static size_t AudioSinkCallback(
     38             MediaPlayerBase::AudioSink *audioSink,
     39             void *data, size_t size, void *me,
     40             MediaPlayerBase::AudioSink::cb_event_t event);
     41 
     42     void queueBuffer(
     43             bool audio,
     44             const sp<ABuffer> &buffer,
     45             const sp<AMessage> &notifyConsumed);
     46 
     47     void queueEOS(bool audio, status_t finalResult);
     48 
     49     void flush(bool audio);
     50 
     51     void signalTimeDiscontinuity();
     52 
     53     void signalAudioSinkChanged();
     54 
     55     void signalDisableOffloadAudio();
     56 
     57     void pause();
     58     void resume();
     59 
     60     void setVideoFrameRate(float fps);
     61 
     62     // Following setters and getters are protected by mTimeLock.
     63     status_t getCurrentPosition(int64_t *mediaUs);
     64     status_t getCurrentPosition(
     65             int64_t *mediaUs, int64_t nowUs, bool allowPastQueuedVideo = false);
     66     void setHasMedia(bool audio);
     67     void setAudioFirstAnchorTime(int64_t mediaUs);
     68     void setAudioFirstAnchorTimeIfNeeded(int64_t mediaUs);
     69     void setAnchorTime(
     70             int64_t mediaUs, int64_t realUs, int64_t numFramesWritten = -1, bool resume = false);
     71     void setVideoLateByUs(int64_t lateUs);
     72     int64_t getVideoLateByUs();
     73     void setPauseStartedTimeRealUs(int64_t realUs);
     74 
     75     bool openAudioSink(
     76             const sp<AMessage> &format,
     77             bool offloadOnly,
     78             bool hasVideo,
     79             uint32_t flags);
     80     void closeAudioSink();
     81 
     82     enum {
     83         kWhatEOS                 = 'eos ',
     84         kWhatFlushComplete       = 'fluC',
     85         kWhatPosition            = 'posi',
     86         kWhatVideoRenderingStart = 'vdrd',
     87         kWhatMediaRenderingStart = 'mdrd',
     88         kWhatAudioOffloadTearDown = 'aOTD',
     89         kWhatAudioOffloadPauseTimeout = 'aOPT',
     90     };
     91 
     92     enum AudioOffloadTearDownReason {
     93         kDueToError = 0,
     94         kDueToTimeout,
     95     };
     96 
     97 protected:
     98     virtual ~Renderer();
     99 
    100     virtual void onMessageReceived(const sp<AMessage> &msg);
    101 
    102 private:
    103     enum {
    104         kWhatDrainAudioQueue     = 'draA',
    105         kWhatDrainVideoQueue     = 'draV',
    106         kWhatPostDrainVideoQueue = 'pDVQ',
    107         kWhatQueueBuffer         = 'queB',
    108         kWhatQueueEOS            = 'qEOS',
    109         kWhatFlush               = 'flus',
    110         kWhatAudioSinkChanged    = 'auSC',
    111         kWhatPause               = 'paus',
    112         kWhatResume              = 'resm',
    113         kWhatOpenAudioSink       = 'opnA',
    114         kWhatCloseAudioSink      = 'clsA',
    115         kWhatStopAudioSink       = 'stpA',
    116         kWhatDisableOffloadAudio = 'noOA',
    117         kWhatSetVideoFrameRate   = 'sVFR',
    118     };
    119 
    120     struct QueueEntry {
    121         sp<ABuffer> mBuffer;
    122         sp<AMessage> mNotifyConsumed;
    123         size_t mOffset;
    124         status_t mFinalResult;
    125         int32_t mBufferOrdinal;
    126     };
    127 
    128     static const int64_t kMinPositionUpdateDelayUs;
    129 
    130     sp<MediaPlayerBase::AudioSink> mAudioSink;
    131     sp<AMessage> mNotify;
    132     Mutex mLock;
    133     uint32_t mFlags;
    134     List<QueueEntry> mAudioQueue;
    135     List<QueueEntry> mVideoQueue;
    136     uint32_t mNumFramesWritten;
    137     sp<VideoFrameScheduler> mVideoScheduler;
    138 
    139     bool mDrainAudioQueuePending;
    140     bool mDrainVideoQueuePending;
    141     int32_t mAudioQueueGeneration;
    142     int32_t mVideoQueueGeneration;
    143 
    144     Mutex mTimeLock;
    145     // |mTimeLock| protects the following 7 member vars that are related to time.
    146     // Note: those members are only written on Renderer thread, so reading on Renderer thread
    147     // doesn't need to be protected. Otherwise accessing those members must be protected by
    148     // |mTimeLock|.
    149     // TODO: move those members to a seperated media clock class.
    150     int64_t mAudioFirstAnchorTimeMediaUs;
    151     int64_t mAnchorTimeMediaUs;
    152     int64_t mAnchorTimeRealUs;
    153     int64_t mAnchorNumFramesWritten;
    154     int64_t mAnchorMaxMediaUs;
    155     int64_t mVideoLateByUs;
    156     bool mHasAudio;
    157     bool mHasVideo;
    158     int64_t mPauseStartedTimeRealUs;
    159 
    160     Mutex mFlushLock;  // protects the following 2 member vars.
    161     bool mFlushingAudio;
    162     bool mFlushingVideo;
    163 
    164     bool mSyncQueues;
    165 
    166     bool mPaused;
    167     bool mVideoSampleReceived;
    168     bool mVideoRenderingStarted;
    169     int32_t mVideoRenderingStartGeneration;
    170     int32_t mAudioRenderingStartGeneration;
    171 
    172     int64_t mLastPositionUpdateUs;
    173 
    174     int32_t mAudioOffloadPauseTimeoutGeneration;
    175     bool mAudioOffloadTornDown;
    176     audio_offload_info_t mCurrentOffloadInfo;
    177 
    178     int32_t mTotalBuffersQueued;
    179     int32_t mLastAudioBufferDrained;
    180 
    181 
    182     size_t fillAudioBuffer(void *buffer, size_t size);
    183 
    184     bool onDrainAudioQueue();
    185     int64_t getPendingAudioPlayoutDurationUs(int64_t nowUs);
    186     int64_t getPlayedOutAudioDurationUs(int64_t nowUs);
    187     void postDrainAudioQueue_l(int64_t delayUs = 0);
    188 
    189     void onNewAudioMediaTime(int64_t mediaTimeUs);
    190     int64_t getRealTimeUs(int64_t mediaTimeUs, int64_t nowUs);
    191 
    192     void onDrainVideoQueue();
    193     void postDrainVideoQueue();
    194 
    195     void prepareForMediaRenderingStart();
    196     void notifyIfMediaRenderingStarted();
    197 
    198     void onQueueBuffer(const sp<AMessage> &msg);
    199     void onQueueEOS(const sp<AMessage> &msg);
    200     void onFlush(const sp<AMessage> &msg);
    201     void onAudioSinkChanged();
    202     void onDisableOffloadAudio();
    203     void onPause();
    204     void onResume();
    205     void onSetVideoFrameRate(float fps);
    206     void onAudioOffloadTearDown(AudioOffloadTearDownReason reason);
    207     bool onOpenAudioSink(
    208             const sp<AMessage> &format,
    209             bool offloadOnly,
    210             bool hasVideo,
    211             uint32_t flags);
    212     void onCloseAudioSink();
    213 
    214     void notifyEOS(bool audio, status_t finalResult, int64_t delayUs = 0);
    215     void notifyFlushComplete(bool audio);
    216     void notifyPosition();
    217     void notifyVideoLateBy(int64_t lateByUs);
    218     void notifyVideoRenderingStart();
    219     void notifyAudioOffloadTearDown();
    220 
    221     void flushQueue(List<QueueEntry> *queue);
    222     bool dropBufferWhileFlushing(bool audio, const sp<AMessage> &msg);
    223     void syncQueuesDone_l();
    224 
    225     bool offloadingAudio() const { return (mFlags & FLAG_OFFLOAD_AUDIO) != 0; }
    226 
    227     void startAudioOffloadPauseTimeout();
    228     void cancelAudioOffloadPauseTimeout();
    229 
    230     DISALLOW_EVIL_CONSTRUCTORS(Renderer);
    231 };
    232 
    233 }  // namespace android
    234 
    235 #endif  // NUPLAYER_RENDERER_H_
    236