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
5381784c37c61b09289654b979567a42bf73cd2b12Eric Laurentnamespace android {
5481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
5581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// ----------------------------------------------------------------------------
5681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent//      TrackBase
5781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// ----------------------------------------------------------------------------
5881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
59da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kastenstatic volatile int32_t nextTrackId = 55;
60da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten
6181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// TrackBase constructor must be called with AudioFlinger::mLock held
6281784c37c61b09289654b979567a42bf73cd2b12Eric LaurentAudioFlinger::ThreadBase::TrackBase::TrackBase(
6381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            ThreadBase *thread,
6481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            const sp<Client>& client,
6581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            uint32_t sampleRate,
6681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            audio_format_t format,
6781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            audio_channel_mask_t channelMask,
6881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            size_t frameCount,
6983b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent            void *buffer,
708fe68036c2a670abb9eb0cc67ab9830c2c23de81Andy Hung            size_t bufferSize,
71d848eb48c121c119e8ba7583efc75415fe102570Glenn Kasten            audio_session_t sessionId,
721f12a8ad958344c50733b948628ffa06db9c5bc6Andy Hung            uid_t clientUid,
73d776ac63ce9c013c9626226e43f7db606e035838Glenn Kasten            bool isOut,
7483b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent            alloc_type alloc,
7520b9ef0b55c9150ae11057ab997ae61be2d496efEric Laurent            track_type type,
7620b9ef0b55c9150ae11057ab997ae61be2d496efEric Laurent            audio_port_handle_t portId)
7781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    :   RefBase(),
7881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        mThread(thread),
7981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        mClient(client),
8081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        mCblk(NULL),
818fe68036c2a670abb9eb0cc67ab9830c2c23de81Andy Hung        // mBuffer, mBufferSize
8281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        mState(IDLE),
8381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        mSampleRate(sampleRate),
8481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        mFormat(format),
8581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        mChannelMask(channelMask),
86e541269be94f3a1072932d51537905b120ef4733Andy Hung        mChannelCount(isOut ?
87e541269be94f3a1072932d51537905b120ef4733Andy Hung                audio_channel_count_from_out_mask(channelMask) :
88e541269be94f3a1072932d51537905b120ef4733Andy Hung                audio_channel_count_from_in_mask(channelMask)),
89fdb3c07db5d44535eb8c3ec46dc78ad8446c01ebPhil Burk        mFrameSize(audio_has_proportional_frames(format) ?
9081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                mChannelCount * audio_bytes_per_sample(format) : sizeof(int8_t)),
9181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        mFrameCount(frameCount),
92e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten        mSessionId(sessionId),
93e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten        mIsOut(isOut),
94bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent        mId(android_atomic_inc(&nextTrackId)),
9583b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent        mTerminated(false),
96aaa44478a373232d8416657035a9020f9c7aa7c3Eric Laurent        mType(type),
9720b9ef0b55c9150ae11057ab997ae61be2d496efEric Laurent        mThreadIoHandle(thread->id()),
986acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent        mPortId(portId),
996acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent        mIsInvalid(false)
10081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{
101dcb346b7dc5b88c3e85db8a70bbd6a2fee8192b9Marco Nelissen    const uid_t callingUid = IPCThreadState::self()->getCallingUid();
1021f12a8ad958344c50733b948628ffa06db9c5bc6Andy Hung    if (!isTrustedCallingUid(callingUid) || clientUid == AUDIO_UID_INVALID) {
1031f12a8ad958344c50733b948628ffa06db9c5bc6Andy Hung        ALOGW_IF(clientUid != AUDIO_UID_INVALID && clientUid != callingUid,
104dcb346b7dc5b88c3e85db8a70bbd6a2fee8192b9Marco Nelissen                "%s uid %d tried to pass itself off as %d", __FUNCTION__, callingUid, clientUid);
1051f12a8ad958344c50733b948628ffa06db9c5bc6Andy Hung        clientUid = callingUid;
106462fd2fa9eef642b0574aa7409de0bde3fec8d43Marco Nelissen    }
107462fd2fa9eef642b0574aa7409de0bde3fec8d43Marco Nelissen    // clientUid contains the uid of the app that is responsible for this track, so we can blame
108462fd2fa9eef642b0574aa7409de0bde3fec8d43Marco Nelissen    // battery usage on it.
109462fd2fa9eef642b0574aa7409de0bde3fec8d43Marco Nelissen    mUid = clientUid;
110462fd2fa9eef642b0574aa7409de0bde3fec8d43Marco Nelissen
11181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    // ALOGD("Creating track with %d buffers @ %d bytes", bufferCount, bufferSize);
1121883f69de5f2c4e71df58d5b71d7c39f9779b50cAndy Hung
1138fe68036c2a670abb9eb0cc67ab9830c2c23de81Andy Hung    size_t minBufferSize = buffer == NULL ? roundup(frameCount) : frameCount;
1141883f69de5f2c4e71df58d5b71d7c39f9779b50cAndy Hung    // check overflow when computing bufferSize due to multiplication by mFrameSize.
1158fe68036c2a670abb9eb0cc67ab9830c2c23de81Andy Hung    if (minBufferSize < frameCount  // roundup rounds down for values above UINT_MAX / 2
1161883f69de5f2c4e71df58d5b71d7c39f9779b50cAndy Hung            || mFrameSize == 0   // format needs to be correct
1178fe68036c2a670abb9eb0cc67ab9830c2c23de81Andy Hung            || minBufferSize > SIZE_MAX / mFrameSize) {
1181883f69de5f2c4e71df58d5b71d7c39f9779b50cAndy Hung        android_errorWriteLog(0x534e4554, "34749571");
1191883f69de5f2c4e71df58d5b71d7c39f9779b50cAndy Hung        return;
1201883f69de5f2c4e71df58d5b71d7c39f9779b50cAndy Hung    }
1218fe68036c2a670abb9eb0cc67ab9830c2c23de81Andy Hung    minBufferSize *= mFrameSize;
1228fe68036c2a670abb9eb0cc67ab9830c2c23de81Andy Hung
1238fe68036c2a670abb9eb0cc67ab9830c2c23de81Andy Hung    if (buffer == nullptr) {
1248fe68036c2a670abb9eb0cc67ab9830c2c23de81Andy Hung        bufferSize = minBufferSize; // allocated here.
1258fe68036c2a670abb9eb0cc67ab9830c2c23de81Andy Hung    } else if (minBufferSize > bufferSize) {
1268fe68036c2a670abb9eb0cc67ab9830c2c23de81Andy Hung        android_errorWriteLog(0x534e4554, "38340117");
1278fe68036c2a670abb9eb0cc67ab9830c2c23de81Andy Hung        return;
1288fe68036c2a670abb9eb0cc67ab9830c2c23de81Andy Hung    }
1291883f69de5f2c4e71df58d5b71d7c39f9779b50cAndy Hung
13081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    size_t size = sizeof(audio_track_cblk_t);
13183b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent    if (buffer == NULL && alloc == ALLOC_CBLK) {
1321883f69de5f2c4e71df58d5b71d7c39f9779b50cAndy Hung        // check overflow when computing allocation size for streaming tracks.
1331883f69de5f2c4e71df58d5b71d7c39f9779b50cAndy Hung        if (size > SIZE_MAX - bufferSize) {
1341883f69de5f2c4e71df58d5b71d7c39f9779b50cAndy Hung            android_errorWriteLog(0x534e4554, "34749571");
1351883f69de5f2c4e71df58d5b71d7c39f9779b50cAndy Hung            return;
1361883f69de5f2c4e71df58d5b71d7c39f9779b50cAndy Hung        }
13781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        size += bufferSize;
13881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    }
13981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
14081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    if (client != 0) {
14181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        mCblkMemory = client->heap()->allocate(size);
142663c2247b71086e30bfd3192979d1dd7f15c539eGlenn Kasten        if (mCblkMemory == 0 ||
143663c2247b71086e30bfd3192979d1dd7f15c539eGlenn Kasten                (mCblk = static_cast<audio_track_cblk_t *>(mCblkMemory->pointer())) == NULL) {
144c42e9b462661673dff480ee71757a58b0f806370Glenn Kasten            ALOGE("not enough memory for AudioTrack size=%zu", size);
14581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            client->heap()->dump("AudioTrack");
146663c2247b71086e30bfd3192979d1dd7f15c539eGlenn Kasten            mCblkMemory.clear();
14781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            return;
14881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        }
14981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    } else {
150afb31487f3156a7284d2f0d06646c7bc00d99537Andy Hung        mCblk = (audio_track_cblk_t *) malloc(size);
151afb31487f3156a7284d2f0d06646c7bc00d99537Andy Hung        if (mCblk == NULL) {
152afb31487f3156a7284d2f0d06646c7bc00d99537Andy Hung            ALOGE("not enough memory for AudioTrack size=%zu", size);
153afb31487f3156a7284d2f0d06646c7bc00d99537Andy Hung            return;
154afb31487f3156a7284d2f0d06646c7bc00d99537Andy Hung        }
15581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    }
15681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
15781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    // construct the shared structure in-place.
15881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    if (mCblk != NULL) {
15981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        new(mCblk) audio_track_cblk_t();
160c263ca0ad8b6bdf5b0693996bc5f2f5916e0cd49Glenn Kasten        switch (alloc) {
161c263ca0ad8b6bdf5b0693996bc5f2f5916e0cd49Glenn Kasten        case ALLOC_READONLY: {
162d776ac63ce9c013c9626226e43f7db606e035838Glenn Kasten            const sp<MemoryDealer> roHeap(thread->readOnlyHeap());
163d776ac63ce9c013c9626226e43f7db606e035838Glenn Kasten            if (roHeap == 0 ||
164d776ac63ce9c013c9626226e43f7db606e035838Glenn Kasten                    (mBufferMemory = roHeap->allocate(bufferSize)) == 0 ||
165d776ac63ce9c013c9626226e43f7db606e035838Glenn Kasten                    (mBuffer = mBufferMemory->pointer()) == NULL) {
166d776ac63ce9c013c9626226e43f7db606e035838Glenn Kasten                ALOGE("not enough memory for read-only buffer size=%zu", bufferSize);
167d776ac63ce9c013c9626226e43f7db606e035838Glenn Kasten                if (roHeap != 0) {
168d776ac63ce9c013c9626226e43f7db606e035838Glenn Kasten                    roHeap->dump("buffer");
169d776ac63ce9c013c9626226e43f7db606e035838Glenn Kasten                }
170d776ac63ce9c013c9626226e43f7db606e035838Glenn Kasten                mCblkMemory.clear();
171d776ac63ce9c013c9626226e43f7db606e035838Glenn Kasten                mBufferMemory.clear();
172d776ac63ce9c013c9626226e43f7db606e035838Glenn Kasten                return;
173d776ac63ce9c013c9626226e43f7db606e035838Glenn Kasten            }
17481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            memset(mBuffer, 0, bufferSize);
175c263ca0ad8b6bdf5b0693996bc5f2f5916e0cd49Glenn Kasten            } break;
176c263ca0ad8b6bdf5b0693996bc5f2f5916e0cd49Glenn Kasten        case ALLOC_PIPE:
177c263ca0ad8b6bdf5b0693996bc5f2f5916e0cd49Glenn Kasten            mBufferMemory = thread->pipeMemory();
178c263ca0ad8b6bdf5b0693996bc5f2f5916e0cd49Glenn Kasten            // mBuffer is the virtual address as seen from current process (mediaserver),
179c263ca0ad8b6bdf5b0693996bc5f2f5916e0cd49Glenn Kasten            // and should normally be coming from mBufferMemory->pointer().
180c263ca0ad8b6bdf5b0693996bc5f2f5916e0cd49Glenn Kasten            // However in this case the TrackBase does not reference the buffer directly.
181c263ca0ad8b6bdf5b0693996bc5f2f5916e0cd49Glenn Kasten            // It should references the buffer via the pipe.
182c263ca0ad8b6bdf5b0693996bc5f2f5916e0cd49Glenn Kasten            // Therefore, to detect incorrect usage of the buffer, we set mBuffer to NULL.
183c263ca0ad8b6bdf5b0693996bc5f2f5916e0cd49Glenn Kasten            mBuffer = NULL;
1848fe68036c2a670abb9eb0cc67ab9830c2c23de81Andy Hung            bufferSize = 0;
185c263ca0ad8b6bdf5b0693996bc5f2f5916e0cd49Glenn Kasten            break;
186c263ca0ad8b6bdf5b0693996bc5f2f5916e0cd49Glenn Kasten        case ALLOC_CBLK:
187d776ac63ce9c013c9626226e43f7db606e035838Glenn Kasten            // clear all buffers
18883b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent            if (buffer == NULL) {
189d776ac63ce9c013c9626226e43f7db606e035838Glenn Kasten                mBuffer = (char*)mCblk + sizeof(audio_track_cblk_t);
190d776ac63ce9c013c9626226e43f7db606e035838Glenn Kasten                memset(mBuffer, 0, bufferSize);
191d776ac63ce9c013c9626226e43f7db606e035838Glenn Kasten            } else {
19283b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent                mBuffer = buffer;
1939f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten#if 0
194d776ac63ce9c013c9626226e43f7db606e035838Glenn Kasten                mCblk->mFlags = CBLK_FORCEREADY;    // FIXME hack, need to fix the track ready logic
1959f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten#endif
196d776ac63ce9c013c9626226e43f7db606e035838Glenn Kasten            }
197c263ca0ad8b6bdf5b0693996bc5f2f5916e0cd49Glenn Kasten            break;
19883b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent        case ALLOC_LOCAL:
19983b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent            mBuffer = calloc(1, bufferSize);
20083b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent            break;
20183b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent        case ALLOC_NONE:
20283b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent            mBuffer = buffer;
20383b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent            break;
2048fe68036c2a670abb9eb0cc67ab9830c2c23de81Andy Hung        default:
2058fe68036c2a670abb9eb0cc67ab9830c2c23de81Andy Hung            LOG_ALWAYS_FATAL("invalid allocation type: %d", (int)alloc);
20681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        }
2078fe68036c2a670abb9eb0cc67ab9830c2c23de81Andy Hung        mBufferSize = bufferSize;
208da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten
20946909e7eb074ce1b95b8a411eb71154f53f84f77Glenn Kasten#ifdef TEE_SINK
210da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten        if (mTeeSinkTrackEnabled) {
211329f6511ee4e03a4605c70bbda8d3a96d2544884Glenn Kasten            NBAIO_Format pipeFormat = Format_from_SR_C(mSampleRate, mChannelCount, mFormat);
2126e0d67d7b496ce17c0970a4ffd3a6f808860949cGlenn Kasten            if (Format_isValid(pipeFormat)) {
21346909e7eb074ce1b95b8a411eb71154f53f84f77Glenn Kasten                Pipe *pipe = new Pipe(mTeeSinkTrackFrames, pipeFormat);
21446909e7eb074ce1b95b8a411eb71154f53f84f77Glenn Kasten                size_t numCounterOffers = 0;
21546909e7eb074ce1b95b8a411eb71154f53f84f77Glenn Kasten                const NBAIO_Format offers[1] = {pipeFormat};
21646909e7eb074ce1b95b8a411eb71154f53f84f77Glenn Kasten                ssize_t index = pipe->negotiate(offers, 1, NULL, numCounterOffers);
21746909e7eb074ce1b95b8a411eb71154f53f84f77Glenn Kasten                ALOG_ASSERT(index == 0);
21846909e7eb074ce1b95b8a411eb71154f53f84f77Glenn Kasten                PipeReader *pipeReader = new PipeReader(*pipe);
21946909e7eb074ce1b95b8a411eb71154f53f84f77Glenn Kasten                numCounterOffers = 0;
22046909e7eb074ce1b95b8a411eb71154f53f84f77Glenn Kasten                index = pipeReader->negotiate(offers, 1, NULL, numCounterOffers);
22146909e7eb074ce1b95b8a411eb71154f53f84f77Glenn Kasten                ALOG_ASSERT(index == 0);
22246909e7eb074ce1b95b8a411eb71154f53f84f77Glenn Kasten                mTeeSink = pipe;
22346909e7eb074ce1b95b8a411eb71154f53f84f77Glenn Kasten                mTeeSource = pipeReader;
22446909e7eb074ce1b95b8a411eb71154f53f84f77Glenn Kasten            }
225da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten        }
22646909e7eb074ce1b95b8a411eb71154f53f84f77Glenn Kasten#endif
227da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten
22881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    }
22981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
23081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
23183b8808faad1e91690c64d7007348be8d9ebde73Eric Laurentstatus_t AudioFlinger::ThreadBase::TrackBase::initCheck() const
23283b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent{
23383b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent    status_t status;
23483b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent    if (mType == TYPE_OUTPUT || mType == TYPE_PATCH) {
23583b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent        status = cblk() != NULL ? NO_ERROR : NO_MEMORY;
23683b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent    } else {
23783b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent        status = getCblk() != 0 ? NO_ERROR : NO_MEMORY;
23883b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent    }
23983b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent    return status;
24083b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent}
24183b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent
24281784c37c61b09289654b979567a42bf73cd2b12Eric LaurentAudioFlinger::ThreadBase::TrackBase::~TrackBase()
24381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{
24446909e7eb074ce1b95b8a411eb71154f53f84f77Glenn Kasten#ifdef TEE_SINK
2455b2191a4a36746b66ba3e8f73b711f49fdb83b4bGlenn Kasten    dumpTee(-1, mTeeSource, mId, 'T');
24646909e7eb074ce1b95b8a411eb71154f53f84f77Glenn Kasten#endif
247e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten    // delete the proxy before deleting the shared memory it refers to, to avoid dangling reference
2485bba2f6916dbe00aea7c0521faa0c6ed42114a75Eric Laurent    mServerProxy.clear();
24981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    if (mCblk != NULL) {
250afb31487f3156a7284d2f0d06646c7bc00d99537Andy Hung        mCblk->~audio_track_cblk_t();   // destroy our shared-structure.
25181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        if (mClient == 0) {
252afb31487f3156a7284d2f0d06646c7bc00d99537Andy Hung            free(mCblk);
25381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        }
25481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    }
25581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    mCblkMemory.clear();    // free the shared memory before releasing the heap it belongs to
25681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    if (mClient != 0) {
257021cf9634ab09c0753a40b7c9ef4ba603be5c3daEric Laurent        // Client destructor must run with AudioFlinger client mutex locked
258021cf9634ab09c0753a40b7c9ef4ba603be5c3daEric Laurent        Mutex::Autolock _l(mClient->audioFlinger()->mClientLock);
25981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        // If the client's reference count drops to zero, the associated destructor
26081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        // must run with AudioFlinger lock held. Thus the explicit clear() rather than
26181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        // relying on the automatic clear() at end of scope.
26281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        mClient.clear();
26381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    }
2643bcffa136909c1fb6e88ee4efd12ccac18360a85Eric Laurent    // flush the binder command buffer
2653bcffa136909c1fb6e88ee4efd12ccac18360a85Eric Laurent    IPCThreadState::self()->flushCommands();
26681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
26781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
26881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// AudioBufferProvider interface
26981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// getNextBuffer() = 0;
270d79072e9dff59f767cce2cda1caab80ce5a0815bGlenn Kasten// This implementation of releaseBuffer() is used by Track and RecordTrack
27181784c37c61b09289654b979567a42bf73cd2b12Eric Laurentvoid AudioFlinger::ThreadBase::TrackBase::releaseBuffer(AudioBufferProvider::Buffer* buffer)
27281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{
27346909e7eb074ce1b95b8a411eb71154f53f84f77Glenn Kasten#ifdef TEE_SINK
274da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten    if (mTeeSink != 0) {
275da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten        (void) mTeeSink->write(buffer->raw, buffer->frameCount);
276da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten    }
27746909e7eb074ce1b95b8a411eb71154f53f84f77Glenn Kasten#endif
278da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten
2799f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    ServerProxy::Buffer buf;
2809f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    buf.mFrameCount = buffer->frameCount;
2819f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    buf.mRaw = buffer->raw;
28281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    buffer->frameCount = 0;
2839f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    buffer->raw = NULL;
2849f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    mServerProxy->releaseBuffer(&buf);
28581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
28681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
28781784c37c61b09289654b979567a42bf73cd2b12Eric Laurentstatus_t AudioFlinger::ThreadBase::TrackBase::setSyncEvent(const sp<SyncEvent>& event)
28881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{
28981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    mSyncEvents.add(event);
29081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    return NO_ERROR;
29181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
29281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
29381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// ----------------------------------------------------------------------------
29481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent//      Playback
29581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// ----------------------------------------------------------------------------
29681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
29781784c37c61b09289654b979567a42bf73cd2b12Eric LaurentAudioFlinger::TrackHandle::TrackHandle(const sp<AudioFlinger::PlaybackThread::Track>& track)
29881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    : BnAudioTrack(),
29981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent      mTrack(track)
30081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{
30181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
30281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
30381784c37c61b09289654b979567a42bf73cd2b12Eric LaurentAudioFlinger::TrackHandle::~TrackHandle() {
30481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    // just stop the track on deletion, associated resources
30581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    // will be freed from the main thread once all pending buffers have
30681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    // been played. Unless it's not in the active track list, in which
30781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    // case we free everything now...
30881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    mTrack->destroy();
30981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
31081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
31181784c37c61b09289654b979567a42bf73cd2b12Eric Laurentsp<IMemory> AudioFlinger::TrackHandle::getCblk() const {
31281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    return mTrack->getCblk();
31381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
31481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
31581784c37c61b09289654b979567a42bf73cd2b12Eric Laurentstatus_t AudioFlinger::TrackHandle::start() {
31681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    return mTrack->start();
31781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
31881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
31981784c37c61b09289654b979567a42bf73cd2b12Eric Laurentvoid AudioFlinger::TrackHandle::stop() {
32081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    mTrack->stop();
32181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
32281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
32381784c37c61b09289654b979567a42bf73cd2b12Eric Laurentvoid AudioFlinger::TrackHandle::flush() {
32481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    mTrack->flush();
32581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
32681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
32781784c37c61b09289654b979567a42bf73cd2b12Eric Laurentvoid AudioFlinger::TrackHandle::pause() {
32881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    mTrack->pause();
32981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
33081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
33181784c37c61b09289654b979567a42bf73cd2b12Eric Laurentstatus_t AudioFlinger::TrackHandle::attachAuxEffect(int EffectId)
33281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{
33381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    return mTrack->attachAuxEffect(EffectId);
33481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
33581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
3363dcd00dddec86a1c5133083ad7ba2265d49c048cGlenn Kastenstatus_t AudioFlinger::TrackHandle::setParameters(const String8& keyValuePairs) {
3373dcd00dddec86a1c5133083ad7ba2265d49c048cGlenn Kasten    return mTrack->setParameters(keyValuePairs);
3383dcd00dddec86a1c5133083ad7ba2265d49c048cGlenn Kasten}
3393dcd00dddec86a1c5133083ad7ba2265d49c048cGlenn Kasten
3409fc8b5cd4a64ef07e84c69112461324d5c13a0b0Andy HungVolumeShaper::Status AudioFlinger::TrackHandle::applyVolumeShaper(
3419fc8b5cd4a64ef07e84c69112461324d5c13a0b0Andy Hung        const sp<VolumeShaper::Configuration>& configuration,
3429fc8b5cd4a64ef07e84c69112461324d5c13a0b0Andy Hung        const sp<VolumeShaper::Operation>& operation) {
3439fc8b5cd4a64ef07e84c69112461324d5c13a0b0Andy Hung    return mTrack->applyVolumeShaper(configuration, operation);
3449fc8b5cd4a64ef07e84c69112461324d5c13a0b0Andy Hung}
3459fc8b5cd4a64ef07e84c69112461324d5c13a0b0Andy Hung
3469fc8b5cd4a64ef07e84c69112461324d5c13a0b0Andy Hungsp<VolumeShaper::State> AudioFlinger::TrackHandle::getVolumeShaperState(int id) {
3479fc8b5cd4a64ef07e84c69112461324d5c13a0b0Andy Hung    return mTrack->getVolumeShaperState(id);
3489fc8b5cd4a64ef07e84c69112461324d5c13a0b0Andy Hung}
3499fc8b5cd4a64ef07e84c69112461324d5c13a0b0Andy Hung
35053cec22821072719ee02c856e9ac2dda2496c570Glenn Kastenstatus_t AudioFlinger::TrackHandle::getTimestamp(AudioTimestamp& timestamp)
35153cec22821072719ee02c856e9ac2dda2496c570Glenn Kasten{
352573d80a8f463f648a515fc0975bf83951b272993Glenn Kasten    return mTrack->getTimestamp(timestamp);
35353cec22821072719ee02c856e9ac2dda2496c570Glenn Kasten}
35453cec22821072719ee02c856e9ac2dda2496c570Glenn Kasten
35559fe010bcc072597852454a2ec53d7b0a2002a3bEric Laurent
35659fe010bcc072597852454a2ec53d7b0a2002a3bEric Laurentvoid AudioFlinger::TrackHandle::signal()
35759fe010bcc072597852454a2ec53d7b0a2002a3bEric Laurent{
35859fe010bcc072597852454a2ec53d7b0a2002a3bEric Laurent    return mTrack->signal();
35959fe010bcc072597852454a2ec53d7b0a2002a3bEric Laurent}
36059fe010bcc072597852454a2ec53d7b0a2002a3bEric Laurent
36181784c37c61b09289654b979567a42bf73cd2b12Eric Laurentstatus_t AudioFlinger::TrackHandle::onTransact(
36281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
36381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{
36481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    return BnAudioTrack::onTransact(code, data, reply, flags);
36581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
36681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
36781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// ----------------------------------------------------------------------------
36881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
36981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// Track constructor must be called with AudioFlinger::mLock and ThreadBase::mLock held
37081784c37c61b09289654b979567a42bf73cd2b12Eric LaurentAudioFlinger::PlaybackThread::Track::Track(
37181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            PlaybackThread *thread,
37281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            const sp<Client>& client,
37381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            audio_stream_type_t streamType,
37481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            uint32_t sampleRate,
37581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            audio_format_t format,
37681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            audio_channel_mask_t channelMask,
37781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            size_t frameCount,
37883b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent            void *buffer,
3798fe68036c2a670abb9eb0cc67ab9830c2c23de81Andy Hung            size_t bufferSize,
38081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            const sp<IMemory>& sharedBuffer,
381d848eb48c121c119e8ba7583efc75415fe102570Glenn Kasten            audio_session_t sessionId,
3821f12a8ad958344c50733b948628ffa06db9c5bc6Andy Hung            uid_t uid,
383050677873c10d4da308ac222f8533c96cca3207eEric Laurent            audio_output_flags_t flags,
38420b9ef0b55c9150ae11057ab997ae61be2d496efEric Laurent            track_type type,
38520b9ef0b55c9150ae11057ab997ae61be2d496efEric Laurent            audio_port_handle_t portId)
38683b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent    :   TrackBase(thread, client, sampleRate, format, channelMask, frameCount,
38783b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent                  (sharedBuffer != 0) ? sharedBuffer->pointer() : buffer,
3888fe68036c2a670abb9eb0cc67ab9830c2c23de81Andy Hung                  (sharedBuffer != 0) ? sharedBuffer->size() : bufferSize,
389050677873c10d4da308ac222f8533c96cca3207eEric Laurent                  sessionId, uid, true /*isOut*/,
39083b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent                  (type == TYPE_PATCH) ? ( buffer == NULL ? ALLOC_LOCAL : ALLOC_NONE) : ALLOC_CBLK,
39120b9ef0b55c9150ae11057ab997ae61be2d496efEric Laurent                  type, portId),
39281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    mFillingUpStatus(FS_INVALID),
39381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    // mRetryCount initialized later when needed
39481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    mSharedBuffer(sharedBuffer),
39581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    mStreamType(streamType),
39681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    mName(-1),  // see note below
39781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    mMainBuffer(thread->mixBuffer()),
39881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    mAuxBuffer(NULL),
39981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    mAuxEffectId(0), mHasVolumeController(false),
40081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    mPresentationCompleteFrames(0),
401e10393e72454bfd8298017dc193faf424f4e9a8fAndy Hung    mFrameMap(16 /* sink-frame-to-track-frame map memory */),
4029fc8b5cd4a64ef07e84c69112461324d5c13a0b0Andy Hung    mVolumeHandler(new VolumeHandler(sampleRate)),
403e10393e72454bfd8298017dc193faf424f4e9a8fAndy Hung    // mSinkTimestamp
40481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    mFastIndex(-1),
4055736c35b841de56ce394b4879389f669b61425e6Glenn Kasten    mCachedVolume(1.0),
4067844f679be8d94c5cdf017f53754cb68ee2f00daHaynes Mathew George    mResumeToStopping(false),
407050677873c10d4da308ac222f8533c96cca3207eEric Laurent    mFlushHwPending(false),
408050677873c10d4da308ac222f8533c96cca3207eEric Laurent    mFlags(flags)
40981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{
41083b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent    // client == 0 implies sharedBuffer == 0
41183b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent    ALOG_ASSERT(!(client == 0 && sharedBuffer != 0));
41283b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent
413e93cc03da360a1a0d2ad937c745ce8c8e8be81c2Eric Laurent    ALOGV_IF(sharedBuffer != 0, "sharedBuffer: %p, size: %zu", sharedBuffer->pointer(),
41483b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent            sharedBuffer->size());
41583b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent
4163ef14ef30359376006a233f6a21a165d4b65a7dfGlenn Kasten    if (mCblk == NULL) {
4173ef14ef30359376006a233f6a21a165d4b65a7dfGlenn Kasten        return;
4183ef14ef30359376006a233f6a21a165d4b65a7dfGlenn Kasten    }
4193ef14ef30359376006a233f6a21a165d4b65a7dfGlenn Kasten
4203ef14ef30359376006a233f6a21a165d4b65a7dfGlenn Kasten    if (sharedBuffer == 0) {
4213ef14ef30359376006a233f6a21a165d4b65a7dfGlenn Kasten        mAudioTrackServerProxy = new AudioTrackServerProxy(mCblk, mBuffer, frameCount,
42283b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent                mFrameSize, !isExternalTrack(), sampleRate);
4233ef14ef30359376006a233f6a21a165d4b65a7dfGlenn Kasten    } else {
4243ef14ef30359376006a233f6a21a165d4b65a7dfGlenn Kasten        mAudioTrackServerProxy = new StaticAudioTrackServerProxy(mCblk, mBuffer, frameCount,
4253ef14ef30359376006a233f6a21a165d4b65a7dfGlenn Kasten                mFrameSize);
4263ef14ef30359376006a233f6a21a165d4b65a7dfGlenn Kasten    }
4273ef14ef30359376006a233f6a21a165d4b65a7dfGlenn Kasten    mServerProxy = mAudioTrackServerProxy;
4283ef14ef30359376006a233f6a21a165d4b65a7dfGlenn Kasten
429ad7dd9610b6fafa81baf69607f4ac669da88182aEric Laurent    mName = thread->getTrackName_l(channelMask, format, sessionId, uid);
4303ef14ef30359376006a233f6a21a165d4b65a7dfGlenn Kasten    if (mName < 0) {
4313ef14ef30359376006a233f6a21a165d4b65a7dfGlenn Kasten        ALOGE("no more track names available");
4323ef14ef30359376006a233f6a21a165d4b65a7dfGlenn Kasten        return;
4333ef14ef30359376006a233f6a21a165d4b65a7dfGlenn Kasten    }
4343ef14ef30359376006a233f6a21a165d4b65a7dfGlenn Kasten    // only allocate a fast track index if we were able to allocate a normal track name
435050677873c10d4da308ac222f8533c96cca3207eEric Laurent    if (flags & AUDIO_OUTPUT_FLAG_FAST) {
436a542782d0045588e55e075a763cedcd2d504ad22Andy Hung        // FIXME: Not calling framesReadyIsCalledByMultipleThreads() exposes a potential
437a542782d0045588e55e075a763cedcd2d504ad22Andy Hung        // race with setSyncEvent(). However, if we call it, we cannot properly start
438a542782d0045588e55e075a763cedcd2d504ad22Andy Hung        // static fast tracks (SoundPool) immediately after stopping.
439a542782d0045588e55e075a763cedcd2d504ad22Andy Hung        //mAudioTrackServerProxy->framesReadyIsCalledByMultipleThreads();
4403ef14ef30359376006a233f6a21a165d4b65a7dfGlenn Kasten        ALOG_ASSERT(thread->mFastTrackAvailMask != 0);
4413ef14ef30359376006a233f6a21a165d4b65a7dfGlenn Kasten        int i = __builtin_ctz(thread->mFastTrackAvailMask);
442dc2c50bad491d2c0c8a2efc0e24491076701c63cGlenn Kasten        ALOG_ASSERT(0 < i && i < (int)FastMixerState::sMaxFastTracks);
4433ef14ef30359376006a233f6a21a165d4b65a7dfGlenn Kasten        // FIXME This is too eager.  We allocate a fast track index before the
4443ef14ef30359376006a233f6a21a165d4b65a7dfGlenn Kasten        //       fast track becomes active.  Since fast tracks are a scarce resource,
4453ef14ef30359376006a233f6a21a165d4b65a7dfGlenn Kasten        //       this means we are potentially denying other more important fast tracks from
4463ef14ef30359376006a233f6a21a165d4b65a7dfGlenn Kasten        //       being created.  It would be better to allocate the index dynamically.
4473ef14ef30359376006a233f6a21a165d4b65a7dfGlenn Kasten        mFastIndex = i;
4483ef14ef30359376006a233f6a21a165d4b65a7dfGlenn Kasten        thread->mFastTrackAvailMask &= ~(1 << i);
44981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    }
45081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
45181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
45281784c37c61b09289654b979567a42bf73cd2b12Eric LaurentAudioFlinger::PlaybackThread::Track::~Track()
45381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{
45481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    ALOGV("PlaybackThread::Track destructor");
4550c72b24f91c68442eb374bd1b338c394105b8262Glenn Kasten
4560c72b24f91c68442eb374bd1b338c394105b8262Glenn Kasten    // The destructor would clear mSharedBuffer,
4570c72b24f91c68442eb374bd1b338c394105b8262Glenn Kasten    // but it will not push the decremented reference count,
4580c72b24f91c68442eb374bd1b338c394105b8262Glenn Kasten    // leaving the client's IMemory dangling indefinitely.
4590c72b24f91c68442eb374bd1b338c394105b8262Glenn Kasten    // This prevents that leak.
4600c72b24f91c68442eb374bd1b338c394105b8262Glenn Kasten    if (mSharedBuffer != 0) {
4610c72b24f91c68442eb374bd1b338c394105b8262Glenn Kasten        mSharedBuffer.clear();
4620c72b24f91c68442eb374bd1b338c394105b8262Glenn Kasten    }
46381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
46481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
465030033342a6ea17003e6af38a56c7edc6d2ead01Glenn Kastenstatus_t AudioFlinger::PlaybackThread::Track::initCheck() const
466030033342a6ea17003e6af38a56c7edc6d2ead01Glenn Kasten{
467030033342a6ea17003e6af38a56c7edc6d2ead01Glenn Kasten    status_t status = TrackBase::initCheck();
468030033342a6ea17003e6af38a56c7edc6d2ead01Glenn Kasten    if (status == NO_ERROR && mName < 0) {
469030033342a6ea17003e6af38a56c7edc6d2ead01Glenn Kasten        status = NO_MEMORY;
470030033342a6ea17003e6af38a56c7edc6d2ead01Glenn Kasten    }
471030033342a6ea17003e6af38a56c7edc6d2ead01Glenn Kasten    return status;
472030033342a6ea17003e6af38a56c7edc6d2ead01Glenn Kasten}
473030033342a6ea17003e6af38a56c7edc6d2ead01Glenn Kasten
47481784c37c61b09289654b979567a42bf73cd2b12Eric Laurentvoid AudioFlinger::PlaybackThread::Track::destroy()
47581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{
47681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    // NOTE: destroyTrack_l() can remove a strong reference to this Track
47781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    // by removing it from mTracks vector, so there is a risk that this Tracks's
47881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    // destructor is called. As the destructor needs to lock mLock,
47981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    // we must acquire a strong reference on this Track before locking mLock
48081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    // here so that the destructor is called only when exiting this function.
48181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    // On the other hand, as long as Track::destroy() is only called by
48281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    // TrackHandle destructor, the TrackHandle still holds a strong ref on
48381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    // this Track with its member mTrack.
48481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    sp<Track> keep(this);
48581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    { // scope for mLock
486aaa44478a373232d8416657035a9020f9c7aa7c3Eric Laurent        bool wasActive = false;
48781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        sp<ThreadBase> thread = mThread.promote();
48881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        if (thread != 0) {
48981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            Mutex::Autolock _l(thread->mLock);
49081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            PlaybackThread *playbackThread = (PlaybackThread *)thread.get();
491aaa44478a373232d8416657035a9020f9c7aa7c3Eric Laurent            wasActive = playbackThread->destroyTrack_l(this);
492aaa44478a373232d8416657035a9020f9c7aa7c3Eric Laurent        }
493aaa44478a373232d8416657035a9020f9c7aa7c3Eric Laurent        if (isExternalTrack() && !wasActive) {
494d848eb48c121c119e8ba7583efc75415fe102570Glenn Kasten            AudioSystem::releaseOutput(mThreadIoHandle, mStreamType, mSessionId);
49581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        }
49681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    }
49781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
49881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
49981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent/*static*/ void AudioFlinger::PlaybackThread::Track::appendDumpHeader(String8& result)
50081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{
5012c6c3bb76b2fa18ed3536331a1700250bd04c7ceAndy Hung    result.append("T Name Active Client Session S  Flags "
5022c6c3bb76b2fa18ed3536331a1700250bd04c7ceAndy Hung                  "  Format Chn mask  SRate "
5032c6c3bb76b2fa18ed3536331a1700250bd04c7ceAndy Hung                  "ST  L dB  R dB  VS dB "
5042c6c3bb76b2fa18ed3536331a1700250bd04c7ceAndy Hung                  "  Server FrmCnt  FrmRdy F Underruns  Flushed "
5052c6c3bb76b2fa18ed3536331a1700250bd04c7ceAndy Hung                  "Main Buf  Aux Buf\n");
50681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
50781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
5082c6c3bb76b2fa18ed3536331a1700250bd04c7ceAndy Hungvoid AudioFlinger::PlaybackThread::Track::appendDump(String8& result, bool active)
50981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{
5102c6c3bb76b2fa18ed3536331a1700250bd04c7ceAndy Hung    char trackType;
5112c6c3bb76b2fa18ed3536331a1700250bd04c7ceAndy Hung    switch (mType) {
5122c6c3bb76b2fa18ed3536331a1700250bd04c7ceAndy Hung    case TYPE_DEFAULT:
5132c6c3bb76b2fa18ed3536331a1700250bd04c7ceAndy Hung    case TYPE_OUTPUT:
5142c6c3bb76b2fa18ed3536331a1700250bd04c7ceAndy Hung        if (mSharedBuffer.get() != nullptr) {
5152c6c3bb76b2fa18ed3536331a1700250bd04c7ceAndy Hung            trackType = 'S'; // static
5162c6c3bb76b2fa18ed3536331a1700250bd04c7ceAndy Hung        } else {
5172c6c3bb76b2fa18ed3536331a1700250bd04c7ceAndy Hung            trackType = ' '; // normal
5182c6c3bb76b2fa18ed3536331a1700250bd04c7ceAndy Hung        }
5192c6c3bb76b2fa18ed3536331a1700250bd04c7ceAndy Hung        break;
5202c6c3bb76b2fa18ed3536331a1700250bd04c7ceAndy Hung    case TYPE_PATCH:
5212c6c3bb76b2fa18ed3536331a1700250bd04c7ceAndy Hung        trackType = 'P';
5222c6c3bb76b2fa18ed3536331a1700250bd04c7ceAndy Hung        break;
5232c6c3bb76b2fa18ed3536331a1700250bd04c7ceAndy Hung    default:
5242c6c3bb76b2fa18ed3536331a1700250bd04c7ceAndy Hung        trackType = '?';
5252c6c3bb76b2fa18ed3536331a1700250bd04c7ceAndy Hung    }
5262c6c3bb76b2fa18ed3536331a1700250bd04c7ceAndy Hung
52781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    if (isFastTrack()) {
5282c6c3bb76b2fa18ed3536331a1700250bd04c7ceAndy Hung        result.appendFormat("F%c %3d", trackType, mFastIndex);
529b220884bf3129253cc5bc8d030bc475411ea4911Marco Nelissen    } else if (mName >= AudioMixer::TRACK0) {
5302c6c3bb76b2fa18ed3536331a1700250bd04c7ceAndy Hung        result.appendFormat("%c %4d", trackType, mName - AudioMixer::TRACK0);
531bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent    } else {
5322c6c3bb76b2fa18ed3536331a1700250bd04c7ceAndy Hung        result.appendFormat("%c none", trackType);
53381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    }
5342c6c3bb76b2fa18ed3536331a1700250bd04c7ceAndy Hung
53581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    char nowInUnderrun;
53681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    switch (mObservedUnderruns.mBitFields.mMostRecent) {
53781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    case UNDERRUN_FULL:
53881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        nowInUnderrun = ' ';
53981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        break;
54081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    case UNDERRUN_PARTIAL:
54181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        nowInUnderrun = '<';
54281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        break;
54381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    case UNDERRUN_EMPTY:
54481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        nowInUnderrun = '*';
54581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        break;
54681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    default:
54781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        nowInUnderrun = '?';
54881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        break;
54981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    }
550da540db0fc21bc9319d9602aefe1a109d00a7e6cAndy Hung
5512c6c3bb76b2fa18ed3536331a1700250bd04c7ceAndy Hung    char fillingStatus;
5522c6c3bb76b2fa18ed3536331a1700250bd04c7ceAndy Hung    switch (mFillingUpStatus) {
5532c6c3bb76b2fa18ed3536331a1700250bd04c7ceAndy Hung    case FS_INVALID:
5542c6c3bb76b2fa18ed3536331a1700250bd04c7ceAndy Hung        fillingStatus = 'I';
5552c6c3bb76b2fa18ed3536331a1700250bd04c7ceAndy Hung        break;
5562c6c3bb76b2fa18ed3536331a1700250bd04c7ceAndy Hung    case FS_FILLING:
5572c6c3bb76b2fa18ed3536331a1700250bd04c7ceAndy Hung        fillingStatus = 'f';
5582c6c3bb76b2fa18ed3536331a1700250bd04c7ceAndy Hung        break;
5592c6c3bb76b2fa18ed3536331a1700250bd04c7ceAndy Hung    case FS_FILLED:
5602c6c3bb76b2fa18ed3536331a1700250bd04c7ceAndy Hung        fillingStatus = 'F';
5612c6c3bb76b2fa18ed3536331a1700250bd04c7ceAndy Hung        break;
5622c6c3bb76b2fa18ed3536331a1700250bd04c7ceAndy Hung    case FS_ACTIVE:
5632c6c3bb76b2fa18ed3536331a1700250bd04c7ceAndy Hung        fillingStatus = 'A';
5642c6c3bb76b2fa18ed3536331a1700250bd04c7ceAndy Hung        break;
5652c6c3bb76b2fa18ed3536331a1700250bd04c7ceAndy Hung    default:
5662c6c3bb76b2fa18ed3536331a1700250bd04c7ceAndy Hung        fillingStatus = '?';
5672c6c3bb76b2fa18ed3536331a1700250bd04c7ceAndy Hung        break;
5682c6c3bb76b2fa18ed3536331a1700250bd04c7ceAndy Hung    }
5692c6c3bb76b2fa18ed3536331a1700250bd04c7ceAndy Hung
5702c6c3bb76b2fa18ed3536331a1700250bd04c7ceAndy Hung    // clip framesReadySafe to max representation in dump
5712c6c3bb76b2fa18ed3536331a1700250bd04c7ceAndy Hung    const size_t framesReadySafe =
5722c6c3bb76b2fa18ed3536331a1700250bd04c7ceAndy Hung            std::min(mAudioTrackServerProxy->framesReadySafe(), (size_t)99999999);
5732c6c3bb76b2fa18ed3536331a1700250bd04c7ceAndy Hung
5742c6c3bb76b2fa18ed3536331a1700250bd04c7ceAndy Hung    // obtain volumes
5752c6c3bb76b2fa18ed3536331a1700250bd04c7ceAndy Hung    const gain_minifloat_packed_t vlr = mAudioTrackServerProxy->getVolumeLR();
5762c6c3bb76b2fa18ed3536331a1700250bd04c7ceAndy Hung    const std::pair<float /* volume */, bool /* active */> vsVolume =
5772c6c3bb76b2fa18ed3536331a1700250bd04c7ceAndy Hung            mVolumeHandler->getLastVolume();
5782c6c3bb76b2fa18ed3536331a1700250bd04c7ceAndy Hung
5792c6c3bb76b2fa18ed3536331a1700250bd04c7ceAndy Hung    // Our effective frame count is obtained by ServerProxy::getBufferSizeInFrames()
5802c6c3bb76b2fa18ed3536331a1700250bd04c7ceAndy Hung    // as it may be reduced by the application.
5812c6c3bb76b2fa18ed3536331a1700250bd04c7ceAndy Hung    const size_t bufferSizeInFrames = (size_t)mAudioTrackServerProxy->getBufferSizeInFrames();
5822c6c3bb76b2fa18ed3536331a1700250bd04c7ceAndy Hung    // Check whether the buffer size has been modified by the app.
5832c6c3bb76b2fa18ed3536331a1700250bd04c7ceAndy Hung    const char modifiedBufferChar = bufferSizeInFrames < mFrameCount
5842c6c3bb76b2fa18ed3536331a1700250bd04c7ceAndy Hung            ? 'r' /* buffer reduced */: bufferSizeInFrames > mFrameCount
5852c6c3bb76b2fa18ed3536331a1700250bd04c7ceAndy Hung                    ? 'e' /* error */ : ' ' /* identical */;
5862c6c3bb76b2fa18ed3536331a1700250bd04c7ceAndy Hung
5872c6c3bb76b2fa18ed3536331a1700250bd04c7ceAndy Hung    result.appendFormat("%7s %6u %7u %2s 0x%03X "
5882c6c3bb76b2fa18ed3536331a1700250bd04c7ceAndy Hung                           "%08X %08X %6u "
5892c6c3bb76b2fa18ed3536331a1700250bd04c7ceAndy Hung                           "%2u %5.2g %5.2g %5.2g%c "
5902c6c3bb76b2fa18ed3536331a1700250bd04c7ceAndy Hung                           "%08X %6zu%c %6zu %c %9u%c %7u "
5912c6c3bb76b2fa18ed3536331a1700250bd04c7ceAndy Hung                           "%08zX %08zX\n",
592b220884bf3129253cc5bc8d030bc475411ea4911Marco Nelissen            active ? "yes" : "no",
59381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            (mClient == 0) ? getpid_cached : mClient->pid(),
5942c6c3bb76b2fa18ed3536331a1700250bd04c7ceAndy Hung            mSessionId,
5952c6c3bb76b2fa18ed3536331a1700250bd04c7ceAndy Hung            getTrackStateString(),
5962c6c3bb76b2fa18ed3536331a1700250bd04c7ceAndy Hung            mCblk->mFlags,
5972c6c3bb76b2fa18ed3536331a1700250bd04c7ceAndy Hung
59881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            mFormat,
59981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            mChannelMask,
6009f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten            mAudioTrackServerProxy->getSampleRate(),
6012c6c3bb76b2fa18ed3536331a1700250bd04c7ceAndy Hung
6022c6c3bb76b2fa18ed3536331a1700250bd04c7ceAndy Hung            mStreamType,
603c56f3426099a3cf2d07ccff8886050c7fbce140fGlenn Kasten            20.0 * log10(float_from_gain(gain_minifloat_unpack_left(vlr))),
604c56f3426099a3cf2d07ccff8886050c7fbce140fGlenn Kasten            20.0 * log10(float_from_gain(gain_minifloat_unpack_right(vlr))),
605da540db0fc21bc9319d9602aefe1a109d00a7e6cAndy Hung            20.0 * log10(vsVolume.first), // VolumeShaper(s) total volume
606da540db0fc21bc9319d9602aefe1a109d00a7e6cAndy Hung            vsVolume.second ? 'A' : ' ',  // if any VolumeShapers active
6072c6c3bb76b2fa18ed3536331a1700250bd04c7ceAndy Hung
608f20e1d8df84c5fbeeace0052d100982ae39bb7a4Glenn Kasten            mCblk->mServer,
6092c6c3bb76b2fa18ed3536331a1700250bd04c7ceAndy Hung            bufferSizeInFrames,
6102c6c3bb76b2fa18ed3536331a1700250bd04c7ceAndy Hung            modifiedBufferChar,
6112c6c3bb76b2fa18ed3536331a1700250bd04c7ceAndy Hung            framesReadySafe,
6122c6c3bb76b2fa18ed3536331a1700250bd04c7ceAndy Hung            fillingStatus,
61382aaf94a5b18939e4d790bbc752031f3070704a3Glenn Kasten            mAudioTrackServerProxy->getUnderrunFrames(),
6142148bf0e79c436b8764b9edc4c8f2730cce98a32Andy Hung            nowInUnderrun,
6152c6c3bb76b2fa18ed3536331a1700250bd04c7ceAndy Hung            (unsigned)mAudioTrackServerProxy->framesFlushed() % 10000000,
6162c6c3bb76b2fa18ed3536331a1700250bd04c7ceAndy Hung
6172c6c3bb76b2fa18ed3536331a1700250bd04c7ceAndy Hung            (size_t)mMainBuffer, // use %zX as %p appends 0x
6182c6c3bb76b2fa18ed3536331a1700250bd04c7ceAndy Hung            (size_t)mAuxBuffer   // use %zX as %p appends 0x
6192c6c3bb76b2fa18ed3536331a1700250bd04c7ceAndy Hung            );
62081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
62181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
6229f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kastenuint32_t AudioFlinger::PlaybackThread::Track::sampleRate() const {
6239f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    return mAudioTrackServerProxy->getSampleRate();
6249f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten}
6259f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten
62681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// AudioBufferProvider interface
62781784c37c61b09289654b979567a42bf73cd2b12Eric Laurentstatus_t AudioFlinger::PlaybackThread::Track::getNextBuffer(
628d79072e9dff59f767cce2cda1caab80ce5a0815bGlenn Kasten        AudioBufferProvider::Buffer* buffer)
62981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{
6309f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    ServerProxy::Buffer buf;
6319f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    size_t desiredFrames = buffer->frameCount;
6329f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    buf.mFrameCount = desiredFrames;
6339f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    status_t status = mServerProxy->obtainBuffer(&buf);
6349f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    buffer->frameCount = buf.mFrameCount;
6359f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    buffer->raw = buf.mRaw;
636a66d3899f7d13e69ee451f1071f0d999678803ceMikhail Naganov    if (buf.mFrameCount == 0 && !isStopping() && !isStopped() && !isPaused()) {
637a66d3899f7d13e69ee451f1071f0d999678803ceMikhail Naganov        ALOGV("underrun,  framesReady(%zu) < framesDesired(%zd), state: %d",
638a66d3899f7d13e69ee451f1071f0d999678803ceMikhail Naganov                buf.mFrameCount, desiredFrames, mState);
63982aaf94a5b18939e4d790bbc752031f3070704a3Glenn Kasten        mAudioTrackServerProxy->tallyUnderrunFrames(desiredFrames);
6402812d9ea3a3a33142dd8e23c9d949c498d6f7a12Phil Burk    } else {
6412812d9ea3a3a33142dd8e23c9d949c498d6f7a12Phil Burk        mAudioTrackServerProxy->tallyUnderrunFrames(0);
64281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    }
6432812d9ea3a3a33142dd8e23c9d949c498d6f7a12Phil Burk
6449f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    return status;
64581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
64681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
6476466c9e6e6278c740aed77f695f679be9f5db478Glenn Kasten// releaseBuffer() is not overridden
6486466c9e6e6278c740aed77f695f679be9f5db478Glenn Kasten
6496466c9e6e6278c740aed77f695f679be9f5db478Glenn Kasten// ExtendedAudioBufferProvider interface
6506466c9e6e6278c740aed77f695f679be9f5db478Glenn Kasten
65127876c02c21cd3ab7ef01bdd1fc5400c5143584aAndy Hung// framesReady() may return an approximation of the number of frames if called
65227876c02c21cd3ab7ef01bdd1fc5400c5143584aAndy Hung// from a different thread than the one calling Proxy->obtainBuffer() and
65327876c02c21cd3ab7ef01bdd1fc5400c5143584aAndy Hung// Proxy->releaseBuffer(). Also note there is no mutual exclusion in the
65427876c02c21cd3ab7ef01bdd1fc5400c5143584aAndy Hung// AudioTrackServerProxy so be especially careful calling with FastTracks.
65581784c37c61b09289654b979567a42bf73cd2b12Eric Laurentsize_t AudioFlinger::PlaybackThread::Track::framesReady() const {
65627876c02c21cd3ab7ef01bdd1fc5400c5143584aAndy Hung    if (mSharedBuffer != 0 && (isStopped() || isStopping())) {
65727876c02c21cd3ab7ef01bdd1fc5400c5143584aAndy Hung        // Static tracks return zero frames immediately upon stopping (for FastTracks).
65827876c02c21cd3ab7ef01bdd1fc5400c5143584aAndy Hung        // The remainder of the buffer is not drained.
65927876c02c21cd3ab7ef01bdd1fc5400c5143584aAndy Hung        return 0;
66027876c02c21cd3ab7ef01bdd1fc5400c5143584aAndy Hung    }
6619f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    return mAudioTrackServerProxy->framesReady();
66281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
66381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
664818e7a32ce3633980138aff2c2bfcc5158b3cfccAndy Hungint64_t AudioFlinger::PlaybackThread::Track::framesReleased() const
6656466c9e6e6278c740aed77f695f679be9f5db478Glenn Kasten{
6666466c9e6e6278c740aed77f695f679be9f5db478Glenn Kasten    return mAudioTrackServerProxy->framesReleased();
6676466c9e6e6278c740aed77f695f679be9f5db478Glenn Kasten}
6686466c9e6e6278c740aed77f695f679be9f5db478Glenn Kasten
669818e7a32ce3633980138aff2c2bfcc5158b3cfccAndy Hungvoid AudioFlinger::PlaybackThread::Track::onTimestamp(const ExtendedTimestamp &timestamp)
6706ae5843c281301a9ffd1059d185620a9337e15a2Andy Hung{
6716ae5843c281301a9ffd1059d185620a9337e15a2Andy Hung    // This call comes from a FastTrack and should be kept lockless.
6726ae5843c281301a9ffd1059d185620a9337e15a2Andy Hung    // The server side frames are already translated to client frames.
673818e7a32ce3633980138aff2c2bfcc5158b3cfccAndy Hung    mAudioTrackServerProxy->setTimestamp(timestamp);
6746ae5843c281301a9ffd1059d185620a9337e15a2Andy Hung
675818e7a32ce3633980138aff2c2bfcc5158b3cfccAndy Hung    // We do not set drained here, as FastTrack timestamp may not go to very last frame.
6766ae5843c281301a9ffd1059d185620a9337e15a2Andy Hung}
6776ae5843c281301a9ffd1059d185620a9337e15a2Andy Hung
67881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// Don't call for fast tracks; the framesReady() could result in priority inversion
67981784c37c61b09289654b979567a42bf73cd2b12Eric Laurentbool AudioFlinger::PlaybackThread::Track::isReady() const {
6808d6c292a0bed3d63b5b7297d09a604af6327c663Krishnankutty Kolathappilly    if (mFillingUpStatus != FS_FILLING || isStopped() || isPausing()) {
6818d6c292a0bed3d63b5b7297d09a604af6327c663Krishnankutty Kolathappilly        return true;
6828d6c292a0bed3d63b5b7297d09a604af6327c663Krishnankutty Kolathappilly    }
6838d6c292a0bed3d63b5b7297d09a604af6327c663Krishnankutty Kolathappilly
684164985121796cf214c7a83d32005d9b01125b558Eric Laurent    if (isStopping()) {
685164985121796cf214c7a83d32005d9b01125b558Eric Laurent        if (framesReady() > 0) {
686164985121796cf214c7a83d32005d9b01125b558Eric Laurent            mFillingUpStatus = FS_FILLED;
687164985121796cf214c7a83d32005d9b01125b558Eric Laurent        }
68881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        return true;
68981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    }
69081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
691e8972b0a27fac327c997fceb20d9abae1dc1d899Phil Burk    if (framesReady() >= mServerProxy->getBufferSizeInFrames() ||
69296f60d8f04432a1ed503b3e24d5736d28c63c9a2Glenn Kasten            (mCblk->mFlags & CBLK_FORCEREADY)) {
69381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        mFillingUpStatus = FS_FILLED;
69496f60d8f04432a1ed503b3e24d5736d28c63c9a2Glenn Kasten        android_atomic_and(~CBLK_FORCEREADY, &mCblk->mFlags);
69581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        return true;
69681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    }
69781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    return false;
69881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
69981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
7000f11b51a57bc9062c4fe8af73747319cedabc5d6Glenn Kastenstatus_t AudioFlinger::PlaybackThread::Track::start(AudioSystem::sync_event_t event __unused,
701d848eb48c121c119e8ba7583efc75415fe102570Glenn Kasten                                                    audio_session_t triggerSession __unused)
70281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{
70381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    status_t status = NO_ERROR;
70481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    ALOGV("start(%d), calling pid %d session %d",
70581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            mName, IPCThreadState::self()->getCallingPid(), mSessionId);
70681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
70781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    sp<ThreadBase> thread = mThread.promote();
70881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    if (thread != 0) {
709813e2a74853bde19e37d878c596a044b3f299efcEric Laurent        if (isOffloaded()) {
710813e2a74853bde19e37d878c596a044b3f299efcEric Laurent            Mutex::Autolock _laf(thread->mAudioFlinger->mLock);
711813e2a74853bde19e37d878c596a044b3f299efcEric Laurent            Mutex::Autolock _lth(thread->mLock);
712813e2a74853bde19e37d878c596a044b3f299efcEric Laurent            sp<EffectChain> ec = thread->getEffectChain_l(mSessionId);
7135baf2af52cd186633b7173196c1e4a4cd3435f22Eric Laurent            if (thread->mAudioFlinger->isNonOffloadableGlobalEffectEnabled_l() ||
7145baf2af52cd186633b7173196c1e4a4cd3435f22Eric Laurent                    (ec != 0 && ec->isNonOffloadableEnabled())) {
715813e2a74853bde19e37d878c596a044b3f299efcEric Laurent                invalidate();
716813e2a74853bde19e37d878c596a044b3f299efcEric Laurent                return PERMISSION_DENIED;
717813e2a74853bde19e37d878c596a044b3f299efcEric Laurent            }
718813e2a74853bde19e37d878c596a044b3f299efcEric Laurent        }
719813e2a74853bde19e37d878c596a044b3f299efcEric Laurent        Mutex::Autolock _lth(thread->mLock);
72081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        track_state state = mState;
72181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        // here the track could be either new, or restarted
72281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        // in both cases "unstop" the track
723bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent
7248d6c292a0bed3d63b5b7297d09a604af6327c663Krishnankutty Kolathappilly        // initial state-stopping. next state-pausing.
7258d6c292a0bed3d63b5b7297d09a604af6327c663Krishnankutty Kolathappilly        // What if resume is called ?
7268d6c292a0bed3d63b5b7297d09a604af6327c663Krishnankutty Kolathappilly
7278d6c292a0bed3d63b5b7297d09a604af6327c663Krishnankutty Kolathappilly        if (state == PAUSED || state == PAUSING) {
728bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent            if (mResumeToStopping) {
729bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent                // happened we need to resume to STOPPING_1
730bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent                mState = TrackBase::STOPPING_1;
731bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent                ALOGV("PAUSED => STOPPING_1 (%d) on thread %p", mName, this);
732bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent            } else {
733bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent                mState = TrackBase::RESUMING;
734bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent                ALOGV("PAUSED => RESUMING (%d) on thread %p", mName, this);
735bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent            }
73681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        } else {
73781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            mState = TrackBase::ACTIVE;
73881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            ALOGV("? => ACTIVE (%d) on thread %p", mName, this);
73981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        }
74081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
741e10393e72454bfd8298017dc193faf424f4e9a8fAndy Hung        // states to reset position info for non-offloaded/direct tracks
742e10393e72454bfd8298017dc193faf424f4e9a8fAndy Hung        if (!isOffloaded() && !isDirect()
743e10393e72454bfd8298017dc193faf424f4e9a8fAndy Hung                && (state == IDLE || state == STOPPED || state == FLUSHED)) {
744e10393e72454bfd8298017dc193faf424f4e9a8fAndy Hung            mFrameMap.reset();
745e10393e72454bfd8298017dc193faf424f4e9a8fAndy Hung        }
746bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent        PlaybackThread *playbackThread = (PlaybackThread *)thread.get();
747240934ba80d6c6165749db7681d243c6857a092fHaynes Mathew George        if (isFastTrack()) {
748240934ba80d6c6165749db7681d243c6857a092fHaynes Mathew George            // refresh fast track underruns on start because that field is never cleared
749240934ba80d6c6165749db7681d243c6857a092fHaynes Mathew George            // by the fast mixer; furthermore, the same track can be recycled, i.e. start
750240934ba80d6c6165749db7681d243c6857a092fHaynes Mathew George            // after stop.
751240934ba80d6c6165749db7681d243c6857a092fHaynes Mathew George            mObservedUnderruns = playbackThread->getFastTrackUnderruns(mFastIndex);
752240934ba80d6c6165749db7681d243c6857a092fHaynes Mathew George        }
753bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent        status = playbackThread->addTrack_l(this);
754bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent        if (status == INVALID_OPERATION || status == PERMISSION_DENIED) {
755bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent            triggerEvents(AudioSystem::SYNC_EVENT_PRESENTATION_COMPLETE);
756bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent            //  restore previous state if start was rejected by policy manager
757bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent            if (status == PERMISSION_DENIED) {
758bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent                mState = state;
75981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            }
76081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        }
761bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent        // track was already in the active list, not a problem
762bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent        if (status == ALREADY_EXISTS) {
763bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent            status = NO_ERROR;
76412022ff8d223ccf4dfae019c81e4a93a3f44985cGlenn Kasten        } else {
76512022ff8d223ccf4dfae019c81e4a93a3f44985cGlenn Kasten            // Acknowledge any pending flush(), so that subsequent new data isn't discarded.
76612022ff8d223ccf4dfae019c81e4a93a3f44985cGlenn Kasten            // It is usually unsafe to access the server proxy from a binder thread.
76712022ff8d223ccf4dfae019c81e4a93a3f44985cGlenn Kasten            // But in this case we know the mixer thread (whether normal mixer or fast mixer)
76812022ff8d223ccf4dfae019c81e4a93a3f44985cGlenn Kasten            // isn't looking at this track yet:  we still hold the normal mixer thread lock,
76912022ff8d223ccf4dfae019c81e4a93a3f44985cGlenn Kasten            // and for fast tracks the track is not yet in the fast mixer thread's active set.
770e6fb82a207f5256933e2d83e77262331af50a27fAndy Hung            // For static tracks, this is used to acknowledge change in position or loop.
771564d144fc28917d42e3a67718ac51d61bfc36315Eric Laurent            ServerProxy::Buffer buffer;
772564d144fc28917d42e3a67718ac51d61bfc36315Eric Laurent            buffer.mFrameCount = 1;
773564d144fc28917d42e3a67718ac51d61bfc36315Eric Laurent            (void) mAudioTrackServerProxy->obtainBuffer(&buffer, true /*ackFlush*/);
77481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        }
77581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    } else {
77681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        status = BAD_VALUE;
77781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    }
77881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    return status;
77981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
78081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
78181784c37c61b09289654b979567a42bf73cd2b12Eric Laurentvoid AudioFlinger::PlaybackThread::Track::stop()
78281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{
78381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    ALOGV("stop(%d), calling pid %d", mName, IPCThreadState::self()->getCallingPid());
78481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    sp<ThreadBase> thread = mThread.promote();
78581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    if (thread != 0) {
78681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        Mutex::Autolock _l(thread->mLock);
78781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        track_state state = mState;
78881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        if (state == RESUMING || state == ACTIVE || state == PAUSING || state == PAUSED) {
78981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            // If the track is not active (PAUSED and buffers full), flush buffers
79081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            PlaybackThread *playbackThread = (PlaybackThread *)thread.get();
79181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            if (playbackThread->mActiveTracks.indexOf(this) < 0) {
79281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                reset();
79381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                mState = STOPPED;
794ab5cdbaf65ca509681d2726aacdf3ac8bfb6b3faEric Laurent            } else if (!isFastTrack() && !isOffloaded() && !isDirect()) {
79581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                mState = STOPPED;
79681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            } else {
797bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent                // For fast tracks prepareTracks_l() will set state to STOPPING_2
798bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent                // presentation is complete
799bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent                // For an offloaded track this starts a drain and state will
800bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent                // move to STOPPING_2 when drain completes and then STOPPED
80181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                mState = STOPPING_1;
802e93cc03da360a1a0d2ad937c745ce8c8e8be81c2Eric Laurent                if (isOffloaded()) {
803e93cc03da360a1a0d2ad937c745ce8c8e8be81c2Eric Laurent                    mRetryCount = PlaybackThread::kMaxTrackStopRetriesOffload;
804e93cc03da360a1a0d2ad937c745ce8c8e8be81c2Eric Laurent                }
80581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            }
806b369cafd67beb63dd0278dba543f519956208a7fEric Laurent            playbackThread->broadcast_l();
80781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            ALOGV("not stopping/stopped => stopping/stopped (%d) on thread %p", mName,
80881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                    playbackThread);
80981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        }
81081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    }
81181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
81281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
81381784c37c61b09289654b979567a42bf73cd2b12Eric Laurentvoid AudioFlinger::PlaybackThread::Track::pause()
81481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{
81581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    ALOGV("pause(%d), calling pid %d", mName, IPCThreadState::self()->getCallingPid());
81681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    sp<ThreadBase> thread = mThread.promote();
81781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    if (thread != 0) {
81881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        Mutex::Autolock _l(thread->mLock);
819bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent        PlaybackThread *playbackThread = (PlaybackThread *)thread.get();
820bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent        switch (mState) {
821bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent        case STOPPING_1:
822bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent        case STOPPING_2:
823bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent            if (!isOffloaded()) {
824bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent                /* nothing to do if track is not offloaded */
825bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent                break;
826bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent            }
827bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent
828bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent            // Offloaded track was draining, we need to carry on draining when resumed
829bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent            mResumeToStopping = true;
830bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent            // fall through...
831bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent        case ACTIVE:
832bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent        case RESUMING:
83381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            mState = PAUSING;
83481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            ALOGV("ACTIVE/RESUMING => PAUSING (%d) on thread %p", mName, thread.get());
835ede6c3b8b1147bc425f7b923882f559a513fe23bEric Laurent            playbackThread->broadcast_l();
836bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent            break;
837bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent
838bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent        default:
839bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent            break;
84081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        }
84181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    }
84281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
84381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
84481784c37c61b09289654b979567a42bf73cd2b12Eric Laurentvoid AudioFlinger::PlaybackThread::Track::flush()
84581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{
84681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    ALOGV("flush(%d)", mName);
84781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    sp<ThreadBase> thread = mThread.promote();
84881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    if (thread != 0) {
84981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        Mutex::Autolock _l(thread->mLock);
85081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        PlaybackThread *playbackThread = (PlaybackThread *)thread.get();
851bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent
8524bb650bb3c4f15789232f3f3cf778c5441122360Phil Burk        // Flush the ring buffer now if the track is not active in the PlaybackThread.
8534bb650bb3c4f15789232f3f3cf778c5441122360Phil Burk        // Otherwise the flush would not be done until the track is resumed.
8544bb650bb3c4f15789232f3f3cf778c5441122360Phil Burk        // Requires FastTrack removal be BLOCK_UNTIL_ACKED
8554bb650bb3c4f15789232f3f3cf778c5441122360Phil Burk        if (playbackThread->mActiveTracks.indexOf(this) < 0) {
8564bb650bb3c4f15789232f3f3cf778c5441122360Phil Burk            (void)mServerProxy->flushBufferIfNeeded();
8574bb650bb3c4f15789232f3f3cf778c5441122360Phil Burk        }
8584bb650bb3c4f15789232f3f3cf778c5441122360Phil Burk
859bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent        if (isOffloaded()) {
860bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent            // If offloaded we allow flush during any state except terminated
861bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent            // and keep the track active to avoid problems if user is seeking
862bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent            // rapidly and underlying hardware has a significant delay handling
863bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent            // a pause
864bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent            if (isTerminated()) {
865bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent                return;
866bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent            }
867bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent
868bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent            ALOGV("flush: offload flush");
86981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            reset();
870bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent
871bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent            if (mState == STOPPING_1 || mState == STOPPING_2) {
872bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent                ALOGV("flushed in STOPPING_1 or 2 state, change state to ACTIVE");
873bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent                mState = ACTIVE;
874bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent            }
875bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent
8767844f679be8d94c5cdf017f53754cb68ee2f00daHaynes Mathew George            mFlushHwPending = true;
877bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent            mResumeToStopping = false;
878bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent        } else {
879bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent            if (mState != STOPPING_1 && mState != STOPPING_2 && mState != STOPPED &&
880bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent                    mState != PAUSED && mState != PAUSING && mState != IDLE && mState != FLUSHED) {
881bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent                return;
882bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent            }
883bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent            // No point remaining in PAUSED state after a flush => go to
884bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent            // FLUSHED state
885bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent            mState = FLUSHED;
886bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent            // do not reset the track if it is still in the process of being stopped or paused.
887bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent            // this will be done by prepareTracks_l() when the track is stopped.
888bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent            // prepareTracks_l() will see mState == FLUSHED, then
889bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent            // remove from active track list, reset(), and trigger presentation complete
890d1f69b0b17acbd96987ecb2f3378abd394d05903Eric Laurent            if (isDirect()) {
891d1f69b0b17acbd96987ecb2f3378abd394d05903Eric Laurent                mFlushHwPending = true;
892d1f69b0b17acbd96987ecb2f3378abd394d05903Eric Laurent            }
893bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent            if (playbackThread->mActiveTracks.indexOf(this) < 0) {
894bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent                reset();
895bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent            }
89681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        }
897bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent        // Prevent flush being lost if the track is flushed and then resumed
898bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent        // before mixer thread can run. This is important when offloading
899bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent        // because the hardware buffer could hold a large amount of audio
900ede6c3b8b1147bc425f7b923882f559a513fe23bEric Laurent        playbackThread->broadcast_l();
90181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    }
90281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
90381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
9047844f679be8d94c5cdf017f53754cb68ee2f00daHaynes Mathew George// must be called with thread lock held
9057844f679be8d94c5cdf017f53754cb68ee2f00daHaynes Mathew Georgevoid AudioFlinger::PlaybackThread::Track::flushAck()
9067844f679be8d94c5cdf017f53754cb68ee2f00daHaynes Mathew George{
907d1f69b0b17acbd96987ecb2f3378abd394d05903Eric Laurent    if (!isOffloaded() && !isDirect())
9087844f679be8d94c5cdf017f53754cb68ee2f00daHaynes Mathew George        return;
9097844f679be8d94c5cdf017f53754cb68ee2f00daHaynes Mathew George
9104bb650bb3c4f15789232f3f3cf778c5441122360Phil Burk    // Clear the client ring buffer so that the app can prime the buffer while paused.
9114bb650bb3c4f15789232f3f3cf778c5441122360Phil Burk    // Otherwise it might not get cleared until playback is resumed and obtainBuffer() is called.
9124bb650bb3c4f15789232f3f3cf778c5441122360Phil Burk    mServerProxy->flushBufferIfNeeded();
9134bb650bb3c4f15789232f3f3cf778c5441122360Phil Burk
9147844f679be8d94c5cdf017f53754cb68ee2f00daHaynes Mathew George    mFlushHwPending = false;
9157844f679be8d94c5cdf017f53754cb68ee2f00daHaynes Mathew George}
9167844f679be8d94c5cdf017f53754cb68ee2f00daHaynes Mathew George
91781784c37c61b09289654b979567a42bf73cd2b12Eric Laurentvoid AudioFlinger::PlaybackThread::Track::reset()
91881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{
91981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    // Do not reset twice to avoid discarding data written just after a flush and before
92081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    // the audioflinger thread detects the track is stopped.
92181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    if (!mResetDone) {
92281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        // Force underrun condition to avoid false underrun callback until first data is
92381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        // written to buffer
92496f60d8f04432a1ed503b3e24d5736d28c63c9a2Glenn Kasten        android_atomic_and(~CBLK_FORCEREADY, &mCblk->mFlags);
92581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        mFillingUpStatus = FS_FILLING;
92681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        mResetDone = true;
92781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        if (mState == FLUSHED) {
92881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            mState = IDLE;
92981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        }
93081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    }
93181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
93281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
933bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurentstatus_t AudioFlinger::PlaybackThread::Track::setParameters(const String8& keyValuePairs)
934bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent{
935bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent    sp<ThreadBase> thread = mThread.promote();
936bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent    if (thread == 0) {
937bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent        ALOGE("thread is dead");
938bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent        return FAILED_TRANSACTION;
939bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent    } else if ((thread->type() == ThreadBase::DIRECT) ||
940bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent                    (thread->type() == ThreadBase::OFFLOAD)) {
941bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent        return thread->setParameters(keyValuePairs);
942bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent    } else {
943bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent        return PERMISSION_DENIED;
944bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent    }
945bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent}
946bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent
9479fc8b5cd4a64ef07e84c69112461324d5c13a0b0Andy HungVolumeShaper::Status AudioFlinger::PlaybackThread::Track::applyVolumeShaper(
9489fc8b5cd4a64ef07e84c69112461324d5c13a0b0Andy Hung        const sp<VolumeShaper::Configuration>& configuration,
9499fc8b5cd4a64ef07e84c69112461324d5c13a0b0Andy Hung        const sp<VolumeShaper::Operation>& operation)
9509fc8b5cd4a64ef07e84c69112461324d5c13a0b0Andy Hung{
95110cbff139360f3f642e0e3b3ccf2d463dbed22cfAndy Hung    sp<VolumeShaper::Configuration> newConfiguration;
95210cbff139360f3f642e0e3b3ccf2d463dbed22cfAndy Hung
95310cbff139360f3f642e0e3b3ccf2d463dbed22cfAndy Hung    if (isOffloadedOrDirect()) {
95410cbff139360f3f642e0e3b3ccf2d463dbed22cfAndy Hung        const VolumeShaper::Configuration::OptionFlag optionFlag
95510cbff139360f3f642e0e3b3ccf2d463dbed22cfAndy Hung            = configuration->getOptionFlags();
95610cbff139360f3f642e0e3b3ccf2d463dbed22cfAndy Hung        if ((optionFlag & VolumeShaper::Configuration::OPTION_FLAG_CLOCK_TIME) == 0) {
95710cbff139360f3f642e0e3b3ccf2d463dbed22cfAndy Hung            ALOGW("%s tracks do not support frame counted VolumeShaper,"
95810cbff139360f3f642e0e3b3ccf2d463dbed22cfAndy Hung                    " using clock time instead", isOffloaded() ? "Offload" : "Direct");
95910cbff139360f3f642e0e3b3ccf2d463dbed22cfAndy Hung            newConfiguration = new VolumeShaper::Configuration(*configuration);
96010cbff139360f3f642e0e3b3ccf2d463dbed22cfAndy Hung            newConfiguration->setOptionFlags(
96110cbff139360f3f642e0e3b3ccf2d463dbed22cfAndy Hung                VolumeShaper::Configuration::OptionFlag(optionFlag
96210cbff139360f3f642e0e3b3ccf2d463dbed22cfAndy Hung                        | VolumeShaper::Configuration::OPTION_FLAG_CLOCK_TIME));
96310cbff139360f3f642e0e3b3ccf2d463dbed22cfAndy Hung        }
96410cbff139360f3f642e0e3b3ccf2d463dbed22cfAndy Hung    }
9659fc8b5cd4a64ef07e84c69112461324d5c13a0b0Andy Hung
96610cbff139360f3f642e0e3b3ccf2d463dbed22cfAndy Hung    VolumeShaper::Status status = mVolumeHandler->applyVolumeShaper(
96710cbff139360f3f642e0e3b3ccf2d463dbed22cfAndy Hung            (newConfiguration.get() != nullptr ? newConfiguration : configuration), operation);
96810cbff139360f3f642e0e3b3ccf2d463dbed22cfAndy Hung
96910cbff139360f3f642e0e3b3ccf2d463dbed22cfAndy Hung    if (isOffloadedOrDirect()) {
97010cbff139360f3f642e0e3b3ccf2d463dbed22cfAndy Hung        // Signal thread to fetch new volume.
97110cbff139360f3f642e0e3b3ccf2d463dbed22cfAndy Hung        sp<ThreadBase> thread = mThread.promote();
97210cbff139360f3f642e0e3b3ccf2d463dbed22cfAndy Hung        if (thread != 0) {
97310cbff139360f3f642e0e3b3ccf2d463dbed22cfAndy Hung             Mutex::Autolock _l(thread->mLock);
97410cbff139360f3f642e0e3b3ccf2d463dbed22cfAndy Hung            thread->broadcast_l();
97510cbff139360f3f642e0e3b3ccf2d463dbed22cfAndy Hung        }
97610cbff139360f3f642e0e3b3ccf2d463dbed22cfAndy Hung    }
97710cbff139360f3f642e0e3b3ccf2d463dbed22cfAndy Hung    return status;
9789fc8b5cd4a64ef07e84c69112461324d5c13a0b0Andy Hung}
9799fc8b5cd4a64ef07e84c69112461324d5c13a0b0Andy Hung
9809fc8b5cd4a64ef07e84c69112461324d5c13a0b0Andy Hungsp<VolumeShaper::State> AudioFlinger::PlaybackThread::Track::getVolumeShaperState(int id)
9819fc8b5cd4a64ef07e84c69112461324d5c13a0b0Andy Hung{
9829fc8b5cd4a64ef07e84c69112461324d5c13a0b0Andy Hung    // Note: We don't check if Thread exists.
9839fc8b5cd4a64ef07e84c69112461324d5c13a0b0Andy Hung
9849fc8b5cd4a64ef07e84c69112461324d5c13a0b0Andy Hung    // mVolumeHandler is thread safe.
9859fc8b5cd4a64ef07e84c69112461324d5c13a0b0Andy Hung    return mVolumeHandler->getVolumeShaperState(id);
9869fc8b5cd4a64ef07e84c69112461324d5c13a0b0Andy Hung}
9879fc8b5cd4a64ef07e84c69112461324d5c13a0b0Andy Hung
988573d80a8f463f648a515fc0975bf83951b272993Glenn Kastenstatus_t AudioFlinger::PlaybackThread::Track::getTimestamp(AudioTimestamp& timestamp)
989573d80a8f463f648a515fc0975bf83951b272993Glenn Kasten{
990818e7a32ce3633980138aff2c2bfcc5158b3cfccAndy Hung    if (!isOffloaded() && !isDirect()) {
991818e7a32ce3633980138aff2c2bfcc5158b3cfccAndy Hung        return INVALID_OPERATION; // normal tracks handled through SSQ
992fe346c707f59d763ded93bc3d27b51f0c0408258Glenn Kasten    }
993573d80a8f463f648a515fc0975bf83951b272993Glenn Kasten    sp<ThreadBase> thread = mThread.promote();
994573d80a8f463f648a515fc0975bf83951b272993Glenn Kasten    if (thread == 0) {
995fe346c707f59d763ded93bc3d27b51f0c0408258Glenn Kasten        return INVALID_OPERATION;
996573d80a8f463f648a515fc0975bf83951b272993Glenn Kasten    }
9976140c79c31f5dc237fba69554de5be641cedf113Phil Burk
998573d80a8f463f648a515fc0975bf83951b272993Glenn Kasten    Mutex::Autolock _l(thread->mLock);
999573d80a8f463f648a515fc0975bf83951b272993Glenn Kasten    PlaybackThread *playbackThread = (PlaybackThread *)thread.get();
1000818e7a32ce3633980138aff2c2bfcc5158b3cfccAndy Hung    return playbackThread->getTimestamp_l(timestamp);
1001573d80a8f463f648a515fc0975bf83951b272993Glenn Kasten}
1002573d80a8f463f648a515fc0975bf83951b272993Glenn Kasten
100381784c37c61b09289654b979567a42bf73cd2b12Eric Laurentstatus_t AudioFlinger::PlaybackThread::Track::attachAuxEffect(int EffectId)
100481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{
100581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    status_t status = DEAD_OBJECT;
100681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    sp<ThreadBase> thread = mThread.promote();
100781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    if (thread != 0) {
100881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        PlaybackThread *playbackThread = (PlaybackThread *)thread.get();
100981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        sp<AudioFlinger> af = mClient->audioFlinger();
101081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
101181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        Mutex::Autolock _l(af->mLock);
101281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
101381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        sp<PlaybackThread> srcThread = af->getEffectThread_l(AUDIO_SESSION_OUTPUT_MIX, EffectId);
101481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
101581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        if (EffectId != 0 && srcThread != 0 && playbackThread != srcThread.get()) {
101681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            Mutex::Autolock _dl(playbackThread->mLock);
101781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            Mutex::Autolock _sl(srcThread->mLock);
101881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            sp<EffectChain> chain = srcThread->getEffectChain_l(AUDIO_SESSION_OUTPUT_MIX);
101981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            if (chain == 0) {
102081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                return INVALID_OPERATION;
102181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            }
102281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
102381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            sp<EffectModule> effect = chain->getEffectFromId_l(EffectId);
102481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            if (effect == 0) {
102581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                return INVALID_OPERATION;
102681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            }
102781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            srcThread->removeEffect_l(effect);
10285baf2af52cd186633b7173196c1e4a4cd3435f22Eric Laurent            status = playbackThread->addEffect_l(effect);
10295baf2af52cd186633b7173196c1e4a4cd3435f22Eric Laurent            if (status != NO_ERROR) {
10305baf2af52cd186633b7173196c1e4a4cd3435f22Eric Laurent                srcThread->addEffect_l(effect);
10315baf2af52cd186633b7173196c1e4a4cd3435f22Eric Laurent                return INVALID_OPERATION;
10325baf2af52cd186633b7173196c1e4a4cd3435f22Eric Laurent            }
103381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            // removeEffect_l() has stopped the effect if it was active so it must be restarted
103481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            if (effect->state() == EffectModule::ACTIVE ||
103581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                    effect->state() == EffectModule::STOPPING) {
103681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                effect->start();
103781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            }
103881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
103981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            sp<EffectChain> dstChain = effect->chain().promote();
104081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            if (dstChain == 0) {
104181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                srcThread->addEffect_l(effect);
104281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                return INVALID_OPERATION;
104381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            }
104481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            AudioSystem::unregisterEffect(effect->id());
104581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            AudioSystem::registerEffect(&effect->desc(),
104681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                                        srcThread->id(),
104781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                                        dstChain->strategy(),
104881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                                        AUDIO_SESSION_OUTPUT_MIX,
104981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                                        effect->id());
1050d72b7c0180ee83fc3754629ed68fc5887a125c4cEric Laurent            AudioSystem::setEffectEnabled(effect->id(), effect->isEnabled());
105181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        }
105281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        status = playbackThread->attachAuxEffect(this, EffectId);
105381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    }
105481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    return status;
105581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
105681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
105781784c37c61b09289654b979567a42bf73cd2b12Eric Laurentvoid AudioFlinger::PlaybackThread::Track::setAuxBuffer(int EffectId, int32_t *buffer)
105881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{
105981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    mAuxEffectId = EffectId;
106081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    mAuxBuffer = buffer;
106181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
106281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
1063818e7a32ce3633980138aff2c2bfcc5158b3cfccAndy Hungbool AudioFlinger::PlaybackThread::Track::presentationComplete(
1064818e7a32ce3633980138aff2c2bfcc5158b3cfccAndy Hung        int64_t framesWritten, size_t audioHalFrames)
106581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{
1066818e7a32ce3633980138aff2c2bfcc5158b3cfccAndy Hung    // TODO: improve this based on FrameMap if it exists, to ensure full drain.
1067818e7a32ce3633980138aff2c2bfcc5158b3cfccAndy Hung    // This assists in proper timestamp computation as well as wakelock management.
1068818e7a32ce3633980138aff2c2bfcc5158b3cfccAndy Hung
106981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    // a track is considered presented when the total number of frames written to audio HAL
107081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    // corresponds to the number of frames written when presentationComplete() is called for the
107181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    // first time (mPresentationCompleteFrames == 0) plus the buffer filling status at that time.
1072bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent    // For an offloaded track the HAL+h/w delay is variable so a HAL drain() is used
1073bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent    // to detect when all frames have been played. In this case framesWritten isn't
1074bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent    // useful because it doesn't always reflect whether there is data in the h/w
1075bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent    // buffers, particularly if a track has been paused and resumed during draining
1076818e7a32ce3633980138aff2c2bfcc5158b3cfccAndy Hung    ALOGV("presentationComplete() mPresentationCompleteFrames %lld framesWritten %lld",
1077818e7a32ce3633980138aff2c2bfcc5158b3cfccAndy Hung            (long long)mPresentationCompleteFrames, (long long)framesWritten);
107881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    if (mPresentationCompleteFrames == 0) {
107981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        mPresentationCompleteFrames = framesWritten + audioHalFrames;
1080818e7a32ce3633980138aff2c2bfcc5158b3cfccAndy Hung        ALOGV("presentationComplete() reset: mPresentationCompleteFrames %lld audioHalFrames %zu",
1081818e7a32ce3633980138aff2c2bfcc5158b3cfccAndy Hung                (long long)mPresentationCompleteFrames, audioHalFrames);
108281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    }
1083bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent
1084c54b1ffc92b8ad27608a8af21033d7cab33cb3a0Andy Hung    bool complete;
1085c54b1ffc92b8ad27608a8af21033d7cab33cb3a0Andy Hung    if (isOffloaded()) {
1086c54b1ffc92b8ad27608a8af21033d7cab33cb3a0Andy Hung        complete = true;
1087c54b1ffc92b8ad27608a8af21033d7cab33cb3a0Andy Hung    } else if (isDirect() || isFastTrack()) { // these do not go through linear map
1088c42e9b462661673dff480ee71757a58b0f806370Glenn Kasten        complete = framesWritten >= (int64_t) mPresentationCompleteFrames;
1089c54b1ffc92b8ad27608a8af21033d7cab33cb3a0Andy Hung    } else {  // Normal tracks, OutputTracks, and PatchTracks
1090c42e9b462661673dff480ee71757a58b0f806370Glenn Kasten        complete = framesWritten >= (int64_t) mPresentationCompleteFrames
1091c54b1ffc92b8ad27608a8af21033d7cab33cb3a0Andy Hung                && mAudioTrackServerProxy->isDrained();
1092c54b1ffc92b8ad27608a8af21033d7cab33cb3a0Andy Hung    }
1093c54b1ffc92b8ad27608a8af21033d7cab33cb3a0Andy Hung
1094c54b1ffc92b8ad27608a8af21033d7cab33cb3a0Andy Hung    if (complete) {
109581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        triggerEvents(AudioSystem::SYNC_EVENT_PRESENTATION_COMPLETE);
1096bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent        mAudioTrackServerProxy->setStreamEndDone();
109781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        return true;
109881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    }
109981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    return false;
110081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
110181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
110281784c37c61b09289654b979567a42bf73cd2b12Eric Laurentvoid AudioFlinger::PlaybackThread::Track::triggerEvents(AudioSystem::sync_event_t type)
110381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{
11043ab368e0810d894dcbc0971350c095049478a055Mark Salyzyn    for (size_t i = 0; i < mSyncEvents.size(); i++) {
110581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        if (mSyncEvents[i]->type() == type) {
110681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            mSyncEvents[i]->trigger();
110781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            mSyncEvents.removeAt(i);
110881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            i--;
110981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        }
111081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    }
111181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
111281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
111381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// implement VolumeBufferProvider interface
111481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
1115c56f3426099a3cf2d07ccff8886050c7fbce140fGlenn Kastengain_minifloat_packed_t AudioFlinger::PlaybackThread::Track::getVolumeLR()
111681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{
111781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    // called by FastMixer, so not allowed to take any locks, block, or do I/O including logs
111881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    ALOG_ASSERT(isFastTrack() && (mCblk != NULL));
1119c56f3426099a3cf2d07ccff8886050c7fbce140fGlenn Kasten    gain_minifloat_packed_t vlr = mAudioTrackServerProxy->getVolumeLR();
1120c56f3426099a3cf2d07ccff8886050c7fbce140fGlenn Kasten    float vl = float_from_gain(gain_minifloat_unpack_left(vlr));
1121c56f3426099a3cf2d07ccff8886050c7fbce140fGlenn Kasten    float vr = float_from_gain(gain_minifloat_unpack_right(vlr));
112281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    // track volumes come from shared memory, so can't be trusted and must be clamped
1123c56f3426099a3cf2d07ccff8886050c7fbce140fGlenn Kasten    if (vl > GAIN_FLOAT_UNITY) {
1124c56f3426099a3cf2d07ccff8886050c7fbce140fGlenn Kasten        vl = GAIN_FLOAT_UNITY;
112581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    }
1126c56f3426099a3cf2d07ccff8886050c7fbce140fGlenn Kasten    if (vr > GAIN_FLOAT_UNITY) {
1127c56f3426099a3cf2d07ccff8886050c7fbce140fGlenn Kasten        vr = GAIN_FLOAT_UNITY;
112881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    }
112981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    // now apply the cached master volume and stream type volume;
113081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    // this is trusted but lacks any synchronization or barrier so may be stale
113181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    float v = mCachedVolume;
113281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    vl *= v;
113381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    vr *= v;
1134c56f3426099a3cf2d07ccff8886050c7fbce140fGlenn Kasten    // re-combine into packed minifloat
1135c56f3426099a3cf2d07ccff8886050c7fbce140fGlenn Kasten    vlr = gain_minifloat_pack(gain_from_float(vl), gain_from_float(vr));
113681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    // FIXME look at mute, pause, and stop flags
113781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    return vlr;
113881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
113981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
114081784c37c61b09289654b979567a42bf73cd2b12Eric Laurentstatus_t AudioFlinger::PlaybackThread::Track::setSyncEvent(const sp<SyncEvent>& event)
114181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{
1142bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent    if (isTerminated() || mState == PAUSED ||
114381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            ((framesReady() == 0) && ((mSharedBuffer != 0) ||
114481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                                      (mState == STOPPED)))) {
1145c42e9b462661673dff480ee71757a58b0f806370Glenn Kasten        ALOGW("Track::setSyncEvent() in invalid state %d on session %d %s mode, framesReady %zu",
114681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent              mState, mSessionId, (mSharedBuffer != 0) ? "static" : "stream", framesReady());
114781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        event->cancel();
114881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        return INVALID_OPERATION;
114981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    }
115081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    (void) TrackBase::setSyncEvent(event);
115181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    return NO_ERROR;
115281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
115381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
11545736c35b841de56ce394b4879389f669b61425e6Glenn Kastenvoid AudioFlinger::PlaybackThread::Track::invalidate()
11555736c35b841de56ce394b4879389f669b61425e6Glenn Kasten{
11566acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent    TrackBase::invalidate();
11574d231dc0ee34380956c71cbe18a750e487a69601Eric Laurent    signalClientFlag(CBLK_INVALID);
11584d231dc0ee34380956c71cbe18a750e487a69601Eric Laurent}
11594d231dc0ee34380956c71cbe18a750e487a69601Eric Laurent
11604d231dc0ee34380956c71cbe18a750e487a69601Eric Laurentvoid AudioFlinger::PlaybackThread::Track::disable()
11614d231dc0ee34380956c71cbe18a750e487a69601Eric Laurent{
11624d231dc0ee34380956c71cbe18a750e487a69601Eric Laurent    signalClientFlag(CBLK_DISABLED);
11634d231dc0ee34380956c71cbe18a750e487a69601Eric Laurent}
11644d231dc0ee34380956c71cbe18a750e487a69601Eric Laurent
11654d231dc0ee34380956c71cbe18a750e487a69601Eric Laurentvoid AudioFlinger::PlaybackThread::Track::signalClientFlag(int32_t flag)
11664d231dc0ee34380956c71cbe18a750e487a69601Eric Laurent{
11679f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    // FIXME should use proxy, and needs work
11689f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    audio_track_cblk_t* cblk = mCblk;
11694d231dc0ee34380956c71cbe18a750e487a69601Eric Laurent    android_atomic_or(flag, &cblk->mFlags);
11709f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    android_atomic_release_store(0x40000000, &cblk->mFutex);
11719f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    // client is not in server, so FUTEX_WAKE is needed instead of FUTEX_WAKE_PRIVATE
1172ee499291404a192b059f2e04c5afc65aa6cdd74cElliott Hughes    (void) syscall(__NR_futex, &cblk->mFutex, FUTEX_WAKE, INT_MAX);
11735736c35b841de56ce394b4879389f669b61425e6Glenn Kasten}
11745736c35b841de56ce394b4879389f669b61425e6Glenn Kasten
117559fe010bcc072597852454a2ec53d7b0a2002a3bEric Laurentvoid AudioFlinger::PlaybackThread::Track::signal()
117659fe010bcc072597852454a2ec53d7b0a2002a3bEric Laurent{
117759fe010bcc072597852454a2ec53d7b0a2002a3bEric Laurent    sp<ThreadBase> thread = mThread.promote();
117859fe010bcc072597852454a2ec53d7b0a2002a3bEric Laurent    if (thread != 0) {
117959fe010bcc072597852454a2ec53d7b0a2002a3bEric Laurent        PlaybackThread *t = (PlaybackThread *)thread.get();
118059fe010bcc072597852454a2ec53d7b0a2002a3bEric Laurent        Mutex::Autolock _l(t->mLock);
118159fe010bcc072597852454a2ec53d7b0a2002a3bEric Laurent        t->broadcast_l();
118259fe010bcc072597852454a2ec53d7b0a2002a3bEric Laurent    }
118359fe010bcc072597852454a2ec53d7b0a2002a3bEric Laurent}
118459fe010bcc072597852454a2ec53d7b0a2002a3bEric Laurent
11858d6c292a0bed3d63b5b7297d09a604af6327c663Krishnankutty Kolathappilly//To be called with thread lock held
11868d6c292a0bed3d63b5b7297d09a604af6327c663Krishnankutty Kolathappillybool AudioFlinger::PlaybackThread::Track::isResumePending() {
11878d6c292a0bed3d63b5b7297d09a604af6327c663Krishnankutty Kolathappilly
11888d6c292a0bed3d63b5b7297d09a604af6327c663Krishnankutty Kolathappilly    if (mState == RESUMING)
11898d6c292a0bed3d63b5b7297d09a604af6327c663Krishnankutty Kolathappilly        return true;
11908d6c292a0bed3d63b5b7297d09a604af6327c663Krishnankutty Kolathappilly    /* Resume is pending if track was stopping before pause was called */
11918d6c292a0bed3d63b5b7297d09a604af6327c663Krishnankutty Kolathappilly    if (mState == STOPPING_1 &&
11928d6c292a0bed3d63b5b7297d09a604af6327c663Krishnankutty Kolathappilly        mResumeToStopping)
11938d6c292a0bed3d63b5b7297d09a604af6327c663Krishnankutty Kolathappilly        return true;
11948d6c292a0bed3d63b5b7297d09a604af6327c663Krishnankutty Kolathappilly
11958d6c292a0bed3d63b5b7297d09a604af6327c663Krishnankutty Kolathappilly    return false;
11968d6c292a0bed3d63b5b7297d09a604af6327c663Krishnankutty Kolathappilly}
11978d6c292a0bed3d63b5b7297d09a604af6327c663Krishnankutty Kolathappilly
11988d6c292a0bed3d63b5b7297d09a604af6327c663Krishnankutty Kolathappilly//To be called with thread lock held
11998d6c292a0bed3d63b5b7297d09a604af6327c663Krishnankutty Kolathappillyvoid AudioFlinger::PlaybackThread::Track::resumeAck() {
12008d6c292a0bed3d63b5b7297d09a604af6327c663Krishnankutty Kolathappilly
12018d6c292a0bed3d63b5b7297d09a604af6327c663Krishnankutty Kolathappilly
12028d6c292a0bed3d63b5b7297d09a604af6327c663Krishnankutty Kolathappilly    if (mState == RESUMING)
12038d6c292a0bed3d63b5b7297d09a604af6327c663Krishnankutty Kolathappilly        mState = ACTIVE;
12042d3ca68363f723fbe269d3ce52dab4985dfc7154Haynes Mathew George
12058d6c292a0bed3d63b5b7297d09a604af6327c663Krishnankutty Kolathappilly    // Other possibility of  pending resume is stopping_1 state
12068d6c292a0bed3d63b5b7297d09a604af6327c663Krishnankutty Kolathappilly    // Do not update the state from stopping as this prevents
12072d3ca68363f723fbe269d3ce52dab4985dfc7154Haynes Mathew George    // drain being called.
12082d3ca68363f723fbe269d3ce52dab4985dfc7154Haynes Mathew George    if (mState == STOPPING_1) {
12092d3ca68363f723fbe269d3ce52dab4985dfc7154Haynes Mathew George        mResumeToStopping = false;
12102d3ca68363f723fbe269d3ce52dab4985dfc7154Haynes Mathew George    }
12118d6c292a0bed3d63b5b7297d09a604af6327c663Krishnankutty Kolathappilly}
1212e10393e72454bfd8298017dc193faf424f4e9a8fAndy Hung
1213e10393e72454bfd8298017dc193faf424f4e9a8fAndy Hung//To be called with thread lock held
1214e10393e72454bfd8298017dc193faf424f4e9a8fAndy Hungvoid AudioFlinger::PlaybackThread::Track::updateTrackFrameInfo(
1215818e7a32ce3633980138aff2c2bfcc5158b3cfccAndy Hung        int64_t trackFramesReleased, int64_t sinkFramesWritten,
1216818e7a32ce3633980138aff2c2bfcc5158b3cfccAndy Hung        const ExtendedTimestamp &timeStamp) {
1217818e7a32ce3633980138aff2c2bfcc5158b3cfccAndy Hung    //update frame map
1218e10393e72454bfd8298017dc193faf424f4e9a8fAndy Hung    mFrameMap.push(trackFramesReleased, sinkFramesWritten);
1219818e7a32ce3633980138aff2c2bfcc5158b3cfccAndy Hung
1220818e7a32ce3633980138aff2c2bfcc5158b3cfccAndy Hung    // adjust server times and set drained state.
1221818e7a32ce3633980138aff2c2bfcc5158b3cfccAndy Hung    //
1222818e7a32ce3633980138aff2c2bfcc5158b3cfccAndy Hung    // Our timestamps are only updated when the track is on the Thread active list.
1223818e7a32ce3633980138aff2c2bfcc5158b3cfccAndy Hung    // We need to ensure that tracks are not removed before full drain.
1224818e7a32ce3633980138aff2c2bfcc5158b3cfccAndy Hung    ExtendedTimestamp local = timeStamp;
1225818e7a32ce3633980138aff2c2bfcc5158b3cfccAndy Hung    bool checked = false;
1226818e7a32ce3633980138aff2c2bfcc5158b3cfccAndy Hung    for (int i = ExtendedTimestamp::LOCATION_MAX - 1;
1227818e7a32ce3633980138aff2c2bfcc5158b3cfccAndy Hung            i >= ExtendedTimestamp::LOCATION_SERVER; --i) {
1228818e7a32ce3633980138aff2c2bfcc5158b3cfccAndy Hung        // Lookup the track frame corresponding to the sink frame position.
1229818e7a32ce3633980138aff2c2bfcc5158b3cfccAndy Hung        if (local.mTimeNs[i] > 0) {
1230818e7a32ce3633980138aff2c2bfcc5158b3cfccAndy Hung            local.mPosition[i] = mFrameMap.findX(local.mPosition[i]);
1231818e7a32ce3633980138aff2c2bfcc5158b3cfccAndy Hung            // check drain state from the latest stage in the pipeline.
12326d7b119a416c9f10288051e562f294365e5d954cAndy Hung            if (!checked && i <= ExtendedTimestamp::LOCATION_KERNEL) {
1233818e7a32ce3633980138aff2c2bfcc5158b3cfccAndy Hung                mAudioTrackServerProxy->setDrained(
1234818e7a32ce3633980138aff2c2bfcc5158b3cfccAndy Hung                        local.mPosition[i] >= mAudioTrackServerProxy->framesReleased());
1235818e7a32ce3633980138aff2c2bfcc5158b3cfccAndy Hung                checked = true;
1236818e7a32ce3633980138aff2c2bfcc5158b3cfccAndy Hung            }
1237818e7a32ce3633980138aff2c2bfcc5158b3cfccAndy Hung        }
1238818e7a32ce3633980138aff2c2bfcc5158b3cfccAndy Hung    }
1239818e7a32ce3633980138aff2c2bfcc5158b3cfccAndy Hung    if (!checked) { // no server info, assume drained.
1240818e7a32ce3633980138aff2c2bfcc5158b3cfccAndy Hung        mAudioTrackServerProxy->setDrained(true);
1241e10393e72454bfd8298017dc193faf424f4e9a8fAndy Hung    }
1242ea2b9c07b34079f0dbd8610a511e006e69a15adcAndy Hung    // Set correction for flushed frames that are not accounted for in released.
1243ea2b9c07b34079f0dbd8610a511e006e69a15adcAndy Hung    local.mFlushed = mAudioTrackServerProxy->framesFlushed();
1244818e7a32ce3633980138aff2c2bfcc5158b3cfccAndy Hung    mServerProxy->setTimestamp(local);
1245e10393e72454bfd8298017dc193faf424f4e9a8fAndy Hung}
1246e10393e72454bfd8298017dc193faf424f4e9a8fAndy Hung
124781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// ----------------------------------------------------------------------------
124881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
124981784c37c61b09289654b979567a42bf73cd2b12Eric LaurentAudioFlinger::PlaybackThread::OutputTrack::OutputTrack(
125081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            PlaybackThread *playbackThread,
125181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            DuplicatingThread *sourceThread,
125281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            uint32_t sampleRate,
125381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            audio_format_t format,
125481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            audio_channel_mask_t channelMask,
1255462fd2fa9eef642b0574aa7409de0bde3fec8d43Marco Nelissen            size_t frameCount,
12561f12a8ad958344c50733b948628ffa06db9c5bc6Andy Hung            uid_t uid)
1257223fd5c9738e9665e495904d37d4632414b68c1eEric Laurent    :   Track(playbackThread, NULL, AUDIO_STREAM_PATCH,
1258223fd5c9738e9665e495904d37d4632414b68c1eEric Laurent              sampleRate, format, channelMask, frameCount,
12598fe68036c2a670abb9eb0cc67ab9830c2c23de81Andy Hung              nullptr /* buffer */, (size_t)0 /* bufferSize */, nullptr /* sharedBuffer */,
12608fe68036c2a670abb9eb0cc67ab9830c2c23de81Andy Hung              AUDIO_SESSION_NONE, uid, AUDIO_OUTPUT_FLAG_NONE,
1261d848eb48c121c119e8ba7583efc75415fe102570Glenn Kasten              TYPE_OUTPUT),
12625bba2f6916dbe00aea7c0521faa0c6ed42114a75Eric Laurent    mActive(false), mSourceThread(sourceThread)
126381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{
126481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
126581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    if (mCblk != NULL) {
126681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        mOutBuffer.frameCount = 0;
126781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        playbackThread->mTracks.add(this);
1268e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten        ALOGV("OutputTrack constructor mCblk %p, mBuffer %p, "
1269c42e9b462661673dff480ee71757a58b0f806370Glenn Kasten                "frameCount %zu, mChannelMask 0x%08x",
1270e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten                mCblk, mBuffer,
127174935e44734c1ec235c2b6677db3e0dbefa5ddb8Glenn Kasten                frameCount, mChannelMask);
1272e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten        // since client and server are in the same process,
1273e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten        // the buffer has the same virtual address on both sides
1274529c61b7e4468a3e21f302f2a92a660249daa722Glenn Kasten        mClientProxy = new AudioTrackClientProxy(mCblk, mBuffer, mFrameCount, mFrameSize,
1275529c61b7e4468a3e21f302f2a92a660249daa722Glenn Kasten                true /*clientInServer*/);
1276c56f3426099a3cf2d07ccff8886050c7fbce140fGlenn Kasten        mClientProxy->setVolumeLR(GAIN_MINIFLOAT_PACKED_UNITY);
12778d2d4932b96632e9eb3af4a3d4000192ef603960Eric Laurent        mClientProxy->setSendLevel(0.0);
12788d2d4932b96632e9eb3af4a3d4000192ef603960Eric Laurent        mClientProxy->setSampleRate(sampleRate);
127981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    } else {
128081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        ALOGW("Error creating output track on thread %p", playbackThread);
128181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    }
128281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
128381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
128481784c37c61b09289654b979567a42bf73cd2b12Eric LaurentAudioFlinger::PlaybackThread::OutputTrack::~OutputTrack()
128581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{
128681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    clearBufferQueue();
1287e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten    // superclass destructor will now delete the server proxy and shared memory both refer to
128881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
128981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
129081784c37c61b09289654b979567a42bf73cd2b12Eric Laurentstatus_t AudioFlinger::PlaybackThread::OutputTrack::start(AudioSystem::sync_event_t event,
1291d848eb48c121c119e8ba7583efc75415fe102570Glenn Kasten                                                          audio_session_t triggerSession)
129281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{
129381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    status_t status = Track::start(event, triggerSession);
129481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    if (status != NO_ERROR) {
129581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        return status;
129681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    }
129781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
129881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    mActive = true;
129981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    mRetryCount = 127;
130081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    return status;
130181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
130281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
130381784c37c61b09289654b979567a42bf73cd2b12Eric Laurentvoid AudioFlinger::PlaybackThread::OutputTrack::stop()
130481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{
130581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    Track::stop();
130681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    clearBufferQueue();
130781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    mOutBuffer.frameCount = 0;
130881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    mActive = false;
130981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
131081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
1311c25b84abdd7ff229d0af663fbf3a37bd9512939dAndy Hungbool AudioFlinger::PlaybackThread::OutputTrack::write(void* data, uint32_t frames)
131281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{
131381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    Buffer *pInBuffer;
131481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    Buffer inBuffer;
131581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    bool outputBufferFull = false;
131681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    inBuffer.frameCount = frames;
1317c25b84abdd7ff229d0af663fbf3a37bd9512939dAndy Hung    inBuffer.raw = data;
131881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
131981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    uint32_t waitTimeLeftMs = mSourceThread->waitTimeMs();
132081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
132181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    if (!mActive && frames != 0) {
13225bedff60b2facaa1ec5b9433647ebf1504f065caAndy Hung        (void) start();
132381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    }
132481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
132581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    while (waitTimeLeftMs) {
132681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        // First write pending buffers, then new data
132781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        if (mBufferQueue.size()) {
132881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            pInBuffer = mBufferQueue.itemAt(0);
132981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        } else {
133081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            pInBuffer = &inBuffer;
133181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        }
133281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
133381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        if (pInBuffer->frameCount == 0) {
133481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            break;
133581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        }
133681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
133781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        if (mOutBuffer.frameCount == 0) {
133881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            mOutBuffer.frameCount = pInBuffer->frameCount;
133981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            nsecs_t startTime = systemTime();
13409f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten            status_t status = obtainBuffer(&mOutBuffer, waitTimeLeftMs);
13414d231dc0ee34380956c71cbe18a750e487a69601Eric Laurent            if (status != NO_ERROR && status != NOT_ENOUGH_DATA) {
13429f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten                ALOGV("OutputTrack::write() %p thread %p no more output buffers; status %d", this,
13439f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten                        mThread.unsafe_get(), status);
134481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                outputBufferFull = true;
134581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                break;
134681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            }
134781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            uint32_t waitTimeMs = (uint32_t)ns2ms(systemTime() - startTime);
134881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            if (waitTimeLeftMs >= waitTimeMs) {
134981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                waitTimeLeftMs -= waitTimeMs;
135081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            } else {
135181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                waitTimeLeftMs = 0;
135281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            }
13534d231dc0ee34380956c71cbe18a750e487a69601Eric Laurent            if (status == NOT_ENOUGH_DATA) {
13544d231dc0ee34380956c71cbe18a750e487a69601Eric Laurent                restartIfDisabled();
13554d231dc0ee34380956c71cbe18a750e487a69601Eric Laurent                continue;
13564d231dc0ee34380956c71cbe18a750e487a69601Eric Laurent            }
135781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        }
135881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
135981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        uint32_t outFrames = pInBuffer->frameCount > mOutBuffer.frameCount ? mOutBuffer.frameCount :
136081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                pInBuffer->frameCount;
1361c25b84abdd7ff229d0af663fbf3a37bd9512939dAndy Hung        memcpy(mOutBuffer.raw, pInBuffer->raw, outFrames * mFrameSize);
13629f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten        Proxy::Buffer buf;
13639f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten        buf.mFrameCount = outFrames;
13649f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten        buf.mRaw = NULL;
13659f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten        mClientProxy->releaseBuffer(&buf);
13664d231dc0ee34380956c71cbe18a750e487a69601Eric Laurent        restartIfDisabled();
136781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        pInBuffer->frameCount -= outFrames;
1368c25b84abdd7ff229d0af663fbf3a37bd9512939dAndy Hung        pInBuffer->raw = (int8_t *)pInBuffer->raw + outFrames * mFrameSize;
136981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        mOutBuffer.frameCount -= outFrames;
1370c25b84abdd7ff229d0af663fbf3a37bd9512939dAndy Hung        mOutBuffer.raw = (int8_t *)mOutBuffer.raw + outFrames * mFrameSize;
137181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
137281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        if (pInBuffer->frameCount == 0) {
137381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            if (mBufferQueue.size()) {
137481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                mBufferQueue.removeAt(0);
1375c25b84abdd7ff229d0af663fbf3a37bd9512939dAndy Hung                free(pInBuffer->mBuffer);
13768adc80866b6cc1bb6be62c1998dd424f1f339deaYunlian Jiang                if (pInBuffer != &inBuffer) {
13778adc80866b6cc1bb6be62c1998dd424f1f339deaYunlian Jiang                    delete pInBuffer;
13788adc80866b6cc1bb6be62c1998dd424f1f339deaYunlian Jiang                }
1379c42e9b462661673dff480ee71757a58b0f806370Glenn Kasten                ALOGV("OutputTrack::write() %p thread %p released overflow buffer %zu", this,
138081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                        mThread.unsafe_get(), mBufferQueue.size());
138181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            } else {
138281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                break;
138381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            }
138481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        }
138581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    }
138681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
138781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    // If we could not write all frames, allocate a buffer and queue it for next time.
138881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    if (inBuffer.frameCount) {
138981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        sp<ThreadBase> thread = mThread.promote();
139081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        if (thread != 0 && !thread->standby()) {
139181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            if (mBufferQueue.size() < kMaxOverFlowBuffers) {
139281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                pInBuffer = new Buffer;
1393c25b84abdd7ff229d0af663fbf3a37bd9512939dAndy Hung                pInBuffer->mBuffer = malloc(inBuffer.frameCount * mFrameSize);
139481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                pInBuffer->frameCount = inBuffer.frameCount;
1395c25b84abdd7ff229d0af663fbf3a37bd9512939dAndy Hung                pInBuffer->raw = pInBuffer->mBuffer;
1396c25b84abdd7ff229d0af663fbf3a37bd9512939dAndy Hung                memcpy(pInBuffer->raw, inBuffer.raw, inBuffer.frameCount * mFrameSize);
139781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                mBufferQueue.add(pInBuffer);
1398c42e9b462661673dff480ee71757a58b0f806370Glenn Kasten                ALOGV("OutputTrack::write() %p thread %p adding overflow buffer %zu", this,
139981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                        mThread.unsafe_get(), mBufferQueue.size());
140081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            } else {
140181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                ALOGW("OutputTrack::write() %p thread %p no more overflow buffers",
140281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent                        mThread.unsafe_get(), this);
140381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            }
140481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        }
140581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    }
140681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
1407c25b84abdd7ff229d0af663fbf3a37bd9512939dAndy Hung    // Calling write() with a 0 length buffer means that no more data will be written:
1408c25b84abdd7ff229d0af663fbf3a37bd9512939dAndy Hung    // We rely on stop() to set the appropriate flags to allow the remaining frames to play out.
1409c25b84abdd7ff229d0af663fbf3a37bd9512939dAndy Hung    if (frames == 0 && mBufferQueue.size() == 0 && mActive) {
1410c25b84abdd7ff229d0af663fbf3a37bd9512939dAndy Hung        stop();
141181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    }
141281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
141381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    return outputBufferFull;
141481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
141581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
141681784c37c61b09289654b979567a42bf73cd2b12Eric Laurentstatus_t AudioFlinger::PlaybackThread::OutputTrack::obtainBuffer(
141781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        AudioBufferProvider::Buffer* buffer, uint32_t waitTimeMs)
141881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{
14199f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    ClientProxy::Buffer buf;
14209f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    buf.mFrameCount = buffer->frameCount;
14219f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    struct timespec timeout;
14229f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    timeout.tv_sec = waitTimeMs / 1000;
14239f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    timeout.tv_nsec = (int) (waitTimeMs % 1000) * 1000000;
14249f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    status_t status = mClientProxy->obtainBuffer(&buf, &timeout);
14259f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    buffer->frameCount = buf.mFrameCount;
14269f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    buffer->raw = buf.mRaw;
14279f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    return status;
142881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
142981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
143081784c37c61b09289654b979567a42bf73cd2b12Eric Laurentvoid AudioFlinger::PlaybackThread::OutputTrack::clearBufferQueue()
143181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{
143281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    size_t size = mBufferQueue.size();
143381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
143481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    for (size_t i = 0; i < size; i++) {
143581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        Buffer *pBuffer = mBufferQueue.itemAt(i);
1436c25b84abdd7ff229d0af663fbf3a37bd9512939dAndy Hung        free(pBuffer->mBuffer);
143781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        delete pBuffer;
143881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    }
143981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    mBufferQueue.clear();
144081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
144181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
14424d231dc0ee34380956c71cbe18a750e487a69601Eric Laurentvoid AudioFlinger::PlaybackThread::OutputTrack::restartIfDisabled()
14434d231dc0ee34380956c71cbe18a750e487a69601Eric Laurent{
14444d231dc0ee34380956c71cbe18a750e487a69601Eric Laurent    int32_t flags = android_atomic_and(~CBLK_DISABLED, &mCblk->mFlags);
14454d231dc0ee34380956c71cbe18a750e487a69601Eric Laurent    if (mActive && (flags & CBLK_DISABLED)) {
14464d231dc0ee34380956c71cbe18a750e487a69601Eric Laurent        start();
14474d231dc0ee34380956c71cbe18a750e487a69601Eric Laurent    }
14484d231dc0ee34380956c71cbe18a750e487a69601Eric Laurent}
144981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
145083b8808faad1e91690c64d7007348be8d9ebde73Eric LaurentAudioFlinger::PlaybackThread::PatchTrack::PatchTrack(PlaybackThread *playbackThread,
14513bcf8597189c592713675ec58326ecbef0ac4ae9Eric Laurent                                                     audio_stream_type_t streamType,
145283b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent                                                     uint32_t sampleRate,
145383b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent                                                     audio_channel_mask_t channelMask,
145483b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent                                                     audio_format_t format,
145583b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent                                                     size_t frameCount,
145683b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent                                                     void *buffer,
14578fe68036c2a670abb9eb0cc67ab9830c2c23de81Andy Hung                                                     size_t bufferSize,
1458050677873c10d4da308ac222f8533c96cca3207eEric Laurent                                                     audio_output_flags_t flags)
14593bcf8597189c592713675ec58326ecbef0ac4ae9Eric Laurent    :   Track(playbackThread, NULL, streamType,
1460223fd5c9738e9665e495904d37d4632414b68c1eEric Laurent              sampleRate, format, channelMask, frameCount,
14618fe68036c2a670abb9eb0cc67ab9830c2c23de81Andy Hung              buffer, bufferSize, nullptr /* sharedBuffer */,
14628fe68036c2a670abb9eb0cc67ab9830c2c23de81Andy Hung              AUDIO_SESSION_NONE, getuid(), flags, TYPE_PATCH),
146383b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent              mProxy(new ClientProxy(mCblk, mBuffer, frameCount, mFrameSize, true, true))
146483b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent{
146583b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent    uint64_t mixBufferNs = ((uint64_t)2 * playbackThread->frameCount() * 1000000000) /
146683b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent                                                                    playbackThread->sampleRate();
146783b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent    mPeerTimeout.tv_sec = mixBufferNs / 1000000000;
146883b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent    mPeerTimeout.tv_nsec = (int) (mixBufferNs % 1000000000);
146983b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent
147083b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent    ALOGV("PatchTrack %p sampleRate %d mPeerTimeout %d.%03d sec",
147183b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent                                      this, sampleRate,
147283b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent                                      (int)mPeerTimeout.tv_sec,
147383b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent                                      (int)(mPeerTimeout.tv_nsec / 1000000));
147483b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent}
147583b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent
147683b8808faad1e91690c64d7007348be8d9ebde73Eric LaurentAudioFlinger::PlaybackThread::PatchTrack::~PatchTrack()
147783b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent{
147883b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent}
147983b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent
14804d231dc0ee34380956c71cbe18a750e487a69601Eric Laurentstatus_t AudioFlinger::PlaybackThread::PatchTrack::start(AudioSystem::sync_event_t event,
1481d848eb48c121c119e8ba7583efc75415fe102570Glenn Kasten                                                          audio_session_t triggerSession)
14824d231dc0ee34380956c71cbe18a750e487a69601Eric Laurent{
14834d231dc0ee34380956c71cbe18a750e487a69601Eric Laurent    status_t status = Track::start(event, triggerSession);
14844d231dc0ee34380956c71cbe18a750e487a69601Eric Laurent    if (status != NO_ERROR) {
14854d231dc0ee34380956c71cbe18a750e487a69601Eric Laurent        return status;
14864d231dc0ee34380956c71cbe18a750e487a69601Eric Laurent    }
14874d231dc0ee34380956c71cbe18a750e487a69601Eric Laurent    android_atomic_and(~CBLK_DISABLED, &mCblk->mFlags);
14884d231dc0ee34380956c71cbe18a750e487a69601Eric Laurent    return status;
14894d231dc0ee34380956c71cbe18a750e487a69601Eric Laurent}
14904d231dc0ee34380956c71cbe18a750e487a69601Eric Laurent
149183b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent// AudioBufferProvider interface
149283b8808faad1e91690c64d7007348be8d9ebde73Eric Laurentstatus_t AudioFlinger::PlaybackThread::PatchTrack::getNextBuffer(
1493d79072e9dff59f767cce2cda1caab80ce5a0815bGlenn Kasten        AudioBufferProvider::Buffer* buffer)
149483b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent{
149583b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent    ALOG_ASSERT(mPeerProxy != 0, "PatchTrack::getNextBuffer() called without peer proxy");
149683b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent    Proxy::Buffer buf;
149783b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent    buf.mFrameCount = buffer->frameCount;
149883b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent    status_t status = mPeerProxy->obtainBuffer(&buf, &mPeerTimeout);
149983b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent    ALOGV_IF(status != NO_ERROR, "PatchTrack() %p getNextBuffer status %d", this, status);
1500c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent    buffer->frameCount = buf.mFrameCount;
150183b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent    if (buf.mFrameCount == 0) {
150283b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent        return WOULD_BLOCK;
150383b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent    }
1504d79072e9dff59f767cce2cda1caab80ce5a0815bGlenn Kasten    status = Track::getNextBuffer(buffer);
150583b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent    return status;
150683b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent}
150783b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent
150883b8808faad1e91690c64d7007348be8d9ebde73Eric Laurentvoid AudioFlinger::PlaybackThread::PatchTrack::releaseBuffer(AudioBufferProvider::Buffer* buffer)
150983b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent{
151083b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent    ALOG_ASSERT(mPeerProxy != 0, "PatchTrack::releaseBuffer() called without peer proxy");
151183b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent    Proxy::Buffer buf;
151283b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent    buf.mFrameCount = buffer->frameCount;
151383b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent    buf.mRaw = buffer->raw;
151483b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent    mPeerProxy->releaseBuffer(&buf);
151583b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent    TrackBase::releaseBuffer(buffer);
151683b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent}
151783b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent
151883b8808faad1e91690c64d7007348be8d9ebde73Eric Laurentstatus_t AudioFlinger::PlaybackThread::PatchTrack::obtainBuffer(Proxy::Buffer* buffer,
151983b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent                                                                const struct timespec *timeOut)
152083b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent{
15214d231dc0ee34380956c71cbe18a750e487a69601Eric Laurent    status_t status = NO_ERROR;
15224d231dc0ee34380956c71cbe18a750e487a69601Eric Laurent    static const int32_t kMaxTries = 5;
15234d231dc0ee34380956c71cbe18a750e487a69601Eric Laurent    int32_t tryCounter = kMaxTries;
15244d231dc0ee34380956c71cbe18a750e487a69601Eric Laurent    do {
15254d231dc0ee34380956c71cbe18a750e487a69601Eric Laurent        if (status == NOT_ENOUGH_DATA) {
15264d231dc0ee34380956c71cbe18a750e487a69601Eric Laurent            restartIfDisabled();
15274d231dc0ee34380956c71cbe18a750e487a69601Eric Laurent        }
15284d231dc0ee34380956c71cbe18a750e487a69601Eric Laurent        status = mProxy->obtainBuffer(buffer, timeOut);
15294d231dc0ee34380956c71cbe18a750e487a69601Eric Laurent    } while ((status == NOT_ENOUGH_DATA) && (tryCounter-- > 0));
15304d231dc0ee34380956c71cbe18a750e487a69601Eric Laurent    return status;
153183b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent}
153283b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent
153383b8808faad1e91690c64d7007348be8d9ebde73Eric Laurentvoid AudioFlinger::PlaybackThread::PatchTrack::releaseBuffer(Proxy::Buffer* buffer)
153483b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent{
153583b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent    mProxy->releaseBuffer(buffer);
15364d231dc0ee34380956c71cbe18a750e487a69601Eric Laurent    restartIfDisabled();
15374d231dc0ee34380956c71cbe18a750e487a69601Eric Laurent    android_atomic_or(CBLK_FORCEREADY, &mCblk->mFlags);
15384d231dc0ee34380956c71cbe18a750e487a69601Eric Laurent}
15394d231dc0ee34380956c71cbe18a750e487a69601Eric Laurent
15404d231dc0ee34380956c71cbe18a750e487a69601Eric Laurentvoid AudioFlinger::PlaybackThread::PatchTrack::restartIfDisabled()
15414d231dc0ee34380956c71cbe18a750e487a69601Eric Laurent{
154283b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent    if (android_atomic_and(~CBLK_DISABLED, &mCblk->mFlags) & CBLK_DISABLED) {
154383b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent        ALOGW("PatchTrack::releaseBuffer() disabled due to previous underrun, restarting");
154483b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent        start();
154583b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent    }
154683b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent}
154783b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent
154881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// ----------------------------------------------------------------------------
154981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent//      Record
155081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// ----------------------------------------------------------------------------
155181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
155281784c37c61b09289654b979567a42bf73cd2b12Eric LaurentAudioFlinger::RecordHandle::RecordHandle(
155381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        const sp<AudioFlinger::RecordThread::RecordTrack>& recordTrack)
155481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    : BnAudioRecord(),
155581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    mRecordTrack(recordTrack)
155681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{
155781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
155881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
155981784c37c61b09289654b979567a42bf73cd2b12Eric LaurentAudioFlinger::RecordHandle::~RecordHandle() {
156081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    stop_nonvirtual();
156181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    mRecordTrack->destroy();
156281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
156381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
156481784c37c61b09289654b979567a42bf73cd2b12Eric Laurentstatus_t AudioFlinger::RecordHandle::start(int /*AudioSystem::sync_event_t*/ event,
1565d848eb48c121c119e8ba7583efc75415fe102570Glenn Kasten        audio_session_t triggerSession) {
156681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    ALOGV("RecordHandle::start()");
156781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    return mRecordTrack->start((AudioSystem::sync_event_t)event, triggerSession);
156881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
156981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
157081784c37c61b09289654b979567a42bf73cd2b12Eric Laurentvoid AudioFlinger::RecordHandle::stop() {
157181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    stop_nonvirtual();
157281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
157381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
157481784c37c61b09289654b979567a42bf73cd2b12Eric Laurentvoid AudioFlinger::RecordHandle::stop_nonvirtual() {
157581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    ALOGV("RecordHandle::stop()");
157681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    mRecordTrack->stop();
157781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
157881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
157981784c37c61b09289654b979567a42bf73cd2b12Eric Laurentstatus_t AudioFlinger::RecordHandle::onTransact(
158081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
158181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{
158281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    return BnAudioRecord::onTransact(code, data, reply, flags);
158381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
158481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
158581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// ----------------------------------------------------------------------------
158681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
158705997e21af6c4517f375def6563af4b9ebe95f39Glenn Kasten// RecordTrack constructor must be called with AudioFlinger::mLock and ThreadBase::mLock held
158881784c37c61b09289654b979567a42bf73cd2b12Eric LaurentAudioFlinger::RecordThread::RecordTrack::RecordTrack(
158981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            RecordThread *thread,
159081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            const sp<Client>& client,
159181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            uint32_t sampleRate,
159281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            audio_format_t format,
159381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            audio_channel_mask_t channelMask,
159481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            size_t frameCount,
159583b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent            void *buffer,
15968fe68036c2a670abb9eb0cc67ab9830c2c23de81Andy Hung            size_t bufferSize,
1597d848eb48c121c119e8ba7583efc75415fe102570Glenn Kasten            audio_session_t sessionId,
15981f12a8ad958344c50733b948628ffa06db9c5bc6Andy Hung            uid_t uid,
1599050677873c10d4da308ac222f8533c96cca3207eEric Laurent            audio_input_flags_t flags,
160020b9ef0b55c9150ae11057ab997ae61be2d496efEric Laurent            track_type type,
160120b9ef0b55c9150ae11057ab997ae61be2d496efEric Laurent            audio_port_handle_t portId)
160281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    :   TrackBase(thread, client, sampleRate, format,
16038fe68036c2a670abb9eb0cc67ab9830c2c23de81Andy Hung                  channelMask, frameCount, buffer, bufferSize, sessionId, uid, false /*isOut*/,
160483b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent                  (type == TYPE_DEFAULT) ?
1605050677873c10d4da308ac222f8533c96cca3207eEric Laurent                          ((flags & AUDIO_INPUT_FLAG_FAST) ? ALLOC_PIPE : ALLOC_CBLK) :
160683b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent                          ((buffer == NULL) ? ALLOC_LOCAL : ALLOC_NONE),
160720b9ef0b55c9150ae11057ab997ae61be2d496efEric Laurent                  type, portId),
160897a893eb34f8687485c88eaf15917974a203f20bAndy Hung        mOverflow(false),
16094c6afaf1053ecbfda6d95098e0f49772ecbcf2e1Andy Hung        mFramesToDrop(0),
16104c6afaf1053ecbfda6d95098e0f49772ecbcf2e1Andy Hung        mResamplerBufferProvider(NULL), // initialize in case of early constructor exit
1611050677873c10d4da308ac222f8533c96cca3207eEric Laurent        mRecordBufferConverter(NULL),
1612050677873c10d4da308ac222f8533c96cca3207eEric Laurent        mFlags(flags)
161381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{
16143ef14ef30359376006a233f6a21a165d4b65a7dfGlenn Kasten    if (mCblk == NULL) {
16153ef14ef30359376006a233f6a21a165d4b65a7dfGlenn Kasten        return;
16169f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    }
16176dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten
161897a893eb34f8687485c88eaf15917974a203f20bAndy Hung    mRecordBufferConverter = new RecordBufferConverter(
161997a893eb34f8687485c88eaf15917974a203f20bAndy Hung            thread->mChannelMask, thread->mFormat, thread->mSampleRate,
162097a893eb34f8687485c88eaf15917974a203f20bAndy Hung            channelMask, format, sampleRate);
162197a893eb34f8687485c88eaf15917974a203f20bAndy Hung    // Check if the RecordBufferConverter construction was successful.
162297a893eb34f8687485c88eaf15917974a203f20bAndy Hung    // If not, don't continue with construction.
162397a893eb34f8687485c88eaf15917974a203f20bAndy Hung    //
162497a893eb34f8687485c88eaf15917974a203f20bAndy Hung    // NOTE: It would be extremely rare that the record track cannot be created
162597a893eb34f8687485c88eaf15917974a203f20bAndy Hung    // for the current device, but a pending or future device change would make
162697a893eb34f8687485c88eaf15917974a203f20bAndy Hung    // the record track configuration valid.
162797a893eb34f8687485c88eaf15917974a203f20bAndy Hung    if (mRecordBufferConverter->initCheck() != NO_ERROR) {
162897a893eb34f8687485c88eaf15917974a203f20bAndy Hung        ALOGE("RecordTrack unable to create record buffer converter");
162997a893eb34f8687485c88eaf15917974a203f20bAndy Hung        return;
163097a893eb34f8687485c88eaf15917974a203f20bAndy Hung    }
163197a893eb34f8687485c88eaf15917974a203f20bAndy Hung
16326ae5843c281301a9ffd1059d185620a9337e15a2Andy Hung    mServerProxy = new AudioRecordServerProxy(mCblk, mBuffer, frameCount,
16333f0c902beb53a245c9db35e871607dba05b8d391Andy Hung            mFrameSize, !isExternalTrack());
16343f0c902beb53a245c9db35e871607dba05b8d391Andy Hung
163597a893eb34f8687485c88eaf15917974a203f20bAndy Hung    mResamplerBufferProvider = new ResamplerBufferProvider(this);
1636c263ca0ad8b6bdf5b0693996bc5f2f5916e0cd49Glenn Kasten
1637050677873c10d4da308ac222f8533c96cca3207eEric Laurent    if (flags & AUDIO_INPUT_FLAG_FAST) {
1638c263ca0ad8b6bdf5b0693996bc5f2f5916e0cd49Glenn Kasten        ALOG_ASSERT(thread->mFastTrackAvail);
1639c263ca0ad8b6bdf5b0693996bc5f2f5916e0cd49Glenn Kasten        thread->mFastTrackAvail = false;
1640c263ca0ad8b6bdf5b0693996bc5f2f5916e0cd49Glenn Kasten    }
164181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
164281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
164381784c37c61b09289654b979567a42bf73cd2b12Eric LaurentAudioFlinger::RecordThread::RecordTrack::~RecordTrack()
164481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{
164581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    ALOGV("%s", __func__);
164697a893eb34f8687485c88eaf15917974a203f20bAndy Hung    delete mRecordBufferConverter;
16476dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten    delete mResamplerBufferProvider;
164881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
164981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
165097a893eb34f8687485c88eaf15917974a203f20bAndy Hungstatus_t AudioFlinger::RecordThread::RecordTrack::initCheck() const
165197a893eb34f8687485c88eaf15917974a203f20bAndy Hung{
165297a893eb34f8687485c88eaf15917974a203f20bAndy Hung    status_t status = TrackBase::initCheck();
165397a893eb34f8687485c88eaf15917974a203f20bAndy Hung    if (status == NO_ERROR && mServerProxy == 0) {
165497a893eb34f8687485c88eaf15917974a203f20bAndy Hung        status = BAD_VALUE;
165597a893eb34f8687485c88eaf15917974a203f20bAndy Hung    }
165697a893eb34f8687485c88eaf15917974a203f20bAndy Hung    return status;
165797a893eb34f8687485c88eaf15917974a203f20bAndy Hung}
165897a893eb34f8687485c88eaf15917974a203f20bAndy Hung
165981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// AudioBufferProvider interface
1660d79072e9dff59f767cce2cda1caab80ce5a0815bGlenn Kastenstatus_t AudioFlinger::RecordThread::RecordTrack::getNextBuffer(AudioBufferProvider::Buffer* buffer)
166181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{
16629f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    ServerProxy::Buffer buf;
16639f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    buf.mFrameCount = buffer->frameCount;
16649f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    status_t status = mServerProxy->obtainBuffer(&buf);
16659f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    buffer->frameCount = buf.mFrameCount;
16669f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    buffer->raw = buf.mRaw;
16679f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    if (buf.mFrameCount == 0) {
16689f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten        // FIXME also wake futex so that overrun is noticed more quickly
166996f60d8f04432a1ed503b3e24d5736d28c63c9a2Glenn Kasten        (void) android_atomic_or(CBLK_OVERRUN, &mCblk->mFlags);
167081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    }
16719f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten    return status;
167281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
167381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
167481784c37c61b09289654b979567a42bf73cd2b12Eric Laurentstatus_t AudioFlinger::RecordThread::RecordTrack::start(AudioSystem::sync_event_t event,
1675d848eb48c121c119e8ba7583efc75415fe102570Glenn Kasten                                                        audio_session_t triggerSession)
167681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{
167781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    sp<ThreadBase> thread = mThread.promote();
167881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    if (thread != 0) {
167981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        RecordThread *recordThread = (RecordThread *)thread.get();
168081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        return recordThread->start(this, event, triggerSession);
168181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    } else {
168281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        return BAD_VALUE;
168381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    }
168481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
168581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
168681784c37c61b09289654b979567a42bf73cd2b12Eric Laurentvoid AudioFlinger::RecordThread::RecordTrack::stop()
168781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{
168881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    sp<ThreadBase> thread = mThread.promote();
168981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    if (thread != 0) {
169081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        RecordThread *recordThread = (RecordThread *)thread.get();
169183b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent        if (recordThread->stop(this) && isExternalTrack()) {
1692d848eb48c121c119e8ba7583efc75415fe102570Glenn Kasten            AudioSystem::stopInput(mThreadIoHandle, mSessionId);
169381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        }
169481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    }
169581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
169681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
169781784c37c61b09289654b979567a42bf73cd2b12Eric Laurentvoid AudioFlinger::RecordThread::RecordTrack::destroy()
169881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{
169981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    // see comments at AudioFlinger::PlaybackThread::Track::destroy()
170081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    sp<RecordTrack> keep(this);
170181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    {
1702aaa44478a373232d8416657035a9020f9c7aa7c3Eric Laurent        if (isExternalTrack()) {
1703aaa44478a373232d8416657035a9020f9c7aa7c3Eric Laurent            if (mState == ACTIVE || mState == RESUMING) {
1704d848eb48c121c119e8ba7583efc75415fe102570Glenn Kasten                AudioSystem::stopInput(mThreadIoHandle, mSessionId);
1705aaa44478a373232d8416657035a9020f9c7aa7c3Eric Laurent            }
1706d848eb48c121c119e8ba7583efc75415fe102570Glenn Kasten            AudioSystem::releaseInput(mThreadIoHandle, mSessionId);
1707aaa44478a373232d8416657035a9020f9c7aa7c3Eric Laurent        }
170881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        sp<ThreadBase> thread = mThread.promote();
170981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        if (thread != 0) {
171081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            Mutex::Autolock _l(thread->mLock);
171181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            RecordThread *recordThread = (RecordThread *) thread.get();
171281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            recordThread->destroyTrack_l(this);
171381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent        }
171481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent    }
171581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
171681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
17179a54bc27876acd5d8be5b1fc3dc46701fe76fbb3Eric Laurentvoid AudioFlinger::RecordThread::RecordTrack::invalidate()
17189a54bc27876acd5d8be5b1fc3dc46701fe76fbb3Eric Laurent{
17196acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent    TrackBase::invalidate();
17209a54bc27876acd5d8be5b1fc3dc46701fe76fbb3Eric Laurent    // FIXME should use proxy, and needs work
17219a54bc27876acd5d8be5b1fc3dc46701fe76fbb3Eric Laurent    audio_track_cblk_t* cblk = mCblk;
17229a54bc27876acd5d8be5b1fc3dc46701fe76fbb3Eric Laurent    android_atomic_or(CBLK_INVALID, &cblk->mFlags);
17239a54bc27876acd5d8be5b1fc3dc46701fe76fbb3Eric Laurent    android_atomic_release_store(0x40000000, &cblk->mFutex);
17249a54bc27876acd5d8be5b1fc3dc46701fe76fbb3Eric Laurent    // client is not in server, so FUTEX_WAKE is needed instead of FUTEX_WAKE_PRIVATE
1725ee499291404a192b059f2e04c5afc65aa6cdd74cElliott Hughes    (void) syscall(__NR_futex, &cblk->mFutex, FUTEX_WAKE, INT_MAX);
17269a54bc27876acd5d8be5b1fc3dc46701fe76fbb3Eric Laurent}
17279a54bc27876acd5d8be5b1fc3dc46701fe76fbb3Eric Laurent
172881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
172981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent/*static*/ void AudioFlinger::RecordThread::RecordTrack::appendDumpHeader(String8& result)
173081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{
17312c6c3bb76b2fa18ed3536331a1700250bd04c7ceAndy Hung    result.append("Active Client Session S  Flags   Format Chn mask  SRate   Server FrmCnt\n");
173281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
173381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
17342c6c3bb76b2fa18ed3536331a1700250bd04c7ceAndy Hungvoid AudioFlinger::RecordThread::RecordTrack::appendDump(String8& result, bool active)
173581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{
17362c6c3bb76b2fa18ed3536331a1700250bd04c7ceAndy Hung    result.appendFormat("%c%5s %6u %7u %2s 0x%03X "
17372c6c3bb76b2fa18ed3536331a1700250bd04c7ceAndy Hung            "%08X %08X %6u "
17382c6c3bb76b2fa18ed3536331a1700250bd04c7ceAndy Hung            "%08X %6zu\n",
17392c6c3bb76b2fa18ed3536331a1700250bd04c7ceAndy Hung            isFastTrack() ? 'F' : ' ',
1740b220884bf3129253cc5bc8d030bc475411ea4911Marco Nelissen            active ? "yes" : "no",
174181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            (mClient == 0) ? getpid_cached : mClient->pid(),
17422c6c3bb76b2fa18ed3536331a1700250bd04c7ceAndy Hung            mSessionId,
17432c6c3bb76b2fa18ed3536331a1700250bd04c7ceAndy Hung            getTrackStateString(),
17442c6c3bb76b2fa18ed3536331a1700250bd04c7ceAndy Hung            mCblk->mFlags,
17452c6c3bb76b2fa18ed3536331a1700250bd04c7ceAndy Hung
174681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            mFormat,
174781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent            mChannelMask,
17482c6c3bb76b2fa18ed3536331a1700250bd04c7ceAndy Hung            mSampleRate,
17496dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten
17502c6c3bb76b2fa18ed3536331a1700250bd04c7ceAndy Hung            mCblk->mServer,
17512c6c3bb76b2fa18ed3536331a1700250bd04c7ceAndy Hung            mFrameCount
17522c6c3bb76b2fa18ed3536331a1700250bd04c7ceAndy Hung            );
175381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}
175481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent
175525f4aa83efaa9179e65a20583a6d441de2c3ff3fGlenn Kastenvoid AudioFlinger::RecordThread::RecordTrack::handleSyncStartEvent(const sp<SyncEvent>& event)
175625f4aa83efaa9179e65a20583a6d441de2c3ff3fGlenn Kasten{
175725f4aa83efaa9179e65a20583a6d441de2c3ff3fGlenn Kasten    if (event == mSyncStartEvent) {
175825f4aa83efaa9179e65a20583a6d441de2c3ff3fGlenn Kasten        ssize_t framesToDrop = 0;
175925f4aa83efaa9179e65a20583a6d441de2c3ff3fGlenn Kasten        sp<ThreadBase> threadBase = mThread.promote();
176025f4aa83efaa9179e65a20583a6d441de2c3ff3fGlenn Kasten        if (threadBase != 0) {
176125f4aa83efaa9179e65a20583a6d441de2c3ff3fGlenn Kasten            // TODO: use actual buffer filling status instead of 2 buffers when info is available
176225f4aa83efaa9179e65a20583a6d441de2c3ff3fGlenn Kasten            // from audio HAL
176325f4aa83efaa9179e65a20583a6d441de2c3ff3fGlenn Kasten            framesToDrop = threadBase->mFrameCount * 2;
176425f4aa83efaa9179e65a20583a6d441de2c3ff3fGlenn Kasten        }
176525f4aa83efaa9179e65a20583a6d441de2c3ff3fGlenn Kasten        mFramesToDrop = framesToDrop;
176625f4aa83efaa9179e65a20583a6d441de2c3ff3fGlenn Kasten    }
176725f4aa83efaa9179e65a20583a6d441de2c3ff3fGlenn Kasten}
176825f4aa83efaa9179e65a20583a6d441de2c3ff3fGlenn Kasten
176925f4aa83efaa9179e65a20583a6d441de2c3ff3fGlenn Kastenvoid AudioFlinger::RecordThread::RecordTrack::clearSyncStartEvent()
177025f4aa83efaa9179e65a20583a6d441de2c3ff3fGlenn Kasten{
177125f4aa83efaa9179e65a20583a6d441de2c3ff3fGlenn Kasten    if (mSyncStartEvent != 0) {
177225f4aa83efaa9179e65a20583a6d441de2c3ff3fGlenn Kasten        mSyncStartEvent->cancel();
177325f4aa83efaa9179e65a20583a6d441de2c3ff3fGlenn Kasten        mSyncStartEvent.clear();
177425f4aa83efaa9179e65a20583a6d441de2c3ff3fGlenn Kasten    }
177525f4aa83efaa9179e65a20583a6d441de2c3ff3fGlenn Kasten    mFramesToDrop = 0;
177625f4aa83efaa9179e65a20583a6d441de2c3ff3fGlenn Kasten}
177725f4aa83efaa9179e65a20583a6d441de2c3ff3fGlenn Kasten
17783f0c902beb53a245c9db35e871607dba05b8d391Andy Hungvoid AudioFlinger::RecordThread::RecordTrack::updateTrackFrameInfo(
17793f0c902beb53a245c9db35e871607dba05b8d391Andy Hung        int64_t trackFramesReleased, int64_t sourceFramesRead,
17803f0c902beb53a245c9db35e871607dba05b8d391Andy Hung        uint32_t halSampleRate, const ExtendedTimestamp &timestamp)
17813f0c902beb53a245c9db35e871607dba05b8d391Andy Hung{
17823f0c902beb53a245c9db35e871607dba05b8d391Andy Hung    ExtendedTimestamp local = timestamp;
17833f0c902beb53a245c9db35e871607dba05b8d391Andy Hung
17843f0c902beb53a245c9db35e871607dba05b8d391Andy Hung    // Convert HAL frames to server-side track frames at track sample rate.
17853f0c902beb53a245c9db35e871607dba05b8d391Andy Hung    // We use trackFramesReleased and sourceFramesRead as an anchor point.
17863f0c902beb53a245c9db35e871607dba05b8d391Andy Hung    for (int i = ExtendedTimestamp::LOCATION_SERVER; i < ExtendedTimestamp::LOCATION_MAX; ++i) {
17873f0c902beb53a245c9db35e871607dba05b8d391Andy Hung        if (local.mTimeNs[i] != 0) {
17883f0c902beb53a245c9db35e871607dba05b8d391Andy Hung            const int64_t relativeServerFrames = local.mPosition[i] - sourceFramesRead;
17893f0c902beb53a245c9db35e871607dba05b8d391Andy Hung            const int64_t relativeTrackFrames = relativeServerFrames
17903f0c902beb53a245c9db35e871607dba05b8d391Andy Hung                    * mSampleRate / halSampleRate; // TODO: potential computation overflow
17913f0c902beb53a245c9db35e871607dba05b8d391Andy Hung            local.mPosition[i] = relativeTrackFrames + trackFramesReleased;
17923f0c902beb53a245c9db35e871607dba05b8d391Andy Hung        }
17933f0c902beb53a245c9db35e871607dba05b8d391Andy Hung    }
17946ae5843c281301a9ffd1059d185620a9337e15a2Andy Hung    mServerProxy->setTimestamp(local);
17953f0c902beb53a245c9db35e871607dba05b8d391Andy Hung}
179683b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent
179783b8808faad1e91690c64d7007348be8d9ebde73Eric LaurentAudioFlinger::RecordThread::PatchRecord::PatchRecord(RecordThread *recordThread,
179883b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent                                                     uint32_t sampleRate,
179983b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent                                                     audio_channel_mask_t channelMask,
180083b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent                                                     audio_format_t format,
180183b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent                                                     size_t frameCount,
180283b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent                                                     void *buffer,
18038fe68036c2a670abb9eb0cc67ab9830c2c23de81Andy Hung                                                     size_t bufferSize,
1804050677873c10d4da308ac222f8533c96cca3207eEric Laurent                                                     audio_input_flags_t flags)
180583b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent    :   RecordTrack(recordThread, NULL, sampleRate, format, channelMask, frameCount,
18068fe68036c2a670abb9eb0cc67ab9830c2c23de81Andy Hung                buffer, bufferSize, AUDIO_SESSION_NONE, getuid(), flags, TYPE_PATCH),
180783b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent                mProxy(new ClientProxy(mCblk, mBuffer, frameCount, mFrameSize, false, true))
180883b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent{
180983b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent    uint64_t mixBufferNs = ((uint64_t)2 * recordThread->frameCount() * 1000000000) /
181083b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent                                                                recordThread->sampleRate();
181183b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent    mPeerTimeout.tv_sec = mixBufferNs / 1000000000;
181283b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent    mPeerTimeout.tv_nsec = (int) (mixBufferNs % 1000000000);
181383b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent
181483b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent    ALOGV("PatchRecord %p sampleRate %d mPeerTimeout %d.%03d sec",
181583b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent                                      this, sampleRate,
181683b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent                                      (int)mPeerTimeout.tv_sec,
181783b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent                                      (int)(mPeerTimeout.tv_nsec / 1000000));
181883b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent}
181983b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent
182083b8808faad1e91690c64d7007348be8d9ebde73Eric LaurentAudioFlinger::RecordThread::PatchRecord::~PatchRecord()
182183b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent{
182283b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent}
182383b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent
182483b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent// AudioBufferProvider interface
182583b8808faad1e91690c64d7007348be8d9ebde73Eric Laurentstatus_t AudioFlinger::RecordThread::PatchRecord::getNextBuffer(
1826d79072e9dff59f767cce2cda1caab80ce5a0815bGlenn Kasten                                                  AudioBufferProvider::Buffer* buffer)
182783b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent{
182883b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent    ALOG_ASSERT(mPeerProxy != 0, "PatchRecord::getNextBuffer() called without peer proxy");
182983b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent    Proxy::Buffer buf;
183083b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent    buf.mFrameCount = buffer->frameCount;
183183b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent    status_t status = mPeerProxy->obtainBuffer(&buf, &mPeerTimeout);
183283b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent    ALOGV_IF(status != NO_ERROR,
183383b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent             "PatchRecord() %p mPeerProxy->obtainBuffer status %d", this, status);
1834c2730ba7c5e9559b7499ef5e0d7742deb18c5110Eric Laurent    buffer->frameCount = buf.mFrameCount;
183583b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent    if (buf.mFrameCount == 0) {
183683b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent        return WOULD_BLOCK;
183783b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent    }
1838d79072e9dff59f767cce2cda1caab80ce5a0815bGlenn Kasten    status = RecordTrack::getNextBuffer(buffer);
183983b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent    return status;
184083b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent}
184183b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent
184283b8808faad1e91690c64d7007348be8d9ebde73Eric Laurentvoid AudioFlinger::RecordThread::PatchRecord::releaseBuffer(AudioBufferProvider::Buffer* buffer)
184383b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent{
184483b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent    ALOG_ASSERT(mPeerProxy != 0, "PatchRecord::releaseBuffer() called without peer proxy");
184583b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent    Proxy::Buffer buf;
184683b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent    buf.mFrameCount = buffer->frameCount;
184783b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent    buf.mRaw = buffer->raw;
184883b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent    mPeerProxy->releaseBuffer(&buf);
184983b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent    TrackBase::releaseBuffer(buffer);
185083b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent}
185183b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent
185283b8808faad1e91690c64d7007348be8d9ebde73Eric Laurentstatus_t AudioFlinger::RecordThread::PatchRecord::obtainBuffer(Proxy::Buffer* buffer,
185383b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent                                                               const struct timespec *timeOut)
185483b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent{
185583b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent    return mProxy->obtainBuffer(buffer, timeOut);
185683b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent}
185783b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent
185883b8808faad1e91690c64d7007348be8d9ebde73Eric Laurentvoid AudioFlinger::RecordThread::PatchRecord::releaseBuffer(Proxy::Buffer* buffer)
185983b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent{
186083b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent    mProxy->releaseBuffer(buffer);
186183b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent}
186283b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent
18636acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent
18646acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent
18656acd1d432f526ae9a055ddaece28bf93b474a776Eric LaurentAudioFlinger::MmapThread::MmapTrack::MmapTrack(ThreadBase *thread,
18666acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent        uint32_t sampleRate,
18676acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent        audio_format_t format,
18686acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent        audio_channel_mask_t channelMask,
18696acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent        audio_session_t sessionId,
18706acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent        uid_t uid,
18712c6c3bb76b2fa18ed3536331a1700250bd04c7ceAndy Hung        pid_t pid,
18726acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent        audio_port_handle_t portId)
18736acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent    :   TrackBase(thread, NULL, sampleRate, format,
18748fe68036c2a670abb9eb0cc67ab9830c2c23de81Andy Hung                  channelMask, (size_t)0 /* frameCount */,
18758fe68036c2a670abb9eb0cc67ab9830c2c23de81Andy Hung                  nullptr /* buffer */, (size_t)0 /* bufferSize */,
18768fe68036c2a670abb9eb0cc67ab9830c2c23de81Andy Hung                  sessionId, uid, false /* isOut */,
18776acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent                  ALLOC_NONE,
18782c6c3bb76b2fa18ed3536331a1700250bd04c7ceAndy Hung                  TYPE_DEFAULT, portId),
18792c6c3bb76b2fa18ed3536331a1700250bd04c7ceAndy Hung        mPid(pid)
18806acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent{
18816acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent}
18826acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent
18836acd1d432f526ae9a055ddaece28bf93b474a776Eric LaurentAudioFlinger::MmapThread::MmapTrack::~MmapTrack()
18846acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent{
18856acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent}
18866acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent
18876acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurentstatus_t AudioFlinger::MmapThread::MmapTrack::initCheck() const
18886acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent{
18896acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent    return NO_ERROR;
18906acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent}
18916acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent
18926acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurentstatus_t AudioFlinger::MmapThread::MmapTrack::start(AudioSystem::sync_event_t event __unused,
18936acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent                                                        audio_session_t triggerSession __unused)
18946acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent{
18956acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent    return NO_ERROR;
18966acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent}
18976acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent
18986acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurentvoid AudioFlinger::MmapThread::MmapTrack::stop()
18996acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent{
19006acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent}
19016acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent
19026acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent// AudioBufferProvider interface
19036acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurentstatus_t AudioFlinger::MmapThread::MmapTrack::getNextBuffer(AudioBufferProvider::Buffer* buffer)
19046acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent{
19056acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent    buffer->frameCount = 0;
19066acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent    buffer->raw = nullptr;
19076acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent    return INVALID_OPERATION;
19086acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent}
19096acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent
19106acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent// ExtendedAudioBufferProvider interface
19116acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurentsize_t AudioFlinger::MmapThread::MmapTrack::framesReady() const {
19126acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent    return 0;
19136acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent}
19146acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent
19156acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurentint64_t AudioFlinger::MmapThread::MmapTrack::framesReleased() const
19166acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent{
19176acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent    return 0;
19186acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent}
19196acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent
19206acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurentvoid AudioFlinger::MmapThread::MmapTrack::onTimestamp(const ExtendedTimestamp &timestamp __unused)
19216acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent{
19226acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent}
19236acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent
19246acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent/*static*/ void AudioFlinger::MmapThread::MmapTrack::appendDumpHeader(String8& result)
19256acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent{
19262c6c3bb76b2fa18ed3536331a1700250bd04c7ceAndy Hung    result.append("Client Session   Format Chn mask  SRate\n");
19276acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent}
19286acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent
19292c6c3bb76b2fa18ed3536331a1700250bd04c7ceAndy Hungvoid AudioFlinger::MmapThread::MmapTrack::appendDump(String8& result, bool active __unused)
19306acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent{
19312c6c3bb76b2fa18ed3536331a1700250bd04c7ceAndy Hung    result.appendFormat("%6u %7u %08X %08X %6u\n",
19322c6c3bb76b2fa18ed3536331a1700250bd04c7ceAndy Hung            mPid,
19332c6c3bb76b2fa18ed3536331a1700250bd04c7ceAndy Hung            mSessionId,
19346acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent            mFormat,
19356acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent            mChannelMask,
19366acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent            mSampleRate);
19376acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent}
19386acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent
193963238efb0d674758902918e3cdaac322126484b7Glenn Kasten} // namespace android
1940