content/media/omx/AudioOffloadPlayer.h

branch
TOR_BUG_9701
changeset 13
44a2da4a2ab2
equal deleted inserted replaced
-1:000000000000 0:69cb6ffc9189
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim:set ts=2 sw=2 sts=2 et cindent: */
3 /*
4 * Copyright (c) 2014 The Linux Foundation. All rights reserved.
5 * Copyright (C) 2009 The Android Open Source Project
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 */
19
20 #ifndef AUDIO_OFFLOAD_PLAYER_H_
21 #define AUDIO_OFFLOAD_PLAYER_H_
22
23 #include <stagefright/MediaBuffer.h>
24 #include <stagefright/MediaSource.h>
25 #include <stagefright/TimeSource.h>
26 #include <utils/threads.h>
27 #include <utils/RefBase.h>
28
29 #include "AudioOutput.h"
30
31 #include "MediaDecoderOwner.h"
32 #include "MediaOmxDecoder.h"
33
34 namespace mozilla {
35
36 class MediaOmxDecoder;
37
38 /**
39 * AudioOffloadPlayer adds support for audio tunneling to a digital signal
40 * processor (DSP) in the device chipset. With tunneling, audio decoding is
41 * off-loaded to the DSP, waking the application processor less often and using
42 * less battery
43 *
44 * This depends on offloading capability provided by Android KK AudioTrack class
45 *
46 * Audio playback is based on pull mechanism, whenever audio sink needs
47 * data, FillBuffer() will read data from compressed audio source and provide
48 * it to the sink
49 *
50 * Also this class passes state changes (play/pause/seek) from MediaOmxDecoder
51 * to AudioSink as well as provide AudioSink status (position changed,
52 * playback ended, seek complete, audio tear down) back to MediaOmxDecoder
53 *
54 * It acts as a bridge between MediaOmxDecoder and AudioSink during
55 * offload playback
56 */
57
58 class AudioOffloadPlayer : public AudioOffloadPlayerBase
59 {
60 typedef android::Mutex Mutex;
61 typedef android::MetaData MetaData;
62 typedef android::status_t status_t;
63 typedef android::AudioTrack AudioTrack;
64 typedef android::MediaBuffer MediaBuffer;
65 typedef android::MediaSource MediaSource;
66
67 public:
68 enum {
69 REACHED_EOS,
70 SEEK_COMPLETE
71 };
72
73 AudioOffloadPlayer(MediaOmxDecoder* aDecoder = nullptr);
74
75 ~AudioOffloadPlayer();
76
77 // Caller retains ownership of "aSource".
78 void SetSource(const android::sp<MediaSource> &aSource);
79
80 // Start the source if it's not already started and open the AudioSink to
81 // create an offloaded audio track
82 status_t Start(bool aSourceAlreadyStarted = false);
83
84 double GetMediaTimeSecs();
85
86 // To update progress bar when the element is visible
87 void SetElementVisibility(bool aIsVisible);
88
89 status_t ChangeState(MediaDecoder::PlayState aState);
90
91 void SetVolume(double aVolume);
92
93 // Update ready state based on current play state. Not checking data
94 // availability since offloading is currently done only when whole compressed
95 // data is available
96 MediaDecoderOwner::NextFrameStatus GetNextFrameStatus();
97
98 void TimeUpdate();
99
100 // Close the audio sink, stop time updates, frees the input buffers
101 void Reset();
102
103 private:
104 // Set when audio source is started and audioSink is initialized
105 // Used only in main thread
106 bool mStarted;
107
108 // Set when audio sink is started. i.e. playback started
109 // Used only in main thread
110 bool mPlaying;
111
112 // Set when playstate is seeking and reset when FillBUffer() acknowledged
113 // seeking by seeking audio source. Used in main thread and offload
114 // callback thread, protected by Mutex mLock
115 bool mSeeking;
116
117 // Once playback reached end of stream (last ~100ms), position provided by DSP
118 // may be reset/corrupted. This bool is used to avoid that.
119 // Used in main thread and offload callback thread, protected by Mutex
120 // mLock
121 bool mReachedEOS;
122
123 // Set when there is a seek request during pause.
124 // Used in main thread and offload callback thread, protected by Mutex
125 // mLock
126 bool mSeekDuringPause;
127
128 // Seek can be triggered internally or by MediaDecoder. This bool is to
129 // to track seek triggered by MediaDecoder so that we can send back
130 // SeekingStarted and SeekingStopped events.
131 // Used in main thread and offload callback thread, protected by Mutex mLock
132 bool mDispatchSeekEvents;
133
134 // Set when the HTML Audio Element is visible to the user.
135 // Used only in main thread
136 bool mIsElementVisible;
137
138 // Session id given by Android::AudioSystem and used while creating audio sink
139 // Used only in main thread
140 int mSessionId;
141
142 // Sample rate of current audio track. Used only in main thread
143 int mSampleRate;
144
145 // After seeking, positions returned by offlaoded tracks (DSP) will be
146 // relative to the seeked position. And seeked position may be slightly
147 // different than given mSeekTimeUs, if audio source cannot find a frame at
148 // that position. Store seeked position in mStartPosUs and provide
149 // mStartPosUs + GetPosition() (i.e. absolute position) to MediaOmxDecoder
150 // Used in main thread and offload callback thread, protected by Mutex
151 // mLock
152 int64_t mStartPosUs;
153
154 // Given seek time when there is a request to seek
155 // Used in main thread and offload callback thread, protected by Mutex
156 // mLock
157 int64_t mSeekTimeUs;
158
159 // Positions obtained from offlaoded tracks (DSP)
160 // Used in main thread and offload callback thread, protected by Mutex
161 // mLock
162 int64_t mPositionTimeMediaUs;
163
164 // State obtained from MediaOmxDecoder. Used only in main thread
165 MediaDecoder::PlayState mPlayState;
166
167 // Protect accessing audio position related variables between main thread and
168 // offload callback thread
169 Mutex mLock;
170
171 // Compressed audio source.
172 // Used in main thread first and later in offload callback thread
173 android::sp<MediaSource> mSource;
174
175 // Audio sink wrapper to access offloaded audio tracks
176 // Used in main thread and offload callback thread
177 // Race conditions are protected in underlying Android::AudioTrack class
178 android::sp<AudioSink> mAudioSink;
179
180 // Buffer used to get date from audio source. Used in offload callback thread
181 MediaBuffer* mInputBuffer;
182
183 // MediaOmxDecoder object used mainly to notify the audio sink status
184 MediaOmxDecoder* mObserver;
185
186 TimeStamp mLastFireUpdateTime;
187
188 // Timer to trigger position changed events
189 nsCOMPtr<nsITimer> mTimeUpdateTimer;
190
191 // Timer to reset AudioSink when audio is paused for OFFLOAD_PAUSE_MAX_USECS.
192 // It is triggered in Pause() and canceled when there is a Play() within
193 // OFFLOAD_PAUSE_MAX_USECS. Used only from main thread so no lock is needed.
194 nsCOMPtr<nsITimer> mResetTimer;
195
196 int64_t GetMediaTimeUs();
197
198 // Provide the playback position in microseconds from total number of
199 // frames played by audio track
200 int64_t GetOutputPlayPositionUs_l() const;
201
202 // Fill the buffer given by audio sink with data from compressed audio
203 // source. Also handles the seek by seeking audio source and stop the sink in
204 // case of error
205 size_t FillBuffer(void *aData, size_t aSize);
206
207 // Called by AudioSink when it needs data, to notify EOS or tear down event
208 static size_t AudioSinkCallback(AudioSink *aAudioSink,
209 void *aData,
210 size_t aSize,
211 void *aMe,
212 AudioSink::cb_event_t aEvent);
213
214 bool IsSeeking();
215
216 // Set mSeekTime to the given position and restart the sink. Actual seek
217 // happens in FillBuffer(). If aDispatchSeekEvents is true, send
218 // SeekingStarted event always and SeekingStopped event when the play state is
219 // paused to MediaDecoder.
220 // When decoding and playing happens separately, if there is a seek during
221 // pause, we can decode and keep data ready.
222 // In case of offload player, no way to seek during pause. So just fake that
223 // seek is done.
224 status_t SeekTo(int64_t aTimeUs, bool aDispatchSeekEvents = false);
225
226 // Start/Resume the audio sink so that callback will start being called to get
227 // compressed data
228 status_t Play();
229
230 // Stop the audio sink if we need to play till we drain the current buffer.
231 // or Pause the sink in case we should stop playing immediately
232 void Pause(bool aPlayPendingSamples = false);
233
234 // When audio is offloaded, application processor wakes up less frequently
235 // (>1sec) But when Player UI is visible we need to update progress bar
236 // atleast once in 250ms. Start a timer when player UI becomes visible or
237 // audio starts playing to send PlaybackPositionChanged events once in 250ms.
238 // Stop the timer when UI goes invisible or play state is not playing.
239 // Also make sure timer functions are always called from main thread
240 nsresult StartTimeUpdate();
241 nsresult StopTimeUpdate();
242
243 // Notify end of stream by sending PlaybackEnded event to observer
244 // (i.e.MediaDecoder)
245 void NotifyAudioEOS();
246
247 // Notify position changed event by sending PlaybackPositionChanged event to
248 // observer
249 void NotifyPositionChanged();
250
251 // Offloaded audio track is invalidated due to usecase change. Notify
252 // MediaDecoder to re-evaluate offloading options
253 void NotifyAudioTearDown();
254
255 // Send information from MetaData to the HAL via AudioSink
256 void SendMetaDataToHal(android::sp<AudioSink>& aSink,
257 const android::sp<MetaData>& aMeta);
258
259 AudioOffloadPlayer(const AudioOffloadPlayer &);
260 AudioOffloadPlayer &operator=(const AudioOffloadPlayer &);
261 };
262
263 } // namespace mozilla
264
265 #endif // AUDIO_OFFLOAD_PLAYER_H_

mercurial