blob: 9fca641f508f1c31575df88b3955627d6cf424f3 [file] [log] [blame]
Wei Jiaec044b02018-02-19 12:41:23 -08001/*
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>
Dichen Zhangf8726912018-10-17 13:31:26 -070022#include <mediaplayer2/JAudioTrack.h>
Wei Jiaec044b02018-02-19 12:41:23 -080023
Dichen Zhangf8726912018-10-17 13:31:26 -070024#include <vector>
25#include <utility>
Wei Jiaec044b02018-02-19 12:41:23 -080026#include <utils/String16.h>
27#include <utils/Vector.h>
28
29namespace android {
30
31class AudioTrack;
32
33class MediaPlayer2AudioOutput : public MediaPlayer2Interface::AudioSink
34{
35 class CallbackData;
36
37public:
38 MediaPlayer2AudioOutput(audio_session_t sessionId,
39 uid_t uid,
40 int pid,
41 const audio_attributes_t * attr,
Dichen Zhangf8726912018-10-17 13:31:26 -070042 std::vector<jobject>& routingDelegatesBackup);
Wei Jiaec044b02018-02-19 12:41:23 -080043 virtual ~MediaPlayer2AudioOutput();
44
45 virtual bool ready() const {
Dichen Zhangf8726912018-10-17 13:31:26 -070046 return mJAudioTrack != nullptr;
Wei Jiaec044b02018-02-19 12:41:23 -080047 }
48 virtual ssize_t bufferSize() const;
49 virtual ssize_t frameCount() const;
50 virtual ssize_t channelCount() const;
51 virtual ssize_t frameSize() const;
52 virtual uint32_t latency() const;
53 virtual float msecsPerFrame() const;
54 virtual status_t getPosition(uint32_t *position) const;
55 virtual status_t getTimestamp(AudioTimestamp &ts) const;
56 virtual int64_t getPlayedOutDurationUs(int64_t nowUs) const;
57 virtual status_t getFramesWritten(uint32_t *frameswritten) const;
58 virtual audio_session_t getSessionId() const;
59 virtual uint32_t getSampleRate() const;
60 virtual int64_t getBufferDurationInUs() const;
61
62 virtual status_t open(
63 uint32_t sampleRate, int channelCount, audio_channel_mask_t channelMask,
Dichen Zhang303bd2d2018-09-28 12:52:49 -070064 audio_format_t format,
Wei Jiaec044b02018-02-19 12:41:23 -080065 AudioCallback cb, void *cookie,
66 audio_output_flags_t flags = AUDIO_OUTPUT_FLAG_NONE,
67 const audio_offload_info_t *offloadInfo = NULL,
Wei Jiaec044b02018-02-19 12:41:23 -080068 uint32_t suggestedFrameCount = 0);
69
70 virtual status_t start();
71 virtual ssize_t write(const void* buffer, size_t size, bool blocking = true);
72 virtual void stop();
73 virtual void flush();
74 virtual void pause();
75 virtual void close();
Wei Jiaec044b02018-02-19 12:41:23 -080076 void setAudioAttributes(const audio_attributes_t * attributes);
Dichen Zhangf8726912018-10-17 13:31:26 -070077 virtual audio_stream_type_t getAudioStreamType() const;
Wei Jiaec044b02018-02-19 12:41:23 -080078
Dichen Zhang7398ca02018-10-15 10:25:12 -070079 void setVolume(float volume);
Wei Jiaec044b02018-02-19 12:41:23 -080080 virtual status_t setPlaybackRate(const AudioPlaybackRate& rate);
81 virtual status_t getPlaybackRate(AudioPlaybackRate* rate /* nonnull */);
82
83 status_t setAuxEffectSendLevel(float level);
84 status_t attachAuxEffect(int effectId);
85 virtual status_t dump(int fd, const Vector<String16>& args) const;
86
87 static bool isOnEmulator();
88 static int getMinBufferCount();
Wei Jiaec044b02018-02-19 12:41:23 -080089 virtual bool needsTrailingPadding() {
90 return true;
91 // TODO: return correct value.
92 //return mNextOutput == NULL;
93 }
Wei Jiaec044b02018-02-19 12:41:23 -080094 // AudioRouting
95 virtual status_t setOutputDevice(audio_port_handle_t deviceId);
96 virtual status_t getRoutedDeviceId(audio_port_handle_t* deviceId);
Dichen Zhangf8726912018-10-17 13:31:26 -070097 virtual status_t addAudioDeviceCallback(jobject routingDelegate);
98 virtual status_t removeAudioDeviceCallback(jobject listener);
99 virtual void copyAudioDeviceCallback(std::vector<jobject>& routingDelegateTarget);
Wei Jiaec044b02018-02-19 12:41:23 -0800100
101private:
102 static void setMinBufferCount();
103 static void CallbackWrapper(int event, void *me, void *info);
104 void deleteRecycledTrack_l();
105 void close_l();
106 status_t updateTrack_l();
107
Dichen Zhangf8726912018-10-17 13:31:26 -0700108 sp<JAudioTrack> mJAudioTrack;
Wei Jiaec044b02018-02-19 12:41:23 -0800109 AudioCallback mCallback;
110 void * mCallbackCookie;
111 CallbackData * mCallbackData;
Wei Jiaec044b02018-02-19 12:41:23 -0800112 audio_attributes_t * mAttributes;
Dichen Zhang7398ca02018-10-15 10:25:12 -0700113 float mVolume;
Wei Jiaec044b02018-02-19 12:41:23 -0800114 AudioPlaybackRate mPlaybackRate;
115 uint32_t mSampleRateHz; // sample rate of the content, as set in open()
116 float mMsecsPerFrame;
117 size_t mFrameSize;
118 audio_session_t mSessionId;
119 uid_t mUid;
120 int mPid;
121 float mSendLevel;
122 int mAuxEffectId;
123 audio_output_flags_t mFlags;
124 audio_port_handle_t mSelectedDeviceId;
125 audio_port_handle_t mRoutedDeviceId;
Wei Jiaec044b02018-02-19 12:41:23 -0800126 mutable Mutex mLock;
Dichen Zhangf8726912018-10-17 13:31:26 -0700127 std::vector<std::pair<jobject, jobject>> mRoutingDelegates; // <listener, routingDelegate>
Wei Jiaec044b02018-02-19 12:41:23 -0800128
129 // static variables below not protected by mutex
130 static bool mIsOnEmulator;
131 static int mMinBufferCount; // 12 for emulator; otherwise 4
132
133 // CallbackData is what is passed to the AudioTrack as the "user" data.
134 // We need to be able to target this to a different Output on the fly,
135 // so we can't use the Output itself for this.
136 class CallbackData {
137 friend MediaPlayer2AudioOutput;
138 public:
139 explicit CallbackData(MediaPlayer2AudioOutput *cookie) {
140 mData = cookie;
141 mSwitching = false;
142 }
143 MediaPlayer2AudioOutput *getOutput() const {
144 return mData;
145 }
146 void setOutput(MediaPlayer2AudioOutput* newcookie) {
147 mData = newcookie;
148 }
149 // lock/unlock are used by the callback before accessing the payload of this object
150 void lock() const {
151 mLock.lock();
152 }
153 void unlock() const {
154 mLock.unlock();
155 }
156
157 // tryBeginTrackSwitch/endTrackSwitch are used when the CallbackData is handed over
158 // to the next sink.
159
160 // tryBeginTrackSwitch() returns true only if it obtains the lock.
161 bool tryBeginTrackSwitch() {
162 LOG_ALWAYS_FATAL_IF(mSwitching, "tryBeginTrackSwitch() already called");
163 if (mLock.tryLock() != OK) {
164 return false;
165 }
166 mSwitching = true;
167 return true;
168 }
169 void endTrackSwitch() {
170 if (mSwitching) {
171 mLock.unlock();
172 }
173 mSwitching = false;
174 }
175
176 private:
177 MediaPlayer2AudioOutput *mData;
178 mutable Mutex mLock; // a recursive mutex might make this unnecessary.
179 bool mSwitching;
180 DISALLOW_EVIL_CONSTRUCTORS(CallbackData);
181 };
182};
183
184}; // namespace android
185
186#endif // ANDROID_MEDIAPLAYER2AUDIOOUTPUT_H