blob: 484d9b73d8f58a75a8380ee5eb5e55a35920a729 [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;
Dichen Zhangc37b1902018-12-18 11:36:13 -080031struct VideoFrameSchedulerBase;
Wei Jia53692fa2017-12-11 10:33:46 -080032
33struct NuPlayer2::Renderer : public AHandler {
34 enum Flags {
35 FLAG_REAL_TIME = 1,
36 FLAG_OFFLOAD_AUDIO = 2,
37 };
Wei Jia33abcc72018-01-30 09:47:38 -080038 Renderer(const sp<MediaPlayer2Interface::AudioSink> &sink,
Wei Jia53692fa2017-12-11 10:33:46 -080039 const sp<MediaClock> &mediaClock,
40 const sp<AMessage> &notify,
41 uint32_t flags = 0);
42
43 static size_t AudioSinkCallback(
Wei Jia33abcc72018-01-30 09:47:38 -080044 MediaPlayer2Interface::AudioSink *audioSink,
Wei Jia53692fa2017-12-11 10:33:46 -080045 void *data, size_t size, void *me,
Wei Jia33abcc72018-01-30 09:47:38 -080046 MediaPlayer2Interface::AudioSink::cb_event_t event);
Wei Jia53692fa2017-12-11 10:33:46 -080047
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
Wei Jia33abcc72018-01-30 09:47:38 -0800151 sp<MediaPlayer2Interface::AudioSink> mAudioSink;
Wei Jia53692fa2017-12-11 10:33:46 -0800152 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;
Dichen Zhangc37b1902018-12-18 11:36:13 -0800159 sp<VideoFrameSchedulerBase> mVideoScheduler;
Wei Jia53692fa2017-12-11 10:33:46 -0800160
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;
Wei Jia53692fa2017-12-11 10:33:46 -0800170
171 AudioPlaybackRate mPlaybackSettings;
172 AVSyncSettings mSyncSettings;
173 float mVideoFpsHint;
174
175 int64_t mAudioFirstAnchorTimeMediaUs;
176 int64_t mAnchorTimeMediaUs;
177 int64_t mAnchorNumFramesWritten;
178 int64_t mVideoLateByUs;
179 int64_t mNextVideoTimeMediaUs;
180 bool mHasAudio;
181 bool mHasVideo;
182
183 bool mNotifyCompleteAudio;
184 bool mNotifyCompleteVideo;
185
186 bool mSyncQueues;
187
188 // modified on only renderer's thread.
189 bool mPaused;
190 int64_t mPauseDrainAudioAllowedUs; // time when we can drain/deliver audio in pause mode.
191
192 bool mVideoSampleReceived;
193 bool mVideoRenderingStarted;
194 int32_t mVideoRenderingStartGeneration;
195 int32_t mAudioRenderingStartGeneration;
196 bool mRenderingDataDelivered;
197
198 int64_t mNextAudioClockUpdateTimeUs;
199 // the media timestamp of last audio sample right before EOS.
200 int64_t mLastAudioMediaTimeUs;
201
202 int32_t mAudioOffloadPauseTimeoutGeneration;
203 bool mAudioTornDown;
204 audio_offload_info_t mCurrentOffloadInfo;
205
206 struct PcmInfo {
207 audio_channel_mask_t mChannelMask;
208 audio_output_flags_t mFlags;
209 audio_format_t mFormat;
210 int32_t mNumChannels;
211 int32_t mSampleRate;
212 };
213 PcmInfo mCurrentPcmInfo;
214 static const PcmInfo AUDIO_PCMINFO_INITIALIZER;
215
216 int32_t mTotalBuffersQueued;
217 int32_t mLastAudioBufferDrained;
218 bool mUseAudioCallback;
219
220 sp<JWakeLock> mWakeLock;
221
222 status_t getCurrentPositionOnLooper(int64_t *mediaUs);
223 status_t getCurrentPositionOnLooper(
224 int64_t *mediaUs, int64_t nowUs, bool allowPastQueuedVideo = false);
225 bool getCurrentPositionIfPaused_l(int64_t *mediaUs);
226 status_t getCurrentPositionFromAnchor(
227 int64_t *mediaUs, int64_t nowUs, bool allowPastQueuedVideo = false);
228
229 void notifyEOSCallback();
230 size_t fillAudioBuffer(void *buffer, size_t size);
231
232 bool onDrainAudioQueue();
233 void drainAudioQueueUntilLastEOS();
234 int64_t getPendingAudioPlayoutDurationUs(int64_t nowUs);
235 void postDrainAudioQueue_l(int64_t delayUs = 0);
236
237 void clearAnchorTime();
238 void clearAudioFirstAnchorTime_l();
239 void setAudioFirstAnchorTimeIfNeeded_l(int64_t mediaUs);
240 void setVideoLateByUs(int64_t lateUs);
241
242 void onNewAudioMediaTime(int64_t mediaTimeUs);
243 int64_t getRealTimeUs(int64_t mediaTimeUs, int64_t nowUs);
244
245 void onDrainVideoQueue();
246 void postDrainVideoQueue();
247
248 void prepareForMediaRenderingStart_l();
249 void notifyIfMediaRenderingStarted_l();
250
251 void onQueueBuffer(const sp<AMessage> &msg);
252 void onQueueEOS(const sp<AMessage> &msg);
253 void onFlush(const sp<AMessage> &msg);
254 void onAudioSinkChanged();
255 void onDisableOffloadAudio();
256 void onEnableOffloadAudio();
257 status_t onConfigPlayback(const AudioPlaybackRate &rate /* sanitized */);
258 status_t onGetPlaybackSettings(AudioPlaybackRate *rate /* nonnull */);
259 status_t onConfigSync(const AVSyncSettings &sync, float videoFpsHint);
260 status_t onGetSyncSettings(AVSyncSettings *sync /* nonnull */, float *videoFps /* nonnull */);
261
262 void onPause();
263 void onResume();
264 void onSetVideoFrameRate(float fps);
265 int32_t getQueueGeneration(bool audio);
266 int32_t getDrainGeneration(bool audio);
267 bool getSyncQueues();
268 void onAudioTearDown(AudioTearDownReason reason);
269 status_t onOpenAudioSink(
270 const sp<AMessage> &format,
271 bool offloadOnly,
272 bool hasVideo,
273 uint32_t flags,
274 bool isStreaming);
275 void onCloseAudioSink();
276 void onChangeAudioFormat(const sp<AMessage> &meta, const sp<AMessage> &notify);
277
278 void notifyEOS(bool audio, status_t finalResult, int64_t delayUs = 0);
279 void notifyEOS_l(bool audio, status_t finalResult, int64_t delayUs = 0);
280 void notifyFlushComplete(bool audio);
281 void notifyPosition();
282 void notifyVideoLateBy(int64_t lateByUs);
283 void notifyVideoRenderingStart();
284 void notifyAudioTearDown(AudioTearDownReason reason);
285
286 void flushQueue(List<QueueEntry> *queue);
287 bool dropBufferIfStale(bool audio, const sp<AMessage> &msg);
288 void syncQueuesDone_l();
289
290 bool offloadingAudio() const { return (mFlags & FLAG_OFFLOAD_AUDIO) != 0; }
291
292 void startAudioOffloadPauseTimeout();
293 void cancelAudioOffloadPauseTimeout();
294
295 int64_t getDurationUsIfPlayedAtSampleRate(uint32_t numFrames);
296
297 DISALLOW_EVIL_CONSTRUCTORS(Renderer);
298};
299
300} // namespace android
301
302#endif // NUPLAYER2_RENDERER_H_