blob: 59b611a4510556827af03b2ec670b9cb93e265ee [file] [log] [blame]
Eric Laurent81784c32012-11-19 14:55:58 -08001/*
2**
3** Copyright 2012, 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
19#define LOG_TAG "AudioFlinger"
20//#define LOG_NDEBUG 0
21
Glenn Kasten153b9fe2013-07-15 11:23:36 -070022#include "Configuration.h"
Eric Laurent81784c32012-11-19 14:55:58 -080023#include <math.h>
Eric Laurent81784c32012-11-19 14:55:58 -080024#include <utils/Log.h>
25
26#include <private/media/AudioTrackShared.h>
27
28#include <common_time/cc_helper.h>
29#include <common_time/local_clock.h>
30
31#include "AudioMixer.h"
32#include "AudioFlinger.h"
33#include "ServiceUtilities.h"
34
Glenn Kastenda6ef132013-01-10 12:31:01 -080035#include <media/nbaio/Pipe.h>
36#include <media/nbaio/PipeReader.h>
37
Eric Laurent81784c32012-11-19 14:55:58 -080038// ----------------------------------------------------------------------------
39
40// Note: the following macro is used for extremely verbose logging message. In
41// order to run with ALOG_ASSERT turned on, we need to have LOG_NDEBUG set to
42// 0; but one side effect of this is to turn all LOGV's as well. Some messages
43// are so verbose that we want to suppress them even when we have ALOG_ASSERT
44// turned on. Do not uncomment the #def below unless you really know what you
45// are doing and want to see all of the extremely verbose messages.
46//#define VERY_VERY_VERBOSE_LOGGING
47#ifdef VERY_VERY_VERBOSE_LOGGING
48#define ALOGVV ALOGV
49#else
50#define ALOGVV(a...) do { } while(0)
51#endif
52
53namespace android {
54
55// ----------------------------------------------------------------------------
56// TrackBase
57// ----------------------------------------------------------------------------
58
Glenn Kastenda6ef132013-01-10 12:31:01 -080059static volatile int32_t nextTrackId = 55;
60
Eric Laurent81784c32012-11-19 14:55:58 -080061// TrackBase constructor must be called with AudioFlinger::mLock held
62AudioFlinger::ThreadBase::TrackBase::TrackBase(
63 ThreadBase *thread,
64 const sp<Client>& client,
65 uint32_t sampleRate,
66 audio_format_t format,
67 audio_channel_mask_t channelMask,
68 size_t frameCount,
Ethan Chen8d420ed2013-11-14 00:40:54 -080069#ifdef QCOM_HARDWARE
Alok Kediya601e9b52013-09-27 11:55:10 +053070 uint32_t flags,
Ethan Chen8d420ed2013-11-14 00:40:54 -080071#endif
Eric Laurent81784c32012-11-19 14:55:58 -080072 const sp<IMemory>& sharedBuffer,
Glenn Kastene3aa6592012-12-04 12:22:46 -080073 int sessionId,
Marco Nelissen9cae2172013-01-14 14:12:05 -080074 int clientUid,
Glenn Kastene3aa6592012-12-04 12:22:46 -080075 bool isOut)
Eric Laurent81784c32012-11-19 14:55:58 -080076 : RefBase(),
77 mThread(thread),
78 mClient(client),
79 mCblk(NULL),
80 // mBuffer
Eric Laurent81784c32012-11-19 14:55:58 -080081 mState(IDLE),
82 mSampleRate(sampleRate),
83 mFormat(format),
84 mChannelMask(channelMask),
85 mChannelCount(popcount(channelMask)),
Ethan Chen8d420ed2013-11-14 00:40:54 -080086#ifdef QCOM_HARDWARE
Alok Kediya601e9b52013-09-27 11:55:10 +053087 mFrameSize((audio_is_linear_pcm(format) || audio_is_supported_compressed(format)) ?
88 ((flags & IAudioFlinger::TRACK_VOICE_COMMUNICATION)? mChannelCount * sizeof(int16_t) : mChannelCount * audio_bytes_per_sample(format)) : sizeof(int8_t)),
Ethan Chen8d420ed2013-11-14 00:40:54 -080089#else
90 mFrameSize(audio_is_linear_pcm(format) ?
91 mChannelCount * audio_bytes_per_sample(format) : sizeof(int8_t)),
92#endif
Eric Laurent81784c32012-11-19 14:55:58 -080093 mFrameCount(frameCount),
Ethan Chen8d420ed2013-11-14 00:40:54 -080094#ifdef QCOM_HARDWARE
Alok Kediya601e9b52013-09-27 11:55:10 +053095 mFlags(0),
Ethan Chen8d420ed2013-11-14 00:40:54 -080096#endif
Glenn Kastene3aa6592012-12-04 12:22:46 -080097 mSessionId(sessionId),
98 mIsOut(isOut),
Glenn Kastenda6ef132013-01-10 12:31:01 -080099 mServerProxy(NULL),
Eric Laurentbfb1b832013-01-07 09:53:42 -0800100 mId(android_atomic_inc(&nextTrackId)),
101 mTerminated(false)
Eric Laurent81784c32012-11-19 14:55:58 -0800102{
Marco Nelissen9cae2172013-01-14 14:12:05 -0800103 // if the caller is us, trust the specified uid
104 if (IPCThreadState::self()->getCallingPid() != getpid_cached || clientUid == -1) {
105 int newclientUid = IPCThreadState::self()->getCallingUid();
106 if (clientUid != -1 && clientUid != newclientUid) {
107 ALOGW("uid %d tried to pass itself off as %d", newclientUid, clientUid);
108 }
109 clientUid = newclientUid;
110 }
111 // clientUid contains the uid of the app that is responsible for this track, so we can blame
112 // battery usage on it.
113 mUid = clientUid;
114
Eric Laurent81784c32012-11-19 14:55:58 -0800115 // client == 0 implies sharedBuffer == 0
116 ALOG_ASSERT(!(client == 0 && sharedBuffer != 0));
117
118 ALOGV_IF(sharedBuffer != 0, "sharedBuffer: %p, size: %d", sharedBuffer->pointer(),
119 sharedBuffer->size());
120
121 // ALOGD("Creating track with %d buffers @ %d bytes", bufferCount, bufferSize);
122 size_t size = sizeof(audio_track_cblk_t);
Ethan Chen8d420ed2013-11-14 00:40:54 -0800123#ifdef QCOM_HARDWARE
Alok Kediya601e9b52013-09-27 11:55:10 +0530124 uint8_t channelCount = popcount(channelMask);
125 size_t bufferSize = 0;
126 if (flags & IAudioFlinger::TRACK_VOICE_COMMUNICATION) {
127 bufferSize = roundup(frameCount) * channelCount * mFrameSize;
128 } else {
129 if ( (format == AUDIO_FORMAT_PCM_16_BIT) ||
130 (format == AUDIO_FORMAT_PCM_8_BIT)) {
131 bufferSize = frameCount * channelCount * sizeof(int16_t);
132 } else if (format == AUDIO_FORMAT_AMR_NB) {
133 bufferSize = frameCount * channelCount * AMR_FRAMESIZE; // full rate frame size
134 } else if (format == AUDIO_FORMAT_EVRC) {
135 bufferSize = frameCount * channelCount * EVRC_FRAMESIZE; // full rate frame size
136 } else if (format == AUDIO_FORMAT_QCELP) {
137 bufferSize = frameCount * channelCount * QCELP_FRAMESIZE; // full rate frame size
138 } else if (format == AUDIO_FORMAT_AAC) {
139 bufferSize = frameCount * AAC_FRAMESIZE; // full rate frame size
140 } else if (format == AUDIO_FORMAT_AMR_WB) {
141 bufferSize = frameCount * channelCount * AMR_WB_FRAMESIZE; // full rate frame size
142 }
143 }
Ethan Chen8d420ed2013-11-14 00:40:54 -0800144#else
145 size_t bufferSize = (sharedBuffer == 0 ? roundup(frameCount) : frameCount) * mFrameSize;
146#endif
Alok Kediya601e9b52013-09-27 11:55:10 +0530147
Eric Laurent81784c32012-11-19 14:55:58 -0800148 if (sharedBuffer == 0) {
149 size += bufferSize;
150 }
151
152 if (client != 0) {
153 mCblkMemory = client->heap()->allocate(size);
154 if (mCblkMemory != 0) {
155 mCblk = static_cast<audio_track_cblk_t *>(mCblkMemory->pointer());
156 // can't assume mCblk != NULL
157 } else {
158 ALOGE("not enough memory for AudioTrack size=%u", size);
159 client->heap()->dump("AudioTrack");
160 return;
161 }
162 } else {
Glenn Kastene3aa6592012-12-04 12:22:46 -0800163 // this syntax avoids calling the audio_track_cblk_t constructor twice
164 mCblk = (audio_track_cblk_t *) new uint8_t[size];
Eric Laurent81784c32012-11-19 14:55:58 -0800165 // assume mCblk != NULL
166 }
167
168 // construct the shared structure in-place.
169 if (mCblk != NULL) {
170 new(mCblk) audio_track_cblk_t();
171 // clear all buffers
172 mCblk->frameCount_ = frameCount;
Eric Laurent81784c32012-11-19 14:55:58 -0800173 if (sharedBuffer == 0) {
174 mBuffer = (char*)mCblk + sizeof(audio_track_cblk_t);
Ethan Chen8d420ed2013-11-14 00:40:54 -0800175#ifdef QCOM_HARDWARE
Alok Kediya601e9b52013-09-27 11:55:10 +0530176 if (flags & IAudioFlinger::TRACK_VOICE_COMMUNICATION) {
177 memset(mBuffer, 0, bufferSize);
178 } else {
179 if ((format == AUDIO_FORMAT_PCM_16_BIT) ||
180 (format == AUDIO_FORMAT_PCM_8_BIT)) {
181 memset(mBuffer, 0, bufferSize);
182 } else if (format == AUDIO_FORMAT_AMR_NB) {
183 // full rate frame size
184 memset(mBuffer, 0, frameCount * channelCount * AMR_FRAMESIZE);
185 } else if (format == AUDIO_FORMAT_EVRC) {
186 // full rate frame size
187 memset(mBuffer, 0, frameCount * channelCount * EVRC_FRAMESIZE);
188 } else if (format == AUDIO_FORMAT_QCELP) {
189 // full rate frame size
190 memset(mBuffer, 0, frameCount * channelCount * QCELP_FRAMESIZE);
191 } else if (format == AUDIO_FORMAT_AAC) {
192 // full rate frame size
193 memset(mBuffer, 0, frameCount * AAC_FRAMESIZE);
194 } else if (format == AUDIO_FORMAT_AMR_WB) {
195 // full rate frame size
196 memset(mBuffer, 0, frameCount * channelCount * AMR_WB_FRAMESIZE);
197 }
198 }
Ethan Chen8d420ed2013-11-14 00:40:54 -0800199#else
200 memset(mBuffer, 0, bufferSize);
201#endif
Eric Laurent81784c32012-11-19 14:55:58 -0800202 } else {
203 mBuffer = sharedBuffer->pointer();
Glenn Kasten9f80dd22012-12-18 15:57:32 -0800204#if 0
Glenn Kasten96f60d82013-07-12 10:21:18 -0700205 mCblk->mFlags = CBLK_FORCEREADY; // FIXME hack, need to fix the track ready logic
Glenn Kasten9f80dd22012-12-18 15:57:32 -0800206#endif
Eric Laurent81784c32012-11-19 14:55:58 -0800207 }
Glenn Kastenda6ef132013-01-10 12:31:01 -0800208
Glenn Kasten46909e72013-02-26 09:20:22 -0800209#ifdef TEE_SINK
Glenn Kastenda6ef132013-01-10 12:31:01 -0800210 if (mTeeSinkTrackEnabled) {
Glenn Kasten46909e72013-02-26 09:20:22 -0800211 NBAIO_Format pipeFormat = Format_from_SR_C(mSampleRate, mChannelCount);
212 if (pipeFormat != Format_Invalid) {
213 Pipe *pipe = new Pipe(mTeeSinkTrackFrames, pipeFormat);
214 size_t numCounterOffers = 0;
215 const NBAIO_Format offers[1] = {pipeFormat};
216 ssize_t index = pipe->negotiate(offers, 1, NULL, numCounterOffers);
217 ALOG_ASSERT(index == 0);
218 PipeReader *pipeReader = new PipeReader(*pipe);
219 numCounterOffers = 0;
220 index = pipeReader->negotiate(offers, 1, NULL, numCounterOffers);
221 ALOG_ASSERT(index == 0);
222 mTeeSink = pipe;
223 mTeeSource = pipeReader;
224 }
Glenn Kastenda6ef132013-01-10 12:31:01 -0800225 }
Glenn Kasten46909e72013-02-26 09:20:22 -0800226#endif
Glenn Kastenda6ef132013-01-10 12:31:01 -0800227
Eric Laurent81784c32012-11-19 14:55:58 -0800228 }
229}
230
231AudioFlinger::ThreadBase::TrackBase::~TrackBase()
232{
Glenn Kasten46909e72013-02-26 09:20:22 -0800233#ifdef TEE_SINK
Glenn Kastenda6ef132013-01-10 12:31:01 -0800234 dumpTee(-1, mTeeSource, mId);
Glenn Kasten46909e72013-02-26 09:20:22 -0800235#endif
Glenn Kastene3aa6592012-12-04 12:22:46 -0800236 // delete the proxy before deleting the shared memory it refers to, to avoid dangling reference
237 delete mServerProxy;
Eric Laurent81784c32012-11-19 14:55:58 -0800238 if (mCblk != NULL) {
239 if (mClient == 0) {
240 delete mCblk;
241 } else {
242 mCblk->~audio_track_cblk_t(); // destroy our shared-structure.
243 }
244 }
245 mCblkMemory.clear(); // free the shared memory before releasing the heap it belongs to
246 if (mClient != 0) {
247 // Client destructor must run with AudioFlinger mutex locked
248 Mutex::Autolock _l(mClient->audioFlinger()->mLock);
249 // If the client's reference count drops to zero, the associated destructor
250 // must run with AudioFlinger lock held. Thus the explicit clear() rather than
251 // relying on the automatic clear() at end of scope.
252 mClient.clear();
253 }
254}
255
256// AudioBufferProvider interface
257// getNextBuffer() = 0;
258// This implementation of releaseBuffer() is used by Track and RecordTrack, but not TimedTrack
259void AudioFlinger::ThreadBase::TrackBase::releaseBuffer(AudioBufferProvider::Buffer* buffer)
260{
Glenn Kasten46909e72013-02-26 09:20:22 -0800261#ifdef TEE_SINK
Glenn Kastenda6ef132013-01-10 12:31:01 -0800262 if (mTeeSink != 0) {
263 (void) mTeeSink->write(buffer->raw, buffer->frameCount);
264 }
Glenn Kasten46909e72013-02-26 09:20:22 -0800265#endif
Glenn Kastenda6ef132013-01-10 12:31:01 -0800266
Glenn Kasten9f80dd22012-12-18 15:57:32 -0800267 ServerProxy::Buffer buf;
268 buf.mFrameCount = buffer->frameCount;
269 buf.mRaw = buffer->raw;
Eric Laurent81784c32012-11-19 14:55:58 -0800270 buffer->frameCount = 0;
Glenn Kasten9f80dd22012-12-18 15:57:32 -0800271 buffer->raw = NULL;
272 mServerProxy->releaseBuffer(&buf);
Eric Laurent81784c32012-11-19 14:55:58 -0800273}
274
Eric Laurent81784c32012-11-19 14:55:58 -0800275status_t AudioFlinger::ThreadBase::TrackBase::setSyncEvent(const sp<SyncEvent>& event)
276{
277 mSyncEvents.add(event);
278 return NO_ERROR;
279}
280
281// ----------------------------------------------------------------------------
282// Playback
283// ----------------------------------------------------------------------------
284
285AudioFlinger::TrackHandle::TrackHandle(const sp<AudioFlinger::PlaybackThread::Track>& track)
286 : BnAudioTrack(),
287 mTrack(track)
288{
289}
290
291AudioFlinger::TrackHandle::~TrackHandle() {
292 // just stop the track on deletion, associated resources
293 // will be freed from the main thread once all pending buffers have
294 // been played. Unless it's not in the active track list, in which
295 // case we free everything now...
296 mTrack->destroy();
297}
298
299sp<IMemory> AudioFlinger::TrackHandle::getCblk() const {
300 return mTrack->getCblk();
301}
302
303status_t AudioFlinger::TrackHandle::start() {
304 return mTrack->start();
305}
306
307void AudioFlinger::TrackHandle::stop() {
308 mTrack->stop();
309}
310
311void AudioFlinger::TrackHandle::flush() {
312 mTrack->flush();
313}
314
Eric Laurent81784c32012-11-19 14:55:58 -0800315void AudioFlinger::TrackHandle::pause() {
316 mTrack->pause();
317}
318
319status_t AudioFlinger::TrackHandle::attachAuxEffect(int EffectId)
320{
321 return mTrack->attachAuxEffect(EffectId);
322}
323
324status_t AudioFlinger::TrackHandle::allocateTimedBuffer(size_t size,
325 sp<IMemory>* buffer) {
326 if (!mTrack->isTimedTrack())
327 return INVALID_OPERATION;
328
329 PlaybackThread::TimedTrack* tt =
330 reinterpret_cast<PlaybackThread::TimedTrack*>(mTrack.get());
331 return tt->allocateTimedBuffer(size, buffer);
332}
333
334status_t AudioFlinger::TrackHandle::queueTimedBuffer(const sp<IMemory>& buffer,
335 int64_t pts) {
336 if (!mTrack->isTimedTrack())
337 return INVALID_OPERATION;
338
339 PlaybackThread::TimedTrack* tt =
340 reinterpret_cast<PlaybackThread::TimedTrack*>(mTrack.get());
341 return tt->queueTimedBuffer(buffer, pts);
342}
343
344status_t AudioFlinger::TrackHandle::setMediaTimeTransform(
345 const LinearTransform& xform, int target) {
346
347 if (!mTrack->isTimedTrack())
348 return INVALID_OPERATION;
349
350 PlaybackThread::TimedTrack* tt =
351 reinterpret_cast<PlaybackThread::TimedTrack*>(mTrack.get());
352 return tt->setMediaTimeTransform(
353 xform, static_cast<TimedAudioTrack::TargetTimeline>(target));
354}
355
Glenn Kasten3dcd00d2013-07-17 10:10:23 -0700356status_t AudioFlinger::TrackHandle::setParameters(const String8& keyValuePairs) {
357 return mTrack->setParameters(keyValuePairs);
358}
359
Glenn Kasten53cec222013-08-29 09:01:02 -0700360status_t AudioFlinger::TrackHandle::getTimestamp(AudioTimestamp& timestamp)
361{
Glenn Kasten573d80a2013-08-26 09:36:23 -0700362 return mTrack->getTimestamp(timestamp);
Glenn Kasten53cec222013-08-29 09:01:02 -0700363}
364
Eric Laurent59fe0102013-09-27 18:48:26 -0700365
366void AudioFlinger::TrackHandle::signal()
367{
368 return mTrack->signal();
369}
370
Eric Laurent81784c32012-11-19 14:55:58 -0800371status_t AudioFlinger::TrackHandle::onTransact(
372 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
373{
374 return BnAudioTrack::onTransact(code, data, reply, flags);
375}
376
377// ----------------------------------------------------------------------------
378
379// Track constructor must be called with AudioFlinger::mLock and ThreadBase::mLock held
380AudioFlinger::PlaybackThread::Track::Track(
381 PlaybackThread *thread,
382 const sp<Client>& client,
383 audio_stream_type_t streamType,
384 uint32_t sampleRate,
385 audio_format_t format,
386 audio_channel_mask_t channelMask,
387 size_t frameCount,
388 const sp<IMemory>& sharedBuffer,
389 int sessionId,
Marco Nelissen9cae2172013-01-14 14:12:05 -0800390 int uid,
Eric Laurent81784c32012-11-19 14:55:58 -0800391 IAudioFlinger::track_flags_t flags)
Ethan Chen8d420ed2013-11-14 00:40:54 -0800392#ifdef QCOM_HARDWARE
Alok Kediya601e9b52013-09-27 11:55:10 +0530393 : TrackBase(thread, client, sampleRate, format, channelMask, frameCount,
394 ((audio_stream_type_t)streamType == AUDIO_STREAM_VOICE_CALL)? IAudioFlinger::TRACK_VOICE_COMMUNICATION:0x0,
Ricardo Cerqueira574d7be2013-12-06 02:42:19 +0000395 sharedBuffer, sessionId, uid, true /*isOut*/),
Ethan Chen8d420ed2013-11-14 00:40:54 -0800396#else
397 : TrackBase(thread, client, sampleRate, format, channelMask, frameCount, sharedBuffer,
Marco Nelissen9cae2172013-01-14 14:12:05 -0800398 sessionId, uid, true /*isOut*/),
Ethan Chen8d420ed2013-11-14 00:40:54 -0800399#endif
Eric Laurent81784c32012-11-19 14:55:58 -0800400 mFillingUpStatus(FS_INVALID),
401 // mRetryCount initialized later when needed
402 mSharedBuffer(sharedBuffer),
403 mStreamType(streamType),
404 mName(-1), // see note below
405 mMainBuffer(thread->mixBuffer()),
406 mAuxBuffer(NULL),
407 mAuxEffectId(0), mHasVolumeController(false),
408 mPresentationCompleteFrames(0),
409 mFlags(flags),
410 mFastIndex(-1),
Glenn Kasten5736c352012-12-04 12:12:34 -0800411 mCachedVolume(1.0),
Glenn Kasten9f80dd22012-12-18 15:57:32 -0800412 mIsInvalid(false),
Eric Laurentbfb1b832013-01-07 09:53:42 -0800413 mAudioTrackServerProxy(NULL),
414 mResumeToStopping(false)
Eric Laurent81784c32012-11-19 14:55:58 -0800415{
416 if (mCblk != NULL) {
Glenn Kasten9f80dd22012-12-18 15:57:32 -0800417 if (sharedBuffer == 0) {
418 mAudioTrackServerProxy = new AudioTrackServerProxy(mCblk, mBuffer, frameCount,
419 mFrameSize);
420 } else {
421 mAudioTrackServerProxy = new StaticAudioTrackServerProxy(mCblk, mBuffer, frameCount,
422 mFrameSize);
423 }
424 mServerProxy = mAudioTrackServerProxy;
Eric Laurent81784c32012-11-19 14:55:58 -0800425 // to avoid leaking a track name, do not allocate one unless there is an mCblk
426 mName = thread->getTrackName_l(channelMask, sessionId);
Eric Laurent81784c32012-11-19 14:55:58 -0800427 if (mName < 0) {
428 ALOGE("no more track names available");
429 return;
430 }
431 // only allocate a fast track index if we were able to allocate a normal track name
432 if (flags & IAudioFlinger::TRACK_FAST) {
Glenn Kasten9f80dd22012-12-18 15:57:32 -0800433 mAudioTrackServerProxy->framesReadyIsCalledByMultipleThreads();
Eric Laurent81784c32012-11-19 14:55:58 -0800434 ALOG_ASSERT(thread->mFastTrackAvailMask != 0);
435 int i = __builtin_ctz(thread->mFastTrackAvailMask);
436 ALOG_ASSERT(0 < i && i < (int)FastMixerState::kMaxFastTracks);
437 // FIXME This is too eager. We allocate a fast track index before the
438 // fast track becomes active. Since fast tracks are a scarce resource,
439 // this means we are potentially denying other more important fast tracks from
440 // being created. It would be better to allocate the index dynamically.
441 mFastIndex = i;
Eric Laurent81784c32012-11-19 14:55:58 -0800442 // Read the initial underruns because this field is never cleared by the fast mixer
443 mObservedUnderruns = thread->getFastTrackUnderruns(i);
444 thread->mFastTrackAvailMask &= ~(1 << i);
445 }
446 }
447 ALOGV("Track constructor name %d, calling pid %d", mName,
448 IPCThreadState::self()->getCallingPid());
449}
450
451AudioFlinger::PlaybackThread::Track::~Track()
452{
453 ALOGV("PlaybackThread::Track destructor");
Glenn Kasten0c72b242013-09-11 09:14:16 -0700454
455 // The destructor would clear mSharedBuffer,
456 // but it will not push the decremented reference count,
457 // leaving the client's IMemory dangling indefinitely.
458 // This prevents that leak.
459 if (mSharedBuffer != 0) {
460 mSharedBuffer.clear();
461 // flush the binder command buffer
462 IPCThreadState::self()->flushCommands();
463 }
Eric Laurent81784c32012-11-19 14:55:58 -0800464}
465
466void AudioFlinger::PlaybackThread::Track::destroy()
467{
468 // NOTE: destroyTrack_l() can remove a strong reference to this Track
469 // by removing it from mTracks vector, so there is a risk that this Tracks's
470 // destructor is called. As the destructor needs to lock mLock,
471 // we must acquire a strong reference on this Track before locking mLock
472 // here so that the destructor is called only when exiting this function.
473 // On the other hand, as long as Track::destroy() is only called by
474 // TrackHandle destructor, the TrackHandle still holds a strong ref on
475 // this Track with its member mTrack.
476 sp<Track> keep(this);
477 { // scope for mLock
478 sp<ThreadBase> thread = mThread.promote();
479 if (thread != 0) {
Eric Laurent81784c32012-11-19 14:55:58 -0800480 Mutex::Autolock _l(thread->mLock);
481 PlaybackThread *playbackThread = (PlaybackThread *)thread.get();
Eric Laurentbfb1b832013-01-07 09:53:42 -0800482 bool wasActive = playbackThread->destroyTrack_l(this);
483 if (!isOutputTrack() && !wasActive) {
484 AudioSystem::releaseOutput(thread->id());
485 }
Eric Laurent81784c32012-11-19 14:55:58 -0800486 }
487 }
488}
489
490/*static*/ void AudioFlinger::PlaybackThread::Track::appendDumpHeader(String8& result)
491{
Eric Laurent972a1732013-09-04 09:42:59 -0700492 result.append(" Name Client Type Fmt Chn mask Session fCount S F SRate "
Glenn Kasten82aaf942013-07-17 16:05:07 -0700493 "L dB R dB Server Main buf Aux Buf Flags UndFrmCnt\n");
Eric Laurent81784c32012-11-19 14:55:58 -0800494}
495
496void AudioFlinger::PlaybackThread::Track::dump(char* buffer, size_t size)
497{
Glenn Kasten9f80dd22012-12-18 15:57:32 -0800498 uint32_t vlr = mAudioTrackServerProxy->getVolumeLR();
Eric Laurent81784c32012-11-19 14:55:58 -0800499 if (isFastTrack()) {
500 sprintf(buffer, " F %2d", mFastIndex);
501 } else {
502 sprintf(buffer, " %4d", mName - AudioMixer::TRACK0);
503 }
504 track_state state = mState;
505 char stateChar;
Eric Laurentbfb1b832013-01-07 09:53:42 -0800506 if (isTerminated()) {
Eric Laurent81784c32012-11-19 14:55:58 -0800507 stateChar = 'T';
Eric Laurentbfb1b832013-01-07 09:53:42 -0800508 } else {
509 switch (state) {
510 case IDLE:
511 stateChar = 'I';
512 break;
513 case STOPPING_1:
514 stateChar = 's';
515 break;
516 case STOPPING_2:
517 stateChar = '5';
518 break;
519 case STOPPED:
520 stateChar = 'S';
521 break;
522 case RESUMING:
523 stateChar = 'R';
524 break;
525 case ACTIVE:
526 stateChar = 'A';
527 break;
528 case PAUSING:
529 stateChar = 'p';
530 break;
531 case PAUSED:
532 stateChar = 'P';
533 break;
534 case FLUSHED:
535 stateChar = 'F';
536 break;
537 default:
538 stateChar = '?';
539 break;
540 }
Eric Laurent81784c32012-11-19 14:55:58 -0800541 }
542 char nowInUnderrun;
543 switch (mObservedUnderruns.mBitFields.mMostRecent) {
544 case UNDERRUN_FULL:
545 nowInUnderrun = ' ';
546 break;
547 case UNDERRUN_PARTIAL:
548 nowInUnderrun = '<';
549 break;
550 case UNDERRUN_EMPTY:
551 nowInUnderrun = '*';
552 break;
553 default:
554 nowInUnderrun = '?';
555 break;
556 }
Eric Laurent972a1732013-09-04 09:42:59 -0700557 snprintf(&buffer[7], size-7, " %6u %4u %08X %08X %7u %6u %1c %1d %5u %5.2g %5.2g "
Glenn Kastenbd4c4fb2013-07-25 14:21:14 -0700558 "%08X %08X %08X 0x%03X %9u%c\n",
Eric Laurent81784c32012-11-19 14:55:58 -0800559 (mClient == 0) ? getpid_cached : mClient->pid(),
560 mStreamType,
561 mFormat,
562 mChannelMask,
563 mSessionId,
Eric Laurent81784c32012-11-19 14:55:58 -0800564 mFrameCount,
565 stateChar,
Eric Laurent81784c32012-11-19 14:55:58 -0800566 mFillingUpStatus,
Glenn Kasten9f80dd22012-12-18 15:57:32 -0800567 mAudioTrackServerProxy->getSampleRate(),
Eric Laurent81784c32012-11-19 14:55:58 -0800568 20.0 * log10((vlr & 0xFFFF) / 4096.0),
569 20.0 * log10((vlr >> 16) / 4096.0),
Glenn Kastenf20e1d82013-07-12 09:45:18 -0700570 mCblk->mServer,
Eric Laurent81784c32012-11-19 14:55:58 -0800571 (int)mMainBuffer,
572 (int)mAuxBuffer,
Glenn Kasten96f60d82013-07-12 10:21:18 -0700573 mCblk->mFlags,
Glenn Kasten82aaf942013-07-17 16:05:07 -0700574 mAudioTrackServerProxy->getUnderrunFrames(),
Eric Laurent81784c32012-11-19 14:55:58 -0800575 nowInUnderrun);
576}
577
Glenn Kasten9f80dd22012-12-18 15:57:32 -0800578uint32_t AudioFlinger::PlaybackThread::Track::sampleRate() const {
579 return mAudioTrackServerProxy->getSampleRate();
580}
581
Eric Laurent81784c32012-11-19 14:55:58 -0800582// AudioBufferProvider interface
583status_t AudioFlinger::PlaybackThread::Track::getNextBuffer(
584 AudioBufferProvider::Buffer* buffer, int64_t pts)
585{
Glenn Kasten9f80dd22012-12-18 15:57:32 -0800586 ServerProxy::Buffer buf;
587 size_t desiredFrames = buffer->frameCount;
588 buf.mFrameCount = desiredFrames;
589 status_t status = mServerProxy->obtainBuffer(&buf);
590 buffer->frameCount = buf.mFrameCount;
591 buffer->raw = buf.mRaw;
592 if (buf.mFrameCount == 0) {
Glenn Kasten82aaf942013-07-17 16:05:07 -0700593 mAudioTrackServerProxy->tallyUnderrunFrames(desiredFrames);
Eric Laurent81784c32012-11-19 14:55:58 -0800594 }
Glenn Kasten9f80dd22012-12-18 15:57:32 -0800595 return status;
Eric Laurent81784c32012-11-19 14:55:58 -0800596}
597
Glenn Kasten6466c9e2013-08-23 10:54:07 -0700598// releaseBuffer() is not overridden
599
600// ExtendedAudioBufferProvider interface
601
Eric Laurent81784c32012-11-19 14:55:58 -0800602// Note that framesReady() takes a mutex on the control block using tryLock().
603// This could result in priority inversion if framesReady() is called by the normal mixer,
604// as the normal mixer thread runs at lower
605// priority than the client's callback thread: there is a short window within framesReady()
606// during which the normal mixer could be preempted, and the client callback would block.
607// Another problem can occur if framesReady() is called by the fast mixer:
608// the tryLock() could block for up to 1 ms, and a sequence of these could delay fast mixer.
609// FIXME Replace AudioTrackShared control block implementation by a non-blocking FIFO queue.
610size_t AudioFlinger::PlaybackThread::Track::framesReady() const {
Glenn Kasten9f80dd22012-12-18 15:57:32 -0800611 return mAudioTrackServerProxy->framesReady();
Eric Laurent81784c32012-11-19 14:55:58 -0800612}
613
Glenn Kasten6466c9e2013-08-23 10:54:07 -0700614size_t AudioFlinger::PlaybackThread::Track::framesReleased() const
615{
616 return mAudioTrackServerProxy->framesReleased();
617}
618
Eric Laurent81784c32012-11-19 14:55:58 -0800619// Don't call for fast tracks; the framesReady() could result in priority inversion
620bool AudioFlinger::PlaybackThread::Track::isReady() const {
Haynes Mathew Georgee0cd1052013-12-27 16:09:28 -0800621 if (mFillingUpStatus != FS_FILLING || isStopped() || isPausing() || isStopping()) {
Eric Laurent81784c32012-11-19 14:55:58 -0800622 return true;
623 }
624
625 if (framesReady() >= mFrameCount ||
Glenn Kasten96f60d82013-07-12 10:21:18 -0700626 (mCblk->mFlags & CBLK_FORCEREADY)) {
Eric Laurent81784c32012-11-19 14:55:58 -0800627 mFillingUpStatus = FS_FILLED;
Glenn Kasten96f60d82013-07-12 10:21:18 -0700628 android_atomic_and(~CBLK_FORCEREADY, &mCblk->mFlags);
Eric Laurent81784c32012-11-19 14:55:58 -0800629 return true;
630 }
631 return false;
632}
633
634status_t AudioFlinger::PlaybackThread::Track::start(AudioSystem::sync_event_t event,
635 int triggerSession)
636{
637 status_t status = NO_ERROR;
638 ALOGV("start(%d), calling pid %d session %d",
639 mName, IPCThreadState::self()->getCallingPid(), mSessionId);
640
641 sp<ThreadBase> thread = mThread.promote();
642 if (thread != 0) {
Eric Laurent813e2a72013-08-31 12:59:48 -0700643 if (isOffloaded()) {
644 Mutex::Autolock _laf(thread->mAudioFlinger->mLock);
645 Mutex::Autolock _lth(thread->mLock);
646 sp<EffectChain> ec = thread->getEffectChain_l(mSessionId);
Eric Laurent5baf2af2013-09-12 17:37:00 -0700647 if (thread->mAudioFlinger->isNonOffloadableGlobalEffectEnabled_l() ||
648 (ec != 0 && ec->isNonOffloadableEnabled())) {
Eric Laurent813e2a72013-08-31 12:59:48 -0700649 invalidate();
650 return PERMISSION_DENIED;
651 }
652 }
653 Mutex::Autolock _lth(thread->mLock);
Eric Laurent81784c32012-11-19 14:55:58 -0800654 track_state state = mState;
655 // here the track could be either new, or restarted
656 // in both cases "unstop" the track
Eric Laurentbfb1b832013-01-07 09:53:42 -0800657
Glenn Kastenc9b2e202013-02-26 11:32:32 -0800658 if (state == PAUSED) {
Eric Laurentbfb1b832013-01-07 09:53:42 -0800659 if (mResumeToStopping) {
660 // happened we need to resume to STOPPING_1
661 mState = TrackBase::STOPPING_1;
662 ALOGV("PAUSED => STOPPING_1 (%d) on thread %p", mName, this);
663 } else {
664 mState = TrackBase::RESUMING;
665 ALOGV("PAUSED => RESUMING (%d) on thread %p", mName, this);
666 }
Eric Laurent81784c32012-11-19 14:55:58 -0800667 } else {
668 mState = TrackBase::ACTIVE;
669 ALOGV("? => ACTIVE (%d) on thread %p", mName, this);
670 }
671
Eric Laurentbfb1b832013-01-07 09:53:42 -0800672 PlaybackThread *playbackThread = (PlaybackThread *)thread.get();
673 status = playbackThread->addTrack_l(this);
674 if (status == INVALID_OPERATION || status == PERMISSION_DENIED) {
Eric Laurent81784c32012-11-19 14:55:58 -0800675 triggerEvents(AudioSystem::SYNC_EVENT_PRESENTATION_COMPLETE);
Eric Laurentbfb1b832013-01-07 09:53:42 -0800676 // restore previous state if start was rejected by policy manager
677 if (status == PERMISSION_DENIED) {
678 mState = state;
679 }
680 }
681 // track was already in the active list, not a problem
682 if (status == ALREADY_EXISTS) {
683 status = NO_ERROR;
Glenn Kasten4ce5dd92013-10-17 11:32:39 -0700684 } else {
685 // Acknowledge any pending flush(), so that subsequent new data isn't discarded.
686 // It is usually unsafe to access the server proxy from a binder thread.
687 // But in this case we know the mixer thread (whether normal mixer or fast mixer)
688 // isn't looking at this track yet: we still hold the normal mixer thread lock,
689 // and for fast tracks the track is not yet in the fast mixer thread's active set.
690 ServerProxy::Buffer buffer;
691 buffer.mFrameCount = 1;
Glenn Kastena6f2c7b2013-10-18 13:00:29 -0700692 (void) mAudioTrackServerProxy->obtainBuffer(&buffer, true /*ackFlush*/);
Eric Laurent81784c32012-11-19 14:55:58 -0800693 }
694 } else {
695 status = BAD_VALUE;
696 }
697 return status;
698}
699
700void AudioFlinger::PlaybackThread::Track::stop()
701{
702 ALOGV("stop(%d), calling pid %d", mName, IPCThreadState::self()->getCallingPid());
703 sp<ThreadBase> thread = mThread.promote();
704 if (thread != 0) {
705 Mutex::Autolock _l(thread->mLock);
706 track_state state = mState;
707 if (state == RESUMING || state == ACTIVE || state == PAUSING || state == PAUSED) {
708 // If the track is not active (PAUSED and buffers full), flush buffers
709 PlaybackThread *playbackThread = (PlaybackThread *)thread.get();
710 if (playbackThread->mActiveTracks.indexOf(this) < 0) {
711 reset();
712 mState = STOPPED;
Eric Laurentbfb1b832013-01-07 09:53:42 -0800713 } else if (!isFastTrack() && !isOffloaded()) {
Eric Laurent81784c32012-11-19 14:55:58 -0800714 mState = STOPPED;
715 } else {
Eric Laurentbfb1b832013-01-07 09:53:42 -0800716 // For fast tracks prepareTracks_l() will set state to STOPPING_2
717 // presentation is complete
718 // For an offloaded track this starts a drain and state will
719 // move to STOPPING_2 when drain completes and then STOPPED
Eric Laurent81784c32012-11-19 14:55:58 -0800720 mState = STOPPING_1;
721 }
722 ALOGV("not stopping/stopped => stopping/stopped (%d) on thread %p", mName,
723 playbackThread);
724 }
Eric Laurent81784c32012-11-19 14:55:58 -0800725 }
726}
727
728void AudioFlinger::PlaybackThread::Track::pause()
729{
730 ALOGV("pause(%d), calling pid %d", mName, IPCThreadState::self()->getCallingPid());
731 sp<ThreadBase> thread = mThread.promote();
732 if (thread != 0) {
733 Mutex::Autolock _l(thread->mLock);
Eric Laurentbfb1b832013-01-07 09:53:42 -0800734 PlaybackThread *playbackThread = (PlaybackThread *)thread.get();
735 switch (mState) {
736 case STOPPING_1:
737 case STOPPING_2:
738 if (!isOffloaded()) {
739 /* nothing to do if track is not offloaded */
740 break;
741 }
742
743 // Offloaded track was draining, we need to carry on draining when resumed
744 mResumeToStopping = true;
745 // fall through...
746 case ACTIVE:
747 case RESUMING:
Eric Laurent81784c32012-11-19 14:55:58 -0800748 mState = PAUSING;
749 ALOGV("ACTIVE/RESUMING => PAUSING (%d) on thread %p", mName, thread.get());
Eric Laurentede6c3b2013-09-19 14:37:46 -0700750 playbackThread->broadcast_l();
Eric Laurentbfb1b832013-01-07 09:53:42 -0800751 break;
Eric Laurent81784c32012-11-19 14:55:58 -0800752
Eric Laurentbfb1b832013-01-07 09:53:42 -0800753 default:
754 break;
Eric Laurent81784c32012-11-19 14:55:58 -0800755 }
756 }
757}
758
759void AudioFlinger::PlaybackThread::Track::flush()
760{
761 ALOGV("flush(%d)", mName);
762 sp<ThreadBase> thread = mThread.promote();
763 if (thread != 0) {
764 Mutex::Autolock _l(thread->mLock);
Eric Laurent81784c32012-11-19 14:55:58 -0800765 PlaybackThread *playbackThread = (PlaybackThread *)thread.get();
Eric Laurentbfb1b832013-01-07 09:53:42 -0800766
767 if (isOffloaded()) {
768 // If offloaded we allow flush during any state except terminated
769 // and keep the track active to avoid problems if user is seeking
770 // rapidly and underlying hardware has a significant delay handling
771 // a pause
772 if (isTerminated()) {
773 return;
774 }
775
776 ALOGV("flush: offload flush");
Eric Laurent81784c32012-11-19 14:55:58 -0800777 reset();
Eric Laurentbfb1b832013-01-07 09:53:42 -0800778
779 if (mState == STOPPING_1 || mState == STOPPING_2) {
780 ALOGV("flushed in STOPPING_1 or 2 state, change state to ACTIVE");
781 mState = ACTIVE;
782 }
783
784 if (mState == ACTIVE) {
785 ALOGV("flush called in active state, resetting buffer time out retry count");
786 mRetryCount = PlaybackThread::kMaxTrackRetriesOffload;
787 }
788
789 mResumeToStopping = false;
790 } else {
791 if (mState != STOPPING_1 && mState != STOPPING_2 && mState != STOPPED &&
792 mState != PAUSED && mState != PAUSING && mState != IDLE && mState != FLUSHED) {
793 return;
794 }
795 // No point remaining in PAUSED state after a flush => go to
796 // FLUSHED state
797 mState = FLUSHED;
798 // do not reset the track if it is still in the process of being stopped or paused.
799 // this will be done by prepareTracks_l() when the track is stopped.
800 // prepareTracks_l() will see mState == FLUSHED, then
801 // remove from active track list, reset(), and trigger presentation complete
802 if (playbackThread->mActiveTracks.indexOf(this) < 0) {
803 reset();
804 }
Eric Laurent81784c32012-11-19 14:55:58 -0800805 }
Eric Laurentbfb1b832013-01-07 09:53:42 -0800806 // Prevent flush being lost if the track is flushed and then resumed
807 // before mixer thread can run. This is important when offloading
808 // because the hardware buffer could hold a large amount of audio
809 playbackThread->flushOutput_l();
Eric Laurentede6c3b2013-09-19 14:37:46 -0700810 playbackThread->broadcast_l();
Eric Laurent81784c32012-11-19 14:55:58 -0800811 }
812}
813
814void AudioFlinger::PlaybackThread::Track::reset()
815{
816 // Do not reset twice to avoid discarding data written just after a flush and before
817 // the audioflinger thread detects the track is stopped.
818 if (!mResetDone) {
Eric Laurent81784c32012-11-19 14:55:58 -0800819 // Force underrun condition to avoid false underrun callback until first data is
820 // written to buffer
Glenn Kasten96f60d82013-07-12 10:21:18 -0700821 android_atomic_and(~CBLK_FORCEREADY, &mCblk->mFlags);
Eric Laurent81784c32012-11-19 14:55:58 -0800822 mFillingUpStatus = FS_FILLING;
823 mResetDone = true;
824 if (mState == FLUSHED) {
825 mState = IDLE;
826 }
827 }
828}
829
Eric Laurentbfb1b832013-01-07 09:53:42 -0800830status_t AudioFlinger::PlaybackThread::Track::setParameters(const String8& keyValuePairs)
831{
832 sp<ThreadBase> thread = mThread.promote();
833 if (thread == 0) {
834 ALOGE("thread is dead");
835 return FAILED_TRANSACTION;
836 } else if ((thread->type() == ThreadBase::DIRECT) ||
837 (thread->type() == ThreadBase::OFFLOAD)) {
838 return thread->setParameters(keyValuePairs);
839 } else {
840 return PERMISSION_DENIED;
841 }
842}
843
Glenn Kasten573d80a2013-08-26 09:36:23 -0700844status_t AudioFlinger::PlaybackThread::Track::getTimestamp(AudioTimestamp& timestamp)
845{
Glenn Kastenfe346c72013-08-30 13:28:22 -0700846 // Client should implement this using SSQ; the unpresented frame count in latch is irrelevant
847 if (isFastTrack()) {
848 return INVALID_OPERATION;
849 }
Glenn Kasten573d80a2013-08-26 09:36:23 -0700850 sp<ThreadBase> thread = mThread.promote();
851 if (thread == 0) {
Glenn Kastenfe346c72013-08-30 13:28:22 -0700852 return INVALID_OPERATION;
Glenn Kasten573d80a2013-08-26 09:36:23 -0700853 }
854 Mutex::Autolock _l(thread->mLock);
855 PlaybackThread *playbackThread = (PlaybackThread *)thread.get();
Eric Laurentaccc1472013-09-20 09:36:34 -0700856 if (!isOffloaded()) {
857 if (!playbackThread->mLatchQValid) {
858 return INVALID_OPERATION;
859 }
860 uint32_t unpresentedFrames =
861 ((int64_t) playbackThread->mLatchQ.mUnpresentedFrames * mSampleRate) /
862 playbackThread->mSampleRate;
863 uint32_t framesWritten = mAudioTrackServerProxy->framesReleased();
864 if (framesWritten < unpresentedFrames) {
865 return INVALID_OPERATION;
866 }
867 timestamp.mPosition = framesWritten - unpresentedFrames;
868 timestamp.mTime = playbackThread->mLatchQ.mTimestamp.mTime;
869 return NO_ERROR;
Glenn Kastenbd096fd2013-08-23 13:53:56 -0700870 }
Eric Laurentaccc1472013-09-20 09:36:34 -0700871
872 return playbackThread->getTimestamp_l(timestamp);
Glenn Kasten573d80a2013-08-26 09:36:23 -0700873}
874
Eric Laurent81784c32012-11-19 14:55:58 -0800875status_t AudioFlinger::PlaybackThread::Track::attachAuxEffect(int EffectId)
876{
877 status_t status = DEAD_OBJECT;
878 sp<ThreadBase> thread = mThread.promote();
879 if (thread != 0) {
880 PlaybackThread *playbackThread = (PlaybackThread *)thread.get();
881 sp<AudioFlinger> af = mClient->audioFlinger();
882
883 Mutex::Autolock _l(af->mLock);
884
885 sp<PlaybackThread> srcThread = af->getEffectThread_l(AUDIO_SESSION_OUTPUT_MIX, EffectId);
886
887 if (EffectId != 0 && srcThread != 0 && playbackThread != srcThread.get()) {
888 Mutex::Autolock _dl(playbackThread->mLock);
889 Mutex::Autolock _sl(srcThread->mLock);
890 sp<EffectChain> chain = srcThread->getEffectChain_l(AUDIO_SESSION_OUTPUT_MIX);
891 if (chain == 0) {
892 return INVALID_OPERATION;
893 }
894
895 sp<EffectModule> effect = chain->getEffectFromId_l(EffectId);
896 if (effect == 0) {
897 return INVALID_OPERATION;
898 }
899 srcThread->removeEffect_l(effect);
Eric Laurent5baf2af2013-09-12 17:37:00 -0700900 status = playbackThread->addEffect_l(effect);
901 if (status != NO_ERROR) {
902 srcThread->addEffect_l(effect);
903 return INVALID_OPERATION;
904 }
Eric Laurent81784c32012-11-19 14:55:58 -0800905 // removeEffect_l() has stopped the effect if it was active so it must be restarted
906 if (effect->state() == EffectModule::ACTIVE ||
907 effect->state() == EffectModule::STOPPING) {
908 effect->start();
909 }
910
911 sp<EffectChain> dstChain = effect->chain().promote();
912 if (dstChain == 0) {
913 srcThread->addEffect_l(effect);
914 return INVALID_OPERATION;
915 }
916 AudioSystem::unregisterEffect(effect->id());
917 AudioSystem::registerEffect(&effect->desc(),
918 srcThread->id(),
919 dstChain->strategy(),
920 AUDIO_SESSION_OUTPUT_MIX,
921 effect->id());
Eric Laurentd72b7c02013-10-12 16:17:46 -0700922 AudioSystem::setEffectEnabled(effect->id(), effect->isEnabled());
Eric Laurent81784c32012-11-19 14:55:58 -0800923 }
924 status = playbackThread->attachAuxEffect(this, EffectId);
925 }
926 return status;
927}
928
929void AudioFlinger::PlaybackThread::Track::setAuxBuffer(int EffectId, int32_t *buffer)
930{
931 mAuxEffectId = EffectId;
932 mAuxBuffer = buffer;
933}
934
935bool AudioFlinger::PlaybackThread::Track::presentationComplete(size_t framesWritten,
936 size_t audioHalFrames)
937{
938 // a track is considered presented when the total number of frames written to audio HAL
939 // corresponds to the number of frames written when presentationComplete() is called for the
940 // first time (mPresentationCompleteFrames == 0) plus the buffer filling status at that time.
Eric Laurentbfb1b832013-01-07 09:53:42 -0800941 // For an offloaded track the HAL+h/w delay is variable so a HAL drain() is used
942 // to detect when all frames have been played. In this case framesWritten isn't
943 // useful because it doesn't always reflect whether there is data in the h/w
944 // buffers, particularly if a track has been paused and resumed during draining
945 ALOGV("presentationComplete() mPresentationCompleteFrames %d framesWritten %d",
946 mPresentationCompleteFrames, framesWritten);
Eric Laurent81784c32012-11-19 14:55:58 -0800947 if (mPresentationCompleteFrames == 0) {
948 mPresentationCompleteFrames = framesWritten + audioHalFrames;
949 ALOGV("presentationComplete() reset: mPresentationCompleteFrames %d audioHalFrames %d",
950 mPresentationCompleteFrames, audioHalFrames);
951 }
Eric Laurentbfb1b832013-01-07 09:53:42 -0800952
953 if (framesWritten >= mPresentationCompleteFrames || isOffloaded()) {
Eric Laurent81784c32012-11-19 14:55:58 -0800954 ALOGV("presentationComplete() session %d complete: framesWritten %d",
955 mSessionId, framesWritten);
956 triggerEvents(AudioSystem::SYNC_EVENT_PRESENTATION_COMPLETE);
Eric Laurentbfb1b832013-01-07 09:53:42 -0800957 mAudioTrackServerProxy->setStreamEndDone();
Eric Laurent81784c32012-11-19 14:55:58 -0800958 return true;
959 }
960 return false;
961}
962
963void AudioFlinger::PlaybackThread::Track::triggerEvents(AudioSystem::sync_event_t type)
964{
965 for (int i = 0; i < (int)mSyncEvents.size(); i++) {
966 if (mSyncEvents[i]->type() == type) {
967 mSyncEvents[i]->trigger();
968 mSyncEvents.removeAt(i);
969 i--;
970 }
971 }
972}
973
974// implement VolumeBufferProvider interface
975
976uint32_t AudioFlinger::PlaybackThread::Track::getVolumeLR()
977{
978 // called by FastMixer, so not allowed to take any locks, block, or do I/O including logs
979 ALOG_ASSERT(isFastTrack() && (mCblk != NULL));
Glenn Kasten9f80dd22012-12-18 15:57:32 -0800980 uint32_t vlr = mAudioTrackServerProxy->getVolumeLR();
Eric Laurent81784c32012-11-19 14:55:58 -0800981 uint32_t vl = vlr & 0xFFFF;
982 uint32_t vr = vlr >> 16;
983 // track volumes come from shared memory, so can't be trusted and must be clamped
984 if (vl > MAX_GAIN_INT) {
985 vl = MAX_GAIN_INT;
986 }
987 if (vr > MAX_GAIN_INT) {
988 vr = MAX_GAIN_INT;
989 }
990 // now apply the cached master volume and stream type volume;
991 // this is trusted but lacks any synchronization or barrier so may be stale
992 float v = mCachedVolume;
993 vl *= v;
994 vr *= v;
995 // re-combine into U4.16
996 vlr = (vr << 16) | (vl & 0xFFFF);
997 // FIXME look at mute, pause, and stop flags
998 return vlr;
999}
1000
1001status_t AudioFlinger::PlaybackThread::Track::setSyncEvent(const sp<SyncEvent>& event)
1002{
Eric Laurentbfb1b832013-01-07 09:53:42 -08001003 if (isTerminated() || mState == PAUSED ||
Eric Laurent81784c32012-11-19 14:55:58 -08001004 ((framesReady() == 0) && ((mSharedBuffer != 0) ||
1005 (mState == STOPPED)))) {
1006 ALOGW("Track::setSyncEvent() in invalid state %d on session %d %s mode, framesReady %d ",
1007 mState, mSessionId, (mSharedBuffer != 0) ? "static" : "stream", framesReady());
1008 event->cancel();
1009 return INVALID_OPERATION;
1010 }
1011 (void) TrackBase::setSyncEvent(event);
1012 return NO_ERROR;
1013}
1014
Glenn Kasten5736c352012-12-04 12:12:34 -08001015void AudioFlinger::PlaybackThread::Track::invalidate()
1016{
Glenn Kasten9f80dd22012-12-18 15:57:32 -08001017 // FIXME should use proxy, and needs work
1018 audio_track_cblk_t* cblk = mCblk;
Glenn Kasten96f60d82013-07-12 10:21:18 -07001019 android_atomic_or(CBLK_INVALID, &cblk->mFlags);
Glenn Kasten9f80dd22012-12-18 15:57:32 -08001020 android_atomic_release_store(0x40000000, &cblk->mFutex);
1021 // client is not in server, so FUTEX_WAKE is needed instead of FUTEX_WAKE_PRIVATE
1022 (void) __futex_syscall3(&cblk->mFutex, FUTEX_WAKE, INT_MAX);
Glenn Kasten5736c352012-12-04 12:12:34 -08001023 mIsInvalid = true;
1024}
1025
Eric Laurent59fe0102013-09-27 18:48:26 -07001026void AudioFlinger::PlaybackThread::Track::signal()
1027{
1028 sp<ThreadBase> thread = mThread.promote();
1029 if (thread != 0) {
1030 PlaybackThread *t = (PlaybackThread *)thread.get();
1031 Mutex::Autolock _l(t->mLock);
1032 t->broadcast_l();
1033 }
1034}
1035
Eric Laurent81784c32012-11-19 14:55:58 -08001036// ----------------------------------------------------------------------------
1037
1038sp<AudioFlinger::PlaybackThread::TimedTrack>
1039AudioFlinger::PlaybackThread::TimedTrack::create(
1040 PlaybackThread *thread,
1041 const sp<Client>& client,
1042 audio_stream_type_t streamType,
1043 uint32_t sampleRate,
1044 audio_format_t format,
1045 audio_channel_mask_t channelMask,
1046 size_t frameCount,
1047 const sp<IMemory>& sharedBuffer,
Marco Nelissen9cae2172013-01-14 14:12:05 -08001048 int sessionId,
1049 int uid) {
Eric Laurent81784c32012-11-19 14:55:58 -08001050 if (!client->reserveTimedTrack())
1051 return 0;
1052
1053 return new TimedTrack(
1054 thread, client, streamType, sampleRate, format, channelMask, frameCount,
Marco Nelissen9cae2172013-01-14 14:12:05 -08001055 sharedBuffer, sessionId, uid);
Eric Laurent81784c32012-11-19 14:55:58 -08001056}
1057
1058AudioFlinger::PlaybackThread::TimedTrack::TimedTrack(
1059 PlaybackThread *thread,
1060 const sp<Client>& client,
1061 audio_stream_type_t streamType,
1062 uint32_t sampleRate,
1063 audio_format_t format,
1064 audio_channel_mask_t channelMask,
1065 size_t frameCount,
1066 const sp<IMemory>& sharedBuffer,
Marco Nelissen9cae2172013-01-14 14:12:05 -08001067 int sessionId,
1068 int uid)
Eric Laurent81784c32012-11-19 14:55:58 -08001069 : Track(thread, client, streamType, sampleRate, format, channelMask,
Marco Nelissen9cae2172013-01-14 14:12:05 -08001070 frameCount, sharedBuffer, sessionId, uid, IAudioFlinger::TRACK_TIMED),
Eric Laurent81784c32012-11-19 14:55:58 -08001071 mQueueHeadInFlight(false),
1072 mTrimQueueHeadOnRelease(false),
1073 mFramesPendingInQueue(0),
1074 mTimedSilenceBuffer(NULL),
1075 mTimedSilenceBufferSize(0),
1076 mTimedAudioOutputOnTime(false),
1077 mMediaTimeTransformValid(false)
1078{
1079 LocalClock lc;
1080 mLocalTimeFreq = lc.getLocalFreq();
1081
1082 mLocalTimeToSampleTransform.a_zero = 0;
1083 mLocalTimeToSampleTransform.b_zero = 0;
1084 mLocalTimeToSampleTransform.a_to_b_numer = sampleRate;
1085 mLocalTimeToSampleTransform.a_to_b_denom = mLocalTimeFreq;
1086 LinearTransform::reduce(&mLocalTimeToSampleTransform.a_to_b_numer,
1087 &mLocalTimeToSampleTransform.a_to_b_denom);
1088
1089 mMediaTimeToSampleTransform.a_zero = 0;
1090 mMediaTimeToSampleTransform.b_zero = 0;
1091 mMediaTimeToSampleTransform.a_to_b_numer = sampleRate;
1092 mMediaTimeToSampleTransform.a_to_b_denom = 1000000;
1093 LinearTransform::reduce(&mMediaTimeToSampleTransform.a_to_b_numer,
1094 &mMediaTimeToSampleTransform.a_to_b_denom);
1095}
1096
1097AudioFlinger::PlaybackThread::TimedTrack::~TimedTrack() {
1098 mClient->releaseTimedTrack();
1099 delete [] mTimedSilenceBuffer;
1100}
1101
1102status_t AudioFlinger::PlaybackThread::TimedTrack::allocateTimedBuffer(
1103 size_t size, sp<IMemory>* buffer) {
1104
1105 Mutex::Autolock _l(mTimedBufferQueueLock);
1106
1107 trimTimedBufferQueue_l();
1108
1109 // lazily initialize the shared memory heap for timed buffers
1110 if (mTimedMemoryDealer == NULL) {
1111 const int kTimedBufferHeapSize = 512 << 10;
1112
1113 mTimedMemoryDealer = new MemoryDealer(kTimedBufferHeapSize,
1114 "AudioFlingerTimed");
1115 if (mTimedMemoryDealer == NULL)
1116 return NO_MEMORY;
1117 }
1118
1119 sp<IMemory> newBuffer = mTimedMemoryDealer->allocate(size);
1120 if (newBuffer == NULL) {
1121 newBuffer = mTimedMemoryDealer->allocate(size);
1122 if (newBuffer == NULL)
1123 return NO_MEMORY;
1124 }
1125
1126 *buffer = newBuffer;
1127 return NO_ERROR;
1128}
1129
1130// caller must hold mTimedBufferQueueLock
1131void AudioFlinger::PlaybackThread::TimedTrack::trimTimedBufferQueue_l() {
1132 int64_t mediaTimeNow;
1133 {
1134 Mutex::Autolock mttLock(mMediaTimeTransformLock);
1135 if (!mMediaTimeTransformValid)
1136 return;
1137
1138 int64_t targetTimeNow;
1139 status_t res = (mMediaTimeTransformTarget == TimedAudioTrack::COMMON_TIME)
1140 ? mCCHelper.getCommonTime(&targetTimeNow)
1141 : mCCHelper.getLocalTime(&targetTimeNow);
1142
1143 if (OK != res)
1144 return;
1145
1146 if (!mMediaTimeTransform.doReverseTransform(targetTimeNow,
1147 &mediaTimeNow)) {
1148 return;
1149 }
1150 }
1151
1152 size_t trimEnd;
1153 for (trimEnd = 0; trimEnd < mTimedBufferQueue.size(); trimEnd++) {
1154 int64_t bufEnd;
1155
1156 if ((trimEnd + 1) < mTimedBufferQueue.size()) {
1157 // We have a next buffer. Just use its PTS as the PTS of the frame
1158 // following the last frame in this buffer. If the stream is sparse
1159 // (ie, there are deliberate gaps left in the stream which should be
1160 // filled with silence by the TimedAudioTrack), then this can result
1161 // in one extra buffer being left un-trimmed when it could have
1162 // been. In general, this is not typical, and we would rather
1163 // optimized away the TS calculation below for the more common case
1164 // where PTSes are contiguous.
1165 bufEnd = mTimedBufferQueue[trimEnd + 1].pts();
1166 } else {
1167 // We have no next buffer. Compute the PTS of the frame following
1168 // the last frame in this buffer by computing the duration of of
1169 // this frame in media time units and adding it to the PTS of the
1170 // buffer.
1171 int64_t frameCount = mTimedBufferQueue[trimEnd].buffer()->size()
1172 / mFrameSize;
1173
1174 if (!mMediaTimeToSampleTransform.doReverseTransform(frameCount,
1175 &bufEnd)) {
1176 ALOGE("Failed to convert frame count of %lld to media time"
1177 " duration" " (scale factor %d/%u) in %s",
1178 frameCount,
1179 mMediaTimeToSampleTransform.a_to_b_numer,
1180 mMediaTimeToSampleTransform.a_to_b_denom,
1181 __PRETTY_FUNCTION__);
1182 break;
1183 }
1184 bufEnd += mTimedBufferQueue[trimEnd].pts();
1185 }
1186
1187 if (bufEnd > mediaTimeNow)
1188 break;
1189
1190 // Is the buffer we want to use in the middle of a mix operation right
1191 // now? If so, don't actually trim it. Just wait for the releaseBuffer
1192 // from the mixer which should be coming back shortly.
1193 if (!trimEnd && mQueueHeadInFlight) {
1194 mTrimQueueHeadOnRelease = true;
1195 }
1196 }
1197
1198 size_t trimStart = mTrimQueueHeadOnRelease ? 1 : 0;
1199 if (trimStart < trimEnd) {
1200 // Update the bookkeeping for framesReady()
1201 for (size_t i = trimStart; i < trimEnd; ++i) {
1202 updateFramesPendingAfterTrim_l(mTimedBufferQueue[i], "trim");
1203 }
1204
1205 // Now actually remove the buffers from the queue.
1206 mTimedBufferQueue.removeItemsAt(trimStart, trimEnd);
1207 }
1208}
1209
1210void AudioFlinger::PlaybackThread::TimedTrack::trimTimedBufferQueueHead_l(
1211 const char* logTag) {
1212 ALOG_ASSERT(mTimedBufferQueue.size() > 0,
1213 "%s called (reason \"%s\"), but timed buffer queue has no"
1214 " elements to trim.", __FUNCTION__, logTag);
1215
1216 updateFramesPendingAfterTrim_l(mTimedBufferQueue[0], logTag);
1217 mTimedBufferQueue.removeAt(0);
1218}
1219
1220void AudioFlinger::PlaybackThread::TimedTrack::updateFramesPendingAfterTrim_l(
1221 const TimedBuffer& buf,
1222 const char* logTag) {
1223 uint32_t bufBytes = buf.buffer()->size();
1224 uint32_t consumedAlready = buf.position();
1225
1226 ALOG_ASSERT(consumedAlready <= bufBytes,
1227 "Bad bookkeeping while updating frames pending. Timed buffer is"
1228 " only %u bytes long, but claims to have consumed %u"
1229 " bytes. (update reason: \"%s\")",
1230 bufBytes, consumedAlready, logTag);
1231
1232 uint32_t bufFrames = (bufBytes - consumedAlready) / mFrameSize;
1233 ALOG_ASSERT(mFramesPendingInQueue >= bufFrames,
1234 "Bad bookkeeping while updating frames pending. Should have at"
1235 " least %u queued frames, but we think we have only %u. (update"
1236 " reason: \"%s\")",
1237 bufFrames, mFramesPendingInQueue, logTag);
1238
1239 mFramesPendingInQueue -= bufFrames;
1240}
1241
1242status_t AudioFlinger::PlaybackThread::TimedTrack::queueTimedBuffer(
1243 const sp<IMemory>& buffer, int64_t pts) {
1244
1245 {
1246 Mutex::Autolock mttLock(mMediaTimeTransformLock);
1247 if (!mMediaTimeTransformValid)
1248 return INVALID_OPERATION;
1249 }
1250
1251 Mutex::Autolock _l(mTimedBufferQueueLock);
1252
1253 uint32_t bufFrames = buffer->size() / mFrameSize;
1254 mFramesPendingInQueue += bufFrames;
1255 mTimedBufferQueue.add(TimedBuffer(buffer, pts));
1256
1257 return NO_ERROR;
1258}
1259
1260status_t AudioFlinger::PlaybackThread::TimedTrack::setMediaTimeTransform(
1261 const LinearTransform& xform, TimedAudioTrack::TargetTimeline target) {
1262
1263 ALOGVV("setMediaTimeTransform az=%lld bz=%lld n=%d d=%u tgt=%d",
1264 xform.a_zero, xform.b_zero, xform.a_to_b_numer, xform.a_to_b_denom,
1265 target);
1266
1267 if (!(target == TimedAudioTrack::LOCAL_TIME ||
1268 target == TimedAudioTrack::COMMON_TIME)) {
1269 return BAD_VALUE;
1270 }
1271
1272 Mutex::Autolock lock(mMediaTimeTransformLock);
1273 mMediaTimeTransform = xform;
1274 mMediaTimeTransformTarget = target;
1275 mMediaTimeTransformValid = true;
1276
1277 return NO_ERROR;
1278}
1279
1280#define min(a, b) ((a) < (b) ? (a) : (b))
1281
1282// implementation of getNextBuffer for tracks whose buffers have timestamps
1283status_t AudioFlinger::PlaybackThread::TimedTrack::getNextBuffer(
1284 AudioBufferProvider::Buffer* buffer, int64_t pts)
1285{
1286 if (pts == AudioBufferProvider::kInvalidPTS) {
1287 buffer->raw = NULL;
1288 buffer->frameCount = 0;
1289 mTimedAudioOutputOnTime = false;
1290 return INVALID_OPERATION;
1291 }
1292
1293 Mutex::Autolock _l(mTimedBufferQueueLock);
1294
1295 ALOG_ASSERT(!mQueueHeadInFlight,
1296 "getNextBuffer called without releaseBuffer!");
1297
1298 while (true) {
1299
1300 // if we have no timed buffers, then fail
1301 if (mTimedBufferQueue.isEmpty()) {
1302 buffer->raw = NULL;
1303 buffer->frameCount = 0;
1304 return NOT_ENOUGH_DATA;
1305 }
1306
1307 TimedBuffer& head = mTimedBufferQueue.editItemAt(0);
1308
1309 // calculate the PTS of the head of the timed buffer queue expressed in
1310 // local time
1311 int64_t headLocalPTS;
1312 {
1313 Mutex::Autolock mttLock(mMediaTimeTransformLock);
1314
1315 ALOG_ASSERT(mMediaTimeTransformValid, "media time transform invalid");
1316
1317 if (mMediaTimeTransform.a_to_b_denom == 0) {
1318 // the transform represents a pause, so yield silence
1319 timedYieldSilence_l(buffer->frameCount, buffer);
1320 return NO_ERROR;
1321 }
1322
1323 int64_t transformedPTS;
1324 if (!mMediaTimeTransform.doForwardTransform(head.pts(),
1325 &transformedPTS)) {
1326 // the transform failed. this shouldn't happen, but if it does
1327 // then just drop this buffer
1328 ALOGW("timedGetNextBuffer transform failed");
1329 buffer->raw = NULL;
1330 buffer->frameCount = 0;
1331 trimTimedBufferQueueHead_l("getNextBuffer; no transform");
1332 return NO_ERROR;
1333 }
1334
1335 if (mMediaTimeTransformTarget == TimedAudioTrack::COMMON_TIME) {
1336 if (OK != mCCHelper.commonTimeToLocalTime(transformedPTS,
1337 &headLocalPTS)) {
1338 buffer->raw = NULL;
1339 buffer->frameCount = 0;
1340 return INVALID_OPERATION;
1341 }
1342 } else {
1343 headLocalPTS = transformedPTS;
1344 }
1345 }
1346
Glenn Kasten9fdcb0a2013-06-26 16:11:36 -07001347 uint32_t sr = sampleRate();
1348
Eric Laurent81784c32012-11-19 14:55:58 -08001349 // adjust the head buffer's PTS to reflect the portion of the head buffer
1350 // that has already been consumed
1351 int64_t effectivePTS = headLocalPTS +
Glenn Kasten9fdcb0a2013-06-26 16:11:36 -07001352 ((head.position() / mFrameSize) * mLocalTimeFreq / sr);
Eric Laurent81784c32012-11-19 14:55:58 -08001353
1354 // Calculate the delta in samples between the head of the input buffer
1355 // queue and the start of the next output buffer that will be written.
1356 // If the transformation fails because of over or underflow, it means
1357 // that the sample's position in the output stream is so far out of
1358 // whack that it should just be dropped.
1359 int64_t sampleDelta;
1360 if (llabs(effectivePTS - pts) >= (static_cast<int64_t>(1) << 31)) {
1361 ALOGV("*** head buffer is too far from PTS: dropped buffer");
1362 trimTimedBufferQueueHead_l("getNextBuffer, buf pts too far from"
1363 " mix");
1364 continue;
1365 }
1366 if (!mLocalTimeToSampleTransform.doForwardTransform(
1367 (effectivePTS - pts) << 32, &sampleDelta)) {
1368 ALOGV("*** too late during sample rate transform: dropped buffer");
1369 trimTimedBufferQueueHead_l("getNextBuffer, bad local to sample");
1370 continue;
1371 }
1372
1373 ALOGVV("*** getNextBuffer head.pts=%lld head.pos=%d pts=%lld"
1374 " sampleDelta=[%d.%08x]",
1375 head.pts(), head.position(), pts,
1376 static_cast<int32_t>((sampleDelta >= 0 ? 0 : 1)
1377 + (sampleDelta >> 32)),
1378 static_cast<uint32_t>(sampleDelta & 0xFFFFFFFF));
1379
1380 // if the delta between the ideal placement for the next input sample and
1381 // the current output position is within this threshold, then we will
1382 // concatenate the next input samples to the previous output
1383 const int64_t kSampleContinuityThreshold =
Glenn Kasten9fdcb0a2013-06-26 16:11:36 -07001384 (static_cast<int64_t>(sr) << 32) / 250;
Eric Laurent81784c32012-11-19 14:55:58 -08001385
1386 // if this is the first buffer of audio that we're emitting from this track
1387 // then it should be almost exactly on time.
1388 const int64_t kSampleStartupThreshold = 1LL << 32;
1389
1390 if ((mTimedAudioOutputOnTime && llabs(sampleDelta) <= kSampleContinuityThreshold) ||
1391 (!mTimedAudioOutputOnTime && llabs(sampleDelta) <= kSampleStartupThreshold)) {
1392 // the next input is close enough to being on time, so concatenate it
1393 // with the last output
1394 timedYieldSamples_l(buffer);
1395
1396 ALOGVV("*** on time: head.pos=%d frameCount=%u",
1397 head.position(), buffer->frameCount);
1398 return NO_ERROR;
1399 }
1400
1401 // Looks like our output is not on time. Reset our on timed status.
1402 // Next time we mix samples from our input queue, then should be within
1403 // the StartupThreshold.
1404 mTimedAudioOutputOnTime = false;
1405 if (sampleDelta > 0) {
1406 // the gap between the current output position and the proper start of
1407 // the next input sample is too big, so fill it with silence
1408 uint32_t framesUntilNextInput = (sampleDelta + 0x80000000) >> 32;
1409
1410 timedYieldSilence_l(framesUntilNextInput, buffer);
1411 ALOGV("*** silence: frameCount=%u", buffer->frameCount);
1412 return NO_ERROR;
1413 } else {
1414 // the next input sample is late
1415 uint32_t lateFrames = static_cast<uint32_t>(-((sampleDelta + 0x80000000) >> 32));
1416 size_t onTimeSamplePosition =
1417 head.position() + lateFrames * mFrameSize;
1418
1419 if (onTimeSamplePosition > head.buffer()->size()) {
1420 // all the remaining samples in the head are too late, so
1421 // drop it and move on
1422 ALOGV("*** too late: dropped buffer");
1423 trimTimedBufferQueueHead_l("getNextBuffer, dropped late buffer");
1424 continue;
1425 } else {
1426 // skip over the late samples
1427 head.setPosition(onTimeSamplePosition);
1428
1429 // yield the available samples
1430 timedYieldSamples_l(buffer);
1431
1432 ALOGV("*** late: head.pos=%d frameCount=%u", head.position(), buffer->frameCount);
1433 return NO_ERROR;
1434 }
1435 }
1436 }
1437}
1438
1439// Yield samples from the timed buffer queue head up to the given output
1440// buffer's capacity.
1441//
1442// Caller must hold mTimedBufferQueueLock
1443void AudioFlinger::PlaybackThread::TimedTrack::timedYieldSamples_l(
1444 AudioBufferProvider::Buffer* buffer) {
1445
1446 const TimedBuffer& head = mTimedBufferQueue[0];
1447
1448 buffer->raw = (static_cast<uint8_t*>(head.buffer()->pointer()) +
1449 head.position());
1450
1451 uint32_t framesLeftInHead = ((head.buffer()->size() - head.position()) /
1452 mFrameSize);
1453 size_t framesRequested = buffer->frameCount;
1454 buffer->frameCount = min(framesLeftInHead, framesRequested);
1455
1456 mQueueHeadInFlight = true;
1457 mTimedAudioOutputOnTime = true;
1458}
1459
1460// Yield samples of silence up to the given output buffer's capacity
1461//
1462// Caller must hold mTimedBufferQueueLock
1463void AudioFlinger::PlaybackThread::TimedTrack::timedYieldSilence_l(
1464 uint32_t numFrames, AudioBufferProvider::Buffer* buffer) {
1465
1466 // lazily allocate a buffer filled with silence
1467 if (mTimedSilenceBufferSize < numFrames * mFrameSize) {
1468 delete [] mTimedSilenceBuffer;
1469 mTimedSilenceBufferSize = numFrames * mFrameSize;
1470 mTimedSilenceBuffer = new uint8_t[mTimedSilenceBufferSize];
1471 memset(mTimedSilenceBuffer, 0, mTimedSilenceBufferSize);
1472 }
1473
1474 buffer->raw = mTimedSilenceBuffer;
1475 size_t framesRequested = buffer->frameCount;
1476 buffer->frameCount = min(numFrames, framesRequested);
1477
1478 mTimedAudioOutputOnTime = false;
1479}
1480
1481// AudioBufferProvider interface
1482void AudioFlinger::PlaybackThread::TimedTrack::releaseBuffer(
1483 AudioBufferProvider::Buffer* buffer) {
1484
1485 Mutex::Autolock _l(mTimedBufferQueueLock);
1486
1487 // If the buffer which was just released is part of the buffer at the head
1488 // of the queue, be sure to update the amt of the buffer which has been
1489 // consumed. If the buffer being returned is not part of the head of the
1490 // queue, its either because the buffer is part of the silence buffer, or
1491 // because the head of the timed queue was trimmed after the mixer called
1492 // getNextBuffer but before the mixer called releaseBuffer.
1493 if (buffer->raw == mTimedSilenceBuffer) {
1494 ALOG_ASSERT(!mQueueHeadInFlight,
1495 "Queue head in flight during release of silence buffer!");
1496 goto done;
1497 }
1498
1499 ALOG_ASSERT(mQueueHeadInFlight,
1500 "TimedTrack::releaseBuffer of non-silence buffer, but no queue"
1501 " head in flight.");
1502
1503 if (mTimedBufferQueue.size()) {
1504 TimedBuffer& head = mTimedBufferQueue.editItemAt(0);
1505
1506 void* start = head.buffer()->pointer();
1507 void* end = reinterpret_cast<void*>(
1508 reinterpret_cast<uint8_t*>(head.buffer()->pointer())
1509 + head.buffer()->size());
1510
1511 ALOG_ASSERT((buffer->raw >= start) && (buffer->raw < end),
1512 "released buffer not within the head of the timed buffer"
1513 " queue; qHead = [%p, %p], released buffer = %p",
1514 start, end, buffer->raw);
1515
1516 head.setPosition(head.position() +
1517 (buffer->frameCount * mFrameSize));
1518 mQueueHeadInFlight = false;
1519
1520 ALOG_ASSERT(mFramesPendingInQueue >= buffer->frameCount,
1521 "Bad bookkeeping during releaseBuffer! Should have at"
1522 " least %u queued frames, but we think we have only %u",
1523 buffer->frameCount, mFramesPendingInQueue);
1524
1525 mFramesPendingInQueue -= buffer->frameCount;
1526
1527 if ((static_cast<size_t>(head.position()) >= head.buffer()->size())
1528 || mTrimQueueHeadOnRelease) {
1529 trimTimedBufferQueueHead_l("releaseBuffer");
1530 mTrimQueueHeadOnRelease = false;
1531 }
1532 } else {
1533 LOG_FATAL("TimedTrack::releaseBuffer of non-silence buffer with no"
1534 " buffers in the timed buffer queue");
1535 }
1536
1537done:
1538 buffer->raw = 0;
1539 buffer->frameCount = 0;
1540}
1541
1542size_t AudioFlinger::PlaybackThread::TimedTrack::framesReady() const {
1543 Mutex::Autolock _l(mTimedBufferQueueLock);
1544 return mFramesPendingInQueue;
1545}
1546
1547AudioFlinger::PlaybackThread::TimedTrack::TimedBuffer::TimedBuffer()
1548 : mPTS(0), mPosition(0) {}
1549
1550AudioFlinger::PlaybackThread::TimedTrack::TimedBuffer::TimedBuffer(
1551 const sp<IMemory>& buffer, int64_t pts)
1552 : mBuffer(buffer), mPTS(pts), mPosition(0) {}
1553
1554
1555// ----------------------------------------------------------------------------
1556
1557AudioFlinger::PlaybackThread::OutputTrack::OutputTrack(
1558 PlaybackThread *playbackThread,
1559 DuplicatingThread *sourceThread,
1560 uint32_t sampleRate,
1561 audio_format_t format,
1562 audio_channel_mask_t channelMask,
Marco Nelissen9cae2172013-01-14 14:12:05 -08001563 size_t frameCount,
1564 int uid)
Eric Laurent81784c32012-11-19 14:55:58 -08001565 : Track(playbackThread, NULL, AUDIO_STREAM_CNT, sampleRate, format, channelMask, frameCount,
Marco Nelissen9cae2172013-01-14 14:12:05 -08001566 NULL, 0, uid, IAudioFlinger::TRACK_DEFAULT),
Glenn Kastene3aa6592012-12-04 12:22:46 -08001567 mActive(false), mSourceThread(sourceThread), mClientProxy(NULL)
Eric Laurent81784c32012-11-19 14:55:58 -08001568{
1569
1570 if (mCblk != NULL) {
Eric Laurent81784c32012-11-19 14:55:58 -08001571 mOutBuffer.frameCount = 0;
1572 playbackThread->mTracks.add(this);
Glenn Kastene3aa6592012-12-04 12:22:46 -08001573 ALOGV("OutputTrack constructor mCblk %p, mBuffer %p, "
Glenn Kasten35cc4f32013-07-25 14:21:35 -07001574 "mCblk->frameCount_ %u, mChannelMask 0x%08x",
Glenn Kastene3aa6592012-12-04 12:22:46 -08001575 mCblk, mBuffer,
Glenn Kasten35cc4f32013-07-25 14:21:35 -07001576 mCblk->frameCount_, mChannelMask);
Glenn Kastene3aa6592012-12-04 12:22:46 -08001577 // since client and server are in the same process,
1578 // the buffer has the same virtual address on both sides
1579 mClientProxy = new AudioTrackClientProxy(mCblk, mBuffer, mFrameCount, mFrameSize);
Eric Laurent8d2d4932013-04-25 12:56:18 -07001580 mClientProxy->setVolumeLR((uint32_t(uint16_t(0x1000)) << 16) | uint16_t(0x1000));
1581 mClientProxy->setSendLevel(0.0);
1582 mClientProxy->setSampleRate(sampleRate);
Glenn Kasten9f80dd22012-12-18 15:57:32 -08001583 mClientProxy = new AudioTrackClientProxy(mCblk, mBuffer, mFrameCount, mFrameSize,
1584 true /*clientInServer*/);
Eric Laurent81784c32012-11-19 14:55:58 -08001585 } else {
1586 ALOGW("Error creating output track on thread %p", playbackThread);
1587 }
1588}
1589
1590AudioFlinger::PlaybackThread::OutputTrack::~OutputTrack()
1591{
1592 clearBufferQueue();
Glenn Kastene3aa6592012-12-04 12:22:46 -08001593 delete mClientProxy;
1594 // superclass destructor will now delete the server proxy and shared memory both refer to
Eric Laurent81784c32012-11-19 14:55:58 -08001595}
1596
1597status_t AudioFlinger::PlaybackThread::OutputTrack::start(AudioSystem::sync_event_t event,
1598 int triggerSession)
1599{
1600 status_t status = Track::start(event, triggerSession);
1601 if (status != NO_ERROR) {
1602 return status;
1603 }
1604
1605 mActive = true;
1606 mRetryCount = 127;
1607 return status;
1608}
1609
1610void AudioFlinger::PlaybackThread::OutputTrack::stop()
1611{
1612 Track::stop();
1613 clearBufferQueue();
1614 mOutBuffer.frameCount = 0;
1615 mActive = false;
1616}
1617
1618bool AudioFlinger::PlaybackThread::OutputTrack::write(int16_t* data, uint32_t frames)
1619{
1620 Buffer *pInBuffer;
1621 Buffer inBuffer;
1622 uint32_t channelCount = mChannelCount;
1623 bool outputBufferFull = false;
1624 inBuffer.frameCount = frames;
1625 inBuffer.i16 = data;
1626
1627 uint32_t waitTimeLeftMs = mSourceThread->waitTimeMs();
1628
1629 if (!mActive && frames != 0) {
1630 start();
1631 sp<ThreadBase> thread = mThread.promote();
1632 if (thread != 0) {
1633 MixerThread *mixerThread = (MixerThread *)thread.get();
1634 if (mFrameCount > frames) {
1635 if (mBufferQueue.size() < kMaxOverFlowBuffers) {
1636 uint32_t startFrames = (mFrameCount - frames);
1637 pInBuffer = new Buffer;
1638 pInBuffer->mBuffer = new int16_t[startFrames * channelCount];
1639 pInBuffer->frameCount = startFrames;
1640 pInBuffer->i16 = pInBuffer->mBuffer;
1641 memset(pInBuffer->raw, 0, startFrames * channelCount * sizeof(int16_t));
1642 mBufferQueue.add(pInBuffer);
1643 } else {
Glenn Kasten7c027242012-12-26 14:43:16 -08001644 ALOGW("OutputTrack::write() %p no more buffers in queue", this);
Eric Laurent81784c32012-11-19 14:55:58 -08001645 }
1646 }
1647 }
1648 }
1649
1650 while (waitTimeLeftMs) {
1651 // First write pending buffers, then new data
1652 if (mBufferQueue.size()) {
1653 pInBuffer = mBufferQueue.itemAt(0);
1654 } else {
1655 pInBuffer = &inBuffer;
1656 }
1657
1658 if (pInBuffer->frameCount == 0) {
1659 break;
1660 }
1661
1662 if (mOutBuffer.frameCount == 0) {
1663 mOutBuffer.frameCount = pInBuffer->frameCount;
1664 nsecs_t startTime = systemTime();
Glenn Kasten9f80dd22012-12-18 15:57:32 -08001665 status_t status = obtainBuffer(&mOutBuffer, waitTimeLeftMs);
1666 if (status != NO_ERROR) {
1667 ALOGV("OutputTrack::write() %p thread %p no more output buffers; status %d", this,
1668 mThread.unsafe_get(), status);
Eric Laurent81784c32012-11-19 14:55:58 -08001669 outputBufferFull = true;
1670 break;
1671 }
1672 uint32_t waitTimeMs = (uint32_t)ns2ms(systemTime() - startTime);
1673 if (waitTimeLeftMs >= waitTimeMs) {
1674 waitTimeLeftMs -= waitTimeMs;
1675 } else {
1676 waitTimeLeftMs = 0;
1677 }
1678 }
1679
1680 uint32_t outFrames = pInBuffer->frameCount > mOutBuffer.frameCount ? mOutBuffer.frameCount :
1681 pInBuffer->frameCount;
1682 memcpy(mOutBuffer.raw, pInBuffer->raw, outFrames * channelCount * sizeof(int16_t));
Glenn Kasten9f80dd22012-12-18 15:57:32 -08001683 Proxy::Buffer buf;
1684 buf.mFrameCount = outFrames;
1685 buf.mRaw = NULL;
1686 mClientProxy->releaseBuffer(&buf);
Eric Laurent81784c32012-11-19 14:55:58 -08001687 pInBuffer->frameCount -= outFrames;
1688 pInBuffer->i16 += outFrames * channelCount;
1689 mOutBuffer.frameCount -= outFrames;
1690 mOutBuffer.i16 += outFrames * channelCount;
1691
1692 if (pInBuffer->frameCount == 0) {
1693 if (mBufferQueue.size()) {
1694 mBufferQueue.removeAt(0);
1695 delete [] pInBuffer->mBuffer;
1696 delete pInBuffer;
1697 ALOGV("OutputTrack::write() %p thread %p released overflow buffer %d", this,
1698 mThread.unsafe_get(), mBufferQueue.size());
1699 } else {
1700 break;
1701 }
1702 }
1703 }
1704
1705 // If we could not write all frames, allocate a buffer and queue it for next time.
1706 if (inBuffer.frameCount) {
1707 sp<ThreadBase> thread = mThread.promote();
1708 if (thread != 0 && !thread->standby()) {
1709 if (mBufferQueue.size() < kMaxOverFlowBuffers) {
1710 pInBuffer = new Buffer;
1711 pInBuffer->mBuffer = new int16_t[inBuffer.frameCount * channelCount];
1712 pInBuffer->frameCount = inBuffer.frameCount;
1713 pInBuffer->i16 = pInBuffer->mBuffer;
1714 memcpy(pInBuffer->raw, inBuffer.raw, inBuffer.frameCount * channelCount *
1715 sizeof(int16_t));
1716 mBufferQueue.add(pInBuffer);
1717 ALOGV("OutputTrack::write() %p thread %p adding overflow buffer %d", this,
1718 mThread.unsafe_get(), mBufferQueue.size());
1719 } else {
1720 ALOGW("OutputTrack::write() %p thread %p no more overflow buffers",
1721 mThread.unsafe_get(), this);
1722 }
1723 }
1724 }
1725
1726 // Calling write() with a 0 length buffer, means that no more data will be written:
1727 // If no more buffers are pending, fill output track buffer to make sure it is started
1728 // by output mixer.
1729 if (frames == 0 && mBufferQueue.size() == 0) {
Glenn Kasten9f80dd22012-12-18 15:57:32 -08001730 // FIXME borken, replace by getting framesReady() from proxy
1731 size_t user = 0; // was mCblk->user
1732 if (user < mFrameCount) {
1733 frames = mFrameCount - user;
Eric Laurent81784c32012-11-19 14:55:58 -08001734 pInBuffer = new Buffer;
1735 pInBuffer->mBuffer = new int16_t[frames * channelCount];
1736 pInBuffer->frameCount = frames;
1737 pInBuffer->i16 = pInBuffer->mBuffer;
1738 memset(pInBuffer->raw, 0, frames * channelCount * sizeof(int16_t));
1739 mBufferQueue.add(pInBuffer);
1740 } else if (mActive) {
1741 stop();
1742 }
1743 }
1744
1745 return outputBufferFull;
1746}
1747
1748status_t AudioFlinger::PlaybackThread::OutputTrack::obtainBuffer(
1749 AudioBufferProvider::Buffer* buffer, uint32_t waitTimeMs)
1750{
Glenn Kasten9f80dd22012-12-18 15:57:32 -08001751 ClientProxy::Buffer buf;
1752 buf.mFrameCount = buffer->frameCount;
1753 struct timespec timeout;
1754 timeout.tv_sec = waitTimeMs / 1000;
1755 timeout.tv_nsec = (int) (waitTimeMs % 1000) * 1000000;
1756 status_t status = mClientProxy->obtainBuffer(&buf, &timeout);
1757 buffer->frameCount = buf.mFrameCount;
1758 buffer->raw = buf.mRaw;
1759 return status;
Eric Laurent81784c32012-11-19 14:55:58 -08001760}
1761
Eric Laurent81784c32012-11-19 14:55:58 -08001762void AudioFlinger::PlaybackThread::OutputTrack::clearBufferQueue()
1763{
1764 size_t size = mBufferQueue.size();
1765
1766 for (size_t i = 0; i < size; i++) {
1767 Buffer *pBuffer = mBufferQueue.itemAt(i);
1768 delete [] pBuffer->mBuffer;
1769 delete pBuffer;
1770 }
1771 mBufferQueue.clear();
1772}
1773
1774
1775// ----------------------------------------------------------------------------
1776// Record
1777// ----------------------------------------------------------------------------
1778
1779AudioFlinger::RecordHandle::RecordHandle(
1780 const sp<AudioFlinger::RecordThread::RecordTrack>& recordTrack)
1781 : BnAudioRecord(),
1782 mRecordTrack(recordTrack)
1783{
1784}
1785
1786AudioFlinger::RecordHandle::~RecordHandle() {
1787 stop_nonvirtual();
1788 mRecordTrack->destroy();
1789}
1790
1791sp<IMemory> AudioFlinger::RecordHandle::getCblk() const {
1792 return mRecordTrack->getCblk();
1793}
1794
1795status_t AudioFlinger::RecordHandle::start(int /*AudioSystem::sync_event_t*/ event,
1796 int triggerSession) {
1797 ALOGV("RecordHandle::start()");
1798 return mRecordTrack->start((AudioSystem::sync_event_t)event, triggerSession);
1799}
1800
1801void AudioFlinger::RecordHandle::stop() {
1802 stop_nonvirtual();
1803}
1804
1805void AudioFlinger::RecordHandle::stop_nonvirtual() {
1806 ALOGV("RecordHandle::stop()");
1807 mRecordTrack->stop();
1808}
1809
1810status_t AudioFlinger::RecordHandle::onTransact(
1811 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
1812{
1813 return BnAudioRecord::onTransact(code, data, reply, flags);
1814}
1815
1816// ----------------------------------------------------------------------------
1817
1818// RecordTrack constructor must be called with AudioFlinger::mLock held
1819AudioFlinger::RecordThread::RecordTrack::RecordTrack(
1820 RecordThread *thread,
1821 const sp<Client>& client,
1822 uint32_t sampleRate,
1823 audio_format_t format,
1824 audio_channel_mask_t channelMask,
1825 size_t frameCount,
Ethan Chen8d420ed2013-11-14 00:40:54 -08001826#ifdef QCOM_HARDWARE
Alok Kediya601e9b52013-09-27 11:55:10 +05301827 uint32_t flags,
Ethan Chen8d420ed2013-11-14 00:40:54 -08001828#endif
Marco Nelissen9cae2172013-01-14 14:12:05 -08001829 int sessionId,
1830 int uid)
Ethan Chen8d420ed2013-11-14 00:40:54 -08001831#ifdef QCOM_HARDWARE
Alok Kediya601e9b52013-09-27 11:55:10 +05301832 : TrackBase(thread, client, sampleRate, format, channelMask, frameCount,
Ricardo Cerqueira574d7be2013-12-06 02:42:19 +00001833 flags, 0 /*sharedBuffer*/, sessionId, uid, false /*isOut*/),
Ethan Chen8d420ed2013-11-14 00:40:54 -08001834#else
1835 : TrackBase(thread, client, sampleRate, format,
Marco Nelissen9cae2172013-01-14 14:12:05 -08001836 channelMask, frameCount, 0 /*sharedBuffer*/, sessionId, uid, false /*isOut*/),
Ethan Chen8d420ed2013-11-14 00:40:54 -08001837#endif
Eric Laurent81784c32012-11-19 14:55:58 -08001838 mOverflow(false)
1839{
Glenn Kasten35cc4f32013-07-25 14:21:35 -07001840 ALOGV("RecordTrack constructor");
Ethan Chen8d420ed2013-11-14 00:40:54 -08001841#ifdef QCOM_HARDWARE
Alok Kediya601e9b52013-09-27 11:55:10 +05301842 mFlags = flags;
Ethan Chen8d420ed2013-11-14 00:40:54 -08001843#endif
Glenn Kasten9f80dd22012-12-18 15:57:32 -08001844 if (mCblk != NULL) {
1845 mAudioRecordServerProxy = new AudioRecordServerProxy(mCblk, mBuffer, frameCount,
1846 mFrameSize);
1847 mServerProxy = mAudioRecordServerProxy;
1848 }
Eric Laurent81784c32012-11-19 14:55:58 -08001849}
1850
1851AudioFlinger::RecordThread::RecordTrack::~RecordTrack()
1852{
1853 ALOGV("%s", __func__);
1854}
1855
1856// AudioBufferProvider interface
1857status_t AudioFlinger::RecordThread::RecordTrack::getNextBuffer(AudioBufferProvider::Buffer* buffer,
1858 int64_t pts)
1859{
Glenn Kasten9f80dd22012-12-18 15:57:32 -08001860 ServerProxy::Buffer buf;
1861 buf.mFrameCount = buffer->frameCount;
1862 status_t status = mServerProxy->obtainBuffer(&buf);
1863 buffer->frameCount = buf.mFrameCount;
1864 buffer->raw = buf.mRaw;
1865 if (buf.mFrameCount == 0) {
1866 // FIXME also wake futex so that overrun is noticed more quickly
Glenn Kasten96f60d82013-07-12 10:21:18 -07001867 (void) android_atomic_or(CBLK_OVERRUN, &mCblk->mFlags);
Eric Laurent81784c32012-11-19 14:55:58 -08001868 }
Glenn Kasten9f80dd22012-12-18 15:57:32 -08001869 return status;
Eric Laurent81784c32012-11-19 14:55:58 -08001870}
1871
1872status_t AudioFlinger::RecordThread::RecordTrack::start(AudioSystem::sync_event_t event,
1873 int triggerSession)
1874{
1875 sp<ThreadBase> thread = mThread.promote();
1876 if (thread != 0) {
1877 RecordThread *recordThread = (RecordThread *)thread.get();
1878 return recordThread->start(this, event, triggerSession);
1879 } else {
1880 return BAD_VALUE;
1881 }
1882}
1883
1884void AudioFlinger::RecordThread::RecordTrack::stop()
1885{
1886 sp<ThreadBase> thread = mThread.promote();
1887 if (thread != 0) {
1888 RecordThread *recordThread = (RecordThread *)thread.get();
Glenn Kastena8356f62013-07-25 14:37:52 -07001889 if (recordThread->stop(this)) {
Eric Laurent81784c32012-11-19 14:55:58 -08001890 AudioSystem::stopInput(recordThread->id());
1891 }
1892 }
1893}
1894
1895void AudioFlinger::RecordThread::RecordTrack::destroy()
1896{
1897 // see comments at AudioFlinger::PlaybackThread::Track::destroy()
1898 sp<RecordTrack> keep(this);
1899 {
1900 sp<ThreadBase> thread = mThread.promote();
1901 if (thread != 0) {
1902 if (mState == ACTIVE || mState == RESUMING) {
1903 AudioSystem::stopInput(thread->id());
1904 }
1905 AudioSystem::releaseInput(thread->id());
1906 Mutex::Autolock _l(thread->mLock);
1907 RecordThread *recordThread = (RecordThread *) thread.get();
1908 recordThread->destroyTrack_l(this);
1909 }
1910 }
1911}
1912
Eric Laurent9a54bc22013-09-09 09:08:44 -07001913void AudioFlinger::RecordThread::RecordTrack::invalidate()
1914{
1915 // FIXME should use proxy, and needs work
1916 audio_track_cblk_t* cblk = mCblk;
1917 android_atomic_or(CBLK_INVALID, &cblk->mFlags);
1918 android_atomic_release_store(0x40000000, &cblk->mFutex);
1919 // client is not in server, so FUTEX_WAKE is needed instead of FUTEX_WAKE_PRIVATE
1920 (void) __futex_syscall3(&cblk->mFutex, FUTEX_WAKE, INT_MAX);
1921}
1922
Eric Laurent81784c32012-11-19 14:55:58 -08001923
1924/*static*/ void AudioFlinger::RecordThread::RecordTrack::appendDumpHeader(String8& result)
1925{
Glenn Kastenbd4c4fb2013-07-25 14:21:14 -07001926 result.append("Client Fmt Chn mask Session S Server fCount\n");
Eric Laurent81784c32012-11-19 14:55:58 -08001927}
1928
1929void AudioFlinger::RecordThread::RecordTrack::dump(char* buffer, size_t size)
1930{
Glenn Kastenbd4c4fb2013-07-25 14:21:14 -07001931 snprintf(buffer, size, "%6u %3u %08X %7u %1d %08X %6u\n",
Eric Laurent81784c32012-11-19 14:55:58 -08001932 (mClient == 0) ? getpid_cached : mClient->pid(),
1933 mFormat,
1934 mChannelMask,
1935 mSessionId,
Eric Laurent81784c32012-11-19 14:55:58 -08001936 mState,
Glenn Kastenf20e1d82013-07-12 09:45:18 -07001937 mCblk->mServer,
Eric Laurent81784c32012-11-19 14:55:58 -08001938 mFrameCount);
1939}
1940
Eric Laurent81784c32012-11-19 14:55:58 -08001941}; // namespace android