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