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