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 <media/AudioResamplerPublic.h> 22 #include <media/AVSyncSettings.h> 23 24 #include "NuPlayer.h" 25 26 namespace android { 27 28 class AWakeLock; 29 struct MediaClock; 30 class MediaCodecBuffer; 31 struct VideoFrameSchedulerBase; 32 33 struct NuPlayer::Renderer : public AHandler { 34 enum Flags { 35 FLAG_REAL_TIME = 1, 36 FLAG_OFFLOAD_AUDIO = 2, 37 }; 38 Renderer(const sp<MediaPlayerBase::AudioSink> &sink, 39 const sp<MediaClock> &mediaClock, 40 const sp<AMessage> ¬ify, 41 uint32_t flags = 0); 42 43 static size_t AudioSinkCallback( 44 MediaPlayerBase::AudioSink *audioSink, 45 void *data, size_t size, void *me, 46 MediaPlayerBase::AudioSink::cb_event_t event); 47 48 void queueBuffer( 49 bool audio, 50 const sp<MediaCodecBuffer> &buffer, 51 const sp<AMessage> ¬ifyConsumed); 52 53 void queueEOS(bool audio, status_t finalResult); 54 55 status_t setPlaybackSettings(const AudioPlaybackRate &rate /* sanitized */); 56 status_t getPlaybackSettings(AudioPlaybackRate *rate /* nonnull */); 57 status_t setSyncSettings(const AVSyncSettings &sync, float videoFpsHint); 58 status_t getSyncSettings(AVSyncSettings *sync /* nonnull */, float *videoFps /* nonnull */); 59 60 void flush(bool audio, bool notifyComplete); 61 62 void signalTimeDiscontinuity(); 63 64 void signalDisableOffloadAudio(); 65 void signalEnableOffloadAudio(); 66 67 void pause(); 68 void resume(); 69 70 void setVideoFrameRate(float fps); 71 72 status_t getCurrentPosition(int64_t *mediaUs); 73 int64_t getVideoLateByUs(); 74 75 status_t openAudioSink( 76 const sp<AMessage> &format, 77 bool offloadOnly, 78 bool hasVideo, 79 uint32_t flags, 80 bool *isOffloaded, 81 bool isStreaming); 82 void closeAudioSink(); 83 84 // re-open audio sink after all pending audio buffers played. 85 void changeAudioFormat( 86 const sp<AMessage> &format, 87 bool offloadOnly, 88 bool hasVideo, 89 uint32_t flags, 90 bool isStreaming, 91 const sp<AMessage> ¬ify); 92 93 enum { 94 kWhatEOS = 'eos ', 95 kWhatFlushComplete = 'fluC', 96 kWhatPosition = 'posi', 97 kWhatVideoRenderingStart = 'vdrd', 98 kWhatMediaRenderingStart = 'mdrd', 99 kWhatAudioTearDown = 'adTD', 100 kWhatAudioOffloadPauseTimeout = 'aOPT', 101 }; 102 103 enum AudioTearDownReason { 104 kDueToError = 0, // Could restart with either offload or non-offload. 105 kDueToTimeout, 106 kForceNonOffload, // Restart only with non-offload. 107 }; 108 109 protected: 110 virtual ~Renderer(); 111 112 virtual void onMessageReceived(const sp<AMessage> &msg); 113 114 private: 115 enum { 116 kWhatDrainAudioQueue = 'draA', 117 kWhatDrainVideoQueue = 'draV', 118 kWhatPostDrainVideoQueue = 'pDVQ', 119 kWhatQueueBuffer = 'queB', 120 kWhatQueueEOS = 'qEOS', 121 kWhatConfigPlayback = 'cfPB', 122 kWhatConfigSync = 'cfSy', 123 kWhatGetPlaybackSettings = 'gPbS', 124 kWhatGetSyncSettings = 'gSyS', 125 kWhatFlush = 'flus', 126 kWhatPause = 'paus', 127 kWhatResume = 'resm', 128 kWhatOpenAudioSink = 'opnA', 129 kWhatCloseAudioSink = 'clsA', 130 kWhatChangeAudioFormat = 'chgA', 131 kWhatStopAudioSink = 'stpA', 132 kWhatDisableOffloadAudio = 'noOA', 133 kWhatEnableOffloadAudio = 'enOA', 134 kWhatSetVideoFrameRate = 'sVFR', 135 }; 136 137 // if mBuffer != nullptr, it's a buffer containing real data. 138 // else if mNotifyConsumed == nullptr, it's EOS. 139 // else it's a tag for re-opening audio sink in different format. 140 struct QueueEntry { 141 sp<MediaCodecBuffer> mBuffer; 142 sp<AMessage> mMeta; 143 sp<AMessage> mNotifyConsumed; 144 size_t mOffset; 145 status_t mFinalResult; 146 int32_t mBufferOrdinal; 147 }; 148 149 static const int64_t kMinPositionUpdateDelayUs; 150 151 sp<MediaPlayerBase::AudioSink> mAudioSink; 152 bool mUseVirtualAudioSink; 153 sp<AMessage> mNotify; 154 Mutex mLock; 155 uint32_t mFlags; 156 List<QueueEntry> mAudioQueue; 157 List<QueueEntry> mVideoQueue; 158 uint32_t mNumFramesWritten; 159 sp<VideoFrameSchedulerBase> mVideoScheduler; 160 161 bool mDrainAudioQueuePending; 162 bool mDrainVideoQueuePending; 163 int32_t mAudioQueueGeneration; 164 int32_t mVideoQueueGeneration; 165 int32_t mAudioDrainGeneration; 166 int32_t mVideoDrainGeneration; 167 int32_t mAudioEOSGeneration; 168 169 const sp<MediaClock> mMediaClock; 170 float mPlaybackRate; // audio track rate 171 172 AudioPlaybackRate mPlaybackSettings; 173 AVSyncSettings mSyncSettings; 174 float mVideoFpsHint; 175 176 int64_t mAudioFirstAnchorTimeMediaUs; 177 int64_t mAnchorTimeMediaUs; 178 int64_t mAnchorNumFramesWritten; 179 int64_t mVideoLateByUs; 180 int64_t mNextVideoTimeMediaUs; 181 bool mHasAudio; 182 bool mHasVideo; 183 184 bool mNotifyCompleteAudio; 185 bool mNotifyCompleteVideo; 186 187 bool mSyncQueues; 188 189 // modified on only renderer's thread. 190 bool mPaused; 191 int64_t mPauseDrainAudioAllowedUs; // time when we can drain/deliver audio in pause mode. 192 193 bool mVideoSampleReceived; 194 bool mVideoRenderingStarted; 195 int32_t mVideoRenderingStartGeneration; 196 int32_t mAudioRenderingStartGeneration; 197 bool mRenderingDataDelivered; 198 199 int64_t mNextAudioClockUpdateTimeUs; 200 // the media timestamp of last audio sample right before EOS. 201 int64_t mLastAudioMediaTimeUs; 202 203 int32_t mAudioOffloadPauseTimeoutGeneration; 204 bool mAudioTornDown; 205 audio_offload_info_t mCurrentOffloadInfo; 206 207 struct PcmInfo { 208 audio_channel_mask_t mChannelMask; 209 audio_output_flags_t mFlags; 210 audio_format_t mFormat; 211 int32_t mNumChannels; 212 int32_t mSampleRate; 213 }; 214 PcmInfo mCurrentPcmInfo; 215 static const PcmInfo AUDIO_PCMINFO_INITIALIZER; 216 217 int32_t mTotalBuffersQueued; 218 int32_t mLastAudioBufferDrained; 219 bool mUseAudioCallback; 220 221 sp<AWakeLock> mWakeLock; 222 223 status_t getCurrentPositionOnLooper(int64_t *mediaUs); 224 status_t getCurrentPositionOnLooper( 225 int64_t *mediaUs, int64_t nowUs, bool allowPastQueuedVideo = false); 226 bool getCurrentPositionIfPaused_l(int64_t *mediaUs); 227 status_t getCurrentPositionFromAnchor( 228 int64_t *mediaUs, int64_t nowUs, bool allowPastQueuedVideo = false); 229 230 void notifyEOSCallback(); 231 size_t fillAudioBuffer(void *buffer, size_t size); 232 233 bool onDrainAudioQueue(); 234 void drainAudioQueueUntilLastEOS(); 235 int64_t getPendingAudioPlayoutDurationUs(int64_t nowUs); 236 void postDrainAudioQueue_l(int64_t delayUs = 0); 237 238 void clearAnchorTime(); 239 void clearAudioFirstAnchorTime_l(); 240 void setAudioFirstAnchorTimeIfNeeded_l(int64_t mediaUs); 241 void setVideoLateByUs(int64_t lateUs); 242 243 void onNewAudioMediaTime(int64_t mediaTimeUs); 244 int64_t getRealTimeUs(int64_t mediaTimeUs, int64_t nowUs); 245 246 void onDrainVideoQueue(); 247 void postDrainVideoQueue(); 248 249 void prepareForMediaRenderingStart_l(); 250 void notifyIfMediaRenderingStarted_l(); 251 252 void onQueueBuffer(const sp<AMessage> &msg); 253 void onQueueEOS(const sp<AMessage> &msg); 254 void onFlush(const sp<AMessage> &msg); 255 void onAudioSinkChanged(); 256 void onDisableOffloadAudio(); 257 void onEnableOffloadAudio(); 258 status_t onConfigPlayback(const AudioPlaybackRate &rate /* sanitized */); 259 status_t onGetPlaybackSettings(AudioPlaybackRate *rate /* nonnull */); 260 status_t onConfigSync(const AVSyncSettings &sync, float videoFpsHint); 261 status_t onGetSyncSettings(AVSyncSettings *sync /* nonnull */, float *videoFps /* nonnull */); 262 263 void onPause(); 264 void onResume(); 265 void onSetVideoFrameRate(float fps); 266 int32_t getQueueGeneration(bool audio); 267 int32_t getDrainGeneration(bool audio); 268 bool getSyncQueues(); 269 void onAudioTearDown(AudioTearDownReason reason); 270 status_t onOpenAudioSink( 271 const sp<AMessage> &format, 272 bool offloadOnly, 273 bool hasVideo, 274 uint32_t flags, 275 bool isStreaming); 276 void onCloseAudioSink(); 277 void onChangeAudioFormat(const sp<AMessage> &meta, const sp<AMessage> ¬ify); 278 279 void notifyEOS(bool audio, status_t finalResult, int64_t delayUs = 0); 280 void notifyEOS_l(bool audio, status_t finalResult, int64_t delayUs = 0); 281 void notifyFlushComplete(bool audio); 282 void notifyPosition(); 283 void notifyVideoLateBy(int64_t lateByUs); 284 void notifyVideoRenderingStart(); 285 void notifyAudioTearDown(AudioTearDownReason reason); 286 287 void flushQueue(List<QueueEntry> *queue); 288 bool dropBufferIfStale(bool audio, const sp<AMessage> &msg); 289 void syncQueuesDone_l(); 290 offloadingAudioRenderer291 bool offloadingAudio() const { return (mFlags & FLAG_OFFLOAD_AUDIO) != 0; } 292 293 void startAudioOffloadPauseTimeout(); 294 void cancelAudioOffloadPauseTimeout(); 295 296 int64_t getDurationUsIfPlayedAtSampleRate(uint32_t numFrames); 297 298 DISALLOW_EVIL_CONSTRUCTORS(Renderer); 299 }; 300 301 } // namespace android 302 303 #endif // NUPLAYER_RENDERER_H_ 304