Home | History | Annotate | Download | only in mediaplayer2
      1 /*
      2 **
      3 ** Copyright 2018, The Android Open Source Project
      4 **
      5 ** Licensed under the Apache License, Version 2.0 (the "License");
      6 ** you may not use this file except in compliance with the License.
      7 ** You may obtain a copy of the License at
      8 **
      9 **     http://www.apache.org/licenses/LICENSE-2.0
     10 **
     11 ** Unless required by applicable law or agreed to in writing, software
     12 ** distributed under the License is distributed on an "AS IS" BASIS,
     13 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     14 ** See the License for the specific language governing permissions and
     15 ** limitations under the License.
     16 */
     17 
     18 #ifndef ANDROID_MEDIAPLAYER2AUDIOOUTPUT_H
     19 #define ANDROID_MEDIAPLAYER2AUDIOOUTPUT_H
     20 
     21 #include <mediaplayer2/MediaPlayer2Interface.h>
     22 #include <mediaplayer2/JAudioTrack.h>
     23 #include <mediaplayer2/JObjectHolder.h>
     24 
     25 #include <utility>
     26 #include <utils/String16.h>
     27 #include <utils/Vector.h>
     28 
     29 #include "jni.h"
     30 
     31 namespace android {
     32 
     33 class AudioTrack;
     34 
     35 class MediaPlayer2AudioOutput : public MediaPlayer2Interface::AudioSink
     36 {
     37     class CallbackData;
     38 
     39 public:
     40     MediaPlayer2AudioOutput(int32_t sessionId,
     41                             uid_t uid,
     42                             int pid,
     43                             const jobject attributes);
     44     virtual ~MediaPlayer2AudioOutput();
     45 
     46     virtual bool ready() const {
     47         return mJAudioTrack != nullptr;
     48     }
     49     virtual ssize_t bufferSize() const;
     50     virtual ssize_t frameCount() const;
     51     virtual ssize_t channelCount() const;
     52     virtual ssize_t frameSize() const;
     53     virtual uint32_t latency() const;
     54     virtual float msecsPerFrame() const;
     55     virtual status_t getPosition(uint32_t *position) const;
     56     virtual status_t getTimestamp(AudioTimestamp &ts) const;
     57     virtual int64_t getPlayedOutDurationUs(int64_t nowUs) const;
     58     virtual status_t getFramesWritten(uint32_t *frameswritten) const;
     59     virtual int32_t getSessionId() const;
     60     virtual void setSessionId(const int32_t id);
     61     virtual uint32_t getSampleRate() const;
     62     virtual int64_t getBufferDurationInUs() const;
     63 
     64     virtual status_t open(
     65             uint32_t sampleRate, int channelCount, audio_channel_mask_t channelMask,
     66             audio_format_t format,
     67             AudioCallback cb, void *cookie,
     68             audio_output_flags_t flags = AUDIO_OUTPUT_FLAG_NONE,
     69             const audio_offload_info_t *offloadInfo = NULL,
     70             uint32_t suggestedFrameCount = 0);
     71 
     72     virtual status_t start();
     73     virtual ssize_t write(const void* buffer, size_t size, bool blocking = true);
     74     virtual void stop();
     75     virtual void flush();
     76     virtual void pause();
     77     virtual void close();
     78     void setAudioAttributes(const jobject attributes);
     79     virtual audio_stream_type_t getAudioStreamType() const;
     80 
     81     void setVolume(float volume);
     82     virtual status_t setPlaybackRate(const AudioPlaybackRate& rate);
     83     virtual status_t getPlaybackRate(AudioPlaybackRate* rate /* nonnull */);
     84 
     85     status_t setAuxEffectSendLevel(float level);
     86     status_t attachAuxEffect(int effectId);
     87     virtual status_t dump(int fd, const Vector<String16>& args) const;
     88 
     89     static bool isOnEmulator();
     90     static int getMinBufferCount();
     91     virtual bool needsTrailingPadding() {
     92         return true;
     93         // TODO: return correct value.
     94         //return mNextOutput == NULL;
     95     }
     96     // AudioRouting
     97     virtual status_t setPreferredDevice(jobject device);
     98     virtual jobject getRoutedDevice();
     99     virtual status_t addAudioDeviceCallback(jobject routingDelegate);
    100     virtual status_t removeAudioDeviceCallback(jobject listener);
    101 
    102 private:
    103     static void setMinBufferCount();
    104     static void CallbackWrapper(int event, void *me, void *info);
    105     void deleteRecycledTrack_l();
    106     void close_l();
    107     status_t updateTrack_l();
    108 
    109     sp<JAudioTrack>         mJAudioTrack;
    110     AudioCallback           mCallback;
    111     void *                  mCallbackCookie;
    112     CallbackData *          mCallbackData;
    113     sp<JObjectHolder>       mAttributes;
    114     float                   mVolume;
    115     AudioPlaybackRate       mPlaybackRate;
    116     uint32_t                mSampleRateHz; // sample rate of the content, as set in open()
    117     float                   mMsecsPerFrame;
    118     size_t                  mFrameSize;
    119     int32_t                 mSessionId;
    120     uid_t                   mUid;
    121     int                     mPid;
    122     float                   mSendLevel;
    123     int                     mAuxEffectId;
    124     audio_output_flags_t    mFlags;
    125     sp<JObjectHolder>       mPreferredDevice;
    126     mutable Mutex           mLock;
    127 
    128     // <listener, routingDelegate>
    129     Vector<std::pair<sp<JObjectHolder>, sp<JObjectHolder>>> mRoutingDelegates;
    130 
    131     // static variables below not protected by mutex
    132     static bool             mIsOnEmulator;
    133     static int              mMinBufferCount;  // 12 for emulator; otherwise 4
    134 
    135     // CallbackData is what is passed to the AudioTrack as the "user" data.
    136     // We need to be able to target this to a different Output on the fly,
    137     // so we can't use the Output itself for this.
    138     class CallbackData {
    139         friend MediaPlayer2AudioOutput;
    140     public:
    141         explicit CallbackData(MediaPlayer2AudioOutput *cookie) {
    142             mData = cookie;
    143             mSwitching = false;
    144         }
    145         MediaPlayer2AudioOutput *getOutput() const {
    146             return mData;
    147         }
    148         void setOutput(MediaPlayer2AudioOutput* newcookie) {
    149             mData = newcookie;
    150         }
    151         // lock/unlock are used by the callback before accessing the payload of this object
    152         void lock() const {
    153             mLock.lock();
    154         }
    155         void unlock() const {
    156             mLock.unlock();
    157         }
    158 
    159         // tryBeginTrackSwitch/endTrackSwitch are used when the CallbackData is handed over
    160         // to the next sink.
    161 
    162         // tryBeginTrackSwitch() returns true only if it obtains the lock.
    163         bool tryBeginTrackSwitch() {
    164             LOG_ALWAYS_FATAL_IF(mSwitching, "tryBeginTrackSwitch() already called");
    165             if (mLock.tryLock() != OK) {
    166                 return false;
    167             }
    168             mSwitching = true;
    169             return true;
    170         }
    171         void endTrackSwitch() {
    172             if (mSwitching) {
    173                 mLock.unlock();
    174             }
    175             mSwitching = false;
    176         }
    177 
    178     private:
    179         MediaPlayer2AudioOutput *mData;
    180         mutable Mutex mLock; // a recursive mutex might make this unnecessary.
    181         bool mSwitching;
    182         DISALLOW_EVIL_CONSTRUCTORS(CallbackData);
    183     };
    184 };
    185 
    186 }; // namespace android
    187 
    188 #endif // ANDROID_MEDIAPLAYER2AUDIOOUTPUT_H
    189