content/media/omx/AudioOffloadPlayer.h

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rwxr-xr-x

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

     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  */
    20 #ifndef AUDIO_OFFLOAD_PLAYER_H_
    21 #define AUDIO_OFFLOAD_PLAYER_H_
    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>
    29 #include "AudioOutput.h"
    31 #include "MediaDecoderOwner.h"
    32 #include "MediaOmxDecoder.h"
    34 namespace mozilla {
    36 class MediaOmxDecoder;
    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  */
    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;
    67 public:
    68   enum {
    69     REACHED_EOS,
    70     SEEK_COMPLETE
    71   };
    73   AudioOffloadPlayer(MediaOmxDecoder* aDecoder = nullptr);
    75   ~AudioOffloadPlayer();
    77   // Caller retains ownership of "aSource".
    78   void SetSource(const android::sp<MediaSource> &aSource);
    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);
    84   double GetMediaTimeSecs();
    86   // To update progress bar when the element is visible
    87   void SetElementVisibility(bool aIsVisible);
    89   status_t ChangeState(MediaDecoder::PlayState aState);
    91   void SetVolume(double aVolume);
    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();
    98   void TimeUpdate();
   100   // Close the audio sink, stop time updates, frees the input buffers
   101   void Reset();
   103 private:
   104   // Set when audio source is started and audioSink is initialized
   105   // Used only in main thread
   106   bool mStarted;
   108   // Set when audio sink is started. i.e. playback started
   109   // Used only in main thread
   110   bool mPlaying;
   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;
   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;
   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;
   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;
   134   // Set when the HTML Audio Element is visible to the user.
   135   // Used only in main thread
   136   bool mIsElementVisible;
   138   // Session id given by Android::AudioSystem and used while creating audio sink
   139   // Used only in main thread
   140   int mSessionId;
   142   // Sample rate of current audio track. Used only in main thread
   143   int mSampleRate;
   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;
   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;
   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;
   164   // State obtained from MediaOmxDecoder. Used only in main thread
   165   MediaDecoder::PlayState mPlayState;
   167   // Protect accessing audio position related variables between main thread and
   168   // offload callback thread
   169   Mutex mLock;
   171   // Compressed audio source.
   172   // Used in main thread first and later in offload callback thread
   173   android::sp<MediaSource> mSource;
   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;
   180   // Buffer used to get date from audio source. Used in offload callback thread
   181   MediaBuffer* mInputBuffer;
   183   // MediaOmxDecoder object used mainly to notify the audio sink status
   184   MediaOmxDecoder* mObserver;
   186   TimeStamp mLastFireUpdateTime;
   188   // Timer to trigger position changed events
   189   nsCOMPtr<nsITimer> mTimeUpdateTimer;
   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;
   196   int64_t GetMediaTimeUs();
   198   // Provide the playback position in microseconds from total number of
   199   // frames played by audio track
   200   int64_t GetOutputPlayPositionUs_l() const;
   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);
   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);
   214   bool IsSeeking();
   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);
   226   // Start/Resume the audio sink so that callback will start being called to get
   227   // compressed data
   228   status_t Play();
   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);
   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();
   243   // Notify end of stream by sending PlaybackEnded event to observer
   244   // (i.e.MediaDecoder)
   245   void NotifyAudioEOS();
   247   // Notify position changed event by sending PlaybackPositionChanged event to
   248   // observer
   249   void NotifyPositionChanged();
   251   // Offloaded audio track is invalidated due to usecase change. Notify
   252   // MediaDecoder to re-evaluate offloading options
   253   void NotifyAudioTearDown();
   255   // Send information from MetaData to the HAL via AudioSink
   256   void SendMetaDataToHal(android::sp<AudioSink>& aSink,
   257                          const android::sp<MetaData>& aMeta);
   259   AudioOffloadPlayer(const AudioOffloadPlayer &);
   260   AudioOffloadPlayer &operator=(const AudioOffloadPlayer &);
   261 };
   263 } // namespace mozilla
   265 #endif  // AUDIO_OFFLOAD_PLAYER_H_

mercurial