blob: 1b3f2dc5dc695abe300aba5e8d59d55b8c5b0c55 [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 <utility>
Wei Jiaec044b02018-02-19 12:41:23 -080026#include <utils/String16.h>
27#include <utils/Vector.h>
28
Dongwon Kang0d7042d2018-10-12 16:52:14 -070029#include "jni.h"
30
Wei Jiaec044b02018-02-19 12:41:23 -080031namespace android {
32
33class AudioTrack;
34
35class MediaPlayer2AudioOutput : public MediaPlayer2Interface::AudioSink
36{
37 class CallbackData;
38
39public:
Dichen Zhang23658642018-11-15 10:26:16 -080040 MediaPlayer2AudioOutput(int32_t sessionId,
Wei Jiaec044b02018-02-19 12:41:23 -080041 uid_t uid,
42 int pid,
Dichen Zhanga60eaa82018-11-13 17:14:34 +000043 const jobject attributes);
Wei Jiaec044b02018-02-19 12:41:23 -080044 virtual ~MediaPlayer2AudioOutput();
45
46 virtual bool ready() const {
Dichen Zhangf8726912018-10-17 13:31:26 -070047 return mJAudioTrack != nullptr;
Wei Jiaec044b02018-02-19 12:41:23 -080048 }
49 virtual ssize_t bufferSize() const;
50 virtual ssize_t frameCount() const;
51 virtual ssize_t channelCount() const;
52 virtual ssize_t frameSize() const;
53 virtual uint32_t latency() const;
54 virtual float msecsPerFrame() const;
55 virtual status_t getPosition(uint32_t *position) const;
56 virtual status_t getTimestamp(AudioTimestamp &ts) const;
57 virtual int64_t getPlayedOutDurationUs(int64_t nowUs) const;
58 virtual status_t getFramesWritten(uint32_t *frameswritten) const;
Dichen Zhang23658642018-11-15 10:26:16 -080059 virtual int32_t getSessionId() const;
60 virtual void setSessionId(const int32_t id);
Wei Jiaec044b02018-02-19 12:41:23 -080061 virtual uint32_t getSampleRate() const;
62 virtual int64_t getBufferDurationInUs() const;
63
64 virtual status_t open(
65 uint32_t sampleRate, int channelCount, audio_channel_mask_t channelMask,
Dichen Zhang303bd2d2018-09-28 12:52:49 -070066 audio_format_t format,
Wei Jiaec044b02018-02-19 12:41:23 -080067 AudioCallback cb, void *cookie,
68 audio_output_flags_t flags = AUDIO_OUTPUT_FLAG_NONE,
69 const audio_offload_info_t *offloadInfo = NULL,
Wei Jiaec044b02018-02-19 12:41:23 -080070 uint32_t suggestedFrameCount = 0);
71
72 virtual status_t start();
73 virtual ssize_t write(const void* buffer, size_t size, bool blocking = true);
74 virtual void stop();
75 virtual void flush();
76 virtual void pause();
77 virtual void close();
Dichen Zhangc2465c52018-11-12 11:56:05 -080078 void setAudioAttributes(const jobject attributes);
Dichen Zhangf8726912018-10-17 13:31:26 -070079 virtual audio_stream_type_t getAudioStreamType() const;
Wei Jiaec044b02018-02-19 12:41:23 -080080
Dichen Zhang7398ca02018-10-15 10:25:12 -070081 void setVolume(float volume);
Wei Jiaec044b02018-02-19 12:41:23 -080082 virtual status_t setPlaybackRate(const AudioPlaybackRate& rate);
83 virtual status_t getPlaybackRate(AudioPlaybackRate* rate /* nonnull */);
84
85 status_t setAuxEffectSendLevel(float level);
86 status_t attachAuxEffect(int effectId);
87 virtual status_t dump(int fd, const Vector<String16>& args) const;
88
89 static bool isOnEmulator();
90 static int getMinBufferCount();
Wei Jiaec044b02018-02-19 12:41:23 -080091 virtual bool needsTrailingPadding() {
92 return true;
93 // TODO: return correct value.
94 //return mNextOutput == NULL;
95 }
Wei Jiaec044b02018-02-19 12:41:23 -080096 // AudioRouting
Dongwon Kang0d7042d2018-10-12 16:52:14 -070097 virtual status_t setPreferredDevice(jobject device);
98 virtual jobject getRoutedDevice();
Dichen Zhangf8726912018-10-17 13:31:26 -070099 virtual status_t addAudioDeviceCallback(jobject routingDelegate);
100 virtual status_t removeAudioDeviceCallback(jobject listener);
Wei Jiaec044b02018-02-19 12:41:23 -0800101
102private:
103 static void setMinBufferCount();
104 static void CallbackWrapper(int event, void *me, void *info);
105 void deleteRecycledTrack_l();
106 void close_l();
107 status_t updateTrack_l();
108
Dichen Zhangf8726912018-10-17 13:31:26 -0700109 sp<JAudioTrack> mJAudioTrack;
Wei Jiaec044b02018-02-19 12:41:23 -0800110 AudioCallback mCallback;
111 void * mCallbackCookie;
112 CallbackData * mCallbackData;
Dichen Zhangc2465c52018-11-12 11:56:05 -0800113 sp<JObjectHolder> mAttributes;
Dichen Zhang7398ca02018-10-15 10:25:12 -0700114 float mVolume;
Wei Jiaec044b02018-02-19 12:41:23 -0800115 AudioPlaybackRate mPlaybackRate;
116 uint32_t mSampleRateHz; // sample rate of the content, as set in open()
117 float mMsecsPerFrame;
118 size_t mFrameSize;
Dichen Zhang23658642018-11-15 10:26:16 -0800119 int32_t mSessionId;
Wei Jiaec044b02018-02-19 12:41:23 -0800120 uid_t mUid;
121 int mPid;
122 float mSendLevel;
123 int mAuxEffectId;
124 audio_output_flags_t mFlags;
Dongwon Kang0d7042d2018-10-12 16:52:14 -0700125 sp<JObjectHolder> mPreferredDevice;
Wei Jiaec044b02018-02-19 12:41:23 -0800126 mutable Mutex mLock;
Dichen Zhang4e9bfa02019-03-06 16:33:59 -0800127 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