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 ready()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(); needsTrailingPadding()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: CallbackData(MediaPlayer2AudioOutput * cookie)141 explicit CallbackData(MediaPlayer2AudioOutput *cookie) { 142 mData = cookie; 143 mSwitching = false; 144 } getOutput()145 MediaPlayer2AudioOutput *getOutput() const { 146 return mData; 147 } setOutput(MediaPlayer2AudioOutput * newcookie)148 void setOutput(MediaPlayer2AudioOutput* newcookie) { 149 mData = newcookie; 150 } 151 // lock/unlock are used by the callback before accessing the payload of this object lock()152 void lock() const { 153 mLock.lock(); 154 } unlock()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. tryBeginTrackSwitch()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 } endTrackSwitch()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