181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent/*
281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent**
381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent** Copyright 2012, The Android Open Source Project
481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent**
581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent** Licensed under the Apache License, Version 2.0 (the "License");
681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent** you may not use this file except in compliance with the License.
781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent** You may obtain a copy of the License at
881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent**
981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent**     http://www.apache.org/licenses/LICENSE-2.0
1081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent**
1181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent** Unless required by applicable law or agreed to in writing, software
1281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent** distributed under the License is distributed on an "AS IS" BASIS,
1381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent** See the License for the specific language governing permissions and
1581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent** limitations under the License.
1681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent*/
1781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
1881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
1981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent#define LOG_TAG "AudioFlinger"
2081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent//#define LOG_NDEBUG 0
2181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
22153b9fe667e6e78e0218ff0159353097428c7657Glenn Kasten#include "Configuration.h"
2381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent#include <math.h>
24ee499291404a192b059f2e04c5afc65aa6cdd74cElliott Hughes#include <sys/syscall.h>
2581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent#include <utils/Log.h>
2681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
2781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent#include <private/media/AudioTrackShared.h>
2881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
2981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent#include <common_time/cc_helper.h>
3081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent#include <common_time/local_clock.h>
3181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
3281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent#include "AudioMixer.h"
3381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent#include "AudioFlinger.h"
3481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent#include "ServiceUtilities.h"
3581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
36da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten#include <media/nbaio/Pipe.h>
37da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten#include <media/nbaio/PipeReader.h>
38c56f3426099a3cf2d07ccff8886050c7fbce140fGlenn Kasten#include <audio_utils/minifloat.h>
39da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten
4081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// ----------------------------------------------------------------------------
4181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
4281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// Note: the following macro is used for extremely verbose logging message.  In
4381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// order to run with ALOG_ASSERT turned on, we need to have LOG_NDEBUG set to
4481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// 0; but one side effect of this is to turn all LOGV's as well.  Some messages
4581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// are so verbose that we want to suppress them even when we have ALOG_ASSERT
4681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// turned on.  Do not uncomment the #def below unless you really know what you
4781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// are doing and want to see all of the extremely verbose messages.
4881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent//#define VERY_VERY_VERBOSE_LOGGING
4981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent#ifdef VERY_VERY_VERBOSE_LOGGING
5081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent#define ALOGVV ALOGV
5181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent#else
5281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent#define ALOGVV(a...) do { } while(0)
5381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent#endif
5481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
5581784c37c61b09289654b979567a42bf73cd2b12Eric Laurentnamespace android {
5681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
5781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// ----------------------------------------------------------------------------
5881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent//      TrackBase
5981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// ----------------------------------------------------------------------------
6081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
61da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kastenstatic volatile int32_t nextTrackId = 55;
62da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten
6381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// TrackBase constructor must be called with AudioFlinger::mLock held
6481784c37c61b09289654b979567a42bf73cd2b12Eric LaurentAudioFlinger::ThreadBase::TrackBase::TrackBase(
6581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            ThreadBase *thread,
6681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            const sp<Client>& client,
6781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            uint32_t sampleRate,
6881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            audio_format_t format,
6981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            audio_channel_mask_t channelMask,
7081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            size_t frameCount,
7183b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent            void *buffer,
72e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten            int sessionId,
73462fd2fa9eef642b0574aa7409de0bde3fec8d43Marco Nelissen            int clientUid,
74755b0a611f539dfa49e88aac592a938427c7e1b8Glenn Kasten            IAudioFlinger::track_flags_t flags,
75d776ac63ce9c013c9626226e43f7db606e035838Glenn Kasten            bool isOut,
7683b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent            alloc_type alloc,
7783b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent            track_type type)
7881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    :   RefBase(),
7981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        mThread(thread),
8081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        mClient(client),
8181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        mCblk(NULL),
8281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        // mBuffer
8381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        mState(IDLE),
8481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        mSampleRate(sampleRate),
8581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        mFormat(format),
8681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        mChannelMask(channelMask),
87e541269be94f3a1072932d51537905b120ef4733Andy Hung        mChannelCount(isOut ?
88e541269be94f3a1072932d51537905b120ef4733Andy Hung                audio_channel_count_from_out_mask(channelMask) :
89e541269be94f3a1072932d51537905b120ef4733Andy Hung                audio_channel_count_from_in_mask(channelMask)),
9081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        mFrameSize(audio_is_linear_pcm(format) ?
9181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                mChannelCount * audio_bytes_per_sample(format) : sizeof(int8_t)),
9281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        mFrameCount(frameCount),
93e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten        mSessionId(sessionId),
94755b0a611f539dfa49e88aac592a938427c7e1b8Glenn Kasten        mFlags(flags),
95e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten        mIsOut(isOut),
96da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten        mServerProxy(NULL),
97bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent        mId(android_atomic_inc(&nextTrackId)),
9883b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent        mTerminated(false),
99aaa44478a373232d8416657035a9020f9c7aa7c3Eric Laurent        mType(type),
100aaa44478a373232d8416657035a9020f9c7aa7c3Eric Laurent        mThreadIoHandle(thread->id())
10181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{
102462fd2fa9eef642b0574aa7409de0bde3fec8d43Marco Nelissen    // if the caller is us, trust the specified uid
103462fd2fa9eef642b0574aa7409de0bde3fec8d43Marco Nelissen    if (IPCThreadState::self()->getCallingPid() != getpid_cached || clientUid == -1) {
104462fd2fa9eef642b0574aa7409de0bde3fec8d43Marco Nelissen        int newclientUid = IPCThreadState::self()->getCallingUid();
105462fd2fa9eef642b0574aa7409de0bde3fec8d43Marco Nelissen        if (clientUid != -1 && clientUid != newclientUid) {
106462fd2fa9eef642b0574aa7409de0bde3fec8d43Marco Nelissen            ALOGW("uid %d tried to pass itself off as %d", newclientUid, clientUid);
107462fd2fa9eef642b0574aa7409de0bde3fec8d43Marco Nelissen        }
108462fd2fa9eef642b0574aa7409de0bde3fec8d43Marco Nelissen        clientUid = newclientUid;
109462fd2fa9eef642b0574aa7409de0bde3fec8d43Marco Nelissen    }
110462fd2fa9eef642b0574aa7409de0bde3fec8d43Marco Nelissen    // clientUid contains the uid of the app that is responsible for this track, so we can blame
111462fd2fa9eef642b0574aa7409de0bde3fec8d43Marco Nelissen    // battery usage on it.
112462fd2fa9eef642b0574aa7409de0bde3fec8d43Marco Nelissen    mUid = clientUid;
113462fd2fa9eef642b0574aa7409de0bde3fec8d43Marco Nelissen
11481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    // ALOGD("Creating track with %d buffers @ %d bytes", bufferCount, bufferSize);
11581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    size_t size = sizeof(audio_track_cblk_t);
11683b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent    size_t bufferSize = (buffer == NULL ? roundup(frameCount) : frameCount) * mFrameSize;
11783b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent    if (buffer == NULL && alloc == ALLOC_CBLK) {
11881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        size += bufferSize;
11981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    }
12081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
12181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    if (client != 0) {
12281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        mCblkMemory = client->heap()->allocate(size);
123663c2247b71086e30bfd3192979d1dd7f15c539eGlenn Kasten        if (mCblkMemory == 0 ||
124663c2247b71086e30bfd3192979d1dd7f15c539eGlenn Kasten                (mCblk = static_cast<audio_track_cblk_t *>(mCblkMemory->pointer())) == NULL) {
12581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            ALOGE("not enough memory for AudioTrack size=%u", size);
12681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            client->heap()->dump("AudioTrack");
127663c2247b71086e30bfd3192979d1dd7f15c539eGlenn Kasten            mCblkMemory.clear();
12881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            return;
12981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        }
13081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    } else {
131e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten        // this syntax avoids calling the audio_track_cblk_t constructor twice
132e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten        mCblk = (audio_track_cblk_t *) new uint8_t[size];
13381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        // assume mCblk != NULL
13481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    }
13581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
13681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    // construct the shared structure in-place.
13781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    if (mCblk != NULL) {
13881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        new(mCblk) audio_track_cblk_t();
139c263ca0ad8b6bdf5b0693996bc5f2f5916e0cd49Glenn Kasten        switch (alloc) {
140c263ca0ad8b6bdf5b0693996bc5f2f5916e0cd49Glenn Kasten        case ALLOC_READONLY: {
141d776ac63ce9c013c9626226e43f7db606e035838Glenn Kasten            const sp<MemoryDealer> roHeap(thread->readOnlyHeap());
142d776ac63ce9c013c9626226e43f7db606e035838Glenn Kasten            if (roHeap == 0 ||
143d776ac63ce9c013c9626226e43f7db606e035838Glenn Kasten                    (mBufferMemory = roHeap->allocate(bufferSize)) == 0 ||
144d776ac63ce9c013c9626226e43f7db606e035838Glenn Kasten                    (mBuffer = mBufferMemory->pointer()) == NULL) {
145d776ac63ce9c013c9626226e43f7db606e035838Glenn Kasten                ALOGE("not enough memory for read-only buffer size=%zu", bufferSize);
146d776ac63ce9c013c9626226e43f7db606e035838Glenn Kasten                if (roHeap != 0) {
147d776ac63ce9c013c9626226e43f7db606e035838Glenn Kasten                    roHeap->dump("buffer");
148d776ac63ce9c013c9626226e43f7db606e035838Glenn Kasten                }
149d776ac63ce9c013c9626226e43f7db606e035838Glenn Kasten                mCblkMemory.clear();
150d776ac63ce9c013c9626226e43f7db606e035838Glenn Kasten                mBufferMemory.clear();
151d776ac63ce9c013c9626226e43f7db606e035838Glenn Kasten                return;
152d776ac63ce9c013c9626226e43f7db606e035838Glenn Kasten            }
15381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            memset(mBuffer, 0, bufferSize);
154c263ca0ad8b6bdf5b0693996bc5f2f5916e0cd49Glenn Kasten            } break;
155c263ca0ad8b6bdf5b0693996bc5f2f5916e0cd49Glenn Kasten        case ALLOC_PIPE:
156c263ca0ad8b6bdf5b0693996bc5f2f5916e0cd49Glenn Kasten            mBufferMemory = thread->pipeMemory();
157c263ca0ad8b6bdf5b0693996bc5f2f5916e0cd49Glenn Kasten            // mBuffer is the virtual address as seen from current process (mediaserver),
158c263ca0ad8b6bdf5b0693996bc5f2f5916e0cd49Glenn Kasten            // and should normally be coming from mBufferMemory->pointer().
159c263ca0ad8b6bdf5b0693996bc5f2f5916e0cd49Glenn Kasten            // However in this case the TrackBase does not reference the buffer directly.
160c263ca0ad8b6bdf5b0693996bc5f2f5916e0cd49Glenn Kasten            // It should references the buffer via the pipe.
161c263ca0ad8b6bdf5b0693996bc5f2f5916e0cd49Glenn Kasten            // Therefore, to detect incorrect usage of the buffer, we set mBuffer to NULL.
162c263ca0ad8b6bdf5b0693996bc5f2f5916e0cd49Glenn Kasten            mBuffer = NULL;
163c263ca0ad8b6bdf5b0693996bc5f2f5916e0cd49Glenn Kasten            break;
164c263ca0ad8b6bdf5b0693996bc5f2f5916e0cd49Glenn Kasten        case ALLOC_CBLK:
165d776ac63ce9c013c9626226e43f7db606e035838Glenn Kasten            // clear all buffers
16683b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent            if (buffer == NULL) {
167d776ac63ce9c013c9626226e43f7db606e035838Glenn Kasten                mBuffer = (char*)mCblk + sizeof(audio_track_cblk_t);
168d776ac63ce9c013c9626226e43f7db606e035838Glenn Kasten                memset(mBuffer, 0, bufferSize);
169d776ac63ce9c013c9626226e43f7db606e035838Glenn Kasten            } else {
17083b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent                mBuffer = buffer;
1719f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten#if 0
172d776ac63ce9c013c9626226e43f7db606e035838Glenn Kasten                mCblk->mFlags = CBLK_FORCEREADY;    // FIXME hack, need to fix the track ready logic
1739f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten#endif
174d776ac63ce9c013c9626226e43f7db606e035838Glenn Kasten            }
175c263ca0ad8b6bdf5b0693996bc5f2f5916e0cd49Glenn Kasten            break;
17683b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent        case ALLOC_LOCAL:
17783b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent            mBuffer = calloc(1, bufferSize);
17883b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent            break;
17983b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent        case ALLOC_NONE:
18083b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent            mBuffer = buffer;
18183b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent            break;
18281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        }
183da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten
18446909e7eb074ce1b95b8a411eb71154f53f84f77Glenn Kasten#ifdef TEE_SINK
185da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten        if (mTeeSinkTrackEnabled) {
186329f6511ee4e03a4605c70bbda8d3a96d2544884Glenn Kasten            NBAIO_Format pipeFormat = Format_from_SR_C(mSampleRate, mChannelCount, mFormat);
1876e0d67d7b496ce17c0970a4ffd3a6f808860949cGlenn Kasten            if (Format_isValid(pipeFormat)) {
18846909e7eb074ce1b95b8a411eb71154f53f84f77Glenn Kasten                Pipe *pipe = new Pipe(mTeeSinkTrackFrames, pipeFormat);
18946909e7eb074ce1b95b8a411eb71154f53f84f77Glenn Kasten                size_t numCounterOffers = 0;
19046909e7eb074ce1b95b8a411eb71154f53f84f77Glenn Kasten                const NBAIO_Format offers[1] = {pipeFormat};
19146909e7eb074ce1b95b8a411eb71154f53f84f77Glenn Kasten                ssize_t index = pipe->negotiate(offers, 1, NULL, numCounterOffers);
19246909e7eb074ce1b95b8a411eb71154f53f84f77Glenn Kasten                ALOG_ASSERT(index == 0);
19346909e7eb074ce1b95b8a411eb71154f53f84f77Glenn Kasten                PipeReader *pipeReader = new PipeReader(*pipe);
19446909e7eb074ce1b95b8a411eb71154f53f84f77Glenn Kasten                numCounterOffers = 0;
19546909e7eb074ce1b95b8a411eb71154f53f84f77Glenn Kasten                index = pipeReader->negotiate(offers, 1, NULL, numCounterOffers);
19646909e7eb074ce1b95b8a411eb71154f53f84f77Glenn Kasten                ALOG_ASSERT(index == 0);
19746909e7eb074ce1b95b8a411eb71154f53f84f77Glenn Kasten                mTeeSink = pipe;
19846909e7eb074ce1b95b8a411eb71154f53f84f77Glenn Kasten                mTeeSource = pipeReader;
19946909e7eb074ce1b95b8a411eb71154f53f84f77Glenn Kasten            }
200da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten        }
20146909e7eb074ce1b95b8a411eb71154f53f84f77Glenn Kasten#endif
202da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten
20381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    }
20481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
20581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
20683b8808faad1e91690c64d7007348be8d9ebde73Eric Laurentstatus_t AudioFlinger::ThreadBase::TrackBase::initCheck() const
20783b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent{
20883b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent    status_t status;
20983b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent    if (mType == TYPE_OUTPUT || mType == TYPE_PATCH) {
21083b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent        status = cblk() != NULL ? NO_ERROR : NO_MEMORY;
21183b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent    } else {
21283b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent        status = getCblk() != 0 ? NO_ERROR : NO_MEMORY;
21383b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent    }
21483b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent    return status;
21583b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent}
21683b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent
21781784c37c61b09289654b979567a42bf73cd2b12Eric LaurentAudioFlinger::ThreadBase::TrackBase::~TrackBase()
21881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{
21946909e7eb074ce1b95b8a411eb71154f53f84f77Glenn Kasten#ifdef TEE_SINK
220da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten    dumpTee(-1, mTeeSource, mId);
22146909e7eb074ce1b95b8a411eb71154f53f84f77Glenn Kasten#endif
222e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten    // delete the proxy before deleting the shared memory it refers to, to avoid dangling reference
223e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten    delete mServerProxy;
22481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    if (mCblk != NULL) {
22581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        if (mClient == 0) {
22681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            delete mCblk;
22781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        } else {
22881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            mCblk->~audio_track_cblk_t();   // destroy our shared-structure.
22981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        }
23081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    }
23181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    mCblkMemory.clear();    // free the shared memory before releasing the heap it belongs to
23281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    if (mClient != 0) {
233021cf9634ab09c0753a40b7c9ef4ba603be5c3daEric Laurent        // Client destructor must run with AudioFlinger client mutex locked
234021cf9634ab09c0753a40b7c9ef4ba603be5c3daEric Laurent        Mutex::Autolock _l(mClient->audioFlinger()->mClientLock);
23581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        // If the client's reference count drops to zero, the associated destructor
23681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        // must run with AudioFlinger lock held. Thus the explicit clear() rather than
23781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        // relying on the automatic clear() at end of scope.
23881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        mClient.clear();
23981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    }
2403bcffa136909c1fb6e88ee4efd12ccac18360a85Eric Laurent    // flush the binder command buffer
2413bcffa136909c1fb6e88ee4efd12ccac18360a85Eric Laurent    IPCThreadState::self()->flushCommands();
24281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
24381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
24481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// AudioBufferProvider interface
24581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// getNextBuffer() = 0;
24681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// This implementation of releaseBuffer() is used by Track and RecordTrack, but not TimedTrack
24781784c37c61b09289654b979567a42bf73cd2b12Eric Laurentvoid AudioFlinger::ThreadBase::TrackBase::releaseBuffer(AudioBufferProvider::Buffer* buffer)
24881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{
24946909e7eb074ce1b95b8a411eb71154f53f84f77Glenn Kasten#ifdef TEE_SINK
250da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten    if (mTeeSink != 0) {
251da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten        (void) mTeeSink->write(buffer->raw, buffer->frameCount);
252da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten    }
25346909e7eb074ce1b95b8a411eb71154f53f84f77Glenn Kasten#endif
254da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten
2559f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    ServerProxy::Buffer buf;
2569f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    buf.mFrameCount = buffer->frameCount;
2579f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    buf.mRaw = buffer->raw;
25881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    buffer->frameCount = 0;
2599f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    buffer->raw = NULL;
2609f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    mServerProxy->releaseBuffer(&buf);
26181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
26281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
26381784c37c61b09289654b979567a42bf73cd2b12Eric Laurentstatus_t AudioFlinger::ThreadBase::TrackBase::setSyncEvent(const sp<SyncEvent>& event)
26481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{
26581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    mSyncEvents.add(event);
26681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    return NO_ERROR;
26781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
26881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
26981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// ----------------------------------------------------------------------------
27081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent//      Playback
27181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// ----------------------------------------------------------------------------
27281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
27381784c37c61b09289654b979567a42bf73cd2b12Eric LaurentAudioFlinger::TrackHandle::TrackHandle(const sp<AudioFlinger::PlaybackThread::Track>& track)
27481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    : BnAudioTrack(),
27581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent      mTrack(track)
27681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{
27781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
27881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
27981784c37c61b09289654b979567a42bf73cd2b12Eric LaurentAudioFlinger::TrackHandle::~TrackHandle() {
28081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    // just stop the track on deletion, associated resources
28181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    // will be freed from the main thread once all pending buffers have
28281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    // been played. Unless it's not in the active track list, in which
28381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    // case we free everything now...
28481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    mTrack->destroy();
28581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
28681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
28781784c37c61b09289654b979567a42bf73cd2b12Eric Laurentsp<IMemory> AudioFlinger::TrackHandle::getCblk() const {
28881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    return mTrack->getCblk();
28981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
29081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
29181784c37c61b09289654b979567a42bf73cd2b12Eric Laurentstatus_t AudioFlinger::TrackHandle::start() {
29281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    return mTrack->start();
29381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
29481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
29581784c37c61b09289654b979567a42bf73cd2b12Eric Laurentvoid AudioFlinger::TrackHandle::stop() {
29681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    mTrack->stop();
29781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
29881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
29981784c37c61b09289654b979567a42bf73cd2b12Eric Laurentvoid AudioFlinger::TrackHandle::flush() {
30081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    mTrack->flush();
30181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
30281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
30381784c37c61b09289654b979567a42bf73cd2b12Eric Laurentvoid AudioFlinger::TrackHandle::pause() {
30481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    mTrack->pause();
30581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
30681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
30781784c37c61b09289654b979567a42bf73cd2b12Eric Laurentstatus_t AudioFlinger::TrackHandle::attachAuxEffect(int EffectId)
30881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{
30981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    return mTrack->attachAuxEffect(EffectId);
31081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
31181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
31281784c37c61b09289654b979567a42bf73cd2b12Eric Laurentstatus_t AudioFlinger::TrackHandle::allocateTimedBuffer(size_t size,
31381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                                                         sp<IMemory>* buffer) {
31481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    if (!mTrack->isTimedTrack())
31581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        return INVALID_OPERATION;
31681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
31781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    PlaybackThread::TimedTrack* tt =
31881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            reinterpret_cast<PlaybackThread::TimedTrack*>(mTrack.get());
31981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    return tt->allocateTimedBuffer(size, buffer);
32081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
32181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
32281784c37c61b09289654b979567a42bf73cd2b12Eric Laurentstatus_t AudioFlinger::TrackHandle::queueTimedBuffer(const sp<IMemory>& buffer,
32381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                                                     int64_t pts) {
32481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    if (!mTrack->isTimedTrack())
32581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        return INVALID_OPERATION;
32681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
327663c2247b71086e30bfd3192979d1dd7f15c539eGlenn Kasten    if (buffer == 0 || buffer->pointer() == NULL) {
328663c2247b71086e30bfd3192979d1dd7f15c539eGlenn Kasten        ALOGE("queueTimedBuffer() buffer is 0 or has NULL pointer()");
329663c2247b71086e30bfd3192979d1dd7f15c539eGlenn Kasten        return BAD_VALUE;
330663c2247b71086e30bfd3192979d1dd7f15c539eGlenn Kasten    }
331663c2247b71086e30bfd3192979d1dd7f15c539eGlenn Kasten
33281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    PlaybackThread::TimedTrack* tt =
33381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            reinterpret_cast<PlaybackThread::TimedTrack*>(mTrack.get());
33481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    return tt->queueTimedBuffer(buffer, pts);
33581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
33681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
33781784c37c61b09289654b979567a42bf73cd2b12Eric Laurentstatus_t AudioFlinger::TrackHandle::setMediaTimeTransform(
33881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    const LinearTransform& xform, int target) {
33981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
34081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    if (!mTrack->isTimedTrack())
34181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        return INVALID_OPERATION;
34281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
34381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    PlaybackThread::TimedTrack* tt =
34481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            reinterpret_cast<PlaybackThread::TimedTrack*>(mTrack.get());
34581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    return tt->setMediaTimeTransform(
34681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        xform, static_cast<TimedAudioTrack::TargetTimeline>(target));
34781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
34881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
3493dcd00dddec86a1c5133083ad7ba2265d49c048cGlenn Kastenstatus_t AudioFlinger::TrackHandle::setParameters(const String8& keyValuePairs) {
3503dcd00dddec86a1c5133083ad7ba2265d49c048cGlenn Kasten    return mTrack->setParameters(keyValuePairs);
3513dcd00dddec86a1c5133083ad7ba2265d49c048cGlenn Kasten}
3523dcd00dddec86a1c5133083ad7ba2265d49c048cGlenn Kasten
35353cec22821072719ee02c856e9ac2dda2496c570Glenn Kastenstatus_t AudioFlinger::TrackHandle::getTimestamp(AudioTimestamp& timestamp)
35453cec22821072719ee02c856e9ac2dda2496c570Glenn Kasten{
355573d80a8f463f648a515fc0975bf83951b272993Glenn Kasten    return mTrack->getTimestamp(timestamp);
35653cec22821072719ee02c856e9ac2dda2496c570Glenn Kasten}
35753cec22821072719ee02c856e9ac2dda2496c570Glenn Kasten
35859fe010bcc072597852454a2ec53d7b0a2002a3bEric Laurent
35959fe010bcc072597852454a2ec53d7b0a2002a3bEric Laurentvoid AudioFlinger::TrackHandle::signal()
36059fe010bcc072597852454a2ec53d7b0a2002a3bEric Laurent{
36159fe010bcc072597852454a2ec53d7b0a2002a3bEric Laurent    return mTrack->signal();
36259fe010bcc072597852454a2ec53d7b0a2002a3bEric Laurent}
36359fe010bcc072597852454a2ec53d7b0a2002a3bEric Laurent
36481784c37c61b09289654b979567a42bf73cd2b12Eric Laurentstatus_t AudioFlinger::TrackHandle::onTransact(
36581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
36681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{
36781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    return BnAudioTrack::onTransact(code, data, reply, flags);
36881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
36981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
37081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// ----------------------------------------------------------------------------
37181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
37281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// Track constructor must be called with AudioFlinger::mLock and ThreadBase::mLock held
37381784c37c61b09289654b979567a42bf73cd2b12Eric LaurentAudioFlinger::PlaybackThread::Track::Track(
37481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            PlaybackThread *thread,
37581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            const sp<Client>& client,
37681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            audio_stream_type_t streamType,
37781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            uint32_t sampleRate,
37881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            audio_format_t format,
37981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            audio_channel_mask_t channelMask,
38081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            size_t frameCount,
38183b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent            void *buffer,
38281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            const sp<IMemory>& sharedBuffer,
38381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            int sessionId,
384462fd2fa9eef642b0574aa7409de0bde3fec8d43Marco Nelissen            int uid,
38583b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent            IAudioFlinger::track_flags_t flags,
38683b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent            track_type type)
38783b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent    :   TrackBase(thread, client, sampleRate, format, channelMask, frameCount,
38883b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent                  (sharedBuffer != 0) ? sharedBuffer->pointer() : buffer,
38983b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent                  sessionId, uid, flags, true /*isOut*/,
39083b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent                  (type == TYPE_PATCH) ? ( buffer == NULL ? ALLOC_LOCAL : ALLOC_NONE) : ALLOC_CBLK,
39183b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent                  type),
39281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    mFillingUpStatus(FS_INVALID),
39381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    // mRetryCount initialized later when needed
39481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    mSharedBuffer(sharedBuffer),
39581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    mStreamType(streamType),
39681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    mName(-1),  // see note below
39781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    mMainBuffer(thread->mixBuffer()),
39881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    mAuxBuffer(NULL),
39981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    mAuxEffectId(0), mHasVolumeController(false),
40081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    mPresentationCompleteFrames(0),
40181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    mFastIndex(-1),
4025736c35b841de56ce394b4879389f669b61425e6Glenn Kasten    mCachedVolume(1.0),
4039f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    mIsInvalid(false),
404bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent    mAudioTrackServerProxy(NULL),
4057844f679be8d94c5cdf017f53754cb68ee2f00daHaynes Mathew George    mResumeToStopping(false),
406ced6e74215937182fe2f9f6b0867f7c28ccd02c1Glenn Kasten    mFlushHwPending(false),
407ced6e74215937182fe2f9f6b0867f7c28ccd02c1Glenn Kasten    mPreviousValid(false),
408ced6e74215937182fe2f9f6b0867f7c28ccd02c1Glenn Kasten    mPreviousFramesWritten(0)
409ced6e74215937182fe2f9f6b0867f7c28ccd02c1Glenn Kasten    // mPreviousTimestamp
41081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{
41183b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent    // client == 0 implies sharedBuffer == 0
41283b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent    ALOG_ASSERT(!(client == 0 && sharedBuffer != 0));
41383b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent
41483b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent    ALOGV_IF(sharedBuffer != 0, "sharedBuffer: %p, size: %d", sharedBuffer->pointer(),
41583b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent            sharedBuffer->size());
41683b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent
4173ef14ef30359376006a233f6a21a165d4b65a7dfGlenn Kasten    if (mCblk == NULL) {
4183ef14ef30359376006a233f6a21a165d4b65a7dfGlenn Kasten        return;
4193ef14ef30359376006a233f6a21a165d4b65a7dfGlenn Kasten    }
4203ef14ef30359376006a233f6a21a165d4b65a7dfGlenn Kasten
4213ef14ef30359376006a233f6a21a165d4b65a7dfGlenn Kasten    if (sharedBuffer == 0) {
4223ef14ef30359376006a233f6a21a165d4b65a7dfGlenn Kasten        mAudioTrackServerProxy = new AudioTrackServerProxy(mCblk, mBuffer, frameCount,
42383b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent                mFrameSize, !isExternalTrack(), sampleRate);
4243ef14ef30359376006a233f6a21a165d4b65a7dfGlenn Kasten    } else {
4253ef14ef30359376006a233f6a21a165d4b65a7dfGlenn Kasten        mAudioTrackServerProxy = new StaticAudioTrackServerProxy(mCblk, mBuffer, frameCount,
4263ef14ef30359376006a233f6a21a165d4b65a7dfGlenn Kasten                mFrameSize);
4273ef14ef30359376006a233f6a21a165d4b65a7dfGlenn Kasten    }
4283ef14ef30359376006a233f6a21a165d4b65a7dfGlenn Kasten    mServerProxy = mAudioTrackServerProxy;
4293ef14ef30359376006a233f6a21a165d4b65a7dfGlenn Kasten
430c263ca0ad8b6bdf5b0693996bc5f2f5916e0cd49Glenn Kasten    mName = thread->getTrackName_l(channelMask, format, sessionId);
4313ef14ef30359376006a233f6a21a165d4b65a7dfGlenn Kasten    if (mName < 0) {
4323ef14ef30359376006a233f6a21a165d4b65a7dfGlenn Kasten        ALOGE("no more track names available");
4333ef14ef30359376006a233f6a21a165d4b65a7dfGlenn Kasten        return;
4343ef14ef30359376006a233f6a21a165d4b65a7dfGlenn Kasten    }
4353ef14ef30359376006a233f6a21a165d4b65a7dfGlenn Kasten    // only allocate a fast track index if we were able to allocate a normal track name
4363ef14ef30359376006a233f6a21a165d4b65a7dfGlenn Kasten    if (flags & IAudioFlinger::TRACK_FAST) {
4373ef14ef30359376006a233f6a21a165d4b65a7dfGlenn Kasten        mAudioTrackServerProxy->framesReadyIsCalledByMultipleThreads();
4383ef14ef30359376006a233f6a21a165d4b65a7dfGlenn Kasten        ALOG_ASSERT(thread->mFastTrackAvailMask != 0);
4393ef14ef30359376006a233f6a21a165d4b65a7dfGlenn Kasten        int i = __builtin_ctz(thread->mFastTrackAvailMask);
4403ef14ef30359376006a233f6a21a165d4b65a7dfGlenn Kasten        ALOG_ASSERT(0 < i && i < (int)FastMixerState::kMaxFastTracks);
4413ef14ef30359376006a233f6a21a165d4b65a7dfGlenn Kasten        // FIXME This is too eager.  We allocate a fast track index before the
4423ef14ef30359376006a233f6a21a165d4b65a7dfGlenn Kasten        //       fast track becomes active.  Since fast tracks are a scarce resource,
4433ef14ef30359376006a233f6a21a165d4b65a7dfGlenn Kasten        //       this means we are potentially denying other more important fast tracks from
4443ef14ef30359376006a233f6a21a165d4b65a7dfGlenn Kasten        //       being created.  It would be better to allocate the index dynamically.
4453ef14ef30359376006a233f6a21a165d4b65a7dfGlenn Kasten        mFastIndex = i;
4463ef14ef30359376006a233f6a21a165d4b65a7dfGlenn Kasten        // Read the initial underruns because this field is never cleared by the fast mixer
4473ef14ef30359376006a233f6a21a165d4b65a7dfGlenn Kasten        mObservedUnderruns = thread->getFastTrackUnderruns(i);
4483ef14ef30359376006a233f6a21a165d4b65a7dfGlenn Kasten        thread->mFastTrackAvailMask &= ~(1 << i);
44981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    }
45081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
45181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
45281784c37c61b09289654b979567a42bf73cd2b12Eric LaurentAudioFlinger::PlaybackThread::Track::~Track()
45381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{
45481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    ALOGV("PlaybackThread::Track destructor");
4550c72b24f91c68442eb374bd1b338c394105b8262Glenn Kasten
4560c72b24f91c68442eb374bd1b338c394105b8262Glenn Kasten    // The destructor would clear mSharedBuffer,
4570c72b24f91c68442eb374bd1b338c394105b8262Glenn Kasten    // but it will not push the decremented reference count,
4580c72b24f91c68442eb374bd1b338c394105b8262Glenn Kasten    // leaving the client's IMemory dangling indefinitely.
4590c72b24f91c68442eb374bd1b338c394105b8262Glenn Kasten    // This prevents that leak.
4600c72b24f91c68442eb374bd1b338c394105b8262Glenn Kasten    if (mSharedBuffer != 0) {
4610c72b24f91c68442eb374bd1b338c394105b8262Glenn Kasten        mSharedBuffer.clear();
4620c72b24f91c68442eb374bd1b338c394105b8262Glenn Kasten    }
46381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
46481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
465030033342a6ea17003e6af38a56c7edc6d2ead01Glenn Kastenstatus_t AudioFlinger::PlaybackThread::Track::initCheck() const
466030033342a6ea17003e6af38a56c7edc6d2ead01Glenn Kasten{
467030033342a6ea17003e6af38a56c7edc6d2ead01Glenn Kasten    status_t status = TrackBase::initCheck();
468030033342a6ea17003e6af38a56c7edc6d2ead01Glenn Kasten    if (status == NO_ERROR && mName < 0) {
469030033342a6ea17003e6af38a56c7edc6d2ead01Glenn Kasten        status = NO_MEMORY;
470030033342a6ea17003e6af38a56c7edc6d2ead01Glenn Kasten    }
471030033342a6ea17003e6af38a56c7edc6d2ead01Glenn Kasten    return status;
472030033342a6ea17003e6af38a56c7edc6d2ead01Glenn Kasten}
473030033342a6ea17003e6af38a56c7edc6d2ead01Glenn Kasten
47481784c37c61b09289654b979567a42bf73cd2b12Eric Laurentvoid AudioFlinger::PlaybackThread::Track::destroy()
47581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{
47681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    // NOTE: destroyTrack_l() can remove a strong reference to this Track
47781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    // by removing it from mTracks vector, so there is a risk that this Tracks's
47881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    // destructor is called. As the destructor needs to lock mLock,
47981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    // we must acquire a strong reference on this Track before locking mLock
48081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    // here so that the destructor is called only when exiting this function.
48181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    // On the other hand, as long as Track::destroy() is only called by
48281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    // TrackHandle destructor, the TrackHandle still holds a strong ref on
48381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    // this Track with its member mTrack.
48481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    sp<Track> keep(this);
48581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    { // scope for mLock
486aaa44478a373232d8416657035a9020f9c7aa7c3Eric Laurent        bool wasActive = false;
48781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        sp<ThreadBase> thread = mThread.promote();
48881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        if (thread != 0) {
48981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            Mutex::Autolock _l(thread->mLock);
49081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            PlaybackThread *playbackThread = (PlaybackThread *)thread.get();
491aaa44478a373232d8416657035a9020f9c7aa7c3Eric Laurent            wasActive = playbackThread->destroyTrack_l(this);
492aaa44478a373232d8416657035a9020f9c7aa7c3Eric Laurent        }
493aaa44478a373232d8416657035a9020f9c7aa7c3Eric Laurent        if (isExternalTrack() && !wasActive) {
494e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent            AudioSystem::releaseOutput(mThreadIoHandle, mStreamType, (audio_session_t)mSessionId);
49581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        }
49681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    }
49781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
49881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
49981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent/*static*/ void AudioFlinger::PlaybackThread::Track::appendDumpHeader(String8& result)
50081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{
501b220884bf3129253cc5bc8d030bc475411ea4911Marco Nelissen    result.append("    Name Active Client Type      Fmt Chn mask Session fCount S F SRate  "
50282aaf94a5b18939e4d790bbc752031f3070704a3Glenn Kasten                  "L dB  R dB    Server Main buf  Aux Buf Flags UndFrmCnt\n");
50381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
50481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
505b220884bf3129253cc5bc8d030bc475411ea4911Marco Nelissenvoid AudioFlinger::PlaybackThread::Track::dump(char* buffer, size_t size, bool active)
50681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{
507c56f3426099a3cf2d07ccff8886050c7fbce140fGlenn Kasten    gain_minifloat_packed_t vlr = mAudioTrackServerProxy->getVolumeLR();
50881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    if (isFastTrack()) {
509b220884bf3129253cc5bc8d030bc475411ea4911Marco Nelissen        sprintf(buffer, "    F %2d", mFastIndex);
510b220884bf3129253cc5bc8d030bc475411ea4911Marco Nelissen    } else if (mName >= AudioMixer::TRACK0) {
511b220884bf3129253cc5bc8d030bc475411ea4911Marco Nelissen        sprintf(buffer, "    %4d", mName - AudioMixer::TRACK0);
51281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    } else {
513b220884bf3129253cc5bc8d030bc475411ea4911Marco Nelissen        sprintf(buffer, "    none");
51481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    }
51581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    track_state state = mState;
51681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    char stateChar;
517bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent    if (isTerminated()) {
51881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        stateChar = 'T';
519bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent    } else {
520bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent        switch (state) {
521bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent        case IDLE:
522bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent            stateChar = 'I';
523bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent            break;
524bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent        case STOPPING_1:
525bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent            stateChar = 's';
526bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent            break;
527bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent        case STOPPING_2:
528bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent            stateChar = '5';
529bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent            break;
530bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent        case STOPPED:
531bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent            stateChar = 'S';
532bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent            break;
533bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent        case RESUMING:
534bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent            stateChar = 'R';
535bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent            break;
536bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent        case ACTIVE:
537bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent            stateChar = 'A';
538bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent            break;
539bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent        case PAUSING:
540bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent            stateChar = 'p';
541bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent            break;
542bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent        case PAUSED:
543bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent            stateChar = 'P';
544bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent            break;
545bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent        case FLUSHED:
546bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent            stateChar = 'F';
547bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent            break;
548bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent        default:
549bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent            stateChar = '?';
550bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent            break;
551bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent        }
55281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    }
55381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    char nowInUnderrun;
55481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    switch (mObservedUnderruns.mBitFields.mMostRecent) {
55581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    case UNDERRUN_FULL:
55681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        nowInUnderrun = ' ';
55781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        break;
55881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    case UNDERRUN_PARTIAL:
55981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        nowInUnderrun = '<';
56081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        break;
56181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    case UNDERRUN_EMPTY:
56281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        nowInUnderrun = '*';
56381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        break;
56481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    default:
56581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        nowInUnderrun = '?';
56681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        break;
56781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    }
5681d6fa7af1288b550faabe4ec2cf98684236723dbNarayan Kamath    snprintf(&buffer[8], size-8, " %6s %6u %4u %08X %08X %7u %6zu %1c %1d %5u %5.2g %5.2g  "
569377b2ec9a2885f9b6405b07ba900a9e3f4349c38Kévin PETIT                                 "%08X %p %p 0x%03X %9u%c\n",
570b220884bf3129253cc5bc8d030bc475411ea4911Marco Nelissen            active ? "yes" : "no",
57181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            (mClient == 0) ? getpid_cached : mClient->pid(),
57281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            mStreamType,
57381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            mFormat,
57481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            mChannelMask,
57581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            mSessionId,
57681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            mFrameCount,
57781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            stateChar,
57881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            mFillingUpStatus,
5799f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten            mAudioTrackServerProxy->getSampleRate(),
580c56f3426099a3cf2d07ccff8886050c7fbce140fGlenn Kasten            20.0 * log10(float_from_gain(gain_minifloat_unpack_left(vlr))),
581c56f3426099a3cf2d07ccff8886050c7fbce140fGlenn Kasten            20.0 * log10(float_from_gain(gain_minifloat_unpack_right(vlr))),
582f20e1d8df84c5fbeeace0052d100982ae39bb7a4Glenn Kasten            mCblk->mServer,
583377b2ec9a2885f9b6405b07ba900a9e3f4349c38Kévin PETIT            mMainBuffer,
584377b2ec9a2885f9b6405b07ba900a9e3f4349c38Kévin PETIT            mAuxBuffer,
58596f60d8f04432a1ed503b3e24d5736d28c63c9a2Glenn Kasten            mCblk->mFlags,
58682aaf94a5b18939e4d790bbc752031f3070704a3Glenn Kasten            mAudioTrackServerProxy->getUnderrunFrames(),
58781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            nowInUnderrun);
58881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
58981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
5909f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kastenuint32_t AudioFlinger::PlaybackThread::Track::sampleRate() const {
5919f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    return mAudioTrackServerProxy->getSampleRate();
5929f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten}
5939f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten
59481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// AudioBufferProvider interface
59581784c37c61b09289654b979567a42bf73cd2b12Eric Laurentstatus_t AudioFlinger::PlaybackThread::Track::getNextBuffer(
5960f11b51a57bc9062c4fe8af73747319cedabc5d6Glenn Kasten        AudioBufferProvider::Buffer* buffer, int64_t pts __unused)
59781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{
5989f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    ServerProxy::Buffer buf;
5999f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    size_t desiredFrames = buffer->frameCount;
6009f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    buf.mFrameCount = desiredFrames;
6019f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    status_t status = mServerProxy->obtainBuffer(&buf);
6029f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    buffer->frameCount = buf.mFrameCount;
6039f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    buffer->raw = buf.mRaw;
6049f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    if (buf.mFrameCount == 0) {
60582aaf94a5b18939e4d790bbc752031f3070704a3Glenn Kasten        mAudioTrackServerProxy->tallyUnderrunFrames(desiredFrames);
60681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    }
6079f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    return status;
60881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
60981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
6106466c9e6e6278c740aed77f695f679be9f5db478Glenn Kasten// releaseBuffer() is not overridden
6116466c9e6e6278c740aed77f695f679be9f5db478Glenn Kasten
6126466c9e6e6278c740aed77f695f679be9f5db478Glenn Kasten// ExtendedAudioBufferProvider interface
6136466c9e6e6278c740aed77f695f679be9f5db478Glenn Kasten
61427876c02c21cd3ab7ef01bdd1fc5400c5143584aAndy Hung// framesReady() may return an approximation of the number of frames if called
61527876c02c21cd3ab7ef01bdd1fc5400c5143584aAndy Hung// from a different thread than the one calling Proxy->obtainBuffer() and
61627876c02c21cd3ab7ef01bdd1fc5400c5143584aAndy Hung// Proxy->releaseBuffer(). Also note there is no mutual exclusion in the
61727876c02c21cd3ab7ef01bdd1fc5400c5143584aAndy Hung// AudioTrackServerProxy so be especially careful calling with FastTracks.
61881784c37c61b09289654b979567a42bf73cd2b12Eric Laurentsize_t AudioFlinger::PlaybackThread::Track::framesReady() const {
61927876c02c21cd3ab7ef01bdd1fc5400c5143584aAndy Hung    if (mSharedBuffer != 0 && (isStopped() || isStopping())) {
62027876c02c21cd3ab7ef01bdd1fc5400c5143584aAndy Hung        // Static tracks return zero frames immediately upon stopping (for FastTracks).
62127876c02c21cd3ab7ef01bdd1fc5400c5143584aAndy Hung        // The remainder of the buffer is not drained.
62227876c02c21cd3ab7ef01bdd1fc5400c5143584aAndy Hung        return 0;
62327876c02c21cd3ab7ef01bdd1fc5400c5143584aAndy Hung    }
6249f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    return mAudioTrackServerProxy->framesReady();
62581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
62681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
6276466c9e6e6278c740aed77f695f679be9f5db478Glenn Kastensize_t AudioFlinger::PlaybackThread::Track::framesReleased() const
6286466c9e6e6278c740aed77f695f679be9f5db478Glenn Kasten{
6296466c9e6e6278c740aed77f695f679be9f5db478Glenn Kasten    return mAudioTrackServerProxy->framesReleased();
6306466c9e6e6278c740aed77f695f679be9f5db478Glenn Kasten}
6316466c9e6e6278c740aed77f695f679be9f5db478Glenn Kasten
63281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// Don't call for fast tracks; the framesReady() could result in priority inversion
63381784c37c61b09289654b979567a42bf73cd2b12Eric Laurentbool AudioFlinger::PlaybackThread::Track::isReady() const {
6348d6c292a0bed3d63b5b7297d09a604af6327c663Krishnankutty Kolathappilly    if (mFillingUpStatus != FS_FILLING || isStopped() || isPausing()) {
6358d6c292a0bed3d63b5b7297d09a604af6327c663Krishnankutty Kolathappilly        return true;
6368d6c292a0bed3d63b5b7297d09a604af6327c663Krishnankutty Kolathappilly    }
6378d6c292a0bed3d63b5b7297d09a604af6327c663Krishnankutty Kolathappilly
638164985121796cf214c7a83d32005d9b01125b558Eric Laurent    if (isStopping()) {
639164985121796cf214c7a83d32005d9b01125b558Eric Laurent        if (framesReady() > 0) {
640164985121796cf214c7a83d32005d9b01125b558Eric Laurent            mFillingUpStatus = FS_FILLED;
641164985121796cf214c7a83d32005d9b01125b558Eric Laurent        }
64281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        return true;
64381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    }
64481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
64581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    if (framesReady() >= mFrameCount ||
64696f60d8f04432a1ed503b3e24d5736d28c63c9a2Glenn Kasten            (mCblk->mFlags & CBLK_FORCEREADY)) {
64781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        mFillingUpStatus = FS_FILLED;
64896f60d8f04432a1ed503b3e24d5736d28c63c9a2Glenn Kasten        android_atomic_and(~CBLK_FORCEREADY, &mCblk->mFlags);
64981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        return true;
65081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    }
65181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    return false;
65281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
65381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
6540f11b51a57bc9062c4fe8af73747319cedabc5d6Glenn Kastenstatus_t AudioFlinger::PlaybackThread::Track::start(AudioSystem::sync_event_t event __unused,
6550f11b51a57bc9062c4fe8af73747319cedabc5d6Glenn Kasten                                                    int triggerSession __unused)
65681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{
65781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    status_t status = NO_ERROR;
65881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    ALOGV("start(%d), calling pid %d session %d",
65981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            mName, IPCThreadState::self()->getCallingPid(), mSessionId);
66081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
66181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    sp<ThreadBase> thread = mThread.promote();
66281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    if (thread != 0) {
663813e2a74853bde19e37d878c596a044b3f299efcEric Laurent        if (isOffloaded()) {
664813e2a74853bde19e37d878c596a044b3f299efcEric Laurent            Mutex::Autolock _laf(thread->mAudioFlinger->mLock);
665813e2a74853bde19e37d878c596a044b3f299efcEric Laurent            Mutex::Autolock _lth(thread->mLock);
666813e2a74853bde19e37d878c596a044b3f299efcEric Laurent            sp<EffectChain> ec = thread->getEffectChain_l(mSessionId);
6675baf2af52cd186633b7173196c1e4a4cd3435f22Eric Laurent            if (thread->mAudioFlinger->isNonOffloadableGlobalEffectEnabled_l() ||
6685baf2af52cd186633b7173196c1e4a4cd3435f22Eric Laurent                    (ec != 0 && ec->isNonOffloadableEnabled())) {
669813e2a74853bde19e37d878c596a044b3f299efcEric Laurent                invalidate();
670813e2a74853bde19e37d878c596a044b3f299efcEric Laurent                return PERMISSION_DENIED;
671813e2a74853bde19e37d878c596a044b3f299efcEric Laurent            }
672813e2a74853bde19e37d878c596a044b3f299efcEric Laurent        }
673813e2a74853bde19e37d878c596a044b3f299efcEric Laurent        Mutex::Autolock _lth(thread->mLock);
67481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        track_state state = mState;
67581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        // here the track could be either new, or restarted
67681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        // in both cases "unstop" the track
677bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent
6788d6c292a0bed3d63b5b7297d09a604af6327c663Krishnankutty Kolathappilly        // initial state-stopping. next state-pausing.
6798d6c292a0bed3d63b5b7297d09a604af6327c663Krishnankutty Kolathappilly        // What if resume is called ?
6808d6c292a0bed3d63b5b7297d09a604af6327c663Krishnankutty Kolathappilly
6818d6c292a0bed3d63b5b7297d09a604af6327c663Krishnankutty Kolathappilly        if (state == PAUSED || state == PAUSING) {
682bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent            if (mResumeToStopping) {
683bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent                // happened we need to resume to STOPPING_1
684bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent                mState = TrackBase::STOPPING_1;
685bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent                ALOGV("PAUSED => STOPPING_1 (%d) on thread %p", mName, this);
686bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent            } else {
687bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent                mState = TrackBase::RESUMING;
688bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent                ALOGV("PAUSED => RESUMING (%d) on thread %p", mName, this);
689bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent            }
69081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        } else {
69181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            mState = TrackBase::ACTIVE;
69281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            ALOGV("? => ACTIVE (%d) on thread %p", mName, this);
69381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        }
69481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
695bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent        PlaybackThread *playbackThread = (PlaybackThread *)thread.get();
696bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent        status = playbackThread->addTrack_l(this);
697bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent        if (status == INVALID_OPERATION || status == PERMISSION_DENIED) {
698bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent            triggerEvents(AudioSystem::SYNC_EVENT_PRESENTATION_COMPLETE);
699bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent            //  restore previous state if start was rejected by policy manager
700bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent            if (status == PERMISSION_DENIED) {
701bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent                mState = state;
70281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            }
70381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        }
704bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent        // track was already in the active list, not a problem
705bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent        if (status == ALREADY_EXISTS) {
706bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent            status = NO_ERROR;
70712022ff8d223ccf4dfae019c81e4a93a3f44985cGlenn Kasten        } else {
70812022ff8d223ccf4dfae019c81e4a93a3f44985cGlenn Kasten            // Acknowledge any pending flush(), so that subsequent new data isn't discarded.
70912022ff8d223ccf4dfae019c81e4a93a3f44985cGlenn Kasten            // It is usually unsafe to access the server proxy from a binder thread.
71012022ff8d223ccf4dfae019c81e4a93a3f44985cGlenn Kasten            // But in this case we know the mixer thread (whether normal mixer or fast mixer)
71112022ff8d223ccf4dfae019c81e4a93a3f44985cGlenn Kasten            // isn't looking at this track yet:  we still hold the normal mixer thread lock,
71212022ff8d223ccf4dfae019c81e4a93a3f44985cGlenn Kasten            // and for fast tracks the track is not yet in the fast mixer thread's active set.
71312022ff8d223ccf4dfae019c81e4a93a3f44985cGlenn Kasten            ServerProxy::Buffer buffer;
71412022ff8d223ccf4dfae019c81e4a93a3f44985cGlenn Kasten            buffer.mFrameCount = 1;
7152e422c472c91aa7912befd0fc038d1e11f354bc1Glenn Kasten            (void) mAudioTrackServerProxy->obtainBuffer(&buffer, true /*ackFlush*/);
71681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        }
71781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    } else {
71881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        status = BAD_VALUE;
71981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    }
72081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    return status;
72181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
72281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
72381784c37c61b09289654b979567a42bf73cd2b12Eric Laurentvoid AudioFlinger::PlaybackThread::Track::stop()
72481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{
72581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    ALOGV("stop(%d), calling pid %d", mName, IPCThreadState::self()->getCallingPid());
72681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    sp<ThreadBase> thread = mThread.promote();
72781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    if (thread != 0) {
72881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        Mutex::Autolock _l(thread->mLock);
72981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        track_state state = mState;
73081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        if (state == RESUMING || state == ACTIVE || state == PAUSING || state == PAUSED) {
73181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            // If the track is not active (PAUSED and buffers full), flush buffers
73281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            PlaybackThread *playbackThread = (PlaybackThread *)thread.get();
73381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            if (playbackThread->mActiveTracks.indexOf(this) < 0) {
73481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                reset();
73581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                mState = STOPPED;
736ab5cdbaf65ca509681d2726aacdf3ac8bfb6b3faEric Laurent            } else if (!isFastTrack() && !isOffloaded() && !isDirect()) {
73781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                mState = STOPPED;
73881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            } else {
739bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent                // For fast tracks prepareTracks_l() will set state to STOPPING_2
740bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent                // presentation is complete
741bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent                // For an offloaded track this starts a drain and state will
742bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent                // move to STOPPING_2 when drain completes and then STOPPED
74381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                mState = STOPPING_1;
74481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            }
74581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            ALOGV("not stopping/stopped => stopping/stopped (%d) on thread %p", mName,
74681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                    playbackThread);
74781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        }
74881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    }
74981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
75081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
75181784c37c61b09289654b979567a42bf73cd2b12Eric Laurentvoid AudioFlinger::PlaybackThread::Track::pause()
75281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{
75381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    ALOGV("pause(%d), calling pid %d", mName, IPCThreadState::self()->getCallingPid());
75481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    sp<ThreadBase> thread = mThread.promote();
75581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    if (thread != 0) {
75681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        Mutex::Autolock _l(thread->mLock);
757bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent        PlaybackThread *playbackThread = (PlaybackThread *)thread.get();
758bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent        switch (mState) {
759bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent        case STOPPING_1:
760bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent        case STOPPING_2:
761bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent            if (!isOffloaded()) {
762bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent                /* nothing to do if track is not offloaded */
763bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent                break;
764bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent            }
765bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent
766bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent            // Offloaded track was draining, we need to carry on draining when resumed
767bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent            mResumeToStopping = true;
768bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent            // fall through...
769bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent        case ACTIVE:
770bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent        case RESUMING:
77181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            mState = PAUSING;
77281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            ALOGV("ACTIVE/RESUMING => PAUSING (%d) on thread %p", mName, thread.get());
773ede6c3b8b1147bc425f7b923882f559a513fe23bEric Laurent            playbackThread->broadcast_l();
774bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent            break;
775bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent
776bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent        default:
777bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent            break;
77881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        }
77981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    }
78081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
78181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
78281784c37c61b09289654b979567a42bf73cd2b12Eric Laurentvoid AudioFlinger::PlaybackThread::Track::flush()
78381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{
78481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    ALOGV("flush(%d)", mName);
78581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    sp<ThreadBase> thread = mThread.promote();
78681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    if (thread != 0) {
78781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        Mutex::Autolock _l(thread->mLock);
78881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        PlaybackThread *playbackThread = (PlaybackThread *)thread.get();
789bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent
790bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent        if (isOffloaded()) {
791bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent            // If offloaded we allow flush during any state except terminated
792bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent            // and keep the track active to avoid problems if user is seeking
793bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent            // rapidly and underlying hardware has a significant delay handling
794bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent            // a pause
795bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent            if (isTerminated()) {
796bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent                return;
797bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent            }
798bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent
799bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent            ALOGV("flush: offload flush");
80081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            reset();
801bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent
802bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent            if (mState == STOPPING_1 || mState == STOPPING_2) {
803bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent                ALOGV("flushed in STOPPING_1 or 2 state, change state to ACTIVE");
804bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent                mState = ACTIVE;
805bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent            }
806bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent
807bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent            if (mState == ACTIVE) {
808bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent                ALOGV("flush called in active state, resetting buffer time out retry count");
809bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent                mRetryCount = PlaybackThread::kMaxTrackRetriesOffload;
810bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent            }
811bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent
8127844f679be8d94c5cdf017f53754cb68ee2f00daHaynes Mathew George            mFlushHwPending = true;
813bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent            mResumeToStopping = false;
814bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent        } else {
815bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent            if (mState != STOPPING_1 && mState != STOPPING_2 && mState != STOPPED &&
816bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent                    mState != PAUSED && mState != PAUSING && mState != IDLE && mState != FLUSHED) {
817bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent                return;
818bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent            }
819bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent            // No point remaining in PAUSED state after a flush => go to
820bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent            // FLUSHED state
821bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent            mState = FLUSHED;
822bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent            // do not reset the track if it is still in the process of being stopped or paused.
823bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent            // this will be done by prepareTracks_l() when the track is stopped.
824bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent            // prepareTracks_l() will see mState == FLUSHED, then
825bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent            // remove from active track list, reset(), and trigger presentation complete
826d1f69b0b17acbd96987ecb2f3378abd394d05903Eric Laurent            if (isDirect()) {
827d1f69b0b17acbd96987ecb2f3378abd394d05903Eric Laurent                mFlushHwPending = true;
828d1f69b0b17acbd96987ecb2f3378abd394d05903Eric Laurent            }
829bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent            if (playbackThread->mActiveTracks.indexOf(this) < 0) {
830bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent                reset();
831bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent            }
83281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        }
833bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent        // Prevent flush being lost if the track is flushed and then resumed
834bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent        // before mixer thread can run. This is important when offloading
835bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent        // because the hardware buffer could hold a large amount of audio
836ede6c3b8b1147bc425f7b923882f559a513fe23bEric Laurent        playbackThread->broadcast_l();
83781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    }
83881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
83981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
8407844f679be8d94c5cdf017f53754cb68ee2f00daHaynes Mathew George// must be called with thread lock held
8417844f679be8d94c5cdf017f53754cb68ee2f00daHaynes Mathew Georgevoid AudioFlinger::PlaybackThread::Track::flushAck()
8427844f679be8d94c5cdf017f53754cb68ee2f00daHaynes Mathew George{
843d1f69b0b17acbd96987ecb2f3378abd394d05903Eric Laurent    if (!isOffloaded() && !isDirect())
8447844f679be8d94c5cdf017f53754cb68ee2f00daHaynes Mathew George        return;
8457844f679be8d94c5cdf017f53754cb68ee2f00daHaynes Mathew George
8467844f679be8d94c5cdf017f53754cb68ee2f00daHaynes Mathew George    mFlushHwPending = false;
8477844f679be8d94c5cdf017f53754cb68ee2f00daHaynes Mathew George}
8487844f679be8d94c5cdf017f53754cb68ee2f00daHaynes Mathew George
84981784c37c61b09289654b979567a42bf73cd2b12Eric Laurentvoid AudioFlinger::PlaybackThread::Track::reset()
85081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{
85181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    // Do not reset twice to avoid discarding data written just after a flush and before
85281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    // the audioflinger thread detects the track is stopped.
85381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    if (!mResetDone) {
85481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        // Force underrun condition to avoid false underrun callback until first data is
85581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        // written to buffer
85696f60d8f04432a1ed503b3e24d5736d28c63c9a2Glenn Kasten        android_atomic_and(~CBLK_FORCEREADY, &mCblk->mFlags);
85781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        mFillingUpStatus = FS_FILLING;
85881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        mResetDone = true;
85981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        if (mState == FLUSHED) {
86081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            mState = IDLE;
86181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        }
86281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    }
86381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
86481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
865bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurentstatus_t AudioFlinger::PlaybackThread::Track::setParameters(const String8& keyValuePairs)
866bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent{
867bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent    sp<ThreadBase> thread = mThread.promote();
868bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent    if (thread == 0) {
869bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent        ALOGE("thread is dead");
870bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent        return FAILED_TRANSACTION;
871bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent    } else if ((thread->type() == ThreadBase::DIRECT) ||
872bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent                    (thread->type() == ThreadBase::OFFLOAD)) {
873bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent        return thread->setParameters(keyValuePairs);
874bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent    } else {
875bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent        return PERMISSION_DENIED;
876bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent    }
877bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent}
878bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent
879573d80a8f463f648a515fc0975bf83951b272993Glenn Kastenstatus_t AudioFlinger::PlaybackThread::Track::getTimestamp(AudioTimestamp& timestamp)
880573d80a8f463f648a515fc0975bf83951b272993Glenn Kasten{
881fe346c707f59d763ded93bc3d27b51f0c0408258Glenn Kasten    // Client should implement this using SSQ; the unpresented frame count in latch is irrelevant
882fe346c707f59d763ded93bc3d27b51f0c0408258Glenn Kasten    if (isFastTrack()) {
883ced6e74215937182fe2f9f6b0867f7c28ccd02c1Glenn Kasten        // FIXME no lock held to set mPreviousValid = false
884fe346c707f59d763ded93bc3d27b51f0c0408258Glenn Kasten        return INVALID_OPERATION;
885fe346c707f59d763ded93bc3d27b51f0c0408258Glenn Kasten    }
886573d80a8f463f648a515fc0975bf83951b272993Glenn Kasten    sp<ThreadBase> thread = mThread.promote();
887573d80a8f463f648a515fc0975bf83951b272993Glenn Kasten    if (thread == 0) {
888ced6e74215937182fe2f9f6b0867f7c28ccd02c1Glenn Kasten        // FIXME no lock held to set mPreviousValid = false
889fe346c707f59d763ded93bc3d27b51f0c0408258Glenn Kasten        return INVALID_OPERATION;
890573d80a8f463f648a515fc0975bf83951b272993Glenn Kasten    }
891573d80a8f463f648a515fc0975bf83951b272993Glenn Kasten    Mutex::Autolock _l(thread->mLock);
892573d80a8f463f648a515fc0975bf83951b272993Glenn Kasten    PlaybackThread *playbackThread = (PlaybackThread *)thread.get();
893ab5cdbaf65ca509681d2726aacdf3ac8bfb6b3faEric Laurent    if (!isOffloaded() && !isDirect()) {
894accc147666bfd37fc8b4ef745f18a8c751555ec2Eric Laurent        if (!playbackThread->mLatchQValid) {
895ced6e74215937182fe2f9f6b0867f7c28ccd02c1Glenn Kasten            mPreviousValid = false;
896accc147666bfd37fc8b4ef745f18a8c751555ec2Eric Laurent            return INVALID_OPERATION;
897accc147666bfd37fc8b4ef745f18a8c751555ec2Eric Laurent        }
898accc147666bfd37fc8b4ef745f18a8c751555ec2Eric Laurent        uint32_t unpresentedFrames =
899accc147666bfd37fc8b4ef745f18a8c751555ec2Eric Laurent                ((int64_t) playbackThread->mLatchQ.mUnpresentedFrames * mSampleRate) /
900accc147666bfd37fc8b4ef745f18a8c751555ec2Eric Laurent                playbackThread->mSampleRate;
9014c053ea158b29fa2cdd4c6f39d3c8da4ee5a7a02Glenn Kasten        // FIXME Since we're using a raw pointer as the key, it is theoretically possible
9024c053ea158b29fa2cdd4c6f39d3c8da4ee5a7a02Glenn Kasten        //       for a brand new track to share the same address as a recently destroyed
9034c053ea158b29fa2cdd4c6f39d3c8da4ee5a7a02Glenn Kasten        //       track, and thus for us to get the frames released of the wrong track.
9044c053ea158b29fa2cdd4c6f39d3c8da4ee5a7a02Glenn Kasten        //       It is unlikely that we would be able to call getTimestamp() so quickly
9054c053ea158b29fa2cdd4c6f39d3c8da4ee5a7a02Glenn Kasten        //       right after creating a new track.  Nevertheless, the index here should
9064c053ea158b29fa2cdd4c6f39d3c8da4ee5a7a02Glenn Kasten        //       be changed to something that is unique.  Or use a completely different strategy.
9074c053ea158b29fa2cdd4c6f39d3c8da4ee5a7a02Glenn Kasten        ssize_t i = playbackThread->mLatchQ.mFramesReleased.indexOfKey(this);
9084c053ea158b29fa2cdd4c6f39d3c8da4ee5a7a02Glenn Kasten        uint32_t framesWritten = i >= 0 ?
9094c053ea158b29fa2cdd4c6f39d3c8da4ee5a7a02Glenn Kasten                playbackThread->mLatchQ.mFramesReleased[i] :
9104c053ea158b29fa2cdd4c6f39d3c8da4ee5a7a02Glenn Kasten                mAudioTrackServerProxy->framesReleased();
911ced6e74215937182fe2f9f6b0867f7c28ccd02c1Glenn Kasten        bool checkPreviousTimestamp = mPreviousValid && framesWritten >= mPreviousFramesWritten;
912accc147666bfd37fc8b4ef745f18a8c751555ec2Eric Laurent        if (framesWritten < unpresentedFrames) {
913ced6e74215937182fe2f9f6b0867f7c28ccd02c1Glenn Kasten            mPreviousValid = false;
914accc147666bfd37fc8b4ef745f18a8c751555ec2Eric Laurent            return INVALID_OPERATION;
915accc147666bfd37fc8b4ef745f18a8c751555ec2Eric Laurent        }
916ced6e74215937182fe2f9f6b0867f7c28ccd02c1Glenn Kasten        mPreviousFramesWritten = framesWritten;
917ced6e74215937182fe2f9f6b0867f7c28ccd02c1Glenn Kasten        uint32_t position = framesWritten - unpresentedFrames;
918ced6e74215937182fe2f9f6b0867f7c28ccd02c1Glenn Kasten        struct timespec time = playbackThread->mLatchQ.mTimestamp.mTime;
919ced6e74215937182fe2f9f6b0867f7c28ccd02c1Glenn Kasten        if (checkPreviousTimestamp) {
920ced6e74215937182fe2f9f6b0867f7c28ccd02c1Glenn Kasten            if (time.tv_sec < mPreviousTimestamp.mTime.tv_sec ||
921ced6e74215937182fe2f9f6b0867f7c28ccd02c1Glenn Kasten                    (time.tv_sec == mPreviousTimestamp.mTime.tv_sec &&
922ced6e74215937182fe2f9f6b0867f7c28ccd02c1Glenn Kasten                    time.tv_nsec < mPreviousTimestamp.mTime.tv_nsec)) {
923ced6e74215937182fe2f9f6b0867f7c28ccd02c1Glenn Kasten                ALOGW("Time is going backwards");
924ced6e74215937182fe2f9f6b0867f7c28ccd02c1Glenn Kasten            }
925ced6e74215937182fe2f9f6b0867f7c28ccd02c1Glenn Kasten            // position can bobble slightly as an artifact; this hides the bobble
926ced6e74215937182fe2f9f6b0867f7c28ccd02c1Glenn Kasten            static const uint32_t MINIMUM_POSITION_DELTA = 8u;
927ced6e74215937182fe2f9f6b0867f7c28ccd02c1Glenn Kasten            if ((position <= mPreviousTimestamp.mPosition) ||
928ced6e74215937182fe2f9f6b0867f7c28ccd02c1Glenn Kasten                    (position - mPreviousTimestamp.mPosition) < MINIMUM_POSITION_DELTA) {
929ced6e74215937182fe2f9f6b0867f7c28ccd02c1Glenn Kasten                position = mPreviousTimestamp.mPosition;
930ced6e74215937182fe2f9f6b0867f7c28ccd02c1Glenn Kasten                time = mPreviousTimestamp.mTime;
931ced6e74215937182fe2f9f6b0867f7c28ccd02c1Glenn Kasten            }
932ced6e74215937182fe2f9f6b0867f7c28ccd02c1Glenn Kasten        }
933ced6e74215937182fe2f9f6b0867f7c28ccd02c1Glenn Kasten        timestamp.mPosition = position;
934ced6e74215937182fe2f9f6b0867f7c28ccd02c1Glenn Kasten        timestamp.mTime = time;
935ced6e74215937182fe2f9f6b0867f7c28ccd02c1Glenn Kasten        mPreviousTimestamp = timestamp;
936ced6e74215937182fe2f9f6b0867f7c28ccd02c1Glenn Kasten        mPreviousValid = true;
937accc147666bfd37fc8b4ef745f18a8c751555ec2Eric Laurent        return NO_ERROR;
938bd096fd9d8e5fc0e62f98807f4818a06f70d0812Glenn Kasten    }
939accc147666bfd37fc8b4ef745f18a8c751555ec2Eric Laurent
940accc147666bfd37fc8b4ef745f18a8c751555ec2Eric Laurent    return playbackThread->getTimestamp_l(timestamp);
941573d80a8f463f648a515fc0975bf83951b272993Glenn Kasten}
942573d80a8f463f648a515fc0975bf83951b272993Glenn Kasten
94381784c37c61b09289654b979567a42bf73cd2b12Eric Laurentstatus_t AudioFlinger::PlaybackThread::Track::attachAuxEffect(int EffectId)
94481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{
94581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    status_t status = DEAD_OBJECT;
94681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    sp<ThreadBase> thread = mThread.promote();
94781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    if (thread != 0) {
94881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        PlaybackThread *playbackThread = (PlaybackThread *)thread.get();
94981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        sp<AudioFlinger> af = mClient->audioFlinger();
95081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
95181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        Mutex::Autolock _l(af->mLock);
95281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
95381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        sp<PlaybackThread> srcThread = af->getEffectThread_l(AUDIO_SESSION_OUTPUT_MIX, EffectId);
95481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
95581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        if (EffectId != 0 && srcThread != 0 && playbackThread != srcThread.get()) {
95681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            Mutex::Autolock _dl(playbackThread->mLock);
95781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            Mutex::Autolock _sl(srcThread->mLock);
95881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            sp<EffectChain> chain = srcThread->getEffectChain_l(AUDIO_SESSION_OUTPUT_MIX);
95981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            if (chain == 0) {
96081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                return INVALID_OPERATION;
96181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            }
96281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
96381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            sp<EffectModule> effect = chain->getEffectFromId_l(EffectId);
96481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            if (effect == 0) {
96581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                return INVALID_OPERATION;
96681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            }
96781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            srcThread->removeEffect_l(effect);
9685baf2af52cd186633b7173196c1e4a4cd3435f22Eric Laurent            status = playbackThread->addEffect_l(effect);
9695baf2af52cd186633b7173196c1e4a4cd3435f22Eric Laurent            if (status != NO_ERROR) {
9705baf2af52cd186633b7173196c1e4a4cd3435f22Eric Laurent                srcThread->addEffect_l(effect);
9715baf2af52cd186633b7173196c1e4a4cd3435f22Eric Laurent                return INVALID_OPERATION;
9725baf2af52cd186633b7173196c1e4a4cd3435f22Eric Laurent            }
97381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            // removeEffect_l() has stopped the effect if it was active so it must be restarted
97481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            if (effect->state() == EffectModule::ACTIVE ||
97581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                    effect->state() == EffectModule::STOPPING) {
97681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                effect->start();
97781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            }
97881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
97981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            sp<EffectChain> dstChain = effect->chain().promote();
98081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            if (dstChain == 0) {
98181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                srcThread->addEffect_l(effect);
98281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                return INVALID_OPERATION;
98381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            }
98481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            AudioSystem::unregisterEffect(effect->id());
98581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            AudioSystem::registerEffect(&effect->desc(),
98681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                                        srcThread->id(),
98781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                                        dstChain->strategy(),
98881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                                        AUDIO_SESSION_OUTPUT_MIX,
98981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                                        effect->id());
990d72b7c0180ee83fc3754629ed68fc5887a125c4cEric Laurent            AudioSystem::setEffectEnabled(effect->id(), effect->isEnabled());
99181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        }
99281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        status = playbackThread->attachAuxEffect(this, EffectId);
99381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    }
99481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    return status;
99581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
99681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
99781784c37c61b09289654b979567a42bf73cd2b12Eric Laurentvoid AudioFlinger::PlaybackThread::Track::setAuxBuffer(int EffectId, int32_t *buffer)
99881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{
99981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    mAuxEffectId = EffectId;
100081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    mAuxBuffer = buffer;
100181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
100281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
100381784c37c61b09289654b979567a42bf73cd2b12Eric Laurentbool AudioFlinger::PlaybackThread::Track::presentationComplete(size_t framesWritten,
100481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                                                         size_t audioHalFrames)
100581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{
100681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    // a track is considered presented when the total number of frames written to audio HAL
100781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    // corresponds to the number of frames written when presentationComplete() is called for the
100881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    // first time (mPresentationCompleteFrames == 0) plus the buffer filling status at that time.
1009bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent    // For an offloaded track the HAL+h/w delay is variable so a HAL drain() is used
1010bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent    // to detect when all frames have been played. In this case framesWritten isn't
1011bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent    // useful because it doesn't always reflect whether there is data in the h/w
1012bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent    // buffers, particularly if a track has been paused and resumed during draining
1013bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent    ALOGV("presentationComplete() mPresentationCompleteFrames %d framesWritten %d",
1014bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent                      mPresentationCompleteFrames, framesWritten);
101581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    if (mPresentationCompleteFrames == 0) {
101681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        mPresentationCompleteFrames = framesWritten + audioHalFrames;
101781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        ALOGV("presentationComplete() reset: mPresentationCompleteFrames %d audioHalFrames %d",
101881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                  mPresentationCompleteFrames, audioHalFrames);
101981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    }
1020bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent
1021bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent    if (framesWritten >= mPresentationCompleteFrames || isOffloaded()) {
102281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        triggerEvents(AudioSystem::SYNC_EVENT_PRESENTATION_COMPLETE);
1023bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent        mAudioTrackServerProxy->setStreamEndDone();
102481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        return true;
102581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    }
102681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    return false;
102781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
102881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
102981784c37c61b09289654b979567a42bf73cd2b12Eric Laurentvoid AudioFlinger::PlaybackThread::Track::triggerEvents(AudioSystem::sync_event_t type)
103081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{
10313ab368e0810d894dcbc0971350c095049478a055Mark Salyzyn    for (size_t i = 0; i < mSyncEvents.size(); i++) {
103281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        if (mSyncEvents[i]->type() == type) {
103381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            mSyncEvents[i]->trigger();
103481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            mSyncEvents.removeAt(i);
103581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            i--;
103681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        }
103781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    }
103881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
103981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
104081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// implement VolumeBufferProvider interface
104181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
1042c56f3426099a3cf2d07ccff8886050c7fbce140fGlenn Kastengain_minifloat_packed_t AudioFlinger::PlaybackThread::Track::getVolumeLR()
104381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{
104481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    // called by FastMixer, so not allowed to take any locks, block, or do I/O including logs
104581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    ALOG_ASSERT(isFastTrack() && (mCblk != NULL));
1046c56f3426099a3cf2d07ccff8886050c7fbce140fGlenn Kasten    gain_minifloat_packed_t vlr = mAudioTrackServerProxy->getVolumeLR();
1047c56f3426099a3cf2d07ccff8886050c7fbce140fGlenn Kasten    float vl = float_from_gain(gain_minifloat_unpack_left(vlr));
1048c56f3426099a3cf2d07ccff8886050c7fbce140fGlenn Kasten    float vr = float_from_gain(gain_minifloat_unpack_right(vlr));
104981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    // track volumes come from shared memory, so can't be trusted and must be clamped
1050c56f3426099a3cf2d07ccff8886050c7fbce140fGlenn Kasten    if (vl > GAIN_FLOAT_UNITY) {
1051c56f3426099a3cf2d07ccff8886050c7fbce140fGlenn Kasten        vl = GAIN_FLOAT_UNITY;
105281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    }
1053c56f3426099a3cf2d07ccff8886050c7fbce140fGlenn Kasten    if (vr > GAIN_FLOAT_UNITY) {
1054c56f3426099a3cf2d07ccff8886050c7fbce140fGlenn Kasten        vr = GAIN_FLOAT_UNITY;
105581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    }
105681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    // now apply the cached master volume and stream type volume;
105781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    // this is trusted but lacks any synchronization or barrier so may be stale
105881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    float v = mCachedVolume;
105981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    vl *= v;
106081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    vr *= v;
1061c56f3426099a3cf2d07ccff8886050c7fbce140fGlenn Kasten    // re-combine into packed minifloat
1062c56f3426099a3cf2d07ccff8886050c7fbce140fGlenn Kasten    vlr = gain_minifloat_pack(gain_from_float(vl), gain_from_float(vr));
106381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    // FIXME look at mute, pause, and stop flags
106481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    return vlr;
106581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
106681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
106781784c37c61b09289654b979567a42bf73cd2b12Eric Laurentstatus_t AudioFlinger::PlaybackThread::Track::setSyncEvent(const sp<SyncEvent>& event)
106881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{
1069bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent    if (isTerminated() || mState == PAUSED ||
107081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            ((framesReady() == 0) && ((mSharedBuffer != 0) ||
107181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                                      (mState == STOPPED)))) {
107281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        ALOGW("Track::setSyncEvent() in invalid state %d on session %d %s mode, framesReady %d ",
107381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent              mState, mSessionId, (mSharedBuffer != 0) ? "static" : "stream", framesReady());
107481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        event->cancel();
107581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        return INVALID_OPERATION;
107681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    }
107781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    (void) TrackBase::setSyncEvent(event);
107881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    return NO_ERROR;
107981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
108081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
10815736c35b841de56ce394b4879389f669b61425e6Glenn Kastenvoid AudioFlinger::PlaybackThread::Track::invalidate()
10825736c35b841de56ce394b4879389f669b61425e6Glenn Kasten{
10839f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    // FIXME should use proxy, and needs work
10849f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    audio_track_cblk_t* cblk = mCblk;
108596f60d8f04432a1ed503b3e24d5736d28c63c9a2Glenn Kasten    android_atomic_or(CBLK_INVALID, &cblk->mFlags);
10869f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    android_atomic_release_store(0x40000000, &cblk->mFutex);
10879f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    // client is not in server, so FUTEX_WAKE is needed instead of FUTEX_WAKE_PRIVATE
1088ee499291404a192b059f2e04c5afc65aa6cdd74cElliott Hughes    (void) syscall(__NR_futex, &cblk->mFutex, FUTEX_WAKE, INT_MAX);
10895736c35b841de56ce394b4879389f669b61425e6Glenn Kasten    mIsInvalid = true;
10905736c35b841de56ce394b4879389f669b61425e6Glenn Kasten}
10915736c35b841de56ce394b4879389f669b61425e6Glenn Kasten
109259fe010bcc072597852454a2ec53d7b0a2002a3bEric Laurentvoid AudioFlinger::PlaybackThread::Track::signal()
109359fe010bcc072597852454a2ec53d7b0a2002a3bEric Laurent{
109459fe010bcc072597852454a2ec53d7b0a2002a3bEric Laurent    sp<ThreadBase> thread = mThread.promote();
109559fe010bcc072597852454a2ec53d7b0a2002a3bEric Laurent    if (thread != 0) {
109659fe010bcc072597852454a2ec53d7b0a2002a3bEric Laurent        PlaybackThread *t = (PlaybackThread *)thread.get();
109759fe010bcc072597852454a2ec53d7b0a2002a3bEric Laurent        Mutex::Autolock _l(t->mLock);
109859fe010bcc072597852454a2ec53d7b0a2002a3bEric Laurent        t->broadcast_l();
109959fe010bcc072597852454a2ec53d7b0a2002a3bEric Laurent    }
110059fe010bcc072597852454a2ec53d7b0a2002a3bEric Laurent}
110159fe010bcc072597852454a2ec53d7b0a2002a3bEric Laurent
11028d6c292a0bed3d63b5b7297d09a604af6327c663Krishnankutty Kolathappilly//To be called with thread lock held
11038d6c292a0bed3d63b5b7297d09a604af6327c663Krishnankutty Kolathappillybool AudioFlinger::PlaybackThread::Track::isResumePending() {
11048d6c292a0bed3d63b5b7297d09a604af6327c663Krishnankutty Kolathappilly
11058d6c292a0bed3d63b5b7297d09a604af6327c663Krishnankutty Kolathappilly    if (mState == RESUMING)
11068d6c292a0bed3d63b5b7297d09a604af6327c663Krishnankutty Kolathappilly        return true;
11078d6c292a0bed3d63b5b7297d09a604af6327c663Krishnankutty Kolathappilly    /* Resume is pending if track was stopping before pause was called */
11088d6c292a0bed3d63b5b7297d09a604af6327c663Krishnankutty Kolathappilly    if (mState == STOPPING_1 &&
11098d6c292a0bed3d63b5b7297d09a604af6327c663Krishnankutty Kolathappilly        mResumeToStopping)
11108d6c292a0bed3d63b5b7297d09a604af6327c663Krishnankutty Kolathappilly        return true;
11118d6c292a0bed3d63b5b7297d09a604af6327c663Krishnankutty Kolathappilly
11128d6c292a0bed3d63b5b7297d09a604af6327c663Krishnankutty Kolathappilly    return false;
11138d6c292a0bed3d63b5b7297d09a604af6327c663Krishnankutty Kolathappilly}
11148d6c292a0bed3d63b5b7297d09a604af6327c663Krishnankutty Kolathappilly
11158d6c292a0bed3d63b5b7297d09a604af6327c663Krishnankutty Kolathappilly//To be called with thread lock held
11168d6c292a0bed3d63b5b7297d09a604af6327c663Krishnankutty Kolathappillyvoid AudioFlinger::PlaybackThread::Track::resumeAck() {
11178d6c292a0bed3d63b5b7297d09a604af6327c663Krishnankutty Kolathappilly
11188d6c292a0bed3d63b5b7297d09a604af6327c663Krishnankutty Kolathappilly
11198d6c292a0bed3d63b5b7297d09a604af6327c663Krishnankutty Kolathappilly    if (mState == RESUMING)
11208d6c292a0bed3d63b5b7297d09a604af6327c663Krishnankutty Kolathappilly        mState = ACTIVE;
11212d3ca68363f723fbe269d3ce52dab4985dfc7154Haynes Mathew George
11228d6c292a0bed3d63b5b7297d09a604af6327c663Krishnankutty Kolathappilly    // Other possibility of  pending resume is stopping_1 state
11238d6c292a0bed3d63b5b7297d09a604af6327c663Krishnankutty Kolathappilly    // Do not update the state from stopping as this prevents
11242d3ca68363f723fbe269d3ce52dab4985dfc7154Haynes Mathew George    // drain being called.
11252d3ca68363f723fbe269d3ce52dab4985dfc7154Haynes Mathew George    if (mState == STOPPING_1) {
11262d3ca68363f723fbe269d3ce52dab4985dfc7154Haynes Mathew George        mResumeToStopping = false;
11272d3ca68363f723fbe269d3ce52dab4985dfc7154Haynes Mathew George    }
11288d6c292a0bed3d63b5b7297d09a604af6327c663Krishnankutty Kolathappilly}
112981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// ----------------------------------------------------------------------------
113081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
113181784c37c61b09289654b979567a42bf73cd2b12Eric Laurentsp<AudioFlinger::PlaybackThread::TimedTrack>
113281784c37c61b09289654b979567a42bf73cd2b12Eric LaurentAudioFlinger::PlaybackThread::TimedTrack::create(
113381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            PlaybackThread *thread,
113481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            const sp<Client>& client,
113581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            audio_stream_type_t streamType,
113681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            uint32_t sampleRate,
113781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            audio_format_t format,
113881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            audio_channel_mask_t channelMask,
113981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            size_t frameCount,
114081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            const sp<IMemory>& sharedBuffer,
1141462fd2fa9eef642b0574aa7409de0bde3fec8d43Marco Nelissen            int sessionId,
11424944acb7355b3aa25748fd25945a363a69d65444Glenn Kasten            int uid)
11434944acb7355b3aa25748fd25945a363a69d65444Glenn Kasten{
114481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    if (!client->reserveTimedTrack())
114581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        return 0;
114681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
114781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    return new TimedTrack(
114881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        thread, client, streamType, sampleRate, format, channelMask, frameCount,
1149462fd2fa9eef642b0574aa7409de0bde3fec8d43Marco Nelissen        sharedBuffer, sessionId, uid);
115081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
115181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
115281784c37c61b09289654b979567a42bf73cd2b12Eric LaurentAudioFlinger::PlaybackThread::TimedTrack::TimedTrack(
115381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            PlaybackThread *thread,
115481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            const sp<Client>& client,
115581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            audio_stream_type_t streamType,
115681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            uint32_t sampleRate,
115781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            audio_format_t format,
115881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            audio_channel_mask_t channelMask,
115981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            size_t frameCount,
116081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            const sp<IMemory>& sharedBuffer,
1161462fd2fa9eef642b0574aa7409de0bde3fec8d43Marco Nelissen            int sessionId,
1162462fd2fa9eef642b0574aa7409de0bde3fec8d43Marco Nelissen            int uid)
116381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    : Track(thread, client, streamType, sampleRate, format, channelMask,
116483b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent            frameCount, (sharedBuffer != 0) ? sharedBuffer->pointer() : NULL, sharedBuffer,
116583b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent                    sessionId, uid, IAudioFlinger::TRACK_TIMED, TYPE_TIMED),
116681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent      mQueueHeadInFlight(false),
116781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent      mTrimQueueHeadOnRelease(false),
116881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent      mFramesPendingInQueue(0),
116981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent      mTimedSilenceBuffer(NULL),
117081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent      mTimedSilenceBufferSize(0),
117181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent      mTimedAudioOutputOnTime(false),
117281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent      mMediaTimeTransformValid(false)
117381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{
117481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    LocalClock lc;
117581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    mLocalTimeFreq = lc.getLocalFreq();
117681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
117781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    mLocalTimeToSampleTransform.a_zero = 0;
117881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    mLocalTimeToSampleTransform.b_zero = 0;
117981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    mLocalTimeToSampleTransform.a_to_b_numer = sampleRate;
118081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    mLocalTimeToSampleTransform.a_to_b_denom = mLocalTimeFreq;
118181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    LinearTransform::reduce(&mLocalTimeToSampleTransform.a_to_b_numer,
118281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                            &mLocalTimeToSampleTransform.a_to_b_denom);
118381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
118481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    mMediaTimeToSampleTransform.a_zero = 0;
118581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    mMediaTimeToSampleTransform.b_zero = 0;
118681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    mMediaTimeToSampleTransform.a_to_b_numer = sampleRate;
118781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    mMediaTimeToSampleTransform.a_to_b_denom = 1000000;
118881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    LinearTransform::reduce(&mMediaTimeToSampleTransform.a_to_b_numer,
118981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                            &mMediaTimeToSampleTransform.a_to_b_denom);
119081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
119181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
119281784c37c61b09289654b979567a42bf73cd2b12Eric LaurentAudioFlinger::PlaybackThread::TimedTrack::~TimedTrack() {
119381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    mClient->releaseTimedTrack();
119481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    delete [] mTimedSilenceBuffer;
119581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
119681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
119781784c37c61b09289654b979567a42bf73cd2b12Eric Laurentstatus_t AudioFlinger::PlaybackThread::TimedTrack::allocateTimedBuffer(
119881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    size_t size, sp<IMemory>* buffer) {
119981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
120081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    Mutex::Autolock _l(mTimedBufferQueueLock);
120181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
120281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    trimTimedBufferQueue_l();
120381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
120481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    // lazily initialize the shared memory heap for timed buffers
120581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    if (mTimedMemoryDealer == NULL) {
120681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        const int kTimedBufferHeapSize = 512 << 10;
120781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
120881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        mTimedMemoryDealer = new MemoryDealer(kTimedBufferHeapSize,
120981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                                              "AudioFlingerTimed");
12106e2ebe97f2ad0a21907f20f9ee644c4eacbb7a40Glenn Kasten        if (mTimedMemoryDealer == NULL) {
121181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            return NO_MEMORY;
12126e2ebe97f2ad0a21907f20f9ee644c4eacbb7a40Glenn Kasten        }
121381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    }
121481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
121581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    sp<IMemory> newBuffer = mTimedMemoryDealer->allocate(size);
1216663c2247b71086e30bfd3192979d1dd7f15c539eGlenn Kasten    if (newBuffer == 0 || newBuffer->pointer() == NULL) {
121730ff92cba19c5acd747631365db1e1084e45ab34Glenn Kasten        return NO_MEMORY;
121881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    }
121981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
122081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    *buffer = newBuffer;
122181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    return NO_ERROR;
122281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
122381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
122481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// caller must hold mTimedBufferQueueLock
122581784c37c61b09289654b979567a42bf73cd2b12Eric Laurentvoid AudioFlinger::PlaybackThread::TimedTrack::trimTimedBufferQueue_l() {
122681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    int64_t mediaTimeNow;
122781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    {
122881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        Mutex::Autolock mttLock(mMediaTimeTransformLock);
122981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        if (!mMediaTimeTransformValid)
123081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            return;
123181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
123281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        int64_t targetTimeNow;
123381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        status_t res = (mMediaTimeTransformTarget == TimedAudioTrack::COMMON_TIME)
123481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            ? mCCHelper.getCommonTime(&targetTimeNow)
123581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            : mCCHelper.getLocalTime(&targetTimeNow);
123681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
123781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        if (OK != res)
123881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            return;
123981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
124081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        if (!mMediaTimeTransform.doReverseTransform(targetTimeNow,
124181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                                                    &mediaTimeNow)) {
124281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            return;
124381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        }
124481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    }
124581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
124681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    size_t trimEnd;
124781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    for (trimEnd = 0; trimEnd < mTimedBufferQueue.size(); trimEnd++) {
124881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        int64_t bufEnd;
124981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
125081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        if ((trimEnd + 1) < mTimedBufferQueue.size()) {
125181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            // We have a next buffer.  Just use its PTS as the PTS of the frame
125281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            // following the last frame in this buffer.  If the stream is sparse
125381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            // (ie, there are deliberate gaps left in the stream which should be
125481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            // filled with silence by the TimedAudioTrack), then this can result
125581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            // in one extra buffer being left un-trimmed when it could have
125681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            // been.  In general, this is not typical, and we would rather
125781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            // optimized away the TS calculation below for the more common case
125881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            // where PTSes are contiguous.
125981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            bufEnd = mTimedBufferQueue[trimEnd + 1].pts();
126081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        } else {
126181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            // We have no next buffer.  Compute the PTS of the frame following
126281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            // the last frame in this buffer by computing the duration of of
126381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            // this frame in media time units and adding it to the PTS of the
126481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            // buffer.
126581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            int64_t frameCount = mTimedBufferQueue[trimEnd].buffer()->size()
126681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                               / mFrameSize;
126781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
126881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            if (!mMediaTimeToSampleTransform.doReverseTransform(frameCount,
126981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                                                                &bufEnd)) {
127081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                ALOGE("Failed to convert frame count of %lld to media time"
127181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                      " duration" " (scale factor %d/%u) in %s",
127281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                      frameCount,
127381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                      mMediaTimeToSampleTransform.a_to_b_numer,
127481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                      mMediaTimeToSampleTransform.a_to_b_denom,
127581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                      __PRETTY_FUNCTION__);
127681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                break;
127781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            }
127881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            bufEnd += mTimedBufferQueue[trimEnd].pts();
127981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        }
128081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
128181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        if (bufEnd > mediaTimeNow)
128281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            break;
128381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
128481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        // Is the buffer we want to use in the middle of a mix operation right
128581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        // now?  If so, don't actually trim it.  Just wait for the releaseBuffer
128681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        // from the mixer which should be coming back shortly.
128781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        if (!trimEnd && mQueueHeadInFlight) {
128881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            mTrimQueueHeadOnRelease = true;
128981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        }
129081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    }
129181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
129281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    size_t trimStart = mTrimQueueHeadOnRelease ? 1 : 0;
129381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    if (trimStart < trimEnd) {
129481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        // Update the bookkeeping for framesReady()
129581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        for (size_t i = trimStart; i < trimEnd; ++i) {
129681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            updateFramesPendingAfterTrim_l(mTimedBufferQueue[i], "trim");
129781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        }
129881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
129981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        // Now actually remove the buffers from the queue.
130081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        mTimedBufferQueue.removeItemsAt(trimStart, trimEnd);
130181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    }
130281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
130381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
130481784c37c61b09289654b979567a42bf73cd2b12Eric Laurentvoid AudioFlinger::PlaybackThread::TimedTrack::trimTimedBufferQueueHead_l(
130581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        const char* logTag) {
130681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    ALOG_ASSERT(mTimedBufferQueue.size() > 0,
130781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                "%s called (reason \"%s\"), but timed buffer queue has no"
130881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                " elements to trim.", __FUNCTION__, logTag);
130981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
131081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    updateFramesPendingAfterTrim_l(mTimedBufferQueue[0], logTag);
131181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    mTimedBufferQueue.removeAt(0);
131281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
131381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
131481784c37c61b09289654b979567a42bf73cd2b12Eric Laurentvoid AudioFlinger::PlaybackThread::TimedTrack::updateFramesPendingAfterTrim_l(
131581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        const TimedBuffer& buf,
13160f11b51a57bc9062c4fe8af73747319cedabc5d6Glenn Kasten        const char* logTag __unused) {
131781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    uint32_t bufBytes        = buf.buffer()->size();
131881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    uint32_t consumedAlready = buf.position();
131981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
132081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    ALOG_ASSERT(consumedAlready <= bufBytes,
132181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                "Bad bookkeeping while updating frames pending.  Timed buffer is"
132281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                " only %u bytes long, but claims to have consumed %u"
132381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                " bytes.  (update reason: \"%s\")",
132481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                bufBytes, consumedAlready, logTag);
132581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
132681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    uint32_t bufFrames = (bufBytes - consumedAlready) / mFrameSize;
132781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    ALOG_ASSERT(mFramesPendingInQueue >= bufFrames,
132881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                "Bad bookkeeping while updating frames pending.  Should have at"
132981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                " least %u queued frames, but we think we have only %u.  (update"
133081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                " reason: \"%s\")",
133181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                bufFrames, mFramesPendingInQueue, logTag);
133281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
133381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    mFramesPendingInQueue -= bufFrames;
133481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
133581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
133681784c37c61b09289654b979567a42bf73cd2b12Eric Laurentstatus_t AudioFlinger::PlaybackThread::TimedTrack::queueTimedBuffer(
133781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    const sp<IMemory>& buffer, int64_t pts) {
133881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
133981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    {
134081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        Mutex::Autolock mttLock(mMediaTimeTransformLock);
134181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        if (!mMediaTimeTransformValid)
134281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            return INVALID_OPERATION;
134381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    }
134481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
134581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    Mutex::Autolock _l(mTimedBufferQueueLock);
134681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
134781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    uint32_t bufFrames = buffer->size() / mFrameSize;
134881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    mFramesPendingInQueue += bufFrames;
134981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    mTimedBufferQueue.add(TimedBuffer(buffer, pts));
135081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
135181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    return NO_ERROR;
135281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
135381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
135481784c37c61b09289654b979567a42bf73cd2b12Eric Laurentstatus_t AudioFlinger::PlaybackThread::TimedTrack::setMediaTimeTransform(
135581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    const LinearTransform& xform, TimedAudioTrack::TargetTimeline target) {
135681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
135781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    ALOGVV("setMediaTimeTransform az=%lld bz=%lld n=%d d=%u tgt=%d",
135881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent           xform.a_zero, xform.b_zero, xform.a_to_b_numer, xform.a_to_b_denom,
135981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent           target);
136081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
136181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    if (!(target == TimedAudioTrack::LOCAL_TIME ||
136281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent          target == TimedAudioTrack::COMMON_TIME)) {
136381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        return BAD_VALUE;
136481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    }
136581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
136681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    Mutex::Autolock lock(mMediaTimeTransformLock);
136781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    mMediaTimeTransform = xform;
136881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    mMediaTimeTransformTarget = target;
136981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    mMediaTimeTransformValid = true;
137081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
137181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    return NO_ERROR;
137281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
137381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
137481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent#define min(a, b) ((a) < (b) ? (a) : (b))
137581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
137681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// implementation of getNextBuffer for tracks whose buffers have timestamps
137781784c37c61b09289654b979567a42bf73cd2b12Eric Laurentstatus_t AudioFlinger::PlaybackThread::TimedTrack::getNextBuffer(
137881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    AudioBufferProvider::Buffer* buffer, int64_t pts)
137981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{
138081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    if (pts == AudioBufferProvider::kInvalidPTS) {
138181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        buffer->raw = NULL;
138281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        buffer->frameCount = 0;
138381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        mTimedAudioOutputOnTime = false;
138481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        return INVALID_OPERATION;
138581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    }
138681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
138781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    Mutex::Autolock _l(mTimedBufferQueueLock);
138881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
138981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    ALOG_ASSERT(!mQueueHeadInFlight,
139081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                "getNextBuffer called without releaseBuffer!");
139181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
139281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    while (true) {
139381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
139481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        // if we have no timed buffers, then fail
139581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        if (mTimedBufferQueue.isEmpty()) {
139681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            buffer->raw = NULL;
139781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            buffer->frameCount = 0;
139881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            return NOT_ENOUGH_DATA;
139981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        }
140081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
140181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        TimedBuffer& head = mTimedBufferQueue.editItemAt(0);
140281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
140381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        // calculate the PTS of the head of the timed buffer queue expressed in
140481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        // local time
140581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        int64_t headLocalPTS;
140681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        {
140781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            Mutex::Autolock mttLock(mMediaTimeTransformLock);
140881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
140981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            ALOG_ASSERT(mMediaTimeTransformValid, "media time transform invalid");
141081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
141181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            if (mMediaTimeTransform.a_to_b_denom == 0) {
141281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                // the transform represents a pause, so yield silence
141381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                timedYieldSilence_l(buffer->frameCount, buffer);
141481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                return NO_ERROR;
141581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            }
141681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
141781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            int64_t transformedPTS;
141881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            if (!mMediaTimeTransform.doForwardTransform(head.pts(),
141981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                                                        &transformedPTS)) {
142081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                // the transform failed.  this shouldn't happen, but if it does
142181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                // then just drop this buffer
142281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                ALOGW("timedGetNextBuffer transform failed");
142381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                buffer->raw = NULL;
142481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                buffer->frameCount = 0;
142581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                trimTimedBufferQueueHead_l("getNextBuffer; no transform");
142681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                return NO_ERROR;
142781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            }
142881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
142981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            if (mMediaTimeTransformTarget == TimedAudioTrack::COMMON_TIME) {
143081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                if (OK != mCCHelper.commonTimeToLocalTime(transformedPTS,
143181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                                                          &headLocalPTS)) {
143281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                    buffer->raw = NULL;
143381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                    buffer->frameCount = 0;
143481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                    return INVALID_OPERATION;
143581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                }
143681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            } else {
143781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                headLocalPTS = transformedPTS;
143881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            }
143981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        }
144081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
14419fdcb0a9497ca290bcf364b10868587b6bde3a34Glenn Kasten        uint32_t sr = sampleRate();
14429fdcb0a9497ca290bcf364b10868587b6bde3a34Glenn Kasten
144381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        // adjust the head buffer's PTS to reflect the portion of the head buffer
144481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        // that has already been consumed
144581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        int64_t effectivePTS = headLocalPTS +
14469fdcb0a9497ca290bcf364b10868587b6bde3a34Glenn Kasten                ((head.position() / mFrameSize) * mLocalTimeFreq / sr);
144781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
144881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        // Calculate the delta in samples between the head of the input buffer
144981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        // queue and the start of the next output buffer that will be written.
145081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        // If the transformation fails because of over or underflow, it means
145181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        // that the sample's position in the output stream is so far out of
145281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        // whack that it should just be dropped.
145381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        int64_t sampleDelta;
145481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        if (llabs(effectivePTS - pts) >= (static_cast<int64_t>(1) << 31)) {
145581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            ALOGV("*** head buffer is too far from PTS: dropped buffer");
145681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            trimTimedBufferQueueHead_l("getNextBuffer, buf pts too far from"
145781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                                       " mix");
145881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            continue;
145981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        }
146081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        if (!mLocalTimeToSampleTransform.doForwardTransform(
146181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                (effectivePTS - pts) << 32, &sampleDelta)) {
146281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            ALOGV("*** too late during sample rate transform: dropped buffer");
146381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            trimTimedBufferQueueHead_l("getNextBuffer, bad local to sample");
146481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            continue;
146581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        }
146681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
146781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        ALOGVV("*** getNextBuffer head.pts=%lld head.pos=%d pts=%lld"
146881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent               " sampleDelta=[%d.%08x]",
146981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent               head.pts(), head.position(), pts,
147081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent               static_cast<int32_t>((sampleDelta >= 0 ? 0 : 1)
147181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                   + (sampleDelta >> 32)),
147281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent               static_cast<uint32_t>(sampleDelta & 0xFFFFFFFF));
147381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
147481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        // if the delta between the ideal placement for the next input sample and
147581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        // the current output position is within this threshold, then we will
147681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        // concatenate the next input samples to the previous output
147781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        const int64_t kSampleContinuityThreshold =
14789fdcb0a9497ca290bcf364b10868587b6bde3a34Glenn Kasten                (static_cast<int64_t>(sr) << 32) / 250;
147981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
148081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        // if this is the first buffer of audio that we're emitting from this track
148181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        // then it should be almost exactly on time.
148281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        const int64_t kSampleStartupThreshold = 1LL << 32;
148381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
148481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        if ((mTimedAudioOutputOnTime && llabs(sampleDelta) <= kSampleContinuityThreshold) ||
148581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent           (!mTimedAudioOutputOnTime && llabs(sampleDelta) <= kSampleStartupThreshold)) {
148681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            // the next input is close enough to being on time, so concatenate it
148781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            // with the last output
148881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            timedYieldSamples_l(buffer);
148981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
149081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            ALOGVV("*** on time: head.pos=%d frameCount=%u",
149181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                    head.position(), buffer->frameCount);
149281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            return NO_ERROR;
149381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        }
149481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
149581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        // Looks like our output is not on time.  Reset our on timed status.
149681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        // Next time we mix samples from our input queue, then should be within
149781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        // the StartupThreshold.
149881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        mTimedAudioOutputOnTime = false;
149981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        if (sampleDelta > 0) {
150081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            // the gap between the current output position and the proper start of
150181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            // the next input sample is too big, so fill it with silence
150281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            uint32_t framesUntilNextInput = (sampleDelta + 0x80000000) >> 32;
150381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
150481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            timedYieldSilence_l(framesUntilNextInput, buffer);
150581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            ALOGV("*** silence: frameCount=%u", buffer->frameCount);
150681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            return NO_ERROR;
150781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        } else {
150881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            // the next input sample is late
150981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            uint32_t lateFrames = static_cast<uint32_t>(-((sampleDelta + 0x80000000) >> 32));
151081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            size_t onTimeSamplePosition =
151181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                    head.position() + lateFrames * mFrameSize;
151281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
151381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            if (onTimeSamplePosition > head.buffer()->size()) {
151481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                // all the remaining samples in the head are too late, so
151581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                // drop it and move on
151681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                ALOGV("*** too late: dropped buffer");
151781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                trimTimedBufferQueueHead_l("getNextBuffer, dropped late buffer");
151881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                continue;
151981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            } else {
152081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                // skip over the late samples
152181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                head.setPosition(onTimeSamplePosition);
152281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
152381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                // yield the available samples
152481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                timedYieldSamples_l(buffer);
152581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
152681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                ALOGV("*** late: head.pos=%d frameCount=%u", head.position(), buffer->frameCount);
152781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                return NO_ERROR;
152881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            }
152981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        }
153081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    }
153181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
153281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
153381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// Yield samples from the timed buffer queue head up to the given output
153481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// buffer's capacity.
153581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent//
153681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// Caller must hold mTimedBufferQueueLock
153781784c37c61b09289654b979567a42bf73cd2b12Eric Laurentvoid AudioFlinger::PlaybackThread::TimedTrack::timedYieldSamples_l(
153881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    AudioBufferProvider::Buffer* buffer) {
153981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
154081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    const TimedBuffer& head = mTimedBufferQueue[0];
154181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
154281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    buffer->raw = (static_cast<uint8_t*>(head.buffer()->pointer()) +
154381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                   head.position());
154481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
154581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    uint32_t framesLeftInHead = ((head.buffer()->size() - head.position()) /
154681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                                 mFrameSize);
154781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    size_t framesRequested = buffer->frameCount;
154881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    buffer->frameCount = min(framesLeftInHead, framesRequested);
154981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
155081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    mQueueHeadInFlight = true;
155181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    mTimedAudioOutputOnTime = true;
155281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
155381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
155481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// Yield samples of silence up to the given output buffer's capacity
155581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent//
155681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// Caller must hold mTimedBufferQueueLock
155781784c37c61b09289654b979567a42bf73cd2b12Eric Laurentvoid AudioFlinger::PlaybackThread::TimedTrack::timedYieldSilence_l(
155881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    uint32_t numFrames, AudioBufferProvider::Buffer* buffer) {
155981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
156081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    // lazily allocate a buffer filled with silence
156181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    if (mTimedSilenceBufferSize < numFrames * mFrameSize) {
156281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        delete [] mTimedSilenceBuffer;
156381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        mTimedSilenceBufferSize = numFrames * mFrameSize;
156481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        mTimedSilenceBuffer = new uint8_t[mTimedSilenceBufferSize];
156581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        memset(mTimedSilenceBuffer, 0, mTimedSilenceBufferSize);
156681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    }
156781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
156881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    buffer->raw = mTimedSilenceBuffer;
156981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    size_t framesRequested = buffer->frameCount;
157081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    buffer->frameCount = min(numFrames, framesRequested);
157181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
157281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    mTimedAudioOutputOnTime = false;
157381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
157481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
157581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// AudioBufferProvider interface
157681784c37c61b09289654b979567a42bf73cd2b12Eric Laurentvoid AudioFlinger::PlaybackThread::TimedTrack::releaseBuffer(
157781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    AudioBufferProvider::Buffer* buffer) {
157881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
157981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    Mutex::Autolock _l(mTimedBufferQueueLock);
158081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
158181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    // If the buffer which was just released is part of the buffer at the head
158281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    // of the queue, be sure to update the amt of the buffer which has been
158381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    // consumed.  If the buffer being returned is not part of the head of the
158481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    // queue, its either because the buffer is part of the silence buffer, or
158581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    // because the head of the timed queue was trimmed after the mixer called
158681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    // getNextBuffer but before the mixer called releaseBuffer.
158781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    if (buffer->raw == mTimedSilenceBuffer) {
158881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        ALOG_ASSERT(!mQueueHeadInFlight,
158981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                    "Queue head in flight during release of silence buffer!");
159081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        goto done;
159181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    }
159281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
159381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    ALOG_ASSERT(mQueueHeadInFlight,
159481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                "TimedTrack::releaseBuffer of non-silence buffer, but no queue"
159581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                " head in flight.");
159681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
159781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    if (mTimedBufferQueue.size()) {
159881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        TimedBuffer& head = mTimedBufferQueue.editItemAt(0);
159981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
160081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        void* start = head.buffer()->pointer();
160181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        void* end   = reinterpret_cast<void*>(
160281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                        reinterpret_cast<uint8_t*>(head.buffer()->pointer())
160381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                        + head.buffer()->size());
160481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
160581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        ALOG_ASSERT((buffer->raw >= start) && (buffer->raw < end),
160681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                    "released buffer not within the head of the timed buffer"
160781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                    " queue; qHead = [%p, %p], released buffer = %p",
160881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                    start, end, buffer->raw);
160981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
161081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        head.setPosition(head.position() +
161181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                (buffer->frameCount * mFrameSize));
161281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        mQueueHeadInFlight = false;
161381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
161481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        ALOG_ASSERT(mFramesPendingInQueue >= buffer->frameCount,
161581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                    "Bad bookkeeping during releaseBuffer!  Should have at"
161681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                    " least %u queued frames, but we think we have only %u",
161781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                    buffer->frameCount, mFramesPendingInQueue);
161881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
161981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        mFramesPendingInQueue -= buffer->frameCount;
162081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
162181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        if ((static_cast<size_t>(head.position()) >= head.buffer()->size())
162281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            || mTrimQueueHeadOnRelease) {
162381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            trimTimedBufferQueueHead_l("releaseBuffer");
162481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            mTrimQueueHeadOnRelease = false;
162581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        }
162681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    } else {
1627adad3d7d935da176ff24941b4ae9edf7340e9b96Glenn Kasten        LOG_ALWAYS_FATAL("TimedTrack::releaseBuffer of non-silence buffer with no"
162881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                  " buffers in the timed buffer queue");
162981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    }
163081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
163181784c37c61b09289654b979567a42bf73cd2b12Eric Laurentdone:
163281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    buffer->raw = 0;
163381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    buffer->frameCount = 0;
163481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
163581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
163681784c37c61b09289654b979567a42bf73cd2b12Eric Laurentsize_t AudioFlinger::PlaybackThread::TimedTrack::framesReady() const {
163781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    Mutex::Autolock _l(mTimedBufferQueueLock);
163881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    return mFramesPendingInQueue;
163981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
164081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
164181784c37c61b09289654b979567a42bf73cd2b12Eric LaurentAudioFlinger::PlaybackThread::TimedTrack::TimedBuffer::TimedBuffer()
164281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        : mPTS(0), mPosition(0) {}
164381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
164481784c37c61b09289654b979567a42bf73cd2b12Eric LaurentAudioFlinger::PlaybackThread::TimedTrack::TimedBuffer::TimedBuffer(
164581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    const sp<IMemory>& buffer, int64_t pts)
164681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        : mBuffer(buffer), mPTS(pts), mPosition(0) {}
164781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
164881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
164981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// ----------------------------------------------------------------------------
165081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
165181784c37c61b09289654b979567a42bf73cd2b12Eric LaurentAudioFlinger::PlaybackThread::OutputTrack::OutputTrack(
165281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            PlaybackThread *playbackThread,
165381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            DuplicatingThread *sourceThread,
165481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            uint32_t sampleRate,
165581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            audio_format_t format,
165681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            audio_channel_mask_t channelMask,
1657462fd2fa9eef642b0574aa7409de0bde3fec8d43Marco Nelissen            size_t frameCount,
1658462fd2fa9eef642b0574aa7409de0bde3fec8d43Marco Nelissen            int uid)
1659223fd5c9738e9665e495904d37d4632414b68c1eEric Laurent    :   Track(playbackThread, NULL, AUDIO_STREAM_PATCH,
1660223fd5c9738e9665e495904d37d4632414b68c1eEric Laurent              sampleRate, format, channelMask, frameCount,
1661223fd5c9738e9665e495904d37d4632414b68c1eEric Laurent              NULL, 0, 0, uid, IAudioFlinger::TRACK_DEFAULT, TYPE_OUTPUT),
1662e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten    mActive(false), mSourceThread(sourceThread), mClientProxy(NULL)
166381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{
166481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
166581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    if (mCblk != NULL) {
166681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        mOutBuffer.frameCount = 0;
166781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        playbackThread->mTracks.add(this);
1668e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten        ALOGV("OutputTrack constructor mCblk %p, mBuffer %p, "
166974935e44734c1ec235c2b6677db3e0dbefa5ddb8Glenn Kasten                "frameCount %u, mChannelMask 0x%08x",
1670e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten                mCblk, mBuffer,
167174935e44734c1ec235c2b6677db3e0dbefa5ddb8Glenn Kasten                frameCount, mChannelMask);
1672e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten        // since client and server are in the same process,
1673e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten        // the buffer has the same virtual address on both sides
1674529c61b7e4468a3e21f302f2a92a660249daa722Glenn Kasten        mClientProxy = new AudioTrackClientProxy(mCblk, mBuffer, mFrameCount, mFrameSize,
1675529c61b7e4468a3e21f302f2a92a660249daa722Glenn Kasten                true /*clientInServer*/);
1676c56f3426099a3cf2d07ccff8886050c7fbce140fGlenn Kasten        mClientProxy->setVolumeLR(GAIN_MINIFLOAT_PACKED_UNITY);
16778d2d4932b96632e9eb3af4a3d4000192ef603960Eric Laurent        mClientProxy->setSendLevel(0.0);
16788d2d4932b96632e9eb3af4a3d4000192ef603960Eric Laurent        mClientProxy->setSampleRate(sampleRate);
167981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    } else {
168081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        ALOGW("Error creating output track on thread %p", playbackThread);
168181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    }
168281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
168381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
168481784c37c61b09289654b979567a42bf73cd2b12Eric LaurentAudioFlinger::PlaybackThread::OutputTrack::~OutputTrack()
168581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{
168681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    clearBufferQueue();
1687e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten    delete mClientProxy;
1688e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten    // superclass destructor will now delete the server proxy and shared memory both refer to
168981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
169081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
169181784c37c61b09289654b979567a42bf73cd2b12Eric Laurentstatus_t AudioFlinger::PlaybackThread::OutputTrack::start(AudioSystem::sync_event_t event,
169281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                                                          int triggerSession)
169381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{
169481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    status_t status = Track::start(event, triggerSession);
169581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    if (status != NO_ERROR) {
169681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        return status;
169781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    }
169881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
169981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    mActive = true;
170081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    mRetryCount = 127;
170181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    return status;
170281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
170381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
170481784c37c61b09289654b979567a42bf73cd2b12Eric Laurentvoid AudioFlinger::PlaybackThread::OutputTrack::stop()
170581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{
170681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    Track::stop();
170781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    clearBufferQueue();
170881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    mOutBuffer.frameCount = 0;
170981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    mActive = false;
171081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
171181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
171281784c37c61b09289654b979567a42bf73cd2b12Eric Laurentbool AudioFlinger::PlaybackThread::OutputTrack::write(int16_t* data, uint32_t frames)
171381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{
171481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    Buffer *pInBuffer;
171581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    Buffer inBuffer;
171681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    uint32_t channelCount = mChannelCount;
171781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    bool outputBufferFull = false;
171881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    inBuffer.frameCount = frames;
171981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    inBuffer.i16 = data;
172081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
172181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    uint32_t waitTimeLeftMs = mSourceThread->waitTimeMs();
172281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
172381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    if (!mActive && frames != 0) {
172481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        start();
172581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        sp<ThreadBase> thread = mThread.promote();
172681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        if (thread != 0) {
172781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            MixerThread *mixerThread = (MixerThread *)thread.get();
172881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            if (mFrameCount > frames) {
172981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                if (mBufferQueue.size() < kMaxOverFlowBuffers) {
173081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                    uint32_t startFrames = (mFrameCount - frames);
173181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                    pInBuffer = new Buffer;
173281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                    pInBuffer->mBuffer = new int16_t[startFrames * channelCount];
173381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                    pInBuffer->frameCount = startFrames;
173481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                    pInBuffer->i16 = pInBuffer->mBuffer;
173581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                    memset(pInBuffer->raw, 0, startFrames * channelCount * sizeof(int16_t));
173681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                    mBufferQueue.add(pInBuffer);
173781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                } else {
17387c027248e1a4ccd5b22bc4deafb03e2d87ac8f38Glenn Kasten                    ALOGW("OutputTrack::write() %p no more buffers in queue", this);
173981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                }
174081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            }
174181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        }
174281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    }
174381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
174481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    while (waitTimeLeftMs) {
174581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        // First write pending buffers, then new data
174681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        if (mBufferQueue.size()) {
174781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            pInBuffer = mBufferQueue.itemAt(0);
174881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        } else {
174981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            pInBuffer = &inBuffer;
175081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        }
175181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
175281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        if (pInBuffer->frameCount == 0) {
175381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            break;
175481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        }
175581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
175681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        if (mOutBuffer.frameCount == 0) {
175781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            mOutBuffer.frameCount = pInBuffer->frameCount;
175881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            nsecs_t startTime = systemTime();
17599f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten            status_t status = obtainBuffer(&mOutBuffer, waitTimeLeftMs);
17609f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten            if (status != NO_ERROR) {
17619f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten                ALOGV("OutputTrack::write() %p thread %p no more output buffers; status %d", this,
17629f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten                        mThread.unsafe_get(), status);
176381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                outputBufferFull = true;
176481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                break;
176581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            }
176681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            uint32_t waitTimeMs = (uint32_t)ns2ms(systemTime() - startTime);
176781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            if (waitTimeLeftMs >= waitTimeMs) {
176881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                waitTimeLeftMs -= waitTimeMs;
176981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            } else {
177081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                waitTimeLeftMs = 0;
177181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            }
177281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        }
177381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
177481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        uint32_t outFrames = pInBuffer->frameCount > mOutBuffer.frameCount ? mOutBuffer.frameCount :
177581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                pInBuffer->frameCount;
177681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        memcpy(mOutBuffer.raw, pInBuffer->raw, outFrames * channelCount * sizeof(int16_t));
17779f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten        Proxy::Buffer buf;
17789f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten        buf.mFrameCount = outFrames;
17799f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten        buf.mRaw = NULL;
17809f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten        mClientProxy->releaseBuffer(&buf);
178181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        pInBuffer->frameCount -= outFrames;
178281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        pInBuffer->i16 += outFrames * channelCount;
178381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        mOutBuffer.frameCount -= outFrames;
178481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        mOutBuffer.i16 += outFrames * channelCount;
178581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
178681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        if (pInBuffer->frameCount == 0) {
178781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            if (mBufferQueue.size()) {
178881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                mBufferQueue.removeAt(0);
178981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                delete [] pInBuffer->mBuffer;
179081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                delete pInBuffer;
179181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                ALOGV("OutputTrack::write() %p thread %p released overflow buffer %d", this,
179281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                        mThread.unsafe_get(), mBufferQueue.size());
179381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            } else {
179481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                break;
179581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            }
179681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        }
179781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    }
179881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
179981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    // If we could not write all frames, allocate a buffer and queue it for next time.
180081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    if (inBuffer.frameCount) {
180181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        sp<ThreadBase> thread = mThread.promote();
180281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        if (thread != 0 && !thread->standby()) {
180381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            if (mBufferQueue.size() < kMaxOverFlowBuffers) {
180481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                pInBuffer = new Buffer;
180581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                pInBuffer->mBuffer = new int16_t[inBuffer.frameCount * channelCount];
180681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                pInBuffer->frameCount = inBuffer.frameCount;
180781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                pInBuffer->i16 = pInBuffer->mBuffer;
180881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                memcpy(pInBuffer->raw, inBuffer.raw, inBuffer.frameCount * channelCount *
180981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                        sizeof(int16_t));
181081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                mBufferQueue.add(pInBuffer);
181181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                ALOGV("OutputTrack::write() %p thread %p adding overflow buffer %d", this,
181281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                        mThread.unsafe_get(), mBufferQueue.size());
181381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            } else {
181481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                ALOGW("OutputTrack::write() %p thread %p no more overflow buffers",
181581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                        mThread.unsafe_get(), this);
181681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            }
181781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        }
181881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    }
181981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
182081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    // Calling write() with a 0 length buffer, means that no more data will be written:
182181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    // If no more buffers are pending, fill output track buffer to make sure it is started
182281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    // by output mixer.
182381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    if (frames == 0 && mBufferQueue.size() == 0) {
18249f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten        // FIXME borken, replace by getting framesReady() from proxy
18259f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten        size_t user = 0;    // was mCblk->user
18269f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten        if (user < mFrameCount) {
18279f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten            frames = mFrameCount - user;
182881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            pInBuffer = new Buffer;
182981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            pInBuffer->mBuffer = new int16_t[frames * channelCount];
183081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            pInBuffer->frameCount = frames;
183181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            pInBuffer->i16 = pInBuffer->mBuffer;
183281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            memset(pInBuffer->raw, 0, frames * channelCount * sizeof(int16_t));
183381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            mBufferQueue.add(pInBuffer);
183481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        } else if (mActive) {
183581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            stop();
183681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        }
183781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    }
183881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
183981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    return outputBufferFull;
184081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
184181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
184281784c37c61b09289654b979567a42bf73cd2b12Eric Laurentstatus_t AudioFlinger::PlaybackThread::OutputTrack::obtainBuffer(
184381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        AudioBufferProvider::Buffer* buffer, uint32_t waitTimeMs)
184481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{
18459f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    ClientProxy::Buffer buf;
18469f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    buf.mFrameCount = buffer->frameCount;
18479f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    struct timespec timeout;
18489f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    timeout.tv_sec = waitTimeMs / 1000;
18499f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    timeout.tv_nsec = (int) (waitTimeMs % 1000) * 1000000;
18509f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    status_t status = mClientProxy->obtainBuffer(&buf, &timeout);
18519f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    buffer->frameCount = buf.mFrameCount;
18529f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    buffer->raw = buf.mRaw;
18539f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    return status;
185481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
185581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
185681784c37c61b09289654b979567a42bf73cd2b12Eric Laurentvoid AudioFlinger::PlaybackThread::OutputTrack::clearBufferQueue()
185781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{
185881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    size_t size = mBufferQueue.size();
185981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
186081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    for (size_t i = 0; i < size; i++) {
186181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        Buffer *pBuffer = mBufferQueue.itemAt(i);
186281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        delete [] pBuffer->mBuffer;
186381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        delete pBuffer;
186481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    }
186581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    mBufferQueue.clear();
186681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
186781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
186881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
186983b8808faad1e91690c64d7007348be8d9ebde73Eric LaurentAudioFlinger::PlaybackThread::PatchTrack::PatchTrack(PlaybackThread *playbackThread,
187083b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent                                                     uint32_t sampleRate,
187183b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent                                                     audio_channel_mask_t channelMask,
187283b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent                                                     audio_format_t format,
187383b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent                                                     size_t frameCount,
187483b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent                                                     void *buffer,
187583b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent                                                     IAudioFlinger::track_flags_t flags)
1876223fd5c9738e9665e495904d37d4632414b68c1eEric Laurent    :   Track(playbackThread, NULL, AUDIO_STREAM_PATCH,
1877223fd5c9738e9665e495904d37d4632414b68c1eEric Laurent              sampleRate, format, channelMask, frameCount,
187883b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent              buffer, 0, 0, getuid(), flags, TYPE_PATCH),
187983b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent              mProxy(new ClientProxy(mCblk, mBuffer, frameCount, mFrameSize, true, true))
188083b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent{
188183b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent    uint64_t mixBufferNs = ((uint64_t)2 * playbackThread->frameCount() * 1000000000) /
188283b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent                                                                    playbackThread->sampleRate();
188383b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent    mPeerTimeout.tv_sec = mixBufferNs / 1000000000;
188483b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent    mPeerTimeout.tv_nsec = (int) (mixBufferNs % 1000000000);
188583b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent
188683b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent    ALOGV("PatchTrack %p sampleRate %d mPeerTimeout %d.%03d sec",
188783b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent                                      this, sampleRate,
188883b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent                                      (int)mPeerTimeout.tv_sec,
188983b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent                                      (int)(mPeerTimeout.tv_nsec / 1000000));
189083b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent}
189183b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent
189283b8808faad1e91690c64d7007348be8d9ebde73Eric LaurentAudioFlinger::PlaybackThread::PatchTrack::~PatchTrack()
189383b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent{
189483b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent}
189583b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent
189683b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent// AudioBufferProvider interface
189783b8808faad1e91690c64d7007348be8d9ebde73Eric Laurentstatus_t AudioFlinger::PlaybackThread::PatchTrack::getNextBuffer(
189883b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent        AudioBufferProvider::Buffer* buffer, int64_t pts)
189983b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent{
190083b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent    ALOG_ASSERT(mPeerProxy != 0, "PatchTrack::getNextBuffer() called without peer proxy");
190183b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent    Proxy::Buffer buf;
190283b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent    buf.mFrameCount = buffer->frameCount;
190383b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent    status_t status = mPeerProxy->obtainBuffer(&buf, &mPeerTimeout);
190483b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent    ALOGV_IF(status != NO_ERROR, "PatchTrack() %p getNextBuffer status %d", this, status);
1905c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent    buffer->frameCount = buf.mFrameCount;
190683b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent    if (buf.mFrameCount == 0) {
190783b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent        return WOULD_BLOCK;
190883b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent    }
190983b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent    status = Track::getNextBuffer(buffer, pts);
191083b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent    return status;
191183b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent}
191283b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent
191383b8808faad1e91690c64d7007348be8d9ebde73Eric Laurentvoid AudioFlinger::PlaybackThread::PatchTrack::releaseBuffer(AudioBufferProvider::Buffer* buffer)
191483b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent{
191583b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent    ALOG_ASSERT(mPeerProxy != 0, "PatchTrack::releaseBuffer() called without peer proxy");
191683b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent    Proxy::Buffer buf;
191783b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent    buf.mFrameCount = buffer->frameCount;
191883b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent    buf.mRaw = buffer->raw;
191983b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent    mPeerProxy->releaseBuffer(&buf);
192083b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent    TrackBase::releaseBuffer(buffer);
192183b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent}
192283b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent
192383b8808faad1e91690c64d7007348be8d9ebde73Eric Laurentstatus_t AudioFlinger::PlaybackThread::PatchTrack::obtainBuffer(Proxy::Buffer* buffer,
192483b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent                                                                const struct timespec *timeOut)
192583b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent{
192683b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent    return mProxy->obtainBuffer(buffer, timeOut);
192783b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent}
192883b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent
192983b8808faad1e91690c64d7007348be8d9ebde73Eric Laurentvoid AudioFlinger::PlaybackThread::PatchTrack::releaseBuffer(Proxy::Buffer* buffer)
193083b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent{
193183b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent    mProxy->releaseBuffer(buffer);
193283b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent    if (android_atomic_and(~CBLK_DISABLED, &mCblk->mFlags) & CBLK_DISABLED) {
193383b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent        ALOGW("PatchTrack::releaseBuffer() disabled due to previous underrun, restarting");
193483b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent        start();
193583b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent    }
193683b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent    android_atomic_or(CBLK_FORCEREADY, &mCblk->mFlags);
193783b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent}
193883b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent
193981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// ----------------------------------------------------------------------------
194081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent//      Record
194181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// ----------------------------------------------------------------------------
194281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
194381784c37c61b09289654b979567a42bf73cd2b12Eric LaurentAudioFlinger::RecordHandle::RecordHandle(
194481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        const sp<AudioFlinger::RecordThread::RecordTrack>& recordTrack)
194581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    : BnAudioRecord(),
194681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    mRecordTrack(recordTrack)
194781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{
194881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
194981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
195081784c37c61b09289654b979567a42bf73cd2b12Eric LaurentAudioFlinger::RecordHandle::~RecordHandle() {
195181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    stop_nonvirtual();
195281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    mRecordTrack->destroy();
195381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
195481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
195581784c37c61b09289654b979567a42bf73cd2b12Eric Laurentstatus_t AudioFlinger::RecordHandle::start(int /*AudioSystem::sync_event_t*/ event,
195681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        int triggerSession) {
195781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    ALOGV("RecordHandle::start()");
195881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    return mRecordTrack->start((AudioSystem::sync_event_t)event, triggerSession);
195981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
196081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
196181784c37c61b09289654b979567a42bf73cd2b12Eric Laurentvoid AudioFlinger::RecordHandle::stop() {
196281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    stop_nonvirtual();
196381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
196481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
196581784c37c61b09289654b979567a42bf73cd2b12Eric Laurentvoid AudioFlinger::RecordHandle::stop_nonvirtual() {
196681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    ALOGV("RecordHandle::stop()");
196781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    mRecordTrack->stop();
196881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
196981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
197081784c37c61b09289654b979567a42bf73cd2b12Eric Laurentstatus_t AudioFlinger::RecordHandle::onTransact(
197181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
197281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{
197381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    return BnAudioRecord::onTransact(code, data, reply, flags);
197481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
197581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
197681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// ----------------------------------------------------------------------------
197781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
197805997e21af6c4517f375def6563af4b9ebe95f39Glenn Kasten// RecordTrack constructor must be called with AudioFlinger::mLock and ThreadBase::mLock held
197981784c37c61b09289654b979567a42bf73cd2b12Eric LaurentAudioFlinger::RecordThread::RecordTrack::RecordTrack(
198081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            RecordThread *thread,
198181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            const sp<Client>& client,
198281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            uint32_t sampleRate,
198381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            audio_format_t format,
198481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            audio_channel_mask_t channelMask,
198581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            size_t frameCount,
198683b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent            void *buffer,
1987462fd2fa9eef642b0574aa7409de0bde3fec8d43Marco Nelissen            int sessionId,
1988d776ac63ce9c013c9626226e43f7db606e035838Glenn Kasten            int uid,
198983b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent            IAudioFlinger::track_flags_t flags,
199083b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent            track_type type)
199181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    :   TrackBase(thread, client, sampleRate, format,
199283b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent                  channelMask, frameCount, buffer, sessionId, uid,
1993755b0a611f539dfa49e88aac592a938427c7e1b8Glenn Kasten                  flags, false /*isOut*/,
199483b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent                  (type == TYPE_DEFAULT) ?
199583b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent                          ((flags & IAudioFlinger::TRACK_FAST) ? ALLOC_PIPE : ALLOC_CBLK) :
199683b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent                          ((buffer == NULL) ? ALLOC_LOCAL : ALLOC_NONE),
199783b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent                  type),
19986dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten        mOverflow(false), mResampler(NULL), mRsmpOutBuffer(NULL), mRsmpOutFrameCount(0),
19996dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten        // See real initialization of mRsmpInFront at RecordThread::start()
20006dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten        mRsmpInUnrel(0), mRsmpInFront(0), mFramesToDrop(0), mResamplerBufferProvider(NULL)
200181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{
20023ef14ef30359376006a233f6a21a165d4b65a7dfGlenn Kasten    if (mCblk == NULL) {
20033ef14ef30359376006a233f6a21a165d4b65a7dfGlenn Kasten        return;
20049f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    }
20056dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten
200683b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent    mServerProxy = new AudioRecordServerProxy(mCblk, mBuffer, frameCount,
200783b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent                                              mFrameSize, !isExternalTrack());
20083ef14ef30359376006a233f6a21a165d4b65a7dfGlenn Kasten
2009e541269be94f3a1072932d51537905b120ef4733Andy Hung    uint32_t channelCount = audio_channel_count_from_in_mask(channelMask);
20106dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten    // FIXME I don't understand either of the channel count checks
20116dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten    if (thread->mSampleRate != sampleRate && thread->mChannelCount <= FCC_2 &&
20126dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten            channelCount <= FCC_2) {
20136dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten        // sink SR
20143348e36c51e91e78020bcc6578eda83d97c31becAndy Hung        mResampler = AudioResampler::create(AUDIO_FORMAT_PCM_16_BIT,
20153348e36c51e91e78020bcc6578eda83d97c31becAndy Hung                thread->mChannelCount, sampleRate);
20166dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten        // source SR
20176dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten        mResampler->setSampleRate(thread->mSampleRate);
20185e58b0abe5b6c8f5bd96a8f78bbeeeb4d3892020Andy Hung        mResampler->setVolume(AudioMixer::UNITY_GAIN_FLOAT, AudioMixer::UNITY_GAIN_FLOAT);
20196dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten        mResamplerBufferProvider = new ResamplerBufferProvider(this);
20206dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten    }
2021c263ca0ad8b6bdf5b0693996bc5f2f5916e0cd49Glenn Kasten
2022c263ca0ad8b6bdf5b0693996bc5f2f5916e0cd49Glenn Kasten    if (flags & IAudioFlinger::TRACK_FAST) {
2023c263ca0ad8b6bdf5b0693996bc5f2f5916e0cd49Glenn Kasten        ALOG_ASSERT(thread->mFastTrackAvail);
2024c263ca0ad8b6bdf5b0693996bc5f2f5916e0cd49Glenn Kasten        thread->mFastTrackAvail = false;
2025c263ca0ad8b6bdf5b0693996bc5f2f5916e0cd49Glenn Kasten    }
202681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
202781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
202881784c37c61b09289654b979567a42bf73cd2b12Eric LaurentAudioFlinger::RecordThread::RecordTrack::~RecordTrack()
202981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{
203081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    ALOGV("%s", __func__);
20316dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten    delete mResampler;
20326dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten    delete[] mRsmpOutBuffer;
20336dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten    delete mResamplerBufferProvider;
203481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
203581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
203681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// AudioBufferProvider interface
203781784c37c61b09289654b979567a42bf73cd2b12Eric Laurentstatus_t AudioFlinger::RecordThread::RecordTrack::getNextBuffer(AudioBufferProvider::Buffer* buffer,
20380f11b51a57bc9062c4fe8af73747319cedabc5d6Glenn Kasten        int64_t pts __unused)
203981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{
20409f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    ServerProxy::Buffer buf;
20419f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    buf.mFrameCount = buffer->frameCount;
20429f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    status_t status = mServerProxy->obtainBuffer(&buf);
20439f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    buffer->frameCount = buf.mFrameCount;
20449f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    buffer->raw = buf.mRaw;
20459f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    if (buf.mFrameCount == 0) {
20469f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten        // FIXME also wake futex so that overrun is noticed more quickly
204796f60d8f04432a1ed503b3e24d5736d28c63c9a2Glenn Kasten        (void) android_atomic_or(CBLK_OVERRUN, &mCblk->mFlags);
204881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    }
20499f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    return status;
205081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
205181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
205281784c37c61b09289654b979567a42bf73cd2b12Eric Laurentstatus_t AudioFlinger::RecordThread::RecordTrack::start(AudioSystem::sync_event_t event,
205381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                                                        int triggerSession)
205481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{
205581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    sp<ThreadBase> thread = mThread.promote();
205681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    if (thread != 0) {
205781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        RecordThread *recordThread = (RecordThread *)thread.get();
205881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        return recordThread->start(this, event, triggerSession);
205981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    } else {
206081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        return BAD_VALUE;
206181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    }
206281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
206381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
206481784c37c61b09289654b979567a42bf73cd2b12Eric Laurentvoid AudioFlinger::RecordThread::RecordTrack::stop()
206581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{
206681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    sp<ThreadBase> thread = mThread.promote();
206781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    if (thread != 0) {
206881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        RecordThread *recordThread = (RecordThread *)thread.get();
206983b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent        if (recordThread->stop(this) && isExternalTrack()) {
2070aaa44478a373232d8416657035a9020f9c7aa7c3Eric Laurent            AudioSystem::stopInput(mThreadIoHandle, (audio_session_t)mSessionId);
207181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        }
207281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    }
207381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
207481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
207581784c37c61b09289654b979567a42bf73cd2b12Eric Laurentvoid AudioFlinger::RecordThread::RecordTrack::destroy()
207681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{
207781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    // see comments at AudioFlinger::PlaybackThread::Track::destroy()
207881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    sp<RecordTrack> keep(this);
207981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    {
2080aaa44478a373232d8416657035a9020f9c7aa7c3Eric Laurent        if (isExternalTrack()) {
2081aaa44478a373232d8416657035a9020f9c7aa7c3Eric Laurent            if (mState == ACTIVE || mState == RESUMING) {
2082aaa44478a373232d8416657035a9020f9c7aa7c3Eric Laurent                AudioSystem::stopInput(mThreadIoHandle, (audio_session_t)mSessionId);
2083aaa44478a373232d8416657035a9020f9c7aa7c3Eric Laurent            }
2084aaa44478a373232d8416657035a9020f9c7aa7c3Eric Laurent            AudioSystem::releaseInput(mThreadIoHandle, (audio_session_t)mSessionId);
2085aaa44478a373232d8416657035a9020f9c7aa7c3Eric Laurent        }
208681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        sp<ThreadBase> thread = mThread.promote();
208781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        if (thread != 0) {
208881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            Mutex::Autolock _l(thread->mLock);
208981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            RecordThread *recordThread = (RecordThread *) thread.get();
209081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            recordThread->destroyTrack_l(this);
209181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        }
209281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    }
209381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
209481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
20959a54bc27876acd5d8be5b1fc3dc46701fe76fbb3Eric Laurentvoid AudioFlinger::RecordThread::RecordTrack::invalidate()
20969a54bc27876acd5d8be5b1fc3dc46701fe76fbb3Eric Laurent{
20979a54bc27876acd5d8be5b1fc3dc46701fe76fbb3Eric Laurent    // FIXME should use proxy, and needs work
20989a54bc27876acd5d8be5b1fc3dc46701fe76fbb3Eric Laurent    audio_track_cblk_t* cblk = mCblk;
20999a54bc27876acd5d8be5b1fc3dc46701fe76fbb3Eric Laurent    android_atomic_or(CBLK_INVALID, &cblk->mFlags);
21009a54bc27876acd5d8be5b1fc3dc46701fe76fbb3Eric Laurent    android_atomic_release_store(0x40000000, &cblk->mFutex);
21019a54bc27876acd5d8be5b1fc3dc46701fe76fbb3Eric Laurent    // client is not in server, so FUTEX_WAKE is needed instead of FUTEX_WAKE_PRIVATE
2102ee499291404a192b059f2e04c5afc65aa6cdd74cElliott Hughes    (void) syscall(__NR_futex, &cblk->mFutex, FUTEX_WAKE, INT_MAX);
21039a54bc27876acd5d8be5b1fc3dc46701fe76fbb3Eric Laurent}
21049a54bc27876acd5d8be5b1fc3dc46701fe76fbb3Eric Laurent
210581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
210681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent/*static*/ void AudioFlinger::RecordThread::RecordTrack::appendDumpHeader(String8& result)
210781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{
21086e6704c06d61bc356e30c164081e5bcffb37920cGlenn Kasten    result.append("    Active Client Fmt Chn mask Session S   Server fCount SRate\n");
210981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
211081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
2111b220884bf3129253cc5bc8d030bc475411ea4911Marco Nelissenvoid AudioFlinger::RecordThread::RecordTrack::dump(char* buffer, size_t size, bool active)
211281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{
21136e6704c06d61bc356e30c164081e5bcffb37920cGlenn Kasten    snprintf(buffer, size, "    %6s %6u %3u %08X %7u %1d %08X %6zu %5u\n",
2114b220884bf3129253cc5bc8d030bc475411ea4911Marco Nelissen            active ? "yes" : "no",
211581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            (mClient == 0) ? getpid_cached : mClient->pid(),
211681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            mFormat,
211781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            mChannelMask,
211881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            mSessionId,
211981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            mState,
2120f20e1d8df84c5fbeeace0052d100982ae39bb7a4Glenn Kasten            mCblk->mServer,
21216dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten            mFrameCount,
21226e6704c06d61bc356e30c164081e5bcffb37920cGlenn Kasten            mSampleRate);
21236dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten
212481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
212581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
212625f4aa83efaa9179e65a20583a6d441de2c3ff3fGlenn Kastenvoid AudioFlinger::RecordThread::RecordTrack::handleSyncStartEvent(const sp<SyncEvent>& event)
212725f4aa83efaa9179e65a20583a6d441de2c3ff3fGlenn Kasten{
212825f4aa83efaa9179e65a20583a6d441de2c3ff3fGlenn Kasten    if (event == mSyncStartEvent) {
212925f4aa83efaa9179e65a20583a6d441de2c3ff3fGlenn Kasten        ssize_t framesToDrop = 0;
213025f4aa83efaa9179e65a20583a6d441de2c3ff3fGlenn Kasten        sp<ThreadBase> threadBase = mThread.promote();
213125f4aa83efaa9179e65a20583a6d441de2c3ff3fGlenn Kasten        if (threadBase != 0) {
213225f4aa83efaa9179e65a20583a6d441de2c3ff3fGlenn Kasten            // TODO: use actual buffer filling status instead of 2 buffers when info is available
213325f4aa83efaa9179e65a20583a6d441de2c3ff3fGlenn Kasten            // from audio HAL
213425f4aa83efaa9179e65a20583a6d441de2c3ff3fGlenn Kasten            framesToDrop = threadBase->mFrameCount * 2;
213525f4aa83efaa9179e65a20583a6d441de2c3ff3fGlenn Kasten        }
213625f4aa83efaa9179e65a20583a6d441de2c3ff3fGlenn Kasten        mFramesToDrop = framesToDrop;
213725f4aa83efaa9179e65a20583a6d441de2c3ff3fGlenn Kasten    }
213825f4aa83efaa9179e65a20583a6d441de2c3ff3fGlenn Kasten}
213925f4aa83efaa9179e65a20583a6d441de2c3ff3fGlenn Kasten
214025f4aa83efaa9179e65a20583a6d441de2c3ff3fGlenn Kastenvoid AudioFlinger::RecordThread::RecordTrack::clearSyncStartEvent()
214125f4aa83efaa9179e65a20583a6d441de2c3ff3fGlenn Kasten{
214225f4aa83efaa9179e65a20583a6d441de2c3ff3fGlenn Kasten    if (mSyncStartEvent != 0) {
214325f4aa83efaa9179e65a20583a6d441de2c3ff3fGlenn Kasten        mSyncStartEvent->cancel();
214425f4aa83efaa9179e65a20583a6d441de2c3ff3fGlenn Kasten        mSyncStartEvent.clear();
214525f4aa83efaa9179e65a20583a6d441de2c3ff3fGlenn Kasten    }
214625f4aa83efaa9179e65a20583a6d441de2c3ff3fGlenn Kasten    mFramesToDrop = 0;
214725f4aa83efaa9179e65a20583a6d441de2c3ff3fGlenn Kasten}
214825f4aa83efaa9179e65a20583a6d441de2c3ff3fGlenn Kasten
214983b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent
215083b8808faad1e91690c64d7007348be8d9ebde73Eric LaurentAudioFlinger::RecordThread::PatchRecord::PatchRecord(RecordThread *recordThread,
215183b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent                                                     uint32_t sampleRate,
215283b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent                                                     audio_channel_mask_t channelMask,
215383b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent                                                     audio_format_t format,
215483b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent                                                     size_t frameCount,
215583b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent                                                     void *buffer,
215683b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent                                                     IAudioFlinger::track_flags_t flags)
215783b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent    :   RecordTrack(recordThread, NULL, sampleRate, format, channelMask, frameCount,
215883b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent                buffer, 0, getuid(), flags, TYPE_PATCH),
215983b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent                mProxy(new ClientProxy(mCblk, mBuffer, frameCount, mFrameSize, false, true))
216083b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent{
216183b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent    uint64_t mixBufferNs = ((uint64_t)2 * recordThread->frameCount() * 1000000000) /
216283b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent                                                                recordThread->sampleRate();
216383b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent    mPeerTimeout.tv_sec = mixBufferNs / 1000000000;
216483b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent    mPeerTimeout.tv_nsec = (int) (mixBufferNs % 1000000000);
216583b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent
216683b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent    ALOGV("PatchRecord %p sampleRate %d mPeerTimeout %d.%03d sec",
216783b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent                                      this, sampleRate,
216883b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent                                      (int)mPeerTimeout.tv_sec,
216983b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent                                      (int)(mPeerTimeout.tv_nsec / 1000000));
217083b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent}
217183b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent
217283b8808faad1e91690c64d7007348be8d9ebde73Eric LaurentAudioFlinger::RecordThread::PatchRecord::~PatchRecord()
217383b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent{
217483b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent}
217583b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent
217683b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent// AudioBufferProvider interface
217783b8808faad1e91690c64d7007348be8d9ebde73Eric Laurentstatus_t AudioFlinger::RecordThread::PatchRecord::getNextBuffer(
217883b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent                                                  AudioBufferProvider::Buffer* buffer, int64_t pts)
217983b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent{
218083b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent    ALOG_ASSERT(mPeerProxy != 0, "PatchRecord::getNextBuffer() called without peer proxy");
218183b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent    Proxy::Buffer buf;
218283b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent    buf.mFrameCount = buffer->frameCount;
218383b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent    status_t status = mPeerProxy->obtainBuffer(&buf, &mPeerTimeout);
218483b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent    ALOGV_IF(status != NO_ERROR,
218583b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent             "PatchRecord() %p mPeerProxy->obtainBuffer status %d", this, status);
2186c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent    buffer->frameCount = buf.mFrameCount;
218783b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent    if (buf.mFrameCount == 0) {
218883b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent        return WOULD_BLOCK;
218983b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent    }
219083b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent    status = RecordTrack::getNextBuffer(buffer, pts);
219183b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent    return status;
219283b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent}
219383b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent
219483b8808faad1e91690c64d7007348be8d9ebde73Eric Laurentvoid AudioFlinger::RecordThread::PatchRecord::releaseBuffer(AudioBufferProvider::Buffer* buffer)
219583b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent{
219683b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent    ALOG_ASSERT(mPeerProxy != 0, "PatchRecord::releaseBuffer() called without peer proxy");
219783b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent    Proxy::Buffer buf;
219883b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent    buf.mFrameCount = buffer->frameCount;
219983b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent    buf.mRaw = buffer->raw;
220083b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent    mPeerProxy->releaseBuffer(&buf);
220183b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent    TrackBase::releaseBuffer(buffer);
220283b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent}
220383b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent
220483b8808faad1e91690c64d7007348be8d9ebde73Eric Laurentstatus_t AudioFlinger::RecordThread::PatchRecord::obtainBuffer(Proxy::Buffer* buffer,
220583b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent                                                               const struct timespec *timeOut)
220683b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent{
220783b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent    return mProxy->obtainBuffer(buffer, timeOut);
220883b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent}
220983b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent
221083b8808faad1e91690c64d7007348be8d9ebde73Eric Laurentvoid AudioFlinger::RecordThread::PatchRecord::releaseBuffer(Proxy::Buffer* buffer)
221183b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent{
221283b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent    mProxy->releaseBuffer(buffer);
221383b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent}
221483b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent
221581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}; // namespace android
2216