blob: fc020ca57354c3755f03cf7dabdb7eeeada4b64a [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 Zhanga60eaa82018-11-13 17:14:34 +000044 const jobject attributes);
Wei Jiaec044b02018-02-19 12:41:23 -080045 virtual ~MediaPlayer2AudioOutput();
46
47 virtual bool ready() const {
Dichen Zhangf8726912018-10-17 13:31:26 -070048 return mJAudioTrack != nullptr;
Wei Jiaec044b02018-02-19 12:41:23 -080049 }
50 virtual ssize_t bufferSize() const;
51 virtual ssize_t frameCount() const;
52 virtual ssize_t channelCount() const;
53 virtual ssize_t frameSize() const;
54 virtual uint32_t latency() const;
55 virtual float msecsPerFrame() const;
56 virtual status_t getPosition(uint32_t *position) const;
57 virtual status_t getTimestamp(AudioTimestamp &ts) const;
58 virtual int64_t getPlayedOutDurationUs(int64_t nowUs) const;
59 virtual status_t getFramesWritten(uint32_t *frameswritten) const;
60 virtual audio_session_t getSessionId() const;
Dichen Zhanga60eaa82018-11-13 17:14:34 +000061 virtual void setSessionId(const audio_session_t id);
Wei Jiaec044b02018-02-19 12:41:23 -080062 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);
Wei Jiaec044b02018-02-19 12:41:23 -0800102
103private:
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
Dichen Zhangf8726912018-10-17 13:31:26 -0700110 sp<JAudioTrack> mJAudioTrack;
Wei Jiaec044b02018-02-19 12:41:23 -0800111 AudioCallback mCallback;
112 void * mCallbackCookie;
113 CallbackData * mCallbackData;
Dichen Zhangc2465c52018-11-12 11:56:05 -0800114 sp<JObjectHolder> mAttributes;
Dichen Zhang7398ca02018-10-15 10:25:12 -0700115 float mVolume;
Wei Jiaec044b02018-02-19 12:41:23 -0800116 AudioPlaybackRate mPlaybackRate;
117 uint32_t mSampleRateHz; // sample rate of the content, as set in open()
118 float mMsecsPerFrame;
119 size_t mFrameSize;
120 audio_session_t mSessionId;
121 uid_t mUid;
122 int mPid;
123 float mSendLevel;
124 int mAuxEffectId;
125 audio_output_flags_t mFlags;
Dongwon Kang0d7042d2018-10-12 16:52:14 -0700126 sp<JObjectHolder> mPreferredDevice;
Wei Jiaec044b02018-02-19 12:41:23 -0800127 mutable Mutex mLock;
Dichen Zhangf8726912018-10-17 13:31:26 -0700128 std::vector<std::pair<jobject, jobject>> mRoutingDelegates; // <listener, routingDelegate>
Wei Jiaec044b02018-02-19 12:41:23 -0800129
130 // static variables below not protected by mutex
131 static bool mIsOnEmulator;
132 static int mMinBufferCount; // 12 for emulator; otherwise 4
133
134 // CallbackData is what is passed to the AudioTrack as the "user" data.
135 // We need to be able to target this to a different Output on the fly,
136 // so we can't use the Output itself for this.
137 class CallbackData {
138 friend MediaPlayer2AudioOutput;
139 public:
140 explicit CallbackData(MediaPlayer2AudioOutput *cookie) {
141 mData = cookie;
142 mSwitching = false;
143 }
144 MediaPlayer2AudioOutput *getOutput() const {
145 return mData;
146 }
147 void setOutput(MediaPlayer2AudioOutput* newcookie) {
148 mData = newcookie;
149 }
150 // lock/unlock are used by the callback before accessing the payload of this object
151 void lock() const {
152 mLock.lock();
153 }
154 void unlock() const {
155 mLock.unlock();
156 }
157
158 // tryBeginTrackSwitch/endTrackSwitch are used when the CallbackData is handed over
159 // to the next sink.
160
161 // tryBeginTrackSwitch() returns true only if it obtains the lock.
162 bool tryBeginTrackSwitch() {
163 LOG_ALWAYS_FATAL_IF(mSwitching, "tryBeginTrackSwitch() already called");
164 if (mLock.tryLock() != OK) {
165 return false;
166 }
167 mSwitching = true;
168 return true;
169 }
170 void endTrackSwitch() {
171 if (mSwitching) {
172 mLock.unlock();
173 }
174 mSwitching = false;
175 }
176
177 private:
178 MediaPlayer2AudioOutput *mData;
179 mutable Mutex mLock; // a recursive mutex might make this unnecessary.
180 bool mSwitching;
181 DISALLOW_EVIL_CONSTRUCTORS(CallbackData);
182 };
183};
184
185}; // namespace android
186
187#endif // ANDROID_MEDIAPLAYER2AUDIOOUTPUT_H