NuPlayerRenderer.h revision 7b15cb33847e6282ea8352c98894683b796127f3
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
23namespace android {
24
25struct ABuffer;
26struct MediaClock;
27struct VideoFrameScheduler;
28
29struct NuPlayer::Renderer : public AHandler {
30    enum Flags {
31        FLAG_REAL_TIME = 1,
32        FLAG_OFFLOAD_AUDIO = 2,
33    };
34    Renderer(const sp<MediaPlayerBase::AudioSink> &sink,
35             const sp<AMessage> &notify,
36             uint32_t flags = 0);
37
38    static size_t AudioSinkCallback(
39            MediaPlayerBase::AudioSink *audioSink,
40            void *data, size_t size, void *me,
41            MediaPlayerBase::AudioSink::cb_event_t event);
42
43    void queueBuffer(
44            bool audio,
45            const sp<ABuffer> &buffer,
46            const sp<AMessage> &notifyConsumed);
47
48    void queueEOS(bool audio, status_t finalResult);
49
50    void flush(bool audio, bool notifyComplete);
51
52    void signalTimeDiscontinuity();
53
54    void signalAudioSinkChanged();
55
56    void signalDisableOffloadAudio();
57    void signalEnableOffloadAudio();
58
59    void pause();
60    void resume();
61
62    void setVideoFrameRate(float fps);
63
64    status_t getCurrentPosition(int64_t *mediaUs);
65    int64_t getVideoLateByUs();
66
67    status_t openAudioSink(
68            const sp<AMessage> &format,
69            bool offloadOnly,
70            bool hasVideo,
71            uint32_t flags,
72            bool *isOffloaded);
73    void closeAudioSink();
74
75    enum {
76        kWhatEOS                 = 'eos ',
77        kWhatFlushComplete       = 'fluC',
78        kWhatPosition            = 'posi',
79        kWhatVideoRenderingStart = 'vdrd',
80        kWhatMediaRenderingStart = 'mdrd',
81        kWhatAudioOffloadTearDown = 'aOTD',
82        kWhatAudioOffloadPauseTimeout = 'aOPT',
83    };
84
85    enum AudioOffloadTearDownReason {
86        kDueToError = 0,
87        kDueToTimeout,
88    };
89
90protected:
91    virtual ~Renderer();
92
93    virtual void onMessageReceived(const sp<AMessage> &msg);
94
95private:
96    enum {
97        kWhatDrainAudioQueue     = 'draA',
98        kWhatDrainVideoQueue     = 'draV',
99        kWhatPostDrainVideoQueue = 'pDVQ',
100        kWhatQueueBuffer         = 'queB',
101        kWhatQueueEOS            = 'qEOS',
102        kWhatFlush               = 'flus',
103        kWhatPause               = 'paus',
104        kWhatResume              = 'resm',
105        kWhatOpenAudioSink       = 'opnA',
106        kWhatCloseAudioSink      = 'clsA',
107        kWhatStopAudioSink       = 'stpA',
108        kWhatDisableOffloadAudio = 'noOA',
109        kWhatEnableOffloadAudio  = 'enOA',
110        kWhatSetVideoFrameRate   = 'sVFR',
111    };
112
113    struct QueueEntry {
114        sp<ABuffer> mBuffer;
115        sp<AMessage> mNotifyConsumed;
116        size_t mOffset;
117        status_t mFinalResult;
118        int32_t mBufferOrdinal;
119    };
120
121    static const int64_t kMinPositionUpdateDelayUs;
122
123    sp<MediaPlayerBase::AudioSink> mAudioSink;
124    sp<AMessage> mNotify;
125    Mutex mLock;
126    uint32_t mFlags;
127    List<QueueEntry> mAudioQueue;
128    List<QueueEntry> mVideoQueue;
129    uint32_t mNumFramesWritten;
130    sp<VideoFrameScheduler> mVideoScheduler;
131
132    bool mDrainAudioQueuePending;
133    bool mDrainVideoQueuePending;
134    int32_t mAudioQueueGeneration;
135    int32_t mVideoQueueGeneration;
136    int32_t mAudioDrainGeneration;
137    int32_t mVideoDrainGeneration;
138
139    sp<MediaClock> mMediaClock;
140    int64_t mAudioFirstAnchorTimeMediaUs;
141    int64_t mAnchorTimeMediaUs;
142    int64_t mAnchorNumFramesWritten;
143    int64_t mVideoLateByUs;
144    bool mHasAudio;
145    bool mHasVideo;
146
147    bool mNotifyCompleteAudio;
148    bool mNotifyCompleteVideo;
149
150    bool mSyncQueues;
151
152    // modified on only renderer's thread.
153    bool mPaused;
154
155    bool mVideoSampleReceived;
156    bool mVideoRenderingStarted;
157    int32_t mVideoRenderingStartGeneration;
158    int32_t mAudioRenderingStartGeneration;
159
160    int64_t mLastPositionUpdateUs;
161
162    int32_t mAudioOffloadPauseTimeoutGeneration;
163    bool mAudioOffloadTornDown;
164    audio_offload_info_t mCurrentOffloadInfo;
165
166    struct PcmInfo {
167        audio_channel_mask_t mChannelMask;
168        audio_output_flags_t mFlags;
169        audio_format_t mFormat;
170        int32_t mNumChannels;
171        int32_t mSampleRate;
172    };
173    PcmInfo mCurrentPcmInfo;
174    static const PcmInfo AUDIO_PCMINFO_INITIALIZER;
175
176    int32_t mTotalBuffersQueued;
177    int32_t mLastAudioBufferDrained;
178
179    size_t fillAudioBuffer(void *buffer, size_t size);
180
181    bool onDrainAudioQueue();
182    int64_t getPendingAudioPlayoutDurationUs(int64_t nowUs);
183    int64_t getPlayedOutAudioDurationUs(int64_t nowUs);
184    void postDrainAudioQueue_l(int64_t delayUs = 0);
185
186    void clearAnchorTime_l();
187    void clearAudioFirstAnchorTime_l();
188    void setAudioFirstAnchorTimeIfNeeded_l(int64_t mediaUs);
189    void setVideoLateByUs(int64_t lateUs);
190
191    void onNewAudioMediaTime(int64_t mediaTimeUs);
192    int64_t getRealTimeUs(int64_t mediaTimeUs, int64_t nowUs);
193
194    void onDrainVideoQueue();
195    void postDrainVideoQueue();
196
197    void prepareForMediaRenderingStart_l();
198    void notifyIfMediaRenderingStarted_l();
199
200    void onQueueBuffer(const sp<AMessage> &msg);
201    void onQueueEOS(const sp<AMessage> &msg);
202    void onFlush(const sp<AMessage> &msg);
203    void onAudioSinkChanged();
204    void onDisableOffloadAudio();
205    void onEnableOffloadAudio();
206    void onPause();
207    void onResume();
208    void onSetVideoFrameRate(float fps);
209    int32_t getQueueGeneration(bool audio);
210    int32_t getDrainGeneration(bool audio);
211    bool getSyncQueues();
212    void onAudioOffloadTearDown(AudioOffloadTearDownReason reason);
213    status_t onOpenAudioSink(
214            const sp<AMessage> &format,
215            bool offloadOnly,
216            bool hasVideo,
217            uint32_t flags);
218    void onCloseAudioSink();
219
220    void notifyEOS(bool audio, status_t finalResult, int64_t delayUs = 0);
221    void notifyFlushComplete(bool audio);
222    void notifyPosition();
223    void notifyVideoLateBy(int64_t lateByUs);
224    void notifyVideoRenderingStart();
225    void notifyAudioOffloadTearDown();
226
227    void flushQueue(List<QueueEntry> *queue);
228    bool dropBufferIfStale(bool audio, const sp<AMessage> &msg);
229    void syncQueuesDone_l();
230
231    bool offloadingAudio() const { return (mFlags & FLAG_OFFLOAD_AUDIO) != 0; }
232
233    void startAudioOffloadPauseTimeout();
234    void cancelAudioOffloadPauseTimeout();
235
236    DISALLOW_EVIL_CONSTRUCTORS(Renderer);
237};
238
239}  // namespace android
240
241#endif  // NUPLAYER_RENDERER_H_
242