Tracks.cpp revision d776ac63ce9c013c9626226e43f7db606e035838
19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/*
29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project**
39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** Copyright 2012, The Android Open Source Project
49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project**
59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** Licensed under the Apache License, Version 2.0 (the "License");
69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** you may not use this file except in compliance with the License.
79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** You may obtain a copy of the License at
89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project**
99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project**     http://www.apache.org/licenses/LICENSE-2.0
109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project**
119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** Unless required by applicable law or agreed to in writing, software
129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** distributed under the License is distributed on an "AS IS" BASIS,
139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** See the License for the specific language governing permissions and
159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** limitations under the License.
169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project*/
179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#define LOG_TAG "AudioFlinger"
209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project//#define LOG_NDEBUG 0
219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "Configuration.h"
239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <math.h>
249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <utils/Log.h>
259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <private/media/AudioTrackShared.h>
279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <common_time/cc_helper.h>
299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <common_time/local_clock.h>
3058feea74b42bbaaa0552d76af23873bdd0b5dca2Mitsuru Oshima
319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "AudioMixer.h"
329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "AudioFlinger.h"
339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "ServiceUtilities.h"
349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <media/nbaio/Pipe.h>
369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <media/nbaio/PipeReader.h>
379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// ----------------------------------------------------------------------------
399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// Note: the following macro is used for extremely verbose logging message.  In
419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// order to run with ALOG_ASSERT turned on, we need to have LOG_NDEBUG set to
429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// 0; but one side effect of this is to turn all LOGV's as well.  Some messages
439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// are so verbose that we want to suppress them even when we have ALOG_ASSERT
449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// turned on.  Do not uncomment the #def below unless you really know what you
459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// are doing and want to see all of the extremely verbose messages.
469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project//#define VERY_VERY_VERBOSE_LOGGING
479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#ifdef VERY_VERY_VERBOSE_LOGGING
489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#define ALOGVV ALOGV
499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#else
509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#define ALOGVV(a...) do { } while(0)
519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif
529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectnamespace android {
549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// ----------------------------------------------------------------------------
569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project//      TrackBase
579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// ----------------------------------------------------------------------------
589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic volatile int32_t nextTrackId = 55;
609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// TrackBase constructor must be called with AudioFlinger::mLock held
629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectAudioFlinger::ThreadBase::TrackBase::TrackBase(
639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            ThreadBase *thread,
649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            const sp<Client>& client,
659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            uint32_t sampleRate,
669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            audio_format_t format,
679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            audio_channel_mask_t channelMask,
689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            size_t frameCount,
699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            const sp<IMemory>& sharedBuffer,
709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            int sessionId,
719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            int clientUid,
729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            bool isOut,
739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            bool useReadOnlyHeap)
749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    :   RefBase(),
759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mThread(thread),
769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mClient(client),
779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mCblk(NULL),
789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // mBuffer
799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mState(IDLE),
809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mSampleRate(sampleRate),
819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mFormat(format),
829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mChannelMask(channelMask),
839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mChannelCount(popcount(channelMask)),
849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mFrameSize(audio_is_linear_pcm(format) ?
859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mChannelCount * audio_bytes_per_sample(format) : sizeof(int8_t)),
869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mFrameCount(frameCount),
879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mSessionId(sessionId),
889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mIsOut(isOut),
899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mServerProxy(NULL),
909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mId(android_atomic_inc(&nextTrackId)),
919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mTerminated(false)
929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // if the caller is us, trust the specified uid
949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (IPCThreadState::self()->getCallingPid() != getpid_cached || clientUid == -1) {
959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int newclientUid = IPCThreadState::self()->getCallingUid();
969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (clientUid != -1 && clientUid != newclientUid) {
979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            ALOGW("uid %d tried to pass itself off as %d", newclientUid, clientUid);
989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        clientUid = newclientUid;
1006465f7753783a614948fb3ffbd8c072345b4eea1Jim Miller    }
1016465f7753783a614948fb3ffbd8c072345b4eea1Jim Miller    // clientUid contains the uid of the app that is responsible for this track, so we can blame
1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // battery usage on it.
1036465f7753783a614948fb3ffbd8c072345b4eea1Jim Miller    mUid = clientUid;
1046465f7753783a614948fb3ffbd8c072345b4eea1Jim Miller
1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // client == 0 implies sharedBuffer == 0
1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    ALOG_ASSERT(!(client == 0 && sharedBuffer != 0));
1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    ALOGV_IF(sharedBuffer != 0, "sharedBuffer: %p, size: %d", sharedBuffer->pointer(),
1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            sharedBuffer->size());
1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // ALOGD("Creating track with %d buffers @ %d bytes", bufferCount, bufferSize);
1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    size_t size = sizeof(audio_track_cblk_t);
1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    size_t bufferSize = (sharedBuffer == 0 ? roundup(frameCount) : frameCount) * mFrameSize;
1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (sharedBuffer == 0 && !useReadOnlyHeap) {
1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        size += bufferSize;
1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (client != 0) {
1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mCblkMemory = client->heap()->allocate(size);
1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mCblkMemory == 0 ||
1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                (mCblk = static_cast<audio_track_cblk_t *>(mCblkMemory->pointer())) == NULL) {
1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            ALOGE("not enough memory for AudioTrack size=%u", size);
1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            client->heap()->dump("AudioTrack");
1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mCblkMemory.clear();
1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return;
1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    } else {
1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // this syntax avoids calling the audio_track_cblk_t constructor twice
1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mCblk = (audio_track_cblk_t *) new uint8_t[size];
1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // assume mCblk != NULL
1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // construct the shared structure in-place.
1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (mCblk != NULL) {
1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        new(mCblk) audio_track_cblk_t();
1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (useReadOnlyHeap) {
1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            const sp<MemoryDealer> roHeap(thread->readOnlyHeap());
1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (roHeap == 0 ||
1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    (mBufferMemory = roHeap->allocate(bufferSize)) == 0 ||
1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    (mBuffer = mBufferMemory->pointer()) == NULL) {
1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                ALOGE("not enough memory for read-only buffer size=%zu", bufferSize);
1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (roHeap != 0) {
1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    roHeap->dump("buffer");
1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
145ae09878698ba6ad56ea43843f5a0895c94c32d90Amith Yamasani                mCblkMemory.clear();
1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mBufferMemory.clear();
147a95e1087b2258b118a7ccb2bedb44da359d3abd0Chet Haase                return;
148a95e1087b2258b118a7ccb2bedb44da359d3abd0Chet Haase            }
1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            memset(mBuffer, 0, bufferSize);
1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // clear all buffers
1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (sharedBuffer == 0) {
1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mBuffer = (char*)mCblk + sizeof(audio_track_cblk_t);
1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                memset(mBuffer, 0, bufferSize);
1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else {
1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mBuffer = sharedBuffer->pointer();
1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#if 0
1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mCblk->mFlags = CBLK_FORCEREADY;    // FIXME hack, need to fix the track ready logic
1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif
1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#ifdef TEE_SINK
1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mTeeSinkTrackEnabled) {
1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            NBAIO_Format pipeFormat = Format_from_SR_C(mSampleRate, mChannelCount);
1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (Format_isValid(pipeFormat)) {
1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                Pipe *pipe = new Pipe(mTeeSinkTrackFrames, pipeFormat);
1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                size_t numCounterOffers = 0;
169a95e1087b2258b118a7ccb2bedb44da359d3abd0Chet Haase                const NBAIO_Format offers[1] = {pipeFormat};
170a95e1087b2258b118a7ccb2bedb44da359d3abd0Chet Haase                ssize_t index = pipe->negotiate(offers, 1, NULL, numCounterOffers);
171a95e1087b2258b118a7ccb2bedb44da359d3abd0Chet Haase                ALOG_ASSERT(index == 0);
1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                PipeReader *pipeReader = new PipeReader(*pipe);
1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                numCounterOffers = 0;
1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                index = pipeReader->negotiate(offers, 1, NULL, numCounterOffers);
1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                ALOG_ASSERT(index == 0);
1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mTeeSink = pipe;
1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mTeeSource = pipeReader;
1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif
1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectAudioFlinger::ThreadBase::TrackBase::~TrackBase()
1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#ifdef TEE_SINK
1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    dumpTee(-1, mTeeSource, mId);
1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif
1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // delete the proxy before deleting the shared memory it refers to, to avoid dangling reference
1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    delete mServerProxy;
1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (mCblk != NULL) {
1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mClient == 0) {
1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            delete mCblk;
1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mCblk->~audio_track_cblk_t();   // destroy our shared-structure.
1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    mCblkMemory.clear();    // free the shared memory before releasing the heap it belongs to
2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (mClient != 0) {
2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // Client destructor must run with AudioFlinger mutex locked
2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Mutex::Autolock _l(mClient->audioFlinger()->mLock);
2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // If the client's reference count drops to zero, the associated destructor
2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // must run with AudioFlinger lock held. Thus the explicit clear() rather than
2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // relying on the automatic clear() at end of scope.
2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mClient.clear();
2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
2099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// AudioBufferProvider interface
2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// getNextBuffer() = 0;
2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// This implementation of releaseBuffer() is used by Track and RecordTrack, but not TimedTrack
2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid AudioFlinger::ThreadBase::TrackBase::releaseBuffer(AudioBufferProvider::Buffer* buffer)
2149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#ifdef TEE_SINK
2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (mTeeSink != 0) {
2179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        (void) mTeeSink->write(buffer->raw, buffer->frameCount);
2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif
2209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    ServerProxy::Buffer buf;
2229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    buf.mFrameCount = buffer->frameCount;
2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    buf.mRaw = buffer->raw;
2249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    buffer->frameCount = 0;
2259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    buffer->raw = NULL;
2269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    mServerProxy->releaseBuffer(&buf);
2279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
2289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatus_t AudioFlinger::ThreadBase::TrackBase::setSyncEvent(const sp<SyncEvent>& event)
2309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
2319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    mSyncEvents.add(event);
2329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return NO_ERROR;
2339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
2349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// ----------------------------------------------------------------------------
2369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project//      Playback
2379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// ----------------------------------------------------------------------------
2389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectAudioFlinger::TrackHandle::TrackHandle(const sp<AudioFlinger::PlaybackThread::Track>& track)
2409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    : BnAudioTrack(),
2419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project      mTrack(track)
2429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
2439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
2449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectAudioFlinger::TrackHandle::~TrackHandle() {
2469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // just stop the track on deletion, associated resources
2479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // will be freed from the main thread once all pending buffers have
2489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // been played. Unless it's not in the active track list, in which
2499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // case we free everything now...
2509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    mTrack->destroy();
2519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
2529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectsp<IMemory> AudioFlinger::TrackHandle::getCblk() const {
2549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return mTrack->getCblk();
2559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
2569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatus_t AudioFlinger::TrackHandle::start() {
2589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return mTrack->start();
2599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
2609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid AudioFlinger::TrackHandle::stop() {
2629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    mTrack->stop();
2639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
264a95e1087b2258b118a7ccb2bedb44da359d3abd0Chet Haase
2659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid AudioFlinger::TrackHandle::flush() {
2669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    mTrack->flush();
2679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
2689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid AudioFlinger::TrackHandle::pause() {
2709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    mTrack->pause();
2719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
2729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatus_t AudioFlinger::TrackHandle::attachAuxEffect(int EffectId)
2749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
2759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return mTrack->attachAuxEffect(EffectId);
2769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
2779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatus_t AudioFlinger::TrackHandle::allocateTimedBuffer(size_t size,
2799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                                         sp<IMemory>* buffer) {
2809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (!mTrack->isTimedTrack())
2819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return INVALID_OPERATION;
2829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    PlaybackThread::TimedTrack* tt =
2849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            reinterpret_cast<PlaybackThread::TimedTrack*>(mTrack.get());
2859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return tt->allocateTimedBuffer(size, buffer);
2869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
2879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatus_t AudioFlinger::TrackHandle::queueTimedBuffer(const sp<IMemory>& buffer,
2899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                                     int64_t pts) {
2909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (!mTrack->isTimedTrack())
2919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return INVALID_OPERATION;
2929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (buffer == 0 || buffer->pointer() == NULL) {
2949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        ALOGE("queueTimedBuffer() buffer is 0 or has NULL pointer()");
2959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return BAD_VALUE;
2969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    PlaybackThread::TimedTrack* tt =
2999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            reinterpret_cast<PlaybackThread::TimedTrack*>(mTrack.get());
3009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return tt->queueTimedBuffer(buffer, pts);
3019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
3029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatus_t AudioFlinger::TrackHandle::setMediaTimeTransform(
3049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const LinearTransform& xform, int target) {
3059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (!mTrack->isTimedTrack())
3079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return INVALID_OPERATION;
3089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    PlaybackThread::TimedTrack* tt =
3109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            reinterpret_cast<PlaybackThread::TimedTrack*>(mTrack.get());
3119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return tt->setMediaTimeTransform(
3129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        xform, static_cast<TimedAudioTrack::TargetTimeline>(target));
3139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
3149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
315b65b7cb5808a3cea59cbfa72ecd46bdda90351faTadashi G. Takaokastatus_t AudioFlinger::TrackHandle::setParameters(const String8& keyValuePairs) {
316b65b7cb5808a3cea59cbfa72ecd46bdda90351faTadashi G. Takaoka    return mTrack->setParameters(keyValuePairs);
317b65b7cb5808a3cea59cbfa72ecd46bdda90351faTadashi G. Takaoka}
318b65b7cb5808a3cea59cbfa72ecd46bdda90351faTadashi G. Takaoka
3199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatus_t AudioFlinger::TrackHandle::getTimestamp(AudioTimestamp& timestamp)
3209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
3219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return mTrack->getTimestamp(timestamp);
3229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
3239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid AudioFlinger::TrackHandle::signal()
3269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
3279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return mTrack->signal();
3289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
3299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatus_t AudioFlinger::TrackHandle::onTransact(
3319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
3329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
3339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return BnAudioTrack::onTransact(code, data, reply, flags);
3349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
3359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// ----------------------------------------------------------------------------
3379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// Track constructor must be called with AudioFlinger::mLock and ThreadBase::mLock held
3399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectAudioFlinger::PlaybackThread::Track::Track(
3409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            PlaybackThread *thread,
3419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            const sp<Client>& client,
3429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            audio_stream_type_t streamType,
3439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            uint32_t sampleRate,
3449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            audio_format_t format,
3459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            audio_channel_mask_t channelMask,
3469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            size_t frameCount,
3479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            const sp<IMemory>& sharedBuffer,
3489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            int sessionId,
3499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            int uid,
3509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            IAudioFlinger::track_flags_t flags)
3519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    :   TrackBase(thread, client, sampleRate, format, channelMask, frameCount, sharedBuffer,
3529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            sessionId, uid, true /*isOut*/),
3539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    mFillingUpStatus(FS_INVALID),
3549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // mRetryCount initialized later when needed
3559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    mSharedBuffer(sharedBuffer),
3569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    mStreamType(streamType),
3579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    mName(-1),  // see note below
3589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    mMainBuffer(thread->mixBuffer()),
3599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    mAuxBuffer(NULL),
3609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    mAuxEffectId(0), mHasVolumeController(false),
3619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    mPresentationCompleteFrames(0),
3629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    mFlags(flags),
3639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    mFastIndex(-1),
3649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    mCachedVolume(1.0),
3659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    mIsInvalid(false),
3669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    mAudioTrackServerProxy(NULL),
3679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    mResumeToStopping(false),
3689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    mFlushHwPending(false)
3699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
3709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (mCblk == NULL) {
3719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return;
3729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (sharedBuffer == 0) {
3759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mAudioTrackServerProxy = new AudioTrackServerProxy(mCblk, mBuffer, frameCount,
3769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mFrameSize);
3779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    } else {
3789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mAudioTrackServerProxy = new StaticAudioTrackServerProxy(mCblk, mBuffer, frameCount,
3799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mFrameSize);
3809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    mServerProxy = mAudioTrackServerProxy;
3829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    mName = thread->getTrackName_l(channelMask, sessionId);
3849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (mName < 0) {
3859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        ALOGE("no more track names available");
3869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return;
3879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // only allocate a fast track index if we were able to allocate a normal track name
3899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (flags & IAudioFlinger::TRACK_FAST) {
3909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mAudioTrackServerProxy->framesReadyIsCalledByMultipleThreads();
3919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        ALOG_ASSERT(thread->mFastTrackAvailMask != 0);
3929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int i = __builtin_ctz(thread->mFastTrackAvailMask);
3939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        ALOG_ASSERT(0 < i && i < (int)FastMixerState::kMaxFastTracks);
3949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // FIXME This is too eager.  We allocate a fast track index before the
3959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        //       fast track becomes active.  Since fast tracks are a scarce resource,
3969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        //       this means we are potentially denying other more important fast tracks from
3979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        //       being created.  It would be better to allocate the index dynamically.
3989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mFastIndex = i;
3999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // Read the initial underruns because this field is never cleared by the fast mixer
4009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mObservedUnderruns = thread->getFastTrackUnderruns(i);
4019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        thread->mFastTrackAvailMask &= ~(1 << i);
4029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
4049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectAudioFlinger::PlaybackThread::Track::~Track()
4069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
4079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    ALOGV("PlaybackThread::Track destructor");
4089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // The destructor would clear mSharedBuffer,
4109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // but it will not push the decremented reference count,
4119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // leaving the client's IMemory dangling indefinitely.
4129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // This prevents that leak.
4139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (mSharedBuffer != 0) {
4149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mSharedBuffer.clear();
4159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // flush the binder command buffer
4169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        IPCThreadState::self()->flushCommands();
4179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
4199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatus_t AudioFlinger::PlaybackThread::Track::initCheck() const
4219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
4229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    status_t status = TrackBase::initCheck();
4239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (status == NO_ERROR && mName < 0) {
4249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        status = NO_MEMORY;
4259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return status;
4279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
4289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid AudioFlinger::PlaybackThread::Track::destroy()
4309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
4319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // NOTE: destroyTrack_l() can remove a strong reference to this Track
4329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // by removing it from mTracks vector, so there is a risk that this Tracks's
4339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // destructor is called. As the destructor needs to lock mLock,
4349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // we must acquire a strong reference on this Track before locking mLock
4359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // here so that the destructor is called only when exiting this function.
4369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // On the other hand, as long as Track::destroy() is only called by
4379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // TrackHandle destructor, the TrackHandle still holds a strong ref on
4389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // this Track with its member mTrack.
4399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    sp<Track> keep(this);
4409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    { // scope for mLock
4419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        sp<ThreadBase> thread = mThread.promote();
4429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (thread != 0) {
4439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            Mutex::Autolock _l(thread->mLock);
4449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            PlaybackThread *playbackThread = (PlaybackThread *)thread.get();
4459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            bool wasActive = playbackThread->destroyTrack_l(this);
4469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (!isOutputTrack() && !wasActive) {
4479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                AudioSystem::releaseOutput(thread->id());
4489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
4499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
4529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/*static*/ void AudioFlinger::PlaybackThread::Track::appendDumpHeader(String8& result)
4549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
4559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    result.append("    Name Active Client Type      Fmt Chn mask Session fCount S F SRate  "
4569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                  "L dB  R dB    Server Main buf  Aux Buf Flags UndFrmCnt\n");
4579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
4589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid AudioFlinger::PlaybackThread::Track::dump(char* buffer, size_t size, bool active)
4609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
4619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    uint32_t vlr = mAudioTrackServerProxy->getVolumeLR();
4629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (isFastTrack()) {
4639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        sprintf(buffer, "    F %2d", mFastIndex);
4649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    } else if (mName >= AudioMixer::TRACK0) {
4659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        sprintf(buffer, "    %4d", mName - AudioMixer::TRACK0);
4669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    } else {
4679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        sprintf(buffer, "    none");
4689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    track_state state = mState;
4709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    char stateChar;
4719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (isTerminated()) {
4729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        stateChar = 'T';
4739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    } else {
4749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        switch (state) {
4759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        case IDLE:
4769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            stateChar = 'I';
4779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            break;
4789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        case STOPPING_1:
4799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            stateChar = 's';
4809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            break;
4819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        case STOPPING_2:
4829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            stateChar = '5';
4839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            break;
4849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        case STOPPED:
4859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            stateChar = 'S';
4869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            break;
4879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        case RESUMING:
4889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            stateChar = 'R';
4899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            break;
4909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        case ACTIVE:
4919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            stateChar = 'A';
4929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            break;
4939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        case PAUSING:
4949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            stateChar = 'p';
4959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            break;
4969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        case PAUSED:
4979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            stateChar = 'P';
4989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            break;
4999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        case FLUSHED:
5009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            stateChar = 'F';
5019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            break;
5029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        default:
5039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            stateChar = '?';
5049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            break;
5059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
5069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    char nowInUnderrun;
5089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    switch (mObservedUnderruns.mBitFields.mMostRecent) {
5099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    case UNDERRUN_FULL:
5109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        nowInUnderrun = ' ';
5119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        break;
5128171b5182f5f07d33c9dfdf2dd8f0f6ae9588039Jae Yong Sung    case UNDERRUN_PARTIAL:
5138171b5182f5f07d33c9dfdf2dd8f0f6ae9588039Jae Yong Sung        nowInUnderrun = '<';
5148171b5182f5f07d33c9dfdf2dd8f0f6ae9588039Jae Yong Sung        break;
5158171b5182f5f07d33c9dfdf2dd8f0f6ae9588039Jae Yong Sung    case UNDERRUN_EMPTY:
5168171b5182f5f07d33c9dfdf2dd8f0f6ae9588039Jae Yong Sung        nowInUnderrun = '*';
5178171b5182f5f07d33c9dfdf2dd8f0f6ae9588039Jae Yong Sung        break;
5188171b5182f5f07d33c9dfdf2dd8f0f6ae9588039Jae Yong Sung    default:
5198171b5182f5f07d33c9dfdf2dd8f0f6ae9588039Jae Yong Sung        nowInUnderrun = '?';
5208171b5182f5f07d33c9dfdf2dd8f0f6ae9588039Jae Yong Sung        break;
5218171b5182f5f07d33c9dfdf2dd8f0f6ae9588039Jae Yong Sung    }
5228171b5182f5f07d33c9dfdf2dd8f0f6ae9588039Jae Yong Sung    snprintf(&buffer[8], size-8, " %6s %6u %4u %08X %08X %7u %6zu %1c %1d %5u %5.2g %5.2g  "
5238171b5182f5f07d33c9dfdf2dd8f0f6ae9588039Jae Yong Sung                                 "%08X %p %p 0x%03X %9u%c\n",
5248171b5182f5f07d33c9dfdf2dd8f0f6ae9588039Jae Yong Sung            active ? "yes" : "no",
5258171b5182f5f07d33c9dfdf2dd8f0f6ae9588039Jae Yong Sung            (mClient == 0) ? getpid_cached : mClient->pid(),
5268171b5182f5f07d33c9dfdf2dd8f0f6ae9588039Jae Yong Sung            mStreamType,
5278171b5182f5f07d33c9dfdf2dd8f0f6ae9588039Jae Yong Sung            mFormat,
5288171b5182f5f07d33c9dfdf2dd8f0f6ae9588039Jae Yong Sung            mChannelMask,
5298171b5182f5f07d33c9dfdf2dd8f0f6ae9588039Jae Yong Sung            mSessionId,
5308171b5182f5f07d33c9dfdf2dd8f0f6ae9588039Jae Yong Sung            mFrameCount,
5318171b5182f5f07d33c9dfdf2dd8f0f6ae9588039Jae Yong Sung            stateChar,
5328171b5182f5f07d33c9dfdf2dd8f0f6ae9588039Jae Yong Sung            mFillingUpStatus,
5338171b5182f5f07d33c9dfdf2dd8f0f6ae9588039Jae Yong Sung            mAudioTrackServerProxy->getSampleRate(),
5348171b5182f5f07d33c9dfdf2dd8f0f6ae9588039Jae Yong Sung            20.0 * log10((vlr & 0xFFFF) / 4096.0),
5358171b5182f5f07d33c9dfdf2dd8f0f6ae9588039Jae Yong Sung            20.0 * log10((vlr >> 16) / 4096.0),
5369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mCblk->mServer,
5379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mMainBuffer,
5389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mAuxBuffer,
5399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mCblk->mFlags,
5409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mAudioTrackServerProxy->getUnderrunFrames(),
5419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            nowInUnderrun);
5429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
5439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
54458feea74b42bbaaa0552d76af23873bdd0b5dca2Mitsuru Oshimauint32_t AudioFlinger::PlaybackThread::Track::sampleRate() const {
54558feea74b42bbaaa0552d76af23873bdd0b5dca2Mitsuru Oshima    return mAudioTrackServerProxy->getSampleRate();
54658feea74b42bbaaa0552d76af23873bdd0b5dca2Mitsuru Oshima}
54758feea74b42bbaaa0552d76af23873bdd0b5dca2Mitsuru Oshima
54858feea74b42bbaaa0552d76af23873bdd0b5dca2Mitsuru Oshima// AudioBufferProvider interface
5499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatus_t AudioFlinger::PlaybackThread::Track::getNextBuffer(
5509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        AudioBufferProvider::Buffer* buffer, int64_t pts __unused)
5519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
5529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    ServerProxy::Buffer buf;
5539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    size_t desiredFrames = buffer->frameCount;
5549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    buf.mFrameCount = desiredFrames;
5559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    status_t status = mServerProxy->obtainBuffer(&buf);
5569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    buffer->frameCount = buf.mFrameCount;
5579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    buffer->raw = buf.mRaw;
5589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (buf.mFrameCount == 0) {
5599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mAudioTrackServerProxy->tallyUnderrunFrames(desiredFrames);
5609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return status;
5629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
5639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// releaseBuffer() is not overridden
5659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// ExtendedAudioBufferProvider interface
5679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// Note that framesReady() takes a mutex on the control block using tryLock().
5699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// This could result in priority inversion if framesReady() is called by the normal mixer,
5709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// as the normal mixer thread runs at lower
5719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// priority than the client's callback thread:  there is a short window within framesReady()
5729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// during which the normal mixer could be preempted, and the client callback would block.
5739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// Another problem can occur if framesReady() is called by the fast mixer:
5749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// the tryLock() could block for up to 1 ms, and a sequence of these could delay fast mixer.
5759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// FIXME Replace AudioTrackShared control block implementation by a non-blocking FIFO queue.
5769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectsize_t AudioFlinger::PlaybackThread::Track::framesReady() const {
5779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return mAudioTrackServerProxy->framesReady();
5789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
5799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectsize_t AudioFlinger::PlaybackThread::Track::framesReleased() const
5819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
5829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return mAudioTrackServerProxy->framesReleased();
5839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
5849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// Don't call for fast tracks; the framesReady() could result in priority inversion
5869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectbool AudioFlinger::PlaybackThread::Track::isReady() const {
5879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (mFillingUpStatus != FS_FILLING || isStopped() || isPausing()) {
5889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return true;
5899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (isStopping()) {
5929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (framesReady() > 0) {
5939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mFillingUpStatus = FS_FILLED;
5949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
5959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return true;
5969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (framesReady() >= mFrameCount ||
5999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            (mCblk->mFlags & CBLK_FORCEREADY)) {
6009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mFillingUpStatus = FS_FILLED;
6019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        android_atomic_and(~CBLK_FORCEREADY, &mCblk->mFlags);
6029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return true;
6039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
604a95e1087b2258b118a7ccb2bedb44da359d3abd0Chet Haase    return false;
6059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
6069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatus_t AudioFlinger::PlaybackThread::Track::start(AudioSystem::sync_event_t event __unused,
6089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                                    int triggerSession __unused)
609a95e1087b2258b118a7ccb2bedb44da359d3abd0Chet Haase{
610a95e1087b2258b118a7ccb2bedb44da359d3abd0Chet Haase    status_t status = NO_ERROR;
611a95e1087b2258b118a7ccb2bedb44da359d3abd0Chet Haase    ALOGV("start(%d), calling pid %d session %d",
612a95e1087b2258b118a7ccb2bedb44da359d3abd0Chet Haase            mName, IPCThreadState::self()->getCallingPid(), mSessionId);
613a95e1087b2258b118a7ccb2bedb44da359d3abd0Chet Haase
614a95e1087b2258b118a7ccb2bedb44da359d3abd0Chet Haase    sp<ThreadBase> thread = mThread.promote();
615a95e1087b2258b118a7ccb2bedb44da359d3abd0Chet Haase    if (thread != 0) {
616a95e1087b2258b118a7ccb2bedb44da359d3abd0Chet Haase        if (isOffloaded()) {
617a95e1087b2258b118a7ccb2bedb44da359d3abd0Chet Haase            Mutex::Autolock _laf(thread->mAudioFlinger->mLock);
618a95e1087b2258b118a7ccb2bedb44da359d3abd0Chet Haase            Mutex::Autolock _lth(thread->mLock);
619a95e1087b2258b118a7ccb2bedb44da359d3abd0Chet Haase            sp<EffectChain> ec = thread->getEffectChain_l(mSessionId);
620a95e1087b2258b118a7ccb2bedb44da359d3abd0Chet Haase            if (thread->mAudioFlinger->isNonOffloadableGlobalEffectEnabled_l() ||
621a95e1087b2258b118a7ccb2bedb44da359d3abd0Chet Haase                    (ec != 0 && ec->isNonOffloadableEnabled())) {
622a95e1087b2258b118a7ccb2bedb44da359d3abd0Chet Haase                invalidate();
623a95e1087b2258b118a7ccb2bedb44da359d3abd0Chet Haase                return PERMISSION_DENIED;
624a95e1087b2258b118a7ccb2bedb44da359d3abd0Chet Haase            }
625a95e1087b2258b118a7ccb2bedb44da359d3abd0Chet Haase        }
626a95e1087b2258b118a7ccb2bedb44da359d3abd0Chet Haase        Mutex::Autolock _lth(thread->mLock);
627a95e1087b2258b118a7ccb2bedb44da359d3abd0Chet Haase        track_state state = mState;
628a95e1087b2258b118a7ccb2bedb44da359d3abd0Chet Haase        // here the track could be either new, or restarted
629a95e1087b2258b118a7ccb2bedb44da359d3abd0Chet Haase        // in both cases "unstop" the track
630a95e1087b2258b118a7ccb2bedb44da359d3abd0Chet Haase
631a95e1087b2258b118a7ccb2bedb44da359d3abd0Chet Haase        // initial state-stopping. next state-pausing.
632a95e1087b2258b118a7ccb2bedb44da359d3abd0Chet Haase        // What if resume is called ?
633a95e1087b2258b118a7ccb2bedb44da359d3abd0Chet Haase
634a95e1087b2258b118a7ccb2bedb44da359d3abd0Chet Haase        if (state == PAUSED || state == PAUSING) {
635a95e1087b2258b118a7ccb2bedb44da359d3abd0Chet Haase            if (mResumeToStopping) {
636a95e1087b2258b118a7ccb2bedb44da359d3abd0Chet Haase                // happened we need to resume to STOPPING_1
637a95e1087b2258b118a7ccb2bedb44da359d3abd0Chet Haase                mState = TrackBase::STOPPING_1;
638a95e1087b2258b118a7ccb2bedb44da359d3abd0Chet Haase                ALOGV("PAUSED => STOPPING_1 (%d) on thread %p", mName, this);
639a95e1087b2258b118a7ccb2bedb44da359d3abd0Chet Haase            } else {
640a95e1087b2258b118a7ccb2bedb44da359d3abd0Chet Haase                mState = TrackBase::RESUMING;
641a95e1087b2258b118a7ccb2bedb44da359d3abd0Chet Haase                ALOGV("PAUSED => RESUMING (%d) on thread %p", mName, this);
6429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
6439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
6449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mState = TrackBase::ACTIVE;
6459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            ALOGV("? => ACTIVE (%d) on thread %p", mName, this);
6469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
6479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        PlaybackThread *playbackThread = (PlaybackThread *)thread.get();
6499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        status = playbackThread->addTrack_l(this);
6509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (status == INVALID_OPERATION || status == PERMISSION_DENIED) {
6519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            triggerEvents(AudioSystem::SYNC_EVENT_PRESENTATION_COMPLETE);
6529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            //  restore previous state if start was rejected by policy manager
6539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (status == PERMISSION_DENIED) {
6549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mState = state;
6559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
6569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
6579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // track was already in the active list, not a problem
6589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (status == ALREADY_EXISTS) {
6599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            status = NO_ERROR;
6609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
6619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // Acknowledge any pending flush(), so that subsequent new data isn't discarded.
6629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // It is usually unsafe to access the server proxy from a binder thread.
6639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // But in this case we know the mixer thread (whether normal mixer or fast mixer)
6649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // isn't looking at this track yet:  we still hold the normal mixer thread lock,
6659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // and for fast tracks the track is not yet in the fast mixer thread's active set.
6669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            ServerProxy::Buffer buffer;
6679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            buffer.mFrameCount = 1;
6689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            (void) mAudioTrackServerProxy->obtainBuffer(&buffer, true /*ackFlush*/);
6699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
6709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    } else {
6719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        status = BAD_VALUE;
6729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
6739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return status;
6749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
6759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid AudioFlinger::PlaybackThread::Track::stop()
6779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
6789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    ALOGV("stop(%d), calling pid %d", mName, IPCThreadState::self()->getCallingPid());
6799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    sp<ThreadBase> thread = mThread.promote();
6809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (thread != 0) {
6819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Mutex::Autolock _l(thread->mLock);
6829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        track_state state = mState;
6839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (state == RESUMING || state == ACTIVE || state == PAUSING || state == PAUSED) {
6849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // If the track is not active (PAUSED and buffers full), flush buffers
6859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            PlaybackThread *playbackThread = (PlaybackThread *)thread.get();
6869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (playbackThread->mActiveTracks.indexOf(this) < 0) {
6879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                reset();
6889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mState = STOPPED;
6899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else if (!isFastTrack() && !isOffloaded()) {
6909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mState = STOPPED;
6919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else {
6929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // For fast tracks prepareTracks_l() will set state to STOPPING_2
6939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // presentation is complete
6949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // For an offloaded track this starts a drain and state will
6959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // move to STOPPING_2 when drain completes and then STOPPED
6969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mState = STOPPING_1;
6976465f7753783a614948fb3ffbd8c072345b4eea1Jim Miller            }
6986465f7753783a614948fb3ffbd8c072345b4eea1Jim Miller            ALOGV("not stopping/stopped => stopping/stopped (%d) on thread %p", mName,
6996465f7753783a614948fb3ffbd8c072345b4eea1Jim Miller                    playbackThread);
7006465f7753783a614948fb3ffbd8c072345b4eea1Jim Miller        }
7019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
7029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
7039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid AudioFlinger::PlaybackThread::Track::pause()
7059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
7069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    ALOGV("pause(%d), calling pid %d", mName, IPCThreadState::self()->getCallingPid());
7079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    sp<ThreadBase> thread = mThread.promote();
7089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (thread != 0) {
7099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Mutex::Autolock _l(thread->mLock);
7109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        PlaybackThread *playbackThread = (PlaybackThread *)thread.get();
7119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        switch (mState) {
7129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        case STOPPING_1:
7136465f7753783a614948fb3ffbd8c072345b4eea1Jim Miller        case STOPPING_2:
7146465f7753783a614948fb3ffbd8c072345b4eea1Jim Miller            if (!isOffloaded()) {
7156465f7753783a614948fb3ffbd8c072345b4eea1Jim Miller                /* nothing to do if track is not offloaded */
7166465f7753783a614948fb3ffbd8c072345b4eea1Jim Miller                break;
7176465f7753783a614948fb3ffbd8c072345b4eea1Jim Miller            }
7186465f7753783a614948fb3ffbd8c072345b4eea1Jim Miller
7196465f7753783a614948fb3ffbd8c072345b4eea1Jim Miller            // Offloaded track was draining, we need to carry on draining when resumed
7209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mResumeToStopping = true;
7216465f7753783a614948fb3ffbd8c072345b4eea1Jim Miller            // fall through...
7229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        case ACTIVE:
7239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        case RESUMING:
7249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mState = PAUSING;
7259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            ALOGV("ACTIVE/RESUMING => PAUSING (%d) on thread %p", mName, thread.get());
7269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            playbackThread->broadcast_l();
7279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            break;
7289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        default:
7309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            break;
7319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
7329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
7339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
7349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid AudioFlinger::PlaybackThread::Track::flush()
7369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
7379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    ALOGV("flush(%d)", mName);
7389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    sp<ThreadBase> thread = mThread.promote();
7399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (thread != 0) {
7409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Mutex::Autolock _l(thread->mLock);
7419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        PlaybackThread *playbackThread = (PlaybackThread *)thread.get();
7429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (isOffloaded()) {
7449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // If offloaded we allow flush during any state except terminated
7459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // and keep the track active to avoid problems if user is seeking
7469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // rapidly and underlying hardware has a significant delay handling
7479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // a pause
7489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (isTerminated()) {
7499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return;
7509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
7519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            ALOGV("flush: offload flush");
7539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            reset();
7549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (mState == STOPPING_1 || mState == STOPPING_2) {
7569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                ALOGV("flushed in STOPPING_1 or 2 state, change state to ACTIVE");
7579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mState = ACTIVE;
7589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
7599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (mState == ACTIVE) {
7619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                ALOGV("flush called in active state, resetting buffer time out retry count");
7629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mRetryCount = PlaybackThread::kMaxTrackRetriesOffload;
7639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
7649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mFlushHwPending = true;
7669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mResumeToStopping = false;
7679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
7689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (mState != STOPPING_1 && mState != STOPPING_2 && mState != STOPPED &&
7699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    mState != PAUSED && mState != PAUSING && mState != IDLE && mState != FLUSHED) {
7709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return;
7719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
7729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // No point remaining in PAUSED state after a flush => go to
7739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // FLUSHED state
7749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mState = FLUSHED;
7759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // do not reset the track if it is still in the process of being stopped or paused.
7769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // this will be done by prepareTracks_l() when the track is stopped.
7779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // prepareTracks_l() will see mState == FLUSHED, then
7789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // remove from active track list, reset(), and trigger presentation complete
7799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (playbackThread->mActiveTracks.indexOf(this) < 0) {
7809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                reset();
7819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
7829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
7839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // Prevent flush being lost if the track is flushed and then resumed
7849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // before mixer thread can run. This is important when offloading
7859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // because the hardware buffer could hold a large amount of audio
7869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        playbackThread->broadcast_l();
7879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
7889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
7899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
790a95e1087b2258b118a7ccb2bedb44da359d3abd0Chet Haase// must be called with thread lock held
7919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid AudioFlinger::PlaybackThread::Track::flushAck()
7929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
7939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (!isOffloaded())
7949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return;
7959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    mFlushHwPending = false;
7979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
7989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid AudioFlinger::PlaybackThread::Track::reset()
800a95e1087b2258b118a7ccb2bedb44da359d3abd0Chet Haase{
8019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // Do not reset twice to avoid discarding data written just after a flush and before
8029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // the audioflinger thread detects the track is stopped.
8039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (!mResetDone) {
8049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // Force underrun condition to avoid false underrun callback until first data is
8059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // written to buffer
8069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        android_atomic_and(~CBLK_FORCEREADY, &mCblk->mFlags);
8079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mFillingUpStatus = FS_FILLING;
8089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mResetDone = true;
8099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mState == FLUSHED) {
8109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mState = IDLE;
8116465f7753783a614948fb3ffbd8c072345b4eea1Jim Miller        }
8126465f7753783a614948fb3ffbd8c072345b4eea1Jim Miller    }
8136465f7753783a614948fb3ffbd8c072345b4eea1Jim Miller}
8146465f7753783a614948fb3ffbd8c072345b4eea1Jim Miller
8156465f7753783a614948fb3ffbd8c072345b4eea1Jim Millerstatus_t AudioFlinger::PlaybackThread::Track::setParameters(const String8& keyValuePairs)
8166465f7753783a614948fb3ffbd8c072345b4eea1Jim Miller{
8176465f7753783a614948fb3ffbd8c072345b4eea1Jim Miller    sp<ThreadBase> thread = mThread.promote();
8186465f7753783a614948fb3ffbd8c072345b4eea1Jim Miller    if (thread == 0) {
8199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        ALOGE("thread is dead");
8209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return FAILED_TRANSACTION;
8219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    } else if ((thread->type() == ThreadBase::DIRECT) ||
8229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    (thread->type() == ThreadBase::OFFLOAD)) {
823a95e1087b2258b118a7ccb2bedb44da359d3abd0Chet Haase        return thread->setParameters(keyValuePairs);
8249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    } else {
8259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return PERMISSION_DENIED;
8269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
8279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
8289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatus_t AudioFlinger::PlaybackThread::Track::getTimestamp(AudioTimestamp& timestamp)
8309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
8319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // Client should implement this using SSQ; the unpresented frame count in latch is irrelevant
8329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (isFastTrack()) {
8339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return INVALID_OPERATION;
8349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
8359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    sp<ThreadBase> thread = mThread.promote();
8369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (thread == 0) {
8379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return INVALID_OPERATION;
8389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
8399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    Mutex::Autolock _l(thread->mLock);
8409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    PlaybackThread *playbackThread = (PlaybackThread *)thread.get();
8419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (!isOffloaded()) {
8429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (!playbackThread->mLatchQValid) {
8439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return INVALID_OPERATION;
8449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
8459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        uint32_t unpresentedFrames =
8469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                ((int64_t) playbackThread->mLatchQ.mUnpresentedFrames * mSampleRate) /
8479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                playbackThread->mSampleRate;
8489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        uint32_t framesWritten = mAudioTrackServerProxy->framesReleased();
8499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (framesWritten < unpresentedFrames) {
8509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return INVALID_OPERATION;
8519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
8529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        timestamp.mPosition = framesWritten - unpresentedFrames;
8539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        timestamp.mTime = playbackThread->mLatchQ.mTimestamp.mTime;
8549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return NO_ERROR;
8559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
8569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return playbackThread->getTimestamp_l(timestamp);
8589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
8599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatus_t AudioFlinger::PlaybackThread::Track::attachAuxEffect(int EffectId)
8619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
8629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    status_t status = DEAD_OBJECT;
8639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    sp<ThreadBase> thread = mThread.promote();
8649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (thread != 0) {
8659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        PlaybackThread *playbackThread = (PlaybackThread *)thread.get();
8669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        sp<AudioFlinger> af = mClient->audioFlinger();
8679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Mutex::Autolock _l(af->mLock);
8699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        sp<PlaybackThread> srcThread = af->getEffectThread_l(AUDIO_SESSION_OUTPUT_MIX, EffectId);
8719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (EffectId != 0 && srcThread != 0 && playbackThread != srcThread.get()) {
8739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            Mutex::Autolock _dl(playbackThread->mLock);
8749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            Mutex::Autolock _sl(srcThread->mLock);
8759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            sp<EffectChain> chain = srcThread->getEffectChain_l(AUDIO_SESSION_OUTPUT_MIX);
8769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (chain == 0) {
8779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return INVALID_OPERATION;
8789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
8799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            sp<EffectModule> effect = chain->getEffectFromId_l(EffectId);
8819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (effect == 0) {
8829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return INVALID_OPERATION;
8839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
8849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            srcThread->removeEffect_l(effect);
8859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            status = playbackThread->addEffect_l(effect);
8869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (status != NO_ERROR) {
8879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                srcThread->addEffect_l(effect);
8889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return INVALID_OPERATION;
8899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
8909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // removeEffect_l() has stopped the effect if it was active so it must be restarted
8919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (effect->state() == EffectModule::ACTIVE ||
8929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    effect->state() == EffectModule::STOPPING) {
8939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                effect->start();
8949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
895
896            sp<EffectChain> dstChain = effect->chain().promote();
897            if (dstChain == 0) {
898                srcThread->addEffect_l(effect);
899                return INVALID_OPERATION;
900            }
901            AudioSystem::unregisterEffect(effect->id());
902            AudioSystem::registerEffect(&effect->desc(),
903                                        srcThread->id(),
904                                        dstChain->strategy(),
905                                        AUDIO_SESSION_OUTPUT_MIX,
906                                        effect->id());
907            AudioSystem::setEffectEnabled(effect->id(), effect->isEnabled());
908        }
909        status = playbackThread->attachAuxEffect(this, EffectId);
910    }
911    return status;
912}
913
914void AudioFlinger::PlaybackThread::Track::setAuxBuffer(int EffectId, int32_t *buffer)
915{
916    mAuxEffectId = EffectId;
917    mAuxBuffer = buffer;
918}
919
920bool AudioFlinger::PlaybackThread::Track::presentationComplete(size_t framesWritten,
921                                                         size_t audioHalFrames)
922{
923    // a track is considered presented when the total number of frames written to audio HAL
924    // corresponds to the number of frames written when presentationComplete() is called for the
925    // first time (mPresentationCompleteFrames == 0) plus the buffer filling status at that time.
926    // For an offloaded track the HAL+h/w delay is variable so a HAL drain() is used
927    // to detect when all frames have been played. In this case framesWritten isn't
928    // useful because it doesn't always reflect whether there is data in the h/w
929    // buffers, particularly if a track has been paused and resumed during draining
930    ALOGV("presentationComplete() mPresentationCompleteFrames %d framesWritten %d",
931                      mPresentationCompleteFrames, framesWritten);
932    if (mPresentationCompleteFrames == 0) {
933        mPresentationCompleteFrames = framesWritten + audioHalFrames;
934        ALOGV("presentationComplete() reset: mPresentationCompleteFrames %d audioHalFrames %d",
935                  mPresentationCompleteFrames, audioHalFrames);
936    }
937
938    if (framesWritten >= mPresentationCompleteFrames || isOffloaded()) {
939        ALOGV("presentationComplete() session %d complete: framesWritten %d",
940                  mSessionId, framesWritten);
941        triggerEvents(AudioSystem::SYNC_EVENT_PRESENTATION_COMPLETE);
942        mAudioTrackServerProxy->setStreamEndDone();
943        return true;
944    }
945    return false;
946}
947
948void AudioFlinger::PlaybackThread::Track::triggerEvents(AudioSystem::sync_event_t type)
949{
950    for (size_t i = 0; i < mSyncEvents.size(); i++) {
951        if (mSyncEvents[i]->type() == type) {
952            mSyncEvents[i]->trigger();
953            mSyncEvents.removeAt(i);
954            i--;
955        }
956    }
957}
958
959// implement VolumeBufferProvider interface
960
961uint32_t AudioFlinger::PlaybackThread::Track::getVolumeLR()
962{
963    // called by FastMixer, so not allowed to take any locks, block, or do I/O including logs
964    ALOG_ASSERT(isFastTrack() && (mCblk != NULL));
965    uint32_t vlr = mAudioTrackServerProxy->getVolumeLR();
966    uint32_t vl = vlr & 0xFFFF;
967    uint32_t vr = vlr >> 16;
968    // track volumes come from shared memory, so can't be trusted and must be clamped
969    if (vl > MAX_GAIN_INT) {
970        vl = MAX_GAIN_INT;
971    }
972    if (vr > MAX_GAIN_INT) {
973        vr = MAX_GAIN_INT;
974    }
975    // now apply the cached master volume and stream type volume;
976    // this is trusted but lacks any synchronization or barrier so may be stale
977    float v = mCachedVolume;
978    vl *= v;
979    vr *= v;
980    // re-combine into U4.16
981    vlr = (vr << 16) | (vl & 0xFFFF);
982    // FIXME look at mute, pause, and stop flags
983    return vlr;
984}
985
986status_t AudioFlinger::PlaybackThread::Track::setSyncEvent(const sp<SyncEvent>& event)
987{
988    if (isTerminated() || mState == PAUSED ||
989            ((framesReady() == 0) && ((mSharedBuffer != 0) ||
990                                      (mState == STOPPED)))) {
991        ALOGW("Track::setSyncEvent() in invalid state %d on session %d %s mode, framesReady %d ",
992              mState, mSessionId, (mSharedBuffer != 0) ? "static" : "stream", framesReady());
993        event->cancel();
994        return INVALID_OPERATION;
995    }
996    (void) TrackBase::setSyncEvent(event);
997    return NO_ERROR;
998}
999
1000void AudioFlinger::PlaybackThread::Track::invalidate()
1001{
1002    // FIXME should use proxy, and needs work
1003    audio_track_cblk_t* cblk = mCblk;
1004    android_atomic_or(CBLK_INVALID, &cblk->mFlags);
1005    android_atomic_release_store(0x40000000, &cblk->mFutex);
1006    // client is not in server, so FUTEX_WAKE is needed instead of FUTEX_WAKE_PRIVATE
1007    (void) __futex_syscall3(&cblk->mFutex, FUTEX_WAKE, INT_MAX);
1008    mIsInvalid = true;
1009}
1010
1011void AudioFlinger::PlaybackThread::Track::signal()
1012{
1013    sp<ThreadBase> thread = mThread.promote();
1014    if (thread != 0) {
1015        PlaybackThread *t = (PlaybackThread *)thread.get();
1016        Mutex::Autolock _l(t->mLock);
1017        t->broadcast_l();
1018    }
1019}
1020
1021//To be called with thread lock held
1022bool AudioFlinger::PlaybackThread::Track::isResumePending() {
1023
1024    if (mState == RESUMING)
1025        return true;
1026    /* Resume is pending if track was stopping before pause was called */
1027    if (mState == STOPPING_1 &&
1028        mResumeToStopping)
1029        return true;
1030
1031    return false;
1032}
1033
1034//To be called with thread lock held
1035void AudioFlinger::PlaybackThread::Track::resumeAck() {
1036
1037
1038    if (mState == RESUMING)
1039        mState = ACTIVE;
1040
1041    // Other possibility of  pending resume is stopping_1 state
1042    // Do not update the state from stopping as this prevents
1043    // drain being called.
1044    if (mState == STOPPING_1) {
1045        mResumeToStopping = false;
1046    }
1047}
1048// ----------------------------------------------------------------------------
1049
1050sp<AudioFlinger::PlaybackThread::TimedTrack>
1051AudioFlinger::PlaybackThread::TimedTrack::create(
1052            PlaybackThread *thread,
1053            const sp<Client>& client,
1054            audio_stream_type_t streamType,
1055            uint32_t sampleRate,
1056            audio_format_t format,
1057            audio_channel_mask_t channelMask,
1058            size_t frameCount,
1059            const sp<IMemory>& sharedBuffer,
1060            int sessionId,
1061            int uid)
1062{
1063    if (!client->reserveTimedTrack())
1064        return 0;
1065
1066    return new TimedTrack(
1067        thread, client, streamType, sampleRate, format, channelMask, frameCount,
1068        sharedBuffer, sessionId, uid);
1069}
1070
1071AudioFlinger::PlaybackThread::TimedTrack::TimedTrack(
1072            PlaybackThread *thread,
1073            const sp<Client>& client,
1074            audio_stream_type_t streamType,
1075            uint32_t sampleRate,
1076            audio_format_t format,
1077            audio_channel_mask_t channelMask,
1078            size_t frameCount,
1079            const sp<IMemory>& sharedBuffer,
1080            int sessionId,
1081            int uid)
1082    : Track(thread, client, streamType, sampleRate, format, channelMask,
1083            frameCount, sharedBuffer, sessionId, uid, IAudioFlinger::TRACK_TIMED),
1084      mQueueHeadInFlight(false),
1085      mTrimQueueHeadOnRelease(false),
1086      mFramesPendingInQueue(0),
1087      mTimedSilenceBuffer(NULL),
1088      mTimedSilenceBufferSize(0),
1089      mTimedAudioOutputOnTime(false),
1090      mMediaTimeTransformValid(false)
1091{
1092    LocalClock lc;
1093    mLocalTimeFreq = lc.getLocalFreq();
1094
1095    mLocalTimeToSampleTransform.a_zero = 0;
1096    mLocalTimeToSampleTransform.b_zero = 0;
1097    mLocalTimeToSampleTransform.a_to_b_numer = sampleRate;
1098    mLocalTimeToSampleTransform.a_to_b_denom = mLocalTimeFreq;
1099    LinearTransform::reduce(&mLocalTimeToSampleTransform.a_to_b_numer,
1100                            &mLocalTimeToSampleTransform.a_to_b_denom);
1101
1102    mMediaTimeToSampleTransform.a_zero = 0;
1103    mMediaTimeToSampleTransform.b_zero = 0;
1104    mMediaTimeToSampleTransform.a_to_b_numer = sampleRate;
1105    mMediaTimeToSampleTransform.a_to_b_denom = 1000000;
1106    LinearTransform::reduce(&mMediaTimeToSampleTransform.a_to_b_numer,
1107                            &mMediaTimeToSampleTransform.a_to_b_denom);
1108}
1109
1110AudioFlinger::PlaybackThread::TimedTrack::~TimedTrack() {
1111    mClient->releaseTimedTrack();
1112    delete [] mTimedSilenceBuffer;
1113}
1114
1115status_t AudioFlinger::PlaybackThread::TimedTrack::allocateTimedBuffer(
1116    size_t size, sp<IMemory>* buffer) {
1117
1118    Mutex::Autolock _l(mTimedBufferQueueLock);
1119
1120    trimTimedBufferQueue_l();
1121
1122    // lazily initialize the shared memory heap for timed buffers
1123    if (mTimedMemoryDealer == NULL) {
1124        const int kTimedBufferHeapSize = 512 << 10;
1125
1126        mTimedMemoryDealer = new MemoryDealer(kTimedBufferHeapSize,
1127                                              "AudioFlingerTimed");
1128        if (mTimedMemoryDealer == NULL) {
1129            return NO_MEMORY;
1130        }
1131    }
1132
1133    sp<IMemory> newBuffer = mTimedMemoryDealer->allocate(size);
1134    if (newBuffer == 0 || newBuffer->pointer() == NULL) {
1135        return NO_MEMORY;
1136    }
1137
1138    *buffer = newBuffer;
1139    return NO_ERROR;
1140}
1141
1142// caller must hold mTimedBufferQueueLock
1143void AudioFlinger::PlaybackThread::TimedTrack::trimTimedBufferQueue_l() {
1144    int64_t mediaTimeNow;
1145    {
1146        Mutex::Autolock mttLock(mMediaTimeTransformLock);
1147        if (!mMediaTimeTransformValid)
1148            return;
1149
1150        int64_t targetTimeNow;
1151        status_t res = (mMediaTimeTransformTarget == TimedAudioTrack::COMMON_TIME)
1152            ? mCCHelper.getCommonTime(&targetTimeNow)
1153            : mCCHelper.getLocalTime(&targetTimeNow);
1154
1155        if (OK != res)
1156            return;
1157
1158        if (!mMediaTimeTransform.doReverseTransform(targetTimeNow,
1159                                                    &mediaTimeNow)) {
1160            return;
1161        }
1162    }
1163
1164    size_t trimEnd;
1165    for (trimEnd = 0; trimEnd < mTimedBufferQueue.size(); trimEnd++) {
1166        int64_t bufEnd;
1167
1168        if ((trimEnd + 1) < mTimedBufferQueue.size()) {
1169            // We have a next buffer.  Just use its PTS as the PTS of the frame
1170            // following the last frame in this buffer.  If the stream is sparse
1171            // (ie, there are deliberate gaps left in the stream which should be
1172            // filled with silence by the TimedAudioTrack), then this can result
1173            // in one extra buffer being left un-trimmed when it could have
1174            // been.  In general, this is not typical, and we would rather
1175            // optimized away the TS calculation below for the more common case
1176            // where PTSes are contiguous.
1177            bufEnd = mTimedBufferQueue[trimEnd + 1].pts();
1178        } else {
1179            // We have no next buffer.  Compute the PTS of the frame following
1180            // the last frame in this buffer by computing the duration of of
1181            // this frame in media time units and adding it to the PTS of the
1182            // buffer.
1183            int64_t frameCount = mTimedBufferQueue[trimEnd].buffer()->size()
1184                               / mFrameSize;
1185
1186            if (!mMediaTimeToSampleTransform.doReverseTransform(frameCount,
1187                                                                &bufEnd)) {
1188                ALOGE("Failed to convert frame count of %lld to media time"
1189                      " duration" " (scale factor %d/%u) in %s",
1190                      frameCount,
1191                      mMediaTimeToSampleTransform.a_to_b_numer,
1192                      mMediaTimeToSampleTransform.a_to_b_denom,
1193                      __PRETTY_FUNCTION__);
1194                break;
1195            }
1196            bufEnd += mTimedBufferQueue[trimEnd].pts();
1197        }
1198
1199        if (bufEnd > mediaTimeNow)
1200            break;
1201
1202        // Is the buffer we want to use in the middle of a mix operation right
1203        // now?  If so, don't actually trim it.  Just wait for the releaseBuffer
1204        // from the mixer which should be coming back shortly.
1205        if (!trimEnd && mQueueHeadInFlight) {
1206            mTrimQueueHeadOnRelease = true;
1207        }
1208    }
1209
1210    size_t trimStart = mTrimQueueHeadOnRelease ? 1 : 0;
1211    if (trimStart < trimEnd) {
1212        // Update the bookkeeping for framesReady()
1213        for (size_t i = trimStart; i < trimEnd; ++i) {
1214            updateFramesPendingAfterTrim_l(mTimedBufferQueue[i], "trim");
1215        }
1216
1217        // Now actually remove the buffers from the queue.
1218        mTimedBufferQueue.removeItemsAt(trimStart, trimEnd);
1219    }
1220}
1221
1222void AudioFlinger::PlaybackThread::TimedTrack::trimTimedBufferQueueHead_l(
1223        const char* logTag) {
1224    ALOG_ASSERT(mTimedBufferQueue.size() > 0,
1225                "%s called (reason \"%s\"), but timed buffer queue has no"
1226                " elements to trim.", __FUNCTION__, logTag);
1227
1228    updateFramesPendingAfterTrim_l(mTimedBufferQueue[0], logTag);
1229    mTimedBufferQueue.removeAt(0);
1230}
1231
1232void AudioFlinger::PlaybackThread::TimedTrack::updateFramesPendingAfterTrim_l(
1233        const TimedBuffer& buf,
1234        const char* logTag __unused) {
1235    uint32_t bufBytes        = buf.buffer()->size();
1236    uint32_t consumedAlready = buf.position();
1237
1238    ALOG_ASSERT(consumedAlready <= bufBytes,
1239                "Bad bookkeeping while updating frames pending.  Timed buffer is"
1240                " only %u bytes long, but claims to have consumed %u"
1241                " bytes.  (update reason: \"%s\")",
1242                bufBytes, consumedAlready, logTag);
1243
1244    uint32_t bufFrames = (bufBytes - consumedAlready) / mFrameSize;
1245    ALOG_ASSERT(mFramesPendingInQueue >= bufFrames,
1246                "Bad bookkeeping while updating frames pending.  Should have at"
1247                " least %u queued frames, but we think we have only %u.  (update"
1248                " reason: \"%s\")",
1249                bufFrames, mFramesPendingInQueue, logTag);
1250
1251    mFramesPendingInQueue -= bufFrames;
1252}
1253
1254status_t AudioFlinger::PlaybackThread::TimedTrack::queueTimedBuffer(
1255    const sp<IMemory>& buffer, int64_t pts) {
1256
1257    {
1258        Mutex::Autolock mttLock(mMediaTimeTransformLock);
1259        if (!mMediaTimeTransformValid)
1260            return INVALID_OPERATION;
1261    }
1262
1263    Mutex::Autolock _l(mTimedBufferQueueLock);
1264
1265    uint32_t bufFrames = buffer->size() / mFrameSize;
1266    mFramesPendingInQueue += bufFrames;
1267    mTimedBufferQueue.add(TimedBuffer(buffer, pts));
1268
1269    return NO_ERROR;
1270}
1271
1272status_t AudioFlinger::PlaybackThread::TimedTrack::setMediaTimeTransform(
1273    const LinearTransform& xform, TimedAudioTrack::TargetTimeline target) {
1274
1275    ALOGVV("setMediaTimeTransform az=%lld bz=%lld n=%d d=%u tgt=%d",
1276           xform.a_zero, xform.b_zero, xform.a_to_b_numer, xform.a_to_b_denom,
1277           target);
1278
1279    if (!(target == TimedAudioTrack::LOCAL_TIME ||
1280          target == TimedAudioTrack::COMMON_TIME)) {
1281        return BAD_VALUE;
1282    }
1283
1284    Mutex::Autolock lock(mMediaTimeTransformLock);
1285    mMediaTimeTransform = xform;
1286    mMediaTimeTransformTarget = target;
1287    mMediaTimeTransformValid = true;
1288
1289    return NO_ERROR;
1290}
1291
1292#define min(a, b) ((a) < (b) ? (a) : (b))
1293
1294// implementation of getNextBuffer for tracks whose buffers have timestamps
1295status_t AudioFlinger::PlaybackThread::TimedTrack::getNextBuffer(
1296    AudioBufferProvider::Buffer* buffer, int64_t pts)
1297{
1298    if (pts == AudioBufferProvider::kInvalidPTS) {
1299        buffer->raw = NULL;
1300        buffer->frameCount = 0;
1301        mTimedAudioOutputOnTime = false;
1302        return INVALID_OPERATION;
1303    }
1304
1305    Mutex::Autolock _l(mTimedBufferQueueLock);
1306
1307    ALOG_ASSERT(!mQueueHeadInFlight,
1308                "getNextBuffer called without releaseBuffer!");
1309
1310    while (true) {
1311
1312        // if we have no timed buffers, then fail
1313        if (mTimedBufferQueue.isEmpty()) {
1314            buffer->raw = NULL;
1315            buffer->frameCount = 0;
1316            return NOT_ENOUGH_DATA;
1317        }
1318
1319        TimedBuffer& head = mTimedBufferQueue.editItemAt(0);
1320
1321        // calculate the PTS of the head of the timed buffer queue expressed in
1322        // local time
1323        int64_t headLocalPTS;
1324        {
1325            Mutex::Autolock mttLock(mMediaTimeTransformLock);
1326
1327            ALOG_ASSERT(mMediaTimeTransformValid, "media time transform invalid");
1328
1329            if (mMediaTimeTransform.a_to_b_denom == 0) {
1330                // the transform represents a pause, so yield silence
1331                timedYieldSilence_l(buffer->frameCount, buffer);
1332                return NO_ERROR;
1333            }
1334
1335            int64_t transformedPTS;
1336            if (!mMediaTimeTransform.doForwardTransform(head.pts(),
1337                                                        &transformedPTS)) {
1338                // the transform failed.  this shouldn't happen, but if it does
1339                // then just drop this buffer
1340                ALOGW("timedGetNextBuffer transform failed");
1341                buffer->raw = NULL;
1342                buffer->frameCount = 0;
1343                trimTimedBufferQueueHead_l("getNextBuffer; no transform");
1344                return NO_ERROR;
1345            }
1346
1347            if (mMediaTimeTransformTarget == TimedAudioTrack::COMMON_TIME) {
1348                if (OK != mCCHelper.commonTimeToLocalTime(transformedPTS,
1349                                                          &headLocalPTS)) {
1350                    buffer->raw = NULL;
1351                    buffer->frameCount = 0;
1352                    return INVALID_OPERATION;
1353                }
1354            } else {
1355                headLocalPTS = transformedPTS;
1356            }
1357        }
1358
1359        uint32_t sr = sampleRate();
1360
1361        // adjust the head buffer's PTS to reflect the portion of the head buffer
1362        // that has already been consumed
1363        int64_t effectivePTS = headLocalPTS +
1364                ((head.position() / mFrameSize) * mLocalTimeFreq / sr);
1365
1366        // Calculate the delta in samples between the head of the input buffer
1367        // queue and the start of the next output buffer that will be written.
1368        // If the transformation fails because of over or underflow, it means
1369        // that the sample's position in the output stream is so far out of
1370        // whack that it should just be dropped.
1371        int64_t sampleDelta;
1372        if (llabs(effectivePTS - pts) >= (static_cast<int64_t>(1) << 31)) {
1373            ALOGV("*** head buffer is too far from PTS: dropped buffer");
1374            trimTimedBufferQueueHead_l("getNextBuffer, buf pts too far from"
1375                                       " mix");
1376            continue;
1377        }
1378        if (!mLocalTimeToSampleTransform.doForwardTransform(
1379                (effectivePTS - pts) << 32, &sampleDelta)) {
1380            ALOGV("*** too late during sample rate transform: dropped buffer");
1381            trimTimedBufferQueueHead_l("getNextBuffer, bad local to sample");
1382            continue;
1383        }
1384
1385        ALOGVV("*** getNextBuffer head.pts=%lld head.pos=%d pts=%lld"
1386               " sampleDelta=[%d.%08x]",
1387               head.pts(), head.position(), pts,
1388               static_cast<int32_t>((sampleDelta >= 0 ? 0 : 1)
1389                   + (sampleDelta >> 32)),
1390               static_cast<uint32_t>(sampleDelta & 0xFFFFFFFF));
1391
1392        // if the delta between the ideal placement for the next input sample and
1393        // the current output position is within this threshold, then we will
1394        // concatenate the next input samples to the previous output
1395        const int64_t kSampleContinuityThreshold =
1396                (static_cast<int64_t>(sr) << 32) / 250;
1397
1398        // if this is the first buffer of audio that we're emitting from this track
1399        // then it should be almost exactly on time.
1400        const int64_t kSampleStartupThreshold = 1LL << 32;
1401
1402        if ((mTimedAudioOutputOnTime && llabs(sampleDelta) <= kSampleContinuityThreshold) ||
1403           (!mTimedAudioOutputOnTime && llabs(sampleDelta) <= kSampleStartupThreshold)) {
1404            // the next input is close enough to being on time, so concatenate it
1405            // with the last output
1406            timedYieldSamples_l(buffer);
1407
1408            ALOGVV("*** on time: head.pos=%d frameCount=%u",
1409                    head.position(), buffer->frameCount);
1410            return NO_ERROR;
1411        }
1412
1413        // Looks like our output is not on time.  Reset our on timed status.
1414        // Next time we mix samples from our input queue, then should be within
1415        // the StartupThreshold.
1416        mTimedAudioOutputOnTime = false;
1417        if (sampleDelta > 0) {
1418            // the gap between the current output position and the proper start of
1419            // the next input sample is too big, so fill it with silence
1420            uint32_t framesUntilNextInput = (sampleDelta + 0x80000000) >> 32;
1421
1422            timedYieldSilence_l(framesUntilNextInput, buffer);
1423            ALOGV("*** silence: frameCount=%u", buffer->frameCount);
1424            return NO_ERROR;
1425        } else {
1426            // the next input sample is late
1427            uint32_t lateFrames = static_cast<uint32_t>(-((sampleDelta + 0x80000000) >> 32));
1428            size_t onTimeSamplePosition =
1429                    head.position() + lateFrames * mFrameSize;
1430
1431            if (onTimeSamplePosition > head.buffer()->size()) {
1432                // all the remaining samples in the head are too late, so
1433                // drop it and move on
1434                ALOGV("*** too late: dropped buffer");
1435                trimTimedBufferQueueHead_l("getNextBuffer, dropped late buffer");
1436                continue;
1437            } else {
1438                // skip over the late samples
1439                head.setPosition(onTimeSamplePosition);
1440
1441                // yield the available samples
1442                timedYieldSamples_l(buffer);
1443
1444                ALOGV("*** late: head.pos=%d frameCount=%u", head.position(), buffer->frameCount);
1445                return NO_ERROR;
1446            }
1447        }
1448    }
1449}
1450
1451// Yield samples from the timed buffer queue head up to the given output
1452// buffer's capacity.
1453//
1454// Caller must hold mTimedBufferQueueLock
1455void AudioFlinger::PlaybackThread::TimedTrack::timedYieldSamples_l(
1456    AudioBufferProvider::Buffer* buffer) {
1457
1458    const TimedBuffer& head = mTimedBufferQueue[0];
1459
1460    buffer->raw = (static_cast<uint8_t*>(head.buffer()->pointer()) +
1461                   head.position());
1462
1463    uint32_t framesLeftInHead = ((head.buffer()->size() - head.position()) /
1464                                 mFrameSize);
1465    size_t framesRequested = buffer->frameCount;
1466    buffer->frameCount = min(framesLeftInHead, framesRequested);
1467
1468    mQueueHeadInFlight = true;
1469    mTimedAudioOutputOnTime = true;
1470}
1471
1472// Yield samples of silence up to the given output buffer's capacity
1473//
1474// Caller must hold mTimedBufferQueueLock
1475void AudioFlinger::PlaybackThread::TimedTrack::timedYieldSilence_l(
1476    uint32_t numFrames, AudioBufferProvider::Buffer* buffer) {
1477
1478    // lazily allocate a buffer filled with silence
1479    if (mTimedSilenceBufferSize < numFrames * mFrameSize) {
1480        delete [] mTimedSilenceBuffer;
1481        mTimedSilenceBufferSize = numFrames * mFrameSize;
1482        mTimedSilenceBuffer = new uint8_t[mTimedSilenceBufferSize];
1483        memset(mTimedSilenceBuffer, 0, mTimedSilenceBufferSize);
1484    }
1485
1486    buffer->raw = mTimedSilenceBuffer;
1487    size_t framesRequested = buffer->frameCount;
1488    buffer->frameCount = min(numFrames, framesRequested);
1489
1490    mTimedAudioOutputOnTime = false;
1491}
1492
1493// AudioBufferProvider interface
1494void AudioFlinger::PlaybackThread::TimedTrack::releaseBuffer(
1495    AudioBufferProvider::Buffer* buffer) {
1496
1497    Mutex::Autolock _l(mTimedBufferQueueLock);
1498
1499    // If the buffer which was just released is part of the buffer at the head
1500    // of the queue, be sure to update the amt of the buffer which has been
1501    // consumed.  If the buffer being returned is not part of the head of the
1502    // queue, its either because the buffer is part of the silence buffer, or
1503    // because the head of the timed queue was trimmed after the mixer called
1504    // getNextBuffer but before the mixer called releaseBuffer.
1505    if (buffer->raw == mTimedSilenceBuffer) {
1506        ALOG_ASSERT(!mQueueHeadInFlight,
1507                    "Queue head in flight during release of silence buffer!");
1508        goto done;
1509    }
1510
1511    ALOG_ASSERT(mQueueHeadInFlight,
1512                "TimedTrack::releaseBuffer of non-silence buffer, but no queue"
1513                " head in flight.");
1514
1515    if (mTimedBufferQueue.size()) {
1516        TimedBuffer& head = mTimedBufferQueue.editItemAt(0);
1517
1518        void* start = head.buffer()->pointer();
1519        void* end   = reinterpret_cast<void*>(
1520                        reinterpret_cast<uint8_t*>(head.buffer()->pointer())
1521                        + head.buffer()->size());
1522
1523        ALOG_ASSERT((buffer->raw >= start) && (buffer->raw < end),
1524                    "released buffer not within the head of the timed buffer"
1525                    " queue; qHead = [%p, %p], released buffer = %p",
1526                    start, end, buffer->raw);
1527
1528        head.setPosition(head.position() +
1529                (buffer->frameCount * mFrameSize));
1530        mQueueHeadInFlight = false;
1531
1532        ALOG_ASSERT(mFramesPendingInQueue >= buffer->frameCount,
1533                    "Bad bookkeeping during releaseBuffer!  Should have at"
1534                    " least %u queued frames, but we think we have only %u",
1535                    buffer->frameCount, mFramesPendingInQueue);
1536
1537        mFramesPendingInQueue -= buffer->frameCount;
1538
1539        if ((static_cast<size_t>(head.position()) >= head.buffer()->size())
1540            || mTrimQueueHeadOnRelease) {
1541            trimTimedBufferQueueHead_l("releaseBuffer");
1542            mTrimQueueHeadOnRelease = false;
1543        }
1544    } else {
1545        LOG_ALWAYS_FATAL("TimedTrack::releaseBuffer of non-silence buffer with no"
1546                  " buffers in the timed buffer queue");
1547    }
1548
1549done:
1550    buffer->raw = 0;
1551    buffer->frameCount = 0;
1552}
1553
1554size_t AudioFlinger::PlaybackThread::TimedTrack::framesReady() const {
1555    Mutex::Autolock _l(mTimedBufferQueueLock);
1556    return mFramesPendingInQueue;
1557}
1558
1559AudioFlinger::PlaybackThread::TimedTrack::TimedBuffer::TimedBuffer()
1560        : mPTS(0), mPosition(0) {}
1561
1562AudioFlinger::PlaybackThread::TimedTrack::TimedBuffer::TimedBuffer(
1563    const sp<IMemory>& buffer, int64_t pts)
1564        : mBuffer(buffer), mPTS(pts), mPosition(0) {}
1565
1566
1567// ----------------------------------------------------------------------------
1568
1569AudioFlinger::PlaybackThread::OutputTrack::OutputTrack(
1570            PlaybackThread *playbackThread,
1571            DuplicatingThread *sourceThread,
1572            uint32_t sampleRate,
1573            audio_format_t format,
1574            audio_channel_mask_t channelMask,
1575            size_t frameCount,
1576            int uid)
1577    :   Track(playbackThread, NULL, AUDIO_STREAM_CNT, sampleRate, format, channelMask, frameCount,
1578                NULL, 0, uid, IAudioFlinger::TRACK_DEFAULT),
1579    mActive(false), mSourceThread(sourceThread), mClientProxy(NULL)
1580{
1581
1582    if (mCblk != NULL) {
1583        mOutBuffer.frameCount = 0;
1584        playbackThread->mTracks.add(this);
1585        ALOGV("OutputTrack constructor mCblk %p, mBuffer %p, "
1586                "frameCount %u, mChannelMask 0x%08x",
1587                mCblk, mBuffer,
1588                frameCount, mChannelMask);
1589        // since client and server are in the same process,
1590        // the buffer has the same virtual address on both sides
1591        mClientProxy = new AudioTrackClientProxy(mCblk, mBuffer, mFrameCount, mFrameSize);
1592        mClientProxy->setVolumeLR((uint32_t(uint16_t(0x1000)) << 16) | uint16_t(0x1000));
1593        mClientProxy->setSendLevel(0.0);
1594        mClientProxy->setSampleRate(sampleRate);
1595        mClientProxy = new AudioTrackClientProxy(mCblk, mBuffer, mFrameCount, mFrameSize,
1596                true /*clientInServer*/);
1597    } else {
1598        ALOGW("Error creating output track on thread %p", playbackThread);
1599    }
1600}
1601
1602AudioFlinger::PlaybackThread::OutputTrack::~OutputTrack()
1603{
1604    clearBufferQueue();
1605    delete mClientProxy;
1606    // superclass destructor will now delete the server proxy and shared memory both refer to
1607}
1608
1609status_t AudioFlinger::PlaybackThread::OutputTrack::start(AudioSystem::sync_event_t event,
1610                                                          int triggerSession)
1611{
1612    status_t status = Track::start(event, triggerSession);
1613    if (status != NO_ERROR) {
1614        return status;
1615    }
1616
1617    mActive = true;
1618    mRetryCount = 127;
1619    return status;
1620}
1621
1622void AudioFlinger::PlaybackThread::OutputTrack::stop()
1623{
1624    Track::stop();
1625    clearBufferQueue();
1626    mOutBuffer.frameCount = 0;
1627    mActive = false;
1628}
1629
1630bool AudioFlinger::PlaybackThread::OutputTrack::write(int16_t* data, uint32_t frames)
1631{
1632    Buffer *pInBuffer;
1633    Buffer inBuffer;
1634    uint32_t channelCount = mChannelCount;
1635    bool outputBufferFull = false;
1636    inBuffer.frameCount = frames;
1637    inBuffer.i16 = data;
1638
1639    uint32_t waitTimeLeftMs = mSourceThread->waitTimeMs();
1640
1641    if (!mActive && frames != 0) {
1642        start();
1643        sp<ThreadBase> thread = mThread.promote();
1644        if (thread != 0) {
1645            MixerThread *mixerThread = (MixerThread *)thread.get();
1646            if (mFrameCount > frames) {
1647                if (mBufferQueue.size() < kMaxOverFlowBuffers) {
1648                    uint32_t startFrames = (mFrameCount - frames);
1649                    pInBuffer = new Buffer;
1650                    pInBuffer->mBuffer = new int16_t[startFrames * channelCount];
1651                    pInBuffer->frameCount = startFrames;
1652                    pInBuffer->i16 = pInBuffer->mBuffer;
1653                    memset(pInBuffer->raw, 0, startFrames * channelCount * sizeof(int16_t));
1654                    mBufferQueue.add(pInBuffer);
1655                } else {
1656                    ALOGW("OutputTrack::write() %p no more buffers in queue", this);
1657                }
1658            }
1659        }
1660    }
1661
1662    while (waitTimeLeftMs) {
1663        // First write pending buffers, then new data
1664        if (mBufferQueue.size()) {
1665            pInBuffer = mBufferQueue.itemAt(0);
1666        } else {
1667            pInBuffer = &inBuffer;
1668        }
1669
1670        if (pInBuffer->frameCount == 0) {
1671            break;
1672        }
1673
1674        if (mOutBuffer.frameCount == 0) {
1675            mOutBuffer.frameCount = pInBuffer->frameCount;
1676            nsecs_t startTime = systemTime();
1677            status_t status = obtainBuffer(&mOutBuffer, waitTimeLeftMs);
1678            if (status != NO_ERROR) {
1679                ALOGV("OutputTrack::write() %p thread %p no more output buffers; status %d", this,
1680                        mThread.unsafe_get(), status);
1681                outputBufferFull = true;
1682                break;
1683            }
1684            uint32_t waitTimeMs = (uint32_t)ns2ms(systemTime() - startTime);
1685            if (waitTimeLeftMs >= waitTimeMs) {
1686                waitTimeLeftMs -= waitTimeMs;
1687            } else {
1688                waitTimeLeftMs = 0;
1689            }
1690        }
1691
1692        uint32_t outFrames = pInBuffer->frameCount > mOutBuffer.frameCount ? mOutBuffer.frameCount :
1693                pInBuffer->frameCount;
1694        memcpy(mOutBuffer.raw, pInBuffer->raw, outFrames * channelCount * sizeof(int16_t));
1695        Proxy::Buffer buf;
1696        buf.mFrameCount = outFrames;
1697        buf.mRaw = NULL;
1698        mClientProxy->releaseBuffer(&buf);
1699        pInBuffer->frameCount -= outFrames;
1700        pInBuffer->i16 += outFrames * channelCount;
1701        mOutBuffer.frameCount -= outFrames;
1702        mOutBuffer.i16 += outFrames * channelCount;
1703
1704        if (pInBuffer->frameCount == 0) {
1705            if (mBufferQueue.size()) {
1706                mBufferQueue.removeAt(0);
1707                delete [] pInBuffer->mBuffer;
1708                delete pInBuffer;
1709                ALOGV("OutputTrack::write() %p thread %p released overflow buffer %d", this,
1710                        mThread.unsafe_get(), mBufferQueue.size());
1711            } else {
1712                break;
1713            }
1714        }
1715    }
1716
1717    // If we could not write all frames, allocate a buffer and queue it for next time.
1718    if (inBuffer.frameCount) {
1719        sp<ThreadBase> thread = mThread.promote();
1720        if (thread != 0 && !thread->standby()) {
1721            if (mBufferQueue.size() < kMaxOverFlowBuffers) {
1722                pInBuffer = new Buffer;
1723                pInBuffer->mBuffer = new int16_t[inBuffer.frameCount * channelCount];
1724                pInBuffer->frameCount = inBuffer.frameCount;
1725                pInBuffer->i16 = pInBuffer->mBuffer;
1726                memcpy(pInBuffer->raw, inBuffer.raw, inBuffer.frameCount * channelCount *
1727                        sizeof(int16_t));
1728                mBufferQueue.add(pInBuffer);
1729                ALOGV("OutputTrack::write() %p thread %p adding overflow buffer %d", this,
1730                        mThread.unsafe_get(), mBufferQueue.size());
1731            } else {
1732                ALOGW("OutputTrack::write() %p thread %p no more overflow buffers",
1733                        mThread.unsafe_get(), this);
1734            }
1735        }
1736    }
1737
1738    // Calling write() with a 0 length buffer, means that no more data will be written:
1739    // If no more buffers are pending, fill output track buffer to make sure it is started
1740    // by output mixer.
1741    if (frames == 0 && mBufferQueue.size() == 0) {
1742        // FIXME borken, replace by getting framesReady() from proxy
1743        size_t user = 0;    // was mCblk->user
1744        if (user < mFrameCount) {
1745            frames = mFrameCount - user;
1746            pInBuffer = new Buffer;
1747            pInBuffer->mBuffer = new int16_t[frames * channelCount];
1748            pInBuffer->frameCount = frames;
1749            pInBuffer->i16 = pInBuffer->mBuffer;
1750            memset(pInBuffer->raw, 0, frames * channelCount * sizeof(int16_t));
1751            mBufferQueue.add(pInBuffer);
1752        } else if (mActive) {
1753            stop();
1754        }
1755    }
1756
1757    return outputBufferFull;
1758}
1759
1760status_t AudioFlinger::PlaybackThread::OutputTrack::obtainBuffer(
1761        AudioBufferProvider::Buffer* buffer, uint32_t waitTimeMs)
1762{
1763    ClientProxy::Buffer buf;
1764    buf.mFrameCount = buffer->frameCount;
1765    struct timespec timeout;
1766    timeout.tv_sec = waitTimeMs / 1000;
1767    timeout.tv_nsec = (int) (waitTimeMs % 1000) * 1000000;
1768    status_t status = mClientProxy->obtainBuffer(&buf, &timeout);
1769    buffer->frameCount = buf.mFrameCount;
1770    buffer->raw = buf.mRaw;
1771    return status;
1772}
1773
1774void AudioFlinger::PlaybackThread::OutputTrack::clearBufferQueue()
1775{
1776    size_t size = mBufferQueue.size();
1777
1778    for (size_t i = 0; i < size; i++) {
1779        Buffer *pBuffer = mBufferQueue.itemAt(i);
1780        delete [] pBuffer->mBuffer;
1781        delete pBuffer;
1782    }
1783    mBufferQueue.clear();
1784}
1785
1786
1787// ----------------------------------------------------------------------------
1788//      Record
1789// ----------------------------------------------------------------------------
1790
1791AudioFlinger::RecordHandle::RecordHandle(
1792        const sp<AudioFlinger::RecordThread::RecordTrack>& recordTrack)
1793    : BnAudioRecord(),
1794    mRecordTrack(recordTrack)
1795{
1796}
1797
1798AudioFlinger::RecordHandle::~RecordHandle() {
1799    stop_nonvirtual();
1800    mRecordTrack->destroy();
1801}
1802
1803sp<IMemory> AudioFlinger::RecordHandle::getCblk() const {
1804    return mRecordTrack->getCblk();
1805}
1806
1807status_t AudioFlinger::RecordHandle::start(int /*AudioSystem::sync_event_t*/ event,
1808        int triggerSession) {
1809    ALOGV("RecordHandle::start()");
1810    return mRecordTrack->start((AudioSystem::sync_event_t)event, triggerSession);
1811}
1812
1813void AudioFlinger::RecordHandle::stop() {
1814    stop_nonvirtual();
1815}
1816
1817void AudioFlinger::RecordHandle::stop_nonvirtual() {
1818    ALOGV("RecordHandle::stop()");
1819    mRecordTrack->stop();
1820}
1821
1822status_t AudioFlinger::RecordHandle::onTransact(
1823    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
1824{
1825    return BnAudioRecord::onTransact(code, data, reply, flags);
1826}
1827
1828// ----------------------------------------------------------------------------
1829
1830// RecordTrack constructor must be called with AudioFlinger::mLock and ThreadBase::mLock held
1831AudioFlinger::RecordThread::RecordTrack::RecordTrack(
1832            RecordThread *thread,
1833            const sp<Client>& client,
1834            uint32_t sampleRate,
1835            audio_format_t format,
1836            audio_channel_mask_t channelMask,
1837            size_t frameCount,
1838            int sessionId,
1839            int uid,
1840            bool isFast)
1841    :   TrackBase(thread, client, sampleRate, format,
1842                  channelMask, frameCount, 0 /*sharedBuffer*/, sessionId, uid, false /*isOut*/,
1843                  isFast /*useReadOnlyHeap*/),
1844        mOverflow(false), mResampler(NULL), mRsmpOutBuffer(NULL), mRsmpOutFrameCount(0),
1845        // See real initialization of mRsmpInFront at RecordThread::start()
1846        mRsmpInUnrel(0), mRsmpInFront(0), mFramesToDrop(0), mResamplerBufferProvider(NULL)
1847{
1848    if (mCblk == NULL) {
1849        return;
1850    }
1851
1852    mServerProxy = new AudioRecordServerProxy(mCblk, mBuffer, frameCount, mFrameSize);
1853
1854    uint32_t channelCount = popcount(channelMask);
1855    // FIXME I don't understand either of the channel count checks
1856    if (thread->mSampleRate != sampleRate && thread->mChannelCount <= FCC_2 &&
1857            channelCount <= FCC_2) {
1858        // sink SR
1859        mResampler = AudioResampler::create(16, thread->mChannelCount, sampleRate);
1860        // source SR
1861        mResampler->setSampleRate(thread->mSampleRate);
1862        mResampler->setVolume(AudioMixer::UNITY_GAIN, AudioMixer::UNITY_GAIN);
1863        mResamplerBufferProvider = new ResamplerBufferProvider(this);
1864    }
1865}
1866
1867AudioFlinger::RecordThread::RecordTrack::~RecordTrack()
1868{
1869    ALOGV("%s", __func__);
1870    delete mResampler;
1871    delete[] mRsmpOutBuffer;
1872    delete mResamplerBufferProvider;
1873}
1874
1875// AudioBufferProvider interface
1876status_t AudioFlinger::RecordThread::RecordTrack::getNextBuffer(AudioBufferProvider::Buffer* buffer,
1877        int64_t pts __unused)
1878{
1879    ServerProxy::Buffer buf;
1880    buf.mFrameCount = buffer->frameCount;
1881    status_t status = mServerProxy->obtainBuffer(&buf);
1882    buffer->frameCount = buf.mFrameCount;
1883    buffer->raw = buf.mRaw;
1884    if (buf.mFrameCount == 0) {
1885        // FIXME also wake futex so that overrun is noticed more quickly
1886        (void) android_atomic_or(CBLK_OVERRUN, &mCblk->mFlags);
1887    }
1888    return status;
1889}
1890
1891status_t AudioFlinger::RecordThread::RecordTrack::start(AudioSystem::sync_event_t event,
1892                                                        int triggerSession)
1893{
1894    sp<ThreadBase> thread = mThread.promote();
1895    if (thread != 0) {
1896        RecordThread *recordThread = (RecordThread *)thread.get();
1897        return recordThread->start(this, event, triggerSession);
1898    } else {
1899        return BAD_VALUE;
1900    }
1901}
1902
1903void AudioFlinger::RecordThread::RecordTrack::stop()
1904{
1905    sp<ThreadBase> thread = mThread.promote();
1906    if (thread != 0) {
1907        RecordThread *recordThread = (RecordThread *)thread.get();
1908        if (recordThread->stop(this)) {
1909            AudioSystem::stopInput(recordThread->id());
1910        }
1911    }
1912}
1913
1914void AudioFlinger::RecordThread::RecordTrack::destroy()
1915{
1916    // see comments at AudioFlinger::PlaybackThread::Track::destroy()
1917    sp<RecordTrack> keep(this);
1918    {
1919        sp<ThreadBase> thread = mThread.promote();
1920        if (thread != 0) {
1921            if (mState == ACTIVE || mState == RESUMING) {
1922                AudioSystem::stopInput(thread->id());
1923            }
1924            AudioSystem::releaseInput(thread->id());
1925            Mutex::Autolock _l(thread->mLock);
1926            RecordThread *recordThread = (RecordThread *) thread.get();
1927            recordThread->destroyTrack_l(this);
1928        }
1929    }
1930}
1931
1932void AudioFlinger::RecordThread::RecordTrack::invalidate()
1933{
1934    // FIXME should use proxy, and needs work
1935    audio_track_cblk_t* cblk = mCblk;
1936    android_atomic_or(CBLK_INVALID, &cblk->mFlags);
1937    android_atomic_release_store(0x40000000, &cblk->mFutex);
1938    // client is not in server, so FUTEX_WAKE is needed instead of FUTEX_WAKE_PRIVATE
1939    (void) __futex_syscall3(&cblk->mFutex, FUTEX_WAKE, INT_MAX);
1940}
1941
1942
1943/*static*/ void AudioFlinger::RecordThread::RecordTrack::appendDumpHeader(String8& result)
1944{
1945    result.append("    Active Client Fmt Chn mask Session S   Server fCount Resampling\n");
1946}
1947
1948void AudioFlinger::RecordThread::RecordTrack::dump(char* buffer, size_t size, bool active)
1949{
1950    snprintf(buffer, size, "    %6s %6u %3u %08X %7u %1d %08X %6zu %10d\n",
1951            active ? "yes" : "no",
1952            (mClient == 0) ? getpid_cached : mClient->pid(),
1953            mFormat,
1954            mChannelMask,
1955            mSessionId,
1956            mState,
1957            mCblk->mServer,
1958            mFrameCount,
1959            mResampler != NULL);
1960
1961}
1962
1963void AudioFlinger::RecordThread::RecordTrack::handleSyncStartEvent(const sp<SyncEvent>& event)
1964{
1965    if (event == mSyncStartEvent) {
1966        ssize_t framesToDrop = 0;
1967        sp<ThreadBase> threadBase = mThread.promote();
1968        if (threadBase != 0) {
1969            // TODO: use actual buffer filling status instead of 2 buffers when info is available
1970            // from audio HAL
1971            framesToDrop = threadBase->mFrameCount * 2;
1972        }
1973        mFramesToDrop = framesToDrop;
1974    }
1975}
1976
1977void AudioFlinger::RecordThread::RecordTrack::clearSyncStartEvent()
1978{
1979    if (mSyncStartEvent != 0) {
1980        mSyncStartEvent->cancel();
1981        mSyncStartEvent.clear();
1982    }
1983    mFramesToDrop = 0;
1984}
1985
1986}; // namespace android
1987