blob: decd9f904b201c4879588f44bc5c4df25be077ba [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>
Dongwon Kang0d7042d2018-10-12 16:52:14 -070023#include <mediaplayer2/JObjectHolder.h>
Wei Jiaec044b02018-02-19 12:41:23 -080024
Dichen Zhangf8726912018-10-17 13:31:26 -070025#include <vector>
26#include <utility>
Wei Jiaec044b02018-02-19 12:41:23 -080027#include <utils/String16.h>
28#include <utils/Vector.h>
29
Dongwon Kang0d7042d2018-10-12 16:52:14 -070030#include "jni.h"
31
Wei Jiaec044b02018-02-19 12:41:23 -080032namespace android {
33
34class AudioTrack;
35
36class MediaPlayer2AudioOutput : public MediaPlayer2Interface::AudioSink
37{
38 class CallbackData;
39
40public:
41 MediaPlayer2AudioOutput(audio_session_t sessionId,
42 uid_t uid,
43 int pid,
Dichen Zhangc2465c52018-11-12 11:56:05 -080044 const jobject attributes,
Dichen Zhangf8726912018-10-17 13:31:26 -070045 std::vector<jobject>& routingDelegatesBackup);
Wei Jiaec044b02018-02-19 12:41:23 -080046 virtual ~MediaPlayer2AudioOutput();
47
48 virtual bool ready() const {
Dichen Zhangf8726912018-10-17 13:31:26 -070049 return mJAudioTrack != nullptr;
Wei Jiaec044b02018-02-19 12:41:23 -080050 }
51 virtual ssize_t bufferSize() const;
52 virtual ssize_t frameCount() const;
53 virtual ssize_t channelCount() const;
54 virtual ssize_t frameSize() const;
55 virtual uint32_t latency() const;
56 virtual float msecsPerFrame() const;
57 virtual status_t getPosition(uint32_t *position) const;
58 virtual status_t getTimestamp(AudioTimestamp &ts) const;
59 virtual int64_t getPlayedOutDurationUs(int64_t nowUs) const;
60 virtual status_t getFramesWritten(uint32_t *frameswritten) const;
61 virtual audio_session_t getSessionId() const;
62 virtual uint32_t getSampleRate() const;
63 virtual int64_t getBufferDurationInUs() const;
64
65 virtual status_t open(
66 uint32_t sampleRate, int channelCount, audio_channel_mask_t channelMask,
Dichen Zhang303bd2d2018-09-28 12:52:49 -070067 audio_format_t format,
Wei Jiaec044b02018-02-19 12:41:23 -080068 AudioCallback cb, void *cookie,
69 audio_output_flags_t flags = AUDIO_OUTPUT_FLAG_NONE,
70 const audio_offload_info_t *offloadInfo = NULL,
Wei Jiaec044b02018-02-19 12:41:23 -080071 uint32_t suggestedFrameCount = 0);
72
73 virtual status_t start();
74 virtual ssize_t write(const void* buffer, size_t size, bool blocking = true);
75 virtual void stop();
76 virtual void flush();
77 virtual void pause();
78 virtual void close();
Dichen Zhangc2465c52018-11-12 11:56:05 -080079 void setAudioAttributes(const jobject attributes);
Dichen Zhangf8726912018-10-17 13:31:26 -070080 virtual audio_stream_type_t getAudioStreamType() const;
Wei Jiaec044b02018-02-19 12:41:23 -080081
Dichen Zhang7398ca02018-10-15 10:25:12 -070082 void setVolume(float volume);
Wei Jiaec044b02018-02-19 12:41:23 -080083 virtual status_t setPlaybackRate(const AudioPlaybackRate& rate);
84 virtual status_t getPlaybackRate(AudioPlaybackRate* rate /* nonnull */);
85
86 status_t setAuxEffectSendLevel(float level);
87 status_t attachAuxEffect(int effectId);
88 virtual status_t dump(int fd, const Vector<String16>& args) const;
89
90 static bool isOnEmulator();
91 static int getMinBufferCount();
Wei Jiaec044b02018-02-19 12:41:23 -080092 virtual bool needsTrailingPadding() {
93 return true;
94 // TODO: return correct value.
95 //return mNextOutput == NULL;
96 }
Wei Jiaec044b02018-02-19 12:41:23 -080097 // AudioRouting
Dongwon Kang0d7042d2018-10-12 16:52:14 -070098 virtual status_t setPreferredDevice(jobject device);
99 virtual jobject getRoutedDevice();
Dichen Zhangf8726912018-10-17 13:31:26 -0700100 virtual status_t addAudioDeviceCallback(jobject routingDelegate);
101 virtual status_t removeAudioDeviceCallback(jobject listener);
102 virtual void copyAudioDeviceCallback(std::vector<jobject>& routingDelegateTarget);
Wei Jiaec044b02018-02-19 12:41:23 -0800103
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
Dichen Zhangf8726912018-10-17 13:31:26 -0700111 sp<JAudioTrack> mJAudioTrack;
Wei Jiaec044b02018-02-19 12:41:23 -0800112 AudioCallback mCallback;
113 void * mCallbackCookie;
114 CallbackData * mCallbackData;
Dichen Zhangc2465c52018-11-12 11:56:05 -0800115 sp<JObjectHolder> mAttributes;
Dichen Zhang7398ca02018-10-15 10:25:12 -0700116 float mVolume;
Wei Jiaec044b02018-02-19 12:41:23 -0800117 AudioPlaybackRate mPlaybackRate;
118 uint32_t mSampleRateHz; // sample rate of the content, as set in open()
119 float mMsecsPerFrame;
120 size_t mFrameSize;
121 audio_session_t mSessionId;
122 uid_t mUid;
123 int mPid;
124 float mSendLevel;
125 int mAuxEffectId;
126 audio_output_flags_t mFlags;
Dongwon Kang0d7042d2018-10-12 16:52:14 -0700127 sp<JObjectHolder> mPreferredDevice;
Wei Jiaec044b02018-02-19 12:41:23 -0800128 mutable Mutex mLock;
Dichen Zhangf8726912018-10-17 13:31:26 -0700129 std::vector<std::pair<jobject, jobject>> mRoutingDelegates; // <listener, routingDelegate>
Wei Jiaec044b02018-02-19 12:41:23 -0800130
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