content/media/omx/AudioOffloadPlayer.h

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rwxr-xr-x

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

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

mercurial