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