blob: 3007654cfc5a7421a708ae885e8504f01f08ff15 [file] [log] [blame]
Wei Jia53692fa2017-12-11 10:33:46 -08001/*
2 * Copyright 2017 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 NUPLAYER2_RENDERER_H_
18
19#define NUPLAYER2_RENDERER_H_
20
21#include <media/AudioResamplerPublic.h>
22#include <media/AVSyncSettings.h>
23
24#include "NuPlayer2.h"
25
26namespace android {
27
28class JWakeLock;
29struct MediaClock;
30class MediaCodecBuffer;
31struct VideoFrameScheduler;
32
33struct NuPlayer2::Renderer : public AHandler {
34 enum Flags {
35 FLAG_REAL_TIME = 1,
36 FLAG_OFFLOAD_AUDIO = 2,
37 };
38 Renderer(const sp<MediaPlayer2Base::AudioSink> &sink,
39 const sp<MediaClock> &mediaClock,
40 const sp<AMessage> &notify,
41 uint32_t flags = 0);
42
43 static size_t AudioSinkCallback(
44 MediaPlayer2Base::AudioSink *audioSink,
45 void *data, size_t size, void *me,
46 MediaPlayer2Base::AudioSink::cb_event_t event);
47
48 void queueBuffer(
49 bool audio,
50 const sp<MediaCodecBuffer> &buffer,
51 const sp<AMessage> &notifyConsumed);
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> &notify);
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
109protected:
110 virtual ~Renderer();
111
112 virtual void onMessageReceived(const sp<AMessage> &msg);
113
114private:
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<MediaPlayer2Base::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<VideoFrameScheduler> 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<JWakeLock> 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> &notify);
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
291 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 // NUPLAYER2_RENDERER_H_