content/media/omx/AudioOffloadPlayer.h

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/content/media/omx/AudioOffloadPlayer.h	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,265 @@
     1.4 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
     1.5 +/* vim:set ts=2 sw=2 sts=2 et cindent: */
     1.6 +/*
     1.7 + * Copyright (c) 2014 The Linux Foundation. All rights reserved.
     1.8 + * Copyright (C) 2009 The Android Open Source Project
     1.9 + *
    1.10 + * Licensed under the Apache License, Version 2.0 (the "License");
    1.11 + * you may not use this file except in compliance with the License.
    1.12 + * You may obtain a copy of the License at
    1.13 + *
    1.14 + *      http://www.apache.org/licenses/LICENSE-2.0
    1.15 + *
    1.16 + * Unless required by applicable law or agreed to in writing, software
    1.17 + * distributed under the License is distributed on an "AS IS" BASIS,
    1.18 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    1.19 + * See the License for the specific language governing permissions and
    1.20 + * limitations under the License.
    1.21 + */
    1.22 +
    1.23 +#ifndef AUDIO_OFFLOAD_PLAYER_H_
    1.24 +#define AUDIO_OFFLOAD_PLAYER_H_
    1.25 +
    1.26 +#include <stagefright/MediaBuffer.h>
    1.27 +#include <stagefright/MediaSource.h>
    1.28 +#include <stagefright/TimeSource.h>
    1.29 +#include <utils/threads.h>
    1.30 +#include <utils/RefBase.h>
    1.31 +
    1.32 +#include "AudioOutput.h"
    1.33 +
    1.34 +#include "MediaDecoderOwner.h"
    1.35 +#include "MediaOmxDecoder.h"
    1.36 +
    1.37 +namespace mozilla {
    1.38 +
    1.39 +class MediaOmxDecoder;
    1.40 +
    1.41 +/**
    1.42 + * AudioOffloadPlayer adds support for audio tunneling to a digital signal
    1.43 + * processor (DSP) in the device chipset. With tunneling, audio decoding is
    1.44 + * off-loaded to the DSP, waking the application processor less often and using
    1.45 + * less battery
    1.46 + *
    1.47 + * This depends on offloading capability provided by Android KK AudioTrack class
    1.48 + *
    1.49 + * Audio playback is based on pull mechanism, whenever audio sink needs
    1.50 + * data, FillBuffer() will read data from compressed audio source and provide
    1.51 + * it to the sink
    1.52 + *
    1.53 + * Also this class passes state changes (play/pause/seek) from MediaOmxDecoder
    1.54 + * to AudioSink as well as provide AudioSink status (position changed,
    1.55 + * playback ended, seek complete, audio tear down) back to MediaOmxDecoder
    1.56 + *
    1.57 + * It acts as a bridge between MediaOmxDecoder and AudioSink during
    1.58 + * offload playback
    1.59 + */
    1.60 +
    1.61 +class AudioOffloadPlayer : public AudioOffloadPlayerBase
    1.62 +{
    1.63 +  typedef android::Mutex Mutex;
    1.64 +  typedef android::MetaData MetaData;
    1.65 +  typedef android::status_t status_t;
    1.66 +  typedef android::AudioTrack AudioTrack;
    1.67 +  typedef android::MediaBuffer MediaBuffer;
    1.68 +  typedef android::MediaSource MediaSource;
    1.69 +
    1.70 +public:
    1.71 +  enum {
    1.72 +    REACHED_EOS,
    1.73 +    SEEK_COMPLETE
    1.74 +  };
    1.75 +
    1.76 +  AudioOffloadPlayer(MediaOmxDecoder* aDecoder = nullptr);
    1.77 +
    1.78 +  ~AudioOffloadPlayer();
    1.79 +
    1.80 +  // Caller retains ownership of "aSource".
    1.81 +  void SetSource(const android::sp<MediaSource> &aSource);
    1.82 +
    1.83 +  // Start the source if it's not already started and open the AudioSink to
    1.84 +  // create an offloaded audio track
    1.85 +  status_t Start(bool aSourceAlreadyStarted = false);
    1.86 +
    1.87 +  double GetMediaTimeSecs();
    1.88 +
    1.89 +  // To update progress bar when the element is visible
    1.90 +  void SetElementVisibility(bool aIsVisible);
    1.91 +
    1.92 +  status_t ChangeState(MediaDecoder::PlayState aState);
    1.93 +
    1.94 +  void SetVolume(double aVolume);
    1.95 +
    1.96 +  // Update ready state based on current play state. Not checking data
    1.97 +  // availability since offloading is currently done only when whole compressed
    1.98 +  // data is available
    1.99 +  MediaDecoderOwner::NextFrameStatus GetNextFrameStatus();
   1.100 +
   1.101 +  void TimeUpdate();
   1.102 +
   1.103 +  // Close the audio sink, stop time updates, frees the input buffers
   1.104 +  void Reset();
   1.105 +
   1.106 +private:
   1.107 +  // Set when audio source is started and audioSink is initialized
   1.108 +  // Used only in main thread
   1.109 +  bool mStarted;
   1.110 +
   1.111 +  // Set when audio sink is started. i.e. playback started
   1.112 +  // Used only in main thread
   1.113 +  bool mPlaying;
   1.114 +
   1.115 +  // Set when playstate is seeking and reset when FillBUffer() acknowledged
   1.116 +  // seeking by seeking audio source. Used in main thread and offload
   1.117 +  // callback thread, protected by Mutex mLock
   1.118 +  bool mSeeking;
   1.119 +
   1.120 +  // Once playback reached end of stream (last ~100ms), position provided by DSP
   1.121 +  // may be reset/corrupted. This bool is used to avoid that.
   1.122 +  // Used in main thread and offload callback thread, protected by Mutex
   1.123 +  // mLock
   1.124 +  bool mReachedEOS;
   1.125 +
   1.126 +  // Set when there is a seek request during pause.
   1.127 +  // Used in main thread and offload callback thread, protected by Mutex
   1.128 +  // mLock
   1.129 +  bool mSeekDuringPause;
   1.130 +
   1.131 +  // Seek can be triggered internally or by MediaDecoder. This bool is to
   1.132 +  // to track seek triggered by MediaDecoder so that we can send back
   1.133 +  // SeekingStarted and SeekingStopped events.
   1.134 +  // Used in main thread and offload callback thread, protected by Mutex mLock
   1.135 +  bool mDispatchSeekEvents;
   1.136 +
   1.137 +  // Set when the HTML Audio Element is visible to the user.
   1.138 +  // Used only in main thread
   1.139 +  bool mIsElementVisible;
   1.140 +
   1.141 +  // Session id given by Android::AudioSystem and used while creating audio sink
   1.142 +  // Used only in main thread
   1.143 +  int mSessionId;
   1.144 +
   1.145 +  // Sample rate of current audio track. Used only in main thread
   1.146 +  int mSampleRate;
   1.147 +
   1.148 +  // After seeking, positions returned by offlaoded tracks (DSP) will be
   1.149 +  // relative to the seeked position. And seeked position may be slightly
   1.150 +  // different than given mSeekTimeUs, if audio source cannot find a frame at
   1.151 +  // that position. Store seeked position in mStartPosUs and provide
   1.152 +  // mStartPosUs + GetPosition() (i.e. absolute position) to MediaOmxDecoder
   1.153 +  // Used in main thread and offload callback thread, protected by Mutex
   1.154 +  // mLock
   1.155 +  int64_t mStartPosUs;
   1.156 +
   1.157 +  // Given seek time when there is a request to seek
   1.158 +  // Used in main thread and offload callback thread, protected by Mutex
   1.159 +  // mLock
   1.160 +  int64_t mSeekTimeUs;
   1.161 +
   1.162 +  // Positions obtained from offlaoded tracks (DSP)
   1.163 +  // Used in main thread and offload callback thread, protected by Mutex
   1.164 +  // mLock
   1.165 +  int64_t mPositionTimeMediaUs;
   1.166 +
   1.167 +  // State obtained from MediaOmxDecoder. Used only in main thread
   1.168 +  MediaDecoder::PlayState mPlayState;
   1.169 +
   1.170 +  // Protect accessing audio position related variables between main thread and
   1.171 +  // offload callback thread
   1.172 +  Mutex mLock;
   1.173 +
   1.174 +  // Compressed audio source.
   1.175 +  // Used in main thread first and later in offload callback thread
   1.176 +  android::sp<MediaSource> mSource;
   1.177 +
   1.178 +  // Audio sink wrapper to access offloaded audio tracks
   1.179 +  // Used in main thread and offload callback thread
   1.180 +  // Race conditions are protected in underlying Android::AudioTrack class
   1.181 +  android::sp<AudioSink> mAudioSink;
   1.182 +
   1.183 +  // Buffer used to get date from audio source. Used in offload callback thread
   1.184 +  MediaBuffer* mInputBuffer;
   1.185 +
   1.186 +  // MediaOmxDecoder object used mainly to notify the audio sink status
   1.187 +  MediaOmxDecoder* mObserver;
   1.188 +
   1.189 +  TimeStamp mLastFireUpdateTime;
   1.190 +
   1.191 +  // Timer to trigger position changed events
   1.192 +  nsCOMPtr<nsITimer> mTimeUpdateTimer;
   1.193 +
   1.194 +  // Timer to reset AudioSink when audio is paused for OFFLOAD_PAUSE_MAX_USECS.
   1.195 +  // It is triggered in Pause() and canceled when there is a Play() within
   1.196 +  // OFFLOAD_PAUSE_MAX_USECS. Used only from main thread so no lock is needed.
   1.197 +  nsCOMPtr<nsITimer> mResetTimer;
   1.198 +
   1.199 +  int64_t GetMediaTimeUs();
   1.200 +
   1.201 +  // Provide the playback position in microseconds from total number of
   1.202 +  // frames played by audio track
   1.203 +  int64_t GetOutputPlayPositionUs_l() const;
   1.204 +
   1.205 +  // Fill the buffer given by audio sink with data from compressed audio
   1.206 +  // source. Also handles the seek by seeking audio source and stop the sink in
   1.207 +  // case of error
   1.208 +  size_t FillBuffer(void *aData, size_t aSize);
   1.209 +
   1.210 +  // Called by AudioSink when it needs data, to notify EOS or tear down event
   1.211 +  static size_t AudioSinkCallback(AudioSink *aAudioSink,
   1.212 +                                  void *aData,
   1.213 +                                  size_t aSize,
   1.214 +                                  void *aMe,
   1.215 +                                  AudioSink::cb_event_t aEvent);
   1.216 +
   1.217 +  bool IsSeeking();
   1.218 +
   1.219 +  // Set mSeekTime to the given position and restart the sink. Actual seek
   1.220 +  // happens in FillBuffer(). If aDispatchSeekEvents is true, send
   1.221 +  // SeekingStarted event always and SeekingStopped event when the play state is
   1.222 +  // paused to MediaDecoder.
   1.223 +  // When decoding and playing happens separately, if there is a seek during
   1.224 +  // pause, we can decode and keep data ready.
   1.225 +  // In case of offload player, no way to seek during pause. So just fake that
   1.226 +  // seek is done.
   1.227 +  status_t SeekTo(int64_t aTimeUs, bool aDispatchSeekEvents = false);
   1.228 +
   1.229 +  // Start/Resume the audio sink so that callback will start being called to get
   1.230 +  // compressed data
   1.231 +  status_t Play();
   1.232 +
   1.233 +  // Stop the audio sink if we need to play till we drain the current buffer.
   1.234 +  // or Pause the sink in case we should stop playing immediately
   1.235 +  void Pause(bool aPlayPendingSamples = false);
   1.236 +
   1.237 +  // When audio is offloaded, application processor wakes up less frequently
   1.238 +  // (>1sec) But when Player UI is visible we need to update progress bar
   1.239 +  // atleast once in 250ms. Start a timer when player UI becomes visible or
   1.240 +  // audio starts playing to send PlaybackPositionChanged events once in 250ms.
   1.241 +  // Stop the timer when UI goes invisible or play state is not playing.
   1.242 +  // Also make sure timer functions are always called from main thread
   1.243 +  nsresult StartTimeUpdate();
   1.244 +  nsresult StopTimeUpdate();
   1.245 +
   1.246 +  // Notify end of stream by sending PlaybackEnded event to observer
   1.247 +  // (i.e.MediaDecoder)
   1.248 +  void NotifyAudioEOS();
   1.249 +
   1.250 +  // Notify position changed event by sending PlaybackPositionChanged event to
   1.251 +  // observer
   1.252 +  void NotifyPositionChanged();
   1.253 +
   1.254 +  // Offloaded audio track is invalidated due to usecase change. Notify
   1.255 +  // MediaDecoder to re-evaluate offloading options
   1.256 +  void NotifyAudioTearDown();
   1.257 +
   1.258 +  // Send information from MetaData to the HAL via AudioSink
   1.259 +  void SendMetaDataToHal(android::sp<AudioSink>& aSink,
   1.260 +                         const android::sp<MetaData>& aMeta);
   1.261 +
   1.262 +  AudioOffloadPlayer(const AudioOffloadPlayer &);
   1.263 +  AudioOffloadPlayer &operator=(const AudioOffloadPlayer &);
   1.264 +};
   1.265 +
   1.266 +} // namespace mozilla
   1.267 +
   1.268 +#endif  // AUDIO_OFFLOAD_PLAYER_H_

mercurial