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"
23ad8510a339ffab330c2c46e5c247dd1cf9e15c22Glenn Kasten#include <linux/futex.h>
2481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent#include <math.h>
25ee499291404a192b059f2e04c5afc65aa6cdd74cElliott Hughes#include <sys/syscall.h>
2681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent#include <utils/Log.h>
2781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
2881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent#include <private/media/AudioTrackShared.h>
2981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
3081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent#include "AudioFlinger.h"
3181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent#include "ServiceUtilities.h"
3281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
33da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten#include <media/nbaio/Pipe.h>
34da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten#include <media/nbaio/PipeReader.h>
358981605d43e24c46d395acb5f145b99589d45917Andy Hung#include <media/RecordBufferConverter.h>
36c56f3426099a3cf2d07ccff8886050c7fbce140fGlenn Kasten#include <audio_utils/minifloat.h>
37da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten
3881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// ----------------------------------------------------------------------------
3981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
4081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// Note: the following macro is used for extremely verbose logging message.  In
4181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// order to run with ALOG_ASSERT turned on, we need to have LOG_NDEBUG set to
4281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// 0; but one side effect of this is to turn all LOGV's as well.  Some messages
4381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// are so verbose that we want to suppress them even when we have ALOG_ASSERT
4481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// turned on.  Do not uncomment the #def below unless you really know what you
4581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// are doing and want to see all of the extremely verbose messages.
4681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent//#define VERY_VERY_VERBOSE_LOGGING
4781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent#ifdef VERY_VERY_VERBOSE_LOGGING
4881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent#define ALOGVV ALOGV
4981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent#else
5081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent#define ALOGVV(a...) do { } while(0)
5181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent#endif
5281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
53e10393e72454bfd8298017dc193faf424f4e9a8fAndy Hung// TODO move to a common header  (Also shared with AudioTrack.cpp)
54e10393e72454bfd8298017dc193faf424f4e9a8fAndy Hung#define NANOS_PER_SECOND    1000000000
559a3fbd9f84656ca25acdfd202ef7d4461a640f74Chih-Hung Hsieh#define TIME_TO_NANOS(time) ((uint64_t)(time).tv_sec * NANOS_PER_SECOND + (time).tv_nsec)
56e10393e72454bfd8298017dc193faf424f4e9a8fAndy Hung
5781784c37c61b09289654b979567a42bf73cd2b12Eric Laurentnamespace android {
5881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
5981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// ----------------------------------------------------------------------------
6081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent//      TrackBase
6181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// ----------------------------------------------------------------------------
6281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
63da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kastenstatic volatile int32_t nextTrackId = 55;
64da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten
6581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// TrackBase constructor must be called with AudioFlinger::mLock held
6681784c37c61b09289654b979567a42bf73cd2b12Eric LaurentAudioFlinger::ThreadBase::TrackBase::TrackBase(
6781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            ThreadBase *thread,
6881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            const sp<Client>& client,
6981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            uint32_t sampleRate,
7081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            audio_format_t format,
7181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            audio_channel_mask_t channelMask,
7281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            size_t frameCount,
7383b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent            void *buffer,
74d848eb48c121c119e8ba7583efc75415fe102570Glenn Kasten            audio_session_t sessionId,
751f12a8ad958344c50733b948628ffa06db9c5bc6Andy Hung            uid_t clientUid,
76d776ac63ce9c013c9626226e43f7db606e035838Glenn Kasten            bool isOut,
7783b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent            alloc_type alloc,
7820b9ef0b55c9150ae11057ab997ae61be2d496efEric Laurent            track_type type,
7920b9ef0b55c9150ae11057ab997ae61be2d496efEric Laurent            audio_port_handle_t portId)
8081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    :   RefBase(),
8181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        mThread(thread),
8281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        mClient(client),
8381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        mCblk(NULL),
8481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        // mBuffer
8581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        mState(IDLE),
8681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        mSampleRate(sampleRate),
8781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        mFormat(format),
8881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        mChannelMask(channelMask),
89e541269be94f3a1072932d51537905b120ef4733Andy Hung        mChannelCount(isOut ?
90e541269be94f3a1072932d51537905b120ef4733Andy Hung                audio_channel_count_from_out_mask(channelMask) :
91e541269be94f3a1072932d51537905b120ef4733Andy Hung                audio_channel_count_from_in_mask(channelMask)),
92fdb3c07db5d44535eb8c3ec46dc78ad8446c01ebPhil Burk        mFrameSize(audio_has_proportional_frames(format) ?
9381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                mChannelCount * audio_bytes_per_sample(format) : sizeof(int8_t)),
9481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        mFrameCount(frameCount),
95e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten        mSessionId(sessionId),
96e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten        mIsOut(isOut),
97bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent        mId(android_atomic_inc(&nextTrackId)),
9883b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent        mTerminated(false),
99aaa44478a373232d8416657035a9020f9c7aa7c3Eric Laurent        mType(type),
10020b9ef0b55c9150ae11057ab997ae61be2d496efEric Laurent        mThreadIoHandle(thread->id()),
1016acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent        mPortId(portId),
1026acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent        mIsInvalid(false)
10381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{
104dcb346b7dc5b88c3e85db8a70bbd6a2fee8192b9Marco Nelissen    const uid_t callingUid = IPCThreadState::self()->getCallingUid();
1051f12a8ad958344c50733b948628ffa06db9c5bc6Andy Hung    if (!isTrustedCallingUid(callingUid) || clientUid == AUDIO_UID_INVALID) {
1061f12a8ad958344c50733b948628ffa06db9c5bc6Andy Hung        ALOGW_IF(clientUid != AUDIO_UID_INVALID && clientUid != callingUid,
107dcb346b7dc5b88c3e85db8a70bbd6a2fee8192b9Marco Nelissen                "%s uid %d tried to pass itself off as %d", __FUNCTION__, callingUid, clientUid);
1081f12a8ad958344c50733b948628ffa06db9c5bc6Andy Hung        clientUid = callingUid;
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);
1151883f69de5f2c4e71df58d5b71d7c39f9779b50cAndy Hung
1161883f69de5f2c4e71df58d5b71d7c39f9779b50cAndy Hung    size_t bufferSize = buffer == NULL ? roundup(frameCount) : frameCount;
1171883f69de5f2c4e71df58d5b71d7c39f9779b50cAndy Hung    // check overflow when computing bufferSize due to multiplication by mFrameSize.
1181883f69de5f2c4e71df58d5b71d7c39f9779b50cAndy Hung    if (bufferSize < frameCount  // roundup rounds down for values above UINT_MAX / 2
1191883f69de5f2c4e71df58d5b71d7c39f9779b50cAndy Hung            || mFrameSize == 0   // format needs to be correct
1201883f69de5f2c4e71df58d5b71d7c39f9779b50cAndy Hung            || bufferSize > SIZE_MAX / mFrameSize) {
1211883f69de5f2c4e71df58d5b71d7c39f9779b50cAndy Hung        android_errorWriteLog(0x534e4554, "34749571");
1221883f69de5f2c4e71df58d5b71d7c39f9779b50cAndy Hung        return;
1231883f69de5f2c4e71df58d5b71d7c39f9779b50cAndy Hung    }
1241883f69de5f2c4e71df58d5b71d7c39f9779b50cAndy Hung    bufferSize *= mFrameSize;
1251883f69de5f2c4e71df58d5b71d7c39f9779b50cAndy Hung
12681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    size_t size = sizeof(audio_track_cblk_t);
12783b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent    if (buffer == NULL && alloc == ALLOC_CBLK) {
1281883f69de5f2c4e71df58d5b71d7c39f9779b50cAndy Hung        // check overflow when computing allocation size for streaming tracks.
1291883f69de5f2c4e71df58d5b71d7c39f9779b50cAndy Hung        if (size > SIZE_MAX - bufferSize) {
1301883f69de5f2c4e71df58d5b71d7c39f9779b50cAndy Hung            android_errorWriteLog(0x534e4554, "34749571");
1311883f69de5f2c4e71df58d5b71d7c39f9779b50cAndy Hung            return;
1321883f69de5f2c4e71df58d5b71d7c39f9779b50cAndy Hung        }
13381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        size += bufferSize;
13481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    }
13581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
13681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    if (client != 0) {
13781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        mCblkMemory = client->heap()->allocate(size);
138663c2247b71086e30bfd3192979d1dd7f15c539eGlenn Kasten        if (mCblkMemory == 0 ||
139663c2247b71086e30bfd3192979d1dd7f15c539eGlenn Kasten                (mCblk = static_cast<audio_track_cblk_t *>(mCblkMemory->pointer())) == NULL) {
140c42e9b462661673dff480ee71757a58b0f806370Glenn Kasten            ALOGE("not enough memory for AudioTrack size=%zu", size);
14181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            client->heap()->dump("AudioTrack");
142663c2247b71086e30bfd3192979d1dd7f15c539eGlenn Kasten            mCblkMemory.clear();
14381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            return;
14481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        }
14581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    } else {
146afb31487f3156a7284d2f0d06646c7bc00d99537Andy Hung        mCblk = (audio_track_cblk_t *) malloc(size);
147afb31487f3156a7284d2f0d06646c7bc00d99537Andy Hung        if (mCblk == NULL) {
148afb31487f3156a7284d2f0d06646c7bc00d99537Andy Hung            ALOGE("not enough memory for AudioTrack size=%zu", size);
149afb31487f3156a7284d2f0d06646c7bc00d99537Andy Hung            return;
150afb31487f3156a7284d2f0d06646c7bc00d99537Andy Hung        }
15181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    }
15281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
15381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    // construct the shared structure in-place.
15481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    if (mCblk != NULL) {
15581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        new(mCblk) audio_track_cblk_t();
156c263ca0ad8b6bdf5b0693996bc5f2f5916e0cd49Glenn Kasten        switch (alloc) {
157c263ca0ad8b6bdf5b0693996bc5f2f5916e0cd49Glenn Kasten        case ALLOC_READONLY: {
158d776ac63ce9c013c9626226e43f7db606e035838Glenn Kasten            const sp<MemoryDealer> roHeap(thread->readOnlyHeap());
159d776ac63ce9c013c9626226e43f7db606e035838Glenn Kasten            if (roHeap == 0 ||
160d776ac63ce9c013c9626226e43f7db606e035838Glenn Kasten                    (mBufferMemory = roHeap->allocate(bufferSize)) == 0 ||
161d776ac63ce9c013c9626226e43f7db606e035838Glenn Kasten                    (mBuffer = mBufferMemory->pointer()) == NULL) {
162d776ac63ce9c013c9626226e43f7db606e035838Glenn Kasten                ALOGE("not enough memory for read-only buffer size=%zu", bufferSize);
163d776ac63ce9c013c9626226e43f7db606e035838Glenn Kasten                if (roHeap != 0) {
164d776ac63ce9c013c9626226e43f7db606e035838Glenn Kasten                    roHeap->dump("buffer");
165d776ac63ce9c013c9626226e43f7db606e035838Glenn Kasten                }
166d776ac63ce9c013c9626226e43f7db606e035838Glenn Kasten                mCblkMemory.clear();
167d776ac63ce9c013c9626226e43f7db606e035838Glenn Kasten                mBufferMemory.clear();
168d776ac63ce9c013c9626226e43f7db606e035838Glenn Kasten                return;
169d776ac63ce9c013c9626226e43f7db606e035838Glenn Kasten            }
17081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            memset(mBuffer, 0, bufferSize);
171c263ca0ad8b6bdf5b0693996bc5f2f5916e0cd49Glenn Kasten            } break;
172c263ca0ad8b6bdf5b0693996bc5f2f5916e0cd49Glenn Kasten        case ALLOC_PIPE:
173c263ca0ad8b6bdf5b0693996bc5f2f5916e0cd49Glenn Kasten            mBufferMemory = thread->pipeMemory();
174c263ca0ad8b6bdf5b0693996bc5f2f5916e0cd49Glenn Kasten            // mBuffer is the virtual address as seen from current process (mediaserver),
175c263ca0ad8b6bdf5b0693996bc5f2f5916e0cd49Glenn Kasten            // and should normally be coming from mBufferMemory->pointer().
176c263ca0ad8b6bdf5b0693996bc5f2f5916e0cd49Glenn Kasten            // However in this case the TrackBase does not reference the buffer directly.
177c263ca0ad8b6bdf5b0693996bc5f2f5916e0cd49Glenn Kasten            // It should references the buffer via the pipe.
178c263ca0ad8b6bdf5b0693996bc5f2f5916e0cd49Glenn Kasten            // Therefore, to detect incorrect usage of the buffer, we set mBuffer to NULL.
179c263ca0ad8b6bdf5b0693996bc5f2f5916e0cd49Glenn Kasten            mBuffer = NULL;
180c263ca0ad8b6bdf5b0693996bc5f2f5916e0cd49Glenn Kasten            break;
181c263ca0ad8b6bdf5b0693996bc5f2f5916e0cd49Glenn Kasten        case ALLOC_CBLK:
182d776ac63ce9c013c9626226e43f7db606e035838Glenn Kasten            // clear all buffers
18383b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent            if (buffer == NULL) {
184d776ac63ce9c013c9626226e43f7db606e035838Glenn Kasten                mBuffer = (char*)mCblk + sizeof(audio_track_cblk_t);
185d776ac63ce9c013c9626226e43f7db606e035838Glenn Kasten                memset(mBuffer, 0, bufferSize);
186d776ac63ce9c013c9626226e43f7db606e035838Glenn Kasten            } else {
18783b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent                mBuffer = buffer;
1889f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten#if 0
189d776ac63ce9c013c9626226e43f7db606e035838Glenn Kasten                mCblk->mFlags = CBLK_FORCEREADY;    // FIXME hack, need to fix the track ready logic
1909f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten#endif
191d776ac63ce9c013c9626226e43f7db606e035838Glenn Kasten            }
192c263ca0ad8b6bdf5b0693996bc5f2f5916e0cd49Glenn Kasten            break;
19383b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent        case ALLOC_LOCAL:
19483b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent            mBuffer = calloc(1, bufferSize);
19583b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent            break;
19683b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent        case ALLOC_NONE:
19783b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent            mBuffer = buffer;
19883b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent            break;
19981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        }
200da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten
20146909e7eb074ce1b95b8a411eb71154f53f84f77Glenn Kasten#ifdef TEE_SINK
202da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten        if (mTeeSinkTrackEnabled) {
203329f6511ee4e03a4605c70bbda8d3a96d2544884Glenn Kasten            NBAIO_Format pipeFormat = Format_from_SR_C(mSampleRate, mChannelCount, mFormat);
2046e0d67d7b496ce17c0970a4ffd3a6f808860949cGlenn Kasten            if (Format_isValid(pipeFormat)) {
20546909e7eb074ce1b95b8a411eb71154f53f84f77Glenn Kasten                Pipe *pipe = new Pipe(mTeeSinkTrackFrames, pipeFormat);
20646909e7eb074ce1b95b8a411eb71154f53f84f77Glenn Kasten                size_t numCounterOffers = 0;
20746909e7eb074ce1b95b8a411eb71154f53f84f77Glenn Kasten                const NBAIO_Format offers[1] = {pipeFormat};
20846909e7eb074ce1b95b8a411eb71154f53f84f77Glenn Kasten                ssize_t index = pipe->negotiate(offers, 1, NULL, numCounterOffers);
20946909e7eb074ce1b95b8a411eb71154f53f84f77Glenn Kasten                ALOG_ASSERT(index == 0);
21046909e7eb074ce1b95b8a411eb71154f53f84f77Glenn Kasten                PipeReader *pipeReader = new PipeReader(*pipe);
21146909e7eb074ce1b95b8a411eb71154f53f84f77Glenn Kasten                numCounterOffers = 0;
21246909e7eb074ce1b95b8a411eb71154f53f84f77Glenn Kasten                index = pipeReader->negotiate(offers, 1, NULL, numCounterOffers);
21346909e7eb074ce1b95b8a411eb71154f53f84f77Glenn Kasten                ALOG_ASSERT(index == 0);
21446909e7eb074ce1b95b8a411eb71154f53f84f77Glenn Kasten                mTeeSink = pipe;
21546909e7eb074ce1b95b8a411eb71154f53f84f77Glenn Kasten                mTeeSource = pipeReader;
21646909e7eb074ce1b95b8a411eb71154f53f84f77Glenn Kasten            }
217da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten        }
21846909e7eb074ce1b95b8a411eb71154f53f84f77Glenn Kasten#endif
219da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten
22081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    }
22181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
22281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
22383b8808faad1e91690c64d7007348be8d9ebde73Eric Laurentstatus_t AudioFlinger::ThreadBase::TrackBase::initCheck() const
22483b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent{
22583b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent    status_t status;
22683b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent    if (mType == TYPE_OUTPUT || mType == TYPE_PATCH) {
22783b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent        status = cblk() != NULL ? NO_ERROR : NO_MEMORY;
22883b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent    } else {
22983b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent        status = getCblk() != 0 ? NO_ERROR : NO_MEMORY;
23083b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent    }
23183b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent    return status;
23283b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent}
23383b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent
23481784c37c61b09289654b979567a42bf73cd2b12Eric LaurentAudioFlinger::ThreadBase::TrackBase::~TrackBase()
23581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{
23646909e7eb074ce1b95b8a411eb71154f53f84f77Glenn Kasten#ifdef TEE_SINK
237da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten    dumpTee(-1, mTeeSource, mId);
23846909e7eb074ce1b95b8a411eb71154f53f84f77Glenn Kasten#endif
239e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten    // delete the proxy before deleting the shared memory it refers to, to avoid dangling reference
2405bba2f6916dbe00aea7c0521faa0c6ed42114a75Eric Laurent    mServerProxy.clear();
24181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    if (mCblk != NULL) {
242afb31487f3156a7284d2f0d06646c7bc00d99537Andy Hung        mCblk->~audio_track_cblk_t();   // destroy our shared-structure.
24381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        if (mClient == 0) {
244afb31487f3156a7284d2f0d06646c7bc00d99537Andy Hung            free(mCblk);
24581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        }
24681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    }
24781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    mCblkMemory.clear();    // free the shared memory before releasing the heap it belongs to
24881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    if (mClient != 0) {
249021cf9634ab09c0753a40b7c9ef4ba603be5c3daEric Laurent        // Client destructor must run with AudioFlinger client mutex locked
250021cf9634ab09c0753a40b7c9ef4ba603be5c3daEric Laurent        Mutex::Autolock _l(mClient->audioFlinger()->mClientLock);
25181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        // If the client's reference count drops to zero, the associated destructor
25281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        // must run with AudioFlinger lock held. Thus the explicit clear() rather than
25381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        // relying on the automatic clear() at end of scope.
25481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        mClient.clear();
25581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    }
2563bcffa136909c1fb6e88ee4efd12ccac18360a85Eric Laurent    // flush the binder command buffer
2573bcffa136909c1fb6e88ee4efd12ccac18360a85Eric Laurent    IPCThreadState::self()->flushCommands();
25881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
25981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
26081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// AudioBufferProvider interface
26181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// getNextBuffer() = 0;
262d79072e9dff59f767cce2cda1caab80ce5a0815bGlenn Kasten// This implementation of releaseBuffer() is used by Track and RecordTrack
26381784c37c61b09289654b979567a42bf73cd2b12Eric Laurentvoid AudioFlinger::ThreadBase::TrackBase::releaseBuffer(AudioBufferProvider::Buffer* buffer)
26481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{
26546909e7eb074ce1b95b8a411eb71154f53f84f77Glenn Kasten#ifdef TEE_SINK
266da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten    if (mTeeSink != 0) {
267da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten        (void) mTeeSink->write(buffer->raw, buffer->frameCount);
268da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten    }
26946909e7eb074ce1b95b8a411eb71154f53f84f77Glenn Kasten#endif
270da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten
2719f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    ServerProxy::Buffer buf;
2729f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    buf.mFrameCount = buffer->frameCount;
2739f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    buf.mRaw = buffer->raw;
27481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    buffer->frameCount = 0;
2759f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    buffer->raw = NULL;
2769f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    mServerProxy->releaseBuffer(&buf);
27781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
27881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
27981784c37c61b09289654b979567a42bf73cd2b12Eric Laurentstatus_t AudioFlinger::ThreadBase::TrackBase::setSyncEvent(const sp<SyncEvent>& event)
28081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{
28181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    mSyncEvents.add(event);
28281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    return NO_ERROR;
28381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
28481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
28581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// ----------------------------------------------------------------------------
28681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent//      Playback
28781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// ----------------------------------------------------------------------------
28881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
28981784c37c61b09289654b979567a42bf73cd2b12Eric LaurentAudioFlinger::TrackHandle::TrackHandle(const sp<AudioFlinger::PlaybackThread::Track>& track)
29081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    : BnAudioTrack(),
29181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent      mTrack(track)
29281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{
29381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
29481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
29581784c37c61b09289654b979567a42bf73cd2b12Eric LaurentAudioFlinger::TrackHandle::~TrackHandle() {
29681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    // just stop the track on deletion, associated resources
29781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    // will be freed from the main thread once all pending buffers have
29881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    // been played. Unless it's not in the active track list, in which
29981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    // case we free everything now...
30081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    mTrack->destroy();
30181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
30281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
30381784c37c61b09289654b979567a42bf73cd2b12Eric Laurentsp<IMemory> AudioFlinger::TrackHandle::getCblk() const {
30481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    return mTrack->getCblk();
30581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
30681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
30781784c37c61b09289654b979567a42bf73cd2b12Eric Laurentstatus_t AudioFlinger::TrackHandle::start() {
30881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    return mTrack->start();
30981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
31081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
31181784c37c61b09289654b979567a42bf73cd2b12Eric Laurentvoid AudioFlinger::TrackHandle::stop() {
31281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    mTrack->stop();
31381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
31481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
31581784c37c61b09289654b979567a42bf73cd2b12Eric Laurentvoid AudioFlinger::TrackHandle::flush() {
31681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    mTrack->flush();
31781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
31881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
31981784c37c61b09289654b979567a42bf73cd2b12Eric Laurentvoid AudioFlinger::TrackHandle::pause() {
32081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    mTrack->pause();
32181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
32281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
32381784c37c61b09289654b979567a42bf73cd2b12Eric Laurentstatus_t AudioFlinger::TrackHandle::attachAuxEffect(int EffectId)
32481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{
32581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    return mTrack->attachAuxEffect(EffectId);
32681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
32781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
3283dcd00dddec86a1c5133083ad7ba2265d49c048cGlenn Kastenstatus_t AudioFlinger::TrackHandle::setParameters(const String8& keyValuePairs) {
3293dcd00dddec86a1c5133083ad7ba2265d49c048cGlenn Kasten    return mTrack->setParameters(keyValuePairs);
3303dcd00dddec86a1c5133083ad7ba2265d49c048cGlenn Kasten}
3313dcd00dddec86a1c5133083ad7ba2265d49c048cGlenn Kasten
3329fc8b5cd4a64ef07e84c69112461324d5c13a0b0Andy HungVolumeShaper::Status AudioFlinger::TrackHandle::applyVolumeShaper(
3339fc8b5cd4a64ef07e84c69112461324d5c13a0b0Andy Hung        const sp<VolumeShaper::Configuration>& configuration,
3349fc8b5cd4a64ef07e84c69112461324d5c13a0b0Andy Hung        const sp<VolumeShaper::Operation>& operation) {
3359fc8b5cd4a64ef07e84c69112461324d5c13a0b0Andy Hung    return mTrack->applyVolumeShaper(configuration, operation);
3369fc8b5cd4a64ef07e84c69112461324d5c13a0b0Andy Hung}
3379fc8b5cd4a64ef07e84c69112461324d5c13a0b0Andy Hung
3389fc8b5cd4a64ef07e84c69112461324d5c13a0b0Andy Hungsp<VolumeShaper::State> AudioFlinger::TrackHandle::getVolumeShaperState(int id) {
3399fc8b5cd4a64ef07e84c69112461324d5c13a0b0Andy Hung    return mTrack->getVolumeShaperState(id);
3409fc8b5cd4a64ef07e84c69112461324d5c13a0b0Andy Hung}
3419fc8b5cd4a64ef07e84c69112461324d5c13a0b0Andy Hung
34253cec22821072719ee02c856e9ac2dda2496c570Glenn Kastenstatus_t AudioFlinger::TrackHandle::getTimestamp(AudioTimestamp& timestamp)
34353cec22821072719ee02c856e9ac2dda2496c570Glenn Kasten{
344573d80a8f463f648a515fc0975bf83951b272993Glenn Kasten    return mTrack->getTimestamp(timestamp);
34553cec22821072719ee02c856e9ac2dda2496c570Glenn Kasten}
34653cec22821072719ee02c856e9ac2dda2496c570Glenn Kasten
34759fe010bcc072597852454a2ec53d7b0a2002a3bEric Laurent
34859fe010bcc072597852454a2ec53d7b0a2002a3bEric Laurentvoid AudioFlinger::TrackHandle::signal()
34959fe010bcc072597852454a2ec53d7b0a2002a3bEric Laurent{
35059fe010bcc072597852454a2ec53d7b0a2002a3bEric Laurent    return mTrack->signal();
35159fe010bcc072597852454a2ec53d7b0a2002a3bEric Laurent}
35259fe010bcc072597852454a2ec53d7b0a2002a3bEric Laurent
35381784c37c61b09289654b979567a42bf73cd2b12Eric Laurentstatus_t AudioFlinger::TrackHandle::onTransact(
35481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
35581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{
35681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    return BnAudioTrack::onTransact(code, data, reply, flags);
35781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
35881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
35981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// ----------------------------------------------------------------------------
36081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
36181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// Track constructor must be called with AudioFlinger::mLock and ThreadBase::mLock held
36281784c37c61b09289654b979567a42bf73cd2b12Eric LaurentAudioFlinger::PlaybackThread::Track::Track(
36381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            PlaybackThread *thread,
36481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            const sp<Client>& client,
36581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            audio_stream_type_t streamType,
36681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            uint32_t sampleRate,
36781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            audio_format_t format,
36881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            audio_channel_mask_t channelMask,
36981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            size_t frameCount,
37083b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent            void *buffer,
37181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            const sp<IMemory>& sharedBuffer,
372d848eb48c121c119e8ba7583efc75415fe102570Glenn Kasten            audio_session_t sessionId,
3731f12a8ad958344c50733b948628ffa06db9c5bc6Andy Hung            uid_t uid,
374050677873c10d4da308ac222f8533c96cca3207eEric Laurent            audio_output_flags_t flags,
37520b9ef0b55c9150ae11057ab997ae61be2d496efEric Laurent            track_type type,
37620b9ef0b55c9150ae11057ab997ae61be2d496efEric Laurent            audio_port_handle_t portId)
37783b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent    :   TrackBase(thread, client, sampleRate, format, channelMask, frameCount,
37883b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent                  (sharedBuffer != 0) ? sharedBuffer->pointer() : buffer,
379050677873c10d4da308ac222f8533c96cca3207eEric Laurent                  sessionId, uid, true /*isOut*/,
38083b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent                  (type == TYPE_PATCH) ? ( buffer == NULL ? ALLOC_LOCAL : ALLOC_NONE) : ALLOC_CBLK,
38120b9ef0b55c9150ae11057ab997ae61be2d496efEric Laurent                  type, portId),
38281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    mFillingUpStatus(FS_INVALID),
38381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    // mRetryCount initialized later when needed
38481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    mSharedBuffer(sharedBuffer),
38581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    mStreamType(streamType),
38681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    mName(-1),  // see note below
38781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    mMainBuffer(thread->mixBuffer()),
38881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    mAuxBuffer(NULL),
38981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    mAuxEffectId(0), mHasVolumeController(false),
39081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    mPresentationCompleteFrames(0),
391e10393e72454bfd8298017dc193faf424f4e9a8fAndy Hung    mFrameMap(16 /* sink-frame-to-track-frame map memory */),
3929fc8b5cd4a64ef07e84c69112461324d5c13a0b0Andy Hung    mVolumeHandler(new VolumeHandler(sampleRate)),
393e10393e72454bfd8298017dc193faf424f4e9a8fAndy Hung    // mSinkTimestamp
39481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    mFastIndex(-1),
3955736c35b841de56ce394b4879389f669b61425e6Glenn Kasten    mCachedVolume(1.0),
3967844f679be8d94c5cdf017f53754cb68ee2f00daHaynes Mathew George    mResumeToStopping(false),
397050677873c10d4da308ac222f8533c96cca3207eEric Laurent    mFlushHwPending(false),
398050677873c10d4da308ac222f8533c96cca3207eEric Laurent    mFlags(flags)
39981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{
40083b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent    // client == 0 implies sharedBuffer == 0
40183b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent    ALOG_ASSERT(!(client == 0 && sharedBuffer != 0));
40283b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent
403e93cc03da360a1a0d2ad937c745ce8c8e8be81c2Eric Laurent    ALOGV_IF(sharedBuffer != 0, "sharedBuffer: %p, size: %zu", sharedBuffer->pointer(),
40483b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent            sharedBuffer->size());
40583b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent
4063ef14ef30359376006a233f6a21a165d4b65a7dfGlenn Kasten    if (mCblk == NULL) {
4073ef14ef30359376006a233f6a21a165d4b65a7dfGlenn Kasten        return;
4083ef14ef30359376006a233f6a21a165d4b65a7dfGlenn Kasten    }
4093ef14ef30359376006a233f6a21a165d4b65a7dfGlenn Kasten
4103ef14ef30359376006a233f6a21a165d4b65a7dfGlenn Kasten    if (sharedBuffer == 0) {
4113ef14ef30359376006a233f6a21a165d4b65a7dfGlenn Kasten        mAudioTrackServerProxy = new AudioTrackServerProxy(mCblk, mBuffer, frameCount,
41283b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent                mFrameSize, !isExternalTrack(), sampleRate);
4133ef14ef30359376006a233f6a21a165d4b65a7dfGlenn Kasten    } else {
414f4aeab2bd69bead05ed75ae3254f53a6ab2316b5Andy Hung        // Is the shared buffer of sufficient size?
415f4aeab2bd69bead05ed75ae3254f53a6ab2316b5Andy Hung        // (frameCount * mFrameSize) is <= SIZE_MAX, checked in TrackBase.
416f4aeab2bd69bead05ed75ae3254f53a6ab2316b5Andy Hung        if (sharedBuffer->size() < frameCount * mFrameSize) {
417f4aeab2bd69bead05ed75ae3254f53a6ab2316b5Andy Hung            // Workaround: clear out mCblk to indicate track hasn't been properly created.
418f4aeab2bd69bead05ed75ae3254f53a6ab2316b5Andy Hung            mCblk->~audio_track_cblk_t();   // destroy our shared-structure.
419f4aeab2bd69bead05ed75ae3254f53a6ab2316b5Andy Hung            if (mClient == 0) {
420f4aeab2bd69bead05ed75ae3254f53a6ab2316b5Andy Hung                free(mCblk);
421f4aeab2bd69bead05ed75ae3254f53a6ab2316b5Andy Hung            }
422f4aeab2bd69bead05ed75ae3254f53a6ab2316b5Andy Hung            mCblk = NULL;
423f4aeab2bd69bead05ed75ae3254f53a6ab2316b5Andy Hung
424f4aeab2bd69bead05ed75ae3254f53a6ab2316b5Andy Hung            mSharedBuffer.clear(); // release shared buffer early
425f4aeab2bd69bead05ed75ae3254f53a6ab2316b5Andy Hung            android_errorWriteLog(0x534e4554, "38340117");
426f4aeab2bd69bead05ed75ae3254f53a6ab2316b5Andy Hung            return;
427f4aeab2bd69bead05ed75ae3254f53a6ab2316b5Andy Hung        }
428f4aeab2bd69bead05ed75ae3254f53a6ab2316b5Andy Hung
4293ef14ef30359376006a233f6a21a165d4b65a7dfGlenn Kasten        mAudioTrackServerProxy = new StaticAudioTrackServerProxy(mCblk, mBuffer, frameCount,
4303ef14ef30359376006a233f6a21a165d4b65a7dfGlenn Kasten                mFrameSize);
4313ef14ef30359376006a233f6a21a165d4b65a7dfGlenn Kasten    }
4323ef14ef30359376006a233f6a21a165d4b65a7dfGlenn Kasten    mServerProxy = mAudioTrackServerProxy;
4333ef14ef30359376006a233f6a21a165d4b65a7dfGlenn Kasten
434ad7dd9610b6fafa81baf69607f4ac669da88182aEric Laurent    mName = thread->getTrackName_l(channelMask, format, sessionId, uid);
4353ef14ef30359376006a233f6a21a165d4b65a7dfGlenn Kasten    if (mName < 0) {
4363ef14ef30359376006a233f6a21a165d4b65a7dfGlenn Kasten        ALOGE("no more track names available");
4373ef14ef30359376006a233f6a21a165d4b65a7dfGlenn Kasten        return;
4383ef14ef30359376006a233f6a21a165d4b65a7dfGlenn Kasten    }
4393ef14ef30359376006a233f6a21a165d4b65a7dfGlenn Kasten    // only allocate a fast track index if we were able to allocate a normal track name
440050677873c10d4da308ac222f8533c96cca3207eEric Laurent    if (flags & AUDIO_OUTPUT_FLAG_FAST) {
441a542782d0045588e55e075a763cedcd2d504ad22Andy Hung        // FIXME: Not calling framesReadyIsCalledByMultipleThreads() exposes a potential
442a542782d0045588e55e075a763cedcd2d504ad22Andy Hung        // race with setSyncEvent(). However, if we call it, we cannot properly start
443a542782d0045588e55e075a763cedcd2d504ad22Andy Hung        // static fast tracks (SoundPool) immediately after stopping.
444a542782d0045588e55e075a763cedcd2d504ad22Andy Hung        //mAudioTrackServerProxy->framesReadyIsCalledByMultipleThreads();
4453ef14ef30359376006a233f6a21a165d4b65a7dfGlenn Kasten        ALOG_ASSERT(thread->mFastTrackAvailMask != 0);
4463ef14ef30359376006a233f6a21a165d4b65a7dfGlenn Kasten        int i = __builtin_ctz(thread->mFastTrackAvailMask);
447dc2c50bad491d2c0c8a2efc0e24491076701c63cGlenn Kasten        ALOG_ASSERT(0 < i && i < (int)FastMixerState::sMaxFastTracks);
4483ef14ef30359376006a233f6a21a165d4b65a7dfGlenn Kasten        // FIXME This is too eager.  We allocate a fast track index before the
4493ef14ef30359376006a233f6a21a165d4b65a7dfGlenn Kasten        //       fast track becomes active.  Since fast tracks are a scarce resource,
4503ef14ef30359376006a233f6a21a165d4b65a7dfGlenn Kasten        //       this means we are potentially denying other more important fast tracks from
4513ef14ef30359376006a233f6a21a165d4b65a7dfGlenn Kasten        //       being created.  It would be better to allocate the index dynamically.
4523ef14ef30359376006a233f6a21a165d4b65a7dfGlenn Kasten        mFastIndex = i;
4533ef14ef30359376006a233f6a21a165d4b65a7dfGlenn Kasten        thread->mFastTrackAvailMask &= ~(1 << i);
45481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    }
45581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
45681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
45781784c37c61b09289654b979567a42bf73cd2b12Eric LaurentAudioFlinger::PlaybackThread::Track::~Track()
45881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{
45981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    ALOGV("PlaybackThread::Track destructor");
4600c72b24f91c68442eb374bd1b338c394105b8262Glenn Kasten
4610c72b24f91c68442eb374bd1b338c394105b8262Glenn Kasten    // The destructor would clear mSharedBuffer,
4620c72b24f91c68442eb374bd1b338c394105b8262Glenn Kasten    // but it will not push the decremented reference count,
4630c72b24f91c68442eb374bd1b338c394105b8262Glenn Kasten    // leaving the client's IMemory dangling indefinitely.
4640c72b24f91c68442eb374bd1b338c394105b8262Glenn Kasten    // This prevents that leak.
4650c72b24f91c68442eb374bd1b338c394105b8262Glenn Kasten    if (mSharedBuffer != 0) {
4660c72b24f91c68442eb374bd1b338c394105b8262Glenn Kasten        mSharedBuffer.clear();
4670c72b24f91c68442eb374bd1b338c394105b8262Glenn Kasten    }
46881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
46981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
470030033342a6ea17003e6af38a56c7edc6d2ead01Glenn Kastenstatus_t AudioFlinger::PlaybackThread::Track::initCheck() const
471030033342a6ea17003e6af38a56c7edc6d2ead01Glenn Kasten{
472030033342a6ea17003e6af38a56c7edc6d2ead01Glenn Kasten    status_t status = TrackBase::initCheck();
473030033342a6ea17003e6af38a56c7edc6d2ead01Glenn Kasten    if (status == NO_ERROR && mName < 0) {
474030033342a6ea17003e6af38a56c7edc6d2ead01Glenn Kasten        status = NO_MEMORY;
475030033342a6ea17003e6af38a56c7edc6d2ead01Glenn Kasten    }
476030033342a6ea17003e6af38a56c7edc6d2ead01Glenn Kasten    return status;
477030033342a6ea17003e6af38a56c7edc6d2ead01Glenn Kasten}
478030033342a6ea17003e6af38a56c7edc6d2ead01Glenn Kasten
47981784c37c61b09289654b979567a42bf73cd2b12Eric Laurentvoid AudioFlinger::PlaybackThread::Track::destroy()
48081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{
48181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    // NOTE: destroyTrack_l() can remove a strong reference to this Track
48281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    // by removing it from mTracks vector, so there is a risk that this Tracks's
48381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    // destructor is called. As the destructor needs to lock mLock,
48481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    // we must acquire a strong reference on this Track before locking mLock
48581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    // here so that the destructor is called only when exiting this function.
48681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    // On the other hand, as long as Track::destroy() is only called by
48781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    // TrackHandle destructor, the TrackHandle still holds a strong ref on
48881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    // this Track with its member mTrack.
48981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    sp<Track> keep(this);
49081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    { // scope for mLock
491aaa44478a373232d8416657035a9020f9c7aa7c3Eric Laurent        bool wasActive = false;
49281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        sp<ThreadBase> thread = mThread.promote();
49381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        if (thread != 0) {
49481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            Mutex::Autolock _l(thread->mLock);
49581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            PlaybackThread *playbackThread = (PlaybackThread *)thread.get();
496aaa44478a373232d8416657035a9020f9c7aa7c3Eric Laurent            wasActive = playbackThread->destroyTrack_l(this);
497aaa44478a373232d8416657035a9020f9c7aa7c3Eric Laurent        }
498aaa44478a373232d8416657035a9020f9c7aa7c3Eric Laurent        if (isExternalTrack() && !wasActive) {
499d848eb48c121c119e8ba7583efc75415fe102570Glenn Kasten            AudioSystem::releaseOutput(mThreadIoHandle, mStreamType, mSessionId);
50081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        }
50181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    }
50281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
50381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
50481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent/*static*/ void AudioFlinger::PlaybackThread::Track::appendDumpHeader(String8& result)
50581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{
506b220884bf3129253cc5bc8d030bc475411ea4911Marco Nelissen    result.append("    Name Active Client Type      Fmt Chn mask Session fCount S F SRate  "
507da540db0fc21bc9319d9602aefe1a109d00a7e6cAndy Hung                  "L dB  R dB  VS dB    Server Main buf  Aux buf Flags UndFrmCnt  Flushed\n");
50881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
50981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
510b220884bf3129253cc5bc8d030bc475411ea4911Marco Nelissenvoid AudioFlinger::PlaybackThread::Track::dump(char* buffer, size_t size, bool active)
51181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{
512c56f3426099a3cf2d07ccff8886050c7fbce140fGlenn Kasten    gain_minifloat_packed_t vlr = mAudioTrackServerProxy->getVolumeLR();
51381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    if (isFastTrack()) {
514b220884bf3129253cc5bc8d030bc475411ea4911Marco Nelissen        sprintf(buffer, "    F %2d", mFastIndex);
515b220884bf3129253cc5bc8d030bc475411ea4911Marco Nelissen    } else if (mName >= AudioMixer::TRACK0) {
516b220884bf3129253cc5bc8d030bc475411ea4911Marco Nelissen        sprintf(buffer, "    %4d", mName - AudioMixer::TRACK0);
51781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    } else {
518b220884bf3129253cc5bc8d030bc475411ea4911Marco Nelissen        sprintf(buffer, "    none");
51981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    }
52081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    track_state state = mState;
52181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    char stateChar;
522bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent    if (isTerminated()) {
52381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        stateChar = 'T';
524bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent    } else {
525bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent        switch (state) {
526bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent        case IDLE:
527bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent            stateChar = 'I';
528bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent            break;
529bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent        case STOPPING_1:
530bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent            stateChar = 's';
531bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent            break;
532bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent        case STOPPING_2:
533bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent            stateChar = '5';
534bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent            break;
535bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent        case STOPPED:
536bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent            stateChar = 'S';
537bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent            break;
538bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent        case RESUMING:
539bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent            stateChar = 'R';
540bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent            break;
541bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent        case ACTIVE:
542bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent            stateChar = 'A';
543bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent            break;
544bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent        case PAUSING:
545bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent            stateChar = 'p';
546bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent            break;
547bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent        case PAUSED:
548bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent            stateChar = 'P';
549bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent            break;
550bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent        case FLUSHED:
551bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent            stateChar = 'F';
552bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent            break;
553bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent        default:
554bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent            stateChar = '?';
555bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent            break;
556bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent        }
55781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    }
55881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    char nowInUnderrun;
55981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    switch (mObservedUnderruns.mBitFields.mMostRecent) {
56081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    case UNDERRUN_FULL:
56181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        nowInUnderrun = ' ';
56281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        break;
56381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    case UNDERRUN_PARTIAL:
56481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        nowInUnderrun = '<';
56581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        break;
56681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    case UNDERRUN_EMPTY:
56781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        nowInUnderrun = '*';
56881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        break;
56981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    default:
57081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        nowInUnderrun = '?';
57181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        break;
57281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    }
573da540db0fc21bc9319d9602aefe1a109d00a7e6cAndy Hung
574da540db0fc21bc9319d9602aefe1a109d00a7e6cAndy Hung    std::pair<float /* volume */, bool /* active */> vsVolume = mVolumeHandler->getLastVolume();
575da540db0fc21bc9319d9602aefe1a109d00a7e6cAndy Hung    snprintf(&buffer[8], size - 8, " %6s %6u %4u %08X %08X %7u %6zu %1c %1d %5u "
576da540db0fc21bc9319d9602aefe1a109d00a7e6cAndy Hung                                   "%5.2g %5.2g %5.2g%c  "
577da540db0fc21bc9319d9602aefe1a109d00a7e6cAndy Hung                                   "%08X %08zX %08zX 0x%03X %9u%c %7u\n",
578b220884bf3129253cc5bc8d030bc475411ea4911Marco Nelissen            active ? "yes" : "no",
57981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            (mClient == 0) ? getpid_cached : mClient->pid(),
58081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            mStreamType,
58181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            mFormat,
58281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            mChannelMask,
58381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            mSessionId,
58481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            mFrameCount,
58581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            stateChar,
58681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            mFillingUpStatus,
5879f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten            mAudioTrackServerProxy->getSampleRate(),
588c56f3426099a3cf2d07ccff8886050c7fbce140fGlenn Kasten            20.0 * log10(float_from_gain(gain_minifloat_unpack_left(vlr))),
589c56f3426099a3cf2d07ccff8886050c7fbce140fGlenn Kasten            20.0 * log10(float_from_gain(gain_minifloat_unpack_right(vlr))),
590da540db0fc21bc9319d9602aefe1a109d00a7e6cAndy Hung            20.0 * log10(vsVolume.first), // VolumeShaper(s) total volume
591da540db0fc21bc9319d9602aefe1a109d00a7e6cAndy Hung            vsVolume.second ? 'A' : ' ',  // if any VolumeShapers active
592f20e1d8df84c5fbeeace0052d100982ae39bb7a4Glenn Kasten            mCblk->mServer,
5932148bf0e79c436b8764b9edc4c8f2730cce98a32Andy Hung            (size_t)mMainBuffer, // use %zX as %p appends 0x
5942148bf0e79c436b8764b9edc4c8f2730cce98a32Andy Hung            (size_t)mAuxBuffer,  // use %zX as %p appends 0x
59596f60d8f04432a1ed503b3e24d5736d28c63c9a2Glenn Kasten            mCblk->mFlags,
59682aaf94a5b18939e4d790bbc752031f3070704a3Glenn Kasten            mAudioTrackServerProxy->getUnderrunFrames(),
5972148bf0e79c436b8764b9edc4c8f2730cce98a32Andy Hung            nowInUnderrun,
5982148bf0e79c436b8764b9edc4c8f2730cce98a32Andy Hung            (unsigned)mAudioTrackServerProxy->framesFlushed() % 10000000); // 7 digits
59981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
60081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
6019f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kastenuint32_t AudioFlinger::PlaybackThread::Track::sampleRate() const {
6029f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    return mAudioTrackServerProxy->getSampleRate();
6039f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten}
6049f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten
60581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// AudioBufferProvider interface
60681784c37c61b09289654b979567a42bf73cd2b12Eric Laurentstatus_t AudioFlinger::PlaybackThread::Track::getNextBuffer(
607d79072e9dff59f767cce2cda1caab80ce5a0815bGlenn Kasten        AudioBufferProvider::Buffer* buffer)
60881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{
6099f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    ServerProxy::Buffer buf;
6109f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    size_t desiredFrames = buffer->frameCount;
6119f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    buf.mFrameCount = desiredFrames;
6129f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    status_t status = mServerProxy->obtainBuffer(&buf);
6139f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    buffer->frameCount = buf.mFrameCount;
6149f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    buffer->raw = buf.mRaw;
615a66d3899f7d13e69ee451f1071f0d999678803ceMikhail Naganov    if (buf.mFrameCount == 0 && !isStopping() && !isStopped() && !isPaused()) {
616a66d3899f7d13e69ee451f1071f0d999678803ceMikhail Naganov        ALOGV("underrun,  framesReady(%zu) < framesDesired(%zd), state: %d",
617a66d3899f7d13e69ee451f1071f0d999678803ceMikhail Naganov                buf.mFrameCount, desiredFrames, mState);
61882aaf94a5b18939e4d790bbc752031f3070704a3Glenn Kasten        mAudioTrackServerProxy->tallyUnderrunFrames(desiredFrames);
6192812d9ea3a3a33142dd8e23c9d949c498d6f7a12Phil Burk    } else {
6202812d9ea3a3a33142dd8e23c9d949c498d6f7a12Phil Burk        mAudioTrackServerProxy->tallyUnderrunFrames(0);
62181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    }
6222812d9ea3a3a33142dd8e23c9d949c498d6f7a12Phil Burk
6239f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    return status;
62481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
62581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
6266466c9e6e6278c740aed77f695f679be9f5db478Glenn Kasten// releaseBuffer() is not overridden
6276466c9e6e6278c740aed77f695f679be9f5db478Glenn Kasten
6286466c9e6e6278c740aed77f695f679be9f5db478Glenn Kasten// ExtendedAudioBufferProvider interface
6296466c9e6e6278c740aed77f695f679be9f5db478Glenn Kasten
63027876c02c21cd3ab7ef01bdd1fc5400c5143584aAndy Hung// framesReady() may return an approximation of the number of frames if called
63127876c02c21cd3ab7ef01bdd1fc5400c5143584aAndy Hung// from a different thread than the one calling Proxy->obtainBuffer() and
63227876c02c21cd3ab7ef01bdd1fc5400c5143584aAndy Hung// Proxy->releaseBuffer(). Also note there is no mutual exclusion in the
63327876c02c21cd3ab7ef01bdd1fc5400c5143584aAndy Hung// AudioTrackServerProxy so be especially careful calling with FastTracks.
63481784c37c61b09289654b979567a42bf73cd2b12Eric Laurentsize_t AudioFlinger::PlaybackThread::Track::framesReady() const {
63527876c02c21cd3ab7ef01bdd1fc5400c5143584aAndy Hung    if (mSharedBuffer != 0 && (isStopped() || isStopping())) {
63627876c02c21cd3ab7ef01bdd1fc5400c5143584aAndy Hung        // Static tracks return zero frames immediately upon stopping (for FastTracks).
63727876c02c21cd3ab7ef01bdd1fc5400c5143584aAndy Hung        // The remainder of the buffer is not drained.
63827876c02c21cd3ab7ef01bdd1fc5400c5143584aAndy Hung        return 0;
63927876c02c21cd3ab7ef01bdd1fc5400c5143584aAndy Hung    }
6409f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    return mAudioTrackServerProxy->framesReady();
64181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
64281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
643818e7a32ce3633980138aff2c2bfcc5158b3cfccAndy Hungint64_t AudioFlinger::PlaybackThread::Track::framesReleased() const
6446466c9e6e6278c740aed77f695f679be9f5db478Glenn Kasten{
6456466c9e6e6278c740aed77f695f679be9f5db478Glenn Kasten    return mAudioTrackServerProxy->framesReleased();
6466466c9e6e6278c740aed77f695f679be9f5db478Glenn Kasten}
6476466c9e6e6278c740aed77f695f679be9f5db478Glenn Kasten
648818e7a32ce3633980138aff2c2bfcc5158b3cfccAndy Hungvoid AudioFlinger::PlaybackThread::Track::onTimestamp(const ExtendedTimestamp &timestamp)
6496ae5843c281301a9ffd1059d185620a9337e15a2Andy Hung{
6506ae5843c281301a9ffd1059d185620a9337e15a2Andy Hung    // This call comes from a FastTrack and should be kept lockless.
6516ae5843c281301a9ffd1059d185620a9337e15a2Andy Hung    // The server side frames are already translated to client frames.
652818e7a32ce3633980138aff2c2bfcc5158b3cfccAndy Hung    mAudioTrackServerProxy->setTimestamp(timestamp);
6536ae5843c281301a9ffd1059d185620a9337e15a2Andy Hung
654818e7a32ce3633980138aff2c2bfcc5158b3cfccAndy Hung    // We do not set drained here, as FastTrack timestamp may not go to very last frame.
6556ae5843c281301a9ffd1059d185620a9337e15a2Andy Hung}
6566ae5843c281301a9ffd1059d185620a9337e15a2Andy Hung
65781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// Don't call for fast tracks; the framesReady() could result in priority inversion
65881784c37c61b09289654b979567a42bf73cd2b12Eric Laurentbool AudioFlinger::PlaybackThread::Track::isReady() const {
6598d6c292a0bed3d63b5b7297d09a604af6327c663Krishnankutty Kolathappilly    if (mFillingUpStatus != FS_FILLING || isStopped() || isPausing()) {
6608d6c292a0bed3d63b5b7297d09a604af6327c663Krishnankutty Kolathappilly        return true;
6618d6c292a0bed3d63b5b7297d09a604af6327c663Krishnankutty Kolathappilly    }
6628d6c292a0bed3d63b5b7297d09a604af6327c663Krishnankutty Kolathappilly
663164985121796cf214c7a83d32005d9b01125b558Eric Laurent    if (isStopping()) {
664164985121796cf214c7a83d32005d9b01125b558Eric Laurent        if (framesReady() > 0) {
665164985121796cf214c7a83d32005d9b01125b558Eric Laurent            mFillingUpStatus = FS_FILLED;
666164985121796cf214c7a83d32005d9b01125b558Eric Laurent        }
66781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        return true;
66881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    }
66981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
670e8972b0a27fac327c997fceb20d9abae1dc1d899Phil Burk    if (framesReady() >= mServerProxy->getBufferSizeInFrames() ||
67196f60d8f04432a1ed503b3e24d5736d28c63c9a2Glenn Kasten            (mCblk->mFlags & CBLK_FORCEREADY)) {
67281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        mFillingUpStatus = FS_FILLED;
67396f60d8f04432a1ed503b3e24d5736d28c63c9a2Glenn Kasten        android_atomic_and(~CBLK_FORCEREADY, &mCblk->mFlags);
67481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        return true;
67581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    }
67681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    return false;
67781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
67881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
6790f11b51a57bc9062c4fe8af73747319cedabc5d6Glenn Kastenstatus_t AudioFlinger::PlaybackThread::Track::start(AudioSystem::sync_event_t event __unused,
680d848eb48c121c119e8ba7583efc75415fe102570Glenn Kasten                                                    audio_session_t triggerSession __unused)
68181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{
68281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    status_t status = NO_ERROR;
68381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    ALOGV("start(%d), calling pid %d session %d",
68481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            mName, IPCThreadState::self()->getCallingPid(), mSessionId);
68581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
68681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    sp<ThreadBase> thread = mThread.promote();
68781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    if (thread != 0) {
688813e2a74853bde19e37d878c596a044b3f299efcEric Laurent        if (isOffloaded()) {
689813e2a74853bde19e37d878c596a044b3f299efcEric Laurent            Mutex::Autolock _laf(thread->mAudioFlinger->mLock);
690813e2a74853bde19e37d878c596a044b3f299efcEric Laurent            Mutex::Autolock _lth(thread->mLock);
691813e2a74853bde19e37d878c596a044b3f299efcEric Laurent            sp<EffectChain> ec = thread->getEffectChain_l(mSessionId);
6925baf2af52cd186633b7173196c1e4a4cd3435f22Eric Laurent            if (thread->mAudioFlinger->isNonOffloadableGlobalEffectEnabled_l() ||
6935baf2af52cd186633b7173196c1e4a4cd3435f22Eric Laurent                    (ec != 0 && ec->isNonOffloadableEnabled())) {
694813e2a74853bde19e37d878c596a044b3f299efcEric Laurent                invalidate();
695813e2a74853bde19e37d878c596a044b3f299efcEric Laurent                return PERMISSION_DENIED;
696813e2a74853bde19e37d878c596a044b3f299efcEric Laurent            }
697813e2a74853bde19e37d878c596a044b3f299efcEric Laurent        }
698813e2a74853bde19e37d878c596a044b3f299efcEric Laurent        Mutex::Autolock _lth(thread->mLock);
69981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        track_state state = mState;
70081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        // here the track could be either new, or restarted
70181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        // in both cases "unstop" the track
702bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent
7038d6c292a0bed3d63b5b7297d09a604af6327c663Krishnankutty Kolathappilly        // initial state-stopping. next state-pausing.
7048d6c292a0bed3d63b5b7297d09a604af6327c663Krishnankutty Kolathappilly        // What if resume is called ?
7058d6c292a0bed3d63b5b7297d09a604af6327c663Krishnankutty Kolathappilly
7068d6c292a0bed3d63b5b7297d09a604af6327c663Krishnankutty Kolathappilly        if (state == PAUSED || state == PAUSING) {
707bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent            if (mResumeToStopping) {
708bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent                // happened we need to resume to STOPPING_1
709bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent                mState = TrackBase::STOPPING_1;
710bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent                ALOGV("PAUSED => STOPPING_1 (%d) on thread %p", mName, this);
711bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent            } else {
712bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent                mState = TrackBase::RESUMING;
713bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent                ALOGV("PAUSED => RESUMING (%d) on thread %p", mName, this);
714bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent            }
71581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        } else {
71681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            mState = TrackBase::ACTIVE;
71781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            ALOGV("? => ACTIVE (%d) on thread %p", mName, this);
71881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        }
71981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
720e10393e72454bfd8298017dc193faf424f4e9a8fAndy Hung        // states to reset position info for non-offloaded/direct tracks
721e10393e72454bfd8298017dc193faf424f4e9a8fAndy Hung        if (!isOffloaded() && !isDirect()
722e10393e72454bfd8298017dc193faf424f4e9a8fAndy Hung                && (state == IDLE || state == STOPPED || state == FLUSHED)) {
723e10393e72454bfd8298017dc193faf424f4e9a8fAndy Hung            mFrameMap.reset();
724e10393e72454bfd8298017dc193faf424f4e9a8fAndy Hung        }
725bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent        PlaybackThread *playbackThread = (PlaybackThread *)thread.get();
726240934ba80d6c6165749db7681d243c6857a092fHaynes Mathew George        if (isFastTrack()) {
727240934ba80d6c6165749db7681d243c6857a092fHaynes Mathew George            // refresh fast track underruns on start because that field is never cleared
728240934ba80d6c6165749db7681d243c6857a092fHaynes Mathew George            // by the fast mixer; furthermore, the same track can be recycled, i.e. start
729240934ba80d6c6165749db7681d243c6857a092fHaynes Mathew George            // after stop.
730240934ba80d6c6165749db7681d243c6857a092fHaynes Mathew George            mObservedUnderruns = playbackThread->getFastTrackUnderruns(mFastIndex);
731240934ba80d6c6165749db7681d243c6857a092fHaynes Mathew George        }
732bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent        status = playbackThread->addTrack_l(this);
733bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent        if (status == INVALID_OPERATION || status == PERMISSION_DENIED) {
734bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent            triggerEvents(AudioSystem::SYNC_EVENT_PRESENTATION_COMPLETE);
735bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent            //  restore previous state if start was rejected by policy manager
736bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent            if (status == PERMISSION_DENIED) {
737bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent                mState = state;
73881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            }
73981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        }
740bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent        // track was already in the active list, not a problem
741bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent        if (status == ALREADY_EXISTS) {
742bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent            status = NO_ERROR;
74312022ff8d223ccf4dfae019c81e4a93a3f44985cGlenn Kasten        } else {
74412022ff8d223ccf4dfae019c81e4a93a3f44985cGlenn Kasten            // Acknowledge any pending flush(), so that subsequent new data isn't discarded.
74512022ff8d223ccf4dfae019c81e4a93a3f44985cGlenn Kasten            // It is usually unsafe to access the server proxy from a binder thread.
74612022ff8d223ccf4dfae019c81e4a93a3f44985cGlenn Kasten            // But in this case we know the mixer thread (whether normal mixer or fast mixer)
74712022ff8d223ccf4dfae019c81e4a93a3f44985cGlenn Kasten            // isn't looking at this track yet:  we still hold the normal mixer thread lock,
74812022ff8d223ccf4dfae019c81e4a93a3f44985cGlenn Kasten            // and for fast tracks the track is not yet in the fast mixer thread's active set.
749e6fb82a207f5256933e2d83e77262331af50a27fAndy Hung            // For static tracks, this is used to acknowledge change in position or loop.
750564d144fc28917d42e3a67718ac51d61bfc36315Eric Laurent            ServerProxy::Buffer buffer;
751564d144fc28917d42e3a67718ac51d61bfc36315Eric Laurent            buffer.mFrameCount = 1;
752564d144fc28917d42e3a67718ac51d61bfc36315Eric Laurent            (void) mAudioTrackServerProxy->obtainBuffer(&buffer, true /*ackFlush*/);
75381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        }
75481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    } else {
75581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        status = BAD_VALUE;
75681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    }
75781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    return status;
75881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
75981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
76081784c37c61b09289654b979567a42bf73cd2b12Eric Laurentvoid AudioFlinger::PlaybackThread::Track::stop()
76181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{
76281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    ALOGV("stop(%d), calling pid %d", mName, IPCThreadState::self()->getCallingPid());
76381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    sp<ThreadBase> thread = mThread.promote();
76481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    if (thread != 0) {
76581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        Mutex::Autolock _l(thread->mLock);
76681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        track_state state = mState;
76781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        if (state == RESUMING || state == ACTIVE || state == PAUSING || state == PAUSED) {
76881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            // If the track is not active (PAUSED and buffers full), flush buffers
76981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            PlaybackThread *playbackThread = (PlaybackThread *)thread.get();
77081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            if (playbackThread->mActiveTracks.indexOf(this) < 0) {
77181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                reset();
77281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                mState = STOPPED;
773ab5cdbaf65ca509681d2726aacdf3ac8bfb6b3faEric Laurent            } else if (!isFastTrack() && !isOffloaded() && !isDirect()) {
77481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                mState = STOPPED;
77581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            } else {
776bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent                // For fast tracks prepareTracks_l() will set state to STOPPING_2
777bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent                // presentation is complete
778bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent                // For an offloaded track this starts a drain and state will
779bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent                // move to STOPPING_2 when drain completes and then STOPPED
78081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                mState = STOPPING_1;
781e93cc03da360a1a0d2ad937c745ce8c8e8be81c2Eric Laurent                if (isOffloaded()) {
782e93cc03da360a1a0d2ad937c745ce8c8e8be81c2Eric Laurent                    mRetryCount = PlaybackThread::kMaxTrackStopRetriesOffload;
783e93cc03da360a1a0d2ad937c745ce8c8e8be81c2Eric Laurent                }
78481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            }
785b369cafd67beb63dd0278dba543f519956208a7fEric Laurent            playbackThread->broadcast_l();
78681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            ALOGV("not stopping/stopped => stopping/stopped (%d) on thread %p", mName,
78781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                    playbackThread);
78881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        }
78981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    }
79081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
79181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
79281784c37c61b09289654b979567a42bf73cd2b12Eric Laurentvoid AudioFlinger::PlaybackThread::Track::pause()
79381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{
79481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    ALOGV("pause(%d), calling pid %d", mName, IPCThreadState::self()->getCallingPid());
79581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    sp<ThreadBase> thread = mThread.promote();
79681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    if (thread != 0) {
79781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        Mutex::Autolock _l(thread->mLock);
798bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent        PlaybackThread *playbackThread = (PlaybackThread *)thread.get();
799bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent        switch (mState) {
800bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent        case STOPPING_1:
801bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent        case STOPPING_2:
802bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent            if (!isOffloaded()) {
803bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent                /* nothing to do if track is not offloaded */
804bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent                break;
805bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent            }
806bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent
807bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent            // Offloaded track was draining, we need to carry on draining when resumed
808bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent            mResumeToStopping = true;
809bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent            // fall through...
810bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent        case ACTIVE:
811bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent        case RESUMING:
81281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            mState = PAUSING;
81381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            ALOGV("ACTIVE/RESUMING => PAUSING (%d) on thread %p", mName, thread.get());
814ede6c3b8b1147bc425f7b923882f559a513fe23bEric Laurent            playbackThread->broadcast_l();
815bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent            break;
816bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent
817bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent        default:
818bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent            break;
81981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        }
82081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    }
82181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
82281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
82381784c37c61b09289654b979567a42bf73cd2b12Eric Laurentvoid AudioFlinger::PlaybackThread::Track::flush()
82481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{
82581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    ALOGV("flush(%d)", mName);
82681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    sp<ThreadBase> thread = mThread.promote();
82781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    if (thread != 0) {
82881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        Mutex::Autolock _l(thread->mLock);
82981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        PlaybackThread *playbackThread = (PlaybackThread *)thread.get();
830bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent
8314bb650bb3c4f15789232f3f3cf778c5441122360Phil Burk        // Flush the ring buffer now if the track is not active in the PlaybackThread.
8324bb650bb3c4f15789232f3f3cf778c5441122360Phil Burk        // Otherwise the flush would not be done until the track is resumed.
8334bb650bb3c4f15789232f3f3cf778c5441122360Phil Burk        // Requires FastTrack removal be BLOCK_UNTIL_ACKED
8344bb650bb3c4f15789232f3f3cf778c5441122360Phil Burk        if (playbackThread->mActiveTracks.indexOf(this) < 0) {
8354bb650bb3c4f15789232f3f3cf778c5441122360Phil Burk            (void)mServerProxy->flushBufferIfNeeded();
8364bb650bb3c4f15789232f3f3cf778c5441122360Phil Burk        }
8374bb650bb3c4f15789232f3f3cf778c5441122360Phil Burk
838bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent        if (isOffloaded()) {
839bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent            // If offloaded we allow flush during any state except terminated
840bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent            // and keep the track active to avoid problems if user is seeking
841bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent            // rapidly and underlying hardware has a significant delay handling
842bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent            // a pause
843bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent            if (isTerminated()) {
844bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent                return;
845bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent            }
846bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent
847bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent            ALOGV("flush: offload flush");
84881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            reset();
849bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent
850bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent            if (mState == STOPPING_1 || mState == STOPPING_2) {
851bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent                ALOGV("flushed in STOPPING_1 or 2 state, change state to ACTIVE");
852bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent                mState = ACTIVE;
853bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent            }
854bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent
8557844f679be8d94c5cdf017f53754cb68ee2f00daHaynes Mathew George            mFlushHwPending = true;
856bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent            mResumeToStopping = false;
857bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent        } else {
858bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent            if (mState != STOPPING_1 && mState != STOPPING_2 && mState != STOPPED &&
859bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent                    mState != PAUSED && mState != PAUSING && mState != IDLE && mState != FLUSHED) {
860bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent                return;
861bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent            }
862bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent            // No point remaining in PAUSED state after a flush => go to
863bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent            // FLUSHED state
864bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent            mState = FLUSHED;
865bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent            // do not reset the track if it is still in the process of being stopped or paused.
866bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent            // this will be done by prepareTracks_l() when the track is stopped.
867bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent            // prepareTracks_l() will see mState == FLUSHED, then
868bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent            // remove from active track list, reset(), and trigger presentation complete
869d1f69b0b17acbd96987ecb2f3378abd394d05903Eric Laurent            if (isDirect()) {
870d1f69b0b17acbd96987ecb2f3378abd394d05903Eric Laurent                mFlushHwPending = true;
871d1f69b0b17acbd96987ecb2f3378abd394d05903Eric Laurent            }
872bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent            if (playbackThread->mActiveTracks.indexOf(this) < 0) {
873bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent                reset();
874bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent            }
87581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        }
876bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent        // Prevent flush being lost if the track is flushed and then resumed
877bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent        // before mixer thread can run. This is important when offloading
878bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent        // because the hardware buffer could hold a large amount of audio
879ede6c3b8b1147bc425f7b923882f559a513fe23bEric Laurent        playbackThread->broadcast_l();
88081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    }
88181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
88281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
8837844f679be8d94c5cdf017f53754cb68ee2f00daHaynes Mathew George// must be called with thread lock held
8847844f679be8d94c5cdf017f53754cb68ee2f00daHaynes Mathew Georgevoid AudioFlinger::PlaybackThread::Track::flushAck()
8857844f679be8d94c5cdf017f53754cb68ee2f00daHaynes Mathew George{
886d1f69b0b17acbd96987ecb2f3378abd394d05903Eric Laurent    if (!isOffloaded() && !isDirect())
8877844f679be8d94c5cdf017f53754cb68ee2f00daHaynes Mathew George        return;
8887844f679be8d94c5cdf017f53754cb68ee2f00daHaynes Mathew George
8894bb650bb3c4f15789232f3f3cf778c5441122360Phil Burk    // Clear the client ring buffer so that the app can prime the buffer while paused.
8904bb650bb3c4f15789232f3f3cf778c5441122360Phil Burk    // Otherwise it might not get cleared until playback is resumed and obtainBuffer() is called.
8914bb650bb3c4f15789232f3f3cf778c5441122360Phil Burk    mServerProxy->flushBufferIfNeeded();
8924bb650bb3c4f15789232f3f3cf778c5441122360Phil Burk
8937844f679be8d94c5cdf017f53754cb68ee2f00daHaynes Mathew George    mFlushHwPending = false;
8947844f679be8d94c5cdf017f53754cb68ee2f00daHaynes Mathew George}
8957844f679be8d94c5cdf017f53754cb68ee2f00daHaynes Mathew George
89681784c37c61b09289654b979567a42bf73cd2b12Eric Laurentvoid AudioFlinger::PlaybackThread::Track::reset()
89781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{
89881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    // Do not reset twice to avoid discarding data written just after a flush and before
89981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    // the audioflinger thread detects the track is stopped.
90081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    if (!mResetDone) {
90181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        // Force underrun condition to avoid false underrun callback until first data is
90281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        // written to buffer
90396f60d8f04432a1ed503b3e24d5736d28c63c9a2Glenn Kasten        android_atomic_and(~CBLK_FORCEREADY, &mCblk->mFlags);
90481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        mFillingUpStatus = FS_FILLING;
90581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        mResetDone = true;
90681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        if (mState == FLUSHED) {
90781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            mState = IDLE;
90881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        }
90981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    }
91081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
91181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
912bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurentstatus_t AudioFlinger::PlaybackThread::Track::setParameters(const String8& keyValuePairs)
913bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent{
914bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent    sp<ThreadBase> thread = mThread.promote();
915bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent    if (thread == 0) {
916bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent        ALOGE("thread is dead");
917bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent        return FAILED_TRANSACTION;
918bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent    } else if ((thread->type() == ThreadBase::DIRECT) ||
919bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent                    (thread->type() == ThreadBase::OFFLOAD)) {
920bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent        return thread->setParameters(keyValuePairs);
921bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent    } else {
922bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent        return PERMISSION_DENIED;
923bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent    }
924bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent}
925bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent
9269fc8b5cd4a64ef07e84c69112461324d5c13a0b0Andy HungVolumeShaper::Status AudioFlinger::PlaybackThread::Track::applyVolumeShaper(
9279fc8b5cd4a64ef07e84c69112461324d5c13a0b0Andy Hung        const sp<VolumeShaper::Configuration>& configuration,
9289fc8b5cd4a64ef07e84c69112461324d5c13a0b0Andy Hung        const sp<VolumeShaper::Operation>& operation)
9299fc8b5cd4a64ef07e84c69112461324d5c13a0b0Andy Hung{
93010cbff139360f3f642e0e3b3ccf2d463dbed22cfAndy Hung    sp<VolumeShaper::Configuration> newConfiguration;
93110cbff139360f3f642e0e3b3ccf2d463dbed22cfAndy Hung
93210cbff139360f3f642e0e3b3ccf2d463dbed22cfAndy Hung    if (isOffloadedOrDirect()) {
93310cbff139360f3f642e0e3b3ccf2d463dbed22cfAndy Hung        const VolumeShaper::Configuration::OptionFlag optionFlag
93410cbff139360f3f642e0e3b3ccf2d463dbed22cfAndy Hung            = configuration->getOptionFlags();
93510cbff139360f3f642e0e3b3ccf2d463dbed22cfAndy Hung        if ((optionFlag & VolumeShaper::Configuration::OPTION_FLAG_CLOCK_TIME) == 0) {
93610cbff139360f3f642e0e3b3ccf2d463dbed22cfAndy Hung            ALOGW("%s tracks do not support frame counted VolumeShaper,"
93710cbff139360f3f642e0e3b3ccf2d463dbed22cfAndy Hung                    " using clock time instead", isOffloaded() ? "Offload" : "Direct");
93810cbff139360f3f642e0e3b3ccf2d463dbed22cfAndy Hung            newConfiguration = new VolumeShaper::Configuration(*configuration);
93910cbff139360f3f642e0e3b3ccf2d463dbed22cfAndy Hung            newConfiguration->setOptionFlags(
94010cbff139360f3f642e0e3b3ccf2d463dbed22cfAndy Hung                VolumeShaper::Configuration::OptionFlag(optionFlag
94110cbff139360f3f642e0e3b3ccf2d463dbed22cfAndy Hung                        | VolumeShaper::Configuration::OPTION_FLAG_CLOCK_TIME));
94210cbff139360f3f642e0e3b3ccf2d463dbed22cfAndy Hung        }
94310cbff139360f3f642e0e3b3ccf2d463dbed22cfAndy Hung    }
9449fc8b5cd4a64ef07e84c69112461324d5c13a0b0Andy Hung
94510cbff139360f3f642e0e3b3ccf2d463dbed22cfAndy Hung    VolumeShaper::Status status = mVolumeHandler->applyVolumeShaper(
94610cbff139360f3f642e0e3b3ccf2d463dbed22cfAndy Hung            (newConfiguration.get() != nullptr ? newConfiguration : configuration), operation);
94710cbff139360f3f642e0e3b3ccf2d463dbed22cfAndy Hung
94810cbff139360f3f642e0e3b3ccf2d463dbed22cfAndy Hung    if (isOffloadedOrDirect()) {
94910cbff139360f3f642e0e3b3ccf2d463dbed22cfAndy Hung        // Signal thread to fetch new volume.
95010cbff139360f3f642e0e3b3ccf2d463dbed22cfAndy Hung        sp<ThreadBase> thread = mThread.promote();
95110cbff139360f3f642e0e3b3ccf2d463dbed22cfAndy Hung        if (thread != 0) {
95210cbff139360f3f642e0e3b3ccf2d463dbed22cfAndy Hung             Mutex::Autolock _l(thread->mLock);
95310cbff139360f3f642e0e3b3ccf2d463dbed22cfAndy Hung            thread->broadcast_l();
95410cbff139360f3f642e0e3b3ccf2d463dbed22cfAndy Hung        }
95510cbff139360f3f642e0e3b3ccf2d463dbed22cfAndy Hung    }
95610cbff139360f3f642e0e3b3ccf2d463dbed22cfAndy Hung    return status;
9579fc8b5cd4a64ef07e84c69112461324d5c13a0b0Andy Hung}
9589fc8b5cd4a64ef07e84c69112461324d5c13a0b0Andy Hung
9599fc8b5cd4a64ef07e84c69112461324d5c13a0b0Andy Hungsp<VolumeShaper::State> AudioFlinger::PlaybackThread::Track::getVolumeShaperState(int id)
9609fc8b5cd4a64ef07e84c69112461324d5c13a0b0Andy Hung{
9619fc8b5cd4a64ef07e84c69112461324d5c13a0b0Andy Hung    // Note: We don't check if Thread exists.
9629fc8b5cd4a64ef07e84c69112461324d5c13a0b0Andy Hung
9639fc8b5cd4a64ef07e84c69112461324d5c13a0b0Andy Hung    // mVolumeHandler is thread safe.
9649fc8b5cd4a64ef07e84c69112461324d5c13a0b0Andy Hung    return mVolumeHandler->getVolumeShaperState(id);
9659fc8b5cd4a64ef07e84c69112461324d5c13a0b0Andy Hung}
9669fc8b5cd4a64ef07e84c69112461324d5c13a0b0Andy Hung
967573d80a8f463f648a515fc0975bf83951b272993Glenn Kastenstatus_t AudioFlinger::PlaybackThread::Track::getTimestamp(AudioTimestamp& timestamp)
968573d80a8f463f648a515fc0975bf83951b272993Glenn Kasten{
969818e7a32ce3633980138aff2c2bfcc5158b3cfccAndy Hung    if (!isOffloaded() && !isDirect()) {
970818e7a32ce3633980138aff2c2bfcc5158b3cfccAndy Hung        return INVALID_OPERATION; // normal tracks handled through SSQ
971fe346c707f59d763ded93bc3d27b51f0c0408258Glenn Kasten    }
972573d80a8f463f648a515fc0975bf83951b272993Glenn Kasten    sp<ThreadBase> thread = mThread.promote();
973573d80a8f463f648a515fc0975bf83951b272993Glenn Kasten    if (thread == 0) {
974fe346c707f59d763ded93bc3d27b51f0c0408258Glenn Kasten        return INVALID_OPERATION;
975573d80a8f463f648a515fc0975bf83951b272993Glenn Kasten    }
9766140c79c31f5dc237fba69554de5be641cedf113Phil Burk
977573d80a8f463f648a515fc0975bf83951b272993Glenn Kasten    Mutex::Autolock _l(thread->mLock);
978573d80a8f463f648a515fc0975bf83951b272993Glenn Kasten    PlaybackThread *playbackThread = (PlaybackThread *)thread.get();
979818e7a32ce3633980138aff2c2bfcc5158b3cfccAndy Hung    return playbackThread->getTimestamp_l(timestamp);
980573d80a8f463f648a515fc0975bf83951b272993Glenn Kasten}
981573d80a8f463f648a515fc0975bf83951b272993Glenn Kasten
98281784c37c61b09289654b979567a42bf73cd2b12Eric Laurentstatus_t AudioFlinger::PlaybackThread::Track::attachAuxEffect(int EffectId)
98381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{
98481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    status_t status = DEAD_OBJECT;
98581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    sp<ThreadBase> thread = mThread.promote();
98681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    if (thread != 0) {
98781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        PlaybackThread *playbackThread = (PlaybackThread *)thread.get();
98881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        sp<AudioFlinger> af = mClient->audioFlinger();
98981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
99081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        Mutex::Autolock _l(af->mLock);
99181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
99281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        sp<PlaybackThread> srcThread = af->getEffectThread_l(AUDIO_SESSION_OUTPUT_MIX, EffectId);
99381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
99481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        if (EffectId != 0 && srcThread != 0 && playbackThread != srcThread.get()) {
99581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            Mutex::Autolock _dl(playbackThread->mLock);
99681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            Mutex::Autolock _sl(srcThread->mLock);
99781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            sp<EffectChain> chain = srcThread->getEffectChain_l(AUDIO_SESSION_OUTPUT_MIX);
99881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            if (chain == 0) {
99981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                return INVALID_OPERATION;
100081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            }
100181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
100281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            sp<EffectModule> effect = chain->getEffectFromId_l(EffectId);
100381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            if (effect == 0) {
100481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                return INVALID_OPERATION;
100581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            }
100681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            srcThread->removeEffect_l(effect);
10075baf2af52cd186633b7173196c1e4a4cd3435f22Eric Laurent            status = playbackThread->addEffect_l(effect);
10085baf2af52cd186633b7173196c1e4a4cd3435f22Eric Laurent            if (status != NO_ERROR) {
10095baf2af52cd186633b7173196c1e4a4cd3435f22Eric Laurent                srcThread->addEffect_l(effect);
10105baf2af52cd186633b7173196c1e4a4cd3435f22Eric Laurent                return INVALID_OPERATION;
10115baf2af52cd186633b7173196c1e4a4cd3435f22Eric Laurent            }
101281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            // removeEffect_l() has stopped the effect if it was active so it must be restarted
101381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            if (effect->state() == EffectModule::ACTIVE ||
101481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                    effect->state() == EffectModule::STOPPING) {
101581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                effect->start();
101681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            }
101781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
101881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            sp<EffectChain> dstChain = effect->chain().promote();
101981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            if (dstChain == 0) {
102081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                srcThread->addEffect_l(effect);
102181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                return INVALID_OPERATION;
102281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            }
102381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            AudioSystem::unregisterEffect(effect->id());
102481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            AudioSystem::registerEffect(&effect->desc(),
102581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                                        srcThread->id(),
102681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                                        dstChain->strategy(),
102781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                                        AUDIO_SESSION_OUTPUT_MIX,
102881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                                        effect->id());
1029d72b7c0180ee83fc3754629ed68fc5887a125c4cEric Laurent            AudioSystem::setEffectEnabled(effect->id(), effect->isEnabled());
103081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        }
103181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        status = playbackThread->attachAuxEffect(this, EffectId);
103281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    }
103381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    return status;
103481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
103581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
103681784c37c61b09289654b979567a42bf73cd2b12Eric Laurentvoid AudioFlinger::PlaybackThread::Track::setAuxBuffer(int EffectId, int32_t *buffer)
103781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{
103881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    mAuxEffectId = EffectId;
103981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    mAuxBuffer = buffer;
104081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
104181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
1042818e7a32ce3633980138aff2c2bfcc5158b3cfccAndy Hungbool AudioFlinger::PlaybackThread::Track::presentationComplete(
1043818e7a32ce3633980138aff2c2bfcc5158b3cfccAndy Hung        int64_t framesWritten, size_t audioHalFrames)
104481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{
1045818e7a32ce3633980138aff2c2bfcc5158b3cfccAndy Hung    // TODO: improve this based on FrameMap if it exists, to ensure full drain.
1046818e7a32ce3633980138aff2c2bfcc5158b3cfccAndy Hung    // This assists in proper timestamp computation as well as wakelock management.
1047818e7a32ce3633980138aff2c2bfcc5158b3cfccAndy Hung
104881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    // a track is considered presented when the total number of frames written to audio HAL
104981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    // corresponds to the number of frames written when presentationComplete() is called for the
105081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    // first time (mPresentationCompleteFrames == 0) plus the buffer filling status at that time.
1051bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent    // For an offloaded track the HAL+h/w delay is variable so a HAL drain() is used
1052bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent    // to detect when all frames have been played. In this case framesWritten isn't
1053bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent    // useful because it doesn't always reflect whether there is data in the h/w
1054bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent    // buffers, particularly if a track has been paused and resumed during draining
1055818e7a32ce3633980138aff2c2bfcc5158b3cfccAndy Hung    ALOGV("presentationComplete() mPresentationCompleteFrames %lld framesWritten %lld",
1056818e7a32ce3633980138aff2c2bfcc5158b3cfccAndy Hung            (long long)mPresentationCompleteFrames, (long long)framesWritten);
105781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    if (mPresentationCompleteFrames == 0) {
105881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        mPresentationCompleteFrames = framesWritten + audioHalFrames;
1059818e7a32ce3633980138aff2c2bfcc5158b3cfccAndy Hung        ALOGV("presentationComplete() reset: mPresentationCompleteFrames %lld audioHalFrames %zu",
1060818e7a32ce3633980138aff2c2bfcc5158b3cfccAndy Hung                (long long)mPresentationCompleteFrames, audioHalFrames);
106181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    }
1062bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent
1063c54b1ffc92b8ad27608a8af21033d7cab33cb3a0Andy Hung    bool complete;
1064c54b1ffc92b8ad27608a8af21033d7cab33cb3a0Andy Hung    if (isOffloaded()) {
1065c54b1ffc92b8ad27608a8af21033d7cab33cb3a0Andy Hung        complete = true;
1066c54b1ffc92b8ad27608a8af21033d7cab33cb3a0Andy Hung    } else if (isDirect() || isFastTrack()) { // these do not go through linear map
1067c42e9b462661673dff480ee71757a58b0f806370Glenn Kasten        complete = framesWritten >= (int64_t) mPresentationCompleteFrames;
1068c54b1ffc92b8ad27608a8af21033d7cab33cb3a0Andy Hung    } else {  // Normal tracks, OutputTracks, and PatchTracks
1069c42e9b462661673dff480ee71757a58b0f806370Glenn Kasten        complete = framesWritten >= (int64_t) mPresentationCompleteFrames
1070c54b1ffc92b8ad27608a8af21033d7cab33cb3a0Andy Hung                && mAudioTrackServerProxy->isDrained();
1071c54b1ffc92b8ad27608a8af21033d7cab33cb3a0Andy Hung    }
1072c54b1ffc92b8ad27608a8af21033d7cab33cb3a0Andy Hung
1073c54b1ffc92b8ad27608a8af21033d7cab33cb3a0Andy Hung    if (complete) {
107481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        triggerEvents(AudioSystem::SYNC_EVENT_PRESENTATION_COMPLETE);
1075bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent        mAudioTrackServerProxy->setStreamEndDone();
107681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        return true;
107781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    }
107881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    return false;
107981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
108081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
108181784c37c61b09289654b979567a42bf73cd2b12Eric Laurentvoid AudioFlinger::PlaybackThread::Track::triggerEvents(AudioSystem::sync_event_t type)
108281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{
10833ab368e0810d894dcbc0971350c095049478a055Mark Salyzyn    for (size_t i = 0; i < mSyncEvents.size(); i++) {
108481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        if (mSyncEvents[i]->type() == type) {
108581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            mSyncEvents[i]->trigger();
108681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            mSyncEvents.removeAt(i);
108781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            i--;
108881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        }
108981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    }
109081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
109181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
109281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// implement VolumeBufferProvider interface
109381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
1094c56f3426099a3cf2d07ccff8886050c7fbce140fGlenn Kastengain_minifloat_packed_t AudioFlinger::PlaybackThread::Track::getVolumeLR()
109581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{
109681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    // called by FastMixer, so not allowed to take any locks, block, or do I/O including logs
109781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    ALOG_ASSERT(isFastTrack() && (mCblk != NULL));
1098c56f3426099a3cf2d07ccff8886050c7fbce140fGlenn Kasten    gain_minifloat_packed_t vlr = mAudioTrackServerProxy->getVolumeLR();
1099c56f3426099a3cf2d07ccff8886050c7fbce140fGlenn Kasten    float vl = float_from_gain(gain_minifloat_unpack_left(vlr));
1100c56f3426099a3cf2d07ccff8886050c7fbce140fGlenn Kasten    float vr = float_from_gain(gain_minifloat_unpack_right(vlr));
110181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    // track volumes come from shared memory, so can't be trusted and must be clamped
1102c56f3426099a3cf2d07ccff8886050c7fbce140fGlenn Kasten    if (vl > GAIN_FLOAT_UNITY) {
1103c56f3426099a3cf2d07ccff8886050c7fbce140fGlenn Kasten        vl = GAIN_FLOAT_UNITY;
110481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    }
1105c56f3426099a3cf2d07ccff8886050c7fbce140fGlenn Kasten    if (vr > GAIN_FLOAT_UNITY) {
1106c56f3426099a3cf2d07ccff8886050c7fbce140fGlenn Kasten        vr = GAIN_FLOAT_UNITY;
110781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    }
110881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    // now apply the cached master volume and stream type volume;
110981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    // this is trusted but lacks any synchronization or barrier so may be stale
111081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    float v = mCachedVolume;
111181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    vl *= v;
111281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    vr *= v;
1113c56f3426099a3cf2d07ccff8886050c7fbce140fGlenn Kasten    // re-combine into packed minifloat
1114c56f3426099a3cf2d07ccff8886050c7fbce140fGlenn Kasten    vlr = gain_minifloat_pack(gain_from_float(vl), gain_from_float(vr));
111581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    // FIXME look at mute, pause, and stop flags
111681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    return vlr;
111781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
111881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
111981784c37c61b09289654b979567a42bf73cd2b12Eric Laurentstatus_t AudioFlinger::PlaybackThread::Track::setSyncEvent(const sp<SyncEvent>& event)
112081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{
1121bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent    if (isTerminated() || mState == PAUSED ||
112281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            ((framesReady() == 0) && ((mSharedBuffer != 0) ||
112381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                                      (mState == STOPPED)))) {
1124c42e9b462661673dff480ee71757a58b0f806370Glenn Kasten        ALOGW("Track::setSyncEvent() in invalid state %d on session %d %s mode, framesReady %zu",
112581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent              mState, mSessionId, (mSharedBuffer != 0) ? "static" : "stream", framesReady());
112681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        event->cancel();
112781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        return INVALID_OPERATION;
112881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    }
112981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    (void) TrackBase::setSyncEvent(event);
113081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    return NO_ERROR;
113181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
113281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
11335736c35b841de56ce394b4879389f669b61425e6Glenn Kastenvoid AudioFlinger::PlaybackThread::Track::invalidate()
11345736c35b841de56ce394b4879389f669b61425e6Glenn Kasten{
11356acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent    TrackBase::invalidate();
11364d231dc0ee34380956c71cbe18a750e487a69601Eric Laurent    signalClientFlag(CBLK_INVALID);
11374d231dc0ee34380956c71cbe18a750e487a69601Eric Laurent}
11384d231dc0ee34380956c71cbe18a750e487a69601Eric Laurent
11394d231dc0ee34380956c71cbe18a750e487a69601Eric Laurentvoid AudioFlinger::PlaybackThread::Track::disable()
11404d231dc0ee34380956c71cbe18a750e487a69601Eric Laurent{
11414d231dc0ee34380956c71cbe18a750e487a69601Eric Laurent    signalClientFlag(CBLK_DISABLED);
11424d231dc0ee34380956c71cbe18a750e487a69601Eric Laurent}
11434d231dc0ee34380956c71cbe18a750e487a69601Eric Laurent
11444d231dc0ee34380956c71cbe18a750e487a69601Eric Laurentvoid AudioFlinger::PlaybackThread::Track::signalClientFlag(int32_t flag)
11454d231dc0ee34380956c71cbe18a750e487a69601Eric Laurent{
11469f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    // FIXME should use proxy, and needs work
11479f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    audio_track_cblk_t* cblk = mCblk;
11484d231dc0ee34380956c71cbe18a750e487a69601Eric Laurent    android_atomic_or(flag, &cblk->mFlags);
11499f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    android_atomic_release_store(0x40000000, &cblk->mFutex);
11509f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    // client is not in server, so FUTEX_WAKE is needed instead of FUTEX_WAKE_PRIVATE
1151ee499291404a192b059f2e04c5afc65aa6cdd74cElliott Hughes    (void) syscall(__NR_futex, &cblk->mFutex, FUTEX_WAKE, INT_MAX);
11525736c35b841de56ce394b4879389f669b61425e6Glenn Kasten}
11535736c35b841de56ce394b4879389f669b61425e6Glenn Kasten
115459fe010bcc072597852454a2ec53d7b0a2002a3bEric Laurentvoid AudioFlinger::PlaybackThread::Track::signal()
115559fe010bcc072597852454a2ec53d7b0a2002a3bEric Laurent{
115659fe010bcc072597852454a2ec53d7b0a2002a3bEric Laurent    sp<ThreadBase> thread = mThread.promote();
115759fe010bcc072597852454a2ec53d7b0a2002a3bEric Laurent    if (thread != 0) {
115859fe010bcc072597852454a2ec53d7b0a2002a3bEric Laurent        PlaybackThread *t = (PlaybackThread *)thread.get();
115959fe010bcc072597852454a2ec53d7b0a2002a3bEric Laurent        Mutex::Autolock _l(t->mLock);
116059fe010bcc072597852454a2ec53d7b0a2002a3bEric Laurent        t->broadcast_l();
116159fe010bcc072597852454a2ec53d7b0a2002a3bEric Laurent    }
116259fe010bcc072597852454a2ec53d7b0a2002a3bEric Laurent}
116359fe010bcc072597852454a2ec53d7b0a2002a3bEric Laurent
11648d6c292a0bed3d63b5b7297d09a604af6327c663Krishnankutty Kolathappilly//To be called with thread lock held
11658d6c292a0bed3d63b5b7297d09a604af6327c663Krishnankutty Kolathappillybool AudioFlinger::PlaybackThread::Track::isResumePending() {
11668d6c292a0bed3d63b5b7297d09a604af6327c663Krishnankutty Kolathappilly
11678d6c292a0bed3d63b5b7297d09a604af6327c663Krishnankutty Kolathappilly    if (mState == RESUMING)
11688d6c292a0bed3d63b5b7297d09a604af6327c663Krishnankutty Kolathappilly        return true;
11698d6c292a0bed3d63b5b7297d09a604af6327c663Krishnankutty Kolathappilly    /* Resume is pending if track was stopping before pause was called */
11708d6c292a0bed3d63b5b7297d09a604af6327c663Krishnankutty Kolathappilly    if (mState == STOPPING_1 &&
11718d6c292a0bed3d63b5b7297d09a604af6327c663Krishnankutty Kolathappilly        mResumeToStopping)
11728d6c292a0bed3d63b5b7297d09a604af6327c663Krishnankutty Kolathappilly        return true;
11738d6c292a0bed3d63b5b7297d09a604af6327c663Krishnankutty Kolathappilly
11748d6c292a0bed3d63b5b7297d09a604af6327c663Krishnankutty Kolathappilly    return false;
11758d6c292a0bed3d63b5b7297d09a604af6327c663Krishnankutty Kolathappilly}
11768d6c292a0bed3d63b5b7297d09a604af6327c663Krishnankutty Kolathappilly
11778d6c292a0bed3d63b5b7297d09a604af6327c663Krishnankutty Kolathappilly//To be called with thread lock held
11788d6c292a0bed3d63b5b7297d09a604af6327c663Krishnankutty Kolathappillyvoid AudioFlinger::PlaybackThread::Track::resumeAck() {
11798d6c292a0bed3d63b5b7297d09a604af6327c663Krishnankutty Kolathappilly
11808d6c292a0bed3d63b5b7297d09a604af6327c663Krishnankutty Kolathappilly
11818d6c292a0bed3d63b5b7297d09a604af6327c663Krishnankutty Kolathappilly    if (mState == RESUMING)
11828d6c292a0bed3d63b5b7297d09a604af6327c663Krishnankutty Kolathappilly        mState = ACTIVE;
11832d3ca68363f723fbe269d3ce52dab4985dfc7154Haynes Mathew George
11848d6c292a0bed3d63b5b7297d09a604af6327c663Krishnankutty Kolathappilly    // Other possibility of  pending resume is stopping_1 state
11858d6c292a0bed3d63b5b7297d09a604af6327c663Krishnankutty Kolathappilly    // Do not update the state from stopping as this prevents
11862d3ca68363f723fbe269d3ce52dab4985dfc7154Haynes Mathew George    // drain being called.
11872d3ca68363f723fbe269d3ce52dab4985dfc7154Haynes Mathew George    if (mState == STOPPING_1) {
11882d3ca68363f723fbe269d3ce52dab4985dfc7154Haynes Mathew George        mResumeToStopping = false;
11892d3ca68363f723fbe269d3ce52dab4985dfc7154Haynes Mathew George    }
11908d6c292a0bed3d63b5b7297d09a604af6327c663Krishnankutty Kolathappilly}
1191e10393e72454bfd8298017dc193faf424f4e9a8fAndy Hung
1192e10393e72454bfd8298017dc193faf424f4e9a8fAndy Hung//To be called with thread lock held
1193e10393e72454bfd8298017dc193faf424f4e9a8fAndy Hungvoid AudioFlinger::PlaybackThread::Track::updateTrackFrameInfo(
1194818e7a32ce3633980138aff2c2bfcc5158b3cfccAndy Hung        int64_t trackFramesReleased, int64_t sinkFramesWritten,
1195818e7a32ce3633980138aff2c2bfcc5158b3cfccAndy Hung        const ExtendedTimestamp &timeStamp) {
1196818e7a32ce3633980138aff2c2bfcc5158b3cfccAndy Hung    //update frame map
1197e10393e72454bfd8298017dc193faf424f4e9a8fAndy Hung    mFrameMap.push(trackFramesReleased, sinkFramesWritten);
1198818e7a32ce3633980138aff2c2bfcc5158b3cfccAndy Hung
1199818e7a32ce3633980138aff2c2bfcc5158b3cfccAndy Hung    // adjust server times and set drained state.
1200818e7a32ce3633980138aff2c2bfcc5158b3cfccAndy Hung    //
1201818e7a32ce3633980138aff2c2bfcc5158b3cfccAndy Hung    // Our timestamps are only updated when the track is on the Thread active list.
1202818e7a32ce3633980138aff2c2bfcc5158b3cfccAndy Hung    // We need to ensure that tracks are not removed before full drain.
1203818e7a32ce3633980138aff2c2bfcc5158b3cfccAndy Hung    ExtendedTimestamp local = timeStamp;
1204818e7a32ce3633980138aff2c2bfcc5158b3cfccAndy Hung    bool checked = false;
1205818e7a32ce3633980138aff2c2bfcc5158b3cfccAndy Hung    for (int i = ExtendedTimestamp::LOCATION_MAX - 1;
1206818e7a32ce3633980138aff2c2bfcc5158b3cfccAndy Hung            i >= ExtendedTimestamp::LOCATION_SERVER; --i) {
1207818e7a32ce3633980138aff2c2bfcc5158b3cfccAndy Hung        // Lookup the track frame corresponding to the sink frame position.
1208818e7a32ce3633980138aff2c2bfcc5158b3cfccAndy Hung        if (local.mTimeNs[i] > 0) {
1209818e7a32ce3633980138aff2c2bfcc5158b3cfccAndy Hung            local.mPosition[i] = mFrameMap.findX(local.mPosition[i]);
1210818e7a32ce3633980138aff2c2bfcc5158b3cfccAndy Hung            // check drain state from the latest stage in the pipeline.
12116d7b119a416c9f10288051e562f294365e5d954cAndy Hung            if (!checked && i <= ExtendedTimestamp::LOCATION_KERNEL) {
1212818e7a32ce3633980138aff2c2bfcc5158b3cfccAndy Hung                mAudioTrackServerProxy->setDrained(
1213818e7a32ce3633980138aff2c2bfcc5158b3cfccAndy Hung                        local.mPosition[i] >= mAudioTrackServerProxy->framesReleased());
1214818e7a32ce3633980138aff2c2bfcc5158b3cfccAndy Hung                checked = true;
1215818e7a32ce3633980138aff2c2bfcc5158b3cfccAndy Hung            }
1216818e7a32ce3633980138aff2c2bfcc5158b3cfccAndy Hung        }
1217818e7a32ce3633980138aff2c2bfcc5158b3cfccAndy Hung    }
1218818e7a32ce3633980138aff2c2bfcc5158b3cfccAndy Hung    if (!checked) { // no server info, assume drained.
1219818e7a32ce3633980138aff2c2bfcc5158b3cfccAndy Hung        mAudioTrackServerProxy->setDrained(true);
1220e10393e72454bfd8298017dc193faf424f4e9a8fAndy Hung    }
1221ea2b9c07b34079f0dbd8610a511e006e69a15adcAndy Hung    // Set correction for flushed frames that are not accounted for in released.
1222ea2b9c07b34079f0dbd8610a511e006e69a15adcAndy Hung    local.mFlushed = mAudioTrackServerProxy->framesFlushed();
1223818e7a32ce3633980138aff2c2bfcc5158b3cfccAndy Hung    mServerProxy->setTimestamp(local);
1224e10393e72454bfd8298017dc193faf424f4e9a8fAndy Hung}
1225e10393e72454bfd8298017dc193faf424f4e9a8fAndy Hung
122681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// ----------------------------------------------------------------------------
122781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
122881784c37c61b09289654b979567a42bf73cd2b12Eric LaurentAudioFlinger::PlaybackThread::OutputTrack::OutputTrack(
122981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            PlaybackThread *playbackThread,
123081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            DuplicatingThread *sourceThread,
123181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            uint32_t sampleRate,
123281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            audio_format_t format,
123381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            audio_channel_mask_t channelMask,
1234462fd2fa9eef642b0574aa7409de0bde3fec8d43Marco Nelissen            size_t frameCount,
12351f12a8ad958344c50733b948628ffa06db9c5bc6Andy Hung            uid_t uid)
1236223fd5c9738e9665e495904d37d4632414b68c1eEric Laurent    :   Track(playbackThread, NULL, AUDIO_STREAM_PATCH,
1237223fd5c9738e9665e495904d37d4632414b68c1eEric Laurent              sampleRate, format, channelMask, frameCount,
1238050677873c10d4da308ac222f8533c96cca3207eEric Laurent              NULL, 0, AUDIO_SESSION_NONE, uid, AUDIO_OUTPUT_FLAG_NONE,
1239d848eb48c121c119e8ba7583efc75415fe102570Glenn Kasten              TYPE_OUTPUT),
12405bba2f6916dbe00aea7c0521faa0c6ed42114a75Eric Laurent    mActive(false), mSourceThread(sourceThread)
124181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{
124281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
124381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    if (mCblk != NULL) {
124481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        mOutBuffer.frameCount = 0;
124581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        playbackThread->mTracks.add(this);
1246e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten        ALOGV("OutputTrack constructor mCblk %p, mBuffer %p, "
1247c42e9b462661673dff480ee71757a58b0f806370Glenn Kasten                "frameCount %zu, mChannelMask 0x%08x",
1248e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten                mCblk, mBuffer,
124974935e44734c1ec235c2b6677db3e0dbefa5ddb8Glenn Kasten                frameCount, mChannelMask);
1250e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten        // since client and server are in the same process,
1251e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten        // the buffer has the same virtual address on both sides
1252529c61b7e4468a3e21f302f2a92a660249daa722Glenn Kasten        mClientProxy = new AudioTrackClientProxy(mCblk, mBuffer, mFrameCount, mFrameSize,
1253529c61b7e4468a3e21f302f2a92a660249daa722Glenn Kasten                true /*clientInServer*/);
1254c56f3426099a3cf2d07ccff8886050c7fbce140fGlenn Kasten        mClientProxy->setVolumeLR(GAIN_MINIFLOAT_PACKED_UNITY);
12558d2d4932b96632e9eb3af4a3d4000192ef603960Eric Laurent        mClientProxy->setSendLevel(0.0);
12568d2d4932b96632e9eb3af4a3d4000192ef603960Eric Laurent        mClientProxy->setSampleRate(sampleRate);
125781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    } else {
125881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        ALOGW("Error creating output track on thread %p", playbackThread);
125981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    }
126081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
126181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
126281784c37c61b09289654b979567a42bf73cd2b12Eric LaurentAudioFlinger::PlaybackThread::OutputTrack::~OutputTrack()
126381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{
126481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    clearBufferQueue();
1265e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten    // superclass destructor will now delete the server proxy and shared memory both refer to
126681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
126781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
126881784c37c61b09289654b979567a42bf73cd2b12Eric Laurentstatus_t AudioFlinger::PlaybackThread::OutputTrack::start(AudioSystem::sync_event_t event,
1269d848eb48c121c119e8ba7583efc75415fe102570Glenn Kasten                                                          audio_session_t triggerSession)
127081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{
127181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    status_t status = Track::start(event, triggerSession);
127281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    if (status != NO_ERROR) {
127381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        return status;
127481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    }
127581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
127681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    mActive = true;
127781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    mRetryCount = 127;
127881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    return status;
127981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
128081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
128181784c37c61b09289654b979567a42bf73cd2b12Eric Laurentvoid AudioFlinger::PlaybackThread::OutputTrack::stop()
128281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{
128381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    Track::stop();
128481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    clearBufferQueue();
128581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    mOutBuffer.frameCount = 0;
128681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    mActive = false;
128781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
128881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
1289c25b84abdd7ff229d0af663fbf3a37bd9512939dAndy Hungbool AudioFlinger::PlaybackThread::OutputTrack::write(void* data, uint32_t frames)
129081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{
129181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    Buffer *pInBuffer;
129281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    Buffer inBuffer;
129381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    bool outputBufferFull = false;
129481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    inBuffer.frameCount = frames;
1295c25b84abdd7ff229d0af663fbf3a37bd9512939dAndy Hung    inBuffer.raw = data;
129681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
129781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    uint32_t waitTimeLeftMs = mSourceThread->waitTimeMs();
129881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
129981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    if (!mActive && frames != 0) {
13005bedff60b2facaa1ec5b9433647ebf1504f065caAndy Hung        (void) start();
130181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    }
130281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
130381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    while (waitTimeLeftMs) {
130481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        // First write pending buffers, then new data
130581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        if (mBufferQueue.size()) {
130681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            pInBuffer = mBufferQueue.itemAt(0);
130781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        } else {
130881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            pInBuffer = &inBuffer;
130981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        }
131081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
131181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        if (pInBuffer->frameCount == 0) {
131281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            break;
131381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        }
131481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
131581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        if (mOutBuffer.frameCount == 0) {
131681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            mOutBuffer.frameCount = pInBuffer->frameCount;
131781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            nsecs_t startTime = systemTime();
13189f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten            status_t status = obtainBuffer(&mOutBuffer, waitTimeLeftMs);
13194d231dc0ee34380956c71cbe18a750e487a69601Eric Laurent            if (status != NO_ERROR && status != NOT_ENOUGH_DATA) {
13209f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten                ALOGV("OutputTrack::write() %p thread %p no more output buffers; status %d", this,
13219f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten                        mThread.unsafe_get(), status);
132281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                outputBufferFull = true;
132381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                break;
132481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            }
132581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            uint32_t waitTimeMs = (uint32_t)ns2ms(systemTime() - startTime);
132681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            if (waitTimeLeftMs >= waitTimeMs) {
132781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                waitTimeLeftMs -= waitTimeMs;
132881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            } else {
132981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                waitTimeLeftMs = 0;
133081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            }
13314d231dc0ee34380956c71cbe18a750e487a69601Eric Laurent            if (status == NOT_ENOUGH_DATA) {
13324d231dc0ee34380956c71cbe18a750e487a69601Eric Laurent                restartIfDisabled();
13334d231dc0ee34380956c71cbe18a750e487a69601Eric Laurent                continue;
13344d231dc0ee34380956c71cbe18a750e487a69601Eric Laurent            }
133581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        }
133681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
133781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        uint32_t outFrames = pInBuffer->frameCount > mOutBuffer.frameCount ? mOutBuffer.frameCount :
133881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                pInBuffer->frameCount;
1339c25b84abdd7ff229d0af663fbf3a37bd9512939dAndy Hung        memcpy(mOutBuffer.raw, pInBuffer->raw, outFrames * mFrameSize);
13409f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten        Proxy::Buffer buf;
13419f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten        buf.mFrameCount = outFrames;
13429f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten        buf.mRaw = NULL;
13439f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten        mClientProxy->releaseBuffer(&buf);
13444d231dc0ee34380956c71cbe18a750e487a69601Eric Laurent        restartIfDisabled();
134581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        pInBuffer->frameCount -= outFrames;
1346c25b84abdd7ff229d0af663fbf3a37bd9512939dAndy Hung        pInBuffer->raw = (int8_t *)pInBuffer->raw + outFrames * mFrameSize;
134781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        mOutBuffer.frameCount -= outFrames;
1348c25b84abdd7ff229d0af663fbf3a37bd9512939dAndy Hung        mOutBuffer.raw = (int8_t *)mOutBuffer.raw + outFrames * mFrameSize;
134981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
135081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        if (pInBuffer->frameCount == 0) {
135181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            if (mBufferQueue.size()) {
135281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                mBufferQueue.removeAt(0);
1353c25b84abdd7ff229d0af663fbf3a37bd9512939dAndy Hung                free(pInBuffer->mBuffer);
135481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                delete pInBuffer;
1355c42e9b462661673dff480ee71757a58b0f806370Glenn Kasten                ALOGV("OutputTrack::write() %p thread %p released overflow buffer %zu", this,
135681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                        mThread.unsafe_get(), mBufferQueue.size());
135781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            } else {
135881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                break;
135981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            }
136081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        }
136181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    }
136281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
136381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    // If we could not write all frames, allocate a buffer and queue it for next time.
136481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    if (inBuffer.frameCount) {
136581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        sp<ThreadBase> thread = mThread.promote();
136681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        if (thread != 0 && !thread->standby()) {
136781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            if (mBufferQueue.size() < kMaxOverFlowBuffers) {
136881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                pInBuffer = new Buffer;
1369c25b84abdd7ff229d0af663fbf3a37bd9512939dAndy Hung                pInBuffer->mBuffer = malloc(inBuffer.frameCount * mFrameSize);
137081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                pInBuffer->frameCount = inBuffer.frameCount;
1371c25b84abdd7ff229d0af663fbf3a37bd9512939dAndy Hung                pInBuffer->raw = pInBuffer->mBuffer;
1372c25b84abdd7ff229d0af663fbf3a37bd9512939dAndy Hung                memcpy(pInBuffer->raw, inBuffer.raw, inBuffer.frameCount * mFrameSize);
137381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                mBufferQueue.add(pInBuffer);
1374c42e9b462661673dff480ee71757a58b0f806370Glenn Kasten                ALOGV("OutputTrack::write() %p thread %p adding overflow buffer %zu", this,
137581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                        mThread.unsafe_get(), mBufferQueue.size());
137681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            } else {
137781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                ALOGW("OutputTrack::write() %p thread %p no more overflow buffers",
137881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                        mThread.unsafe_get(), this);
137981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            }
138081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        }
138181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    }
138281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
1383c25b84abdd7ff229d0af663fbf3a37bd9512939dAndy Hung    // Calling write() with a 0 length buffer means that no more data will be written:
1384c25b84abdd7ff229d0af663fbf3a37bd9512939dAndy Hung    // We rely on stop() to set the appropriate flags to allow the remaining frames to play out.
1385c25b84abdd7ff229d0af663fbf3a37bd9512939dAndy Hung    if (frames == 0 && mBufferQueue.size() == 0 && mActive) {
1386c25b84abdd7ff229d0af663fbf3a37bd9512939dAndy Hung        stop();
138781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    }
138881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
138981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    return outputBufferFull;
139081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
139181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
139281784c37c61b09289654b979567a42bf73cd2b12Eric Laurentstatus_t AudioFlinger::PlaybackThread::OutputTrack::obtainBuffer(
139381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        AudioBufferProvider::Buffer* buffer, uint32_t waitTimeMs)
139481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{
13959f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    ClientProxy::Buffer buf;
13969f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    buf.mFrameCount = buffer->frameCount;
13979f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    struct timespec timeout;
13989f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    timeout.tv_sec = waitTimeMs / 1000;
13999f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    timeout.tv_nsec = (int) (waitTimeMs % 1000) * 1000000;
14009f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    status_t status = mClientProxy->obtainBuffer(&buf, &timeout);
14019f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    buffer->frameCount = buf.mFrameCount;
14029f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    buffer->raw = buf.mRaw;
14039f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    return status;
140481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
140581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
140681784c37c61b09289654b979567a42bf73cd2b12Eric Laurentvoid AudioFlinger::PlaybackThread::OutputTrack::clearBufferQueue()
140781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{
140881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    size_t size = mBufferQueue.size();
140981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
141081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    for (size_t i = 0; i < size; i++) {
141181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        Buffer *pBuffer = mBufferQueue.itemAt(i);
1412c25b84abdd7ff229d0af663fbf3a37bd9512939dAndy Hung        free(pBuffer->mBuffer);
141381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        delete pBuffer;
141481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    }
141581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    mBufferQueue.clear();
141681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
141781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
14184d231dc0ee34380956c71cbe18a750e487a69601Eric Laurentvoid AudioFlinger::PlaybackThread::OutputTrack::restartIfDisabled()
14194d231dc0ee34380956c71cbe18a750e487a69601Eric Laurent{
14204d231dc0ee34380956c71cbe18a750e487a69601Eric Laurent    int32_t flags = android_atomic_and(~CBLK_DISABLED, &mCblk->mFlags);
14214d231dc0ee34380956c71cbe18a750e487a69601Eric Laurent    if (mActive && (flags & CBLK_DISABLED)) {
14224d231dc0ee34380956c71cbe18a750e487a69601Eric Laurent        start();
14234d231dc0ee34380956c71cbe18a750e487a69601Eric Laurent    }
14244d231dc0ee34380956c71cbe18a750e487a69601Eric Laurent}
142581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
142683b8808faad1e91690c64d7007348be8d9ebde73Eric LaurentAudioFlinger::PlaybackThread::PatchTrack::PatchTrack(PlaybackThread *playbackThread,
14273bcf8597189c592713675ec58326ecbef0ac4ae9Eric Laurent                                                     audio_stream_type_t streamType,
142883b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent                                                     uint32_t sampleRate,
142983b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent                                                     audio_channel_mask_t channelMask,
143083b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent                                                     audio_format_t format,
143183b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent                                                     size_t frameCount,
143283b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent                                                     void *buffer,
1433050677873c10d4da308ac222f8533c96cca3207eEric Laurent                                                     audio_output_flags_t flags)
14343bcf8597189c592713675ec58326ecbef0ac4ae9Eric Laurent    :   Track(playbackThread, NULL, streamType,
1435223fd5c9738e9665e495904d37d4632414b68c1eEric Laurent              sampleRate, format, channelMask, frameCount,
1436d848eb48c121c119e8ba7583efc75415fe102570Glenn Kasten              buffer, 0, AUDIO_SESSION_NONE, getuid(), flags, TYPE_PATCH),
143783b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent              mProxy(new ClientProxy(mCblk, mBuffer, frameCount, mFrameSize, true, true))
143883b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent{
143983b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent    uint64_t mixBufferNs = ((uint64_t)2 * playbackThread->frameCount() * 1000000000) /
144083b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent                                                                    playbackThread->sampleRate();
144183b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent    mPeerTimeout.tv_sec = mixBufferNs / 1000000000;
144283b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent    mPeerTimeout.tv_nsec = (int) (mixBufferNs % 1000000000);
144383b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent
144483b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent    ALOGV("PatchTrack %p sampleRate %d mPeerTimeout %d.%03d sec",
144583b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent                                      this, sampleRate,
144683b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent                                      (int)mPeerTimeout.tv_sec,
144783b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent                                      (int)(mPeerTimeout.tv_nsec / 1000000));
144883b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent}
144983b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent
145083b8808faad1e91690c64d7007348be8d9ebde73Eric LaurentAudioFlinger::PlaybackThread::PatchTrack::~PatchTrack()
145183b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent{
145283b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent}
145383b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent
14544d231dc0ee34380956c71cbe18a750e487a69601Eric Laurentstatus_t AudioFlinger::PlaybackThread::PatchTrack::start(AudioSystem::sync_event_t event,
1455d848eb48c121c119e8ba7583efc75415fe102570Glenn Kasten                                                          audio_session_t triggerSession)
14564d231dc0ee34380956c71cbe18a750e487a69601Eric Laurent{
14574d231dc0ee34380956c71cbe18a750e487a69601Eric Laurent    status_t status = Track::start(event, triggerSession);
14584d231dc0ee34380956c71cbe18a750e487a69601Eric Laurent    if (status != NO_ERROR) {
14594d231dc0ee34380956c71cbe18a750e487a69601Eric Laurent        return status;
14604d231dc0ee34380956c71cbe18a750e487a69601Eric Laurent    }
14614d231dc0ee34380956c71cbe18a750e487a69601Eric Laurent    android_atomic_and(~CBLK_DISABLED, &mCblk->mFlags);
14624d231dc0ee34380956c71cbe18a750e487a69601Eric Laurent    return status;
14634d231dc0ee34380956c71cbe18a750e487a69601Eric Laurent}
14644d231dc0ee34380956c71cbe18a750e487a69601Eric Laurent
146583b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent// AudioBufferProvider interface
146683b8808faad1e91690c64d7007348be8d9ebde73Eric Laurentstatus_t AudioFlinger::PlaybackThread::PatchTrack::getNextBuffer(
1467d79072e9dff59f767cce2cda1caab80ce5a0815bGlenn Kasten        AudioBufferProvider::Buffer* buffer)
146883b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent{
146983b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent    ALOG_ASSERT(mPeerProxy != 0, "PatchTrack::getNextBuffer() called without peer proxy");
147083b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent    Proxy::Buffer buf;
147183b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent    buf.mFrameCount = buffer->frameCount;
147283b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent    status_t status = mPeerProxy->obtainBuffer(&buf, &mPeerTimeout);
147383b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent    ALOGV_IF(status != NO_ERROR, "PatchTrack() %p getNextBuffer status %d", this, status);
1474c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent    buffer->frameCount = buf.mFrameCount;
147583b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent    if (buf.mFrameCount == 0) {
147683b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent        return WOULD_BLOCK;
147783b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent    }
1478d79072e9dff59f767cce2cda1caab80ce5a0815bGlenn Kasten    status = Track::getNextBuffer(buffer);
147983b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent    return status;
148083b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent}
148183b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent
148283b8808faad1e91690c64d7007348be8d9ebde73Eric Laurentvoid AudioFlinger::PlaybackThread::PatchTrack::releaseBuffer(AudioBufferProvider::Buffer* buffer)
148383b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent{
148483b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent    ALOG_ASSERT(mPeerProxy != 0, "PatchTrack::releaseBuffer() called without peer proxy");
148583b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent    Proxy::Buffer buf;
148683b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent    buf.mFrameCount = buffer->frameCount;
148783b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent    buf.mRaw = buffer->raw;
148883b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent    mPeerProxy->releaseBuffer(&buf);
148983b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent    TrackBase::releaseBuffer(buffer);
149083b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent}
149183b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent
149283b8808faad1e91690c64d7007348be8d9ebde73Eric Laurentstatus_t AudioFlinger::PlaybackThread::PatchTrack::obtainBuffer(Proxy::Buffer* buffer,
149383b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent                                                                const struct timespec *timeOut)
149483b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent{
14954d231dc0ee34380956c71cbe18a750e487a69601Eric Laurent    status_t status = NO_ERROR;
14964d231dc0ee34380956c71cbe18a750e487a69601Eric Laurent    static const int32_t kMaxTries = 5;
14974d231dc0ee34380956c71cbe18a750e487a69601Eric Laurent    int32_t tryCounter = kMaxTries;
14984d231dc0ee34380956c71cbe18a750e487a69601Eric Laurent    do {
14994d231dc0ee34380956c71cbe18a750e487a69601Eric Laurent        if (status == NOT_ENOUGH_DATA) {
15004d231dc0ee34380956c71cbe18a750e487a69601Eric Laurent            restartIfDisabled();
15014d231dc0ee34380956c71cbe18a750e487a69601Eric Laurent        }
15024d231dc0ee34380956c71cbe18a750e487a69601Eric Laurent        status = mProxy->obtainBuffer(buffer, timeOut);
15034d231dc0ee34380956c71cbe18a750e487a69601Eric Laurent    } while ((status == NOT_ENOUGH_DATA) && (tryCounter-- > 0));
15044d231dc0ee34380956c71cbe18a750e487a69601Eric Laurent    return status;
150583b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent}
150683b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent
150783b8808faad1e91690c64d7007348be8d9ebde73Eric Laurentvoid AudioFlinger::PlaybackThread::PatchTrack::releaseBuffer(Proxy::Buffer* buffer)
150883b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent{
150983b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent    mProxy->releaseBuffer(buffer);
15104d231dc0ee34380956c71cbe18a750e487a69601Eric Laurent    restartIfDisabled();
15114d231dc0ee34380956c71cbe18a750e487a69601Eric Laurent    android_atomic_or(CBLK_FORCEREADY, &mCblk->mFlags);
15124d231dc0ee34380956c71cbe18a750e487a69601Eric Laurent}
15134d231dc0ee34380956c71cbe18a750e487a69601Eric Laurent
15144d231dc0ee34380956c71cbe18a750e487a69601Eric Laurentvoid AudioFlinger::PlaybackThread::PatchTrack::restartIfDisabled()
15154d231dc0ee34380956c71cbe18a750e487a69601Eric Laurent{
151683b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent    if (android_atomic_and(~CBLK_DISABLED, &mCblk->mFlags) & CBLK_DISABLED) {
151783b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent        ALOGW("PatchTrack::releaseBuffer() disabled due to previous underrun, restarting");
151883b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent        start();
151983b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent    }
152083b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent}
152183b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent
152281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// ----------------------------------------------------------------------------
152381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent//      Record
152481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// ----------------------------------------------------------------------------
152581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
152681784c37c61b09289654b979567a42bf73cd2b12Eric LaurentAudioFlinger::RecordHandle::RecordHandle(
152781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        const sp<AudioFlinger::RecordThread::RecordTrack>& recordTrack)
152881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    : BnAudioRecord(),
152981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    mRecordTrack(recordTrack)
153081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{
153181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
153281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
153381784c37c61b09289654b979567a42bf73cd2b12Eric LaurentAudioFlinger::RecordHandle::~RecordHandle() {
153481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    stop_nonvirtual();
153581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    mRecordTrack->destroy();
153681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
153781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
153881784c37c61b09289654b979567a42bf73cd2b12Eric Laurentstatus_t AudioFlinger::RecordHandle::start(int /*AudioSystem::sync_event_t*/ event,
1539d848eb48c121c119e8ba7583efc75415fe102570Glenn Kasten        audio_session_t triggerSession) {
154081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    ALOGV("RecordHandle::start()");
154181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    return mRecordTrack->start((AudioSystem::sync_event_t)event, triggerSession);
154281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
154381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
154481784c37c61b09289654b979567a42bf73cd2b12Eric Laurentvoid AudioFlinger::RecordHandle::stop() {
154581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    stop_nonvirtual();
154681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
154781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
154881784c37c61b09289654b979567a42bf73cd2b12Eric Laurentvoid AudioFlinger::RecordHandle::stop_nonvirtual() {
154981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    ALOGV("RecordHandle::stop()");
155081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    mRecordTrack->stop();
155181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
155281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
155381784c37c61b09289654b979567a42bf73cd2b12Eric Laurentstatus_t AudioFlinger::RecordHandle::onTransact(
155481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
155581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{
155681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    return BnAudioRecord::onTransact(code, data, reply, flags);
155781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
155881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
155981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// ----------------------------------------------------------------------------
156081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
156105997e21af6c4517f375def6563af4b9ebe95f39Glenn Kasten// RecordTrack constructor must be called with AudioFlinger::mLock and ThreadBase::mLock held
156281784c37c61b09289654b979567a42bf73cd2b12Eric LaurentAudioFlinger::RecordThread::RecordTrack::RecordTrack(
156381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            RecordThread *thread,
156481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            const sp<Client>& client,
156581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            uint32_t sampleRate,
156681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            audio_format_t format,
156781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            audio_channel_mask_t channelMask,
156881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            size_t frameCount,
156983b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent            void *buffer,
1570d848eb48c121c119e8ba7583efc75415fe102570Glenn Kasten            audio_session_t sessionId,
15711f12a8ad958344c50733b948628ffa06db9c5bc6Andy Hung            uid_t uid,
1572050677873c10d4da308ac222f8533c96cca3207eEric Laurent            audio_input_flags_t flags,
157320b9ef0b55c9150ae11057ab997ae61be2d496efEric Laurent            track_type type,
157420b9ef0b55c9150ae11057ab997ae61be2d496efEric Laurent            audio_port_handle_t portId)
157581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    :   TrackBase(thread, client, sampleRate, format,
1576050677873c10d4da308ac222f8533c96cca3207eEric Laurent                  channelMask, frameCount, buffer, sessionId, uid, false /*isOut*/,
157783b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent                  (type == TYPE_DEFAULT) ?
1578050677873c10d4da308ac222f8533c96cca3207eEric Laurent                          ((flags & AUDIO_INPUT_FLAG_FAST) ? ALLOC_PIPE : ALLOC_CBLK) :
157983b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent                          ((buffer == NULL) ? ALLOC_LOCAL : ALLOC_NONE),
158020b9ef0b55c9150ae11057ab997ae61be2d496efEric Laurent                  type, portId),
158197a893eb34f8687485c88eaf15917974a203f20bAndy Hung        mOverflow(false),
15824c6afaf1053ecbfda6d95098e0f49772ecbcf2e1Andy Hung        mFramesToDrop(0),
15834c6afaf1053ecbfda6d95098e0f49772ecbcf2e1Andy Hung        mResamplerBufferProvider(NULL), // initialize in case of early constructor exit
1584050677873c10d4da308ac222f8533c96cca3207eEric Laurent        mRecordBufferConverter(NULL),
1585050677873c10d4da308ac222f8533c96cca3207eEric Laurent        mFlags(flags)
158681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{
15873ef14ef30359376006a233f6a21a165d4b65a7dfGlenn Kasten    if (mCblk == NULL) {
15883ef14ef30359376006a233f6a21a165d4b65a7dfGlenn Kasten        return;
15899f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    }
15906dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten
159197a893eb34f8687485c88eaf15917974a203f20bAndy Hung    mRecordBufferConverter = new RecordBufferConverter(
159297a893eb34f8687485c88eaf15917974a203f20bAndy Hung            thread->mChannelMask, thread->mFormat, thread->mSampleRate,
159397a893eb34f8687485c88eaf15917974a203f20bAndy Hung            channelMask, format, sampleRate);
159497a893eb34f8687485c88eaf15917974a203f20bAndy Hung    // Check if the RecordBufferConverter construction was successful.
159597a893eb34f8687485c88eaf15917974a203f20bAndy Hung    // If not, don't continue with construction.
159697a893eb34f8687485c88eaf15917974a203f20bAndy Hung    //
159797a893eb34f8687485c88eaf15917974a203f20bAndy Hung    // NOTE: It would be extremely rare that the record track cannot be created
159897a893eb34f8687485c88eaf15917974a203f20bAndy Hung    // for the current device, but a pending or future device change would make
159997a893eb34f8687485c88eaf15917974a203f20bAndy Hung    // the record track configuration valid.
160097a893eb34f8687485c88eaf15917974a203f20bAndy Hung    if (mRecordBufferConverter->initCheck() != NO_ERROR) {
160197a893eb34f8687485c88eaf15917974a203f20bAndy Hung        ALOGE("RecordTrack unable to create record buffer converter");
160297a893eb34f8687485c88eaf15917974a203f20bAndy Hung        return;
160397a893eb34f8687485c88eaf15917974a203f20bAndy Hung    }
160497a893eb34f8687485c88eaf15917974a203f20bAndy Hung
16056ae5843c281301a9ffd1059d185620a9337e15a2Andy Hung    mServerProxy = new AudioRecordServerProxy(mCblk, mBuffer, frameCount,
16063f0c902beb53a245c9db35e871607dba05b8d391Andy Hung            mFrameSize, !isExternalTrack());
16073f0c902beb53a245c9db35e871607dba05b8d391Andy Hung
160897a893eb34f8687485c88eaf15917974a203f20bAndy Hung    mResamplerBufferProvider = new ResamplerBufferProvider(this);
1609c263ca0ad8b6bdf5b0693996bc5f2f5916e0cd49Glenn Kasten
1610050677873c10d4da308ac222f8533c96cca3207eEric Laurent    if (flags & AUDIO_INPUT_FLAG_FAST) {
1611c263ca0ad8b6bdf5b0693996bc5f2f5916e0cd49Glenn Kasten        ALOG_ASSERT(thread->mFastTrackAvail);
1612c263ca0ad8b6bdf5b0693996bc5f2f5916e0cd49Glenn Kasten        thread->mFastTrackAvail = false;
1613c263ca0ad8b6bdf5b0693996bc5f2f5916e0cd49Glenn Kasten    }
161481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
161581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
161681784c37c61b09289654b979567a42bf73cd2b12Eric LaurentAudioFlinger::RecordThread::RecordTrack::~RecordTrack()
161781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{
161881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    ALOGV("%s", __func__);
161997a893eb34f8687485c88eaf15917974a203f20bAndy Hung    delete mRecordBufferConverter;
16206dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten    delete mResamplerBufferProvider;
162181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
162281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
162397a893eb34f8687485c88eaf15917974a203f20bAndy Hungstatus_t AudioFlinger::RecordThread::RecordTrack::initCheck() const
162497a893eb34f8687485c88eaf15917974a203f20bAndy Hung{
162597a893eb34f8687485c88eaf15917974a203f20bAndy Hung    status_t status = TrackBase::initCheck();
162697a893eb34f8687485c88eaf15917974a203f20bAndy Hung    if (status == NO_ERROR && mServerProxy == 0) {
162797a893eb34f8687485c88eaf15917974a203f20bAndy Hung        status = BAD_VALUE;
162897a893eb34f8687485c88eaf15917974a203f20bAndy Hung    }
162997a893eb34f8687485c88eaf15917974a203f20bAndy Hung    return status;
163097a893eb34f8687485c88eaf15917974a203f20bAndy Hung}
163197a893eb34f8687485c88eaf15917974a203f20bAndy Hung
163281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// AudioBufferProvider interface
1633d79072e9dff59f767cce2cda1caab80ce5a0815bGlenn Kastenstatus_t AudioFlinger::RecordThread::RecordTrack::getNextBuffer(AudioBufferProvider::Buffer* buffer)
163481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{
16359f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    ServerProxy::Buffer buf;
16369f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    buf.mFrameCount = buffer->frameCount;
16379f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    status_t status = mServerProxy->obtainBuffer(&buf);
16389f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    buffer->frameCount = buf.mFrameCount;
16399f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    buffer->raw = buf.mRaw;
16409f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    if (buf.mFrameCount == 0) {
16419f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten        // FIXME also wake futex so that overrun is noticed more quickly
164296f60d8f04432a1ed503b3e24d5736d28c63c9a2Glenn Kasten        (void) android_atomic_or(CBLK_OVERRUN, &mCblk->mFlags);
164381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    }
16449f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    return status;
164581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
164681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
164781784c37c61b09289654b979567a42bf73cd2b12Eric Laurentstatus_t AudioFlinger::RecordThread::RecordTrack::start(AudioSystem::sync_event_t event,
1648d848eb48c121c119e8ba7583efc75415fe102570Glenn Kasten                                                        audio_session_t triggerSession)
164981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{
165081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    sp<ThreadBase> thread = mThread.promote();
165181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    if (thread != 0) {
165281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        RecordThread *recordThread = (RecordThread *)thread.get();
165381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        return recordThread->start(this, event, triggerSession);
165481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    } else {
165581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        return BAD_VALUE;
165681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    }
165781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
165881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
165981784c37c61b09289654b979567a42bf73cd2b12Eric Laurentvoid AudioFlinger::RecordThread::RecordTrack::stop()
166081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{
166181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    sp<ThreadBase> thread = mThread.promote();
166281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    if (thread != 0) {
166381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        RecordThread *recordThread = (RecordThread *)thread.get();
166483b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent        if (recordThread->stop(this) && isExternalTrack()) {
1665d848eb48c121c119e8ba7583efc75415fe102570Glenn Kasten            AudioSystem::stopInput(mThreadIoHandle, mSessionId);
166681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        }
166781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    }
166881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
166981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
167081784c37c61b09289654b979567a42bf73cd2b12Eric Laurentvoid AudioFlinger::RecordThread::RecordTrack::destroy()
167181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{
167281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    // see comments at AudioFlinger::PlaybackThread::Track::destroy()
167381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    sp<RecordTrack> keep(this);
167481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    {
1675aaa44478a373232d8416657035a9020f9c7aa7c3Eric Laurent        if (isExternalTrack()) {
1676aaa44478a373232d8416657035a9020f9c7aa7c3Eric Laurent            if (mState == ACTIVE || mState == RESUMING) {
1677d848eb48c121c119e8ba7583efc75415fe102570Glenn Kasten                AudioSystem::stopInput(mThreadIoHandle, mSessionId);
1678aaa44478a373232d8416657035a9020f9c7aa7c3Eric Laurent            }
1679d848eb48c121c119e8ba7583efc75415fe102570Glenn Kasten            AudioSystem::releaseInput(mThreadIoHandle, mSessionId);
1680aaa44478a373232d8416657035a9020f9c7aa7c3Eric Laurent        }
168181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        sp<ThreadBase> thread = mThread.promote();
168281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        if (thread != 0) {
168381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            Mutex::Autolock _l(thread->mLock);
168481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            RecordThread *recordThread = (RecordThread *) thread.get();
168581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            recordThread->destroyTrack_l(this);
168681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        }
168781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    }
168881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
168981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
16909a54bc27876acd5d8be5b1fc3dc46701fe76fbb3Eric Laurentvoid AudioFlinger::RecordThread::RecordTrack::invalidate()
16919a54bc27876acd5d8be5b1fc3dc46701fe76fbb3Eric Laurent{
16926acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent    TrackBase::invalidate();
16939a54bc27876acd5d8be5b1fc3dc46701fe76fbb3Eric Laurent    // FIXME should use proxy, and needs work
16949a54bc27876acd5d8be5b1fc3dc46701fe76fbb3Eric Laurent    audio_track_cblk_t* cblk = mCblk;
16959a54bc27876acd5d8be5b1fc3dc46701fe76fbb3Eric Laurent    android_atomic_or(CBLK_INVALID, &cblk->mFlags);
16969a54bc27876acd5d8be5b1fc3dc46701fe76fbb3Eric Laurent    android_atomic_release_store(0x40000000, &cblk->mFutex);
16979a54bc27876acd5d8be5b1fc3dc46701fe76fbb3Eric Laurent    // client is not in server, so FUTEX_WAKE is needed instead of FUTEX_WAKE_PRIVATE
1698ee499291404a192b059f2e04c5afc65aa6cdd74cElliott Hughes    (void) syscall(__NR_futex, &cblk->mFutex, FUTEX_WAKE, INT_MAX);
16999a54bc27876acd5d8be5b1fc3dc46701fe76fbb3Eric Laurent}
17009a54bc27876acd5d8be5b1fc3dc46701fe76fbb3Eric Laurent
170181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
170281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent/*static*/ void AudioFlinger::RecordThread::RecordTrack::appendDumpHeader(String8& result)
170381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{
17046e6704c06d61bc356e30c164081e5bcffb37920cGlenn Kasten    result.append("    Active Client Fmt Chn mask Session S   Server fCount SRate\n");
170581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
170681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
1707b220884bf3129253cc5bc8d030bc475411ea4911Marco Nelissenvoid AudioFlinger::RecordThread::RecordTrack::dump(char* buffer, size_t size, bool active)
170881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{
17096e6704c06d61bc356e30c164081e5bcffb37920cGlenn Kasten    snprintf(buffer, size, "    %6s %6u %3u %08X %7u %1d %08X %6zu %5u\n",
1710b220884bf3129253cc5bc8d030bc475411ea4911Marco Nelissen            active ? "yes" : "no",
171181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            (mClient == 0) ? getpid_cached : mClient->pid(),
171281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            mFormat,
171381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            mChannelMask,
171481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            mSessionId,
171581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            mState,
1716f20e1d8df84c5fbeeace0052d100982ae39bb7a4Glenn Kasten            mCblk->mServer,
17176dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten            mFrameCount,
17186e6704c06d61bc356e30c164081e5bcffb37920cGlenn Kasten            mSampleRate);
17196dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten
172081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
172181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
172225f4aa83efaa9179e65a20583a6d441de2c3ff3fGlenn Kastenvoid AudioFlinger::RecordThread::RecordTrack::handleSyncStartEvent(const sp<SyncEvent>& event)
172325f4aa83efaa9179e65a20583a6d441de2c3ff3fGlenn Kasten{
172425f4aa83efaa9179e65a20583a6d441de2c3ff3fGlenn Kasten    if (event == mSyncStartEvent) {
172525f4aa83efaa9179e65a20583a6d441de2c3ff3fGlenn Kasten        ssize_t framesToDrop = 0;
172625f4aa83efaa9179e65a20583a6d441de2c3ff3fGlenn Kasten        sp<ThreadBase> threadBase = mThread.promote();
172725f4aa83efaa9179e65a20583a6d441de2c3ff3fGlenn Kasten        if (threadBase != 0) {
172825f4aa83efaa9179e65a20583a6d441de2c3ff3fGlenn Kasten            // TODO: use actual buffer filling status instead of 2 buffers when info is available
172925f4aa83efaa9179e65a20583a6d441de2c3ff3fGlenn Kasten            // from audio HAL
173025f4aa83efaa9179e65a20583a6d441de2c3ff3fGlenn Kasten            framesToDrop = threadBase->mFrameCount * 2;
173125f4aa83efaa9179e65a20583a6d441de2c3ff3fGlenn Kasten        }
173225f4aa83efaa9179e65a20583a6d441de2c3ff3fGlenn Kasten        mFramesToDrop = framesToDrop;
173325f4aa83efaa9179e65a20583a6d441de2c3ff3fGlenn Kasten    }
173425f4aa83efaa9179e65a20583a6d441de2c3ff3fGlenn Kasten}
173525f4aa83efaa9179e65a20583a6d441de2c3ff3fGlenn Kasten
173625f4aa83efaa9179e65a20583a6d441de2c3ff3fGlenn Kastenvoid AudioFlinger::RecordThread::RecordTrack::clearSyncStartEvent()
173725f4aa83efaa9179e65a20583a6d441de2c3ff3fGlenn Kasten{
173825f4aa83efaa9179e65a20583a6d441de2c3ff3fGlenn Kasten    if (mSyncStartEvent != 0) {
173925f4aa83efaa9179e65a20583a6d441de2c3ff3fGlenn Kasten        mSyncStartEvent->cancel();
174025f4aa83efaa9179e65a20583a6d441de2c3ff3fGlenn Kasten        mSyncStartEvent.clear();
174125f4aa83efaa9179e65a20583a6d441de2c3ff3fGlenn Kasten    }
174225f4aa83efaa9179e65a20583a6d441de2c3ff3fGlenn Kasten    mFramesToDrop = 0;
174325f4aa83efaa9179e65a20583a6d441de2c3ff3fGlenn Kasten}
174425f4aa83efaa9179e65a20583a6d441de2c3ff3fGlenn Kasten
17453f0c902beb53a245c9db35e871607dba05b8d391Andy Hungvoid AudioFlinger::RecordThread::RecordTrack::updateTrackFrameInfo(
17463f0c902beb53a245c9db35e871607dba05b8d391Andy Hung        int64_t trackFramesReleased, int64_t sourceFramesRead,
17473f0c902beb53a245c9db35e871607dba05b8d391Andy Hung        uint32_t halSampleRate, const ExtendedTimestamp &timestamp)
17483f0c902beb53a245c9db35e871607dba05b8d391Andy Hung{
17493f0c902beb53a245c9db35e871607dba05b8d391Andy Hung    ExtendedTimestamp local = timestamp;
17503f0c902beb53a245c9db35e871607dba05b8d391Andy Hung
17513f0c902beb53a245c9db35e871607dba05b8d391Andy Hung    // Convert HAL frames to server-side track frames at track sample rate.
17523f0c902beb53a245c9db35e871607dba05b8d391Andy Hung    // We use trackFramesReleased and sourceFramesRead as an anchor point.
17533f0c902beb53a245c9db35e871607dba05b8d391Andy Hung    for (int i = ExtendedTimestamp::LOCATION_SERVER; i < ExtendedTimestamp::LOCATION_MAX; ++i) {
17543f0c902beb53a245c9db35e871607dba05b8d391Andy Hung        if (local.mTimeNs[i] != 0) {
17553f0c902beb53a245c9db35e871607dba05b8d391Andy Hung            const int64_t relativeServerFrames = local.mPosition[i] - sourceFramesRead;
17563f0c902beb53a245c9db35e871607dba05b8d391Andy Hung            const int64_t relativeTrackFrames = relativeServerFrames
17573f0c902beb53a245c9db35e871607dba05b8d391Andy Hung                    * mSampleRate / halSampleRate; // TODO: potential computation overflow
17583f0c902beb53a245c9db35e871607dba05b8d391Andy Hung            local.mPosition[i] = relativeTrackFrames + trackFramesReleased;
17593f0c902beb53a245c9db35e871607dba05b8d391Andy Hung        }
17603f0c902beb53a245c9db35e871607dba05b8d391Andy Hung    }
17616ae5843c281301a9ffd1059d185620a9337e15a2Andy Hung    mServerProxy->setTimestamp(local);
17623f0c902beb53a245c9db35e871607dba05b8d391Andy Hung}
176383b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent
176483b8808faad1e91690c64d7007348be8d9ebde73Eric LaurentAudioFlinger::RecordThread::PatchRecord::PatchRecord(RecordThread *recordThread,
176583b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent                                                     uint32_t sampleRate,
176683b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent                                                     audio_channel_mask_t channelMask,
176783b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent                                                     audio_format_t format,
176883b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent                                                     size_t frameCount,
176983b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent                                                     void *buffer,
1770050677873c10d4da308ac222f8533c96cca3207eEric Laurent                                                     audio_input_flags_t flags)
177183b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent    :   RecordTrack(recordThread, NULL, sampleRate, format, channelMask, frameCount,
1772d848eb48c121c119e8ba7583efc75415fe102570Glenn Kasten                buffer, AUDIO_SESSION_NONE, getuid(), flags, TYPE_PATCH),
177383b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent                mProxy(new ClientProxy(mCblk, mBuffer, frameCount, mFrameSize, false, true))
177483b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent{
177583b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent    uint64_t mixBufferNs = ((uint64_t)2 * recordThread->frameCount() * 1000000000) /
177683b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent                                                                recordThread->sampleRate();
177783b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent    mPeerTimeout.tv_sec = mixBufferNs / 1000000000;
177883b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent    mPeerTimeout.tv_nsec = (int) (mixBufferNs % 1000000000);
177983b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent
178083b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent    ALOGV("PatchRecord %p sampleRate %d mPeerTimeout %d.%03d sec",
178183b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent                                      this, sampleRate,
178283b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent                                      (int)mPeerTimeout.tv_sec,
178383b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent                                      (int)(mPeerTimeout.tv_nsec / 1000000));
178483b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent}
178583b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent
178683b8808faad1e91690c64d7007348be8d9ebde73Eric LaurentAudioFlinger::RecordThread::PatchRecord::~PatchRecord()
178783b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent{
178883b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent}
178983b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent
179083b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent// AudioBufferProvider interface
179183b8808faad1e91690c64d7007348be8d9ebde73Eric Laurentstatus_t AudioFlinger::RecordThread::PatchRecord::getNextBuffer(
1792d79072e9dff59f767cce2cda1caab80ce5a0815bGlenn Kasten                                                  AudioBufferProvider::Buffer* buffer)
179383b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent{
179483b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent    ALOG_ASSERT(mPeerProxy != 0, "PatchRecord::getNextBuffer() called without peer proxy");
179583b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent    Proxy::Buffer buf;
179683b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent    buf.mFrameCount = buffer->frameCount;
179783b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent    status_t status = mPeerProxy->obtainBuffer(&buf, &mPeerTimeout);
179883b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent    ALOGV_IF(status != NO_ERROR,
179983b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent             "PatchRecord() %p mPeerProxy->obtainBuffer status %d", this, status);
1800c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent    buffer->frameCount = buf.mFrameCount;
180183b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent    if (buf.mFrameCount == 0) {
180283b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent        return WOULD_BLOCK;
180383b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent    }
1804d79072e9dff59f767cce2cda1caab80ce5a0815bGlenn Kasten    status = RecordTrack::getNextBuffer(buffer);
180583b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent    return status;
180683b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent}
180783b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent
180883b8808faad1e91690c64d7007348be8d9ebde73Eric Laurentvoid AudioFlinger::RecordThread::PatchRecord::releaseBuffer(AudioBufferProvider::Buffer* buffer)
180983b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent{
181083b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent    ALOG_ASSERT(mPeerProxy != 0, "PatchRecord::releaseBuffer() called without peer proxy");
181183b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent    Proxy::Buffer buf;
181283b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent    buf.mFrameCount = buffer->frameCount;
181383b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent    buf.mRaw = buffer->raw;
181483b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent    mPeerProxy->releaseBuffer(&buf);
181583b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent    TrackBase::releaseBuffer(buffer);
181683b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent}
181783b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent
181883b8808faad1e91690c64d7007348be8d9ebde73Eric Laurentstatus_t AudioFlinger::RecordThread::PatchRecord::obtainBuffer(Proxy::Buffer* buffer,
181983b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent                                                               const struct timespec *timeOut)
182083b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent{
182183b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent    return mProxy->obtainBuffer(buffer, timeOut);
182283b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent}
182383b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent
182483b8808faad1e91690c64d7007348be8d9ebde73Eric Laurentvoid AudioFlinger::RecordThread::PatchRecord::releaseBuffer(Proxy::Buffer* buffer)
182583b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent{
182683b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent    mProxy->releaseBuffer(buffer);
182783b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent}
182883b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent
18296acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent
18306acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent
18316acd1d432f526ae9a055ddaece28bf93b474a776Eric LaurentAudioFlinger::MmapThread::MmapTrack::MmapTrack(ThreadBase *thread,
18326acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent        uint32_t sampleRate,
18336acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent        audio_format_t format,
18346acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent        audio_channel_mask_t channelMask,
18356acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent        audio_session_t sessionId,
18366acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent        uid_t uid,
18376acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent        audio_port_handle_t portId)
18386acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent    :   TrackBase(thread, NULL, sampleRate, format,
18396acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent                  channelMask, 0, NULL, sessionId, uid, false,
18406acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent                  ALLOC_NONE,
18416acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent                  TYPE_DEFAULT, portId)
18426acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent{
18436acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent}
18446acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent
18456acd1d432f526ae9a055ddaece28bf93b474a776Eric LaurentAudioFlinger::MmapThread::MmapTrack::~MmapTrack()
18466acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent{
18476acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent}
18486acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent
18496acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurentstatus_t AudioFlinger::MmapThread::MmapTrack::initCheck() const
18506acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent{
18516acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent    return NO_ERROR;
18526acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent}
18536acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent
18546acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurentstatus_t AudioFlinger::MmapThread::MmapTrack::start(AudioSystem::sync_event_t event __unused,
18556acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent                                                        audio_session_t triggerSession __unused)
18566acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent{
18576acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent    return NO_ERROR;
18586acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent}
18596acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent
18606acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurentvoid AudioFlinger::MmapThread::MmapTrack::stop()
18616acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent{
18626acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent}
18636acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent
18646acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent// AudioBufferProvider interface
18656acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurentstatus_t AudioFlinger::MmapThread::MmapTrack::getNextBuffer(AudioBufferProvider::Buffer* buffer)
18666acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent{
18676acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent    buffer->frameCount = 0;
18686acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent    buffer->raw = nullptr;
18696acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent    return INVALID_OPERATION;
18706acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent}
18716acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent
18726acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent// ExtendedAudioBufferProvider interface
18736acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurentsize_t AudioFlinger::MmapThread::MmapTrack::framesReady() const {
18746acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent    return 0;
18756acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent}
18766acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent
18776acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurentint64_t AudioFlinger::MmapThread::MmapTrack::framesReleased() const
18786acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent{
18796acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent    return 0;
18806acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent}
18816acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent
18826acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurentvoid AudioFlinger::MmapThread::MmapTrack::onTimestamp(const ExtendedTimestamp &timestamp __unused)
18836acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent{
18846acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent}
18856acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent
18866acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent/*static*/ void AudioFlinger::MmapThread::MmapTrack::appendDumpHeader(String8& result)
18876acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent{
18886acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent    result.append("    Client Fmt Chn mask  SRate\n");
18896acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent}
18906acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent
18916acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurentvoid AudioFlinger::MmapThread::MmapTrack::dump(char* buffer, size_t size)
18926acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent{
18936acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent    snprintf(buffer, size, "            %6u %3u    %08X %5u\n",
18946acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent            mUid,
18956acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent            mFormat,
18966acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent            mChannelMask,
18976acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent            mSampleRate);
18986acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent
18996acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent}
19006acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent
190163238efb0d674758902918e3cdaac322126484b7Glenn Kasten} // namespace android
1902