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 23 #include <utils/String16.h> 24 #include <utils/Vector.h> 25 26 namespace android { 27 28 class AudioTrack; 29 30 class MediaPlayer2AudioOutput : public MediaPlayer2Interface::AudioSink 31 { 32 class CallbackData; 33 34 public: 35 MediaPlayer2AudioOutput(audio_session_t sessionId, 36 uid_t uid, 37 int pid, 38 const audio_attributes_t * attr, 39 const sp<AudioSystem::AudioDeviceCallback>& deviceCallback); 40 virtual ~MediaPlayer2AudioOutput(); 41 ready()42 virtual bool ready() const { 43 return mTrack != 0; 44 } 45 virtual ssize_t bufferSize() const; 46 virtual ssize_t frameCount() const; 47 virtual ssize_t channelCount() const; 48 virtual ssize_t frameSize() const; 49 virtual uint32_t latency() const; 50 virtual float msecsPerFrame() const; 51 virtual status_t getPosition(uint32_t *position) const; 52 virtual status_t getTimestamp(AudioTimestamp &ts) const; 53 virtual int64_t getPlayedOutDurationUs(int64_t nowUs) const; 54 virtual status_t getFramesWritten(uint32_t *frameswritten) const; 55 virtual audio_session_t getSessionId() const; 56 virtual uint32_t getSampleRate() const; 57 virtual int64_t getBufferDurationInUs() const; 58 59 virtual status_t open( 60 uint32_t sampleRate, int channelCount, audio_channel_mask_t channelMask, 61 audio_format_t format, int bufferCount, 62 AudioCallback cb, void *cookie, 63 audio_output_flags_t flags = AUDIO_OUTPUT_FLAG_NONE, 64 const audio_offload_info_t *offloadInfo = NULL, 65 bool doNotReconnect = false, 66 uint32_t suggestedFrameCount = 0); 67 68 virtual status_t start(); 69 virtual ssize_t write(const void* buffer, size_t size, bool blocking = true); 70 virtual void stop(); 71 virtual void flush(); 72 virtual void pause(); 73 virtual void close(); 74 void setAudioStreamType(audio_stream_type_t streamType); getAudioStreamType()75 virtual audio_stream_type_t getAudioStreamType() const { 76 return mStreamType; 77 } 78 void setAudioAttributes(const audio_attributes_t * attributes); 79 80 void setVolume(float left, float right); 81 virtual status_t setPlaybackRate(const AudioPlaybackRate& rate); 82 virtual status_t getPlaybackRate(AudioPlaybackRate* rate /* nonnull */); 83 84 status_t setAuxEffectSendLevel(float level); 85 status_t attachAuxEffect(int effectId); 86 virtual status_t dump(int fd, const Vector<String16>& args) const; 87 88 static bool isOnEmulator(); 89 static int getMinBufferCount(); needsTrailingPadding()90 virtual bool needsTrailingPadding() { 91 return true; 92 // TODO: return correct value. 93 //return mNextOutput == NULL; 94 } 95 virtual status_t setParameters(const String8& keyValuePairs); 96 virtual String8 getParameters(const String8& keys); 97 98 // AudioRouting 99 virtual status_t setOutputDevice(audio_port_handle_t deviceId); 100 virtual status_t getRoutedDeviceId(audio_port_handle_t* deviceId); 101 virtual status_t enableAudioDeviceCallback(bool enabled); 102 103 private: 104 static void setMinBufferCount(); 105 static void CallbackWrapper(int event, void *me, void *info); 106 void deleteRecycledTrack_l(); 107 void close_l(); 108 status_t updateTrack_l(); 109 110 sp<AudioTrack> mTrack; 111 AudioCallback mCallback; 112 void * mCallbackCookie; 113 CallbackData * mCallbackData; 114 audio_stream_type_t mStreamType; 115 audio_attributes_t * mAttributes; 116 float mLeftVolume; 117 float mRightVolume; 118 AudioPlaybackRate mPlaybackRate; 119 uint32_t mSampleRateHz; // sample rate of the content, as set in open() 120 float mMsecsPerFrame; 121 size_t mFrameSize; 122 audio_session_t mSessionId; 123 uid_t mUid; 124 int mPid; 125 float mSendLevel; 126 int mAuxEffectId; 127 audio_output_flags_t mFlags; 128 audio_port_handle_t mSelectedDeviceId; 129 audio_port_handle_t mRoutedDeviceId; 130 bool mDeviceCallbackEnabled; 131 wp<AudioSystem::AudioDeviceCallback> mDeviceCallback; 132 mutable Mutex mLock; 133 134 // static variables below not protected by mutex 135 static bool mIsOnEmulator; 136 static int mMinBufferCount; // 12 for emulator; otherwise 4 137 138 // CallbackData is what is passed to the AudioTrack as the "user" data. 139 // We need to be able to target this to a different Output on the fly, 140 // so we can't use the Output itself for this. 141 class CallbackData { 142 friend MediaPlayer2AudioOutput; 143 public: CallbackData(MediaPlayer2AudioOutput * cookie)144 explicit CallbackData(MediaPlayer2AudioOutput *cookie) { 145 mData = cookie; 146 mSwitching = false; 147 } getOutput()148 MediaPlayer2AudioOutput *getOutput() const { 149 return mData; 150 } setOutput(MediaPlayer2AudioOutput * newcookie)151 void setOutput(MediaPlayer2AudioOutput* newcookie) { 152 mData = newcookie; 153 } 154 // lock/unlock are used by the callback before accessing the payload of this object lock()155 void lock() const { 156 mLock.lock(); 157 } unlock()158 void unlock() const { 159 mLock.unlock(); 160 } 161 162 // tryBeginTrackSwitch/endTrackSwitch are used when the CallbackData is handed over 163 // to the next sink. 164 165 // tryBeginTrackSwitch() returns true only if it obtains the lock. tryBeginTrackSwitch()166 bool tryBeginTrackSwitch() { 167 LOG_ALWAYS_FATAL_IF(mSwitching, "tryBeginTrackSwitch() already called"); 168 if (mLock.tryLock() != OK) { 169 return false; 170 } 171 mSwitching = true; 172 return true; 173 } endTrackSwitch()174 void endTrackSwitch() { 175 if (mSwitching) { 176 mLock.unlock(); 177 } 178 mSwitching = false; 179 } 180 181 private: 182 MediaPlayer2AudioOutput *mData; 183 mutable Mutex mLock; // a recursive mutex might make this unnecessary. 184 bool mSwitching; 185 DISALLOW_EVIL_CONSTRUCTORS(CallbackData); 186 }; 187 }; 188 189 }; // namespace android 190 191 #endif // ANDROID_MEDIAPLAYER2AUDIOOUTPUT_H 192