blob: ad4937af2fa5303765a691aeaccc7930ef8b7882 [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>
22
23#include <utils/String16.h>
24#include <utils/Vector.h>
25
26namespace android {
27
28class AudioTrack;
29
30class MediaPlayer2AudioOutput : public MediaPlayer2Interface::AudioSink
31{
32 class CallbackData;
33
34public:
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
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);
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();
90 void setNextOutput(const sp<MediaPlayer2AudioOutput>& nextOutput);
91 virtual bool needsTrailingPadding() {
92 return true;
93 // TODO: return correct value.
94 //return mNextOutput == NULL;
95 }
96 virtual status_t setParameters(const String8& keyValuePairs);
97 virtual String8 getParameters(const String8& keys);
98
99 // AudioRouting
100 virtual status_t setOutputDevice(audio_port_handle_t deviceId);
101 virtual status_t getRoutedDeviceId(audio_port_handle_t* deviceId);
102 virtual status_t enableAudioDeviceCallback(bool enabled);
103
104private:
105 static void setMinBufferCount();
106 static void CallbackWrapper(int event, void *me, void *info);
107 void deleteRecycledTrack_l();
108 void close_l();
109 status_t updateTrack_l();
110
111 sp<AudioTrack> mTrack;
112 AudioCallback mCallback;
113 void * mCallbackCookie;
114 CallbackData * mCallbackData;
115 audio_stream_type_t mStreamType;
116 audio_attributes_t * mAttributes;
117 float mLeftVolume;
118 float mRightVolume;
119 AudioPlaybackRate mPlaybackRate;
120 uint32_t mSampleRateHz; // sample rate of the content, as set in open()
121 float mMsecsPerFrame;
122 size_t mFrameSize;
123 audio_session_t mSessionId;
124 uid_t mUid;
125 int mPid;
126 float mSendLevel;
127 int mAuxEffectId;
128 audio_output_flags_t mFlags;
129 audio_port_handle_t mSelectedDeviceId;
130 audio_port_handle_t mRoutedDeviceId;
131 bool mDeviceCallbackEnabled;
132 wp<AudioSystem::AudioDeviceCallback> mDeviceCallback;
133 mutable Mutex mLock;
134
135 // static variables below not protected by mutex
136 static bool mIsOnEmulator;
137 static int mMinBufferCount; // 12 for emulator; otherwise 4
138
139 // CallbackData is what is passed to the AudioTrack as the "user" data.
140 // We need to be able to target this to a different Output on the fly,
141 // so we can't use the Output itself for this.
142 class CallbackData {
143 friend MediaPlayer2AudioOutput;
144 public:
145 explicit CallbackData(MediaPlayer2AudioOutput *cookie) {
146 mData = cookie;
147 mSwitching = false;
148 }
149 MediaPlayer2AudioOutput *getOutput() const {
150 return mData;
151 }
152 void setOutput(MediaPlayer2AudioOutput* newcookie) {
153 mData = newcookie;
154 }
155 // lock/unlock are used by the callback before accessing the payload of this object
156 void lock() const {
157 mLock.lock();
158 }
159 void unlock() const {
160 mLock.unlock();
161 }
162
163 // tryBeginTrackSwitch/endTrackSwitch are used when the CallbackData is handed over
164 // to the next sink.
165
166 // tryBeginTrackSwitch() returns true only if it obtains the lock.
167 bool tryBeginTrackSwitch() {
168 LOG_ALWAYS_FATAL_IF(mSwitching, "tryBeginTrackSwitch() already called");
169 if (mLock.tryLock() != OK) {
170 return false;
171 }
172 mSwitching = true;
173 return true;
174 }
175 void endTrackSwitch() {
176 if (mSwitching) {
177 mLock.unlock();
178 }
179 mSwitching = false;
180 }
181
182 private:
183 MediaPlayer2AudioOutput *mData;
184 mutable Mutex mLock; // a recursive mutex might make this unnecessary.
185 bool mSwitching;
186 DISALLOW_EVIL_CONSTRUCTORS(CallbackData);
187 };
188};
189
190}; // namespace android
191
192#endif // ANDROID_MEDIAPLAYER2AUDIOOUTPUT_H