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 21371eb9756c32109ea572b91216b19bb623f6d3fdAlex Ray#define ATRACE_TAG ATRACE_TAG_AUDIO 2281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 23153b9fe667e6e78e0218ff0159353097428c7657Glenn Kasten#include "Configuration.h" 2481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent#include <math.h> 2581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent#include <fcntl.h> 26ad8510a339ffab330c2c46e5c247dd1cf9e15c22Glenn Kasten#include <linux/futex.h> 2781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent#include <sys/stat.h> 28ad8510a339ffab330c2c46e5c247dd1cf9e15c22Glenn Kasten#include <sys/syscall.h> 2981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent#include <cutils/properties.h> 301ab85ec401801ef9a9184650d0f5a1639b45eeb9Glenn Kasten#include <media/AudioParameter.h> 31cd04484f4837b8ca0041d118286ab6a98e84fc75Andy Hung#include <media/AudioResamplerPublic.h> 328981605d43e24c46d395acb5f145b99589d45917Andy Hung#include <media/RecordBufferConverter.h> 33913d06c099bd689375483a839e11057ccf284d1cMikhail Naganov#include <media/TypeConverter.h> 3481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent#include <utils/Log.h> 35371eb9756c32109ea572b91216b19bb623f6d3fdAlex Ray#include <utils/Trace.h> 3681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 3781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent#include <private/media/AudioTrackShared.h> 38f2ae3e19080938db8cbf29a963fd744a3964fcc2Wei Jia#include <private/android_filesystem_config.h> 396bf707f4c0752643757a7389384817da41d34fabGlenn Kasten#include <audio_utils/mono_blend.h> 4081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent#include <audio_utils/primitives.h> 4198ef978df4e928f486d244c4d7f7ad9f13111e98Andy Hung#include <audio_utils/format.h> 42c56f3426099a3cf2d07ccff8886050c7fbce140fGlenn Kasten#include <audio_utils/minifloat.h> 439fe94012187a29eeeca2c74e75f121192560fba0Mikhail Naganov#include <system/audio_effects/effect_ns.h> 449fe94012187a29eeeca2c74e75f121192560fba0Mikhail Naganov#include <system/audio_effects/effect_aec.h> 45cbc8f617c1aebef5d041fa40dcd38a5466690b99Mikhail Naganov#include <system/audio.h> 4681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 4781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// NBAIO implementations 486dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten#include <media/nbaio/AudioStreamInSource.h> 4981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent#include <media/nbaio/AudioStreamOutSink.h> 5081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent#include <media/nbaio/MonoPipe.h> 5181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent#include <media/nbaio/MonoPipeReader.h> 5281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent#include <media/nbaio/Pipe.h> 5381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent#include <media/nbaio/PipeReader.h> 5481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent#include <media/nbaio/SourceAudioBufferProvider.h> 553f273d10817ddb2f792ae043de692efcdf1988aeWei Jia#include <mediautils/BatteryNotifier.h> 5681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 5781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent#include <powermanager/PowerManager.h> 5881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 5981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent#include "AudioFlinger.h" 6081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent#include "FastMixer.h" 616dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten#include "FastCapture.h" 6281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent#include "ServiceUtilities.h" 63f99498ee4de7123e2fd71778c6877be44fbd1506Eino-Ville Talvala#include "mediautils/SchedulingPolicyService.h" 6481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 6581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent#ifdef ADD_BATTERY_DATA 6681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent#include <media/IMediaPlayerService.h> 6781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent#include <media/IMediaDeathNotifier.h> 6881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent#endif 6981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 7081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent#ifdef DEBUG_CPU_USAGE 7181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent#include <cpustats/CentralTendencyStatistics.h> 7281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent#include <cpustats/ThreadCpuUsage.h> 7381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent#endif 7481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 75c05b8d7df46619d3474356241d47655478b8bc82Glenn Kasten#include "AutoPark.h" 76c05b8d7df46619d3474356241d47655478b8bc82Glenn Kasten 77fe1e1449cadff4f946c33403aecc73b4b4a11e56Nicolas Roulet#include <pthread.h> 78fe1e1449cadff4f946c33403aecc73b4b4a11e56Nicolas Roulet#include "TypedLogger.h" 79fe1e1449cadff4f946c33403aecc73b4b4a11e56Nicolas Roulet 8081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// ---------------------------------------------------------------------------- 8181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 8281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// Note: the following macro is used for extremely verbose logging message. In 8381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// order to run with ALOG_ASSERT turned on, we need to have LOG_NDEBUG set to 8481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// 0; but one side effect of this is to turn all LOGV's as well. Some messages 8581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// are so verbose that we want to suppress them even when we have ALOG_ASSERT 8681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// turned on. Do not uncomment the #def below unless you really know what you 8781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// are doing and want to see all of the extremely verbose messages. 8881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent//#define VERY_VERY_VERBOSE_LOGGING 8981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent#ifdef VERY_VERY_VERBOSE_LOGGING 9081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent#define ALOGVV ALOGV 9181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent#else 9281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent#define ALOGVV(a...) do { } while(0) 9381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent#endif 9481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 956770c6faa3467c92eabc5ec9b23d60eb556a0d03Andy Hung// TODO: Move these macro/inlines to a header file. 9649d00ad9164ea5ce48c85765a2b6460d9b457d38Glenn Kasten#define max(a, b) ((a) > (b) ? (a) : (b)) 976770c6faa3467c92eabc5ec9b23d60eb556a0d03Andy Hungtemplate <typename T> 986770c6faa3467c92eabc5ec9b23d60eb556a0d03Andy Hungstatic inline T min(const T& a, const T& b) 996770c6faa3467c92eabc5ec9b23d60eb556a0d03Andy Hung{ 1006770c6faa3467c92eabc5ec9b23d60eb556a0d03Andy Hung return a < b ? a : b; 1016770c6faa3467c92eabc5ec9b23d60eb556a0d03Andy Hung} 10249d00ad9164ea5ce48c85765a2b6460d9b457d38Glenn Kasten 103d330ee46022f34da76d14d0c4d2910526ecc2321Andy Hung#ifndef ARRAY_SIZE 104bf29173d6d63536ae9f8cfd1d02153237ee23612Chih-Hung Hsieh#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0])) 105d330ee46022f34da76d14d0c4d2910526ecc2321Andy Hung#endif 106d330ee46022f34da76d14d0c4d2910526ecc2321Andy Hung 10781784c37c61b09289654b979567a42bf73cd2b12Eric Laurentnamespace android { 10881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 10981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// retry counts for buffer fill timeout 11081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// 50 * ~20msecs = 1 second 11181784c37c61b09289654b979567a42bf73cd2b12Eric Laurentstatic const int8_t kMaxTrackRetries = 50; 11281784c37c61b09289654b979567a42bf73cd2b12Eric Laurentstatic const int8_t kMaxTrackStartupRetries = 50; 11381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// allow less retry attempts on direct output thread. 11481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// direct outputs can be a scarce resource in audio hardware and should 11581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// be released as quickly as possible. 11681784c37c61b09289654b979567a42bf73cd2b12Eric Laurentstatic const int8_t kMaxTrackRetriesDirect = 2; 117e93cc03da360a1a0d2ad937c745ce8c8e8be81c2Eric Laurent 118517161856d74f5fe39cce131f29b977bc1745991Eric Laurent 11981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 12081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// don't warn about blocked writes or record buffer overflows more often than this 12181784c37c61b09289654b979567a42bf73cd2b12Eric Laurentstatic const nsecs_t kWarningThrottleNs = seconds(5); 12281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 12381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// RecordThread loop sleep time upon application overrun or audio HAL read error 12481784c37c61b09289654b979567a42bf73cd2b12Eric Laurentstatic const int kRecordThreadSleepUs = 5000; 12581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 1261035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent// maximum time to wait in sendConfigEvent_l() for a status to be received 1271035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurentstatic const nsecs_t kConfigEventTimeoutNs = seconds(2); 12881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 12981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// minimum sleep time for the mixer thread loop when tracks are active but in underrun 13081784c37c61b09289654b979567a42bf73cd2b12Eric Laurentstatic const uint32_t kMinThreadSleepTimeUs = 5000; 13181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// maximum divider applied to the active sleep time in the mixer thread loop 13281784c37c61b09289654b979567a42bf73cd2b12Eric Laurentstatic const uint32_t kMaxThreadSleepTimeShift = 2; 13381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 13409a5007b17acb49d25cfa386a2e2534d942e8854Andy Hung// minimum normal sink buffer size, expressed in milliseconds rather than frames 135eb9487e10294a4e73977f460f30eeaff503acd21Glenn Kasten// FIXME This should be based on experimentally observed scheduling jitter 13609a5007b17acb49d25cfa386a2e2534d942e8854Andy Hungstatic const uint32_t kMinNormalSinkBufferSizeMs = 20; 13709a5007b17acb49d25cfa386a2e2534d942e8854Andy Hung// maximum normal sink buffer size 13809a5007b17acb49d25cfa386a2e2534d942e8854Andy Hungstatic const uint32_t kMaxNormalSinkBufferSizeMs = 24; 13981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 140eb9487e10294a4e73977f460f30eeaff503acd21Glenn Kasten// minimum capture buffer size in milliseconds to _not_ need a fast capture thread 141eb9487e10294a4e73977f460f30eeaff503acd21Glenn Kasten// FIXME This should be based on experimentally observed scheduling jitter 142eb9487e10294a4e73977f460f30eeaff503acd21Glenn Kastenstatic const uint32_t kMinNormalCaptureBufferSizeMs = 12; 143eb9487e10294a4e73977f460f30eeaff503acd21Glenn Kasten 144972a173d7d1de1a3b5a617aae3e2abb6e05ae02dEric Laurent// Offloaded output thread standby delay: allows track transition without going to standby 145972a173d7d1de1a3b5a617aae3e2abb6e05ae02dEric Laurentstatic const nsecs_t kOffloadStandbyDelayNs = seconds(1); 146972a173d7d1de1a3b5a617aae3e2abb6e05ae02dEric Laurent 147517161856d74f5fe39cce131f29b977bc1745991Eric Laurent// Direct output thread minimum sleep time in idle or active(underrun) state 148517161856d74f5fe39cce131f29b977bc1745991Eric Laurentstatic const nsecs_t kDirectMinSleepTimeUs = 10000; 149517161856d74f5fe39cce131f29b977bc1745991Eric Laurent 1501b291841a58ce6b2b291232dfdd56134b2185c48Glenn Kasten// The universal constant for ubiquitous 20ms value. The value of 20ms seems to provide a good 1511b291841a58ce6b2b291232dfdd56134b2185c48Glenn Kasten// balance between power consumption and latency, and allows threads to be scheduled reliably 1521b291841a58ce6b2b291232dfdd56134b2185c48Glenn Kasten// by the CFS scheduler. 1531b291841a58ce6b2b291232dfdd56134b2185c48Glenn Kasten// FIXME Express other hardcoded references to 20ms with references to this constant and move 1541b291841a58ce6b2b291232dfdd56134b2185c48Glenn Kasten// it appropriately. 1551b291841a58ce6b2b291232dfdd56134b2185c48Glenn Kasten#define FMS_20 20 156517161856d74f5fe39cce131f29b977bc1745991Eric Laurent 15781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// Whether to use fast mixer 15881784c37c61b09289654b979567a42bf73cd2b12Eric Laurentstatic const enum { 15981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent FastMixer_Never, // never initialize or use: for debugging only 16081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent FastMixer_Always, // always initialize and use, even if not needed: for debugging only 16181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // normal mixer multiplier is 1 16281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent FastMixer_Static, // initialize if needed, then use all the time if initialized, 16381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // multiplier is calculated based on min & max normal mixer buffer size 16481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent FastMixer_Dynamic, // initialize if needed, then use dynamically depending on track load, 16581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // multiplier is calculated based on min & max normal mixer buffer size 16681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // FIXME for FastMixer_Dynamic: 16781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // Supporting this option will require fixing HALs that can't handle large writes. 16881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // For example, one HAL implementation returns an error from a large write, 16981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // and another HAL implementation corrupts memory, possibly in the sample rate converter. 17081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // We could either fix the HAL implementations, or provide a wrapper that breaks 17181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // up large writes into smaller ones, and the wrapper would need to deal with scheduler. 17281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} kUseFastMixer = FastMixer_Static; 17381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 1746dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten// Whether to use fast capture 1756dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kastenstatic const enum { 1766dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten FastCapture_Never, // never initialize or use: for debugging only 1776dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten FastCapture_Always, // always initialize and use, even if not needed: for debugging only 1786dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten FastCapture_Static, // initialize if needed, then use all the time if initialized 1796dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten} kUseFastCapture = FastCapture_Static; 1806dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten 18181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// Priorities for requestPriority 18281784c37c61b09289654b979567a42bf73cd2b12Eric Laurentstatic const int kPriorityAudioApp = 2; 18381784c37c61b09289654b979567a42bf73cd2b12Eric Laurentstatic const int kPriorityFastMixer = 3; 1846dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kastenstatic const int kPriorityFastCapture = 3; 18581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 186ea38ee7742e799b23bd8675f5801ef72f94de0f4Glenn Kasten// IAudioFlinger::createTrack() has an in/out parameter 'pFrameCount' for the total size of the 187ea38ee7742e799b23bd8675f5801ef72f94de0f4Glenn Kasten// track buffer in shared memory. Zero on input means to use a default value. For fast tracks, 188ea38ee7742e799b23bd8675f5801ef72f94de0f4Glenn Kasten// AudioFlinger derives the default from HAL buffer size and 'fast track multiplier'. 1890349009fd19f89f8414c428f6b71b369f7546085Glenn Kasten 1900349009fd19f89f8414c428f6b71b369f7546085Glenn Kasten// This is the default value, if not specified by property. 191b5fed68bcdd6f44424c9e4d12bfe9a3ff51bd62eGlenn Kastenstatic const int kFastTrackMultiplier = 2; 19281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 1930349009fd19f89f8414c428f6b71b369f7546085Glenn Kasten// The minimum and maximum allowed values 1940349009fd19f89f8414c428f6b71b369f7546085Glenn Kastenstatic const int kFastTrackMultiplierMin = 1; 1950349009fd19f89f8414c428f6b71b369f7546085Glenn Kastenstatic const int kFastTrackMultiplierMax = 2; 1960349009fd19f89f8414c428f6b71b369f7546085Glenn Kasten 1970349009fd19f89f8414c428f6b71b369f7546085Glenn Kasten// The actual value to use, which can be specified per-device via property af.fast_track_multiplier. 1980349009fd19f89f8414c428f6b71b369f7546085Glenn Kastenstatic int sFastTrackMultiplier = kFastTrackMultiplier; 1990349009fd19f89f8414c428f6b71b369f7546085Glenn Kasten 200b880f5e5fc07397ddd09a94ba18bdf4fa62aae00Glenn Kasten// See Thread::readOnlyHeap(). 201b880f5e5fc07397ddd09a94ba18bdf4fa62aae00Glenn Kasten// Initially this heap is used to allocate client buffers for "fast" AudioRecord. 202b880f5e5fc07397ddd09a94ba18bdf4fa62aae00Glenn Kasten// Eventually it will be the single buffer that FastCapture writes into via HAL read(), 203b880f5e5fc07397ddd09a94ba18bdf4fa62aae00Glenn Kasten// and that all "fast" AudioRecord clients read from. In either case, the size can be small. 2049f81de3452dfb2385bd57dc05456a045174a1ab1Glenn Kastenstatic const size_t kRecordThreadReadOnlyHeapSize = 0x2000; 205b880f5e5fc07397ddd09a94ba18bdf4fa62aae00Glenn Kasten 20681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// ---------------------------------------------------------------------------- 20781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 2080349009fd19f89f8414c428f6b71b369f7546085Glenn Kastenstatic pthread_once_t sFastTrackMultiplierOnce = PTHREAD_ONCE_INIT; 2090349009fd19f89f8414c428f6b71b369f7546085Glenn Kasten 2100349009fd19f89f8414c428f6b71b369f7546085Glenn Kastenstatic void sFastTrackMultiplierInit() 2110349009fd19f89f8414c428f6b71b369f7546085Glenn Kasten{ 2120349009fd19f89f8414c428f6b71b369f7546085Glenn Kasten char value[PROPERTY_VALUE_MAX]; 2130349009fd19f89f8414c428f6b71b369f7546085Glenn Kasten if (property_get("af.fast_track_multiplier", value, NULL) > 0) { 2140349009fd19f89f8414c428f6b71b369f7546085Glenn Kasten char *endptr; 2150349009fd19f89f8414c428f6b71b369f7546085Glenn Kasten unsigned long ul = strtoul(value, &endptr, 0); 2160349009fd19f89f8414c428f6b71b369f7546085Glenn Kasten if (*endptr == '\0' && kFastTrackMultiplierMin <= ul && ul <= kFastTrackMultiplierMax) { 2170349009fd19f89f8414c428f6b71b369f7546085Glenn Kasten sFastTrackMultiplier = (int) ul; 2180349009fd19f89f8414c428f6b71b369f7546085Glenn Kasten } 2190349009fd19f89f8414c428f6b71b369f7546085Glenn Kasten } 2200349009fd19f89f8414c428f6b71b369f7546085Glenn Kasten} 2210349009fd19f89f8414c428f6b71b369f7546085Glenn Kasten 2220349009fd19f89f8414c428f6b71b369f7546085Glenn Kasten// ---------------------------------------------------------------------------- 2230349009fd19f89f8414c428f6b71b369f7546085Glenn Kasten 22481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent#ifdef ADD_BATTERY_DATA 22581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// To collect the amplifier usage 22681784c37c61b09289654b979567a42bf73cd2b12Eric Laurentstatic void addBatteryData(uint32_t params) { 22781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent sp<IMediaPlayerService> service = IMediaDeathNotifier::getMediaPlayerService(); 22881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (service == NULL) { 22981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // it already logged 23081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent return; 23181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 23281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 23381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent service->addBatteryData(params); 23481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 23581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent#endif 23681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 2373f0c902beb53a245c9db35e871607dba05b8d391Andy Hung// Track the CLOCK_BOOTTIME versus CLOCK_MONOTONIC timebase offset 2383f0c902beb53a245c9db35e871607dba05b8d391Andy Hungstruct { 2393f0c902beb53a245c9db35e871607dba05b8d391Andy Hung // call when you acquire a partial wakelock 2403f0c902beb53a245c9db35e871607dba05b8d391Andy Hung void acquire(const sp<IBinder> &wakeLockToken) { 2413f0c902beb53a245c9db35e871607dba05b8d391Andy Hung pthread_mutex_lock(&mLock); 2423f0c902beb53a245c9db35e871607dba05b8d391Andy Hung if (wakeLockToken.get() == nullptr) { 2433f0c902beb53a245c9db35e871607dba05b8d391Andy Hung adjustTimebaseOffset(&mBoottimeOffset, ExtendedTimestamp::TIMEBASE_BOOTTIME); 2443f0c902beb53a245c9db35e871607dba05b8d391Andy Hung } else { 2453f0c902beb53a245c9db35e871607dba05b8d391Andy Hung if (mCount == 0) { 2463f0c902beb53a245c9db35e871607dba05b8d391Andy Hung adjustTimebaseOffset(&mBoottimeOffset, ExtendedTimestamp::TIMEBASE_BOOTTIME); 2473f0c902beb53a245c9db35e871607dba05b8d391Andy Hung } 2483f0c902beb53a245c9db35e871607dba05b8d391Andy Hung ++mCount; 2493f0c902beb53a245c9db35e871607dba05b8d391Andy Hung } 2503f0c902beb53a245c9db35e871607dba05b8d391Andy Hung pthread_mutex_unlock(&mLock); 2513f0c902beb53a245c9db35e871607dba05b8d391Andy Hung } 2523f0c902beb53a245c9db35e871607dba05b8d391Andy Hung 2533f0c902beb53a245c9db35e871607dba05b8d391Andy Hung // call when you release a partial wakelock. 2543f0c902beb53a245c9db35e871607dba05b8d391Andy Hung void release(const sp<IBinder> &wakeLockToken) { 2553f0c902beb53a245c9db35e871607dba05b8d391Andy Hung if (wakeLockToken.get() == nullptr) { 2563f0c902beb53a245c9db35e871607dba05b8d391Andy Hung return; 2573f0c902beb53a245c9db35e871607dba05b8d391Andy Hung } 2583f0c902beb53a245c9db35e871607dba05b8d391Andy Hung pthread_mutex_lock(&mLock); 2593f0c902beb53a245c9db35e871607dba05b8d391Andy Hung if (--mCount < 0) { 2603f0c902beb53a245c9db35e871607dba05b8d391Andy Hung ALOGE("negative wakelock count"); 2613f0c902beb53a245c9db35e871607dba05b8d391Andy Hung mCount = 0; 2623f0c902beb53a245c9db35e871607dba05b8d391Andy Hung } 2633f0c902beb53a245c9db35e871607dba05b8d391Andy Hung pthread_mutex_unlock(&mLock); 2643f0c902beb53a245c9db35e871607dba05b8d391Andy Hung } 2653f0c902beb53a245c9db35e871607dba05b8d391Andy Hung 2663f0c902beb53a245c9db35e871607dba05b8d391Andy Hung // retrieves the boottime timebase offset from monotonic. 2673f0c902beb53a245c9db35e871607dba05b8d391Andy Hung int64_t getBoottimeOffset() { 2683f0c902beb53a245c9db35e871607dba05b8d391Andy Hung pthread_mutex_lock(&mLock); 2693f0c902beb53a245c9db35e871607dba05b8d391Andy Hung int64_t boottimeOffset = mBoottimeOffset; 2703f0c902beb53a245c9db35e871607dba05b8d391Andy Hung pthread_mutex_unlock(&mLock); 2713f0c902beb53a245c9db35e871607dba05b8d391Andy Hung return boottimeOffset; 2723f0c902beb53a245c9db35e871607dba05b8d391Andy Hung } 2733f0c902beb53a245c9db35e871607dba05b8d391Andy Hung 2743f0c902beb53a245c9db35e871607dba05b8d391Andy Hung // Adjusts the timebase offset between TIMEBASE_MONOTONIC 2753f0c902beb53a245c9db35e871607dba05b8d391Andy Hung // and the selected timebase. 2763f0c902beb53a245c9db35e871607dba05b8d391Andy Hung // Currently only TIMEBASE_BOOTTIME is allowed. 2773f0c902beb53a245c9db35e871607dba05b8d391Andy Hung // 2783f0c902beb53a245c9db35e871607dba05b8d391Andy Hung // This only needs to be called upon acquiring the first partial wakelock 2793f0c902beb53a245c9db35e871607dba05b8d391Andy Hung // after all other partial wakelocks are released. 2803f0c902beb53a245c9db35e871607dba05b8d391Andy Hung // 2813f0c902beb53a245c9db35e871607dba05b8d391Andy Hung // We do an empirical measurement of the offset rather than parsing 2823f0c902beb53a245c9db35e871607dba05b8d391Andy Hung // /proc/timer_list since the latter is not a formal kernel ABI. 2833f0c902beb53a245c9db35e871607dba05b8d391Andy Hung static void adjustTimebaseOffset(int64_t *offset, ExtendedTimestamp::Timebase timebase) { 2843f0c902beb53a245c9db35e871607dba05b8d391Andy Hung int clockbase; 2853f0c902beb53a245c9db35e871607dba05b8d391Andy Hung switch (timebase) { 2863f0c902beb53a245c9db35e871607dba05b8d391Andy Hung case ExtendedTimestamp::TIMEBASE_BOOTTIME: 2873f0c902beb53a245c9db35e871607dba05b8d391Andy Hung clockbase = SYSTEM_TIME_BOOTTIME; 2883f0c902beb53a245c9db35e871607dba05b8d391Andy Hung break; 2893f0c902beb53a245c9db35e871607dba05b8d391Andy Hung default: 2903f0c902beb53a245c9db35e871607dba05b8d391Andy Hung LOG_ALWAYS_FATAL("invalid timebase %d", timebase); 2913f0c902beb53a245c9db35e871607dba05b8d391Andy Hung break; 2923f0c902beb53a245c9db35e871607dba05b8d391Andy Hung } 2933f0c902beb53a245c9db35e871607dba05b8d391Andy Hung // try three times to get the clock offset, choose the one 2943f0c902beb53a245c9db35e871607dba05b8d391Andy Hung // with the minimum gap in measurements. 2953f0c902beb53a245c9db35e871607dba05b8d391Andy Hung const int tries = 3; 2963f0c902beb53a245c9db35e871607dba05b8d391Andy Hung nsecs_t bestGap, measured; 2973f0c902beb53a245c9db35e871607dba05b8d391Andy Hung for (int i = 0; i < tries; ++i) { 2983f0c902beb53a245c9db35e871607dba05b8d391Andy Hung const nsecs_t tmono = systemTime(SYSTEM_TIME_MONOTONIC); 2993f0c902beb53a245c9db35e871607dba05b8d391Andy Hung const nsecs_t tbase = systemTime(clockbase); 3003f0c902beb53a245c9db35e871607dba05b8d391Andy Hung const nsecs_t tmono2 = systemTime(SYSTEM_TIME_MONOTONIC); 3013f0c902beb53a245c9db35e871607dba05b8d391Andy Hung const nsecs_t gap = tmono2 - tmono; 3023f0c902beb53a245c9db35e871607dba05b8d391Andy Hung if (i == 0 || gap < bestGap) { 3033f0c902beb53a245c9db35e871607dba05b8d391Andy Hung bestGap = gap; 3043f0c902beb53a245c9db35e871607dba05b8d391Andy Hung measured = tbase - ((tmono + tmono2) >> 1); 3053f0c902beb53a245c9db35e871607dba05b8d391Andy Hung } 3063f0c902beb53a245c9db35e871607dba05b8d391Andy Hung } 3073f0c902beb53a245c9db35e871607dba05b8d391Andy Hung 3083f0c902beb53a245c9db35e871607dba05b8d391Andy Hung // to avoid micro-adjusting, we don't change the timebase 3093f0c902beb53a245c9db35e871607dba05b8d391Andy Hung // unless it is significantly different. 3103f0c902beb53a245c9db35e871607dba05b8d391Andy Hung // 3113f0c902beb53a245c9db35e871607dba05b8d391Andy Hung // Assumption: It probably takes more than toleranceNs to 3123f0c902beb53a245c9db35e871607dba05b8d391Andy Hung // suspend and resume the device. 3133f0c902beb53a245c9db35e871607dba05b8d391Andy Hung static int64_t toleranceNs = 10000; // 10 us 3143f0c902beb53a245c9db35e871607dba05b8d391Andy Hung if (llabs(*offset - measured) > toleranceNs) { 3153f0c902beb53a245c9db35e871607dba05b8d391Andy Hung ALOGV("Adjusting timebase offset old: %lld new: %lld", 3163f0c902beb53a245c9db35e871607dba05b8d391Andy Hung (long long)*offset, (long long)measured); 3173f0c902beb53a245c9db35e871607dba05b8d391Andy Hung *offset = measured; 3183f0c902beb53a245c9db35e871607dba05b8d391Andy Hung } 3193f0c902beb53a245c9db35e871607dba05b8d391Andy Hung } 3203f0c902beb53a245c9db35e871607dba05b8d391Andy Hung 3213f0c902beb53a245c9db35e871607dba05b8d391Andy Hung pthread_mutex_t mLock; 3223f0c902beb53a245c9db35e871607dba05b8d391Andy Hung int32_t mCount; 3233f0c902beb53a245c9db35e871607dba05b8d391Andy Hung int64_t mBoottimeOffset; 3243f0c902beb53a245c9db35e871607dba05b8d391Andy Hung} gBoottime = { PTHREAD_MUTEX_INITIALIZER, 0, 0 }; // static, so use POD initialization 32581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 32681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// ---------------------------------------------------------------------------- 32781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// CPU Stats 32881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// ---------------------------------------------------------------------------- 32981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 33081784c37c61b09289654b979567a42bf73cd2b12Eric Laurentclass CpuStats { 33181784c37c61b09289654b979567a42bf73cd2b12Eric Laurentpublic: 33281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent CpuStats(); 33381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent void sample(const String8 &title); 33481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent#ifdef DEBUG_CPU_USAGE 33581784c37c61b09289654b979567a42bf73cd2b12Eric Laurentprivate: 33681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent ThreadCpuUsage mCpuUsage; // instantaneous thread CPU usage in wall clock ns 33781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent CentralTendencyStatistics mWcStats; // statistics on thread CPU usage in wall clock ns 33881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 33981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent CentralTendencyStatistics mHzStats; // statistics on thread CPU usage in cycles 34081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 34181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent int mCpuNum; // thread's current CPU number 34281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent int mCpukHz; // frequency of thread's current CPU in kHz 34381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent#endif 34481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}; 34581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 34681784c37c61b09289654b979567a42bf73cd2b12Eric LaurentCpuStats::CpuStats() 34781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent#ifdef DEBUG_CPU_USAGE 34881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent : mCpuNum(-1), mCpukHz(-1) 34981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent#endif 35081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 35181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 35281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 3530f11b51a57bc9062c4fe8af73747319cedabc5d6Glenn Kastenvoid CpuStats::sample(const String8 &title 3540f11b51a57bc9062c4fe8af73747319cedabc5d6Glenn Kasten#ifndef DEBUG_CPU_USAGE 3550f11b51a57bc9062c4fe8af73747319cedabc5d6Glenn Kasten __unused 3560f11b51a57bc9062c4fe8af73747319cedabc5d6Glenn Kasten#endif 3570f11b51a57bc9062c4fe8af73747319cedabc5d6Glenn Kasten ) { 35881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent#ifdef DEBUG_CPU_USAGE 35981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // get current thread's delta CPU time in wall clock ns 36081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent double wcNs; 36181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent bool valid = mCpuUsage.sampleAndEnable(wcNs); 36281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 36381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // record sample for wall clock statistics 36481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (valid) { 36581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mWcStats.sample(wcNs); 36681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 36781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 36881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // get the current CPU number 36981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent int cpuNum = sched_getcpu(); 37081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 37181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // get the current CPU frequency in kHz 37281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent int cpukHz = mCpuUsage.getCpukHz(cpuNum); 37381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 37481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // check if either CPU number or frequency changed 37581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (cpuNum != mCpuNum || cpukHz != mCpukHz) { 37681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mCpuNum = cpuNum; 37781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mCpukHz = cpukHz; 37881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // ignore sample for purposes of cycles 37981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent valid = false; 38081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 38181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 38281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // if no change in CPU number or frequency, then record sample for cycle statistics 38381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (valid && mCpukHz > 0) { 38481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent double cycles = wcNs * cpukHz * 0.000001; 38581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mHzStats.sample(cycles); 38681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 38781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 38881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent unsigned n = mWcStats.n(); 38981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // mCpuUsage.elapsed() is expensive, so don't call it every loop 39081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if ((n & 127) == 1) { 39181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent long long elapsed = mCpuUsage.elapsed(); 39281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (elapsed >= DEBUG_CPU_USAGE * 1000000000LL) { 39381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent double perLoop = elapsed / (double) n; 39481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent double perLoop100 = perLoop * 0.01; 39581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent double perLoop1k = perLoop * 0.001; 39681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent double mean = mWcStats.mean(); 39781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent double stddev = mWcStats.stddev(); 39881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent double minimum = mWcStats.minimum(); 39981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent double maximum = mWcStats.maximum(); 40081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent double meanCycles = mHzStats.mean(); 40181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent double stddevCycles = mHzStats.stddev(); 40281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent double minCycles = mHzStats.minimum(); 40381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent double maxCycles = mHzStats.maximum(); 40481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mCpuUsage.resetElapsed(); 40581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mWcStats.reset(); 40681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mHzStats.reset(); 40781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent ALOGD("CPU usage for %s over past %.1f secs\n" 40881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent " (%u mixer loops at %.1f mean ms per loop):\n" 40981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent " us per mix loop: mean=%.0f stddev=%.0f min=%.0f max=%.0f\n" 41081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent " %% of wall: mean=%.1f stddev=%.1f min=%.1f max=%.1f\n" 41181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent " MHz: mean=%.1f, stddev=%.1f, min=%.1f max=%.1f", 41281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent title.string(), 41381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent elapsed * .000000001, n, perLoop * .000001, 41481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mean * .001, 41581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent stddev * .001, 41681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent minimum * .001, 41781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent maximum * .001, 41881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mean / perLoop100, 41981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent stddev / perLoop100, 42081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent minimum / perLoop100, 42181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent maximum / perLoop100, 42281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent meanCycles / perLoop1k, 42381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent stddevCycles / perLoop1k, 42481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent minCycles / perLoop1k, 42581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent maxCycles / perLoop1k); 42681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 42781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 42881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 42981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent#endif 43081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}; 43181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 43281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// ---------------------------------------------------------------------------- 43381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// ThreadBase 43481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// ---------------------------------------------------------------------------- 43581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 43697b7b75b6a31330e213bdb96ccc60916218ad903Glenn Kasten// static 43797b7b75b6a31330e213bdb96ccc60916218ad903Glenn Kastenconst char *AudioFlinger::ThreadBase::threadTypeToString(AudioFlinger::ThreadBase::type_t type) 43897b7b75b6a31330e213bdb96ccc60916218ad903Glenn Kasten{ 43997b7b75b6a31330e213bdb96ccc60916218ad903Glenn Kasten switch (type) { 44097b7b75b6a31330e213bdb96ccc60916218ad903Glenn Kasten case MIXER: 44197b7b75b6a31330e213bdb96ccc60916218ad903Glenn Kasten return "MIXER"; 44297b7b75b6a31330e213bdb96ccc60916218ad903Glenn Kasten case DIRECT: 44397b7b75b6a31330e213bdb96ccc60916218ad903Glenn Kasten return "DIRECT"; 44497b7b75b6a31330e213bdb96ccc60916218ad903Glenn Kasten case DUPLICATING: 44597b7b75b6a31330e213bdb96ccc60916218ad903Glenn Kasten return "DUPLICATING"; 44697b7b75b6a31330e213bdb96ccc60916218ad903Glenn Kasten case RECORD: 44797b7b75b6a31330e213bdb96ccc60916218ad903Glenn Kasten return "RECORD"; 44897b7b75b6a31330e213bdb96ccc60916218ad903Glenn Kasten case OFFLOAD: 44997b7b75b6a31330e213bdb96ccc60916218ad903Glenn Kasten return "OFFLOAD"; 4506d8018f0b7be9deec6b0acab10a0dca6e91d0fb8Glenn Kasten case MMAP: 4516d8018f0b7be9deec6b0acab10a0dca6e91d0fb8Glenn Kasten return "MMAP"; 45297b7b75b6a31330e213bdb96ccc60916218ad903Glenn Kasten default: 45397b7b75b6a31330e213bdb96ccc60916218ad903Glenn Kasten return "unknown"; 45497b7b75b6a31330e213bdb96ccc60916218ad903Glenn Kasten } 45597b7b75b6a31330e213bdb96ccc60916218ad903Glenn Kasten} 45697b7b75b6a31330e213bdb96ccc60916218ad903Glenn Kasten 457913d06c099bd689375483a839e11057ccf284d1cMikhail Naganovstd::string devicesToString(audio_devices_t devices) 458913d06c099bd689375483a839e11057ccf284d1cMikhail Naganov{ 459913d06c099bd689375483a839e11057ccf284d1cMikhail Naganov std::string result; 4600f5b562737d6b5457aa83a4fdce9c6fb32584d9dGlenn Kasten if (devices & AUDIO_DEVICE_BIT_IN) { 461913d06c099bd689375483a839e11057ccf284d1cMikhail Naganov InputDeviceConverter::maskToString(devices, result); 4620f5b562737d6b5457aa83a4fdce9c6fb32584d9dGlenn Kasten } else { 463913d06c099bd689375483a839e11057ccf284d1cMikhail Naganov OutputDeviceConverter::maskToString(devices, result); 4640f5b562737d6b5457aa83a4fdce9c6fb32584d9dGlenn Kasten } 4650f5b562737d6b5457aa83a4fdce9c6fb32584d9dGlenn Kasten return result; 4660f5b562737d6b5457aa83a4fdce9c6fb32584d9dGlenn Kasten} 4670f5b562737d6b5457aa83a4fdce9c6fb32584d9dGlenn Kasten 468913d06c099bd689375483a839e11057ccf284d1cMikhail Naganovstd::string inputFlagsToString(audio_input_flags_t flags) 4690f5b562737d6b5457aa83a4fdce9c6fb32584d9dGlenn Kasten{ 470913d06c099bd689375483a839e11057ccf284d1cMikhail Naganov std::string result; 471913d06c099bd689375483a839e11057ccf284d1cMikhail Naganov InputFlagConverter::maskToString(flags, result); 4720f5b562737d6b5457aa83a4fdce9c6fb32584d9dGlenn Kasten return result; 4730f5b562737d6b5457aa83a4fdce9c6fb32584d9dGlenn Kasten} 4740f5b562737d6b5457aa83a4fdce9c6fb32584d9dGlenn Kasten 475913d06c099bd689375483a839e11057ccf284d1cMikhail Naganovstd::string outputFlagsToString(audio_output_flags_t flags) 476913d06c099bd689375483a839e11057ccf284d1cMikhail Naganov{ 477913d06c099bd689375483a839e11057ccf284d1cMikhail Naganov std::string result; 478913d06c099bd689375483a839e11057ccf284d1cMikhail Naganov OutputFlagConverter::maskToString(flags, result); 47997b7b75b6a31330e213bdb96ccc60916218ad903Glenn Kasten return result; 48097b7b75b6a31330e213bdb96ccc60916218ad903Glenn Kasten} 48197b7b75b6a31330e213bdb96ccc60916218ad903Glenn Kasten 4820f5b562737d6b5457aa83a4fdce9c6fb32584d9dGlenn Kastenconst char *sourceToString(audio_source_t source) 4830f5b562737d6b5457aa83a4fdce9c6fb32584d9dGlenn Kasten{ 4840f5b562737d6b5457aa83a4fdce9c6fb32584d9dGlenn Kasten switch (source) { 4850f5b562737d6b5457aa83a4fdce9c6fb32584d9dGlenn Kasten case AUDIO_SOURCE_DEFAULT: return "default"; 4860f5b562737d6b5457aa83a4fdce9c6fb32584d9dGlenn Kasten case AUDIO_SOURCE_MIC: return "mic"; 4870f5b562737d6b5457aa83a4fdce9c6fb32584d9dGlenn Kasten case AUDIO_SOURCE_VOICE_UPLINK: return "voice uplink"; 4880f5b562737d6b5457aa83a4fdce9c6fb32584d9dGlenn Kasten case AUDIO_SOURCE_VOICE_DOWNLINK: return "voice downlink"; 4890f5b562737d6b5457aa83a4fdce9c6fb32584d9dGlenn Kasten case AUDIO_SOURCE_VOICE_CALL: return "voice call"; 4900f5b562737d6b5457aa83a4fdce9c6fb32584d9dGlenn Kasten case AUDIO_SOURCE_CAMCORDER: return "camcorder"; 4910f5b562737d6b5457aa83a4fdce9c6fb32584d9dGlenn Kasten case AUDIO_SOURCE_VOICE_RECOGNITION: return "voice recognition"; 4920f5b562737d6b5457aa83a4fdce9c6fb32584d9dGlenn Kasten case AUDIO_SOURCE_VOICE_COMMUNICATION: return "voice communication"; 4930f5b562737d6b5457aa83a4fdce9c6fb32584d9dGlenn Kasten case AUDIO_SOURCE_REMOTE_SUBMIX: return "remote submix"; 4948a397d583a4f4cf24ad88facaf2fd33990cfb811rago case AUDIO_SOURCE_UNPROCESSED: return "unprocessed"; 4950f5b562737d6b5457aa83a4fdce9c6fb32584d9dGlenn Kasten case AUDIO_SOURCE_FM_TUNER: return "FM tuner"; 4960f5b562737d6b5457aa83a4fdce9c6fb32584d9dGlenn Kasten case AUDIO_SOURCE_HOTWORD: return "hotword"; 4970f5b562737d6b5457aa83a4fdce9c6fb32584d9dGlenn Kasten default: return "unknown"; 4980f5b562737d6b5457aa83a4fdce9c6fb32584d9dGlenn Kasten } 4990f5b562737d6b5457aa83a4fdce9c6fb32584d9dGlenn Kasten} 5000f5b562737d6b5457aa83a4fdce9c6fb32584d9dGlenn Kasten 50181784c37c61b09289654b979567a42bf73cd2b12Eric LaurentAudioFlinger::ThreadBase::ThreadBase(const sp<AudioFlinger>& audioFlinger, audio_io_handle_t id, 50272e3f39146fce4686bd96f11057c051bea376dfbEric Laurent audio_devices_t outDevice, audio_devices_t inDevice, type_t type, bool systemReady) 50381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent : Thread(false /*canCallJava*/), 50481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mType(type), 5059b58f63e45ef2fdfb839b9b9bb3411d81eb96128Glenn Kasten mAudioFlinger(audioFlinger), 50670949c47fbae3f836d15f040551d7631be3ed7c2Glenn Kasten // mSampleRate, mFrameCount, mChannelMask, mChannelCount, mFrameSize, mFormat, mBufferSize 507deca2ae0a7cf8bc54ff3f30b7dc39bbc78b94c0dGlenn Kasten // are set by PlaybackThread::readOutputParameters_l() or 508deca2ae0a7cf8bc54ff3f30b7dc39bbc78b94c0dGlenn Kasten // RecordThread::readInputParameters_l() 509fd4779740ec3e9e865d5514464df26d015354388Eric Laurent //FIXME: mStandby should be true here. Is this some kind of hack? 51081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mStandby(false), mOutDevice(outDevice), mInDevice(inDevice), 5117c1ec5f038e63a5eb8b04434577c25bc23f5f410Eric Laurent mPrevOutDevice(AUDIO_DEVICE_NONE), mPrevInDevice(AUDIO_DEVICE_NONE), 5127c1ec5f038e63a5eb8b04434577c25bc23f5f410Eric Laurent mAudioSource(AUDIO_SOURCE_DEFAULT), mId(id), 51381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // mName will be set by concrete (non-virtual) subclass 51472e3f39146fce4686bd96f11057c051bea376dfbEric Laurent mDeathRecipient(new PMDeathRecipient(this)), 5156acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent mSystemReady(systemReady), 5166acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent mSignalPending(false) 51781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 518296fb13dd9b5e90d6a05cce897c3b1e7914a478aEric Laurent memset(&mPatch, 0, sizeof(struct audio_patch)); 51981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 52081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 52181784c37c61b09289654b979567a42bf73cd2b12Eric LaurentAudioFlinger::ThreadBase::~ThreadBase() 52281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 523c6ae3c8a261794fd4445e4e152d1ada074a3f92fGlenn Kasten // mConfigEvents should be empty, but just in case it isn't, free the memory it owns 524c6ae3c8a261794fd4445e4e152d1ada074a3f92fGlenn Kasten mConfigEvents.clear(); 525c6ae3c8a261794fd4445e4e152d1ada074a3f92fGlenn Kasten 52681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // do not lock the mutex in destructor 52781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent releaseWakeLock_l(); 52881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (mPowerManager != 0) { 52906b46062d2f8bc82ca3061a23d197734ae51918bMarco Nelissen sp<IBinder> binder = IInterface::asBinder(mPowerManager); 53081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent binder->unlinkToDeath(mDeathRecipient); 53181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 53281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 53381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 534cf04c2cb8e031acc03c1c91cb1ccab15098c89b6Glenn Kastenstatus_t AudioFlinger::ThreadBase::readyToRun() 535cf04c2cb8e031acc03c1c91cb1ccab15098c89b6Glenn Kasten{ 536cf04c2cb8e031acc03c1c91cb1ccab15098c89b6Glenn Kasten status_t status = initCheck(); 537cf04c2cb8e031acc03c1c91cb1ccab15098c89b6Glenn Kasten if (status == NO_ERROR) { 5386d8018f0b7be9deec6b0acab10a0dca6e91d0fb8Glenn Kasten ALOGI("AudioFlinger's thread %p tid=%d ready to run", this, getTid()); 539cf04c2cb8e031acc03c1c91cb1ccab15098c89b6Glenn Kasten } else { 540cf04c2cb8e031acc03c1c91cb1ccab15098c89b6Glenn Kasten ALOGE("No working audio driver found."); 541cf04c2cb8e031acc03c1c91cb1ccab15098c89b6Glenn Kasten } 542cf04c2cb8e031acc03c1c91cb1ccab15098c89b6Glenn Kasten return status; 543cf04c2cb8e031acc03c1c91cb1ccab15098c89b6Glenn Kasten} 544cf04c2cb8e031acc03c1c91cb1ccab15098c89b6Glenn Kasten 54581784c37c61b09289654b979567a42bf73cd2b12Eric Laurentvoid AudioFlinger::ThreadBase::exit() 54681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 54781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent ALOGV("ThreadBase::exit"); 54881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // do any cleanup required for exit to succeed 54981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent preExit(); 55081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent { 55181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // This lock prevents the following race in thread (uniprocessor for illustration): 55281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // if (!exitPending()) { 55381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // // context switch from here to exit() 55481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // // exit() calls requestExit(), what exitPending() observes 55581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // // exit() calls signal(), which is dropped since no waiters 55681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // // context switch back from exit() to here 55781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // mWaitWorkCV.wait(...); 55881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // // now thread is hung 55981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // } 56081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent AutoMutex lock(mLock); 56181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent requestExit(); 56281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mWaitWorkCV.broadcast(); 56381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 56481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // When Thread::requestExitAndWait is made virtual and this method is renamed to 56581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // "virtual status_t requestExitAndWait()", replace by "return Thread::requestExitAndWait();" 56681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent requestExitAndWait(); 56781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 56881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 56981784c37c61b09289654b979567a42bf73cd2b12Eric Laurentstatus_t AudioFlinger::ThreadBase::setParameters(const String8& keyValuePairs) 57081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 57181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent ALOGV("ThreadBase::setParameters() %s", keyValuePairs.string()); 57281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent Mutex::Autolock _l(mLock); 57381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 5741035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent return sendSetParameterConfigEvent_l(keyValuePairs); 5751035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent} 5761035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent 5771035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent// sendConfigEvent_l() must be called with ThreadBase::mLock held 5781035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent// Can temporarily release the lock if waiting for a reply from processConfigEvents_l(). 5791035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurentstatus_t AudioFlinger::ThreadBase::sendConfigEvent_l(sp<ConfigEvent>& event) 5801035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent{ 5811035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent status_t status = NO_ERROR; 5821035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent 58372e3f39146fce4686bd96f11057c051bea376dfbEric Laurent if (event->mRequiresSystemReady && !mSystemReady) { 58472e3f39146fce4686bd96f11057c051bea376dfbEric Laurent event->mWaitStatus = false; 58572e3f39146fce4686bd96f11057c051bea376dfbEric Laurent mPendingConfigEvents.add(event); 58672e3f39146fce4686bd96f11057c051bea376dfbEric Laurent return status; 58772e3f39146fce4686bd96f11057c051bea376dfbEric Laurent } 5881035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent mConfigEvents.add(event); 589c42e9b462661673dff480ee71757a58b0f806370Glenn Kasten ALOGV("sendConfigEvent_l() num events %zu event %d", mConfigEvents.size(), event->mType); 59081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mWaitWorkCV.signal(); 5911035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent mLock.unlock(); 5921035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent { 5931035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent Mutex::Autolock _l(event->mLock); 5941035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent while (event->mWaitStatus) { 5951035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent if (event->mCond.waitRelative(event->mLock, kConfigEventTimeoutNs) != NO_ERROR) { 5961035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent event->mStatus = TIMED_OUT; 5971035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent event->mWaitStatus = false; 5981035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent } 5991035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent } 6001035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent status = event->mStatus; 60181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 6021035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent mLock.lock(); 60381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent return status; 60481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 60581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 6067c1ec5f038e63a5eb8b04434577c25bc23f5f410Eric Laurentvoid AudioFlinger::ThreadBase::sendIoConfigEvent(audio_io_config_event event, pid_t pid) 60781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 60881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent Mutex::Autolock _l(mLock); 6097c1ec5f038e63a5eb8b04434577c25bc23f5f410Eric Laurent sendIoConfigEvent_l(event, pid); 61081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 61181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 61281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// sendIoConfigEvent_l() must be called with ThreadBase::mLock held 6137c1ec5f038e63a5eb8b04434577c25bc23f5f410Eric Laurentvoid AudioFlinger::ThreadBase::sendIoConfigEvent_l(audio_io_config_event event, pid_t pid) 61481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 6157c1ec5f038e63a5eb8b04434577c25bc23f5f410Eric Laurent sp<ConfigEvent> configEvent = (ConfigEvent *)new IoConfigEvent(event, pid); 6161035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent sendConfigEvent_l(configEvent); 61781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 61881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 61983f042776b131b149f803fff6ab184ae2c4d98cdMikhail Naganovvoid AudioFlinger::ThreadBase::sendPrioConfigEvent(pid_t pid, pid_t tid, int32_t prio, bool forApp) 62072e3f39146fce4686bd96f11057c051bea376dfbEric Laurent{ 62172e3f39146fce4686bd96f11057c051bea376dfbEric Laurent Mutex::Autolock _l(mLock); 62283f042776b131b149f803fff6ab184ae2c4d98cdMikhail Naganov sendPrioConfigEvent_l(pid, tid, prio, forApp); 62372e3f39146fce4686bd96f11057c051bea376dfbEric Laurent} 62472e3f39146fce4686bd96f11057c051bea376dfbEric Laurent 62581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// sendPrioConfigEvent_l() must be called with ThreadBase::mLock held 62683f042776b131b149f803fff6ab184ae2c4d98cdMikhail Naganovvoid AudioFlinger::ThreadBase::sendPrioConfigEvent_l( 62783f042776b131b149f803fff6ab184ae2c4d98cdMikhail Naganov pid_t pid, pid_t tid, int32_t prio, bool forApp) 62881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 62983f042776b131b149f803fff6ab184ae2c4d98cdMikhail Naganov sp<ConfigEvent> configEvent = (ConfigEvent *)new PrioConfigEvent(pid, tid, prio, forApp); 6301035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent sendConfigEvent_l(configEvent); 63181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 63281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 6331035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent// sendSetParameterConfigEvent_l() must be called with ThreadBase::mLock held 6341035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurentstatus_t AudioFlinger::ThreadBase::sendSetParameterConfigEvent_l(const String8& keyValuePair) 63581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 6362ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hung sp<ConfigEvent> configEvent; 6372ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hung AudioParameter param(keyValuePair); 6382ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hung int value; 63900260b5e6996b0a4b12f71c5b84e44adea040534Mikhail Naganov if (param.getInt(String8(AudioParameter::keyMonoOutput), value) == NO_ERROR) { 6402ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hung setMasterMono_l(value != 0); 6412ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hung if (param.size() == 1) { 6422ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hung return NO_ERROR; // should be a solo parameter - we don't pass down 6432ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hung } 64400260b5e6996b0a4b12f71c5b84e44adea040534Mikhail Naganov param.remove(String8(AudioParameter::keyMonoOutput)); 6452ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hung configEvent = new SetParameterConfigEvent(param.toString()); 6462ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hung } else { 6472ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hung configEvent = new SetParameterConfigEvent(keyValuePair); 6482ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hung } 6491035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent return sendConfigEvent_l(configEvent); 650f777331418a86cd9fd709af898ef24a69967aeb4Glenn Kasten} 651f777331418a86cd9fd709af898ef24a69967aeb4Glenn Kasten 6521c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurentstatus_t AudioFlinger::ThreadBase::sendCreateAudioPatchConfigEvent( 6531c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent const struct audio_patch *patch, 6541c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent audio_patch_handle_t *handle) 6551c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent{ 6561c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent Mutex::Autolock _l(mLock); 6571c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent sp<ConfigEvent> configEvent = (ConfigEvent *)new CreateAudioPatchConfigEvent(*patch, *handle); 6581c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent status_t status = sendConfigEvent_l(configEvent); 6591c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent if (status == NO_ERROR) { 6601c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent CreateAudioPatchConfigEventData *data = 6611c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent (CreateAudioPatchConfigEventData *)configEvent->mData.get(); 6621c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent *handle = data->mHandle; 6631c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent } 6641c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent return status; 6651c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent} 6661c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent 6671c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurentstatus_t AudioFlinger::ThreadBase::sendReleaseAudioPatchConfigEvent( 6681c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent const audio_patch_handle_t handle) 6691c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent{ 6701c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent Mutex::Autolock _l(mLock); 6711c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent sp<ConfigEvent> configEvent = (ConfigEvent *)new ReleaseAudioPatchConfigEvent(handle); 6721c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent return sendConfigEvent_l(configEvent); 6731c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent} 6741c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent 6751c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent 6762cfbf88b89854f30b295e8ae26a031edb8d712f8Glenn Kasten// post condition: mConfigEvents.isEmpty() 677021cf9634ab09c0753a40b7c9ef4ba603be5c3daEric Laurentvoid AudioFlinger::ThreadBase::processConfigEvents_l() 678f777331418a86cd9fd709af898ef24a69967aeb4Glenn Kasten{ 6791035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent bool configChanged = false; 6801035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent 68181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent while (!mConfigEvents.isEmpty()) { 682c42e9b462661673dff480ee71757a58b0f806370Glenn Kasten ALOGV("processConfigEvents_l() remaining events %zu", mConfigEvents.size()); 6831035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent sp<ConfigEvent> event = mConfigEvents[0]; 68481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mConfigEvents.removeAt(0); 6851035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent switch (event->mType) { 6863468e8a4d79cc6a7bb0f03f8382426195bed44dfGlenn Kasten case CFG_EVENT_PRIO: { 6871035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent PrioConfigEventData *data = (PrioConfigEventData *)event->mData.get(); 6881035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent // FIXME Need to understand why this has to be done asynchronously 68983f042776b131b149f803fff6ab184ae2c4d98cdMikhail Naganov int err = requestPriority(data->mPid, data->mTid, data->mPrio, data->mForApp, 6903468e8a4d79cc6a7bb0f03f8382426195bed44dfGlenn Kasten true /*asynchronous*/); 6913468e8a4d79cc6a7bb0f03f8382426195bed44dfGlenn Kasten if (err != 0) { 6923468e8a4d79cc6a7bb0f03f8382426195bed44dfGlenn Kasten ALOGW("Policy SCHED_FIFO priority %d is unavailable for pid %d tid %d; error %d", 6931035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent data->mPrio, data->mPid, data->mTid, err); 6943468e8a4d79cc6a7bb0f03f8382426195bed44dfGlenn Kasten } 6953468e8a4d79cc6a7bb0f03f8382426195bed44dfGlenn Kasten } break; 6963468e8a4d79cc6a7bb0f03f8382426195bed44dfGlenn Kasten case CFG_EVENT_IO: { 6971035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent IoConfigEventData *data = (IoConfigEventData *)event->mData.get(); 6987c1ec5f038e63a5eb8b04434577c25bc23f5f410Eric Laurent ioConfigChanged(data->mEvent, data->mPid); 6991035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent } break; 7001035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent case CFG_EVENT_SET_PARAMETER: { 7011035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent SetParameterConfigEventData *data = (SetParameterConfigEventData *)event->mData.get(); 7021035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent if (checkForNewParameter_l(data->mKeyValuePairs, event->mStatus)) { 7031035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent configChanged = true; 704293558ad1977e24e65f7ba78f47382d33fc77d64Andy Hung mLocalLog.log("CFG_EVENT_SET_PARAMETER: (%s) configuration changed", 705293558ad1977e24e65f7ba78f47382d33fc77d64Andy Hung data->mKeyValuePairs.string()); 706d5418eb594435c958d6c37fa9938161a0112adbdGlenn Kasten } 7073468e8a4d79cc6a7bb0f03f8382426195bed44dfGlenn Kasten } break; 7081c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent case CFG_EVENT_CREATE_AUDIO_PATCH: { 709293558ad1977e24e65f7ba78f47382d33fc77d64Andy Hung const audio_devices_t oldDevice = getDevice(); 7101c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent CreateAudioPatchConfigEventData *data = 7111c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent (CreateAudioPatchConfigEventData *)event->mData.get(); 7121c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent event->mStatus = createAudioPatch_l(&data->mPatch, &data->mHandle); 713293558ad1977e24e65f7ba78f47382d33fc77d64Andy Hung const audio_devices_t newDevice = getDevice(); 714293558ad1977e24e65f7ba78f47382d33fc77d64Andy Hung mLocalLog.log("CFG_EVENT_CREATE_AUDIO_PATCH: old device %#x (%s) new device %#x (%s)", 715293558ad1977e24e65f7ba78f47382d33fc77d64Andy Hung (unsigned)oldDevice, devicesToString(oldDevice).c_str(), 716293558ad1977e24e65f7ba78f47382d33fc77d64Andy Hung (unsigned)newDevice, devicesToString(newDevice).c_str()); 7171c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent } break; 7181c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent case CFG_EVENT_RELEASE_AUDIO_PATCH: { 719293558ad1977e24e65f7ba78f47382d33fc77d64Andy Hung const audio_devices_t oldDevice = getDevice(); 7201c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent ReleaseAudioPatchConfigEventData *data = 7211c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent (ReleaseAudioPatchConfigEventData *)event->mData.get(); 7221c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent event->mStatus = releaseAudioPatch_l(data->mHandle); 723293558ad1977e24e65f7ba78f47382d33fc77d64Andy Hung const audio_devices_t newDevice = getDevice(); 724293558ad1977e24e65f7ba78f47382d33fc77d64Andy Hung mLocalLog.log("CFG_EVENT_RELEASE_AUDIO_PATCH: old device %#x (%s) new device %#x (%s)", 725293558ad1977e24e65f7ba78f47382d33fc77d64Andy Hung (unsigned)oldDevice, devicesToString(oldDevice).c_str(), 726293558ad1977e24e65f7ba78f47382d33fc77d64Andy Hung (unsigned)newDevice, devicesToString(newDevice).c_str()); 7271c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent } break; 7283468e8a4d79cc6a7bb0f03f8382426195bed44dfGlenn Kasten default: 7291035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent ALOG_ASSERT(false, "processConfigEvents_l() unknown event type %d", event->mType); 7303468e8a4d79cc6a7bb0f03f8382426195bed44dfGlenn Kasten break; 73181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 7321035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent { 7331035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent Mutex::Autolock _l(event->mLock); 7341035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent if (event->mWaitStatus) { 7351035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent event->mWaitStatus = false; 7361035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent event->mCond.signal(); 7371035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent } 7381035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent } 7391035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent ALOGV_IF(mConfigEvents.isEmpty(), "processConfigEvents_l() DONE thread %p", this); 7401035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent } 7411035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent 7421035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent if (configChanged) { 7431035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent cacheParameters_l(); 74481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 74581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 74681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 747b220884bf3129253cc5bc8d030bc475411ea4911Marco NelissenString8 channelMaskToString(audio_channel_mask_t mask, bool output) { 748b220884bf3129253cc5bc8d030bc475411ea4911Marco Nelissen String8 s; 749e1635ec096d1110c33a5aa46847af59c261fb7faGlenn Kasten const audio_channel_representation_t representation = 750e1635ec096d1110c33a5aa46847af59c261fb7faGlenn Kasten audio_channel_mask_get_representation(mask); 751f98ec8d0d42e6952c0a7cc5027935851073f7426Andy Hung 752f98ec8d0d42e6952c0a7cc5027935851073f7426Andy Hung switch (representation) { 753f98ec8d0d42e6952c0a7cc5027935851073f7426Andy Hung case AUDIO_CHANNEL_REPRESENTATION_POSITION: { 754f98ec8d0d42e6952c0a7cc5027935851073f7426Andy Hung if (output) { 755f98ec8d0d42e6952c0a7cc5027935851073f7426Andy Hung if (mask & AUDIO_CHANNEL_OUT_FRONT_LEFT) s.append("front-left, "); 756f98ec8d0d42e6952c0a7cc5027935851073f7426Andy Hung if (mask & AUDIO_CHANNEL_OUT_FRONT_RIGHT) s.append("front-right, "); 757f98ec8d0d42e6952c0a7cc5027935851073f7426Andy Hung if (mask & AUDIO_CHANNEL_OUT_FRONT_CENTER) s.append("front-center, "); 758f98ec8d0d42e6952c0a7cc5027935851073f7426Andy Hung if (mask & AUDIO_CHANNEL_OUT_LOW_FREQUENCY) s.append("low freq, "); 759f98ec8d0d42e6952c0a7cc5027935851073f7426Andy Hung if (mask & AUDIO_CHANNEL_OUT_BACK_LEFT) s.append("back-left, "); 760f98ec8d0d42e6952c0a7cc5027935851073f7426Andy Hung if (mask & AUDIO_CHANNEL_OUT_BACK_RIGHT) s.append("back-right, "); 761f98ec8d0d42e6952c0a7cc5027935851073f7426Andy Hung if (mask & AUDIO_CHANNEL_OUT_FRONT_LEFT_OF_CENTER) s.append("front-left-of-center, "); 762f98ec8d0d42e6952c0a7cc5027935851073f7426Andy Hung if (mask & AUDIO_CHANNEL_OUT_FRONT_RIGHT_OF_CENTER) s.append("front-right-of-center, "); 763f98ec8d0d42e6952c0a7cc5027935851073f7426Andy Hung if (mask & AUDIO_CHANNEL_OUT_BACK_CENTER) s.append("back-center, "); 764f98ec8d0d42e6952c0a7cc5027935851073f7426Andy Hung if (mask & AUDIO_CHANNEL_OUT_SIDE_LEFT) s.append("side-left, "); 765f98ec8d0d42e6952c0a7cc5027935851073f7426Andy Hung if (mask & AUDIO_CHANNEL_OUT_SIDE_RIGHT) s.append("side-right, "); 766f98ec8d0d42e6952c0a7cc5027935851073f7426Andy Hung if (mask & AUDIO_CHANNEL_OUT_TOP_CENTER) s.append("top-center ,"); 767f98ec8d0d42e6952c0a7cc5027935851073f7426Andy Hung if (mask & AUDIO_CHANNEL_OUT_TOP_FRONT_LEFT) s.append("top-front-left, "); 768f98ec8d0d42e6952c0a7cc5027935851073f7426Andy Hung if (mask & AUDIO_CHANNEL_OUT_TOP_FRONT_CENTER) s.append("top-front-center, "); 769f98ec8d0d42e6952c0a7cc5027935851073f7426Andy Hung if (mask & AUDIO_CHANNEL_OUT_TOP_FRONT_RIGHT) s.append("top-front-right, "); 770f98ec8d0d42e6952c0a7cc5027935851073f7426Andy Hung if (mask & AUDIO_CHANNEL_OUT_TOP_BACK_LEFT) s.append("top-back-left, "); 771f98ec8d0d42e6952c0a7cc5027935851073f7426Andy Hung if (mask & AUDIO_CHANNEL_OUT_TOP_BACK_CENTER) s.append("top-back-center, " ); 772f98ec8d0d42e6952c0a7cc5027935851073f7426Andy Hung if (mask & AUDIO_CHANNEL_OUT_TOP_BACK_RIGHT) s.append("top-back-right, " ); 773f98ec8d0d42e6952c0a7cc5027935851073f7426Andy Hung if (mask & ~AUDIO_CHANNEL_OUT_ALL) s.append("unknown, "); 774f98ec8d0d42e6952c0a7cc5027935851073f7426Andy Hung } else { 775f98ec8d0d42e6952c0a7cc5027935851073f7426Andy Hung if (mask & AUDIO_CHANNEL_IN_LEFT) s.append("left, "); 776f98ec8d0d42e6952c0a7cc5027935851073f7426Andy Hung if (mask & AUDIO_CHANNEL_IN_RIGHT) s.append("right, "); 777f98ec8d0d42e6952c0a7cc5027935851073f7426Andy Hung if (mask & AUDIO_CHANNEL_IN_FRONT) s.append("front, "); 778f98ec8d0d42e6952c0a7cc5027935851073f7426Andy Hung if (mask & AUDIO_CHANNEL_IN_BACK) s.append("back, "); 779f98ec8d0d42e6952c0a7cc5027935851073f7426Andy Hung if (mask & AUDIO_CHANNEL_IN_LEFT_PROCESSED) s.append("left-processed, "); 780f98ec8d0d42e6952c0a7cc5027935851073f7426Andy Hung if (mask & AUDIO_CHANNEL_IN_RIGHT_PROCESSED) s.append("right-processed, "); 781f98ec8d0d42e6952c0a7cc5027935851073f7426Andy Hung if (mask & AUDIO_CHANNEL_IN_FRONT_PROCESSED) s.append("front-processed, "); 782f98ec8d0d42e6952c0a7cc5027935851073f7426Andy Hung if (mask & AUDIO_CHANNEL_IN_BACK_PROCESSED) s.append("back-processed, "); 783f98ec8d0d42e6952c0a7cc5027935851073f7426Andy Hung if (mask & AUDIO_CHANNEL_IN_PRESSURE) s.append("pressure, "); 784f98ec8d0d42e6952c0a7cc5027935851073f7426Andy Hung if (mask & AUDIO_CHANNEL_IN_X_AXIS) s.append("X, "); 785f98ec8d0d42e6952c0a7cc5027935851073f7426Andy Hung if (mask & AUDIO_CHANNEL_IN_Y_AXIS) s.append("Y, "); 786f98ec8d0d42e6952c0a7cc5027935851073f7426Andy Hung if (mask & AUDIO_CHANNEL_IN_Z_AXIS) s.append("Z, "); 787f98ec8d0d42e6952c0a7cc5027935851073f7426Andy Hung if (mask & AUDIO_CHANNEL_IN_VOICE_UPLINK) s.append("voice-uplink, "); 788f98ec8d0d42e6952c0a7cc5027935851073f7426Andy Hung if (mask & AUDIO_CHANNEL_IN_VOICE_DNLINK) s.append("voice-dnlink, "); 789f98ec8d0d42e6952c0a7cc5027935851073f7426Andy Hung if (mask & ~AUDIO_CHANNEL_IN_ALL) s.append("unknown, "); 790f98ec8d0d42e6952c0a7cc5027935851073f7426Andy Hung } 791f98ec8d0d42e6952c0a7cc5027935851073f7426Andy Hung const int len = s.length(); 792f98ec8d0d42e6952c0a7cc5027935851073f7426Andy Hung if (len > 2) { 79357c4e6f7464d458eb52d209c2a63524913d6406dGlenn Kasten (void) s.lockBuffer(len); // needed? 794f98ec8d0d42e6952c0a7cc5027935851073f7426Andy Hung s.unlockBuffer(len - 2); // remove trailing ", " 795f98ec8d0d42e6952c0a7cc5027935851073f7426Andy Hung } 796f98ec8d0d42e6952c0a7cc5027935851073f7426Andy Hung return s; 797b220884bf3129253cc5bc8d030bc475411ea4911Marco Nelissen } 798f98ec8d0d42e6952c0a7cc5027935851073f7426Andy Hung case AUDIO_CHANNEL_REPRESENTATION_INDEX: 799f98ec8d0d42e6952c0a7cc5027935851073f7426Andy Hung s.appendFormat("index mask, bits:%#x", audio_channel_mask_get_bits(mask)); 800f98ec8d0d42e6952c0a7cc5027935851073f7426Andy Hung return s; 801f98ec8d0d42e6952c0a7cc5027935851073f7426Andy Hung default: 802f98ec8d0d42e6952c0a7cc5027935851073f7426Andy Hung s.appendFormat("unknown mask, representation:%d bits:%#x", 803f98ec8d0d42e6952c0a7cc5027935851073f7426Andy Hung representation, audio_channel_mask_get_bits(mask)); 804f98ec8d0d42e6952c0a7cc5027935851073f7426Andy Hung return s; 805b220884bf3129253cc5bc8d030bc475411ea4911Marco Nelissen } 806b220884bf3129253cc5bc8d030bc475411ea4911Marco Nelissen} 807b220884bf3129253cc5bc8d030bc475411ea4911Marco Nelissen 8080f11b51a57bc9062c4fe8af73747319cedabc5d6Glenn Kastenvoid AudioFlinger::ThreadBase::dumpBase(int fd, const Vector<String16>& args __unused) 80981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 81081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent const size_t SIZE = 256; 81181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent char buffer[SIZE]; 81281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent String8 result; 81381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 8146d8018f0b7be9deec6b0acab10a0dca6e91d0fb8Glenn Kasten dprintf(fd, "\n%s thread %p, name %s, tid %d, type %d (%s):\n", isOutput() ? "Output" : "Input", 8156d8018f0b7be9deec6b0acab10a0dca6e91d0fb8Glenn Kasten this, mThreadName, getTid(), type(), threadTypeToString(type())); 8166d8018f0b7be9deec6b0acab10a0dca6e91d0fb8Glenn Kasten 81781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent bool locked = AudioFlinger::dumpTryLock(mLock); 81881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (!locked) { 8196d8018f0b7be9deec6b0acab10a0dca6e91d0fb8Glenn Kasten dprintf(fd, " Thread may be deadlocked\n"); 820b220884bf3129253cc5bc8d030bc475411ea4911Marco Nelissen } 821b220884bf3129253cc5bc8d030bc475411ea4911Marco Nelissen 82287cebadd48710e42474756fc3513df678de045ceElliott Hughes dprintf(fd, " I/O handle: %d\n", mId); 82387cebadd48710e42474756fc3513df678de045ceElliott Hughes dprintf(fd, " Standby: %s\n", mStandby ? "yes" : "no"); 82497b7b75b6a31330e213bdb96ccc60916218ad903Glenn Kasten dprintf(fd, " Sample rate: %u Hz\n", mSampleRate); 82587cebadd48710e42474756fc3513df678de045ceElliott Hughes dprintf(fd, " HAL frame count: %zu\n", mFrameCount); 826913d06c099bd689375483a839e11057ccf284d1cMikhail Naganov dprintf(fd, " HAL format: 0x%x (%s)\n", mHALFormat, formatToString(mHALFormat).c_str()); 827c42e9b462661673dff480ee71757a58b0f806370Glenn Kasten dprintf(fd, " HAL buffer size: %zu bytes\n", mBufferSize); 82897b7b75b6a31330e213bdb96ccc60916218ad903Glenn Kasten dprintf(fd, " Channel count: %u\n", mChannelCount); 82997b7b75b6a31330e213bdb96ccc60916218ad903Glenn Kasten dprintf(fd, " Channel mask: 0x%08x (%s)\n", mChannelMask, 830b220884bf3129253cc5bc8d030bc475411ea4911Marco Nelissen channelMaskToString(mChannelMask, mType != RECORD).string()); 831913d06c099bd689375483a839e11057ccf284d1cMikhail Naganov dprintf(fd, " Processing format: 0x%x (%s)\n", mFormat, formatToString(mFormat).c_str()); 832f87c2f5eb4e37f0950962e31b9ca49e32f5b0864Glenn Kasten dprintf(fd, " Processing frame size: %zu bytes\n", mFrameSize); 83387cebadd48710e42474756fc3513df678de045ceElliott Hughes dprintf(fd, " Pending config events:"); 834b220884bf3129253cc5bc8d030bc475411ea4911Marco Nelissen size_t numConfig = mConfigEvents.size(); 835b220884bf3129253cc5bc8d030bc475411ea4911Marco Nelissen if (numConfig) { 836b220884bf3129253cc5bc8d030bc475411ea4911Marco Nelissen for (size_t i = 0; i < numConfig; i++) { 837b220884bf3129253cc5bc8d030bc475411ea4911Marco Nelissen mConfigEvents[i]->dump(buffer, SIZE); 83887cebadd48710e42474756fc3513df678de045ceElliott Hughes dprintf(fd, "\n %s", buffer); 839b220884bf3129253cc5bc8d030bc475411ea4911Marco Nelissen } 84087cebadd48710e42474756fc3513df678de045ceElliott Hughes dprintf(fd, "\n"); 841b220884bf3129253cc5bc8d030bc475411ea4911Marco Nelissen } else { 84287cebadd48710e42474756fc3513df678de045ceElliott Hughes dprintf(fd, " none\n"); 84381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 844293558ad1977e24e65f7ba78f47382d33fc77d64Andy Hung // Note: output device may be used by capture threads for effects such as AEC. 845913d06c099bd689375483a839e11057ccf284d1cMikhail Naganov dprintf(fd, " Output device: %#x (%s)\n", mOutDevice, devicesToString(mOutDevice).c_str()); 846913d06c099bd689375483a839e11057ccf284d1cMikhail Naganov dprintf(fd, " Input device: %#x (%s)\n", mInDevice, devicesToString(mInDevice).c_str()); 8470b89bc0d285b8fd4798df1ff0ba9f93851a3bd48Glenn Kasten dprintf(fd, " Audio source: %d (%s)\n", mAudioSource, sourceToString(mAudioSource)); 84881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 84981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (locked) { 85081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mLock.unlock(); 85181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 85281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 85381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 85481784c37c61b09289654b979567a42bf73cd2b12Eric Laurentvoid AudioFlinger::ThreadBase::dumpEffectChains(int fd, const Vector<String16>& args) 85581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 85681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent const size_t SIZE = 256; 85781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent char buffer[SIZE]; 85881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent String8 result; 85981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 860b220884bf3129253cc5bc8d030bc475411ea4911Marco Nelissen size_t numEffectChains = mEffectChains.size(); 8611d6fa7af1288b550faabe4ec2cf98684236723dbNarayan Kamath snprintf(buffer, SIZE, " %zu Effect Chains\n", numEffectChains); 86281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent write(fd, buffer, strlen(buffer)); 86381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 864b220884bf3129253cc5bc8d030bc475411ea4911Marco Nelissen for (size_t i = 0; i < numEffectChains; ++i) { 86581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent sp<EffectChain> chain = mEffectChains[i]; 86681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (chain != 0) { 86781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent chain->dump(fd, args); 86881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 86981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 87081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 87181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 872dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hungvoid AudioFlinger::ThreadBase::acquireWakeLock() 87381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 87481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent Mutex::Autolock _l(mLock); 875dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hung acquireWakeLock_l(); 87681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 87781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 878014e7fa2e90827d911c37bb0ce4d2e10e14d0bb3Narayan KamathString16 AudioFlinger::ThreadBase::getWakeLockTag() 879014e7fa2e90827d911c37bb0ce4d2e10e14d0bb3Narayan Kamath{ 880014e7fa2e90827d911c37bb0ce4d2e10e14d0bb3Narayan Kamath switch (mType) { 881bcb1486d052e329ae4790d93055d1c51017286c3Glenn Kasten case MIXER: 882bcb1486d052e329ae4790d93055d1c51017286c3Glenn Kasten return String16("AudioMix"); 883bcb1486d052e329ae4790d93055d1c51017286c3Glenn Kasten case DIRECT: 884bcb1486d052e329ae4790d93055d1c51017286c3Glenn Kasten return String16("AudioDirectOut"); 885bcb1486d052e329ae4790d93055d1c51017286c3Glenn Kasten case DUPLICATING: 886bcb1486d052e329ae4790d93055d1c51017286c3Glenn Kasten return String16("AudioDup"); 887bcb1486d052e329ae4790d93055d1c51017286c3Glenn Kasten case RECORD: 888bcb1486d052e329ae4790d93055d1c51017286c3Glenn Kasten return String16("AudioIn"); 889bcb1486d052e329ae4790d93055d1c51017286c3Glenn Kasten case OFFLOAD: 890bcb1486d052e329ae4790d93055d1c51017286c3Glenn Kasten return String16("AudioOffload"); 8916acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent case MMAP: 8926acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent return String16("Mmap"); 893bcb1486d052e329ae4790d93055d1c51017286c3Glenn Kasten default: 894bcb1486d052e329ae4790d93055d1c51017286c3Glenn Kasten ALOG_ASSERT(false); 895bcb1486d052e329ae4790d93055d1c51017286c3Glenn Kasten return String16("AudioUnknown"); 896014e7fa2e90827d911c37bb0ce4d2e10e14d0bb3Narayan Kamath } 897014e7fa2e90827d911c37bb0ce4d2e10e14d0bb3Narayan Kamath} 898014e7fa2e90827d911c37bb0ce4d2e10e14d0bb3Narayan Kamath 899dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hungvoid AudioFlinger::ThreadBase::acquireWakeLock_l() 90081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 901462fd2fa9eef642b0574aa7409de0bde3fec8d43Marco Nelissen getPowerManager_l(); 90281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (mPowerManager != 0) { 90381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent sp<IBinder> binder = new BBinder(); 904dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hung // Uses AID_AUDIOSERVER for wakelock. updateWakeLockUids_l() updates with client uids. 905dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hung status_t status = mPowerManager->acquireWakeLock(POWERMANAGER_PARTIAL_WAKE_LOCK, 9069cab746b116b8aed38ca6b97bfea35103535e522Eric Laurent binder, 9079cab746b116b8aed38ca6b97bfea35103535e522Eric Laurent getWakeLockTag(), 9089cab746b116b8aed38ca6b97bfea35103535e522Eric Laurent String16("audioserver"), 9099cab746b116b8aed38ca6b97bfea35103535e522Eric Laurent true /* FIXME force oneway contrary to .aidl */); 91081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (status == NO_ERROR) { 91181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mWakeLockToken = binder; 91281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 913d7dca050c630bddbd73a6623271b34b4290460eeGlenn Kasten ALOGV("acquireWakeLock_l() %s status %d", mThreadName, status); 91481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 9153f273d10817ddb2f792ae043de692efcdf1988aeWei Jia 9163f0c902beb53a245c9db35e871607dba05b8d391Andy Hung gBoottime.acquire(mWakeLockToken); 917818e7a32ce3633980138aff2c2bfcc5158b3cfccAndy Hung mTimestamp.mTimebaseOffset[ExtendedTimestamp::TIMEBASE_BOOTTIME] = 918818e7a32ce3633980138aff2c2bfcc5158b3cfccAndy Hung gBoottime.getBoottimeOffset(); 91981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 92081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 92181784c37c61b09289654b979567a42bf73cd2b12Eric Laurentvoid AudioFlinger::ThreadBase::releaseWakeLock() 92281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 92381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent Mutex::Autolock _l(mLock); 92481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent releaseWakeLock_l(); 92581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 92681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 92781784c37c61b09289654b979567a42bf73cd2b12Eric Laurentvoid AudioFlinger::ThreadBase::releaseWakeLock_l() 92881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 9293f0c902beb53a245c9db35e871607dba05b8d391Andy Hung gBoottime.release(mWakeLockToken); 93081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (mWakeLockToken != 0) { 931d7dca050c630bddbd73a6623271b34b4290460eeGlenn Kasten ALOGV("releaseWakeLock_l() %s", mThreadName); 93281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (mPowerManager != 0) { 9333abc2ded40066f3b1df23aceb553f22d569c5cd3Glenn Kasten mPowerManager->releaseWakeLock(mWakeLockToken, 0, 9343abc2ded40066f3b1df23aceb553f22d569c5cd3Glenn Kasten true /* FIXME force oneway contrary to .aidl */); 93581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 93681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mWakeLockToken.clear(); 93781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 938462fd2fa9eef642b0574aa7409de0bde3fec8d43Marco Nelissen} 939462fd2fa9eef642b0574aa7409de0bde3fec8d43Marco Nelissen 940462fd2fa9eef642b0574aa7409de0bde3fec8d43Marco Nelissenvoid AudioFlinger::ThreadBase::getPowerManager_l() { 94172e3f39146fce4686bd96f11057c051bea376dfbEric Laurent if (mSystemReady && mPowerManager == 0) { 942462fd2fa9eef642b0574aa7409de0bde3fec8d43Marco Nelissen // use checkService() to avoid blocking if power service is not up yet 943462fd2fa9eef642b0574aa7409de0bde3fec8d43Marco Nelissen sp<IBinder> binder = 944462fd2fa9eef642b0574aa7409de0bde3fec8d43Marco Nelissen defaultServiceManager()->checkService(String16("power")); 945462fd2fa9eef642b0574aa7409de0bde3fec8d43Marco Nelissen if (binder == 0) { 946d7dca050c630bddbd73a6623271b34b4290460eeGlenn Kasten ALOGW("Thread %s cannot connect to the power manager service", mThreadName); 947462fd2fa9eef642b0574aa7409de0bde3fec8d43Marco Nelissen } else { 948462fd2fa9eef642b0574aa7409de0bde3fec8d43Marco Nelissen mPowerManager = interface_cast<IPowerManager>(binder); 949462fd2fa9eef642b0574aa7409de0bde3fec8d43Marco Nelissen binder->linkToDeath(mDeathRecipient); 950462fd2fa9eef642b0574aa7409de0bde3fec8d43Marco Nelissen } 951462fd2fa9eef642b0574aa7409de0bde3fec8d43Marco Nelissen } 952462fd2fa9eef642b0574aa7409de0bde3fec8d43Marco Nelissen} 953462fd2fa9eef642b0574aa7409de0bde3fec8d43Marco Nelissen 954d01b0f18491c355d808a57cb272404480e69618fAndy Hungvoid AudioFlinger::ThreadBase::updateWakeLockUids_l(const SortedVector<uid_t> &uids) { 955462fd2fa9eef642b0574aa7409de0bde3fec8d43Marco Nelissen getPowerManager_l(); 956dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hung 957dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hung#if !LOG_NDEBUG 958dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hung std::stringstream s; 959d01b0f18491c355d808a57cb272404480e69618fAndy Hung for (uid_t uid : uids) { 960dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hung s << uid << " "; 961dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hung } 962dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hung ALOGD("updateWakeLockUids_l %s uids:%s", mThreadName, s.str().c_str()); 963dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hung#endif 964dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hung 965438e7572c83674f4b9e6184f32f3dc94cd50524eAndy Hung if (mWakeLockToken == NULL) { // token may be NULL if AudioFlinger::systemReady() not called. 966438e7572c83674f4b9e6184f32f3dc94cd50524eAndy Hung if (mSystemReady) { 967438e7572c83674f4b9e6184f32f3dc94cd50524eAndy Hung ALOGE("no wake lock to update, but system ready!"); 968438e7572c83674f4b9e6184f32f3dc94cd50524eAndy Hung } else { 969438e7572c83674f4b9e6184f32f3dc94cd50524eAndy Hung ALOGW("no wake lock to update, system not ready yet"); 970438e7572c83674f4b9e6184f32f3dc94cd50524eAndy Hung } 971462fd2fa9eef642b0574aa7409de0bde3fec8d43Marco Nelissen return; 972462fd2fa9eef642b0574aa7409de0bde3fec8d43Marco Nelissen } 973462fd2fa9eef642b0574aa7409de0bde3fec8d43Marco Nelissen if (mPowerManager != 0) { 9741f12a8ad958344c50733b948628ffa06db9c5bc6Andy Hung std::vector<int> uidsAsInt(uids.begin(), uids.end()); // powermanager expects uids as ints 9751f12a8ad958344c50733b948628ffa06db9c5bc6Andy Hung status_t status = mPowerManager->updateWakeLockUids( 9761f12a8ad958344c50733b948628ffa06db9c5bc6Andy Hung mWakeLockToken, uidsAsInt.size(), uidsAsInt.data(), 9771f12a8ad958344c50733b948628ffa06db9c5bc6Andy Hung true /* FIXME force oneway contrary to .aidl */); 9784d231dc0ee34380956c71cbe18a750e487a69601Eric Laurent ALOGV("updateWakeLockUids_l() %s status %d", mThreadName, status); 979462fd2fa9eef642b0574aa7409de0bde3fec8d43Marco Nelissen } 980462fd2fa9eef642b0574aa7409de0bde3fec8d43Marco Nelissen} 981462fd2fa9eef642b0574aa7409de0bde3fec8d43Marco Nelissen 98281784c37c61b09289654b979567a42bf73cd2b12Eric Laurentvoid AudioFlinger::ThreadBase::clearPowerManager() 98381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 98481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent Mutex::Autolock _l(mLock); 98581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent releaseWakeLock_l(); 98681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mPowerManager.clear(); 98781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 98881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 9890f11b51a57bc9062c4fe8af73747319cedabc5d6Glenn Kastenvoid AudioFlinger::ThreadBase::PMDeathRecipient::binderDied(const wp<IBinder>& who __unused) 99081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 99181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent sp<ThreadBase> thread = mThread.promote(); 99281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (thread != 0) { 99381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent thread->clearPowerManager(); 99481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 99581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent ALOGW("power manager service died !!!"); 99681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 99781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 99881784c37c61b09289654b979567a42bf73cd2b12Eric Laurentvoid AudioFlinger::ThreadBase::setEffectSuspended( 999d848eb48c121c119e8ba7583efc75415fe102570Glenn Kasten const effect_uuid_t *type, bool suspend, audio_session_t sessionId) 100081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 100181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent Mutex::Autolock _l(mLock); 100281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent setEffectSuspended_l(type, suspend, sessionId); 100381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 100481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 100581784c37c61b09289654b979567a42bf73cd2b12Eric Laurentvoid AudioFlinger::ThreadBase::setEffectSuspended_l( 1006d848eb48c121c119e8ba7583efc75415fe102570Glenn Kasten const effect_uuid_t *type, bool suspend, audio_session_t sessionId) 100781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 100881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent sp<EffectChain> chain = getEffectChain_l(sessionId); 100981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (chain != 0) { 101081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (type != NULL) { 101181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent chain->setEffectSuspended_l(type, suspend); 101281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } else { 101381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent chain->setEffectSuspendedAll_l(suspend); 101481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 101581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 101681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 101781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent updateSuspendedSessions_l(type, suspend, sessionId); 101881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 101981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 102081784c37c61b09289654b979567a42bf73cd2b12Eric Laurentvoid AudioFlinger::ThreadBase::checkSuspendOnAddEffectChain_l(const sp<EffectChain>& chain) 102181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 102281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent ssize_t index = mSuspendedSessions.indexOfKey(chain->sessionId()); 102381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (index < 0) { 102481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent return; 102581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 102681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 102781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent const KeyedVector <int, sp<SuspendedSessionDesc> >& sessionEffects = 102881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mSuspendedSessions.valueAt(index); 102981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 103081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent for (size_t i = 0; i < sessionEffects.size(); i++) { 1031e964d4e421e2d1ca937227a580c0c837091a11e3Chih-Hung Hsieh const sp<SuspendedSessionDesc>& desc = sessionEffects.valueAt(i); 103281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent for (int j = 0; j < desc->mRefCount; j++) { 103381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (sessionEffects.keyAt(i) == EffectChain::kKeyForSuspendAll) { 103481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent chain->setEffectSuspendedAll_l(true); 103581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } else { 103681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent ALOGV("checkSuspendOnAddEffectChain_l() suspending effects %08x", 103781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent desc->mType.timeLow); 103881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent chain->setEffectSuspended_l(&desc->mType, true); 103981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 104081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 104181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 104281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 104381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 104481784c37c61b09289654b979567a42bf73cd2b12Eric Laurentvoid AudioFlinger::ThreadBase::updateSuspendedSessions_l(const effect_uuid_t *type, 104581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent bool suspend, 1046d848eb48c121c119e8ba7583efc75415fe102570Glenn Kasten audio_session_t sessionId) 104781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 104881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent ssize_t index = mSuspendedSessions.indexOfKey(sessionId); 104981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 105081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent KeyedVector <int, sp<SuspendedSessionDesc> > sessionEffects; 105181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 105281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (suspend) { 105381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (index >= 0) { 105481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent sessionEffects = mSuspendedSessions.valueAt(index); 105581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } else { 105681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mSuspendedSessions.add(sessionId, sessionEffects); 105781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 105881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } else { 105981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (index < 0) { 106081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent return; 106181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 106281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent sessionEffects = mSuspendedSessions.valueAt(index); 106381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 106481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 106581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 106681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent int key = EffectChain::kKeyForSuspendAll; 106781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (type != NULL) { 106881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent key = type->timeLow; 106981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 107081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent index = sessionEffects.indexOfKey(key); 107181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 107281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent sp<SuspendedSessionDesc> desc; 107381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (suspend) { 107481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (index >= 0) { 107581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent desc = sessionEffects.valueAt(index); 107681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } else { 107781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent desc = new SuspendedSessionDesc(); 107881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (type != NULL) { 107981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent desc->mType = *type; 108081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 108181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent sessionEffects.add(key, desc); 108281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent ALOGV("updateSuspendedSessions_l() suspend adding effect %08x", key); 108381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 108481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent desc->mRefCount++; 108581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } else { 108681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (index < 0) { 108781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent return; 108881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 108981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent desc = sessionEffects.valueAt(index); 109081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (--desc->mRefCount == 0) { 109181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent ALOGV("updateSuspendedSessions_l() restore removing effect %08x", key); 109281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent sessionEffects.removeItemsAt(index); 109381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (sessionEffects.isEmpty()) { 109481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent ALOGV("updateSuspendedSessions_l() restore removing session %d", 109581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent sessionId); 109681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mSuspendedSessions.removeItem(sessionId); 109781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 109881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 109981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 110081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (!sessionEffects.isEmpty()) { 110181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mSuspendedSessions.replaceValueFor(sessionId, sessionEffects); 110281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 110381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 110481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 110581784c37c61b09289654b979567a42bf73cd2b12Eric Laurentvoid AudioFlinger::ThreadBase::checkSuspendOnEffectEnabled(const sp<EffectModule>& effect, 110681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent bool enabled, 1107d848eb48c121c119e8ba7583efc75415fe102570Glenn Kasten audio_session_t sessionId) 110881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 110981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent Mutex::Autolock _l(mLock); 111081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent checkSuspendOnEffectEnabled_l(effect, enabled, sessionId); 111181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 111281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 111381784c37c61b09289654b979567a42bf73cd2b12Eric Laurentvoid AudioFlinger::ThreadBase::checkSuspendOnEffectEnabled_l(const sp<EffectModule>& effect, 111481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent bool enabled, 1115d848eb48c121c119e8ba7583efc75415fe102570Glenn Kasten audio_session_t sessionId) 111681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 111781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (mType != RECORD) { 111881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // suspend all effects in AUDIO_SESSION_OUTPUT_MIX when enabling any effect on 111981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // another session. This gives the priority to well behaved effect control panels 112081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // and applications not using global effects. 112181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // Enabling post processing in AUDIO_SESSION_OUTPUT_STAGE session does not affect 112281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // global effects 112381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if ((sessionId != AUDIO_SESSION_OUTPUT_MIX) && (sessionId != AUDIO_SESSION_OUTPUT_STAGE)) { 112481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent setEffectSuspended_l(NULL, enabled, AUDIO_SESSION_OUTPUT_MIX); 112581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 112681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 112781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 112881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent sp<EffectChain> chain = getEffectChain_l(sessionId); 112981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (chain != 0) { 113081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent chain->checkSuspendOnEffectEnabled(effect, enabled); 113181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 113281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 113381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 11344c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent// checkEffectCompatibility_l() must be called with ThreadBase::mLock held 11354c415062ad1bb53e9af8f644d8215837262b79bbEric Laurentstatus_t AudioFlinger::RecordThread::checkEffectCompatibility_l( 11364c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent const effect_descriptor_t *desc, audio_session_t sessionId) 11374c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent{ 11384c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent // No global effect sessions on record threads 11394c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent if (sessionId == AUDIO_SESSION_OUTPUT_MIX || sessionId == AUDIO_SESSION_OUTPUT_STAGE) { 11404c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent ALOGW("checkEffectCompatibility_l(): global effect %s on record thread %s", 11414c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent desc->name, mThreadName); 11424c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent return BAD_VALUE; 11434c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent } 11444c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent // only pre processing effects on record thread 11454c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent if ((desc->flags & EFFECT_FLAG_TYPE_MASK) != EFFECT_FLAG_TYPE_PRE_PROC) { 11464c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent ALOGW("checkEffectCompatibility_l(): non pre processing effect %s on record thread %s", 11474c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent desc->name, mThreadName); 11484c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent return BAD_VALUE; 11494c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent } 11506dd0fd92d6cdeb2cf5b7127c0e880e5eacfd4574Eric Laurent 11516dd0fd92d6cdeb2cf5b7127c0e880e5eacfd4574Eric Laurent // always allow effects without processing load or latency 11526dd0fd92d6cdeb2cf5b7127c0e880e5eacfd4574Eric Laurent if ((desc->flags & EFFECT_FLAG_NO_PROCESS_MASK) == EFFECT_FLAG_NO_PROCESS) { 11536dd0fd92d6cdeb2cf5b7127c0e880e5eacfd4574Eric Laurent return NO_ERROR; 11546dd0fd92d6cdeb2cf5b7127c0e880e5eacfd4574Eric Laurent } 11556dd0fd92d6cdeb2cf5b7127c0e880e5eacfd4574Eric Laurent 11564c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent audio_input_flags_t flags = mInput->flags; 11574c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent if (hasFastCapture() || (flags & AUDIO_INPUT_FLAG_FAST)) { 11584c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent if (flags & AUDIO_INPUT_FLAG_RAW) { 11594c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent ALOGW("checkEffectCompatibility_l(): effect %s on record thread %s in raw mode", 11604c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent desc->name, mThreadName); 11614c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent return BAD_VALUE; 11624c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent } 11634c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent if ((desc->flags & EFFECT_FLAG_HW_ACC_TUNNEL) == 0) { 11644c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent ALOGW("checkEffectCompatibility_l(): non HW effect %s on record thread %s in fast mode", 11654c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent desc->name, mThreadName); 11664c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent return BAD_VALUE; 11674c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent } 11684c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent } 11694c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent return NO_ERROR; 11704c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent} 11714c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent 11724c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent// checkEffectCompatibility_l() must be called with ThreadBase::mLock held 11734c415062ad1bb53e9af8f644d8215837262b79bbEric Laurentstatus_t AudioFlinger::PlaybackThread::checkEffectCompatibility_l( 11744c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent const effect_descriptor_t *desc, audio_session_t sessionId) 11754c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent{ 11764c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent // no preprocessing on playback threads 11774c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent if ((desc->flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_PRE_PROC) { 11784c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent ALOGW("checkEffectCompatibility_l(): pre processing effect %s created on playback" 11794c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent " thread %s", desc->name, mThreadName); 11804c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent return BAD_VALUE; 11814c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent } 11824c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent 11834c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent switch (mType) { 11844c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent case MIXER: { 11854c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent // Reject any effect on mixer multichannel sinks. 11864c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent // TODO: fix both format and multichannel issues with effects. 11874c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent if (mChannelCount != FCC_2) { 11884c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent ALOGW("checkEffectCompatibility_l(): effect %s for multichannel(%d) on MIXER" 11894c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent " thread %s", desc->name, mChannelCount, mThreadName); 11904c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent return BAD_VALUE; 11914c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent } 11924c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent audio_output_flags_t flags = mOutput->flags; 11934c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent if (hasFastMixer() || (flags & AUDIO_OUTPUT_FLAG_FAST)) { 11944c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent if (sessionId == AUDIO_SESSION_OUTPUT_MIX) { 11954c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent // global effects are applied only to non fast tracks if they are SW 11964c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent if ((desc->flags & EFFECT_FLAG_HW_ACC_TUNNEL) == 0) { 11974c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent break; 11984c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent } 11994c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent } else if (sessionId == AUDIO_SESSION_OUTPUT_STAGE) { 12004c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent // only post processing on output stage session 12014c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent if ((desc->flags & EFFECT_FLAG_TYPE_MASK) != EFFECT_FLAG_TYPE_POST_PROC) { 12024c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent ALOGW("checkEffectCompatibility_l(): non post processing effect %s not allowed" 12034c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent " on output stage session", desc->name); 12044c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent return BAD_VALUE; 12054c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent } 12064c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent } else { 12074c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent // no restriction on effects applied on non fast tracks 12084c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent if ((hasAudioSession_l(sessionId) & ThreadBase::FAST_SESSION) == 0) { 12094c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent break; 12104c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent } 12114c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent } 12126dd0fd92d6cdeb2cf5b7127c0e880e5eacfd4574Eric Laurent 12136dd0fd92d6cdeb2cf5b7127c0e880e5eacfd4574Eric Laurent // always allow effects without processing load or latency 12146dd0fd92d6cdeb2cf5b7127c0e880e5eacfd4574Eric Laurent if ((desc->flags & EFFECT_FLAG_NO_PROCESS_MASK) == EFFECT_FLAG_NO_PROCESS) { 12156dd0fd92d6cdeb2cf5b7127c0e880e5eacfd4574Eric Laurent break; 12166dd0fd92d6cdeb2cf5b7127c0e880e5eacfd4574Eric Laurent } 12174c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent if (flags & AUDIO_OUTPUT_FLAG_RAW) { 12184c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent ALOGW("checkEffectCompatibility_l(): effect %s on playback thread in raw mode", 12194c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent desc->name); 12204c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent return BAD_VALUE; 12214c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent } 12224c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent if ((desc->flags & EFFECT_FLAG_HW_ACC_TUNNEL) == 0) { 12234c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent ALOGW("checkEffectCompatibility_l(): non HW effect %s on playback thread" 12244c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent " in fast mode", desc->name); 12254c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent return BAD_VALUE; 12264c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent } 12274c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent } 12284c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent } break; 12294c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent case OFFLOAD: 1230773ee957aadbe86ee53ac96a108ce47f8e02b961Jean-Michel Trivi // nothing actionable on offload threads, if the effect: 1231773ee957aadbe86ee53ac96a108ce47f8e02b961Jean-Michel Trivi // - is offloadable: the effect can be created 1232773ee957aadbe86ee53ac96a108ce47f8e02b961Jean-Michel Trivi // - is NOT offloadable: the effect should still be created, but EffectHandle::enable() 1233773ee957aadbe86ee53ac96a108ce47f8e02b961Jean-Michel Trivi // will take care of invalidating the tracks of the thread 12344c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent break; 12354c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent case DIRECT: 12364c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent // Reject any effect on Direct output threads for now, since the format of 12374c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent // mSinkBuffer is not guaranteed to be compatible with effect processing (PCM 16 stereo). 12384c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent ALOGW("checkEffectCompatibility_l(): effect %s on DIRECT output thread %s", 12394c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent desc->name, mThreadName); 12404c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent return BAD_VALUE; 12414c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent case DUPLICATING: 12424c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent // Reject any effect on mixer multichannel sinks. 12434c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent // TODO: fix both format and multichannel issues with effects. 12444c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent if (mChannelCount != FCC_2) { 12454c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent ALOGW("checkEffectCompatibility_l(): effect %s for multichannel(%d)" 12464c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent " on DUPLICATING thread %s", desc->name, mChannelCount, mThreadName); 12474c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent return BAD_VALUE; 12484c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent } 12494c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent if ((sessionId == AUDIO_SESSION_OUTPUT_STAGE) || (sessionId == AUDIO_SESSION_OUTPUT_MIX)) { 12504c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent ALOGW("checkEffectCompatibility_l(): global effect %s on DUPLICATING" 12514c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent " thread %s", desc->name, mThreadName); 12524c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent return BAD_VALUE; 12534c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent } 12544c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent if ((desc->flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_POST_PROC) { 12554c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent ALOGW("checkEffectCompatibility_l(): post processing effect %s on" 12564c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent " DUPLICATING thread %s", desc->name, mThreadName); 12574c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent return BAD_VALUE; 12584c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent } 12594c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent if ((desc->flags & EFFECT_FLAG_HW_ACC_TUNNEL) != 0) { 12604c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent ALOGW("checkEffectCompatibility_l(): HW tunneled effect %s on" 12614c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent " DUPLICATING thread %s", desc->name, mThreadName); 12624c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent return BAD_VALUE; 12634c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent } 12644c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent break; 12654c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent default: 12664c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent LOG_ALWAYS_FATAL("checkEffectCompatibility_l(): wrong thread type %d", mType); 12674c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent } 12684c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent 12694c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent return NO_ERROR; 12704c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent} 12714c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent 127281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// ThreadBase::createEffect_l() must be called with AudioFlinger::mLock held 127381784c37c61b09289654b979567a42bf73cd2b12Eric Laurentsp<AudioFlinger::EffectHandle> AudioFlinger::ThreadBase::createEffect_l( 127481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent const sp<AudioFlinger::Client>& client, 127581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent const sp<IEffectClient>& effectClient, 127681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent int32_t priority, 1277d848eb48c121c119e8ba7583efc75415fe102570Glenn Kasten audio_session_t sessionId, 127881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent effect_descriptor_t *desc, 127981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent int *enabled, 12800d5a2ed0a05a2bf337c68edb54f24c60e18032c1Eric Laurent status_t *status, 12810d5a2ed0a05a2bf337c68edb54f24c60e18032c1Eric Laurent bool pinned) 128281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 128381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent sp<EffectModule> effect; 128481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent sp<EffectHandle> handle; 128581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent status_t lStatus; 128681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent sp<EffectChain> chain; 128781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent bool chainCreated = false; 128881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent bool effectCreated = false; 128981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent bool effectRegistered = false; 12902247f7b84bf0ce3cc9c909ef987eedb086e3b4e8Mikhail Naganov audio_unique_id_t effectId = AUDIO_UNIQUE_ID_USE_UNSPECIFIED; 129181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 129281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent lStatus = initCheck(); 129381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (lStatus != NO_ERROR) { 129481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent ALOGW("createEffect_l() Audio driver not initialized."); 129581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent goto Exit; 129681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 129781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 129881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent ALOGV("createEffect_l() thread %p effect %s on session %d", this, desc->name, sessionId); 129981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 130081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent { // scope for mLock 130181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent Mutex::Autolock _l(mLock); 130281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 13034c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent lStatus = checkEffectCompatibility_l(desc, sessionId); 13044c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent if (lStatus != NO_ERROR) { 13054c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent goto Exit; 13064c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent } 13074c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent 130881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // check for existing effect chain with the requested audio session 130981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent chain = getEffectChain_l(sessionId); 131081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (chain == 0) { 131181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // create a new chain for this session 131281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent ALOGV("createEffect_l() new effect chain for session %d", sessionId); 131381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent chain = new EffectChain(this, sessionId); 131481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent addEffectChain_l(chain); 131581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent chain->setStrategy(getStrategyForSession_l(sessionId)); 131681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent chainCreated = true; 131781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } else { 131881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent effect = chain->getEffectFromDesc_l(desc); 131981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 132081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 132181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent ALOGV("createEffect_l() got effect %p on chain %p", effect.get(), chain.get()); 132281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 132381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (effect == 0) { 13242247f7b84bf0ce3cc9c909ef987eedb086e3b4e8Mikhail Naganov effectId = mAudioFlinger->nextUniqueId(AUDIO_UNIQUE_ID_USE_EFFECT); 132581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // Check CPU and memory usage 13262247f7b84bf0ce3cc9c909ef987eedb086e3b4e8Mikhail Naganov lStatus = AudioSystem::registerEffect( 13272247f7b84bf0ce3cc9c909ef987eedb086e3b4e8Mikhail Naganov desc, mId, chain->strategy(), sessionId, effectId); 132881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (lStatus != NO_ERROR) { 132981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent goto Exit; 133081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 133181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent effectRegistered = true; 133281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // create a new effect module if none present in the chain 13332247f7b84bf0ce3cc9c909ef987eedb086e3b4e8Mikhail Naganov lStatus = chain->createEffect_l(effect, this, desc, effectId, sessionId, pinned); 133481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (lStatus != NO_ERROR) { 133581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent goto Exit; 133681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 133781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent effectCreated = true; 133881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 133981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent effect->setDevice(mOutDevice); 134081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent effect->setDevice(mInDevice); 134181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent effect->setMode(mAudioFlinger->getMode()); 134281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent effect->setAudioSource(mAudioSource); 134381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 134481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // create effect handle and connect it to effect module 134581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent handle = new EffectHandle(effect, client, effectClient, priority); 1346e75da4004b2c814987aa2adf8a76190f92d99c65Glenn Kasten lStatus = handle->initCheck(); 1347e75da4004b2c814987aa2adf8a76190f92d99c65Glenn Kasten if (lStatus == OK) { 1348e75da4004b2c814987aa2adf8a76190f92d99c65Glenn Kasten lStatus = effect->addHandle(handle.get()); 1349e75da4004b2c814987aa2adf8a76190f92d99c65Glenn Kasten } 135081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (enabled != NULL) { 135181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent *enabled = (int)effect->isEnabled(); 135281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 135381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 135481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 135581784c37c61b09289654b979567a42bf73cd2b12Eric LaurentExit: 135681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (lStatus != NO_ERROR && lStatus != ALREADY_EXISTS) { 135781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent Mutex::Autolock _l(mLock); 135881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (effectCreated) { 135981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent chain->removeEffect_l(effect); 136081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 136181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (effectRegistered) { 13622247f7b84bf0ce3cc9c909ef987eedb086e3b4e8Mikhail Naganov AudioSystem::unregisterEffect(effectId); 136381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 136481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (chainCreated) { 136581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent removeEffectChain_l(chain); 136681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 136781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent handle.clear(); 136881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 136981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 13709156ef3e11b68cc4b6d3cea77f1f63673855a6d1Glenn Kasten *status = lStatus; 137181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent return handle; 137281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 137381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 13740d5a2ed0a05a2bf337c68edb54f24c60e18032c1Eric Laurentvoid AudioFlinger::ThreadBase::disconnectEffectHandle(EffectHandle *handle, 13750d5a2ed0a05a2bf337c68edb54f24c60e18032c1Eric Laurent bool unpinIfLast) 13760d5a2ed0a05a2bf337c68edb54f24c60e18032c1Eric Laurent{ 13770d5a2ed0a05a2bf337c68edb54f24c60e18032c1Eric Laurent bool remove = false; 13780d5a2ed0a05a2bf337c68edb54f24c60e18032c1Eric Laurent sp<EffectModule> effect; 13790d5a2ed0a05a2bf337c68edb54f24c60e18032c1Eric Laurent { 13800d5a2ed0a05a2bf337c68edb54f24c60e18032c1Eric Laurent Mutex::Autolock _l(mLock); 13810d5a2ed0a05a2bf337c68edb54f24c60e18032c1Eric Laurent 13820d5a2ed0a05a2bf337c68edb54f24c60e18032c1Eric Laurent effect = handle->effect().promote(); 13830d5a2ed0a05a2bf337c68edb54f24c60e18032c1Eric Laurent if (effect == 0) { 13840d5a2ed0a05a2bf337c68edb54f24c60e18032c1Eric Laurent return; 13850d5a2ed0a05a2bf337c68edb54f24c60e18032c1Eric Laurent } 13860d5a2ed0a05a2bf337c68edb54f24c60e18032c1Eric Laurent // restore suspended effects if the disconnected handle was enabled and the last one. 13870d5a2ed0a05a2bf337c68edb54f24c60e18032c1Eric Laurent remove = (effect->removeHandle(handle) == 0) && (!effect->isPinned() || unpinIfLast); 13880d5a2ed0a05a2bf337c68edb54f24c60e18032c1Eric Laurent if (remove) { 13890d5a2ed0a05a2bf337c68edb54f24c60e18032c1Eric Laurent removeEffect_l(effect, true); 13900d5a2ed0a05a2bf337c68edb54f24c60e18032c1Eric Laurent } 13910d5a2ed0a05a2bf337c68edb54f24c60e18032c1Eric Laurent } 13920d5a2ed0a05a2bf337c68edb54f24c60e18032c1Eric Laurent if (remove) { 13930d5a2ed0a05a2bf337c68edb54f24c60e18032c1Eric Laurent mAudioFlinger->updateOrphanEffectChains(effect); 13940d5a2ed0a05a2bf337c68edb54f24c60e18032c1Eric Laurent AudioSystem::unregisterEffect(effect->id()); 13950d5a2ed0a05a2bf337c68edb54f24c60e18032c1Eric Laurent if (handle->enabled()) { 13960d5a2ed0a05a2bf337c68edb54f24c60e18032c1Eric Laurent checkSuspendOnEffectEnabled(effect, false, effect->sessionId()); 13970d5a2ed0a05a2bf337c68edb54f24c60e18032c1Eric Laurent } 13980d5a2ed0a05a2bf337c68edb54f24c60e18032c1Eric Laurent } 13990d5a2ed0a05a2bf337c68edb54f24c60e18032c1Eric Laurent} 14000d5a2ed0a05a2bf337c68edb54f24c60e18032c1Eric Laurent 1401d848eb48c121c119e8ba7583efc75415fe102570Glenn Kastensp<AudioFlinger::EffectModule> AudioFlinger::ThreadBase::getEffect(audio_session_t sessionId, 1402d848eb48c121c119e8ba7583efc75415fe102570Glenn Kasten int effectId) 140381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 140481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent Mutex::Autolock _l(mLock); 140581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent return getEffect_l(sessionId, effectId); 140681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 140781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 1408d848eb48c121c119e8ba7583efc75415fe102570Glenn Kastensp<AudioFlinger::EffectModule> AudioFlinger::ThreadBase::getEffect_l(audio_session_t sessionId, 1409d848eb48c121c119e8ba7583efc75415fe102570Glenn Kasten int effectId) 141081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 141181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent sp<EffectChain> chain = getEffectChain_l(sessionId); 141281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent return chain != 0 ? chain->getEffectFromId_l(effectId) : 0; 141381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 141481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 141581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// PlaybackThread::addEffect_l() must be called with AudioFlinger::mLock and 141681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// PlaybackThread::mLock held 141781784c37c61b09289654b979567a42bf73cd2b12Eric Laurentstatus_t AudioFlinger::ThreadBase::addEffect_l(const sp<EffectModule>& effect) 141881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 141981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // check for existing effect chain with the requested audio session 1420d848eb48c121c119e8ba7583efc75415fe102570Glenn Kasten audio_session_t sessionId = effect->sessionId(); 142181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent sp<EffectChain> chain = getEffectChain_l(sessionId); 142281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent bool chainCreated = false; 142381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 14245baf2af52cd186633b7173196c1e4a4cd3435f22Eric Laurent ALOGD_IF((mType == OFFLOAD) && !effect->isOffloadable(), 14255baf2af52cd186633b7173196c1e4a4cd3435f22Eric Laurent "addEffect_l() on offloaded thread %p: effect %s does not support offload flags %x", 14265baf2af52cd186633b7173196c1e4a4cd3435f22Eric Laurent this, effect->desc().name, effect->desc().flags); 14275baf2af52cd186633b7173196c1e4a4cd3435f22Eric Laurent 142881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (chain == 0) { 142981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // create a new chain for this session 143081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent ALOGV("addEffect_l() new effect chain for session %d", sessionId); 143181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent chain = new EffectChain(this, sessionId); 143281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent addEffectChain_l(chain); 143381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent chain->setStrategy(getStrategyForSession_l(sessionId)); 143481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent chainCreated = true; 143581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 143681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent ALOGV("addEffect_l() %p chain %p effect %p", this, chain.get(), effect.get()); 143781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 143881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (chain->getEffectFromId_l(effect->id()) != 0) { 143981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent ALOGW("addEffect_l() %p effect %s already present in chain %p", 144081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent this, effect->desc().name, chain.get()); 144181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent return BAD_VALUE; 144281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 144381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 14445baf2af52cd186633b7173196c1e4a4cd3435f22Eric Laurent effect->setOffloaded(mType == OFFLOAD, mId); 14455baf2af52cd186633b7173196c1e4a4cd3435f22Eric Laurent 144681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent status_t status = chain->addEffect_l(effect); 144781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (status != NO_ERROR) { 144881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (chainCreated) { 144981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent removeEffectChain_l(chain); 145081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 145181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent return status; 145281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 145381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 145481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent effect->setDevice(mOutDevice); 145581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent effect->setDevice(mInDevice); 145681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent effect->setMode(mAudioFlinger->getMode()); 145781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent effect->setAudioSource(mAudioSource); 145881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent return NO_ERROR; 145981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 146081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 14610d5a2ed0a05a2bf337c68edb54f24c60e18032c1Eric Laurentvoid AudioFlinger::ThreadBase::removeEffect_l(const sp<EffectModule>& effect, bool release) { 146281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 14630d5a2ed0a05a2bf337c68edb54f24c60e18032c1Eric Laurent ALOGV("%s %p effect %p", __FUNCTION__, this, effect.get()); 146481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent effect_descriptor_t desc = effect->desc(); 146581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if ((desc.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_AUXILIARY) { 146681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent detachAuxEffect_l(effect->id()); 146781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 146881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 146981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent sp<EffectChain> chain = effect->chain().promote(); 147081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (chain != 0) { 147181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // remove effect chain if removing last effect 14720d5a2ed0a05a2bf337c68edb54f24c60e18032c1Eric Laurent if (chain->removeEffect_l(effect, release) == 0) { 147381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent removeEffectChain_l(chain); 147481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 147581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } else { 147681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent ALOGW("removeEffect_l() %p cannot promote chain for effect %p", this, effect.get()); 147781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 147881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 147981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 148081784c37c61b09289654b979567a42bf73cd2b12Eric Laurentvoid AudioFlinger::ThreadBase::lockEffectChains_l( 148181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent Vector< sp<AudioFlinger::EffectChain> >& effectChains) 148281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 148381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent effectChains = mEffectChains; 148481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent for (size_t i = 0; i < mEffectChains.size(); i++) { 148581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mEffectChains[i]->lock(); 148681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 148781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 148881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 148981784c37c61b09289654b979567a42bf73cd2b12Eric Laurentvoid AudioFlinger::ThreadBase::unlockEffectChains( 149081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent const Vector< sp<AudioFlinger::EffectChain> >& effectChains) 149181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 149281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent for (size_t i = 0; i < effectChains.size(); i++) { 149381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent effectChains[i]->unlock(); 149481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 149581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 149681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 1497d848eb48c121c119e8ba7583efc75415fe102570Glenn Kastensp<AudioFlinger::EffectChain> AudioFlinger::ThreadBase::getEffectChain(audio_session_t sessionId) 149881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 149981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent Mutex::Autolock _l(mLock); 150081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent return getEffectChain_l(sessionId); 150181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 150281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 1503d848eb48c121c119e8ba7583efc75415fe102570Glenn Kastensp<AudioFlinger::EffectChain> AudioFlinger::ThreadBase::getEffectChain_l(audio_session_t sessionId) 1504d848eb48c121c119e8ba7583efc75415fe102570Glenn Kasten const 150581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 150681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent size_t size = mEffectChains.size(); 150781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent for (size_t i = 0; i < size; i++) { 150881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (mEffectChains[i]->sessionId() == sessionId) { 150981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent return mEffectChains[i]; 151081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 151181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 151281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent return 0; 151381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 151481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 151581784c37c61b09289654b979567a42bf73cd2b12Eric Laurentvoid AudioFlinger::ThreadBase::setMode(audio_mode_t mode) 151681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 151781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent Mutex::Autolock _l(mLock); 151881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent size_t size = mEffectChains.size(); 151981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent for (size_t i = 0; i < size; i++) { 152081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mEffectChains[i]->setMode_l(mode); 152181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 152281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 152381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 152483b8808faad1e91690c64d7007348be8d9ebde73Eric Laurentvoid AudioFlinger::ThreadBase::getAudioPortConfig(struct audio_port_config *config) 152583b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent{ 152683b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent config->type = AUDIO_PORT_TYPE_MIX; 152783b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent config->ext.mix.handle = mId; 152883b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent config->sample_rate = mSampleRate; 152983b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent config->format = mFormat; 153083b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent config->channel_mask = mChannelMask; 153183b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent config->config_mask = AUDIO_PORT_CONFIG_SAMPLE_RATE|AUDIO_PORT_CONFIG_CHANNEL_MASK| 153283b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent AUDIO_PORT_CONFIG_FORMAT; 153383b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent} 153483b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent 153572e3f39146fce4686bd96f11057c051bea376dfbEric Laurentvoid AudioFlinger::ThreadBase::systemReady() 153672e3f39146fce4686bd96f11057c051bea376dfbEric Laurent{ 153772e3f39146fce4686bd96f11057c051bea376dfbEric Laurent Mutex::Autolock _l(mLock); 153872e3f39146fce4686bd96f11057c051bea376dfbEric Laurent if (mSystemReady) { 153972e3f39146fce4686bd96f11057c051bea376dfbEric Laurent return; 154072e3f39146fce4686bd96f11057c051bea376dfbEric Laurent } 154172e3f39146fce4686bd96f11057c051bea376dfbEric Laurent mSystemReady = true; 154272e3f39146fce4686bd96f11057c051bea376dfbEric Laurent 154372e3f39146fce4686bd96f11057c051bea376dfbEric Laurent for (size_t i = 0; i < mPendingConfigEvents.size(); i++) { 154472e3f39146fce4686bd96f11057c051bea376dfbEric Laurent sendConfigEvent_l(mPendingConfigEvents.editItemAt(i)); 154572e3f39146fce4686bd96f11057c051bea376dfbEric Laurent } 154672e3f39146fce4686bd96f11057c051bea376dfbEric Laurent mPendingConfigEvents.clear(); 154772e3f39146fce4686bd96f11057c051bea376dfbEric Laurent} 154872e3f39146fce4686bd96f11057c051bea376dfbEric Laurent 1549dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hungtemplate <typename T> 1550dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hungssize_t AudioFlinger::ThreadBase::ActiveTracks<T>::add(const sp<T> &track) { 1551dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hung ssize_t index = mActiveTracks.indexOf(track); 1552dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hung if (index >= 0) { 1553dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hung ALOGW("ActiveTracks<T>::add track %p already there", track.get()); 1554dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hung return index; 1555dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hung } 1556dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hung mActiveTracksGeneration++; 1557dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hung mLatestActiveTrack = track; 1558dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hung ++mBatteryCounter[track->uid()].second; 1559dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hung return mActiveTracks.add(track); 1560dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hung} 1561dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hung 1562dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hungtemplate <typename T> 1563dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hungssize_t AudioFlinger::ThreadBase::ActiveTracks<T>::remove(const sp<T> &track) { 1564dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hung ssize_t index = mActiveTracks.remove(track); 1565dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hung if (index < 0) { 1566dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hung ALOGW("ActiveTracks<T>::remove nonexistent track %p", track.get()); 1567dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hung return index; 1568dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hung } 1569dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hung mActiveTracksGeneration++; 1570dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hung --mBatteryCounter[track->uid()].second; 1571dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hung // mLatestActiveTrack is not cleared even if is the same as track. 1572dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hung return index; 1573dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hung} 1574dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hung 1575dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hungtemplate <typename T> 1576dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hungvoid AudioFlinger::ThreadBase::ActiveTracks<T>::clear() { 1577dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hung for (const sp<T> &track : mActiveTracks) { 1578dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hung BatteryNotifier::getInstance().noteStopAudio(track->uid()); 1579dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hung } 1580dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hung mLastActiveTracksGeneration = mActiveTracksGeneration; 1581dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hung mActiveTracks.clear(); 1582dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hung mLatestActiveTrack.clear(); 1583dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hung mBatteryCounter.clear(); 1584dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hung} 1585dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hung 1586dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hungtemplate <typename T> 1587dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hungvoid AudioFlinger::ThreadBase::ActiveTracks<T>::updatePowerState( 1588dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hung sp<ThreadBase> thread, bool force) { 1589dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hung // Updates ActiveTracks client uids to the thread wakelock. 1590dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hung if (mActiveTracksGeneration != mLastActiveTracksGeneration || force) { 1591dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hung thread->updateWakeLockUids_l(getWakeLockUids()); 1592dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hung mLastActiveTracksGeneration = mActiveTracksGeneration; 1593dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hung } 1594dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hung 1595dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hung // Updates BatteryNotifier uids 1596dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hung for (auto it = mBatteryCounter.begin(); it != mBatteryCounter.end();) { 1597dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hung const uid_t uid = it->first; 1598dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hung ssize_t &previous = it->second.first; 1599dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hung ssize_t ¤t = it->second.second; 1600dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hung if (current > 0) { 1601dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hung if (previous == 0) { 1602dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hung BatteryNotifier::getInstance().noteStartAudio(uid); 1603dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hung } 1604dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hung previous = current; 1605dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hung ++it; 1606dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hung } else if (current == 0) { 1607dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hung if (previous > 0) { 1608dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hung BatteryNotifier::getInstance().noteStopAudio(uid); 1609dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hung } 1610dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hung it = mBatteryCounter.erase(it); // std::map<> is stable on iterator erase. 1611dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hung } else /* (current < 0) */ { 1612dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hung LOG_ALWAYS_FATAL("negative battery count %zd", current); 1613dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hung } 1614dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hung } 1615dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hung} 161683b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent 16176acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurentvoid AudioFlinger::ThreadBase::broadcast_l() 16186acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent{ 16196acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent // Thread could be blocked waiting for async 16206acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent // so signal it to handle state changes immediately 16216acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent // If threadLoop is currently unlocked a signal of mWaitWorkCV will 16226acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent // be lost so we also flag to prevent it blocking on mWaitWorkCV 16236acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent mSignalPending = true; 16246acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent mWaitWorkCV.broadcast(); 16256acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent} 16266acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 162781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// ---------------------------------------------------------------------------- 162881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// Playback 162981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// ---------------------------------------------------------------------------- 163081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 163181784c37c61b09289654b979567a42bf73cd2b12Eric LaurentAudioFlinger::PlaybackThread::PlaybackThread(const sp<AudioFlinger>& audioFlinger, 163281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent AudioStreamOut* output, 163381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent audio_io_handle_t id, 163481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent audio_devices_t device, 163572e3f39146fce4686bd96f11057c051bea376dfbEric Laurent type_t type, 1636e93cc03da360a1a0d2ad937c745ce8c8e8be81c2Eric Laurent bool systemReady) 163772e3f39146fce4686bd96f11057c051bea376dfbEric Laurent : ThreadBase(audioFlinger, id, device, AUDIO_DEVICE_NONE, type, systemReady), 16382098f2744cedf2dc3fa36f608aa965a34602e7c0Andy Hung mNormalFrameCount(0), mSinkBuffer(NULL), 16396146c08f0c3dd8b9e5788063aa433f304a810602Andy Hung mMixerBufferEnabled(AudioFlinger::kEnableExtendedPrecision), 164069aed5f0f4a3be3996d1e78a0473e1a72c1547daAndy Hung mMixerBuffer(NULL), 164169aed5f0f4a3be3996d1e78a0473e1a72c1547daAndy Hung mMixerBufferSize(0), 164269aed5f0f4a3be3996d1e78a0473e1a72c1547daAndy Hung mMixerBufferFormat(AUDIO_FORMAT_INVALID), 164369aed5f0f4a3be3996d1e78a0473e1a72c1547daAndy Hung mMixerBufferValid(false), 16446146c08f0c3dd8b9e5788063aa433f304a810602Andy Hung mEffectBufferEnabled(AudioFlinger::kEnableExtendedPrecision), 164598ef978df4e928f486d244c4d7f7ad9f13111e98Andy Hung mEffectBuffer(NULL), 164698ef978df4e928f486d244c4d7f7ad9f13111e98Andy Hung mEffectBufferSize(0), 164798ef978df4e928f486d244c4d7f7ad9f13111e98Andy Hung mEffectBufferFormat(AUDIO_FORMAT_INVALID), 164898ef978df4e928f486d244c4d7f7ad9f13111e98Andy Hung mEffectBufferValid(false), 1649c1fac191069774c7bfcb062edbb821ea56e7dbc0Glenn Kasten mSuspended(0), mBytesWritten(0), 1650c54b1ffc92b8ad27608a8af21033d7cab33cb3a0Andy Hung mFramesWritten(0), 1651238fa3deff26d7e4d9e81bd0a88c936f16226c4eAndy Hung mSuspendedFrames(0), 165281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // mStreamTypes[] initialized in constructor body 165381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mOutput(output), 165469488c4ef115c9de52c85f4fcae27c7774720298Andy Hung mLastWriteTime(-1), mNumWrites(0), mNumDelayedWrites(0), mInWrite(false), 165581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mMixerStatus(MIXER_IDLE), 165681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mMixerStatusIgnoringFastTracks(MIXER_IDLE), 1657ad9cb8b88e4f8face23f01d8dc89fa769dacb50fEric Laurent mStandbyDelayNs(AudioFlinger::mStandbyTimeInNsecs), 1658bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent mBytesRemaining(0), 1659bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent mCurrentWriteLength(0), 1660bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent mUseAsyncWrite(false), 16613b4529e03c5fc7a44c22f9091ad15a269bfca3a8Eric Laurent mWriteAckSequence(0), 16623b4529e03c5fc7a44c22f9091ad15a269bfca3a8Eric Laurent mDrainSequence(0), 166381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mScreenState(AudioFlinger::mScreenState), 166481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // index 0 is reserved for normal mixer's submix 1665dc2c50bad491d2c0c8a2efc0e24491076701c63cGlenn Kasten mFastTrackAvailMask(((1 << FastMixerState::sMaxFastTracks) - 1) & ~1), 1666e10393e72454bfd8298017dc193faf424f4e9a8fAndy Hung mHwSupportsPause(false), mHwPaused(false), mFlushPending(false) 166781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 1668d7dca050c630bddbd73a6623271b34b4290460eeGlenn Kasten snprintf(mThreadName, kThreadNameLength, "AudioOut_%X", id); 1669d7dca050c630bddbd73a6623271b34b4290460eeGlenn Kasten mNBLogWriter = audioFlinger->newWriter_l(kLogSize, mThreadName); 167081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 167181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // Assumes constructor is called by AudioFlinger with it's mLock held, but 167281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // it would be safer to explicitly pass initial masterVolume/masterMute as 167381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // parameter. 167481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // 167581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // If the HAL we are using has support for master volume or master mute, 167681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // then do not attenuate or mute during mixing (just leave the volume at 1.0 167781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // and the mute set to false). 167881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mMasterVolume = audioFlinger->masterVolume_l(); 167981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mMasterMute = audioFlinger->masterMute_l(); 168081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (mOutput && mOutput->audioHwDev) { 168181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (mOutput->audioHwDev->canSetMasterVolume()) { 168281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mMasterVolume = 1.0; 168381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 168481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 168581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (mOutput->audioHwDev->canSetMasterMute()) { 168681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mMasterMute = false; 168781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 168881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 168981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 1690deca2ae0a7cf8bc54ff3f30b7dc39bbc78b94c0dGlenn Kasten readOutputParameters_l(); 169181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 1692223fd5c9738e9665e495904d37d4632414b68c1eEric Laurent // ++ operator does not compile 169366e4635cb09fadcaccf912f37c387396c428378aGlenn Kasten for (audio_stream_type_t stream = AUDIO_STREAM_MIN; stream < AUDIO_STREAM_CNT; 169481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent stream = (audio_stream_type_t) (stream + 1)) { 169581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mStreamTypes[stream].volume = mAudioFlinger->streamVolume_l(stream); 169681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mStreamTypes[stream].mute = mAudioFlinger->streamMute_l(stream); 169781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 169881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 169981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 170081784c37c61b09289654b979567a42bf73cd2b12Eric LaurentAudioFlinger::PlaybackThread::~PlaybackThread() 170181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 17029e58b552f51b00b3b674102876bd6c77ef3da806Glenn Kasten mAudioFlinger->unregisterWriter(mNBLogWriter); 1703010a1a1a552cdaad362cea8a0333b8906402dbcbAndy Hung free(mSinkBuffer); 170469aed5f0f4a3be3996d1e78a0473e1a72c1547daAndy Hung free(mMixerBuffer); 170598ef978df4e928f486d244c4d7f7ad9f13111e98Andy Hung free(mEffectBuffer); 170681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 170781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 170881784c37c61b09289654b979567a42bf73cd2b12Eric Laurentvoid AudioFlinger::PlaybackThread::dump(int fd, const Vector<String16>& args) 170981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 171081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent dumpInternals(fd, args); 171181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent dumpTracks(fd, args); 171281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent dumpEffectChains(fd, args); 1713293558ad1977e24e65f7ba78f47382d33fc77d64Andy Hung dprintf(fd, " Local log:\n"); 1714293558ad1977e24e65f7ba78f47382d33fc77d64Andy Hung mLocalLog.dump(fd, " " /* prefix */, 40 /* lines */); 171581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 171681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 17170f11b51a57bc9062c4fe8af73747319cedabc5d6Glenn Kastenvoid AudioFlinger::PlaybackThread::dumpTracks(int fd, const Vector<String16>& args __unused) 171881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 171981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent const size_t SIZE = 256; 172081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent char buffer[SIZE]; 172181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent String8 result; 172281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 1723b220884bf3129253cc5bc8d030bc475411ea4911Marco Nelissen result.appendFormat(" Stream volumes in dB: "); 172481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent for (int i = 0; i < AUDIO_STREAM_CNT; ++i) { 172581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent const stream_type_t *st = &mStreamTypes[i]; 172681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (i > 0) { 172781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent result.appendFormat(", "); 172881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 172981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent result.appendFormat("%d:%.2g", i, 20.0 * log10(st->volume)); 173081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (st->mute) { 173181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent result.append("M"); 173281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 173381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 173481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent result.append("\n"); 173581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent write(fd, result.string(), result.length()); 173681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent result.clear(); 173781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 1738b220884bf3129253cc5bc8d030bc475411ea4911Marco Nelissen // These values are "raw"; they will wrap around. See prepareTracks_l() for a better way. 1739b220884bf3129253cc5bc8d030bc475411ea4911Marco Nelissen FastTrackUnderruns underruns = getFastTrackUnderruns(0); 174087cebadd48710e42474756fc3513df678de045ceElliott Hughes dprintf(fd, " Normal mixer raw underrun counters: partial=%u empty=%u\n", 1741b220884bf3129253cc5bc8d030bc475411ea4911Marco Nelissen underruns.mBitFields.mPartial, underruns.mBitFields.mEmpty); 1742b220884bf3129253cc5bc8d030bc475411ea4911Marco Nelissen 1743b220884bf3129253cc5bc8d030bc475411ea4911Marco Nelissen size_t numtracks = mTracks.size(); 1744b220884bf3129253cc5bc8d030bc475411ea4911Marco Nelissen size_t numactive = mActiveTracks.size(); 1745c42e9b462661673dff480ee71757a58b0f806370Glenn Kasten dprintf(fd, " %zu Tracks", numtracks); 1746b220884bf3129253cc5bc8d030bc475411ea4911Marco Nelissen size_t numactiveseen = 0; 1747b220884bf3129253cc5bc8d030bc475411ea4911Marco Nelissen if (numtracks) { 1748c42e9b462661673dff480ee71757a58b0f806370Glenn Kasten dprintf(fd, " of which %zu are active\n", numactive); 1749b220884bf3129253cc5bc8d030bc475411ea4911Marco Nelissen Track::appendDumpHeader(result); 1750b220884bf3129253cc5bc8d030bc475411ea4911Marco Nelissen for (size_t i = 0; i < numtracks; ++i) { 1751b220884bf3129253cc5bc8d030bc475411ea4911Marco Nelissen sp<Track> track = mTracks[i]; 1752b220884bf3129253cc5bc8d030bc475411ea4911Marco Nelissen if (track != 0) { 1753b220884bf3129253cc5bc8d030bc475411ea4911Marco Nelissen bool active = mActiveTracks.indexOf(track) >= 0; 1754b220884bf3129253cc5bc8d030bc475411ea4911Marco Nelissen if (active) { 1755b220884bf3129253cc5bc8d030bc475411ea4911Marco Nelissen numactiveseen++; 1756b220884bf3129253cc5bc8d030bc475411ea4911Marco Nelissen } 1757b220884bf3129253cc5bc8d030bc475411ea4911Marco Nelissen track->dump(buffer, SIZE, active); 1758b220884bf3129253cc5bc8d030bc475411ea4911Marco Nelissen result.append(buffer); 1759b220884bf3129253cc5bc8d030bc475411ea4911Marco Nelissen } 176081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 1761b220884bf3129253cc5bc8d030bc475411ea4911Marco Nelissen } else { 1762b220884bf3129253cc5bc8d030bc475411ea4911Marco Nelissen result.append("\n"); 176381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 1764b220884bf3129253cc5bc8d030bc475411ea4911Marco Nelissen if (numactiveseen != numactive) { 1765b220884bf3129253cc5bc8d030bc475411ea4911Marco Nelissen // some tracks in the active list were not in the tracks list 1766b220884bf3129253cc5bc8d030bc475411ea4911Marco Nelissen snprintf(buffer, SIZE, " The following tracks are in the active list but" 1767b220884bf3129253cc5bc8d030bc475411ea4911Marco Nelissen " not in the track list\n"); 1768b220884bf3129253cc5bc8d030bc475411ea4911Marco Nelissen result.append(buffer); 1769b220884bf3129253cc5bc8d030bc475411ea4911Marco Nelissen Track::appendDumpHeader(result); 1770b220884bf3129253cc5bc8d030bc475411ea4911Marco Nelissen for (size_t i = 0; i < numactive; ++i) { 1771dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hung sp<Track> track = mActiveTracks[i]; 1772dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hung if (mTracks.indexOf(track) < 0) { 1773b220884bf3129253cc5bc8d030bc475411ea4911Marco Nelissen track->dump(buffer, SIZE, true); 1774b220884bf3129253cc5bc8d030bc475411ea4911Marco Nelissen result.append(buffer); 1775b220884bf3129253cc5bc8d030bc475411ea4911Marco Nelissen } 177681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 177781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 1778b220884bf3129253cc5bc8d030bc475411ea4911Marco Nelissen 177981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent write(fd, result.string(), result.size()); 178081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 178181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 178281784c37c61b09289654b979567a42bf73cd2b12Eric Laurentvoid AudioFlinger::PlaybackThread::dumpInternals(int fd, const Vector<String16>& args) 178381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 178444182c206f7c5584ef2cf504da6be98fab665dbfGlenn Kasten dumpBase(fd, args); 178544182c206f7c5584ef2cf504da6be98fab665dbfGlenn Kasten 178687cebadd48710e42474756fc3513df678de045ceElliott Hughes dprintf(fd, " Normal frame count: %zu\n", mNormalFrameCount); 1787c42e9b462661673dff480ee71757a58b0f806370Glenn Kasten dprintf(fd, " Last write occurred (msecs): %llu\n", 1788c42e9b462661673dff480ee71757a58b0f806370Glenn Kasten (unsigned long long) ns2ms(systemTime() - mLastWriteTime)); 178987cebadd48710e42474756fc3513df678de045ceElliott Hughes dprintf(fd, " Total writes: %d\n", mNumWrites); 179087cebadd48710e42474756fc3513df678de045ceElliott Hughes dprintf(fd, " Delayed writes: %d\n", mNumDelayedWrites); 179187cebadd48710e42474756fc3513df678de045ceElliott Hughes dprintf(fd, " Blocked in write: %s\n", mInWrite ? "yes" : "no"); 179287cebadd48710e42474756fc3513df678de045ceElliott Hughes dprintf(fd, " Suspend count: %d\n", mSuspended); 179387cebadd48710e42474756fc3513df678de045ceElliott Hughes dprintf(fd, " Sink buffer : %p\n", mSinkBuffer); 179487cebadd48710e42474756fc3513df678de045ceElliott Hughes dprintf(fd, " Mixer buffer: %p\n", mMixerBuffer); 179587cebadd48710e42474756fc3513df678de045ceElliott Hughes dprintf(fd, " Effect buffer: %p\n", mEffectBuffer); 179687cebadd48710e42474756fc3513df678de045ceElliott Hughes dprintf(fd, " Fast track availMask=%#x\n", mFastTrackAvailMask); 179742537be61479e59c4718e1304364551c1454f63cEric Laurent dprintf(fd, " Standby delay ns=%lld\n", (long long)mStandbyDelayNs); 179897b7b75b6a31330e213bdb96ccc60916218ad903Glenn Kasten AudioStreamOut *output = mOutput; 179997b7b75b6a31330e213bdb96ccc60916218ad903Glenn Kasten audio_output_flags_t flags = output != NULL ? output->flags : AUDIO_OUTPUT_FLAG_NONE; 1800913d06c099bd689375483a839e11057ccf284d1cMikhail Naganov dprintf(fd, " AudioStreamOut: %p flags %#x (%s)\n", 1801913d06c099bd689375483a839e11057ccf284d1cMikhail Naganov output, flags, outputFlagsToString(flags).c_str()); 1802b54c854d1ef1bb66e093c94099f915178eac570eAndy Hung dprintf(fd, " Frames written: %lld\n", (long long)mFramesWritten); 1803b54c854d1ef1bb66e093c94099f915178eac570eAndy Hung dprintf(fd, " Suspended frames: %lld\n", (long long)mSuspendedFrames); 1804b54c854d1ef1bb66e093c94099f915178eac570eAndy Hung if (mPipeSink.get() != nullptr) { 1805b54c854d1ef1bb66e093c94099f915178eac570eAndy Hung dprintf(fd, " PipeSink frames written: %lld\n", (long long)mPipeSink->framesWritten()); 1806b54c854d1ef1bb66e093c94099f915178eac570eAndy Hung } 1807b54c854d1ef1bb66e093c94099f915178eac570eAndy Hung if (output != nullptr) { 1808b54c854d1ef1bb66e093c94099f915178eac570eAndy Hung dprintf(fd, " Hal stream dump:\n"); 1809b54c854d1ef1bb66e093c94099f915178eac570eAndy Hung (void)output->stream->dump(fd); 1810b54c854d1ef1bb66e093c94099f915178eac570eAndy Hung } 181181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 181281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 181381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// Thread virtuals 181481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 181581784c37c61b09289654b979567a42bf73cd2b12Eric Laurentvoid AudioFlinger::PlaybackThread::onFirstRef() 181681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 1817d7dca050c630bddbd73a6623271b34b4290460eeGlenn Kasten run(mThreadName, ANDROID_PRIORITY_URGENT_AUDIO); 181881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 181981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 182081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// ThreadBase virtuals 182181784c37c61b09289654b979567a42bf73cd2b12Eric Laurentvoid AudioFlinger::PlaybackThread::preExit() 182281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 182381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent ALOGV(" preExit()"); 182481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // FIXME this is using hard-coded strings but in the future, this functionality will be 182581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // converted to use audio HAL extensions required to support tunneling 18261dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov status_t result = mOutput->stream->setParameters(String8("exiting=1")); 18271dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov ALOGE_IF(result != OK, "Error when setting parameters on exit: %d", result); 182881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 182981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 183081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// PlaybackThread::createTrack_l() must be called with AudioFlinger::mLock held 183181784c37c61b09289654b979567a42bf73cd2b12Eric Laurentsp<AudioFlinger::PlaybackThread::Track> AudioFlinger::PlaybackThread::createTrack_l( 183281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent const sp<AudioFlinger::Client>& client, 183381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent audio_stream_type_t streamType, 183481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent uint32_t sampleRate, 183581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent audio_format_t format, 183681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent audio_channel_mask_t channelMask, 183774935e44734c1ec235c2b6677db3e0dbefa5ddb8Glenn Kasten size_t *pFrameCount, 183881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent const sp<IMemory>& sharedBuffer, 1839d848eb48c121c119e8ba7583efc75415fe102570Glenn Kasten audio_session_t sessionId, 1840050677873c10d4da308ac222f8533c96cca3207eEric Laurent audio_output_flags_t *flags, 184181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent pid_t tid, 18421f12a8ad958344c50733b948628ffa06db9c5bc6Andy Hung uid_t uid, 184320b9ef0b55c9150ae11057ab997ae61be2d496efEric Laurent status_t *status, 184420b9ef0b55c9150ae11057ab997ae61be2d496efEric Laurent audio_port_handle_t portId) 184581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 184674935e44734c1ec235c2b6677db3e0dbefa5ddb8Glenn Kasten size_t frameCount = *pFrameCount; 184781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent sp<Track> track; 184881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent status_t lStatus; 1849050677873c10d4da308ac222f8533c96cca3207eEric Laurent audio_output_flags_t outputFlags = mOutput->flags; 1850050677873c10d4da308ac222f8533c96cca3207eEric Laurent 1851050677873c10d4da308ac222f8533c96cca3207eEric Laurent // special case for FAST flag considered OK if fast mixer is present 1852050677873c10d4da308ac222f8533c96cca3207eEric Laurent if (hasFastMixer()) { 1853050677873c10d4da308ac222f8533c96cca3207eEric Laurent outputFlags = (audio_output_flags_t)(outputFlags | AUDIO_OUTPUT_FLAG_FAST); 1854050677873c10d4da308ac222f8533c96cca3207eEric Laurent } 1855050677873c10d4da308ac222f8533c96cca3207eEric Laurent 1856050677873c10d4da308ac222f8533c96cca3207eEric Laurent // Check if requested flags are compatible with output stream flags 1857050677873c10d4da308ac222f8533c96cca3207eEric Laurent if ((*flags & outputFlags) != *flags) { 1858050677873c10d4da308ac222f8533c96cca3207eEric Laurent ALOGW("createTrack_l(): mismatch between requested flags (%08x) and output flags (%08x)", 1859050677873c10d4da308ac222f8533c96cca3207eEric Laurent *flags, outputFlags); 1860050677873c10d4da308ac222f8533c96cca3207eEric Laurent *flags = (audio_output_flags_t)(*flags & outputFlags); 1861050677873c10d4da308ac222f8533c96cca3207eEric Laurent } 186281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 186381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // client expresses a preference for FAST, but we get the final say 1864050677873c10d4da308ac222f8533c96cca3207eEric Laurent if (*flags & AUDIO_OUTPUT_FLAG_FAST) { 186581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if ( 186681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // PCM data 186781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent audio_is_linear_pcm(format) && 18681f439e1cf16a29347288ba9ddd06c0b6d086a145Andy Hung // TODO: extract as a data library function that checks that a computationally 18691f439e1cf16a29347288ba9ddd06c0b6d086a145Andy Hung // expensive downmixer is not required: isFastOutputChannelConversion() 18709a59276fb465e492138e0576523b54079671e8f4Andy Hung (channelMask == mChannelMask || 18711f439e1cf16a29347288ba9ddd06c0b6d086a145Andy Hung mChannelMask != AUDIO_CHANNEL_OUT_STEREO || 18721f439e1cf16a29347288ba9ddd06c0b6d086a145Andy Hung (channelMask == AUDIO_CHANNEL_OUT_MONO 18731f439e1cf16a29347288ba9ddd06c0b6d086a145Andy Hung /* && mChannelMask == AUDIO_CHANNEL_OUT_STEREO */)) && 187481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // hardware sample rate 187581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent (sampleRate == mSampleRate) && 187681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // normal mixer has an associated fast mixer 187781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent hasFastMixer() && 187881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // there are sufficient fast track slots available 187981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent (mFastTrackAvailMask != 0) 188081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // FIXME test that MixerThread for this fast track has a capable output HAL 188181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // FIXME add a permission test also? 188281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent ) { 1883e0a269a5f75956efdf78a9cacaefc428b352730cAndy Hung // static tracks can have any nonzero framecount, streaming tracks check against minimum. 1884e0a269a5f75956efdf78a9cacaefc428b352730cAndy Hung if (sharedBuffer == 0) { 18850349009fd19f89f8414c428f6b71b369f7546085Glenn Kasten // read the fast track multiplier property the first time it is needed 18860349009fd19f89f8414c428f6b71b369f7546085Glenn Kasten int ok = pthread_once(&sFastTrackMultiplierOnce, sFastTrackMultiplierInit); 18870349009fd19f89f8414c428f6b71b369f7546085Glenn Kasten if (ok != 0) { 18880349009fd19f89f8414c428f6b71b369f7546085Glenn Kasten ALOGE("%s pthread_once failed: %d", __func__, ok); 18890349009fd19f89f8414c428f6b71b369f7546085Glenn Kasten } 1890e0a269a5f75956efdf78a9cacaefc428b352730cAndy Hung frameCount = max(frameCount, mFrameCount * sFastTrackMultiplier); // incl framecount 0 189181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 18924c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent 18934c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent // check compatibility with audio effects. 18944c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent { // scope for mLock 18954c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent Mutex::Autolock _l(mLock); 1896d3bb0adfe40e60bb94e9a87e8d5bffb4ea6863b0Andy Hung for (audio_session_t session : { 1897d3bb0adfe40e60bb94e9a87e8d5bffb4ea6863b0Andy Hung AUDIO_SESSION_OUTPUT_STAGE, 1898d3bb0adfe40e60bb94e9a87e8d5bffb4ea6863b0Andy Hung AUDIO_SESSION_OUTPUT_MIX, 1899d3bb0adfe40e60bb94e9a87e8d5bffb4ea6863b0Andy Hung sessionId, 1900d3bb0adfe40e60bb94e9a87e8d5bffb4ea6863b0Andy Hung }) { 1901d3bb0adfe40e60bb94e9a87e8d5bffb4ea6863b0Andy Hung sp<EffectChain> chain = getEffectChain_l(session); 1902d3bb0adfe40e60bb94e9a87e8d5bffb4ea6863b0Andy Hung if (chain.get() != nullptr) { 1903d3bb0adfe40e60bb94e9a87e8d5bffb4ea6863b0Andy Hung audio_output_flags_t old = *flags; 1904d3bb0adfe40e60bb94e9a87e8d5bffb4ea6863b0Andy Hung chain->checkOutputFlagCompatibility(flags); 1905d3bb0adfe40e60bb94e9a87e8d5bffb4ea6863b0Andy Hung if (old != *flags) { 1906d3bb0adfe40e60bb94e9a87e8d5bffb4ea6863b0Andy Hung ALOGV("AUDIO_OUTPUT_FLAGS denied by effect, session=%d old=%#x new=%#x", 1907d3bb0adfe40e60bb94e9a87e8d5bffb4ea6863b0Andy Hung (int)session, (int)old, (int)*flags); 1908d3bb0adfe40e60bb94e9a87e8d5bffb4ea6863b0Andy Hung } 19094c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent } 19104c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent } 19114c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent } 1912122f7e793fe6fb8904634cc6d2e35ac4b014ea72Eric Laurent ALOGV_IF((*flags & AUDIO_OUTPUT_FLAG_FAST) != 0, 19134c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent "AUDIO_OUTPUT_FLAG_FAST accepted: frameCount=%zu mFrameCount=%zu", 19144c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent frameCount, mFrameCount); 191581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } else { 1916c42e9b462661673dff480ee71757a58b0f806370Glenn Kasten ALOGV("AUDIO_OUTPUT_FLAG_FAST denied: sharedBuffer=%p frameCount=%zu " 1917c42e9b462661673dff480ee71757a58b0f806370Glenn Kasten "mFrameCount=%zu format=%#x mFormat=%#x isLinear=%d channelMask=%#x " 19186146c08f0c3dd8b9e5788063aa433f304a810602Andy Hung "sampleRate=%u mSampleRate=%u " 191981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent "hasFastMixer=%d tid=%d fastTrackAvailMask=%#x", 1920d79072e9dff59f767cce2cda1caab80ce5a0815bGlenn Kasten sharedBuffer.get(), frameCount, mFrameCount, format, mFormat, 192181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent audio_is_linear_pcm(format), 192281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent channelMask, sampleRate, mSampleRate, hasFastMixer(), tid, mFastTrackAvailMask); 19234c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent *flags = (audio_output_flags_t)(*flags & ~AUDIO_OUTPUT_FLAG_FAST); 19240e48d25606c82def035ad10a5b3923767a765cddAndy Hung } 19250e48d25606c82def035ad10a5b3923767a765cddAndy Hung } 19260e48d25606c82def035ad10a5b3923767a765cddAndy Hung // For normal PCM streaming tracks, update minimum frame count. 19270e48d25606c82def035ad10a5b3923767a765cddAndy Hung // For compatibility with AudioTrack calculation, buffer depth is forced 19280e48d25606c82def035ad10a5b3923767a765cddAndy Hung // to be at least 2 x the normal mixer frame count and cover audio hardware latency. 19290e48d25606c82def035ad10a5b3923767a765cddAndy Hung // This is probably too conservative, but legacy application code may depend on it. 19300e48d25606c82def035ad10a5b3923767a765cddAndy Hung // If you change this calculation, also review the start threshold which is related. 1931050677873c10d4da308ac222f8533c96cca3207eEric Laurent if (!(*flags & AUDIO_OUTPUT_FLAG_FAST) 1932fdb3c07db5d44535eb8c3ec46dc78ad8446c01ebPhil Burk && audio_has_proportional_frames(format) && sharedBuffer == 0) { 19338edb8dc44b8a2f81bdb5db645b6b708548771a31Andy Hung // this must match AudioTrack.cpp calculateMinFrameCount(). 19348edb8dc44b8a2f81bdb5db645b6b708548771a31Andy Hung // TODO: Move to a common library 19351dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov uint32_t latencyMs = 0; 19361dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov lStatus = mOutput->stream->getLatency(&latencyMs); 19371dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov if (lStatus != OK) { 19381dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov ALOGE("Error when retrieving output stream latency: %d", lStatus); 19391dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov goto Exit; 19401dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov } 194181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent uint32_t minBufCount = latencyMs / ((1000 * mNormalFrameCount) / mSampleRate); 194281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (minBufCount < 2) { 194381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent minBufCount = 2; 194481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 19458edb8dc44b8a2f81bdb5db645b6b708548771a31Andy Hung // For normal mixing tracks, if speed is > 1.0f (normal), AudioTrack 19468edb8dc44b8a2f81bdb5db645b6b708548771a31Andy Hung // or the client should compute and pass in a larger buffer request. 19470e48d25606c82def035ad10a5b3923767a765cddAndy Hung size_t minFrameCount = 19488edb8dc44b8a2f81bdb5db645b6b708548771a31Andy Hung minBufCount * sourceFramesNeededWithTimestretch( 19498edb8dc44b8a2f81bdb5db645b6b708548771a31Andy Hung sampleRate, mNormalFrameCount, 19508edb8dc44b8a2f81bdb5db645b6b708548771a31Andy Hung mSampleRate, AUDIO_TIMESTRETCH_SPEED_NORMAL /*speed*/); 19510e48d25606c82def035ad10a5b3923767a765cddAndy Hung if (frameCount < minFrameCount) { // including frameCount == 0 195281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent frameCount = minFrameCount; 195381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 195481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 195574935e44734c1ec235c2b6677db3e0dbefa5ddb8Glenn Kasten *pFrameCount = frameCount; 195681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 1957c3df838434b37d8400eea2438083cc01a4c1cc71Glenn Kasten switch (mType) { 1958c3df838434b37d8400eea2438083cc01a4c1cc71Glenn Kasten 1959c3df838434b37d8400eea2438083cc01a4c1cc71Glenn Kasten case DIRECT: 1960fdb3c07db5d44535eb8c3ec46dc78ad8446c01ebPhil Burk if (audio_is_linear_pcm(format)) { // TODO maybe use audio_has_proportional_frames()? 196181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (sampleRate != mSampleRate || format != mFormat || channelMask != mChannelMask) { 1962cac3daa6332bf6d1f7d26adc4a9915f3d7992dd9Glenn Kasten ALOGE("createTrack_l() Bad parameter: sampleRate %u format %#x, channelMask 0x%08x " 1963cac3daa6332bf6d1f7d26adc4a9915f3d7992dd9Glenn Kasten "for output %p with format %#x", 196481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent sampleRate, format, channelMask, mOutput, mFormat); 196581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent lStatus = BAD_VALUE; 196681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent goto Exit; 196781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 196881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 1969c3df838434b37d8400eea2438083cc01a4c1cc71Glenn Kasten break; 1970c3df838434b37d8400eea2438083cc01a4c1cc71Glenn Kasten 1971c3df838434b37d8400eea2438083cc01a4c1cc71Glenn Kasten case OFFLOAD: 1972bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent if (sampleRate != mSampleRate || format != mFormat || channelMask != mChannelMask) { 1973cac3daa6332bf6d1f7d26adc4a9915f3d7992dd9Glenn Kasten ALOGE("createTrack_l() Bad parameter: sampleRate %d format %#x, channelMask 0x%08x \"" 1974cac3daa6332bf6d1f7d26adc4a9915f3d7992dd9Glenn Kasten "for output %p with format %#x", 1975bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent sampleRate, format, channelMask, mOutput, mFormat); 1976bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent lStatus = BAD_VALUE; 1977bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent goto Exit; 1978bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent } 1979c3df838434b37d8400eea2438083cc01a4c1cc71Glenn Kasten break; 1980c3df838434b37d8400eea2438083cc01a4c1cc71Glenn Kasten 1981c3df838434b37d8400eea2438083cc01a4c1cc71Glenn Kasten default: 1982993fa0603707e94ce259e95e56838a85b5ccbdc5Glenn Kasten if (!audio_is_linear_pcm(format)) { 1983cac3daa6332bf6d1f7d26adc4a9915f3d7992dd9Glenn Kasten ALOGE("createTrack_l() Bad parameter: format %#x \"" 1984cac3daa6332bf6d1f7d26adc4a9915f3d7992dd9Glenn Kasten "for output %p with format %#x", 1985bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent format, mOutput, mFormat); 1986bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent lStatus = BAD_VALUE; 1987bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent goto Exit; 1988bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent } 1989cd04484f4837b8ca0041d118286ab6a98e84fc75Andy Hung if (sampleRate > mSampleRate * AUDIO_RESAMPLER_DOWN_RATIO_MAX) { 199081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent ALOGE("Sample rate out of range: %u mSampleRate %u", sampleRate, mSampleRate); 199181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent lStatus = BAD_VALUE; 199281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent goto Exit; 199381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 1994c3df838434b37d8400eea2438083cc01a4c1cc71Glenn Kasten break; 1995c3df838434b37d8400eea2438083cc01a4c1cc71Glenn Kasten 199681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 199781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 199881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent lStatus = initCheck(); 199981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (lStatus != NO_ERROR) { 200015e5798908ccac14e10c84834eaf08c42931bd06Glenn Kasten ALOGE("createTrack_l() audio driver not initialized"); 200181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent goto Exit; 200281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 200381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 200481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent { // scope for mLock 200581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent Mutex::Autolock _l(mLock); 200681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 200781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // all tracks in same audio session must share the same routing strategy otherwise 200881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // conflicts will happen when tracks are moved from one output to another by audio policy 200981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // manager 201081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent uint32_t strategy = AudioSystem::getStrategyForStream(streamType); 201181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent for (size_t i = 0; i < mTracks.size(); ++i) { 201281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent sp<Track> t = mTracks[i]; 201383b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent if (t != 0 && t->isExternalTrack()) { 201481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent uint32_t actual = AudioSystem::getStrategyForStream(t->streamType()); 201581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (sessionId == t->sessionId() && strategy != actual) { 201681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent ALOGE("createTrack_l() mismatched strategy; expected %u but found %u", 201781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent strategy, actual); 201881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent lStatus = BAD_VALUE; 201981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent goto Exit; 202081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 202181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 202281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 202381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 2024d79072e9dff59f767cce2cda1caab80ce5a0815bGlenn Kasten track = new Track(this, client, streamType, sampleRate, format, 2025d79072e9dff59f767cce2cda1caab80ce5a0815bGlenn Kasten channelMask, frameCount, NULL, sharedBuffer, 202620b9ef0b55c9150ae11057ab997ae61be2d496efEric Laurent sessionId, uid, *flags, TrackBase::TYPE_DEFAULT, portId); 2027030033342a6ea17003e6af38a56c7edc6d2ead01Glenn Kasten 2028030033342a6ea17003e6af38a56c7edc6d2ead01Glenn Kasten lStatus = track != 0 ? track->initCheck() : (status_t) NO_MEMORY; 2029030033342a6ea17003e6af38a56c7edc6d2ead01Glenn Kasten if (lStatus != NO_ERROR) { 20300cde076ddb283c84c3801a2df4cc3df99bd1577fGlenn Kasten ALOGE("createTrack_l() initCheck failed %d; no control block?", lStatus); 203103e9e83c47ab4a518da0a1f36b8f702f59221c95Haynes Mathew George // track must be cleared from the caller as the caller has the AF lock 203281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent goto Exit; 203381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 203481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mTracks.add(track); 203581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 203681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent sp<EffectChain> chain = getEffectChain_l(sessionId); 203781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (chain != 0) { 203881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent ALOGV("createTrack_l() setting main buffer %p", chain->inBuffer()); 203981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent track->setMainBuffer(chain->inBuffer()); 204081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent chain->setStrategy(AudioSystem::getStrategyForStream(track->streamType())); 204181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent chain->incTrackCnt(); 204281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 204381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 2044050677873c10d4da308ac222f8533c96cca3207eEric Laurent if ((*flags & AUDIO_OUTPUT_FLAG_FAST) && (tid != -1)) { 204581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent pid_t callingPid = IPCThreadState::self()->getCallingPid(); 204681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // we don't have CAP_SYS_NICE, nor do we want to have it as it's too powerful, 204781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // so ask activity manager to do this on our behalf 204883f042776b131b149f803fff6ab184ae2c4d98cdMikhail Naganov sendPrioConfigEvent_l(callingPid, tid, kPriorityAudioApp, true /*isForApp*/); 204981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 205081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 205181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 205281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent lStatus = NO_ERROR; 205381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 205481784c37c61b09289654b979567a42bf73cd2b12Eric LaurentExit: 20559156ef3e11b68cc4b6d3cea77f1f63673855a6d1Glenn Kasten *status = lStatus; 205681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent return track; 205781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 205881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 205981784c37c61b09289654b979567a42bf73cd2b12Eric Laurentuint32_t AudioFlinger::PlaybackThread::correctLatency_l(uint32_t latency) const 206081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 206181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent return latency; 206281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 206381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 206481784c37c61b09289654b979567a42bf73cd2b12Eric Laurentuint32_t AudioFlinger::PlaybackThread::latency() const 206581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 206681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent Mutex::Autolock _l(mLock); 206781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent return latency_l(); 206881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 206981784c37c61b09289654b979567a42bf73cd2b12Eric Laurentuint32_t AudioFlinger::PlaybackThread::latency_l() const 207081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 20711dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov uint32_t latency; 20721dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov if (initCheck() == NO_ERROR && mOutput->stream->getLatency(&latency) == OK) { 20731dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov return correctLatency_l(latency); 207481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 20751dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov return 0; 207681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 207781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 207881784c37c61b09289654b979567a42bf73cd2b12Eric Laurentvoid AudioFlinger::PlaybackThread::setMasterVolume(float value) 207981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 208081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent Mutex::Autolock _l(mLock); 208181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // Don't apply master volume in SW if our HAL can do it for us. 208281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (mOutput && mOutput->audioHwDev && 208381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mOutput->audioHwDev->canSetMasterVolume()) { 208481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mMasterVolume = 1.0; 208581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } else { 208681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mMasterVolume = value; 208781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 208881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 208981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 209081784c37c61b09289654b979567a42bf73cd2b12Eric Laurentvoid AudioFlinger::PlaybackThread::setMasterMute(bool muted) 209181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 20926acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent if (isDuplicating()) { 20936acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent return; 20946acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } 209581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent Mutex::Autolock _l(mLock); 209681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // Don't apply master mute in SW if our HAL can do it for us. 209781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (mOutput && mOutput->audioHwDev && 209881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mOutput->audioHwDev->canSetMasterMute()) { 209981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mMasterMute = false; 210081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } else { 210181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mMasterMute = muted; 210281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 210381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 210481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 210581784c37c61b09289654b979567a42bf73cd2b12Eric Laurentvoid AudioFlinger::PlaybackThread::setStreamVolume(audio_stream_type_t stream, float value) 210681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 210781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent Mutex::Autolock _l(mLock); 210881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mStreamTypes[stream].volume = value; 2109ede6c3b8b1147bc425f7b923882f559a513fe23bEric Laurent broadcast_l(); 211081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 211181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 211281784c37c61b09289654b979567a42bf73cd2b12Eric Laurentvoid AudioFlinger::PlaybackThread::setStreamMute(audio_stream_type_t stream, bool muted) 211381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 211481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent Mutex::Autolock _l(mLock); 211581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mStreamTypes[stream].mute = muted; 2116ede6c3b8b1147bc425f7b923882f559a513fe23bEric Laurent broadcast_l(); 211781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 211881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 211981784c37c61b09289654b979567a42bf73cd2b12Eric Laurentfloat AudioFlinger::PlaybackThread::streamVolume(audio_stream_type_t stream) const 212081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 212181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent Mutex::Autolock _l(mLock); 212281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent return mStreamTypes[stream].volume; 212381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 212481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 212581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// addTrack_l() must be called with ThreadBase::mLock held 212681784c37c61b09289654b979567a42bf73cd2b12Eric Laurentstatus_t AudioFlinger::PlaybackThread::addTrack_l(const sp<Track>& track) 212781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 212881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent status_t status = ALREADY_EXISTS; 212981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 213081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (mActiveTracks.indexOf(track) < 0) { 213181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // the track is newly added, make sure it fills up all its 213281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // buffers before playing. This is to ensure the client will 213381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // effectively get the latency it requested. 213483b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent if (track->isExternalTrack()) { 2135bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent TrackBase::track_state state = track->mState; 2136bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent mLock.unlock(); 2137e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent status = AudioSystem::startOutput(mId, track->streamType(), 2138d848eb48c121c119e8ba7583efc75415fe102570Glenn Kasten track->sessionId()); 2139bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent mLock.lock(); 2140bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent // abort track was stopped/paused while we released the lock 2141bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent if (state != track->mState) { 2142bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent if (status == NO_ERROR) { 2143bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent mLock.unlock(); 2144e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent AudioSystem::stopOutput(mId, track->streamType(), 2145d848eb48c121c119e8ba7583efc75415fe102570Glenn Kasten track->sessionId()); 2146bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent mLock.lock(); 2147bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent } 2148bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent return INVALID_OPERATION; 2149bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent } 2150bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent // abort if start is rejected by audio policy manager 2151bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent if (status != NO_ERROR) { 2152bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent return PERMISSION_DENIED; 2153bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent } 2154bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent#ifdef ADD_BATTERY_DATA 2155bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent // to track the speaker usage 2156bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent addBatteryData(IMediaPlayerService::kBatteryDataAudioFlingerStart); 2157bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent#endif 2158bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent } 2159bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent 2160517161856d74f5fe39cce131f29b977bc1745991Eric Laurent // set retry count for buffer fill 2161517161856d74f5fe39cce131f29b977bc1745991Eric Laurent if (track->isOffloaded()) { 2162e93cc03da360a1a0d2ad937c745ce8c8e8be81c2Eric Laurent if (track->isStopping_1()) { 2163e93cc03da360a1a0d2ad937c745ce8c8e8be81c2Eric Laurent track->mRetryCount = kMaxTrackStopRetriesOffload; 2164e93cc03da360a1a0d2ad937c745ce8c8e8be81c2Eric Laurent } else { 2165e93cc03da360a1a0d2ad937c745ce8c8e8be81c2Eric Laurent track->mRetryCount = kMaxTrackStartupRetriesOffload; 2166e93cc03da360a1a0d2ad937c745ce8c8e8be81c2Eric Laurent } 2167e93cc03da360a1a0d2ad937c745ce8c8e8be81c2Eric Laurent track->mFillingUpStatus = mStandby ? Track::FS_FILLING : Track::FS_FILLED; 2168517161856d74f5fe39cce131f29b977bc1745991Eric Laurent } else { 2169517161856d74f5fe39cce131f29b977bc1745991Eric Laurent track->mRetryCount = kMaxTrackStartupRetries; 2170e93cc03da360a1a0d2ad937c745ce8c8e8be81c2Eric Laurent track->mFillingUpStatus = 2171e93cc03da360a1a0d2ad937c745ce8c8e8be81c2Eric Laurent track->sharedBuffer() != 0 ? Track::FS_FILLED : Track::FS_FILLING; 2172517161856d74f5fe39cce131f29b977bc1745991Eric Laurent } 2173517161856d74f5fe39cce131f29b977bc1745991Eric Laurent 217481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent track->mResetDone = false; 217581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent track->mPresentationCompleteFrames = 0; 217681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mActiveTracks.add(track); 2177d0107bcd44fe608b0c00a8843d19fb6356c4cb69Eric Laurent sp<EffectChain> chain = getEffectChain_l(track->sessionId()); 2178d0107bcd44fe608b0c00a8843d19fb6356c4cb69Eric Laurent if (chain != 0) { 2179d0107bcd44fe608b0c00a8843d19fb6356c4cb69Eric Laurent ALOGV("addTrack_l() starting track on chain %p for session %d", chain.get(), 2180d0107bcd44fe608b0c00a8843d19fb6356c4cb69Eric Laurent track->sessionId()); 2181d0107bcd44fe608b0c00a8843d19fb6356c4cb69Eric Laurent chain->incActiveTrackCnt(); 218281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 218381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 21842148bf0e79c436b8764b9edc4c8f2730cce98a32Andy Hung char buffer[256]; 21852148bf0e79c436b8764b9edc4c8f2730cce98a32Andy Hung track->dump(buffer, ARRAY_SIZE(buffer), false /* active */); 21862148bf0e79c436b8764b9edc4c8f2730cce98a32Andy Hung mLocalLog.log("addTrack_l (%p) %s", track.get(), buffer + 4); // log for analysis 21872148bf0e79c436b8764b9edc4c8f2730cce98a32Andy Hung 218881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent status = NO_ERROR; 218981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 219081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 21914c6a433d74d5ae8b9bc0557207e3ced43bf34a25Haynes Mathew George onAddNewTrack_l(); 219281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent return status; 219381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 219481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 2195bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurentbool AudioFlinger::PlaybackThread::destroyTrack_l(const sp<Track>& track) 219681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 2197bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent track->terminate(); 219881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // active tracks are removed by threadLoop() 2199bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent bool trackActive = (mActiveTracks.indexOf(track) >= 0); 2200bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent track->mState = TrackBase::STOPPED; 2201bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent if (!trackActive) { 220281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent removeTrack_l(track); 2203ab5cdbaf65ca509681d2726aacdf3ac8bfb6b3faEric Laurent } else if (track->isFastTrack() || track->isOffloaded() || track->isDirect()) { 2204bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent track->mState = TrackBase::STOPPING_1; 220581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 2206bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent 2207bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent return trackActive; 220881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 220981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 221081784c37c61b09289654b979567a42bf73cd2b12Eric Laurentvoid AudioFlinger::PlaybackThread::removeTrack_l(const sp<Track>& track) 221181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 221281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent track->triggerEvents(AudioSystem::SYNC_EVENT_PRESENTATION_COMPLETE); 22132148bf0e79c436b8764b9edc4c8f2730cce98a32Andy Hung 22142148bf0e79c436b8764b9edc4c8f2730cce98a32Andy Hung char buffer[256]; 22152148bf0e79c436b8764b9edc4c8f2730cce98a32Andy Hung track->dump(buffer, ARRAY_SIZE(buffer), false /* active */); 22162148bf0e79c436b8764b9edc4c8f2730cce98a32Andy Hung mLocalLog.log("removeTrack_l (%p) %s", track.get(), buffer + 4); // log for analysis 22172148bf0e79c436b8764b9edc4c8f2730cce98a32Andy Hung 221881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mTracks.remove(track); 221981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent deleteTrackName_l(track->name()); 222081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // redundant as track is about to be destroyed, for dumpsys only 222181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent track->mName = -1; 222281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (track->isFastTrack()) { 222381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent int index = track->mFastIndex; 2224dc2c50bad491d2c0c8a2efc0e24491076701c63cGlenn Kasten ALOG_ASSERT(0 < index && index < (int)FastMixerState::sMaxFastTracks); 222581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent ALOG_ASSERT(!(mFastTrackAvailMask & (1 << index))); 222681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mFastTrackAvailMask |= 1 << index; 222781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // redundant as track is about to be destroyed, for dumpsys only 222881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent track->mFastIndex = -1; 222981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 223081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent sp<EffectChain> chain = getEffectChain_l(track->sessionId()); 223181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (chain != 0) { 223281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent chain->decTrackCnt(); 223381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 223481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 223581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 223681784c37c61b09289654b979567a42bf73cd2b12Eric LaurentString8 AudioFlinger::PlaybackThread::getParameters(const String8& keys) 223781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 223881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent Mutex::Autolock _l(mLock); 22391dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov String8 out_s8; 22401dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov if (initCheck() == NO_ERROR && mOutput->stream->getParameters(keys, &out_s8) == OK) { 22411dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov return out_s8; 224281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 22431dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov return String8(); 224481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 224581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 22467c1ec5f038e63a5eb8b04434577c25bc23f5f410Eric Laurentvoid AudioFlinger::PlaybackThread::ioConfigChanged(audio_io_config_event event, pid_t pid) { 224773e26b661af50be2c0a4ff6c9ac85f7347a8b235Eric Laurent sp<AudioIoDescriptor> desc = new AudioIoDescriptor(); 224873e26b661af50be2c0a4ff6c9ac85f7347a8b235Eric Laurent ALOGV("PlaybackThread::ioConfigChanged, thread %p, event %d", this, event); 224981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 225073e26b661af50be2c0a4ff6c9ac85f7347a8b235Eric Laurent desc->mIoHandle = mId; 225181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 225281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent switch (event) { 225373e26b661af50be2c0a4ff6c9ac85f7347a8b235Eric Laurent case AUDIO_OUTPUT_OPENED: 225473e26b661af50be2c0a4ff6c9ac85f7347a8b235Eric Laurent case AUDIO_OUTPUT_CONFIG_CHANGED: 2255296fb13dd9b5e90d6a05cce897c3b1e7914a478aEric Laurent desc->mPatch = mPatch; 225673e26b661af50be2c0a4ff6c9ac85f7347a8b235Eric Laurent desc->mChannelMask = mChannelMask; 225773e26b661af50be2c0a4ff6c9ac85f7347a8b235Eric Laurent desc->mSamplingRate = mSampleRate; 225873e26b661af50be2c0a4ff6c9ac85f7347a8b235Eric Laurent desc->mFormat = mFormat; 225973e26b661af50be2c0a4ff6c9ac85f7347a8b235Eric Laurent desc->mFrameCount = mNormalFrameCount; // FIXME see 226081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // AudioFlinger::frameCount(audio_io_handle_t) 22614a8308b11b92e608cdaf29f73f7919e75706f9a2Glenn Kasten desc->mFrameCountHAL = mFrameCount; 226273e26b661af50be2c0a4ff6c9ac85f7347a8b235Eric Laurent desc->mLatency = latency_l(); 226381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent break; 226481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 226573e26b661af50be2c0a4ff6c9ac85f7347a8b235Eric Laurent case AUDIO_OUTPUT_CLOSED: 226681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent default: 226781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent break; 226881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 22697c1ec5f038e63a5eb8b04434577c25bc23f5f410Eric Laurent mAudioFlinger->ioConfigChanged(event, desc, pid); 227081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 227181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 22721dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganovvoid AudioFlinger::PlaybackThread::onWriteReady() 2273bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent{ 22743b4529e03c5fc7a44c22f9091ad15a269bfca3a8Eric Laurent mCallbackThread->resetWriteBlocked(); 2275bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent} 2276bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent 22771dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganovvoid AudioFlinger::PlaybackThread::onDrainReady() 2278bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent{ 22793b4529e03c5fc7a44c22f9091ad15a269bfca3a8Eric Laurent mCallbackThread->resetDraining(); 2280bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent} 2281bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent 22821dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganovvoid AudioFlinger::PlaybackThread::onError() 22834527b9ebc6a37b861f5a3bba68bcc63dc8d69adaHaynes Mathew George{ 22844527b9ebc6a37b861f5a3bba68bcc63dc8d69adaHaynes Mathew George mCallbackThread->setAsyncError(); 22854527b9ebc6a37b861f5a3bba68bcc63dc8d69adaHaynes Mathew George} 22864527b9ebc6a37b861f5a3bba68bcc63dc8d69adaHaynes Mathew George 22873b4529e03c5fc7a44c22f9091ad15a269bfca3a8Eric Laurentvoid AudioFlinger::PlaybackThread::resetWriteBlocked(uint32_t sequence) 2288bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent{ 2289bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent Mutex::Autolock _l(mLock); 22903b4529e03c5fc7a44c22f9091ad15a269bfca3a8Eric Laurent // reject out of sequence requests 22913b4529e03c5fc7a44c22f9091ad15a269bfca3a8Eric Laurent if ((mWriteAckSequence & 1) && (sequence == mWriteAckSequence)) { 22923b4529e03c5fc7a44c22f9091ad15a269bfca3a8Eric Laurent mWriteAckSequence &= ~1; 2293bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent mWaitWorkCV.signal(); 2294bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent } 2295bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent} 2296bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent 22973b4529e03c5fc7a44c22f9091ad15a269bfca3a8Eric Laurentvoid AudioFlinger::PlaybackThread::resetDraining(uint32_t sequence) 2298bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent{ 2299bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent Mutex::Autolock _l(mLock); 23003b4529e03c5fc7a44c22f9091ad15a269bfca3a8Eric Laurent // reject out of sequence requests 23013b4529e03c5fc7a44c22f9091ad15a269bfca3a8Eric Laurent if ((mDrainSequence & 1) && (sequence == mDrainSequence)) { 23023b4529e03c5fc7a44c22f9091ad15a269bfca3a8Eric Laurent mDrainSequence &= ~1; 2303bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent mWaitWorkCV.signal(); 2304bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent } 2305bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent} 2306bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent 2307deca2ae0a7cf8bc54ff3f30b7dc39bbc78b94c0dGlenn Kastenvoid AudioFlinger::PlaybackThread::readOutputParameters_l() 230881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 2309adad3d7d935da176ff24941b4ae9edf7340e9b96Glenn Kasten // unfortunately we have no way of recovering from errors here, hence the LOG_ALWAYS_FATAL 2310ca5e6143740299c877d69e97f7968cd04476d32cPhil Burk mSampleRate = mOutput->getSampleRate(); 2311ca5e6143740299c877d69e97f7968cd04476d32cPhil Burk mChannelMask = mOutput->getChannelMask(); 23127fc97ba08e2850f3f16db704b78ce78e3dbe1ff0Glenn Kasten if (!audio_is_output_channel(mChannelMask)) { 2313adad3d7d935da176ff24941b4ae9edf7340e9b96Glenn Kasten LOG_ALWAYS_FATAL("HAL channel mask %#x not valid for output", mChannelMask); 23147fc97ba08e2850f3f16db704b78ce78e3dbe1ff0Glenn Kasten } 23159a59276fb465e492138e0576523b54079671e8f4Andy Hung if ((mType == MIXER || mType == DUPLICATING) 23169a59276fb465e492138e0576523b54079671e8f4Andy Hung && !isValidPcmSinkChannelMask(mChannelMask)) { 23179a59276fb465e492138e0576523b54079671e8f4Andy Hung LOG_ALWAYS_FATAL("HAL channel mask %#x not supported for mixed output", 23189a59276fb465e492138e0576523b54079671e8f4Andy Hung mChannelMask); 23197fc97ba08e2850f3f16db704b78ce78e3dbe1ff0Glenn Kasten } 2320e541269be94f3a1072932d51537905b120ef4733Andy Hung mChannelCount = audio_channel_count_from_out_mask(mChannelMask); 2321ca5e6143740299c877d69e97f7968cd04476d32cPhil Burk 2322ca5e6143740299c877d69e97f7968cd04476d32cPhil Burk // Get actual HAL format. 23231dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov status_t result = mOutput->stream->getFormat(&mHALFormat); 23241dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov LOG_ALWAYS_FATAL_IF(result != OK, "Error when retrieving output stream format: %d", result); 2325ca5e6143740299c877d69e97f7968cd04476d32cPhil Burk // Get format from the shim, which will be different than the HAL format 2326ca5e6143740299c877d69e97f7968cd04476d32cPhil Burk // if playing compressed audio over HDMI passthrough. 2327ca5e6143740299c877d69e97f7968cd04476d32cPhil Burk mFormat = mOutput->getFormat(); 23287fc97ba08e2850f3f16db704b78ce78e3dbe1ff0Glenn Kasten if (!audio_is_valid_format(mFormat)) { 2329adad3d7d935da176ff24941b4ae9edf7340e9b96Glenn Kasten LOG_ALWAYS_FATAL("HAL format %#x not valid for output", mFormat); 23307fc97ba08e2850f3f16db704b78ce78e3dbe1ff0Glenn Kasten } 23316146c08f0c3dd8b9e5788063aa433f304a810602Andy Hung if ((mType == MIXER || mType == DUPLICATING) 23326146c08f0c3dd8b9e5788063aa433f304a810602Andy Hung && !isValidPcmSinkFormat(mFormat)) { 23336146c08f0c3dd8b9e5788063aa433f304a810602Andy Hung LOG_FATAL("HAL format %#x not supported for mixed output", 23346146c08f0c3dd8b9e5788063aa433f304a810602Andy Hung mFormat); 23357fc97ba08e2850f3f16db704b78ce78e3dbe1ff0Glenn Kasten } 2336062e67a26e0553dd142be622821f493df541f0c6Phil Burk mFrameSize = mOutput->getFrameSize(); 23371dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov result = mOutput->stream->getBufferSize(&mBufferSize); 23381dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov LOG_ALWAYS_FATAL_IF(result != OK, 23391dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov "Error when retrieving output stream buffer size: %d", result); 234070949c47fbae3f836d15f040551d7631be3ed7c2Glenn Kasten mFrameCount = mBufferSize / mFrameSize; 234181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (mFrameCount & 15) { 2342c42e9b462661673dff480ee71757a58b0f806370Glenn Kasten ALOGW("HAL output buffer size is %zu frames but AudioMixer requires multiples of 16 frames", 234381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mFrameCount); 234481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 234581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 23461dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov if (mOutput->flags & AUDIO_OUTPUT_FLAG_NON_BLOCKING) { 23471dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov if (mOutput->stream->setCallback(this) == OK) { 2348bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent mUseAsyncWrite = true; 23494de95592980dba88a35b3dc8f3fd045588387a4fEric Laurent mCallbackThread = new AudioFlinger::AsyncCallbackThread(this); 2350bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent } 2351bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent } 2352bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent 2353d1f69b0b17acbd96987ecb2f3378abd394d05903Eric Laurent mHwSupportsPause = false; 2354d1f69b0b17acbd96987ecb2f3378abd394d05903Eric Laurent if (mOutput->flags & AUDIO_OUTPUT_FLAG_DIRECT) { 23551dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov bool supportsPause = false, supportsResume = false; 23561dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov if (mOutput->stream->supportsPauseAndResume(&supportsPause, &supportsResume) == OK) { 23571dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov if (supportsPause && supportsResume) { 2358d1f69b0b17acbd96987ecb2f3378abd394d05903Eric Laurent mHwSupportsPause = true; 23591dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov } else if (supportsPause) { 2360d1f69b0b17acbd96987ecb2f3378abd394d05903Eric Laurent ALOGW("direct output implements pause but not resume"); 23611dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov } else if (supportsResume) { 23621dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov ALOGW("direct output implements resume but not pause"); 2363d1f69b0b17acbd96987ecb2f3378abd394d05903Eric Laurent } 2364d1f69b0b17acbd96987ecb2f3378abd394d05903Eric Laurent } 2365d1f69b0b17acbd96987ecb2f3378abd394d05903Eric Laurent } 23666fc2a7c81f62b1e21487ae37e11aae6241bc3eadPhil Burk if (!mHwSupportsPause && mOutput->flags & AUDIO_OUTPUT_FLAG_HW_AV_SYNC) { 23676fc2a7c81f62b1e21487ae37e11aae6241bc3eadPhil Burk LOG_ALWAYS_FATAL("HW_AV_SYNC requested but HAL does not implement pause and resume"); 23686fc2a7c81f62b1e21487ae37e11aae6241bc3eadPhil Burk } 2369d1f69b0b17acbd96987ecb2f3378abd394d05903Eric Laurent 2370fbfc3959f4aac839445edc7075532067fef497c2Andy Hung if (mType == DUPLICATING && mMixerBufferEnabled && mEffectBufferEnabled) { 2371fbfc3959f4aac839445edc7075532067fef497c2Andy Hung // For best precision, we use float instead of the associated output 2372fbfc3959f4aac839445edc7075532067fef497c2Andy Hung // device format (typically PCM 16 bit). 2373fbfc3959f4aac839445edc7075532067fef497c2Andy Hung 2374fbfc3959f4aac839445edc7075532067fef497c2Andy Hung mFormat = AUDIO_FORMAT_PCM_FLOAT; 2375fbfc3959f4aac839445edc7075532067fef497c2Andy Hung mFrameSize = mChannelCount * audio_bytes_per_sample(mFormat); 2376fbfc3959f4aac839445edc7075532067fef497c2Andy Hung mBufferSize = mFrameSize * mFrameCount; 2377fbfc3959f4aac839445edc7075532067fef497c2Andy Hung 2378fbfc3959f4aac839445edc7075532067fef497c2Andy Hung // TODO: We currently use the associated output device channel mask and sample rate. 2379fbfc3959f4aac839445edc7075532067fef497c2Andy Hung // (1) Perhaps use the ORed channel mask of all downstream MixerThreads 2380fbfc3959f4aac839445edc7075532067fef497c2Andy Hung // (if a valid mask) to avoid premature downmix. 2381fbfc3959f4aac839445edc7075532067fef497c2Andy Hung // (2) Perhaps use the maximum sample rate of all downstream MixerThreads 2382fbfc3959f4aac839445edc7075532067fef497c2Andy Hung // instead of the output device sample rate to avoid loss of high frequency information. 2383fbfc3959f4aac839445edc7075532067fef497c2Andy Hung // This may need to be updated as MixerThread/OutputTracks are added and not here. 2384fbfc3959f4aac839445edc7075532067fef497c2Andy Hung } 2385fbfc3959f4aac839445edc7075532067fef497c2Andy Hung 238609a5007b17acb49d25cfa386a2e2534d942e8854Andy Hung // Calculate size of normal sink buffer relative to the HAL output buffer size 238781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent double multiplier = 1.0; 238881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (mType == MIXER && (kUseFastMixer == FastMixer_Static || 238981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent kUseFastMixer == FastMixer_Dynamic)) { 239009a5007b17acb49d25cfa386a2e2534d942e8854Andy Hung size_t minNormalFrameCount = (kMinNormalSinkBufferSizeMs * mSampleRate) / 1000; 239109a5007b17acb49d25cfa386a2e2534d942e8854Andy Hung size_t maxNormalFrameCount = (kMaxNormalSinkBufferSizeMs * mSampleRate) / 1000; 2392227a14be87e8c63eb7a464b857a1d29c86c90e7cHaynes Mathew George 239381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // round up minimum and round down maximum to nearest 16 frames to satisfy AudioMixer 239481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent minNormalFrameCount = (minNormalFrameCount + 15) & ~15; 239581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent maxNormalFrameCount = maxNormalFrameCount & ~15; 239681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (maxNormalFrameCount < minNormalFrameCount) { 239781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent maxNormalFrameCount = minNormalFrameCount; 239881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 239981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent multiplier = (double) minNormalFrameCount / (double) mFrameCount; 240081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (multiplier <= 1.0) { 240181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent multiplier = 1.0; 240281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } else if (multiplier <= 2.0) { 240381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (2 * mFrameCount <= maxNormalFrameCount) { 240481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent multiplier = 2.0; 240581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } else { 240681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent multiplier = (double) maxNormalFrameCount / (double) mFrameCount; 240781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 240881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } else { 2409227a14be87e8c63eb7a464b857a1d29c86c90e7cHaynes Mathew George multiplier = floor(multiplier); 241081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 241181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 241281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mNormalFrameCount = multiplier * mFrameCount; 241381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // round up to nearest 16 frames to satisfy AudioMixer 2414ab5cdbaf65ca509681d2726aacdf3ac8bfb6b3faEric Laurent if (mType == MIXER || mType == DUPLICATING) { 2415ab5cdbaf65ca509681d2726aacdf3ac8bfb6b3faEric Laurent mNormalFrameCount = (mNormalFrameCount + 15) & ~15; 2416ab5cdbaf65ca509681d2726aacdf3ac8bfb6b3faEric Laurent } 2417c42e9b462661673dff480ee71757a58b0f806370Glenn Kasten ALOGI("HAL output buffer size %zu frames, normal sink buffer size %zu frames", mFrameCount, 241881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mNormalFrameCount); 241981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 242008fb1743f80437c38b4094070d851ea7f6d485e5Andy Hung // Check if we want to throttle the processing to no more than 2x normal rate 242108fb1743f80437c38b4094070d851ea7f6d485e5Andy Hung mThreadThrottle = property_get_bool("af.thread.throttle", true /* default_value */); 242240eb1a1f8871909c272e72afaf7d5af84fea2412Andy Hung mThreadThrottleTimeMs = 0; 242340eb1a1f8871909c272e72afaf7d5af84fea2412Andy Hung mThreadThrottleEndMs = 0; 242408fb1743f80437c38b4094070d851ea7f6d485e5Andy Hung mHalfBufferMs = mNormalFrameCount * 1000 / (2 * mSampleRate); 242508fb1743f80437c38b4094070d851ea7f6d485e5Andy Hung 2426010a1a1a552cdaad362cea8a0333b8906402dbcbAndy Hung // mSinkBuffer is the sink buffer. Size is always multiple-of-16 frames. 2427010a1a1a552cdaad362cea8a0333b8906402dbcbAndy Hung // Originally this was int16_t[] array, need to remove legacy implications. 2428010a1a1a552cdaad362cea8a0333b8906402dbcbAndy Hung free(mSinkBuffer); 2429010a1a1a552cdaad362cea8a0333b8906402dbcbAndy Hung mSinkBuffer = NULL; 24305b10a2037a835e790994b9ebec3c2e55052f1f3bAndy Hung // For sink buffer size, we use the frame size from the downstream sink to avoid problems 24315b10a2037a835e790994b9ebec3c2e55052f1f3bAndy Hung // with non PCM formats for compressed music, e.g. AAC, and Offload threads. 24325b10a2037a835e790994b9ebec3c2e55052f1f3bAndy Hung const size_t sinkBufferSize = mNormalFrameCount * mFrameSize; 2433010a1a1a552cdaad362cea8a0333b8906402dbcbAndy Hung (void)posix_memalign(&mSinkBuffer, 32, sinkBufferSize); 243481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 243569aed5f0f4a3be3996d1e78a0473e1a72c1547daAndy Hung // We resize the mMixerBuffer according to the requirements of the sink buffer which 243669aed5f0f4a3be3996d1e78a0473e1a72c1547daAndy Hung // drives the output. 243769aed5f0f4a3be3996d1e78a0473e1a72c1547daAndy Hung free(mMixerBuffer); 243869aed5f0f4a3be3996d1e78a0473e1a72c1547daAndy Hung mMixerBuffer = NULL; 243969aed5f0f4a3be3996d1e78a0473e1a72c1547daAndy Hung if (mMixerBufferEnabled) { 244069aed5f0f4a3be3996d1e78a0473e1a72c1547daAndy Hung mMixerBufferFormat = AUDIO_FORMAT_PCM_FLOAT; // also valid: AUDIO_FORMAT_PCM_16_BIT. 244169aed5f0f4a3be3996d1e78a0473e1a72c1547daAndy Hung mMixerBufferSize = mNormalFrameCount * mChannelCount 244269aed5f0f4a3be3996d1e78a0473e1a72c1547daAndy Hung * audio_bytes_per_sample(mMixerBufferFormat); 244369aed5f0f4a3be3996d1e78a0473e1a72c1547daAndy Hung (void)posix_memalign(&mMixerBuffer, 32, mMixerBufferSize); 244469aed5f0f4a3be3996d1e78a0473e1a72c1547daAndy Hung } 244598ef978df4e928f486d244c4d7f7ad9f13111e98Andy Hung free(mEffectBuffer); 244698ef978df4e928f486d244c4d7f7ad9f13111e98Andy Hung mEffectBuffer = NULL; 244798ef978df4e928f486d244c4d7f7ad9f13111e98Andy Hung if (mEffectBufferEnabled) { 244898ef978df4e928f486d244c4d7f7ad9f13111e98Andy Hung mEffectBufferFormat = AUDIO_FORMAT_PCM_16_BIT; // Note: Effects support 16b only 244998ef978df4e928f486d244c4d7f7ad9f13111e98Andy Hung mEffectBufferSize = mNormalFrameCount * mChannelCount 245098ef978df4e928f486d244c4d7f7ad9f13111e98Andy Hung * audio_bytes_per_sample(mEffectBufferFormat); 245198ef978df4e928f486d244c4d7f7ad9f13111e98Andy Hung (void)posix_memalign(&mEffectBuffer, 32, mEffectBufferSize); 245298ef978df4e928f486d244c4d7f7ad9f13111e98Andy Hung } 245369aed5f0f4a3be3996d1e78a0473e1a72c1547daAndy Hung 245481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // force reconfiguration of effect chains and engines to take new buffer size and audio 245581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // parameters into account 2456deca2ae0a7cf8bc54ff3f30b7dc39bbc78b94c0dGlenn Kasten // Note that mLock is not held when readOutputParameters_l() is called from the constructor 245781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // but in this case nothing is done below as no audio sessions have effect yet so it doesn't 245881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // matter. 245981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // create a copy of mEffectChains as calling moveEffectChain_l() can reorder some effect chains 246081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent Vector< sp<EffectChain> > effectChains = mEffectChains; 246181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent for (size_t i = 0; i < effectChains.size(); i ++) { 246281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mAudioFlinger->moveEffectChain_l(effectChains[i]->sessionId(), this, this, false); 246381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 246481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 246581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 246681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 2467377b2ec9a2885f9b6405b07ba900a9e3f4349c38Kévin PETITstatus_t AudioFlinger::PlaybackThread::getRenderPosition(uint32_t *halFrames, uint32_t *dspFrames) 246881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 246981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (halFrames == NULL || dspFrames == NULL) { 247081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent return BAD_VALUE; 247181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 247281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent Mutex::Autolock _l(mLock); 247381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (initCheck() != NO_ERROR) { 247481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent return INVALID_OPERATION; 247581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 2476818e7a32ce3633980138aff2c2bfcc5158b3cfccAndy Hung int64_t framesWritten = mBytesWritten / mFrameSize; 247781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent *halFrames = framesWritten; 247881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 247981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (isSuspended()) { 248081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // return an estimation of rendered frames when the output is suspended 248181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent size_t latencyFrames = (latency_l() * mSampleRate) / 1000; 2482818e7a32ce3633980138aff2c2bfcc5158b3cfccAndy Hung *dspFrames = (uint32_t) 2483818e7a32ce3633980138aff2c2bfcc5158b3cfccAndy Hung (framesWritten >= (int64_t)latencyFrames ? framesWritten - latencyFrames : 0); 248481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent return NO_ERROR; 248581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } else { 2486377b2ec9a2885f9b6405b07ba900a9e3f4349c38Kévin PETIT status_t status; 2487377b2ec9a2885f9b6405b07ba900a9e3f4349c38Kévin PETIT uint32_t frames; 2488062e67a26e0553dd142be622821f493df541f0c6Phil Burk status = mOutput->getRenderPosition(&frames); 2489377b2ec9a2885f9b6405b07ba900a9e3f4349c38Kévin PETIT *dspFrames = (size_t)frames; 2490377b2ec9a2885f9b6405b07ba900a9e3f4349c38Kévin PETIT return status; 249181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 249281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 249381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 24944c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent// hasAudioSession_l() must be called with ThreadBase::mLock held 24954c415062ad1bb53e9af8f644d8215837262b79bbEric Laurentuint32_t AudioFlinger::PlaybackThread::hasAudioSession_l(audio_session_t sessionId) const 249681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 249781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent uint32_t result = 0; 249881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (getEffectChain_l(sessionId) != 0) { 249981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent result = EFFECT_SESSION; 250081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 250181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 250281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent for (size_t i = 0; i < mTracks.size(); ++i) { 250381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent sp<Track> track = mTracks[i]; 25045736c35b841de56ce394b4879389f669b61425e6Glenn Kasten if (sessionId == track->sessionId() && !track->isInvalid()) { 250581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent result |= TRACK_SESSION; 25064c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent if (track->isFastTrack()) { 25074c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent result |= FAST_SESSION; 25084c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent } 250981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent break; 251081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 251181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 251281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 251381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent return result; 251481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 251581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 2516d848eb48c121c119e8ba7583efc75415fe102570Glenn Kastenuint32_t AudioFlinger::PlaybackThread::getStrategyForSession_l(audio_session_t sessionId) 251781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 251881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // session AUDIO_SESSION_OUTPUT_MIX is placed in same strategy as MUSIC stream so that 251981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // it is moved to correct output by audio policy manager when A2DP is connected or disconnected 252081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (sessionId == AUDIO_SESSION_OUTPUT_MIX) { 252181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent return AudioSystem::getStrategyForStream(AUDIO_STREAM_MUSIC); 252281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 252381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent for (size_t i = 0; i < mTracks.size(); i++) { 252481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent sp<Track> track = mTracks[i]; 25255736c35b841de56ce394b4879389f669b61425e6Glenn Kasten if (sessionId == track->sessionId() && !track->isInvalid()) { 252681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent return AudioSystem::getStrategyForStream(track->streamType()); 252781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 252881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 252981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent return AudioSystem::getStrategyForStream(AUDIO_STREAM_MUSIC); 253081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 253181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 253281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 2533062e67a26e0553dd142be622821f493df541f0c6Phil BurkAudioStreamOut* AudioFlinger::PlaybackThread::getOutput() const 253481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 253581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent Mutex::Autolock _l(mLock); 253681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent return mOutput; 253781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 253881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 2539062e67a26e0553dd142be622821f493df541f0c6Phil BurkAudioStreamOut* AudioFlinger::PlaybackThread::clearOutput() 254081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 254181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent Mutex::Autolock _l(mLock); 254281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent AudioStreamOut *output = mOutput; 254381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mOutput = NULL; 254481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // FIXME FastMixer might also have a raw ptr to mOutputSink; 254581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // must push a NULL and wait for ack 254681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mOutputSink.clear(); 254781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mPipeSink.clear(); 254881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mNormalSink.clear(); 254981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent return output; 255081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 255181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 255281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// this method must always be called either with ThreadBase mLock held or inside the thread loop 25531dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganovsp<StreamHalInterface> AudioFlinger::PlaybackThread::stream() const 255481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 255581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (mOutput == NULL) { 255681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent return NULL; 255781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 25581dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov return mOutput->stream; 255981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 256081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 256181784c37c61b09289654b979567a42bf73cd2b12Eric Laurentuint32_t AudioFlinger::PlaybackThread::activeSleepTimeUs() const 256281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 256381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent return (uint32_t)((uint32_t)((mNormalFrameCount * 1000) / mSampleRate) * 1000); 256481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 256581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 256681784c37c61b09289654b979567a42bf73cd2b12Eric Laurentstatus_t AudioFlinger::PlaybackThread::setSyncEvent(const sp<SyncEvent>& event) 256781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 256881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (!isValidSyncEvent(event)) { 256981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent return BAD_VALUE; 257081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 257181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 257281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent Mutex::Autolock _l(mLock); 257381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 257481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent for (size_t i = 0; i < mTracks.size(); ++i) { 257581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent sp<Track> track = mTracks[i]; 257681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (event->triggerSession() == track->sessionId()) { 257781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent (void) track->setSyncEvent(event); 257881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent return NO_ERROR; 257981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 258081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 258181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 258281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent return NAME_NOT_FOUND; 258381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 258481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 258581784c37c61b09289654b979567a42bf73cd2b12Eric Laurentbool AudioFlinger::PlaybackThread::isValidSyncEvent(const sp<SyncEvent>& event) const 258681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 258781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent return event->type() == AudioSystem::SYNC_EVENT_PRESENTATION_COMPLETE; 258881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 258981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 259081784c37c61b09289654b979567a42bf73cd2b12Eric Laurentvoid AudioFlinger::PlaybackThread::threadLoop_removeTracks( 259181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent const Vector< sp<Track> >& tracksToRemove) 259281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 259381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent size_t count = tracksToRemove.size(); 259434fca34606b448e6b71c2942f63cb13a0aebd620Glenn Kasten if (count > 0) { 259581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent for (size_t i = 0 ; i < count ; i++) { 259681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent const sp<Track>& track = tracksToRemove.itemAt(i); 259783b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent if (track->isExternalTrack()) { 2598e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent AudioSystem::stopOutput(mId, track->streamType(), 2599d848eb48c121c119e8ba7583efc75415fe102570Glenn Kasten track->sessionId()); 2600bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent#ifdef ADD_BATTERY_DATA 2601bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent // to track the speaker usage 2602bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent addBatteryData(IMediaPlayerService::kBatteryDataAudioFlingerStop); 2603bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent#endif 2604bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent if (track->isTerminated()) { 2605e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent AudioSystem::releaseOutput(mId, track->streamType(), 2606d848eb48c121c119e8ba7583efc75415fe102570Glenn Kasten track->sessionId()); 2607bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent } 260881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 260981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 261081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 261181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 261281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 261381784c37c61b09289654b979567a42bf73cd2b12Eric Laurentvoid AudioFlinger::PlaybackThread::checkSilentMode_l() 261481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 261581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (!mMasterMute) { 261681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent char value[PROPERTY_VALUE_MAX]; 261732f37c22f60b7a1a6ccfa351700f80c03918d4feJean-Michel Trivi if (mOutDevice == AUDIO_DEVICE_OUT_REMOTE_SUBMIX) { 261832f37c22f60b7a1a6ccfa351700f80c03918d4feJean-Michel Trivi ALOGD("ro.audio.silent will be ignored for threads on AUDIO_DEVICE_OUT_REMOTE_SUBMIX"); 261932f37c22f60b7a1a6ccfa351700f80c03918d4feJean-Michel Trivi return; 262032f37c22f60b7a1a6ccfa351700f80c03918d4feJean-Michel Trivi } 262181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (property_get("ro.audio.silent", value, "0") > 0) { 262281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent char *endptr; 262381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent unsigned long ul = strtoul(value, &endptr, 0); 262481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (*endptr == '\0' && ul != 0) { 262581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent ALOGD("Silence is golden"); 262681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // The setprop command will not allow a property to be changed after 262781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // the first time it is set, so we don't have to worry about un-muting. 262881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent setMasterMute_l(true); 262981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 263081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 263181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 263281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 263381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 263481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// shared by MIXER and DIRECT, overridden by DUPLICATING 2635bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurentssize_t AudioFlinger::PlaybackThread::threadLoop_write() 263681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 263781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mInWrite = true; 2638bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent ssize_t bytesWritten; 2639010a1a1a552cdaad362cea8a0333b8906402dbcbAndy Hung const size_t offset = mCurrentWriteLength - mBytesRemaining; 264081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 264181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // If an NBAIO sink is present, use it to write the normal mixer's submix 264281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (mNormalSink != 0) { 26434c053ea158b29fa2cdd4c6f39d3c8da4ee5a7a02Glenn Kasten 2644010a1a1a552cdaad362cea8a0333b8906402dbcbAndy Hung const size_t count = mBytesRemaining / mFrameSize; 2645010a1a1a552cdaad362cea8a0333b8906402dbcbAndy Hung 26462d590964aa58e137d17a43e095e6443dd0fe2e98Simon Wilson ATRACE_BEGIN("write"); 264781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // update the setpoint when AudioFlinger::mScreenState changes 264881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent uint32_t screenState = AudioFlinger::mScreenState; 264981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (screenState != mScreenState) { 265081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mScreenState = screenState; 265181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent MonoPipe *pipe = (MonoPipe *)mPipeSink.get(); 265281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (pipe != NULL) { 265381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent pipe->setAvgFrames((mScreenState & 1) ? 265481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent (pipe->maxFrames() * 7) / 8 : mNormalFrameCount * 2); 265581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 265681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 2657010a1a1a552cdaad362cea8a0333b8906402dbcbAndy Hung ssize_t framesWritten = mNormalSink->write((char *)mSinkBuffer + offset, count); 26582d590964aa58e137d17a43e095e6443dd0fe2e98Simon Wilson ATRACE_END(); 265981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (framesWritten > 0) { 2660010a1a1a552cdaad362cea8a0333b8906402dbcbAndy Hung bytesWritten = framesWritten * mFrameSize; 266181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } else { 266281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent bytesWritten = framesWritten; 266381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 266481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // otherwise use the HAL / AudioStreamOut directly 266581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } else { 2666bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent // Direct output and offload threads 2667010a1a1a552cdaad362cea8a0333b8906402dbcbAndy Hung 2668bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent if (mUseAsyncWrite) { 26693b4529e03c5fc7a44c22f9091ad15a269bfca3a8Eric Laurent ALOGW_IF(mWriteAckSequence & 1, "threadLoop_write(): out of sequence write request"); 26703b4529e03c5fc7a44c22f9091ad15a269bfca3a8Eric Laurent mWriteAckSequence += 2; 26713b4529e03c5fc7a44c22f9091ad15a269bfca3a8Eric Laurent mWriteAckSequence |= 1; 2672bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent ALOG_ASSERT(mCallbackThread != 0); 26733b4529e03c5fc7a44c22f9091ad15a269bfca3a8Eric Laurent mCallbackThread->setWriteBlocked(mWriteAckSequence); 2674bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent } 2675767094dd98b01baf21de2ad09c27b3c98776cf73Glenn Kasten // FIXME We should have an implementation of timestamps for direct output threads. 2676767094dd98b01baf21de2ad09c27b3c98776cf73Glenn Kasten // They are used e.g for multichannel PCM playback over HDMI. 2677062e67a26e0553dd142be622821f493df541f0c6Phil Burk bytesWritten = mOutput->write((char *)mSinkBuffer + offset, mBytesRemaining); 2678517161856d74f5fe39cce131f29b977bc1745991Eric Laurent 2679bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent if (mUseAsyncWrite && 2680bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent ((bytesWritten < 0) || (bytesWritten == (ssize_t)mBytesRemaining))) { 2681bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent // do not wait for async callback in case of error of full write 26823b4529e03c5fc7a44c22f9091ad15a269bfca3a8Eric Laurent mWriteAckSequence &= ~1; 2683bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent ALOG_ASSERT(mCallbackThread != 0); 26843b4529e03c5fc7a44c22f9091ad15a269bfca3a8Eric Laurent mCallbackThread->setWriteBlocked(mWriteAckSequence); 2685bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent } 268681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 268781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 268881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mNumWrites++; 268981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mInWrite = false; 2690fd4779740ec3e9e865d5514464df26d015354388Eric Laurent mStandby = false; 2691bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent return bytesWritten; 2692bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent} 2693bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent 2694bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurentvoid AudioFlinger::PlaybackThread::threadLoop_drain() 2695bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent{ 26961dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov bool supportsDrain = false; 26971dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov if (mOutput->stream->supportsDrain(&supportsDrain) == OK && supportsDrain) { 2698bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent ALOGV("draining %s", (mMixerStatus == MIXER_DRAIN_TRACK) ? "early" : "full"); 2699bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent if (mUseAsyncWrite) { 27003b4529e03c5fc7a44c22f9091ad15a269bfca3a8Eric Laurent ALOGW_IF(mDrainSequence & 1, "threadLoop_drain(): out of sequence drain request"); 27013b4529e03c5fc7a44c22f9091ad15a269bfca3a8Eric Laurent mDrainSequence |= 1; 2702bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent ALOG_ASSERT(mCallbackThread != 0); 27033b4529e03c5fc7a44c22f9091ad15a269bfca3a8Eric Laurent mCallbackThread->setDraining(mDrainSequence); 2704bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent } 2705cbc8f617c1aebef5d041fa40dcd38a5466690b99Mikhail Naganov status_t result = mOutput->stream->drain(mMixerStatus == MIXER_DRAIN_TRACK); 27061dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov ALOGE_IF(result != OK, "Error when draining stream: %d", result); 2707bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent } 2708bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent} 2709bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent 2710bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurentvoid AudioFlinger::PlaybackThread::threadLoop_exit() 2711bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent{ 2712275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent { 2713275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent Mutex::Autolock _l(mLock); 2714275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent for (size_t i = 0; i < mTracks.size(); i++) { 2715275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent sp<Track> track = mTracks[i]; 2716275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent track->invalidate(); 2717275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent } 2718dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hung // Clear ActiveTracks to update BatteryNotifier in case active tracks remain. 2719dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hung // After we exit there are no more track changes sent to BatteryNotifier 2720dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hung // because that requires an active threadLoop. 2721dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hung // TODO: should we decActiveTrackCnt() of the cleared track effect chain? 2722dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hung mActiveTracks.clear(); 2723275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent } 272481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 272581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 272681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent/* 272781784c37c61b09289654b979567a42bf73cd2b12Eric LaurentThe derived values that are cached: 272825c2dac12114699e90deb1c579cadebce7b91a97Andy Hung - mSinkBufferSize from frame count * frame size 2729ad9cb8b88e4f8face23f01d8dc89fa769dacb50fEric Laurent - mActiveSleepTimeUs from activeSleepTimeUs() 2730ad9cb8b88e4f8face23f01d8dc89fa769dacb50fEric Laurent - mIdleSleepTimeUs from idleSleepTimeUs() 273142537be61479e59c4718e1304364551c1454f63cEric Laurent - mStandbyDelayNs from mActiveSleepTimeUs (DIRECT only) or forced to at least 273242537be61479e59c4718e1304364551c1454f63cEric Laurent kDefaultStandbyTimeInNsecs when connected to an A2DP device. 273381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent - maxPeriod from frame count and sample rate (MIXER only) 273481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 273581784c37c61b09289654b979567a42bf73cd2b12Eric LaurentThe parameters that affect these derived values are: 273681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent - frame count 273781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent - frame size 273881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent - sample rate 273981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent - device type: A2DP or not 274081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent - device latency 274181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent - format: PCM or not 274281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent - active sleep time 274381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent - idle sleep time 274481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent*/ 274581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 274681784c37c61b09289654b979567a42bf73cd2b12Eric Laurentvoid AudioFlinger::PlaybackThread::cacheParameters_l() 274781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 274825c2dac12114699e90deb1c579cadebce7b91a97Andy Hung mSinkBufferSize = mNormalFrameCount * mFrameSize; 2749ad9cb8b88e4f8face23f01d8dc89fa769dacb50fEric Laurent mActiveSleepTimeUs = activeSleepTimeUs(); 2750ad9cb8b88e4f8face23f01d8dc89fa769dacb50fEric Laurent mIdleSleepTimeUs = idleSleepTimeUs(); 275142537be61479e59c4718e1304364551c1454f63cEric Laurent 275242537be61479e59c4718e1304364551c1454f63cEric Laurent // make sure standby delay is not too short when connected to an A2DP sink to avoid 275342537be61479e59c4718e1304364551c1454f63cEric Laurent // truncating audio when going to standby. 275442537be61479e59c4718e1304364551c1454f63cEric Laurent mStandbyDelayNs = AudioFlinger::mStandbyTimeInNsecs; 275542537be61479e59c4718e1304364551c1454f63cEric Laurent if ((mOutDevice & AUDIO_DEVICE_OUT_ALL_A2DP) != 0) { 275642537be61479e59c4718e1304364551c1454f63cEric Laurent if (mStandbyDelayNs < kDefaultStandbyTimeInNsecs) { 275742537be61479e59c4718e1304364551c1454f63cEric Laurent mStandbyDelayNs = kDefaultStandbyTimeInNsecs; 275842537be61479e59c4718e1304364551c1454f63cEric Laurent } 275942537be61479e59c4718e1304364551c1454f63cEric Laurent } 276081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 276181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 276213084621072ea2e4c34e2a9d79793c621d9bf005Eric Laurentbool AudioFlinger::PlaybackThread::invalidateTracks_l(audio_stream_type_t streamType) 276381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 2764c42e9b462661673dff480ee71757a58b0f806370Glenn Kasten ALOGV("MixerThread::invalidateTracks() mixer %p, streamType %d, mTracks.size %zu", 276581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent this, streamType, mTracks.size()); 276613084621072ea2e4c34e2a9d79793c621d9bf005Eric Laurent bool trackMatch = false; 276781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent size_t size = mTracks.size(); 276881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent for (size_t i = 0; i < size; i++) { 276981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent sp<Track> t = mTracks[i]; 2770d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent if (t->streamType() == streamType && t->isExternalTrack()) { 27715736c35b841de56ce394b4879389f669b61425e6Glenn Kasten t->invalidate(); 277213084621072ea2e4c34e2a9d79793c621d9bf005Eric Laurent trackMatch = true; 277381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 277481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 277513084621072ea2e4c34e2a9d79793c621d9bf005Eric Laurent return trackMatch; 277681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 277781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 277805317d29b27e5fda654bea21b80d4423a03f49b3Haynes Mathew Georgevoid AudioFlinger::PlaybackThread::invalidateTracks(audio_stream_type_t streamType) 277905317d29b27e5fda654bea21b80d4423a03f49b3Haynes Mathew George{ 278005317d29b27e5fda654bea21b80d4423a03f49b3Haynes Mathew George Mutex::Autolock _l(mLock); 278105317d29b27e5fda654bea21b80d4423a03f49b3Haynes Mathew George invalidateTracks_l(streamType); 278205317d29b27e5fda654bea21b80d4423a03f49b3Haynes Mathew George} 278305317d29b27e5fda654bea21b80d4423a03f49b3Haynes Mathew George 278481784c37c61b09289654b979567a42bf73cd2b12Eric Laurentstatus_t AudioFlinger::PlaybackThread::addEffectChain_l(const sp<EffectChain>& chain) 278581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 2786d848eb48c121c119e8ba7583efc75415fe102570Glenn Kasten audio_session_t session = chain->sessionId(); 2787022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov sp<EffectBufferHalInterface> halInBuffer, halOutBuffer; 2788022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov status_t result = EffectBufferHalInterface::mirror( 2789022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov mEffectBufferEnabled ? mEffectBuffer : mSinkBuffer, 2790022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov mEffectBufferEnabled ? mEffectBufferSize : mSinkBufferSize, 2791022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov &halInBuffer); 2792022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov if (result != OK) return result; 2793022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov halOutBuffer = halInBuffer; 2794022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov int16_t *buffer = reinterpret_cast<int16_t*>(halInBuffer->externalData()); 279581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 279681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent ALOGV("addEffectChain_l() %p on thread %p for session %d", chain.get(), this, session); 2797d848eb48c121c119e8ba7583efc75415fe102570Glenn Kasten if (session > AUDIO_SESSION_OUTPUT_MIX) { 279881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // Only one effect chain can be present in direct output thread and it uses 27992098f2744cedf2dc3fa36f608aa965a34602e7c0Andy Hung // the sink buffer as input 280081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (mType != DIRECT) { 280181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent size_t numSamples = mNormalFrameCount * mChannelCount; 2802022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov status_t result = EffectBufferHalInterface::allocate( 2803022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov numSamples * sizeof(int16_t), 2804022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov &halInBuffer); 2805022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov if (result != OK) return result; 2806022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov buffer = halInBuffer->audioBuffer()->s16; 2807022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov ALOGV("addEffectChain_l() creating new input buffer %p session %d", 2808022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov buffer, session); 280981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 281081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 281181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // Attach all tracks with same session ID to this chain. 281281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent for (size_t i = 0; i < mTracks.size(); ++i) { 281381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent sp<Track> track = mTracks[i]; 281481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (session == track->sessionId()) { 281581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent ALOGV("addEffectChain_l() track->setMainBuffer track %p buffer %p", track.get(), 281681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent buffer); 281781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent track->setMainBuffer(buffer); 281881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent chain->incTrackCnt(); 281981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 282081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 282181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 282281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // indicate all active tracks in the chain 2823dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hung for (const sp<Track> &track : mActiveTracks) { 282481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (session == track->sessionId()) { 282581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent ALOGV("addEffectChain_l() activating track %p on session %d", track.get(), session); 282681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent chain->incActiveTrackCnt(); 282781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 282881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 282981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 2830aaa44478a373232d8416657035a9020f9c7aa7c3Eric Laurent chain->setThread(this); 2831022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov chain->setInBuffer(halInBuffer); 2832022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov chain->setOutBuffer(halOutBuffer); 283381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // Effect chain for session AUDIO_SESSION_OUTPUT_STAGE is inserted at end of effect 2834d848eb48c121c119e8ba7583efc75415fe102570Glenn Kasten // chains list in order to be processed last as it contains output stage effects. 283581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // Effect chain for session AUDIO_SESSION_OUTPUT_MIX is inserted before 283681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // session AUDIO_SESSION_OUTPUT_STAGE to be processed 2837d848eb48c121c119e8ba7583efc75415fe102570Glenn Kasten // after track specific effects and before output stage. 283881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // It is therefore mandatory that AUDIO_SESSION_OUTPUT_MIX == 0 and 2839d848eb48c121c119e8ba7583efc75415fe102570Glenn Kasten // that AUDIO_SESSION_OUTPUT_STAGE < AUDIO_SESSION_OUTPUT_MIX. 284081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // Effect chain for other sessions are inserted at beginning of effect 284181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // chains list to be processed before output mix effects. Relative order between other 2842d848eb48c121c119e8ba7583efc75415fe102570Glenn Kasten // sessions is not important. 2843d848eb48c121c119e8ba7583efc75415fe102570Glenn Kasten static_assert(AUDIO_SESSION_OUTPUT_MIX == 0 && 2844d848eb48c121c119e8ba7583efc75415fe102570Glenn Kasten AUDIO_SESSION_OUTPUT_STAGE < AUDIO_SESSION_OUTPUT_MIX, 2845d848eb48c121c119e8ba7583efc75415fe102570Glenn Kasten "audio_session_t constants misdefined"); 284681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent size_t size = mEffectChains.size(); 284781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent size_t i = 0; 284881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent for (i = 0; i < size; i++) { 284981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (mEffectChains[i]->sessionId() < session) { 285081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent break; 285181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 285281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 285381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mEffectChains.insertAt(chain, i); 285481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent checkSuspendOnAddEffectChain_l(chain); 285581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 285681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent return NO_ERROR; 285781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 285881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 285981784c37c61b09289654b979567a42bf73cd2b12Eric Laurentsize_t AudioFlinger::PlaybackThread::removeEffectChain_l(const sp<EffectChain>& chain) 286081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 2861d848eb48c121c119e8ba7583efc75415fe102570Glenn Kasten audio_session_t session = chain->sessionId(); 286281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 286381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent ALOGV("removeEffectChain_l() %p from thread %p for session %d", chain.get(), this, session); 286481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 286581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent for (size_t i = 0; i < mEffectChains.size(); i++) { 286681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (chain == mEffectChains[i]) { 286781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mEffectChains.removeAt(i); 286881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // detach all active tracks from the chain 2869dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hung for (const sp<Track> &track : mActiveTracks) { 287081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (session == track->sessionId()) { 287181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent ALOGV("removeEffectChain_l(): stopping track on chain %p for session Id: %d", 287281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent chain.get(), session); 287381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent chain->decActiveTrackCnt(); 287481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 287581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 287681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 287781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // detach all tracks with same session ID from this chain 287881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent for (size_t i = 0; i < mTracks.size(); ++i) { 287981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent sp<Track> track = mTracks[i]; 288081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (session == track->sessionId()) { 2881010a1a1a552cdaad362cea8a0333b8906402dbcbAndy Hung track->setMainBuffer(reinterpret_cast<int16_t*>(mSinkBuffer)); 288281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent chain->decTrackCnt(); 288381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 288481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 288581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent break; 288681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 288781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 288881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent return mEffectChains.size(); 288981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 289081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 289181784c37c61b09289654b979567a42bf73cd2b12Eric Laurentstatus_t AudioFlinger::PlaybackThread::attachAuxEffect( 2892e964d4e421e2d1ca937227a580c0c837091a11e3Chih-Hung Hsieh const sp<AudioFlinger::PlaybackThread::Track>& track, int EffectId) 289381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 289481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent Mutex::Autolock _l(mLock); 289581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent return attachAuxEffect_l(track, EffectId); 289681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 289781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 289881784c37c61b09289654b979567a42bf73cd2b12Eric Laurentstatus_t AudioFlinger::PlaybackThread::attachAuxEffect_l( 2899e964d4e421e2d1ca937227a580c0c837091a11e3Chih-Hung Hsieh const sp<AudioFlinger::PlaybackThread::Track>& track, int EffectId) 290081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 290181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent status_t status = NO_ERROR; 290281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 290381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (EffectId == 0) { 290481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent track->setAuxBuffer(0, NULL); 290581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } else { 290681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // Auxiliary effects are always in audio session AUDIO_SESSION_OUTPUT_MIX 290781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent sp<EffectModule> effect = getEffect_l(AUDIO_SESSION_OUTPUT_MIX, EffectId); 290881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (effect != 0) { 290981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if ((effect->desc().flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_AUXILIARY) { 291081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent track->setAuxBuffer(EffectId, (int32_t *)effect->inBuffer()); 291181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } else { 291281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent status = INVALID_OPERATION; 291381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 291481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } else { 291581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent status = BAD_VALUE; 291681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 291781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 291881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent return status; 291981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 292081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 292181784c37c61b09289654b979567a42bf73cd2b12Eric Laurentvoid AudioFlinger::PlaybackThread::detachAuxEffect_l(int effectId) 292281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 292381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent for (size_t i = 0; i < mTracks.size(); ++i) { 292481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent sp<Track> track = mTracks[i]; 292581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (track->auxEffectId() == effectId) { 292681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent attachAuxEffect_l(track, 0); 292781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 292881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 292981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 293081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 293181784c37c61b09289654b979567a42bf73cd2b12Eric Laurentbool AudioFlinger::PlaybackThread::threadLoop() 293281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 2933fe1e1449cadff4f946c33403aecc73b4b4a11e56Nicolas Roulet logWriterTLS = mNBLogWriter.get(); 2934fe1e1449cadff4f946c33403aecc73b4b4a11e56Nicolas Roulet 293581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent Vector< sp<Track> > tracksToRemove; 293681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 2937ad9cb8b88e4f8face23f01d8dc89fa769dacb50fEric Laurent mStandbyTimeNs = systemTime(); 293869488c4ef115c9de52c85f4fcae27c7774720298Andy Hung nsecs_t lastWriteFinished = -1; // time last server write completed 293969488c4ef115c9de52c85f4fcae27c7774720298Andy Hung int64_t lastFramesWritten = -1; // track changes in timestamp server frames written 294081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 294181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // MIXER 294281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent nsecs_t lastWarning = 0; 294381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 294481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // DUPLICATING 294581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // FIXME could this be made local to while loop? 294681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent writeFrames = 0; 294781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 294881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent cacheParameters_l(); 2949ad9cb8b88e4f8face23f01d8dc89fa769dacb50fEric Laurent mSleepTimeUs = mIdleSleepTimeUs; 295081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 295181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (mType == MIXER) { 295281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent sleepTimeShift = 0; 295381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 295481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 295581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent CpuStats cpuStats; 295681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent const String8 myName(String8::format("thread %p type %d TID %d", this, mType, gettid())); 295781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 295881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent acquireWakeLock(); 295981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 29609e58b552f51b00b3b674102876bd6c77ef3da806Glenn Kasten // mNBLogWriter->log can only be called while thread mutex mLock is held. 29619e58b552f51b00b3b674102876bd6c77ef3da806Glenn Kasten // So if you need to log when mutex is unlocked, set logString to a non-NULL string, 29629e58b552f51b00b3b674102876bd6c77ef3da806Glenn Kasten // and then that string will be logged at the next convenient opportunity. 29639e58b552f51b00b3b674102876bd6c77ef3da806Glenn Kasten const char *logString = NULL; 29649e58b552f51b00b3b674102876bd6c77ef3da806Glenn Kasten 29651bb9082596c9cac2995dc9b4465a7c6d5666d099rago // Estimated time for next buffer to be written to hal. This is used only on 29661bb9082596c9cac2995dc9b4465a7c6d5666d099rago // suspended mode (for now) to help schedule the wait time until next iteration. 29671bb9082596c9cac2995dc9b4465a7c6d5666d099rago nsecs_t timeLoopNextNs = 0; 29681bb9082596c9cac2995dc9b4465a7c6d5666d099rago 2969664539d25180ab8f77e0521533ea2821cf28985fEric Laurent checkSilentMode_l(); 2970fe1e1449cadff4f946c33403aecc73b4b4a11e56Nicolas Roulet#if 0 2971fe1e1449cadff4f946c33403aecc73b4b4a11e56Nicolas Roulet int z = 0; // used in logFormat example 2972fe1e1449cadff4f946c33403aecc73b4b4a11e56Nicolas Roulet#endif 297381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent while (!exitPending()) 297481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent { 2975dcdfaecc1fa630a799e1fdb508a9b92da55abc36Nicolas Roulet // Log merge requests are performed during AudioFlinger binder transactions, but 2976dcdfaecc1fa630a799e1fdb508a9b92da55abc36Nicolas Roulet // that does not cover audio playback. It's requested here for that reason. 2977dcdfaecc1fa630a799e1fdb508a9b92da55abc36Nicolas Roulet mAudioFlinger->requestLogMerge(); 2978dcdfaecc1fa630a799e1fdb508a9b92da55abc36Nicolas Roulet 297981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent cpuStats.sample(myName); 298081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 298181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent Vector< sp<EffectChain> > effectChains; 298281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 298381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent { // scope for mLock 298481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 298581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent Mutex::Autolock _l(mLock); 298681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 2987021cf9634ab09c0753a40b7c9ef4ba603be5c3daEric Laurent processConfigEvents_l(); 29881035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent 29899e58b552f51b00b3b674102876bd6c77ef3da806Glenn Kasten if (logString != NULL) { 29909e58b552f51b00b3b674102876bd6c77ef3da806Glenn Kasten mNBLogWriter->logTimestamp(); 29919e58b552f51b00b3b674102876bd6c77ef3da806Glenn Kasten mNBLogWriter->log(logString); 29929e58b552f51b00b3b674102876bd6c77ef3da806Glenn Kasten logString = NULL; 29939e58b552f51b00b3b674102876bd6c77ef3da806Glenn Kasten } 29949e58b552f51b00b3b674102876bd6c77ef3da806Glenn Kasten 29954c053ea158b29fa2cdd4c6f39d3c8da4ee5a7a02Glenn Kasten // Gather the framesReleased counters for all active tracks, 2996e10393e72454bfd8298017dc193faf424f4e9a8fAndy Hung // and associate with the sink frames written out. We need 2997e10393e72454bfd8298017dc193faf424f4e9a8fAndy Hung // this to convert the sink timestamp to the track timestamp. 299869488c4ef115c9de52c85f4fcae27c7774720298Andy Hung bool kernelLocationUpdate = false; 2999e10393e72454bfd8298017dc193faf424f4e9a8fAndy Hung if (mNormalSink != 0) { 3000c54b1ffc92b8ad27608a8af21033d7cab33cb3a0Andy Hung // Note: The DuplicatingThread may not have a mNormalSink. 3001818e7a32ce3633980138aff2c2bfcc5158b3cfccAndy Hung // We always fetch the timestamp here because often the downstream 300269488c4ef115c9de52c85f4fcae27c7774720298Andy Hung // sink will block while writing. 3003818e7a32ce3633980138aff2c2bfcc5158b3cfccAndy Hung ExtendedTimestamp timestamp; // use private copy to fetch 3004818e7a32ce3633980138aff2c2bfcc5158b3cfccAndy Hung (void) mNormalSink->getTimestamp(timestamp); 30056d7b119a416c9f10288051e562f294365e5d954cAndy Hung 30066d7b119a416c9f10288051e562f294365e5d954cAndy Hung // We keep track of the last valid kernel position in case we are in underrun 30076d7b119a416c9f10288051e562f294365e5d954cAndy Hung // and the normal mixer period is the same as the fast mixer period, or there 30086d7b119a416c9f10288051e562f294365e5d954cAndy Hung // is some error from the HAL. 30096d7b119a416c9f10288051e562f294365e5d954cAndy Hung if (mTimestamp.mTimeNs[ExtendedTimestamp::LOCATION_KERNEL] >= 0) { 30106d7b119a416c9f10288051e562f294365e5d954cAndy Hung mTimestamp.mPosition[ExtendedTimestamp::LOCATION_KERNEL_LASTKERNELOK] = 30116d7b119a416c9f10288051e562f294365e5d954cAndy Hung mTimestamp.mPosition[ExtendedTimestamp::LOCATION_KERNEL]; 30126d7b119a416c9f10288051e562f294365e5d954cAndy Hung mTimestamp.mTimeNs[ExtendedTimestamp::LOCATION_KERNEL_LASTKERNELOK] = 30136d7b119a416c9f10288051e562f294365e5d954cAndy Hung mTimestamp.mTimeNs[ExtendedTimestamp::LOCATION_KERNEL]; 30146d7b119a416c9f10288051e562f294365e5d954cAndy Hung 30156d7b119a416c9f10288051e562f294365e5d954cAndy Hung mTimestamp.mPosition[ExtendedTimestamp::LOCATION_SERVER_LASTKERNELOK] = 30166d7b119a416c9f10288051e562f294365e5d954cAndy Hung mTimestamp.mPosition[ExtendedTimestamp::LOCATION_SERVER]; 30176d7b119a416c9f10288051e562f294365e5d954cAndy Hung mTimestamp.mTimeNs[ExtendedTimestamp::LOCATION_SERVER_LASTKERNELOK] = 30186d7b119a416c9f10288051e562f294365e5d954cAndy Hung mTimestamp.mTimeNs[ExtendedTimestamp::LOCATION_SERVER]; 301969488c4ef115c9de52c85f4fcae27c7774720298Andy Hung } 302069488c4ef115c9de52c85f4fcae27c7774720298Andy Hung 302169488c4ef115c9de52c85f4fcae27c7774720298Andy Hung if (timestamp.mTimeNs[ExtendedTimestamp::LOCATION_KERNEL] >= 0) { 302269488c4ef115c9de52c85f4fcae27c7774720298Andy Hung kernelLocationUpdate = true; 30236d7b119a416c9f10288051e562f294365e5d954cAndy Hung } else { 3024122f7e793fe6fb8904634cc6d2e35ac4b014ea72Eric Laurent ALOGVV("getTimestamp error - no valid kernel position"); 30256d7b119a416c9f10288051e562f294365e5d954cAndy Hung } 30266d7b119a416c9f10288051e562f294365e5d954cAndy Hung 3027818e7a32ce3633980138aff2c2bfcc5158b3cfccAndy Hung // copy over kernel info 3028818e7a32ce3633980138aff2c2bfcc5158b3cfccAndy Hung mTimestamp.mPosition[ExtendedTimestamp::LOCATION_KERNEL] = 3029238fa3deff26d7e4d9e81bd0a88c936f16226c4eAndy Hung timestamp.mPosition[ExtendedTimestamp::LOCATION_KERNEL] 3030238fa3deff26d7e4d9e81bd0a88c936f16226c4eAndy Hung + mSuspendedFrames; // add frames discarded when suspended 3031818e7a32ce3633980138aff2c2bfcc5158b3cfccAndy Hung mTimestamp.mTimeNs[ExtendedTimestamp::LOCATION_KERNEL] = 3032818e7a32ce3633980138aff2c2bfcc5158b3cfccAndy Hung timestamp.mTimeNs[ExtendedTimestamp::LOCATION_KERNEL]; 3033c54b1ffc92b8ad27608a8af21033d7cab33cb3a0Andy Hung } 3034c54b1ffc92b8ad27608a8af21033d7cab33cb3a0Andy Hung // mFramesWritten for non-offloaded tracks are contiguous 3035c54b1ffc92b8ad27608a8af21033d7cab33cb3a0Andy Hung // even after standby() is called. This is useful for the track frame 3036c54b1ffc92b8ad27608a8af21033d7cab33cb3a0Andy Hung // to sink frame mapping. 303769488c4ef115c9de52c85f4fcae27c7774720298Andy Hung bool serverLocationUpdate = false; 303869488c4ef115c9de52c85f4fcae27c7774720298Andy Hung if (mFramesWritten != lastFramesWritten) { 303969488c4ef115c9de52c85f4fcae27c7774720298Andy Hung serverLocationUpdate = true; 304069488c4ef115c9de52c85f4fcae27c7774720298Andy Hung lastFramesWritten = mFramesWritten; 304169488c4ef115c9de52c85f4fcae27c7774720298Andy Hung } 304269488c4ef115c9de52c85f4fcae27c7774720298Andy Hung // Only update timestamps if there is a meaningful change. 304369488c4ef115c9de52c85f4fcae27c7774720298Andy Hung // Either the kernel timestamp must be valid or we have written something. 304469488c4ef115c9de52c85f4fcae27c7774720298Andy Hung if (kernelLocationUpdate || serverLocationUpdate) { 304569488c4ef115c9de52c85f4fcae27c7774720298Andy Hung if (serverLocationUpdate) { 304669488c4ef115c9de52c85f4fcae27c7774720298Andy Hung // use the time before we called the HAL write - it is a bit more accurate 304769488c4ef115c9de52c85f4fcae27c7774720298Andy Hung // to when the server last read data than the current time here. 304869488c4ef115c9de52c85f4fcae27c7774720298Andy Hung // 304969488c4ef115c9de52c85f4fcae27c7774720298Andy Hung // If we haven't written anything, mLastWriteTime will be -1 305069488c4ef115c9de52c85f4fcae27c7774720298Andy Hung // and we use systemTime(). 305169488c4ef115c9de52c85f4fcae27c7774720298Andy Hung mTimestamp.mPosition[ExtendedTimestamp::LOCATION_SERVER] = mFramesWritten; 305269488c4ef115c9de52c85f4fcae27c7774720298Andy Hung mTimestamp.mTimeNs[ExtendedTimestamp::LOCATION_SERVER] = mLastWriteTime == -1 305369488c4ef115c9de52c85f4fcae27c7774720298Andy Hung ? systemTime() : mLastWriteTime; 305469488c4ef115c9de52c85f4fcae27c7774720298Andy Hung } 3055dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hung 3056dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hung for (const sp<Track> &t : mActiveTracks) { 3057dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hung if (!t->isFastTrack()) { 305869488c4ef115c9de52c85f4fcae27c7774720298Andy Hung t->updateTrackFrameInfo( 305969488c4ef115c9de52c85f4fcae27c7774720298Andy Hung t->mAudioTrackServerProxy->framesReleased(), 306069488c4ef115c9de52c85f4fcae27c7774720298Andy Hung mFramesWritten, 306169488c4ef115c9de52c85f4fcae27c7774720298Andy Hung mTimestamp); 306269488c4ef115c9de52c85f4fcae27c7774720298Andy Hung } 30634c053ea158b29fa2cdd4c6f39d3c8da4ee5a7a02Glenn Kasten } 3064bd096fd9d8e5fc0e62f98807f4818a06f70d0812Glenn Kasten } 3065fe1e1449cadff4f946c33403aecc73b4b4a11e56Nicolas Roulet#if 0 3066fe1e1449cadff4f946c33403aecc73b4b4a11e56Nicolas Roulet // logFormat example 3067c20cb50c1c14cd765874511872f087c875f43ed9Nicolas Roulet if (z % 100 == 0) { 3068fe1e1449cadff4f946c33403aecc73b4b4a11e56Nicolas Roulet timespec ts; 3069fe1e1449cadff4f946c33403aecc73b4b4a11e56Nicolas Roulet clock_gettime(CLOCK_MONOTONIC, &ts); 30704da7820be451847bad698ac0f687b964d9b5d34fNicolas Roulet LOGT("This is an integer %d, this is a float %f, this is my " 3071fe1e1449cadff4f946c33403aecc73b4b4a11e56Nicolas Roulet "pid %p %% %s %t", 42, 3.14, "and this is a timestamp", ts); 30724da7820be451847bad698ac0f687b964d9b5d34fNicolas Roulet LOGT("A deceptive null-terminated string %\0"); 3073fe1e1449cadff4f946c33403aecc73b4b4a11e56Nicolas Roulet } 3074fe1e1449cadff4f946c33403aecc73b4b4a11e56Nicolas Roulet ++z; 3075fe1e1449cadff4f946c33403aecc73b4b4a11e56Nicolas Roulet#endif 307681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent saveOutputTracks(); 3077bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent if (mSignalPending) { 3078bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent // A signal was raised while we were unlocked 3079bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent mSignalPending = false; 3080bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent } else if (waitingAsyncCallback_l()) { 3081bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent if (exitPending()) { 3082bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent break; 3083bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent } 3084078538cfc6c4682889ed52de460d29c0d15bb9ebMarco Nelissen bool released = false; 3085646679779a8f952980a5d4219ad9c6f93efc4b92Eric Laurent if (!keepWakeLock()) { 3086078538cfc6c4682889ed52de460d29c0d15bb9ebMarco Nelissen releaseWakeLock_l(); 3087078538cfc6c4682889ed52de460d29c0d15bb9ebMarco Nelissen released = true; 3088078538cfc6c4682889ed52de460d29c0d15bb9ebMarco Nelissen } 308910cbff139360f3f642e0e3b3ccf2d463dbed22cfAndy Hung 309010cbff139360f3f642e0e3b3ccf2d463dbed22cfAndy Hung const int64_t waitNs = computeWaitTimeNs_l(); 309110cbff139360f3f642e0e3b3ccf2d463dbed22cfAndy Hung ALOGV("wait async completion (wait time: %lld)", (long long)waitNs); 309210cbff139360f3f642e0e3b3ccf2d463dbed22cfAndy Hung status_t status = mWaitWorkCV.waitRelative(mLock, waitNs); 309310cbff139360f3f642e0e3b3ccf2d463dbed22cfAndy Hung if (status == TIMED_OUT) { 309410cbff139360f3f642e0e3b3ccf2d463dbed22cfAndy Hung mSignalPending = true; // if timeout recheck everything 309510cbff139360f3f642e0e3b3ccf2d463dbed22cfAndy Hung } 3096bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent ALOGV("async completion/wake"); 3097078538cfc6c4682889ed52de460d29c0d15bb9ebMarco Nelissen if (released) { 3098078538cfc6c4682889ed52de460d29c0d15bb9ebMarco Nelissen acquireWakeLock_l(); 3099078538cfc6c4682889ed52de460d29c0d15bb9ebMarco Nelissen } 3100ad9cb8b88e4f8face23f01d8dc89fa769dacb50fEric Laurent mStandbyTimeNs = systemTime() + mStandbyDelayNs; 3101ad9cb8b88e4f8face23f01d8dc89fa769dacb50fEric Laurent mSleepTimeUs = 0; 3102ede6c3b8b1147bc425f7b923882f559a513fe23bEric Laurent 3103ede6c3b8b1147bc425f7b923882f559a513fe23bEric Laurent continue; 3104ede6c3b8b1147bc425f7b923882f559a513fe23bEric Laurent } 3105ad9cb8b88e4f8face23f01d8dc89fa769dacb50fEric Laurent if ((!mActiveTracks.size() && systemTime() > mStandbyTimeNs) || 3106bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent isSuspended()) { 3107bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent // put audio hardware into standby after short delay 3108bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent if (shouldStandby_l()) { 310981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 311081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent threadLoop_standby(); 311181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 311281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mStandby = true; 311381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 311481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 311581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (!mActiveTracks.size() && mConfigEvents.isEmpty()) { 311681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // we're about to wait, flush the binder command buffer 311781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent IPCThreadState::self()->flushCommands(); 311881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 311981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent clearOutputTracks(); 312081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 312181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (exitPending()) { 312281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent break; 312381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 312481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 312581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent releaseWakeLock_l(); 312681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // wait until we have something to do... 312781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent ALOGV("%s going to sleep", myName.string()); 312881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mWaitWorkCV.wait(mLock); 312981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent ALOGV("%s waking up", myName.string()); 313081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent acquireWakeLock_l(); 313181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 313281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mMixerStatus = MIXER_IDLE; 313381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mMixerStatusIgnoringFastTracks = MIXER_IDLE; 313481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mBytesWritten = 0; 3135bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent mBytesRemaining = 0; 313681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent checkSilentMode_l(); 313781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 3138ad9cb8b88e4f8face23f01d8dc89fa769dacb50fEric Laurent mStandbyTimeNs = systemTime() + mStandbyDelayNs; 3139ad9cb8b88e4f8face23f01d8dc89fa769dacb50fEric Laurent mSleepTimeUs = mIdleSleepTimeUs; 314081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (mType == MIXER) { 314181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent sleepTimeShift = 0; 314281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 314381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 314481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent continue; 314581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 314681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 314781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // mMixerStatusIgnoringFastTracks is also updated internally 314881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mMixerStatus = prepareTracks_l(&tracksToRemove); 314981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 3150dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hung mActiveTracks.updatePowerState(this); 3151462fd2fa9eef642b0574aa7409de0bde3fec8d43Marco Nelissen 315281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // prevent any changes in effect chain list and in each effect chain 315381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // during mixing and effect process as the audio buffers could be deleted 315481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // or modified if an effect is created or deleted 315581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent lockEffectChains_l(effectChains); 3156462fd2fa9eef642b0574aa7409de0bde3fec8d43Marco Nelissen } // mLock scope ends 315781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 3158bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent if (mBytesRemaining == 0) { 3159bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent mCurrentWriteLength = 0; 3160bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent if (mMixerStatus == MIXER_TRACKS_READY) { 3161bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent // threadLoop_mix() sets mCurrentWriteLength 3162bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent threadLoop_mix(); 3163bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent } else if ((mMixerStatus != MIXER_DRAIN_TRACK) 3164bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent && (mMixerStatus != MIXER_DRAIN_ALL)) { 3165ad9cb8b88e4f8face23f01d8dc89fa769dacb50fEric Laurent // threadLoop_sleepTime sets mSleepTimeUs to 0 if data 3166bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent // must be written to HAL 3167bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent threadLoop_sleepTime(); 3168ad9cb8b88e4f8face23f01d8dc89fa769dacb50fEric Laurent if (mSleepTimeUs == 0) { 316925c2dac12114699e90deb1c579cadebce7b91a97Andy Hung mCurrentWriteLength = mSinkBufferSize; 3170bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent } 3171bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent } 317298ef978df4e928f486d244c4d7f7ad9f13111e98Andy Hung // Either threadLoop_mix() or threadLoop_sleepTime() should have set 3173ad9cb8b88e4f8face23f01d8dc89fa769dacb50fEric Laurent // mMixerBuffer with data if mMixerBufferValid is true and mSleepTimeUs == 0. 317498ef978df4e928f486d244c4d7f7ad9f13111e98Andy Hung // Merge mMixerBuffer data into mEffectBuffer (if any effects are valid) 317598ef978df4e928f486d244c4d7f7ad9f13111e98Andy Hung // or mSinkBuffer (if there are no effects). 317698ef978df4e928f486d244c4d7f7ad9f13111e98Andy Hung // 317798ef978df4e928f486d244c4d7f7ad9f13111e98Andy Hung // This is done pre-effects computation; if effects change to 317898ef978df4e928f486d244c4d7f7ad9f13111e98Andy Hung // support higher precision, this needs to move. 317998ef978df4e928f486d244c4d7f7ad9f13111e98Andy Hung // 318098ef978df4e928f486d244c4d7f7ad9f13111e98Andy Hung // mMixerBufferValid is only set true by MixerThread::prepareTracks_l(). 3181ad9cb8b88e4f8face23f01d8dc89fa769dacb50fEric Laurent // TODO use mSleepTimeUs == 0 as an additional condition. 318298ef978df4e928f486d244c4d7f7ad9f13111e98Andy Hung if (mMixerBufferValid) { 318398ef978df4e928f486d244c4d7f7ad9f13111e98Andy Hung void *buffer = mEffectBufferValid ? mEffectBuffer : mSinkBuffer; 318498ef978df4e928f486d244c4d7f7ad9f13111e98Andy Hung audio_format_t format = mEffectBufferValid ? mEffectBufferFormat : mFormat; 318598ef978df4e928f486d244c4d7f7ad9f13111e98Andy Hung 31862ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hung // mono blend occurs for mixer threads only (not direct or offloaded) 31872ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hung // and is handled here if we're going directly to the sink. 31882ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hung if (requireMonoBlend() && !mEffectBufferValid) { 318903c48d5afcb3dfc1e43df93e1f3b3b3e9292e148Glenn Kasten mono_blend(mMixerBuffer, mMixerBufferFormat, mChannelCount, mNormalFrameCount, 319003c48d5afcb3dfc1e43df93e1f3b3b3e9292e148Glenn Kasten true /*limit*/); 31912ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hung } 31922ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hung 319398ef978df4e928f486d244c4d7f7ad9f13111e98Andy Hung memcpy_by_audio_format(buffer, format, mMixerBuffer, mMixerBufferFormat, 319498ef978df4e928f486d244c4d7f7ad9f13111e98Andy Hung mNormalFrameCount * mChannelCount); 319598ef978df4e928f486d244c4d7f7ad9f13111e98Andy Hung } 319698ef978df4e928f486d244c4d7f7ad9f13111e98Andy Hung 3197bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent mBytesRemaining = mCurrentWriteLength; 3198bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent if (isSuspended()) { 3199238fa3deff26d7e4d9e81bd0a88c936f16226c4eAndy Hung // Simulate write to HAL when suspended (e.g. BT SCO phone call). 3200238fa3deff26d7e4d9e81bd0a88c936f16226c4eAndy Hung mSleepTimeUs = suspendSleepTimeUs(); // assumes full buffer. 3201238fa3deff26d7e4d9e81bd0a88c936f16226c4eAndy Hung const size_t framesRemaining = mBytesRemaining / mFrameSize; 3202238fa3deff26d7e4d9e81bd0a88c936f16226c4eAndy Hung mBytesWritten += mBytesRemaining; 3203238fa3deff26d7e4d9e81bd0a88c936f16226c4eAndy Hung mFramesWritten += framesRemaining; 3204238fa3deff26d7e4d9e81bd0a88c936f16226c4eAndy Hung mSuspendedFrames += framesRemaining; // to adjust kernel HAL position 3205bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent mBytesRemaining = 0; 3206bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent } 320781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 3208bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent // only process effects if we're going to write 3209ad9cb8b88e4f8face23f01d8dc89fa769dacb50fEric Laurent if (mSleepTimeUs == 0 && mType != OFFLOAD) { 3210bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent for (size_t i = 0; i < effectChains.size(); i ++) { 3211bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent effectChains[i]->process_l(); 3212bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent } 321381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 321481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 321559fe010bcc072597852454a2ec53d7b0a2002a3bEric Laurent // Process effect chains for offloaded thread even if no audio 321659fe010bcc072597852454a2ec53d7b0a2002a3bEric Laurent // was read from audio track: process only updates effect state 321759fe010bcc072597852454a2ec53d7b0a2002a3bEric Laurent // and thus does have to be synchronized with audio writes but may have 321859fe010bcc072597852454a2ec53d7b0a2002a3bEric Laurent // to be called while waiting for async write callback 321959fe010bcc072597852454a2ec53d7b0a2002a3bEric Laurent if (mType == OFFLOAD) { 322059fe010bcc072597852454a2ec53d7b0a2002a3bEric Laurent for (size_t i = 0; i < effectChains.size(); i ++) { 322159fe010bcc072597852454a2ec53d7b0a2002a3bEric Laurent effectChains[i]->process_l(); 322259fe010bcc072597852454a2ec53d7b0a2002a3bEric Laurent } 322359fe010bcc072597852454a2ec53d7b0a2002a3bEric Laurent } 322481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 322598ef978df4e928f486d244c4d7f7ad9f13111e98Andy Hung // Only if the Effects buffer is enabled and there is data in the 322698ef978df4e928f486d244c4d7f7ad9f13111e98Andy Hung // Effects buffer (buffer valid), we need to 322798ef978df4e928f486d244c4d7f7ad9f13111e98Andy Hung // copy into the sink buffer. 3228ad9cb8b88e4f8face23f01d8dc89fa769dacb50fEric Laurent // TODO use mSleepTimeUs == 0 as an additional condition. 322998ef978df4e928f486d244c4d7f7ad9f13111e98Andy Hung if (mEffectBufferValid) { 323098ef978df4e928f486d244c4d7f7ad9f13111e98Andy Hung //ALOGV("writing effect buffer to sink buffer format %#x", mFormat); 32312ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hung 32322ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hung if (requireMonoBlend()) { 323303c48d5afcb3dfc1e43df93e1f3b3b3e9292e148Glenn Kasten mono_blend(mEffectBuffer, mEffectBufferFormat, mChannelCount, mNormalFrameCount, 323403c48d5afcb3dfc1e43df93e1f3b3b3e9292e148Glenn Kasten true /*limit*/); 32352ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hung } 32362ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hung 323798ef978df4e928f486d244c4d7f7ad9f13111e98Andy Hung memcpy_by_audio_format(mSinkBuffer, mFormat, mEffectBuffer, mEffectBufferFormat, 323898ef978df4e928f486d244c4d7f7ad9f13111e98Andy Hung mNormalFrameCount * mChannelCount); 323998ef978df4e928f486d244c4d7f7ad9f13111e98Andy Hung } 324098ef978df4e928f486d244c4d7f7ad9f13111e98Andy Hung 324181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // enable changes in effect chain 324281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent unlockEffectChains(effectChains); 324381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 3244bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent if (!waitingAsyncCallback()) { 3245ad9cb8b88e4f8face23f01d8dc89fa769dacb50fEric Laurent // mSleepTimeUs == 0 means we must write to audio hardware 3246ad9cb8b88e4f8face23f01d8dc89fa769dacb50fEric Laurent if (mSleepTimeUs == 0) { 324708fb1743f80437c38b4094070d851ea7f6d485e5Andy Hung ssize_t ret = 0; 324869488c4ef115c9de52c85f4fcae27c7774720298Andy Hung // We save lastWriteFinished here, as previousLastWriteFinished, 324969488c4ef115c9de52c85f4fcae27c7774720298Andy Hung // for throttling. On thread start, previousLastWriteFinished will be 325069488c4ef115c9de52c85f4fcae27c7774720298Andy Hung // set to -1, which properly results in no throttling after the first write. 325169488c4ef115c9de52c85f4fcae27c7774720298Andy Hung nsecs_t previousLastWriteFinished = lastWriteFinished; 325269488c4ef115c9de52c85f4fcae27c7774720298Andy Hung nsecs_t delta = 0; 3253bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent if (mBytesRemaining) { 325469488c4ef115c9de52c85f4fcae27c7774720298Andy Hung // FIXME rewrite to reduce number of system calls 325569488c4ef115c9de52c85f4fcae27c7774720298Andy Hung mLastWriteTime = systemTime(); // also used for dumpsys 325608fb1743f80437c38b4094070d851ea7f6d485e5Andy Hung ret = threadLoop_write(); 325769488c4ef115c9de52c85f4fcae27c7774720298Andy Hung lastWriteFinished = systemTime(); 325869488c4ef115c9de52c85f4fcae27c7774720298Andy Hung delta = lastWriteFinished - mLastWriteTime; 3259bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent if (ret < 0) { 3260bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent mBytesRemaining = 0; 3261bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent } else { 3262bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent mBytesWritten += ret; 3263bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent mBytesRemaining -= ret; 3264c54b1ffc92b8ad27608a8af21033d7cab33cb3a0Andy Hung mFramesWritten += ret / mFrameSize; 3265bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent } 3266bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent } else if ((mMixerStatus == MIXER_DRAIN_TRACK) || 3267bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent (mMixerStatus == MIXER_DRAIN_ALL)) { 3268bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent threadLoop_drain(); 3269bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent } 327008fb1743f80437c38b4094070d851ea7f6d485e5Andy Hung if (mType == MIXER && !mStandby) { 32714944acb7355b3aa25748fd25945a363a69d65444Glenn Kasten // write blocked detection 327208fb1743f80437c38b4094070d851ea7f6d485e5Andy Hung if (delta > maxPeriod) { 32734944acb7355b3aa25748fd25945a363a69d65444Glenn Kasten mNumDelayedWrites++; 327469488c4ef115c9de52c85f4fcae27c7774720298Andy Hung if ((lastWriteFinished - lastWarning) > kWarningThrottleNs) { 32754944acb7355b3aa25748fd25945a363a69d65444Glenn Kasten ATRACE_NAME("underrun"); 32764944acb7355b3aa25748fd25945a363a69d65444Glenn Kasten ALOGW("write blocked for %llu msecs, %d delayed writes, thread %p", 3277c42e9b462661673dff480ee71757a58b0f806370Glenn Kasten (unsigned long long) ns2ms(delta), mNumDelayedWrites, this); 327869488c4ef115c9de52c85f4fcae27c7774720298Andy Hung lastWarning = lastWriteFinished; 32794944acb7355b3aa25748fd25945a363a69d65444Glenn Kasten } 3280bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent } 328108fb1743f80437c38b4094070d851ea7f6d485e5Andy Hung 328208fb1743f80437c38b4094070d851ea7f6d485e5Andy Hung if (mThreadThrottle 328308fb1743f80437c38b4094070d851ea7f6d485e5Andy Hung && mMixerStatus == MIXER_TRACKS_READY // we are mixing (active tracks) 328408fb1743f80437c38b4094070d851ea7f6d485e5Andy Hung && ret > 0) { // we wrote something 328508fb1743f80437c38b4094070d851ea7f6d485e5Andy Hung // Limit MixerThread data processing to no more than twice the 328608fb1743f80437c38b4094070d851ea7f6d485e5Andy Hung // expected processing rate. 328708fb1743f80437c38b4094070d851ea7f6d485e5Andy Hung // 328808fb1743f80437c38b4094070d851ea7f6d485e5Andy Hung // This helps prevent underruns with NuPlayer and other applications 328908fb1743f80437c38b4094070d851ea7f6d485e5Andy Hung // which may set up buffers that are close to the minimum size, or use 329008fb1743f80437c38b4094070d851ea7f6d485e5Andy Hung // deep buffers, and rely on a double-buffering sleep strategy to fill. 329108fb1743f80437c38b4094070d851ea7f6d485e5Andy Hung // 329208fb1743f80437c38b4094070d851ea7f6d485e5Andy Hung // The throttle smooths out sudden large data drains from the device, 329308fb1743f80437c38b4094070d851ea7f6d485e5Andy Hung // e.g. when it comes out of standby, which often causes problems with 329408fb1743f80437c38b4094070d851ea7f6d485e5Andy Hung // (1) mixer threads without a fast mixer (which has its own warm-up) 329508fb1743f80437c38b4094070d851ea7f6d485e5Andy Hung // (2) minimum buffer sized tracks (even if the track is full, 329608fb1743f80437c38b4094070d851ea7f6d485e5Andy Hung // the app won't fill fast enough to handle the sudden draw). 3297f92b2175cd4a8d0fa9aca6e660ed4e85f6b7078bHaynes Mathew George // 3298f92b2175cd4a8d0fa9aca6e660ed4e85f6b7078bHaynes Mathew George // Total time spent in last processing cycle equals time spent in 3299f92b2175cd4a8d0fa9aca6e660ed4e85f6b7078bHaynes Mathew George // 1. threadLoop_write, as well as time spent in 3300f92b2175cd4a8d0fa9aca6e660ed4e85f6b7078bHaynes Mathew George // 2. threadLoop_mix (significant for heavy mixing, especially 3301f92b2175cd4a8d0fa9aca6e660ed4e85f6b7078bHaynes Mathew George // on low tier processors) 330208fb1743f80437c38b4094070d851ea7f6d485e5Andy Hung 330369488c4ef115c9de52c85f4fcae27c7774720298Andy Hung // it's OK if deltaMs is an overestimate. 330469488c4ef115c9de52c85f4fcae27c7774720298Andy Hung const int32_t deltaMs = 330569488c4ef115c9de52c85f4fcae27c7774720298Andy Hung (lastWriteFinished - previousLastWriteFinished) / 1000000; 330608fb1743f80437c38b4094070d851ea7f6d485e5Andy Hung const int32_t throttleMs = mHalfBufferMs - deltaMs; 330708fb1743f80437c38b4094070d851ea7f6d485e5Andy Hung if ((signed)mHalfBufferMs >= throttleMs && throttleMs > 0) { 330808fb1743f80437c38b4094070d851ea7f6d485e5Andy Hung usleep(throttleMs * 1000); 330940eb1a1f8871909c272e72afaf7d5af84fea2412Andy Hung // notify of throttle start on verbose log 331040eb1a1f8871909c272e72afaf7d5af84fea2412Andy Hung ALOGV_IF(mThreadThrottleEndMs == mThreadThrottleTimeMs, 331140eb1a1f8871909c272e72afaf7d5af84fea2412Andy Hung "mixer(%p) throttle begin:" 331240eb1a1f8871909c272e72afaf7d5af84fea2412Andy Hung " ret(%zd) deltaMs(%d) requires sleep %d ms", 331308fb1743f80437c38b4094070d851ea7f6d485e5Andy Hung this, ret, deltaMs, throttleMs); 331440eb1a1f8871909c272e72afaf7d5af84fea2412Andy Hung mThreadThrottleTimeMs += throttleMs; 33150a31dddf67e739684f60aecc85311ff446fb68f9Andy Hung // Throttle must be attributed to the previous mixer loop's write time 33160a31dddf67e739684f60aecc85311ff446fb68f9Andy Hung // to allow back-to-back throttling. 33170a31dddf67e739684f60aecc85311ff446fb68f9Andy Hung lastWriteFinished += throttleMs * 1000000; 331840eb1a1f8871909c272e72afaf7d5af84fea2412Andy Hung } else { 331940eb1a1f8871909c272e72afaf7d5af84fea2412Andy Hung uint32_t diff = mThreadThrottleTimeMs - mThreadThrottleEndMs; 332040eb1a1f8871909c272e72afaf7d5af84fea2412Andy Hung if (diff > 0) { 332140eb1a1f8871909c272e72afaf7d5af84fea2412Andy Hung // notify of throttle end on debug log 33223ea004dd80c06c5b366e1a2547ea9b28fffc1865Andy Hung // but prevent spamming for bluetooth 33233ea004dd80c06c5b366e1a2547ea9b28fffc1865Andy Hung ALOGD_IF(!audio_is_a2dp_out_device(outDevice()), 33243ea004dd80c06c5b366e1a2547ea9b28fffc1865Andy Hung "mixer(%p) throttle end: throttle time(%u)", this, diff); 332540eb1a1f8871909c272e72afaf7d5af84fea2412Andy Hung mThreadThrottleEndMs = mThreadThrottleTimeMs; 332640eb1a1f8871909c272e72afaf7d5af84fea2412Andy Hung } 332708fb1743f80437c38b4094070d851ea7f6d485e5Andy Hung } 332808fb1743f80437c38b4094070d851ea7f6d485e5Andy Hung } 332981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 333081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 3331bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent } else { 3332e77540228e1f60b1129a1615d2e43e0bf8015d3cGlenn Kasten ATRACE_BEGIN("sleep"); 3333e93cc03da360a1a0d2ad937c745ce8c8e8be81c2Eric Laurent Mutex::Autolock _l(mLock); 33341bb9082596c9cac2995dc9b4465a7c6d5666d099rago // suspended requires accurate metering of sleep time. 33351bb9082596c9cac2995dc9b4465a7c6d5666d099rago if (isSuspended()) { 33361bb9082596c9cac2995dc9b4465a7c6d5666d099rago // advance by expected sleepTime 33371bb9082596c9cac2995dc9b4465a7c6d5666d099rago timeLoopNextNs += microseconds((nsecs_t)mSleepTimeUs); 33381bb9082596c9cac2995dc9b4465a7c6d5666d099rago const nsecs_t nowNs = systemTime(); 33391bb9082596c9cac2995dc9b4465a7c6d5666d099rago 33401bb9082596c9cac2995dc9b4465a7c6d5666d099rago // compute expected next time vs current time. 33411bb9082596c9cac2995dc9b4465a7c6d5666d099rago // (negative deltas are treated as delays). 33421bb9082596c9cac2995dc9b4465a7c6d5666d099rago nsecs_t deltaNs = timeLoopNextNs - nowNs; 33431bb9082596c9cac2995dc9b4465a7c6d5666d099rago if (deltaNs < -kMaxNextBufferDelayNs) { 33441bb9082596c9cac2995dc9b4465a7c6d5666d099rago // Delays longer than the max allowed trigger a reset. 33451bb9082596c9cac2995dc9b4465a7c6d5666d099rago ALOGV("DelayNs: %lld, resetting timeLoopNextNs", (long long) deltaNs); 33461bb9082596c9cac2995dc9b4465a7c6d5666d099rago deltaNs = microseconds((nsecs_t)mSleepTimeUs); 33471bb9082596c9cac2995dc9b4465a7c6d5666d099rago timeLoopNextNs = nowNs + deltaNs; 33481bb9082596c9cac2995dc9b4465a7c6d5666d099rago } else if (deltaNs < 0) { 33491bb9082596c9cac2995dc9b4465a7c6d5666d099rago // Delays within the max delay allowed: zero the delta/sleepTime 33501bb9082596c9cac2995dc9b4465a7c6d5666d099rago // to help the system catch up in the next iteration(s) 33511bb9082596c9cac2995dc9b4465a7c6d5666d099rago ALOGV("DelayNs: %lld, catching-up", (long long) deltaNs); 33521bb9082596c9cac2995dc9b4465a7c6d5666d099rago deltaNs = 0; 33531bb9082596c9cac2995dc9b4465a7c6d5666d099rago } 33541bb9082596c9cac2995dc9b4465a7c6d5666d099rago // update sleep time (which is >= 0) 33551bb9082596c9cac2995dc9b4465a7c6d5666d099rago mSleepTimeUs = deltaNs / 1000; 33561bb9082596c9cac2995dc9b4465a7c6d5666d099rago } 3357e93cc03da360a1a0d2ad937c745ce8c8e8be81c2Eric Laurent if (!mSignalPending && mConfigEvents.isEmpty() && !exitPending()) { 3358e93cc03da360a1a0d2ad937c745ce8c8e8be81c2Eric Laurent mWaitWorkCV.waitRelative(mLock, microseconds((nsecs_t)mSleepTimeUs)); 3359517161856d74f5fe39cce131f29b977bc1745991Eric Laurent } 3360e77540228e1f60b1129a1615d2e43e0bf8015d3cGlenn Kasten ATRACE_END(); 3361bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent } 336281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 336381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 336481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // Finally let go of removed track(s), without the lock held 336581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // since we can't guarantee the destructors won't acquire that 336681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // same lock. This will also mutate and push a new fast mixer state. 336781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent threadLoop_removeTracks(tracksToRemove); 336881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent tracksToRemove.clear(); 336981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 337081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // FIXME I don't understand the need for this here; 337181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // it was in the original code but maybe the 337281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // assignment in saveOutputTracks() makes this unnecessary? 337381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent clearOutputTracks(); 337481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 337581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // Effect chains will be actually deleted here if they were removed from 337681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // mEffectChains list during mixing or effects processing 337781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent effectChains.clear(); 337881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 337981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // FIXME Note that the above .clear() is no longer necessary since effectChains 338081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // is now local to this block, but will keep it for now (at least until merge done). 338181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 338281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 3383bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent threadLoop_exit(); 3384bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent 3385cf817a2330936947df94c11859f48771f5596a59Eric Laurent if (!mStandby) { 3386cf817a2330936947df94c11859f48771f5596a59Eric Laurent threadLoop_standby(); 3387cf817a2330936947df94c11859f48771f5596a59Eric Laurent mStandby = true; 338881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 338981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 339081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent releaseWakeLock(); 339181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 339281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent ALOGV("Thread %p type %d exiting", this, mType); 339381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent return false; 339481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 339581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 3396bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent// removeTracks_l() must be called with ThreadBase::mLock held 3397bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurentvoid AudioFlinger::PlaybackThread::removeTracks_l(const Vector< sp<Track> >& tracksToRemove) 3398bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent{ 3399bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent size_t count = tracksToRemove.size(); 340034fca34606b448e6b71c2942f63cb13a0aebd620Glenn Kasten if (count > 0) { 3401bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent for (size_t i=0 ; i<count ; i++) { 3402bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent const sp<Track>& track = tracksToRemove.itemAt(i); 3403bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent mActiveTracks.remove(track); 3404bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent ALOGV("removeTracks_l removing track on session %d", track->sessionId()); 3405bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent sp<EffectChain> chain = getEffectChain_l(track->sessionId()); 3406bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent if (chain != 0) { 3407bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent ALOGV("stopping track on chain %p for session Id: %d", chain.get(), 3408bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent track->sessionId()); 3409bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent chain->decActiveTrackCnt(); 3410bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent } 3411bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent if (track->isTerminated()) { 3412bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent removeTrack_l(track); 34132148bf0e79c436b8764b9edc4c8f2730cce98a32Andy Hung } else { // inactive but not terminated 34142148bf0e79c436b8764b9edc4c8f2730cce98a32Andy Hung char buffer[256]; 34152148bf0e79c436b8764b9edc4c8f2730cce98a32Andy Hung track->dump(buffer, ARRAY_SIZE(buffer), false /* active */); 34162148bf0e79c436b8764b9edc4c8f2730cce98a32Andy Hung mLocalLog.log("removeTracks_l(%p) %s", track.get(), buffer + 4); 3417bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent } 3418bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent } 3419bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent } 3420bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent 3421bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent} 342281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 3423accc147666bfd37fc8b4ef745f18a8c751555ec2Eric Laurentstatus_t AudioFlinger::PlaybackThread::getTimestamp_l(AudioTimestamp& timestamp) 3424accc147666bfd37fc8b4ef745f18a8c751555ec2Eric Laurent{ 3425accc147666bfd37fc8b4ef745f18a8c751555ec2Eric Laurent if (mNormalSink != 0) { 3426818e7a32ce3633980138aff2c2bfcc5158b3cfccAndy Hung ExtendedTimestamp ets; 3427818e7a32ce3633980138aff2c2bfcc5158b3cfccAndy Hung status_t status = mNormalSink->getTimestamp(ets); 3428818e7a32ce3633980138aff2c2bfcc5158b3cfccAndy Hung if (status == NO_ERROR) { 3429818e7a32ce3633980138aff2c2bfcc5158b3cfccAndy Hung status = ets.getBestTimestamp(×tamp); 3430818e7a32ce3633980138aff2c2bfcc5158b3cfccAndy Hung } 3431818e7a32ce3633980138aff2c2bfcc5158b3cfccAndy Hung return status; 3432accc147666bfd37fc8b4ef745f18a8c751555ec2Eric Laurent } 34331dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov if ((mType == OFFLOAD || mType == DIRECT) && mOutput != NULL) { 3434accc147666bfd37fc8b4ef745f18a8c751555ec2Eric Laurent uint64_t position64; 34351dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov if (mOutput->getPresentationPosition(&position64, ×tamp.mTime) == OK) { 3436accc147666bfd37fc8b4ef745f18a8c751555ec2Eric Laurent timestamp.mPosition = (uint32_t)position64; 3437accc147666bfd37fc8b4ef745f18a8c751555ec2Eric Laurent return NO_ERROR; 3438accc147666bfd37fc8b4ef745f18a8c751555ec2Eric Laurent } 3439accc147666bfd37fc8b4ef745f18a8c751555ec2Eric Laurent } 3440accc147666bfd37fc8b4ef745f18a8c751555ec2Eric Laurent return INVALID_OPERATION; 3441accc147666bfd37fc8b4ef745f18a8c751555ec2Eric Laurent} 34421c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent 3443054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurentstatus_t AudioFlinger::MixerThread::createAudioPatch_l(const struct audio_patch *patch, 3444054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurent audio_patch_handle_t *handle) 3445054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurent{ 3446f60abceac70c7a30dc2f888c4b80256b4a01a6ddAndy Hung status_t status; 3447f60abceac70c7a30dc2f888c4b80256b4a01a6ddAndy Hung if (property_get_bool("af.patch_park", false /* default_value */)) { 3448f60abceac70c7a30dc2f888c4b80256b4a01a6ddAndy Hung // Park FastMixer to avoid potential DOS issues with writing to the HAL 3449f60abceac70c7a30dc2f888c4b80256b4a01a6ddAndy Hung // or if HAL does not properly lock against access. 3450f60abceac70c7a30dc2f888c4b80256b4a01a6ddAndy Hung AutoPark<FastMixer> park(mFastMixer); 3451f60abceac70c7a30dc2f888c4b80256b4a01a6ddAndy Hung status = PlaybackThread::createAudioPatch_l(patch, handle); 3452f60abceac70c7a30dc2f888c4b80256b4a01a6ddAndy Hung } else { 3453f60abceac70c7a30dc2f888c4b80256b4a01a6ddAndy Hung status = PlaybackThread::createAudioPatch_l(patch, handle); 3454f60abceac70c7a30dc2f888c4b80256b4a01a6ddAndy Hung } 3455054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurent return status; 3456054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurent} 3457054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurent 34581c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurentstatus_t AudioFlinger::PlaybackThread::createAudioPatch_l(const struct audio_patch *patch, 34591c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent audio_patch_handle_t *handle) 34601c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent{ 34611c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent status_t status = NO_ERROR; 3462054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurent 3463054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurent // store new device and send to effects 3464054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurent audio_devices_t type = AUDIO_DEVICE_NONE; 3465054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurent for (unsigned int i = 0; i < patch->num_sinks; i++) { 3466054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurent type |= patch->sinks[i].ext.device.type; 3467054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurent } 3468054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurent 3469054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurent#ifdef ADD_BATTERY_DATA 3470054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurent // when changing the audio output device, call addBatteryData to notify 3471054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurent // the change 3472054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurent if (mOutDevice != type) { 3473054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurent uint32_t params = 0; 3474054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurent // check whether speaker is on 3475054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurent if (type & AUDIO_DEVICE_OUT_SPEAKER) { 3476054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurent params |= IMediaPlayerService::kBatteryDataSpeakerOn; 34771c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent } 3478054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurent 3479054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurent audio_devices_t deviceWithoutSpeaker 3480054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurent = AUDIO_DEVICE_OUT_ALL & ~AUDIO_DEVICE_OUT_SPEAKER; 3481054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurent // check if any other device (except speaker) is on 3482054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurent if (type & deviceWithoutSpeaker) { 3483054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurent params |= IMediaPlayerService::kBatteryDataOtherAudioDeviceOn; 3484054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurent } 3485054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurent 3486054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurent if (params != 0) { 3487054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurent addBatteryData(params); 34881c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent } 3489054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurent } 3490054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurent#endif 34911c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent 3492054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurent for (size_t i = 0; i < mEffectChains.size(); i++) { 3493054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurent mEffectChains[i]->setDevice_l(type); 3494054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurent } 34957c1ec5f038e63a5eb8b04434577c25bc23f5f410Eric Laurent 34967c1ec5f038e63a5eb8b04434577c25bc23f5f410Eric Laurent // mPrevOutDevice is the latest device set by createAudioPatch_l(). It is not set when 34977c1ec5f038e63a5eb8b04434577c25bc23f5f410Eric Laurent // the thread is created so that the first patch creation triggers an ioConfigChanged callback 34987c1ec5f038e63a5eb8b04434577c25bc23f5f410Eric Laurent bool configChanged = mPrevOutDevice != type; 3499054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurent mOutDevice = type; 3500296fb13dd9b5e90d6a05cce897c3b1e7914a478aEric Laurent mPatch = *patch; 3501054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurent 35029ee0540d3a61bff03d561ca431a371c3d9335d2bMikhail Naganov if (mOutput->audioHwDev->supportsAudioPatches()) { 3503e4f1f63a2c54ee8687ad8cca18df0f6639ad7c81Mikhail Naganov sp<DeviceHalInterface> hwDevice = mOutput->audioHwDev->hwDevice(); 3504e4f1f63a2c54ee8687ad8cca18df0f6639ad7c81Mikhail Naganov status = hwDevice->createAudioPatch(patch->num_sources, 3505e4f1f63a2c54ee8687ad8cca18df0f6639ad7c81Mikhail Naganov patch->sources, 3506e4f1f63a2c54ee8687ad8cca18df0f6639ad7c81Mikhail Naganov patch->num_sinks, 3507e4f1f63a2c54ee8687ad8cca18df0f6639ad7c81Mikhail Naganov patch->sinks, 3508e4f1f63a2c54ee8687ad8cca18df0f6639ad7c81Mikhail Naganov handle); 35091c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent } else { 3510054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurent char *address; 3511054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurent if (strcmp(patch->sinks[0].ext.device.address, "") != 0) { 3512054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurent //FIXME: we only support address on first sink with HAL version < 3.0 3513054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurent address = audio_device_address_to_parameter( 3514054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurent patch->sinks[0].ext.device.type, 3515054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurent patch->sinks[0].ext.device.address); 3516054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurent } else { 3517054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurent address = (char *)calloc(1, 1); 3518054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurent } 3519054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurent AudioParameter param = AudioParameter(String8(address)); 3520054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurent free(address); 352100260b5e6996b0a4b12f71c5b84e44adea040534Mikhail Naganov param.addInt(String8(AudioParameter::keyRouting), (int)type); 35221dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov status = mOutput->stream->setParameters(param.toString()); 3523054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurent *handle = AUDIO_PATCH_HANDLE_NONE; 3524054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurent } 3525e8726fea8a53bf3474aa3c6deaf2f6c1f565e694Eric Laurent if (configChanged) { 35267c1ec5f038e63a5eb8b04434577c25bc23f5f410Eric Laurent mPrevOutDevice = type; 3527e8726fea8a53bf3474aa3c6deaf2f6c1f565e694Eric Laurent sendIoConfigEvent_l(AUDIO_OUTPUT_CONFIG_CHANGED); 3528e8726fea8a53bf3474aa3c6deaf2f6c1f565e694Eric Laurent } 3529054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurent return status; 3530054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurent} 3531054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurent 3532054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurentstatus_t AudioFlinger::MixerThread::releaseAudioPatch_l(const audio_patch_handle_t handle) 3533054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurent{ 3534f60abceac70c7a30dc2f888c4b80256b4a01a6ddAndy Hung status_t status; 3535f60abceac70c7a30dc2f888c4b80256b4a01a6ddAndy Hung if (property_get_bool("af.patch_park", false /* default_value */)) { 3536f60abceac70c7a30dc2f888c4b80256b4a01a6ddAndy Hung // Park FastMixer to avoid potential DOS issues with writing to the HAL 3537f60abceac70c7a30dc2f888c4b80256b4a01a6ddAndy Hung // or if HAL does not properly lock against access. 3538f60abceac70c7a30dc2f888c4b80256b4a01a6ddAndy Hung AutoPark<FastMixer> park(mFastMixer); 3539f60abceac70c7a30dc2f888c4b80256b4a01a6ddAndy Hung status = PlaybackThread::releaseAudioPatch_l(handle); 3540f60abceac70c7a30dc2f888c4b80256b4a01a6ddAndy Hung } else { 3541f60abceac70c7a30dc2f888c4b80256b4a01a6ddAndy Hung status = PlaybackThread::releaseAudioPatch_l(handle); 3542f60abceac70c7a30dc2f888c4b80256b4a01a6ddAndy Hung } 35431c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent return status; 35441c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent} 35451c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent 35461c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurentstatus_t AudioFlinger::PlaybackThread::releaseAudioPatch_l(const audio_patch_handle_t handle) 35471c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent{ 35481c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent status_t status = NO_ERROR; 3549054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurent 3550054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurent mOutDevice = AUDIO_DEVICE_NONE; 3551054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurent 35529ee0540d3a61bff03d561ca431a371c3d9335d2bMikhail Naganov if (mOutput->audioHwDev->supportsAudioPatches()) { 3553e4f1f63a2c54ee8687ad8cca18df0f6639ad7c81Mikhail Naganov sp<DeviceHalInterface> hwDevice = mOutput->audioHwDev->hwDevice(); 3554e4f1f63a2c54ee8687ad8cca18df0f6639ad7c81Mikhail Naganov status = hwDevice->releaseAudioPatch(handle); 35551c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent } else { 3556054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurent AudioParameter param; 355700260b5e6996b0a4b12f71c5b84e44adea040534Mikhail Naganov param.addInt(String8(AudioParameter::keyRouting), 0); 35581dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov status = mOutput->stream->setParameters(param.toString()); 35591c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent } 35601c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent return status; 35611c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent} 35621c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent 356383b8808faad1e91690c64d7007348be8d9ebde73Eric Laurentvoid AudioFlinger::PlaybackThread::addPatchTrack(const sp<PatchTrack>& track) 356483b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent{ 356583b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent Mutex::Autolock _l(mLock); 356683b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent mTracks.add(track); 356783b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent} 356883b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent 356983b8808faad1e91690c64d7007348be8d9ebde73Eric Laurentvoid AudioFlinger::PlaybackThread::deletePatchTrack(const sp<PatchTrack>& track) 357083b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent{ 357183b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent Mutex::Autolock _l(mLock); 357283b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent destroyTrack_l(track); 357383b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent} 357483b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent 357583b8808faad1e91690c64d7007348be8d9ebde73Eric Laurentvoid AudioFlinger::PlaybackThread::getAudioPortConfig(struct audio_port_config *config) 357683b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent{ 357783b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent ThreadBase::getAudioPortConfig(config); 357883b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent config->role = AUDIO_PORT_ROLE_SOURCE; 357983b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent config->ext.mix.hw_module = mOutput->audioHwDev->handle(); 358083b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent config->ext.mix.usecase.stream = AUDIO_STREAM_DEFAULT; 358183b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent} 358283b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent 358381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// ---------------------------------------------------------------------------- 358481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 358581784c37c61b09289654b979567a42bf73cd2b12Eric LaurentAudioFlinger::MixerThread::MixerThread(const sp<AudioFlinger>& audioFlinger, AudioStreamOut* output, 358672e3f39146fce4686bd96f11057c051bea376dfbEric Laurent audio_io_handle_t id, audio_devices_t device, bool systemReady, type_t type) 358772e3f39146fce4686bd96f11057c051bea376dfbEric Laurent : PlaybackThread(audioFlinger, output, id, device, type, systemReady), 358881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // mAudioMixer below 358981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // mFastMixer below 35902ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hung mFastMixerFutex(0), 35912ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hung mMasterMono(false) 359281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // mOutputSink below 359381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // mPipeSink below 359481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // mNormalSink below 359581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 359681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent ALOGV("MixerThread() id=%d device=%#x type=%d", id, device, type); 3597c42e9b462661673dff480ee71757a58b0f806370Glenn Kasten ALOGV("mSampleRate=%u, mChannelMask=%#x, mChannelCount=%u, mFormat=%d, mFrameSize=%zu, " 3598c42e9b462661673dff480ee71757a58b0f806370Glenn Kasten "mFrameCount=%zu, mNormalFrameCount=%zu", 359981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mSampleRate, mChannelMask, mChannelCount, mFormat, mFrameSize, mFrameCount, 360081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mNormalFrameCount); 360181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mAudioMixer = new AudioMixer(mNormalFrameCount, mSampleRate); 360281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 3603fbfc3959f4aac839445edc7075532067fef497c2Andy Hung if (type == DUPLICATING) { 3604fbfc3959f4aac839445edc7075532067fef497c2Andy Hung // The Duplicating thread uses the AudioMixer and delivers data to OutputTracks 3605fbfc3959f4aac839445edc7075532067fef497c2Andy Hung // (downstream MixerThreads) in DuplicatingThread::threadLoop_write(). 3606fbfc3959f4aac839445edc7075532067fef497c2Andy Hung // Do not create or use mFastMixer, mOutputSink, mPipeSink, or mNormalSink. 3607fbfc3959f4aac839445edc7075532067fef497c2Andy Hung return; 3608fbfc3959f4aac839445edc7075532067fef497c2Andy Hung } 360981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // create an NBAIO sink for the HAL output stream, and negotiate 3610a0c91339814f37ea78365afb436c9f3d1f0a0090Mikhail Naganov mOutputSink = new AudioStreamOutSink(output->stream); 361181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent size_t numCounterOffers = 0; 3612f69f9869514730aebe5724c461768507084dfff7Glenn Kasten const NBAIO_Format offers[1] = {Format_from_SR_C(mSampleRate, mChannelCount, mFormat)}; 361357c4e6f7464d458eb52d209c2a63524913d6406dGlenn Kasten#if !LOG_NDEBUG 361457c4e6f7464d458eb52d209c2a63524913d6406dGlenn Kasten ssize_t index = 361557c4e6f7464d458eb52d209c2a63524913d6406dGlenn Kasten#else 361657c4e6f7464d458eb52d209c2a63524913d6406dGlenn Kasten (void) 361757c4e6f7464d458eb52d209c2a63524913d6406dGlenn Kasten#endif 361857c4e6f7464d458eb52d209c2a63524913d6406dGlenn Kasten mOutputSink->negotiate(offers, 1, NULL, numCounterOffers); 361981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent ALOG_ASSERT(index == 0); 362081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 362181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // initialize fast mixer depending on configuration 362281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent bool initFastMixer; 362381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent switch (kUseFastMixer) { 362481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent case FastMixer_Never: 362581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent initFastMixer = false; 362681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent break; 362781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent case FastMixer_Always: 362881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent initFastMixer = true; 362981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent break; 363081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent case FastMixer_Static: 363181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent case FastMixer_Dynamic: 3632fda69406966f8578a7827e889bff615f0144b441Andy Hung // FastMixer was designed to operate with a HAL that pulls at a regular rate, 3633fda69406966f8578a7827e889bff615f0144b441Andy Hung // where the period is less than an experimentally determined threshold that can be 3634fda69406966f8578a7827e889bff615f0144b441Andy Hung // scheduled reliably with CFS. However, the BT A2DP HAL is 3635fda69406966f8578a7827e889bff615f0144b441Andy Hung // bursty (does not pull at a regular rate) and so cannot operate with FastMixer. 3636fda69406966f8578a7827e889bff615f0144b441Andy Hung initFastMixer = mFrameCount < mNormalFrameCount 3637fda69406966f8578a7827e889bff615f0144b441Andy Hung && (mOutDevice & AUDIO_DEVICE_OUT_ALL_A2DP) == 0; 363881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent break; 363981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 3640fda69406966f8578a7827e889bff615f0144b441Andy Hung ALOGW_IF(initFastMixer == false && mFrameCount < mNormalFrameCount, 3641fda69406966f8578a7827e889bff615f0144b441Andy Hung "FastMixer is preferred for this sink as frameCount %zu is less than threshold %zu", 3642fda69406966f8578a7827e889bff615f0144b441Andy Hung mFrameCount, mNormalFrameCount); 364381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (initFastMixer) { 36441258c1ab592a899fabb1e31eb5db2ef413b6f38aAndy Hung audio_format_t fastMixerFormat; 36451258c1ab592a899fabb1e31eb5db2ef413b6f38aAndy Hung if (mMixerBufferEnabled && mEffectBufferEnabled) { 36461258c1ab592a899fabb1e31eb5db2ef413b6f38aAndy Hung fastMixerFormat = AUDIO_FORMAT_PCM_FLOAT; 36471258c1ab592a899fabb1e31eb5db2ef413b6f38aAndy Hung } else { 36481258c1ab592a899fabb1e31eb5db2ef413b6f38aAndy Hung fastMixerFormat = AUDIO_FORMAT_PCM_16_BIT; 36491258c1ab592a899fabb1e31eb5db2ef413b6f38aAndy Hung } 36501258c1ab592a899fabb1e31eb5db2ef413b6f38aAndy Hung if (mFormat != fastMixerFormat) { 36511258c1ab592a899fabb1e31eb5db2ef413b6f38aAndy Hung // change our Sink format to accept our intermediate precision 36521258c1ab592a899fabb1e31eb5db2ef413b6f38aAndy Hung mFormat = fastMixerFormat; 36531258c1ab592a899fabb1e31eb5db2ef413b6f38aAndy Hung free(mSinkBuffer); 36541258c1ab592a899fabb1e31eb5db2ef413b6f38aAndy Hung mFrameSize = mChannelCount * audio_bytes_per_sample(mFormat); 36551258c1ab592a899fabb1e31eb5db2ef413b6f38aAndy Hung const size_t sinkBufferSize = mNormalFrameCount * mFrameSize; 36561258c1ab592a899fabb1e31eb5db2ef413b6f38aAndy Hung (void)posix_memalign(&mSinkBuffer, 32, sinkBufferSize); 36571258c1ab592a899fabb1e31eb5db2ef413b6f38aAndy Hung } 365881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 365981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // create a MonoPipe to connect our submix to FastMixer 366081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent NBAIO_Format format = mOutputSink->format(); 366157c4e6f7464d458eb52d209c2a63524913d6406dGlenn Kasten#ifdef TEE_SINK 3662ba0b34c18da93681c0813ecdab19b0e215b6d261Glenn Kasten NBAIO_Format origformat = format; 366357c4e6f7464d458eb52d209c2a63524913d6406dGlenn Kasten#endif 36641258c1ab592a899fabb1e31eb5db2ef413b6f38aAndy Hung // adjust format to match that of the Fast Mixer 366597b7b75b6a31330e213bdb96ccc60916218ad903Glenn Kasten ALOGV("format changed from %d to %d", format.mFormat, fastMixerFormat); 36661258c1ab592a899fabb1e31eb5db2ef413b6f38aAndy Hung format.mFormat = fastMixerFormat; 36671258c1ab592a899fabb1e31eb5db2ef413b6f38aAndy Hung format.mFrameSize = audio_bytes_per_sample(format.mFormat) * format.mChannelCount; 36681258c1ab592a899fabb1e31eb5db2ef413b6f38aAndy Hung 366981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // This pipe depth compensates for scheduling latency of the normal mixer thread. 367081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // When it wakes up after a maximum latency, it runs a few cycles quickly before 367181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // finally blocking. Note the pipe implementation rounds up the request to a power of 2. 367281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent MonoPipe *monoPipe = new MonoPipe(mNormalFrameCount * 4, format, true /*writeCanBlock*/); 367381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent const NBAIO_Format offers[1] = {format}; 367481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent size_t numCounterOffers = 0; 3675fc302fd9e2d2cbafef771de77c47799488e1c044Glenn Kasten#if !LOG_NDEBUG || defined(TEE_SINK) 367657c4e6f7464d458eb52d209c2a63524913d6406dGlenn Kasten ssize_t index = 367757c4e6f7464d458eb52d209c2a63524913d6406dGlenn Kasten#else 367857c4e6f7464d458eb52d209c2a63524913d6406dGlenn Kasten (void) 367957c4e6f7464d458eb52d209c2a63524913d6406dGlenn Kasten#endif 368057c4e6f7464d458eb52d209c2a63524913d6406dGlenn Kasten monoPipe->negotiate(offers, 1, NULL, numCounterOffers); 368181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent ALOG_ASSERT(index == 0); 368281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent monoPipe->setAvgFrames((mScreenState & 1) ? 368381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent (monoPipe->maxFrames() * 7) / 8 : mNormalFrameCount * 2); 368481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mPipeSink = monoPipe; 368581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 368646909e7eb074ce1b95b8a411eb71154f53f84f77Glenn Kasten#ifdef TEE_SINK 3687da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten if (mTeeSinkOutputEnabled) { 3688da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten // create a Pipe to archive a copy of FastMixer's output for dumpsys 3689ba0b34c18da93681c0813ecdab19b0e215b6d261Glenn Kasten Pipe *teeSink = new Pipe(mTeeSinkOutputFrames, origformat); 3690ba0b34c18da93681c0813ecdab19b0e215b6d261Glenn Kasten const NBAIO_Format offers2[1] = {origformat}; 3691da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten numCounterOffers = 0; 3692ba0b34c18da93681c0813ecdab19b0e215b6d261Glenn Kasten index = teeSink->negotiate(offers2, 1, NULL, numCounterOffers); 3693da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten ALOG_ASSERT(index == 0); 3694da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten mTeeSink = teeSink; 3695da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten PipeReader *teeSource = new PipeReader(*teeSink); 3696da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten numCounterOffers = 0; 3697ba0b34c18da93681c0813ecdab19b0e215b6d261Glenn Kasten index = teeSource->negotiate(offers2, 1, NULL, numCounterOffers); 3698da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten ALOG_ASSERT(index == 0); 3699da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten mTeeSource = teeSource; 3700da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten } 370146909e7eb074ce1b95b8a411eb71154f53f84f77Glenn Kasten#endif 370281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 370381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // create fast mixer and configure it initially with just one fast track for our submix 370481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mFastMixer = new FastMixer(); 370581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent FastMixerStateQueue *sq = mFastMixer->sq(); 370681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent#ifdef STATE_QUEUE_DUMP 370781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent sq->setObserverDump(&mStateQueueObserverDump); 370881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent sq->setMutatorDump(&mStateQueueMutatorDump); 370981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent#endif 371081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent FastMixerState *state = sq->begin(); 371181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent FastTrack *fastTrack = &state->mFastTracks[0]; 371281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // wrap the source side of the MonoPipe to make it an AudioBufferProvider 371381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent fastTrack->mBufferProvider = new SourceAudioBufferProvider(new MonoPipeReader(monoPipe)); 371481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent fastTrack->mVolumeProvider = NULL; 3715e8a1ced4da17dc6c07803dc2af8060f62a8389c1Andy Hung fastTrack->mChannelMask = mChannelMask; // mPipeSink channel mask for audio to FastMixer 3716e8a1ced4da17dc6c07803dc2af8060f62a8389c1Andy Hung fastTrack->mFormat = mFormat; // mPipeSink format for audio to FastMixer 371781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent fastTrack->mGeneration++; 371881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent state->mFastTracksGen++; 371981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent state->mTrackMask = 1; 372081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // fast mixer will use the HAL output sink 372181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent state->mOutputSink = mOutputSink.get(); 372281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent state->mOutputSinkGen++; 372381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent state->mFrameCount = mFrameCount; 372481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent state->mCommand = FastMixerState::COLD_IDLE; 372581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // already done in constructor initialization list 372681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent //mFastMixerFutex = 0; 372781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent state->mColdFutexAddr = &mFastMixerFutex; 372881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent state->mColdGen++; 372981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent state->mDumpState = &mFastMixerDumpState; 373046909e7eb074ce1b95b8a411eb71154f53f84f77Glenn Kasten#ifdef TEE_SINK 373181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent state->mTeeSink = mTeeSink.get(); 373246909e7eb074ce1b95b8a411eb71154f53f84f77Glenn Kasten#endif 37339e58b552f51b00b3b674102876bd6c77ef3da806Glenn Kasten mFastMixerNBLogWriter = audioFlinger->newWriter_l(kFastMixerLogSize, "FastMixer"); 37349e58b552f51b00b3b674102876bd6c77ef3da806Glenn Kasten state->mNBLogWriter = mFastMixerNBLogWriter.get(); 373581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent sq->end(); 373681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent sq->push(FastMixerStateQueue::BLOCK_UNTIL_PUSHED); 373781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 373881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // start the fast mixer 373981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mFastMixer->run("FastMixer", PRIORITY_URGENT_AUDIO); 374081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent pid_t tid = mFastMixer->getTid(); 374183f042776b131b149f803fff6ab184ae2c4d98cdMikhail Naganov sendPrioConfigEvent(getpid_cached, tid, kPriorityFastMixer, false); 3742e1c4b5d7a94c21b8ce0c5707b4af84de596fbb79Mikhail Naganov stream()->setHalThreadPriority(kPriorityFastMixer); 374381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 374481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent#ifdef AUDIO_WATCHDOG 374581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // create and start the watchdog 374681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mAudioWatchdog = new AudioWatchdog(); 374781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mAudioWatchdog->setDump(&mAudioWatchdogDump); 374881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mAudioWatchdog->run("AudioWatchdog", PRIORITY_URGENT_AUDIO); 374981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent tid = mAudioWatchdog->getTid(); 375072e3f39146fce4686bd96f11057c051bea376dfbEric Laurent sendPrioConfigEvent(getpid_cached, tid, kPriorityFastMixer); 375181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent#endif 375281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 375381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 375481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 375581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent switch (kUseFastMixer) { 375681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent case FastMixer_Never: 375781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent case FastMixer_Dynamic: 375881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mNormalSink = mOutputSink; 375981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent break; 376081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent case FastMixer_Always: 376181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mNormalSink = mPipeSink; 376281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent break; 376381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent case FastMixer_Static: 376481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mNormalSink = initFastMixer ? mPipeSink : mOutputSink; 376581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent break; 376681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 376781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 376881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 376981784c37c61b09289654b979567a42bf73cd2b12Eric LaurentAudioFlinger::MixerThread::~MixerThread() 377081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 37714d23ca370dd0ce584f49a80ef9dfcdbb75ba2c8eGlenn Kasten if (mFastMixer != 0) { 377281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent FastMixerStateQueue *sq = mFastMixer->sq(); 377381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent FastMixerState *state = sq->begin(); 377481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (state->mCommand == FastMixerState::COLD_IDLE) { 377581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent int32_t old = android_atomic_inc(&mFastMixerFutex); 377681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (old == -1) { 3777ee499291404a192b059f2e04c5afc65aa6cdd74cElliott Hughes (void) syscall(__NR_futex, &mFastMixerFutex, FUTEX_WAKE_PRIVATE, 1); 377881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 377981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 378081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent state->mCommand = FastMixerState::EXIT; 378181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent sq->end(); 378281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent sq->push(FastMixerStateQueue::BLOCK_UNTIL_PUSHED); 378381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mFastMixer->join(); 378481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // Though the fast mixer thread has exited, it's state queue is still valid. 378581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // We'll use that extract the final state which contains one remaining fast track 378681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // corresponding to our sub-mix. 378781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent state = sq->begin(); 378881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent ALOG_ASSERT(state->mTrackMask == 1); 378981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent FastTrack *fastTrack = &state->mFastTracks[0]; 379081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent ALOG_ASSERT(fastTrack->mBufferProvider != NULL); 379181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent delete fastTrack->mBufferProvider; 379281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent sq->end(false /*didModify*/); 37934d23ca370dd0ce584f49a80ef9dfcdbb75ba2c8eGlenn Kasten mFastMixer.clear(); 379481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent#ifdef AUDIO_WATCHDOG 379581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (mAudioWatchdog != 0) { 379681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mAudioWatchdog->requestExit(); 379781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mAudioWatchdog->requestExitAndWait(); 379881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mAudioWatchdog.clear(); 379981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 380081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent#endif 380181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 38029e58b552f51b00b3b674102876bd6c77ef3da806Glenn Kasten mAudioFlinger->unregisterWriter(mFastMixerNBLogWriter); 380381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent delete mAudioMixer; 380481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 380581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 380681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 380781784c37c61b09289654b979567a42bf73cd2b12Eric Laurentuint32_t AudioFlinger::MixerThread::correctLatency_l(uint32_t latency) const 380881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 38094d23ca370dd0ce584f49a80ef9dfcdbb75ba2c8eGlenn Kasten if (mFastMixer != 0) { 381081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent MonoPipe *pipe = (MonoPipe *)mPipeSink.get(); 381181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent latency += (pipe->getAvgFrames() * 1000) / mSampleRate; 381281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 381381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent return latency; 381481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 381581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 381681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 381781784c37c61b09289654b979567a42bf73cd2b12Eric Laurentvoid AudioFlinger::MixerThread::threadLoop_removeTracks(const Vector< sp<Track> >& tracksToRemove) 381881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 381981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent PlaybackThread::threadLoop_removeTracks(tracksToRemove); 382081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 382181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 3822bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurentssize_t AudioFlinger::MixerThread::threadLoop_write() 382381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 382481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // FIXME we should only do one push per cycle; confirm this is true 382581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // Start the fast mixer if it's not already running 38264d23ca370dd0ce584f49a80ef9dfcdbb75ba2c8eGlenn Kasten if (mFastMixer != 0) { 382781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent FastMixerStateQueue *sq = mFastMixer->sq(); 382881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent FastMixerState *state = sq->begin(); 382981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (state->mCommand != FastMixerState::MIX_WRITE && 383081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent (kUseFastMixer != FastMixer_Dynamic || state->mTrackMask > 1)) { 383181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (state->mCommand == FastMixerState::COLD_IDLE) { 3832a2ab4505c807f42afe34809409c4e85d91618a8cEric Laurent 3833a2ab4505c807f42afe34809409c4e85d91618a8cEric Laurent // FIXME workaround for first HAL write being CPU bound on some devices 3834a2ab4505c807f42afe34809409c4e85d91618a8cEric Laurent ATRACE_BEGIN("write"); 3835a2ab4505c807f42afe34809409c4e85d91618a8cEric Laurent mOutput->write((char *)mSinkBuffer, 0); 3836a2ab4505c807f42afe34809409c4e85d91618a8cEric Laurent ATRACE_END(); 3837a2ab4505c807f42afe34809409c4e85d91618a8cEric Laurent 383881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent int32_t old = android_atomic_inc(&mFastMixerFutex); 383981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (old == -1) { 3840ee499291404a192b059f2e04c5afc65aa6cdd74cElliott Hughes (void) syscall(__NR_futex, &mFastMixerFutex, FUTEX_WAKE_PRIVATE, 1); 384181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 384281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent#ifdef AUDIO_WATCHDOG 384381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (mAudioWatchdog != 0) { 384481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mAudioWatchdog->resume(); 384581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 384681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent#endif 384781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 384881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent state->mCommand = FastMixerState::MIX_WRITE; 3849d797a9d5daad3051f9ac1d348abc2f434ea3ddcfGlenn Kasten#ifdef FAST_THREAD_STATISTICS 38504182c4e2a07e2441fcd5c22eaff0ddfe7f826f61Glenn Kasten mFastMixerDumpState.increaseSamplingN(mAudioFlinger->isLowRamDevice() ? 3851fbdb2aceab7317aa44bc8f301a93eb49e17b2bceGlenn Kasten FastThreadDumpState::kSamplingNforLowRamDevice : FastThreadDumpState::kSamplingN); 3852d797a9d5daad3051f9ac1d348abc2f434ea3ddcfGlenn Kasten#endif 385381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent sq->end(); 385481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent sq->push(FastMixerStateQueue::BLOCK_UNTIL_PUSHED); 385581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (kUseFastMixer == FastMixer_Dynamic) { 385681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mNormalSink = mPipeSink; 385781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 385881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } else { 385981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent sq->end(false /*didModify*/); 386081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 386181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 3862bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent return PlaybackThread::threadLoop_write(); 386381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 386481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 386581784c37c61b09289654b979567a42bf73cd2b12Eric Laurentvoid AudioFlinger::MixerThread::threadLoop_standby() 386681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 386781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // Idle the fast mixer if it's currently running 38684d23ca370dd0ce584f49a80ef9dfcdbb75ba2c8eGlenn Kasten if (mFastMixer != 0) { 386981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent FastMixerStateQueue *sq = mFastMixer->sq(); 387081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent FastMixerState *state = sq->begin(); 387181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (!(state->mCommand & FastMixerState::IDLE)) { 38722148bf0e79c436b8764b9edc4c8f2730cce98a32Andy Hung // Report any frames trapped in the Monopipe 38732148bf0e79c436b8764b9edc4c8f2730cce98a32Andy Hung MonoPipe *monoPipe = (MonoPipe *)mPipeSink.get(); 38742148bf0e79c436b8764b9edc4c8f2730cce98a32Andy Hung const long long pipeFrames = monoPipe->maxFrames() - monoPipe->availableToWrite(); 38752148bf0e79c436b8764b9edc4c8f2730cce98a32Andy Hung mLocalLog.log("threadLoop_standby: framesWritten:%lld suspendedFrames:%lld " 38762148bf0e79c436b8764b9edc4c8f2730cce98a32Andy Hung "monoPipeWritten:%lld monoPipeLeft:%lld", 38772148bf0e79c436b8764b9edc4c8f2730cce98a32Andy Hung (long long)mFramesWritten, (long long)mSuspendedFrames, 38782148bf0e79c436b8764b9edc4c8f2730cce98a32Andy Hung (long long)mPipeSink->framesWritten(), pipeFrames); 38792148bf0e79c436b8764b9edc4c8f2730cce98a32Andy Hung mLocalLog.log("threadLoop_standby: %s", mTimestamp.toString().c_str()); 38802148bf0e79c436b8764b9edc4c8f2730cce98a32Andy Hung 388181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent state->mCommand = FastMixerState::COLD_IDLE; 388281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent state->mColdFutexAddr = &mFastMixerFutex; 388381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent state->mColdGen++; 388481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mFastMixerFutex = 0; 388581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent sq->end(); 388681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // BLOCK_UNTIL_PUSHED would be insufficient, as we need it to stop doing I/O now 388781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent sq->push(FastMixerStateQueue::BLOCK_UNTIL_ACKED); 388881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (kUseFastMixer == FastMixer_Dynamic) { 388981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mNormalSink = mOutputSink; 389081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 389181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent#ifdef AUDIO_WATCHDOG 389281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (mAudioWatchdog != 0) { 389381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mAudioWatchdog->pause(); 389481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 389581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent#endif 389681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } else { 389781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent sq->end(false /*didModify*/); 389881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 389981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 390081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent PlaybackThread::threadLoop_standby(); 390181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 390281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 3903bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurentbool AudioFlinger::PlaybackThread::waitingAsyncCallback_l() 3904bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent{ 3905bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent return false; 3906bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent} 3907bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent 3908bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurentbool AudioFlinger::PlaybackThread::shouldStandby_l() 3909bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent{ 3910bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent return !mStandby; 3911bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent} 3912bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent 3913bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurentbool AudioFlinger::PlaybackThread::waitingAsyncCallback() 3914bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent{ 3915bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent Mutex::Autolock _l(mLock); 3916bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent return waitingAsyncCallback_l(); 3917bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent} 3918bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent 391981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// shared by MIXER and DIRECT, overridden by DUPLICATING 392081784c37c61b09289654b979567a42bf73cd2b12Eric Laurentvoid AudioFlinger::PlaybackThread::threadLoop_standby() 392181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 392281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent ALOGV("Audio hardware entering standby, mixer %p, suspend count %d", this, mSuspended); 3923062e67a26e0553dd142be622821f493df541f0c6Phil Burk mOutput->standby(); 3924bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent if (mUseAsyncWrite != 0) { 39253b4529e03c5fc7a44c22f9091ad15a269bfca3a8Eric Laurent // discard any pending drain or write ack by incrementing sequence 39263b4529e03c5fc7a44c22f9091ad15a269bfca3a8Eric Laurent mWriteAckSequence = (mWriteAckSequence + 2) & ~1; 39273b4529e03c5fc7a44c22f9091ad15a269bfca3a8Eric Laurent mDrainSequence = (mDrainSequence + 2) & ~1; 3928bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent ALOG_ASSERT(mCallbackThread != 0); 39293b4529e03c5fc7a44c22f9091ad15a269bfca3a8Eric Laurent mCallbackThread->setWriteBlocked(mWriteAckSequence); 39303b4529e03c5fc7a44c22f9091ad15a269bfca3a8Eric Laurent mCallbackThread->setDraining(mDrainSequence); 3931bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent } 3932d1f69b0b17acbd96987ecb2f3378abd394d05903Eric Laurent mHwPaused = false; 393381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 393481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 39354c6a433d74d5ae8b9bc0557207e3ced43bf34a25Haynes Mathew Georgevoid AudioFlinger::PlaybackThread::onAddNewTrack_l() 39364c6a433d74d5ae8b9bc0557207e3ced43bf34a25Haynes Mathew George{ 39374c6a433d74d5ae8b9bc0557207e3ced43bf34a25Haynes Mathew George ALOGV("signal playback thread"); 39384c6a433d74d5ae8b9bc0557207e3ced43bf34a25Haynes Mathew George broadcast_l(); 39394c6a433d74d5ae8b9bc0557207e3ced43bf34a25Haynes Mathew George} 39404c6a433d74d5ae8b9bc0557207e3ced43bf34a25Haynes Mathew George 39414527b9ebc6a37b861f5a3bba68bcc63dc8d69adaHaynes Mathew Georgevoid AudioFlinger::PlaybackThread::onAsyncError() 39424527b9ebc6a37b861f5a3bba68bcc63dc8d69adaHaynes Mathew George{ 39434527b9ebc6a37b861f5a3bba68bcc63dc8d69adaHaynes Mathew George for (int i = AUDIO_STREAM_SYSTEM; i < (int)AUDIO_STREAM_CNT; i++) { 39444527b9ebc6a37b861f5a3bba68bcc63dc8d69adaHaynes Mathew George invalidateTracks((audio_stream_type_t)i); 39454527b9ebc6a37b861f5a3bba68bcc63dc8d69adaHaynes Mathew George } 39464527b9ebc6a37b861f5a3bba68bcc63dc8d69adaHaynes Mathew George} 39474527b9ebc6a37b861f5a3bba68bcc63dc8d69adaHaynes Mathew George 394881784c37c61b09289654b979567a42bf73cd2b12Eric Laurentvoid AudioFlinger::MixerThread::threadLoop_mix() 394981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 395081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // mix buffers... 3951d79072e9dff59f767cce2cda1caab80ce5a0815bGlenn Kasten mAudioMixer->process(); 395225c2dac12114699e90deb1c579cadebce7b91a97Andy Hung mCurrentWriteLength = mSinkBufferSize; 395381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // increase sleep time progressively when application underrun condition clears. 395481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // Only increase sleep time if the mixer is ready for two consecutive times to avoid 395581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // that a steady state of alternating ready/not ready conditions keeps the sleep time 395681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // such that we would underrun the audio HAL. 3957ad9cb8b88e4f8face23f01d8dc89fa769dacb50fEric Laurent if ((mSleepTimeUs == 0) && (sleepTimeShift > 0)) { 395881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent sleepTimeShift--; 395981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 3960ad9cb8b88e4f8face23f01d8dc89fa769dacb50fEric Laurent mSleepTimeUs = 0; 3961ad9cb8b88e4f8face23f01d8dc89fa769dacb50fEric Laurent mStandbyTimeNs = systemTime() + mStandbyDelayNs; 396281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent //TODO: delay standby when effects have a tail 39634c053ea158b29fa2cdd4c6f39d3c8da4ee5a7a02Glenn Kasten 396481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 396581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 396681784c37c61b09289654b979567a42bf73cd2b12Eric Laurentvoid AudioFlinger::MixerThread::threadLoop_sleepTime() 396781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 396881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // If no tracks are ready, sleep once for the duration of an output 396981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // buffer size, then write 0s to the output 3970ad9cb8b88e4f8face23f01d8dc89fa769dacb50fEric Laurent if (mSleepTimeUs == 0) { 397181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (mMixerStatus == MIXER_TRACKS_ENABLED) { 3972ad9cb8b88e4f8face23f01d8dc89fa769dacb50fEric Laurent mSleepTimeUs = mActiveSleepTimeUs >> sleepTimeShift; 3973ad9cb8b88e4f8face23f01d8dc89fa769dacb50fEric Laurent if (mSleepTimeUs < kMinThreadSleepTimeUs) { 3974ad9cb8b88e4f8face23f01d8dc89fa769dacb50fEric Laurent mSleepTimeUs = kMinThreadSleepTimeUs; 397581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 397681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // reduce sleep time in case of consecutive application underruns to avoid 397781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // starving the audio HAL. As activeSleepTimeUs() is larger than a buffer 397881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // duration we would end up writing less data than needed by the audio HAL if 397981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // the condition persists. 398081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (sleepTimeShift < kMaxThreadSleepTimeShift) { 398181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent sleepTimeShift++; 398281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 398381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } else { 3984ad9cb8b88e4f8face23f01d8dc89fa769dacb50fEric Laurent mSleepTimeUs = mIdleSleepTimeUs; 398581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 398681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } else if (mBytesWritten != 0 || (mMixerStatus == MIXER_TRACKS_ENABLED)) { 398798ef978df4e928f486d244c4d7f7ad9f13111e98Andy Hung // clear out mMixerBuffer or mSinkBuffer, to ensure buffers are cleared 398898ef978df4e928f486d244c4d7f7ad9f13111e98Andy Hung // before effects processing or output. 398998ef978df4e928f486d244c4d7f7ad9f13111e98Andy Hung if (mMixerBufferValid) { 399098ef978df4e928f486d244c4d7f7ad9f13111e98Andy Hung memset(mMixerBuffer, 0, mMixerBufferSize); 399198ef978df4e928f486d244c4d7f7ad9f13111e98Andy Hung } else { 399298ef978df4e928f486d244c4d7f7ad9f13111e98Andy Hung memset(mSinkBuffer, 0, mSinkBufferSize); 399398ef978df4e928f486d244c4d7f7ad9f13111e98Andy Hung } 3994ad9cb8b88e4f8face23f01d8dc89fa769dacb50fEric Laurent mSleepTimeUs = 0; 399581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent ALOGV_IF(mBytesWritten == 0 && (mMixerStatus == MIXER_TRACKS_ENABLED), 399681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent "anticipated start"); 399781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 399881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // TODO add standby time extension fct of effect tail 399981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 400081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 400181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// prepareTracks_l() must be called with ThreadBase::mLock held 400281784c37c61b09289654b979567a42bf73cd2b12Eric LaurentAudioFlinger::PlaybackThread::mixer_state AudioFlinger::MixerThread::prepareTracks_l( 400381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent Vector< sp<Track> > *tracksToRemove) 400481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 400581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 400681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mixer_state mixerStatus = MIXER_IDLE; 400781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // find out which tracks need to be processed 400881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent size_t count = mActiveTracks.size(); 400981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent size_t mixedTracks = 0; 401081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent size_t tracksWithEffect = 0; 401181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // counts only _active_ fast tracks 401281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent size_t fastTracks = 0; 401381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent uint32_t resetMask = 0; // bit mask of fast tracks that need to be reset 401481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 401581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent float masterVolume = mMasterVolume; 401681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent bool masterMute = mMasterMute; 401781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 401881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (masterMute) { 401981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent masterVolume = 0; 402081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 402181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // Delegate master volume control to effect in output mix effect chain if needed 402281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent sp<EffectChain> chain = getEffectChain_l(AUDIO_SESSION_OUTPUT_MIX); 402381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (chain != 0) { 402481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent uint32_t v = (uint32_t)(masterVolume * (1 << 24)); 402581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent chain->setVolume_l(&v, &v); 402681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent masterVolume = (float)((v + (1 << 23)) >> 24); 402781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent chain.clear(); 402881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 402981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 403081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // prepare a new state to push 403181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent FastMixerStateQueue *sq = NULL; 403281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent FastMixerState *state = NULL; 403381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent bool didModify = false; 403481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent FastMixerStateQueue::block_t block = FastMixerStateQueue::BLOCK_UNTIL_PUSHED; 4035f228531c5d01f497f5802c44545e0000ec44ab83Andy Hung bool coldIdle = false; 40364d23ca370dd0ce584f49a80ef9dfcdbb75ba2c8eGlenn Kasten if (mFastMixer != 0) { 403781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent sq = mFastMixer->sq(); 403881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent state = sq->begin(); 4039f228531c5d01f497f5802c44545e0000ec44ab83Andy Hung coldIdle = state->mCommand == FastMixerState::COLD_IDLE; 404081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 404181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 404269aed5f0f4a3be3996d1e78a0473e1a72c1547daAndy Hung mMixerBufferValid = false; // mMixerBuffer has no valid data until appropriate tracks found. 404398ef978df4e928f486d244c4d7f7ad9f13111e98Andy Hung mEffectBufferValid = false; // mEffectBuffer has no valid data until tracks found. 404469aed5f0f4a3be3996d1e78a0473e1a72c1547daAndy Hung 404581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent for (size_t i=0 ; i<count ; i++) { 4046dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hung const sp<Track> t = mActiveTracks[i]; 404781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 404881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // this const just means the local variable doesn't change 404981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent Track* const track = t.get(); 405081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 405181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // process fast tracks 405281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (track->isFastTrack()) { 405381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 405481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // It's theoretically possible (though unlikely) for a fast track to be created 405581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // and then removed within the same normal mix cycle. This is not a problem, as 405681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // the track never becomes active so it's fast mixer slot is never touched. 405781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // The converse, of removing an (active) track and then creating a new track 405881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // at the identical fast mixer slot within the same normal mix cycle, 405981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // is impossible because the slot isn't marked available until the end of each cycle. 406081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent int j = track->mFastIndex; 4061dc2c50bad491d2c0c8a2efc0e24491076701c63cGlenn Kasten ALOG_ASSERT(0 < j && j < (int)FastMixerState::sMaxFastTracks); 406281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent ALOG_ASSERT(!(mFastTrackAvailMask & (1 << j))); 406381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent FastTrack *fastTrack = &state->mFastTracks[j]; 406481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 406581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // Determine whether the track is currently in underrun condition, 406681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // and whether it had a recent underrun. 406781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent FastTrackDump *ftDump = &mFastMixerDumpState.mTracks[j]; 406881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent FastTrackUnderruns underruns = ftDump->mUnderruns; 406981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent uint32_t recentFull = (underruns.mBitFields.mFull - 407081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent track->mObservedUnderruns.mBitFields.mFull) & UNDERRUN_MASK; 407181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent uint32_t recentPartial = (underruns.mBitFields.mPartial - 407281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent track->mObservedUnderruns.mBitFields.mPartial) & UNDERRUN_MASK; 407381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent uint32_t recentEmpty = (underruns.mBitFields.mEmpty - 407481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent track->mObservedUnderruns.mBitFields.mEmpty) & UNDERRUN_MASK; 407581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent uint32_t recentUnderruns = recentPartial + recentEmpty; 407681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent track->mObservedUnderruns = underruns; 407781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // don't count underruns that occur while stopping or pausing 407881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // or stopped which can occur when flush() is called while active 407982aaf94a5b18939e4d790bbc752031f3070704a3Glenn Kasten if (!(track->isStopping() || track->isPausing() || track->isStopped()) && 408082aaf94a5b18939e4d790bbc752031f3070704a3Glenn Kasten recentUnderruns > 0) { 408182aaf94a5b18939e4d790bbc752031f3070704a3Glenn Kasten // FIXME fast mixer will pull & mix partial buffers, but we count as a full underrun 408282aaf94a5b18939e4d790bbc752031f3070704a3Glenn Kasten track->mAudioTrackServerProxy->tallyUnderrunFrames(recentUnderruns * mFrameCount); 40832812d9ea3a3a33142dd8e23c9d949c498d6f7a12Phil Burk } else { 40842812d9ea3a3a33142dd8e23c9d949c498d6f7a12Phil Burk track->mAudioTrackServerProxy->tallyUnderrunFrames(0); 408581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 408681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 408781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // This is similar to the state machine for normal tracks, 408881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // with a few modifications for fast tracks. 408981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent bool isActive = true; 409081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent switch (track->mState) { 409181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent case TrackBase::STOPPING_1: 409281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // track stays active in STOPPING_1 state until first underrun 4093bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent if (recentUnderruns > 0 || track->isTerminated()) { 409481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent track->mState = TrackBase::STOPPING_2; 409581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 409681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent break; 409781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent case TrackBase::PAUSING: 409881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // ramp down is not yet implemented 409981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent track->setPaused(); 410081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent break; 410181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent case TrackBase::RESUMING: 410281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // ramp up is not yet implemented 410381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent track->mState = TrackBase::ACTIVE; 410481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent break; 410581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent case TrackBase::ACTIVE: 410681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (recentFull > 0 || recentPartial > 0) { 410781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // track has provided at least some frames recently: reset retry count 410881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent track->mRetryCount = kMaxTrackRetries; 410981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 411081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (recentUnderruns == 0) { 411181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // no recent underruns: stay active 411281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent break; 411381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 411481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // there has recently been an underrun of some kind 411581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (track->sharedBuffer() == 0) { 411681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // were any of the recent underruns "empty" (no frames available)? 411781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (recentEmpty == 0) { 411881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // no, then ignore the partial underruns as they are allowed indefinitely 411981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent break; 412081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 412181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // there has recently been an "empty" underrun: decrement the retry counter 412281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (--(track->mRetryCount) > 0) { 412381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent break; 412481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 412581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // indicate to client process that the track was disabled because of underrun; 412681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // it will then automatically call start() when data is available 41274d231dc0ee34380956c71cbe18a750e487a69601Eric Laurent track->disable(); 412881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // remove from active list, but state remains ACTIVE [confusing but true] 412981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent isActive = false; 413081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent break; 413181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 413281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // fall through 413381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent case TrackBase::STOPPING_2: 413481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent case TrackBase::PAUSED: 413581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent case TrackBase::STOPPED: 413681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent case TrackBase::FLUSHED: // flush() while active 413781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // Check for presentation complete if track is inactive 413881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // We have consumed all the buffers of this track. 413981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // This would be incomplete if we auto-paused on underrun 414081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent { 41411dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov uint32_t latency = 0; 41421dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov status_t result = mOutput->stream->getLatency(&latency); 41431dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov ALOGE_IF(result != OK, 41441dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov "Error when retrieving output stream latency: %d", result); 41451dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov size_t audioHALFrames = (latency * mSampleRate) / 1000; 4146818e7a32ce3633980138aff2c2bfcc5158b3cfccAndy Hung int64_t framesWritten = mBytesWritten / mFrameSize; 414781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (!(mStandby || track->presentationComplete(framesWritten, audioHALFrames))) { 414881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // track stays in active list until presentation is complete 414981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent break; 415081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 415181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 415281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (track->isStopping_2()) { 415381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent track->mState = TrackBase::STOPPED; 415481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 415581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (track->isStopped()) { 415681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // Can't reset directly, as fast mixer is still polling this track 415781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // track->reset(); 415881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // So instead mark this track as needing to be reset after push with ack 415981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent resetMask |= 1 << i; 416081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 416181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent isActive = false; 416281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent break; 416381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent case TrackBase::IDLE: 416481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent default: 4165adad3d7d935da176ff24941b4ae9edf7340e9b96Glenn Kasten LOG_ALWAYS_FATAL("unexpected track state %d", track->mState); 416681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 416781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 416881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (isActive) { 416981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // was it previously inactive? 417081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (!(state->mTrackMask & (1 << j))) { 417181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent ExtendedAudioBufferProvider *eabp = track; 417281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent VolumeProvider *vp = track; 417381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent fastTrack->mBufferProvider = eabp; 417481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent fastTrack->mVolumeProvider = vp; 417581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent fastTrack->mChannelMask = track->mChannelMask; 4176e8a1ced4da17dc6c07803dc2af8060f62a8389c1Andy Hung fastTrack->mFormat = track->mFormat; 417781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent fastTrack->mGeneration++; 417881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent state->mTrackMask |= 1 << j; 417981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent didModify = true; 418081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // no acknowledgement required for newly active tracks 418181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 418281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // cache the combined master volume and stream type volume for fast mixer; this 418381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // lacks any synchronization or barrier so VolumeProvider may read a stale value 41849fc8b5cd4a64ef07e84c69112461324d5c13a0b0Andy Hung const float vh = track->getVolumeHandler()->getVolume( 418510cbff139360f3f642e0e3b3ccf2d463dbed22cfAndy Hung track->mAudioTrackServerProxy->framesReleased()).first; 41869fc8b5cd4a64ef07e84c69112461324d5c13a0b0Andy Hung track->mCachedVolume = masterVolume 41879fc8b5cd4a64ef07e84c69112461324d5c13a0b0Andy Hung * mStreamTypes[track->streamType()].volume 41889fc8b5cd4a64ef07e84c69112461324d5c13a0b0Andy Hung * vh; 418981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent ++fastTracks; 419081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } else { 419181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // was it previously active? 419281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (state->mTrackMask & (1 << j)) { 419381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent fastTrack->mBufferProvider = NULL; 419481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent fastTrack->mGeneration++; 419581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent state->mTrackMask &= ~(1 << j); 419681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent didModify = true; 419781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // If any fast tracks were removed, we must wait for acknowledgement 419881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // because we're about to decrement the last sp<> on those tracks. 419981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent block = FastMixerStateQueue::BLOCK_UNTIL_ACKED; 420081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } else { 4201f7d65ee34f64e8fad9c5af3f11da783193caf5f9Glenn Kasten LOG_ALWAYS_FATAL("fast track %d should have been active; " 4202f7d65ee34f64e8fad9c5af3f11da783193caf5f9Glenn Kasten "mState=%d, mTrackMask=%#x, recentUnderruns=%u, isShared=%d", 4203f7d65ee34f64e8fad9c5af3f11da783193caf5f9Glenn Kasten j, track->mState, state->mTrackMask, recentUnderruns, 4204f7d65ee34f64e8fad9c5af3f11da783193caf5f9Glenn Kasten track->sharedBuffer() != 0); 420581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 420681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent tracksToRemove->add(track); 420781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // Avoids a misleading display in dumpsys 420881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent track->mObservedUnderruns.mBitFields.mMostRecent = UNDERRUN_FULL; 420981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 421081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent continue; 421181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 421281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 421381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent { // local variable scope to avoid goto warning 421481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 421581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent audio_track_cblk_t* cblk = track->cblk(); 421681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 421781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // The first time a track is added we wait 421881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // for all its buffers to be filled before processing it 421981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent int name = track->name(); 422081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // make sure that we have enough frames to mix one full buffer. 422181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // enforce this condition only once to enable draining the buffer in case the client 422281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // app does not call stop() and relies on underrun to stop: 422381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // hence the test on (mMixerStatus == MIXER_TRACKS_READY) meaning the track was mixed 422481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // during last round 42259f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten size_t desiredFrames; 42268edb8dc44b8a2f81bdb5db645b6b708548771a31Andy Hung const uint32_t sampleRate = track->mAudioTrackServerProxy->getSampleRate(); 42275a8a95de6dad1a3bcf3da5a37b35766e89086e13Ricardo Garcia AudioPlaybackRate playbackRate = track->mAudioTrackServerProxy->getPlaybackRate(); 42288edb8dc44b8a2f81bdb5db645b6b708548771a31Andy Hung 42298edb8dc44b8a2f81bdb5db645b6b708548771a31Andy Hung desiredFrames = sourceFramesNeededWithTimestretch( 42305a8a95de6dad1a3bcf3da5a37b35766e89086e13Ricardo Garcia sampleRate, mNormalFrameCount, mSampleRate, playbackRate.mSpeed); 42318edb8dc44b8a2f81bdb5db645b6b708548771a31Andy Hung // TODO: ONLY USED FOR LEGACY RESAMPLERS, remove when they are removed. 42328edb8dc44b8a2f81bdb5db645b6b708548771a31Andy Hung // add frames already consumed but not yet released by the resampler 42338edb8dc44b8a2f81bdb5db645b6b708548771a31Andy Hung // because mAudioTrackServerProxy->framesReady() will include these frames 42348edb8dc44b8a2f81bdb5db645b6b708548771a31Andy Hung desiredFrames += mAudioMixer->getUnreleasedFrames(track->name()); 42358edb8dc44b8a2f81bdb5db645b6b708548771a31Andy Hung 423681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent uint32_t minFrames = 1; 423781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if ((track->sharedBuffer() == 0) && !track->isStopped() && !track->isPausing() && 423881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent (mMixerStatusIgnoringFastTracks == MIXER_TRACKS_READY)) { 42399f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten minFrames = desiredFrames; 42409f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten } 424113e4c960ea3db03a43e084fbd85d52aa77f7b871Eric Laurent 424213e4c960ea3db03a43e084fbd85d52aa77f7b871Eric Laurent size_t framesReady = track->framesReady(); 4243e77540228e1f60b1129a1615d2e43e0bf8015d3cGlenn Kasten if (ATRACE_ENABLED()) { 4244e77540228e1f60b1129a1615d2e43e0bf8015d3cGlenn Kasten // I wish we had formatted trace names 4245e77540228e1f60b1129a1615d2e43e0bf8015d3cGlenn Kasten char traceName[16]; 4246e77540228e1f60b1129a1615d2e43e0bf8015d3cGlenn Kasten strcpy(traceName, "nRdy"); 4247e77540228e1f60b1129a1615d2e43e0bf8015d3cGlenn Kasten int name = track->name(); 4248e77540228e1f60b1129a1615d2e43e0bf8015d3cGlenn Kasten if (AudioMixer::TRACK0 <= name && 4249e77540228e1f60b1129a1615d2e43e0bf8015d3cGlenn Kasten name < (int) (AudioMixer::TRACK0 + AudioMixer::MAX_NUM_TRACKS)) { 4250e77540228e1f60b1129a1615d2e43e0bf8015d3cGlenn Kasten name -= AudioMixer::TRACK0; 4251e77540228e1f60b1129a1615d2e43e0bf8015d3cGlenn Kasten traceName[4] = (name / 10) + '0'; 4252e77540228e1f60b1129a1615d2e43e0bf8015d3cGlenn Kasten traceName[5] = (name % 10) + '0'; 4253e77540228e1f60b1129a1615d2e43e0bf8015d3cGlenn Kasten } else { 4254e77540228e1f60b1129a1615d2e43e0bf8015d3cGlenn Kasten traceName[4] = '?'; 4255e77540228e1f60b1129a1615d2e43e0bf8015d3cGlenn Kasten traceName[5] = '?'; 4256e77540228e1f60b1129a1615d2e43e0bf8015d3cGlenn Kasten } 4257e77540228e1f60b1129a1615d2e43e0bf8015d3cGlenn Kasten traceName[6] = '\0'; 4258e77540228e1f60b1129a1615d2e43e0bf8015d3cGlenn Kasten ATRACE_INT(traceName, framesReady); 4259e77540228e1f60b1129a1615d2e43e0bf8015d3cGlenn Kasten } 42609f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten if ((framesReady >= minFrames) && track->isReady() && 426181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent !track->isPaused() && !track->isTerminated()) 426281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent { 4263f20e1d8df84c5fbeeace0052d100982ae39bb7a4Glenn Kasten ALOGVV("track %d s=%08x [OK] on thread %p", name, cblk->mServer, this); 426481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 426581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mixedTracks++; 426681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 426769aed5f0f4a3be3996d1e78a0473e1a72c1547daAndy Hung // track->mainBuffer() != mSinkBuffer or mMixerBuffer means 426869aed5f0f4a3be3996d1e78a0473e1a72c1547daAndy Hung // there is an effect chain connected to the track 426981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent chain.clear(); 427069aed5f0f4a3be3996d1e78a0473e1a72c1547daAndy Hung if (track->mainBuffer() != mSinkBuffer && 427169aed5f0f4a3be3996d1e78a0473e1a72c1547daAndy Hung track->mainBuffer() != mMixerBuffer) { 427298ef978df4e928f486d244c4d7f7ad9f13111e98Andy Hung if (mEffectBufferEnabled) { 427398ef978df4e928f486d244c4d7f7ad9f13111e98Andy Hung mEffectBufferValid = true; // Later can set directly. 427498ef978df4e928f486d244c4d7f7ad9f13111e98Andy Hung } 427581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent chain = getEffectChain_l(track->sessionId()); 427681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // Delegate volume control to effect in track effect chain if needed 427781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (chain != 0) { 427881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent tracksWithEffect++; 427981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } else { 428081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent ALOGW("prepareTracks_l(): track %d attached to effect but no chain found on " 428181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent "session %d", 428281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent name, track->sessionId()); 428381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 428481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 428581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 428681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 428781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent int param = AudioMixer::VOLUME; 428881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (track->mFillingUpStatus == Track::FS_FILLED) { 428981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // no ramp for the first volume setting 429081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent track->mFillingUpStatus = Track::FS_ACTIVE; 429181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (track->mState == TrackBase::RESUMING) { 429281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent track->mState = TrackBase::ACTIVE; 429381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent param = AudioMixer::RAMP_VOLUME; 429481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 429581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mAudioMixer->setParameter(name, AudioMixer::RESAMPLE, AudioMixer::RESET, NULL); 4296f20e1d8df84c5fbeeace0052d100982ae39bb7a4Glenn Kasten // FIXME should not make a decision based on mServer 4297f20e1d8df84c5fbeeace0052d100982ae39bb7a4Glenn Kasten } else if (cblk->mServer != 0) { 429881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // If the track is stopped before the first frame was mixed, 429981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // do not apply ramp 430081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent param = AudioMixer::RAMP_VOLUME; 430181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 430281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 430381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // compute volume for this track 43046be494077f8d7970f3a88129c5d139c5a0c88f6dAndy Hung uint32_t vl, vr; // in U8.24 integer format 43056be494077f8d7970f3a88129c5d139c5a0c88f6dAndy Hung float vlf, vrf, vaf; // in [0.0, 1.0] float format 4306e4756fe3a387615acb63c6a05788c8db9b5786cbGlenn Kasten if (track->isPausing() || mStreamTypes[track->streamType()].mute) { 43076be494077f8d7970f3a88129c5d139c5a0c88f6dAndy Hung vl = vr = 0; 43086be494077f8d7970f3a88129c5d139c5a0c88f6dAndy Hung vlf = vrf = vaf = 0.; 430981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (track->isPausing()) { 431081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent track->setPaused(); 431181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 431281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } else { 431381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 431481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // read original volumes with volume control 431581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent float typeVolume = mStreamTypes[track->streamType()].volume; 431681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent float v = masterVolume * typeVolume; 43175bba2f6916dbe00aea7c0521faa0c6ed42114a75Eric Laurent sp<AudioTrackServerProxy> proxy = track->mAudioTrackServerProxy; 4318c56f3426099a3cf2d07ccff8886050c7fbce140fGlenn Kasten gain_minifloat_packed_t vlr = proxy->getVolumeLR(); 43196be494077f8d7970f3a88129c5d139c5a0c88f6dAndy Hung vlf = float_from_gain(gain_minifloat_unpack_left(vlr)); 43206be494077f8d7970f3a88129c5d139c5a0c88f6dAndy Hung vrf = float_from_gain(gain_minifloat_unpack_right(vlr)); 432181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // track volumes come from shared memory, so can't be trusted and must be clamped 4322c56f3426099a3cf2d07ccff8886050c7fbce140fGlenn Kasten if (vlf > GAIN_FLOAT_UNITY) { 4323c56f3426099a3cf2d07ccff8886050c7fbce140fGlenn Kasten ALOGV("Track left volume out of range: %.3g", vlf); 4324c56f3426099a3cf2d07ccff8886050c7fbce140fGlenn Kasten vlf = GAIN_FLOAT_UNITY; 432581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 4326c56f3426099a3cf2d07ccff8886050c7fbce140fGlenn Kasten if (vrf > GAIN_FLOAT_UNITY) { 4327c56f3426099a3cf2d07ccff8886050c7fbce140fGlenn Kasten ALOGV("Track right volume out of range: %.3g", vrf); 4328c56f3426099a3cf2d07ccff8886050c7fbce140fGlenn Kasten vrf = GAIN_FLOAT_UNITY; 432981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 43309fc8b5cd4a64ef07e84c69112461324d5c13a0b0Andy Hung const float vh = track->getVolumeHandler()->getVolume( 433110cbff139360f3f642e0e3b3ccf2d463dbed22cfAndy Hung track->mAudioTrackServerProxy->framesReleased()).first; 43329fc8b5cd4a64ef07e84c69112461324d5c13a0b0Andy Hung // now apply the master volume and stream type volume and shaper volume 43339fc8b5cd4a64ef07e84c69112461324d5c13a0b0Andy Hung vlf *= v * vh; 43349fc8b5cd4a64ef07e84c69112461324d5c13a0b0Andy Hung vrf *= v * vh; 433581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // assuming master volume and stream type volume each go up to 1.0, 43366be494077f8d7970f3a88129c5d139c5a0c88f6dAndy Hung // then derive vl and vr as U8.24 versions for the effect chain 43376be494077f8d7970f3a88129c5d139c5a0c88f6dAndy Hung const float scaleto8_24 = MAX_GAIN_INT * MAX_GAIN_INT; 43386be494077f8d7970f3a88129c5d139c5a0c88f6dAndy Hung vl = (uint32_t) (scaleto8_24 * vlf); 43396be494077f8d7970f3a88129c5d139c5a0c88f6dAndy Hung vr = (uint32_t) (scaleto8_24 * vrf); 43406be494077f8d7970f3a88129c5d139c5a0c88f6dAndy Hung // vl and vr are now in U8.24 format 4341e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten uint16_t sendLevel = proxy->getSendLevel_U4_12(); 434281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // send level comes from shared memory and so may be corrupt 434381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (sendLevel > MAX_GAIN_INT) { 434481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent ALOGV("Track send level out of range: %04X", sendLevel); 434581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent sendLevel = MAX_GAIN_INT; 434681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 43476be494077f8d7970f3a88129c5d139c5a0c88f6dAndy Hung // vaf is represented as [0.0, 1.0] float by rescaling sendLevel 43486be494077f8d7970f3a88129c5d139c5a0c88f6dAndy Hung vaf = v * sendLevel * (1. / MAX_GAIN_INT); 434981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 4350bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent 435181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // Delegate volume control to effect in track effect chain if needed 435281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (chain != 0 && chain->setVolume_l(&vl, &vr)) { 435381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // Do not ramp volume if volume is controlled by effect 435481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent param = AudioMixer::VOLUME; 4355b6be7f22a82ee3bad8bcc709d21e72fc4727da09Bryant Liu // Update remaining floating point volume levels 4356b6be7f22a82ee3bad8bcc709d21e72fc4727da09Bryant Liu vlf = (float)vl / (1 << 24); 4357b6be7f22a82ee3bad8bcc709d21e72fc4727da09Bryant Liu vrf = (float)vr / (1 << 24); 435881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent track->mHasVolumeController = true; 435981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } else { 436081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // force no volume ramp when volume controller was just disabled or removed 436181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // from effect chain to avoid volume spike 436281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (track->mHasVolumeController) { 436381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent param = AudioMixer::VOLUME; 436481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 436581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent track->mHasVolumeController = false; 436681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 436781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 436881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // XXX: these things DON'T need to be done each time 436981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mAudioMixer->setBufferProvider(name, track); 437081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mAudioMixer->enable(name); 437181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 43726be494077f8d7970f3a88129c5d139c5a0c88f6dAndy Hung mAudioMixer->setParameter(name, param, AudioMixer::VOLUME0, &vlf); 43736be494077f8d7970f3a88129c5d139c5a0c88f6dAndy Hung mAudioMixer->setParameter(name, param, AudioMixer::VOLUME1, &vrf); 43746be494077f8d7970f3a88129c5d139c5a0c88f6dAndy Hung mAudioMixer->setParameter(name, param, AudioMixer::AUXLEVEL, &vaf); 437581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mAudioMixer->setParameter( 437681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent name, 437781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent AudioMixer::TRACK, 437881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent AudioMixer::FORMAT, (void *)track->format()); 437981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mAudioMixer->setParameter( 438081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent name, 438181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent AudioMixer::TRACK, 4382377b2ec9a2885f9b6405b07ba900a9e3f4349c38Kévin PETIT AudioMixer::CHANNEL_MASK, (void *)(uintptr_t)track->channelMask()); 43839a59276fb465e492138e0576523b54079671e8f4Andy Hung mAudioMixer->setParameter( 43849a59276fb465e492138e0576523b54079671e8f4Andy Hung name, 43859a59276fb465e492138e0576523b54079671e8f4Andy Hung AudioMixer::TRACK, 43869a59276fb465e492138e0576523b54079671e8f4Andy Hung AudioMixer::MIXER_CHANNEL_MASK, (void *)(uintptr_t)mChannelMask); 4387e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten // limit track sample rate to 2 x output sample rate, which changes at re-configuration 4388cd04484f4837b8ca0041d118286ab6a98e84fc75Andy Hung uint32_t maxSampleRate = mSampleRate * AUDIO_RESAMPLER_DOWN_RATIO_MAX; 43899f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten uint32_t reqSampleRate = track->mAudioTrackServerProxy->getSampleRate(); 4390e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten if (reqSampleRate == 0) { 4391e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten reqSampleRate = mSampleRate; 4392e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten } else if (reqSampleRate > maxSampleRate) { 4393e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten reqSampleRate = maxSampleRate; 4394e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten } 439581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mAudioMixer->setParameter( 439681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent name, 439781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent AudioMixer::RESAMPLE, 439881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent AudioMixer::SAMPLE_RATE, 4399377b2ec9a2885f9b6405b07ba900a9e3f4349c38Kévin PETIT (void *)(uintptr_t)reqSampleRate); 44008edb8dc44b8a2f81bdb5db645b6b708548771a31Andy Hung 44015a8a95de6dad1a3bcf3da5a37b35766e89086e13Ricardo Garcia AudioPlaybackRate playbackRate = track->mAudioTrackServerProxy->getPlaybackRate(); 44028edb8dc44b8a2f81bdb5db645b6b708548771a31Andy Hung mAudioMixer->setParameter( 44038edb8dc44b8a2f81bdb5db645b6b708548771a31Andy Hung name, 44048edb8dc44b8a2f81bdb5db645b6b708548771a31Andy Hung AudioMixer::TIMESTRETCH, 44058edb8dc44b8a2f81bdb5db645b6b708548771a31Andy Hung AudioMixer::PLAYBACK_RATE, 44065a8a95de6dad1a3bcf3da5a37b35766e89086e13Ricardo Garcia &playbackRate); 44078edb8dc44b8a2f81bdb5db645b6b708548771a31Andy Hung 440869aed5f0f4a3be3996d1e78a0473e1a72c1547daAndy Hung /* 440969aed5f0f4a3be3996d1e78a0473e1a72c1547daAndy Hung * Select the appropriate output buffer for the track. 441069aed5f0f4a3be3996d1e78a0473e1a72c1547daAndy Hung * 441198ef978df4e928f486d244c4d7f7ad9f13111e98Andy Hung * Tracks with effects go into their own effects chain buffer 441298ef978df4e928f486d244c4d7f7ad9f13111e98Andy Hung * and from there into either mEffectBuffer or mSinkBuffer. 441369aed5f0f4a3be3996d1e78a0473e1a72c1547daAndy Hung * 441469aed5f0f4a3be3996d1e78a0473e1a72c1547daAndy Hung * Other tracks can use mMixerBuffer for higher precision 441569aed5f0f4a3be3996d1e78a0473e1a72c1547daAndy Hung * channel accumulation. If this buffer is enabled 441669aed5f0f4a3be3996d1e78a0473e1a72c1547daAndy Hung * (mMixerBufferEnabled true), then selected tracks will accumulate 441769aed5f0f4a3be3996d1e78a0473e1a72c1547daAndy Hung * into it. 441869aed5f0f4a3be3996d1e78a0473e1a72c1547daAndy Hung * 441969aed5f0f4a3be3996d1e78a0473e1a72c1547daAndy Hung */ 442069aed5f0f4a3be3996d1e78a0473e1a72c1547daAndy Hung if (mMixerBufferEnabled 442169aed5f0f4a3be3996d1e78a0473e1a72c1547daAndy Hung && (track->mainBuffer() == mSinkBuffer 442269aed5f0f4a3be3996d1e78a0473e1a72c1547daAndy Hung || track->mainBuffer() == mMixerBuffer)) { 442369aed5f0f4a3be3996d1e78a0473e1a72c1547daAndy Hung mAudioMixer->setParameter( 442469aed5f0f4a3be3996d1e78a0473e1a72c1547daAndy Hung name, 442569aed5f0f4a3be3996d1e78a0473e1a72c1547daAndy Hung AudioMixer::TRACK, 4426788207057ed4b8df4719ed8089f376ef52de9ca1Andy Hung AudioMixer::MIXER_FORMAT, (void *)mMixerBufferFormat); 442769aed5f0f4a3be3996d1e78a0473e1a72c1547daAndy Hung mAudioMixer->setParameter( 442869aed5f0f4a3be3996d1e78a0473e1a72c1547daAndy Hung name, 442969aed5f0f4a3be3996d1e78a0473e1a72c1547daAndy Hung AudioMixer::TRACK, 443069aed5f0f4a3be3996d1e78a0473e1a72c1547daAndy Hung AudioMixer::MAIN_BUFFER, (void *)mMixerBuffer); 443169aed5f0f4a3be3996d1e78a0473e1a72c1547daAndy Hung // TODO: override track->mainBuffer()? 443269aed5f0f4a3be3996d1e78a0473e1a72c1547daAndy Hung mMixerBufferValid = true; 443369aed5f0f4a3be3996d1e78a0473e1a72c1547daAndy Hung } else { 443469aed5f0f4a3be3996d1e78a0473e1a72c1547daAndy Hung mAudioMixer->setParameter( 443569aed5f0f4a3be3996d1e78a0473e1a72c1547daAndy Hung name, 443669aed5f0f4a3be3996d1e78a0473e1a72c1547daAndy Hung AudioMixer::TRACK, 4437788207057ed4b8df4719ed8089f376ef52de9ca1Andy Hung AudioMixer::MIXER_FORMAT, (void *)AUDIO_FORMAT_PCM_16_BIT); 443869aed5f0f4a3be3996d1e78a0473e1a72c1547daAndy Hung mAudioMixer->setParameter( 443969aed5f0f4a3be3996d1e78a0473e1a72c1547daAndy Hung name, 444069aed5f0f4a3be3996d1e78a0473e1a72c1547daAndy Hung AudioMixer::TRACK, 444169aed5f0f4a3be3996d1e78a0473e1a72c1547daAndy Hung AudioMixer::MAIN_BUFFER, (void *)track->mainBuffer()); 444269aed5f0f4a3be3996d1e78a0473e1a72c1547daAndy Hung } 444381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mAudioMixer->setParameter( 444481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent name, 444581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent AudioMixer::TRACK, 444681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent AudioMixer::AUX_BUFFER, (void *)track->auxBuffer()); 444781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 444881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // reset retry count 444981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent track->mRetryCount = kMaxTrackRetries; 445081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 445181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // If one track is ready, set the mixer ready if: 445281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // - the mixer was not ready during previous round OR 445381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // - no other track is not ready 445481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (mMixerStatusIgnoringFastTracks != MIXER_TRACKS_READY || 445581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mixerStatus != MIXER_TRACKS_ENABLED) { 445681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mixerStatus = MIXER_TRACKS_READY; 445781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 445881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } else { 44599f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten if (framesReady < desiredFrames && !track->isStopped() && !track->isPaused()) { 446008fb1743f80437c38b4094070d851ea7f6d485e5Andy Hung ALOGV("track(%p) underrun, framesReady(%zu) < framesDesired(%zd)", 446108fb1743f80437c38b4094070d851ea7f6d485e5Andy Hung track, framesReady, desiredFrames); 446282aaf94a5b18939e4d790bbc752031f3070704a3Glenn Kasten track->mAudioTrackServerProxy->tallyUnderrunFrames(desiredFrames); 44632812d9ea3a3a33142dd8e23c9d949c498d6f7a12Phil Burk } else { 44642812d9ea3a3a33142dd8e23c9d949c498d6f7a12Phil Burk track->mAudioTrackServerProxy->tallyUnderrunFrames(0); 44659f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten } 44662812d9ea3a3a33142dd8e23c9d949c498d6f7a12Phil Burk 446781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // clear effect chain input buffer if an active track underruns to avoid sending 446881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // previous audio buffer again to effects 446981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent chain = getEffectChain_l(track->sessionId()); 447081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (chain != 0) { 447181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent chain->clearInputBuffer(); 447281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 447381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 4474f20e1d8df84c5fbeeace0052d100982ae39bb7a4Glenn Kasten ALOGVV("track %d s=%08x [NOT READY] on thread %p", name, cblk->mServer, this); 447581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if ((track->sharedBuffer() != 0) || track->isTerminated() || 447681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent track->isStopped() || track->isPaused()) { 447781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // We have consumed all the buffers of this track. 447881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // Remove it from the list of active tracks. 447981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // TODO: use actual buffer filling status instead of latency when available from 448081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // audio HAL 448181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent size_t audioHALFrames = (latency_l() * mSampleRate) / 1000; 4482818e7a32ce3633980138aff2c2bfcc5158b3cfccAndy Hung int64_t framesWritten = mBytesWritten / mFrameSize; 448381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (mStandby || track->presentationComplete(framesWritten, audioHALFrames)) { 448481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (track->isStopped()) { 448581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent track->reset(); 448681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 448781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent tracksToRemove->add(track); 448881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 448981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } else { 449081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // No buffers for this track. Give it a few chances to 449181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // fill a buffer, then remove it from active list. 449281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (--(track->mRetryCount) <= 0) { 4493c9b2e20f7c9a71e07ef398152709c76079decbcdGlenn Kasten ALOGI("BUFFER TIMEOUT: remove(%d) from active list on thread %p", name, this); 449481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent tracksToRemove->add(track); 449581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // indicate to client process that the track was disabled because of underrun; 449681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // it will then automatically call start() when data is available 44974d231dc0ee34380956c71cbe18a750e487a69601Eric Laurent track->disable(); 449881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // If one track is not ready, mark the mixer also not ready if: 449981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // - the mixer was ready during previous round OR 450081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // - no other track is ready 450181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } else if (mMixerStatusIgnoringFastTracks == MIXER_TRACKS_READY || 450281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mixerStatus != MIXER_TRACKS_READY) { 450381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mixerStatus = MIXER_TRACKS_ENABLED; 450481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 450581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 450681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mAudioMixer->disable(name); 450781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 450881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 450981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } // local variable scope to avoid goto warning 451081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 451181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 451281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 451381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // Push the new FastMixer state if necessary 451481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent bool pauseAudioWatchdog = false; 451581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (didModify) { 451681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent state->mFastTracksGen++; 451781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // if the fast mixer was active, but now there are no fast tracks, then put it in cold idle 451881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (kUseFastMixer == FastMixer_Dynamic && 451981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent state->mCommand == FastMixerState::MIX_WRITE && state->mTrackMask <= 1) { 452081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent state->mCommand = FastMixerState::COLD_IDLE; 452181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent state->mColdFutexAddr = &mFastMixerFutex; 452281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent state->mColdGen++; 452381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mFastMixerFutex = 0; 452481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (kUseFastMixer == FastMixer_Dynamic) { 452581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mNormalSink = mOutputSink; 452681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 452781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // If we go into cold idle, need to wait for acknowledgement 452881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // so that fast mixer stops doing I/O. 452981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent block = FastMixerStateQueue::BLOCK_UNTIL_ACKED; 453081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent pauseAudioWatchdog = true; 453181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 453281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 453381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (sq != NULL) { 453481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent sq->end(didModify); 4535f228531c5d01f497f5802c44545e0000ec44ab83Andy Hung // No need to block if the FastMixer is in COLD_IDLE as the FastThread 4536f228531c5d01f497f5802c44545e0000ec44ab83Andy Hung // is not active. (We BLOCK_UNTIL_ACKED when entering COLD_IDLE 4537f228531c5d01f497f5802c44545e0000ec44ab83Andy Hung // when bringing the output sink into standby.) 4538f228531c5d01f497f5802c44545e0000ec44ab83Andy Hung // 4539f228531c5d01f497f5802c44545e0000ec44ab83Andy Hung // We will get the latest FastMixer state when we come out of COLD_IDLE. 4540f228531c5d01f497f5802c44545e0000ec44ab83Andy Hung // 4541f228531c5d01f497f5802c44545e0000ec44ab83Andy Hung // This occurs with BT suspend when we idle the FastMixer with 4542f228531c5d01f497f5802c44545e0000ec44ab83Andy Hung // active tracks, which may be added or removed. 4543f228531c5d01f497f5802c44545e0000ec44ab83Andy Hung sq->push(coldIdle ? FastMixerStateQueue::BLOCK_NEVER : block); 454481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 454581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent#ifdef AUDIO_WATCHDOG 454681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (pauseAudioWatchdog && mAudioWatchdog != 0) { 454781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mAudioWatchdog->pause(); 454881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 454981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent#endif 455081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 455181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // Now perform the deferred reset on fast tracks that have stopped 455281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent while (resetMask != 0) { 455381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent size_t i = __builtin_ctz(resetMask); 455481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent ALOG_ASSERT(i < count); 455581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent resetMask &= ~(1 << i); 4556dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hung sp<Track> track = mActiveTracks[i]; 455781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent ALOG_ASSERT(track->isFastTrack() && track->isStopped()); 455881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent track->reset(); 455981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 456081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 456181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // remove all the tracks that need to be... 4562bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent removeTracks_l(*tracksToRemove); 456381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 456497d547da43c9c41711d1ed1e3f4fa87c2ee3cb9aEric Laurent if (getEffectChain_l(AUDIO_SESSION_OUTPUT_MIX) != 0) { 456597d547da43c9c41711d1ed1e3f4fa87c2ee3cb9aEric Laurent mEffectBufferValid = true; 4566ac302143551a8b964f026385a524dda9ff8ea5baMarco Nelissen } 4567ac302143551a8b964f026385a524dda9ff8ea5baMarco Nelissen 4568ac302143551a8b964f026385a524dda9ff8ea5baMarco Nelissen if (mEffectBufferValid) { 456957088b5c8e76855b99b3e6b3e410de5b6382670eMarco Nelissen // as long as there are effects we should clear the effects buffer, to avoid 457057088b5c8e76855b99b3e6b3e410de5b6382670eMarco Nelissen // passing a non-clean buffer to the effect chain 457157088b5c8e76855b99b3e6b3e410de5b6382670eMarco Nelissen memset(mEffectBuffer, 0, mEffectBufferSize); 457297d547da43c9c41711d1ed1e3f4fa87c2ee3cb9aEric Laurent } 457369aed5f0f4a3be3996d1e78a0473e1a72c1547daAndy Hung // sink or mix buffer must be cleared if all tracks are connected to an 457469aed5f0f4a3be3996d1e78a0473e1a72c1547daAndy Hung // effect chain as in this case the mixer will not write to the sink or mix buffer 457569aed5f0f4a3be3996d1e78a0473e1a72c1547daAndy Hung // and track effects will accumulate into it 4576bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent if ((mBytesRemaining == 0) && ((mixedTracks != 0 && mixedTracks == tracksWithEffect) || 4577bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent (mixedTracks == 0 && fastTracks > 0))) { 457881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // FIXME as a performance optimization, should remember previous zero status 457969aed5f0f4a3be3996d1e78a0473e1a72c1547daAndy Hung if (mMixerBufferValid) { 458069aed5f0f4a3be3996d1e78a0473e1a72c1547daAndy Hung memset(mMixerBuffer, 0, mMixerBufferSize); 458169aed5f0f4a3be3996d1e78a0473e1a72c1547daAndy Hung // TODO: In testing, mSinkBuffer below need not be cleared because 458269aed5f0f4a3be3996d1e78a0473e1a72c1547daAndy Hung // the PlaybackThread::threadLoop() copies mMixerBuffer into mSinkBuffer 458369aed5f0f4a3be3996d1e78a0473e1a72c1547daAndy Hung // after mixing. 458469aed5f0f4a3be3996d1e78a0473e1a72c1547daAndy Hung // 458569aed5f0f4a3be3996d1e78a0473e1a72c1547daAndy Hung // To enforce this guarantee: 458669aed5f0f4a3be3996d1e78a0473e1a72c1547daAndy Hung // ((mixedTracks != 0 && mixedTracks == tracksWithEffect) || 458769aed5f0f4a3be3996d1e78a0473e1a72c1547daAndy Hung // (mixedTracks == 0 && fastTracks > 0)) 458869aed5f0f4a3be3996d1e78a0473e1a72c1547daAndy Hung // must imply MIXER_TRACKS_READY. 458969aed5f0f4a3be3996d1e78a0473e1a72c1547daAndy Hung // Later, we may clear buffers regardless, and skip much of this logic. 459069aed5f0f4a3be3996d1e78a0473e1a72c1547daAndy Hung } 459198ef978df4e928f486d244c4d7f7ad9f13111e98Andy Hung // FIXME as a performance optimization, should remember previous zero status 45925567aaf4818007cd8e77329683a91c0f5d7a8837Andy Hung memset(mSinkBuffer, 0, mNormalFrameCount * mFrameSize); 459381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 459481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 459581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // if any fast tracks, then status is ready 459681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mMixerStatusIgnoringFastTracks = mixerStatus; 459781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (fastTracks > 0) { 459881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mixerStatus = MIXER_TRACKS_READY; 459981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 460081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent return mixerStatus; 460181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 460281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 4603ad7dd9610b6fafa81baf69607f4ac669da88182aEric Laurent// trackCountForUid_l() must be called with ThreadBase::mLock held 4604ad7dd9610b6fafa81baf69607f4ac669da88182aEric Laurentuint32_t AudioFlinger::PlaybackThread::trackCountForUid_l(uid_t uid) 4605ad7dd9610b6fafa81baf69607f4ac669da88182aEric Laurent{ 4606ad7dd9610b6fafa81baf69607f4ac669da88182aEric Laurent uint32_t trackCount = 0; 4607ad7dd9610b6fafa81baf69607f4ac669da88182aEric Laurent for (size_t i = 0; i < mTracks.size() ; i++) { 46081f12a8ad958344c50733b948628ffa06db9c5bc6Andy Hung if (mTracks[i]->uid() == uid) { 4609ad7dd9610b6fafa81baf69607f4ac669da88182aEric Laurent trackCount++; 4610ad7dd9610b6fafa81baf69607f4ac669da88182aEric Laurent } 4611ad7dd9610b6fafa81baf69607f4ac669da88182aEric Laurent } 4612ad7dd9610b6fafa81baf69607f4ac669da88182aEric Laurent return trackCount; 4613ad7dd9610b6fafa81baf69607f4ac669da88182aEric Laurent} 4614ad7dd9610b6fafa81baf69607f4ac669da88182aEric Laurent 461581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// getTrackName_l() must be called with ThreadBase::mLock held 4616e8a1ced4da17dc6c07803dc2af8060f62a8389c1Andy Hungint AudioFlinger::MixerThread::getTrackName_l(audio_channel_mask_t channelMask, 4617ad7dd9610b6fafa81baf69607f4ac669da88182aEric Laurent audio_format_t format, audio_session_t sessionId, uid_t uid) 461881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 4619ad7dd9610b6fafa81baf69607f4ac669da88182aEric Laurent if (trackCountForUid_l(uid) > (PlaybackThread::kMaxTracksPerUid - 1)) { 4620ad7dd9610b6fafa81baf69607f4ac669da88182aEric Laurent return -1; 4621ad7dd9610b6fafa81baf69607f4ac669da88182aEric Laurent } 4622e8a1ced4da17dc6c07803dc2af8060f62a8389c1Andy Hung return mAudioMixer->getTrackName(channelMask, format, sessionId); 462381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 462481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 462581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// deleteTrackName_l() must be called with ThreadBase::mLock held 462681784c37c61b09289654b979567a42bf73cd2b12Eric Laurentvoid AudioFlinger::MixerThread::deleteTrackName_l(int name) 462781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 462881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent ALOGV("remove track (%d) and delete from mixer", name); 462981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mAudioMixer->deleteTrackName(name); 463081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 463181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 46321035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent// checkForNewParameter_l() must be called with ThreadBase::mLock held 46331035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurentbool AudioFlinger::MixerThread::checkForNewParameter_l(const String8& keyValuePair, 46341035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent status_t& status) 463581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 463681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent bool reconfig = false; 463742537be61479e59c4718e1304364551c1454f63cEric Laurent bool a2dpDeviceChanged = false; 463881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 46391035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent status = NO_ERROR; 464081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 4641c05b8d7df46619d3474356241d47655478b8bc82Glenn Kasten AutoPark<FastMixer> park(mFastMixer); 464281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 46431035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent AudioParameter param = AudioParameter(keyValuePair); 46441035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent int value; 46451035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent if (param.getInt(String8(AudioParameter::keySamplingRate), value) == NO_ERROR) { 46461035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent reconfig = true; 46471035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent } 46481035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent if (param.getInt(String8(AudioParameter::keyFormat), value) == NO_ERROR) { 46499a59276fb465e492138e0576523b54079671e8f4Andy Hung if (!isValidPcmSinkFormat((audio_format_t) value)) { 46501035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent status = BAD_VALUE; 46511035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent } else { 46521035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent // no need to save value, since it's constant 465381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent reconfig = true; 465481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 46551035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent } 46561035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent if (param.getInt(String8(AudioParameter::keyChannels), value) == NO_ERROR) { 46579a59276fb465e492138e0576523b54079671e8f4Andy Hung if (!isValidPcmSinkChannelMask((audio_channel_mask_t) value)) { 46581035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent status = BAD_VALUE; 46591035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent } else { 46601035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent // no need to save value, since it's constant 46611035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent reconfig = true; 466281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 46631035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent } 46641035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent if (param.getInt(String8(AudioParameter::keyFrameCount), value) == NO_ERROR) { 46651035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent // do not accept frame count changes if tracks are open as the track buffer 46661035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent // size depends on frame count and correct behavior would not be guaranteed 46671035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent // if frame count is changed after track creation 46681035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent if (!mTracks.isEmpty()) { 46691035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent status = INVALID_OPERATION; 46701035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent } else { 46711035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent reconfig = true; 467281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 46731035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent } 46741035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent if (param.getInt(String8(AudioParameter::keyRouting), value) == NO_ERROR) { 467581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent#ifdef ADD_BATTERY_DATA 46761035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent // when changing the audio output device, call addBatteryData to notify 46771035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent // the change 46781035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent if (mOutDevice != value) { 46791035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent uint32_t params = 0; 46801035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent // check whether speaker is on 46811035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent if (value & AUDIO_DEVICE_OUT_SPEAKER) { 46821035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent params |= IMediaPlayerService::kBatteryDataSpeakerOn; 46831035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent } 468481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 46851035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent audio_devices_t deviceWithoutSpeaker 46861035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent = AUDIO_DEVICE_OUT_ALL & ~AUDIO_DEVICE_OUT_SPEAKER; 46871035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent // check if any other device (except speaker) is on 4688054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurent if (value & deviceWithoutSpeaker) { 46891035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent params |= IMediaPlayerService::kBatteryDataOtherAudioDeviceOn; 46901035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent } 469181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 46921035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent if (params != 0) { 46931035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent addBatteryData(params); 469481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 46951035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent } 469681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent#endif 469781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 46981035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent // forward device change to effects that have requested to be 46991035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent // aware of attached audio device. 47001035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent if (value != AUDIO_DEVICE_NONE) { 470142537be61479e59c4718e1304364551c1454f63cEric Laurent a2dpDeviceChanged = 470242537be61479e59c4718e1304364551c1454f63cEric Laurent (mOutDevice & AUDIO_DEVICE_OUT_ALL_A2DP) != (value & AUDIO_DEVICE_OUT_ALL_A2DP); 47031035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent mOutDevice = value; 47041035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent for (size_t i = 0; i < mEffectChains.size(); i++) { 47051035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent mEffectChains[i]->setDevice_l(mOutDevice); 470681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 470781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 47081035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent } 470981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 47101035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent if (status == NO_ERROR) { 47111dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov status = mOutput->stream->setParameters(keyValuePair); 47121035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent if (!mStandby && status == INVALID_OPERATION) { 4713062e67a26e0553dd142be622821f493df541f0c6Phil Burk mOutput->standby(); 47141035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent mStandby = true; 47151035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent mBytesWritten = 0; 47161dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov status = mOutput->stream->setParameters(keyValuePair); 47171035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent } 47181035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent if (status == NO_ERROR && reconfig) { 47191035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent readOutputParameters_l(); 47201035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent delete mAudioMixer; 47211035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent mAudioMixer = new AudioMixer(mNormalFrameCount, mSampleRate); 47221035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent for (size_t i = 0; i < mTracks.size() ; i++) { 4723e8a1ced4da17dc6c07803dc2af8060f62a8389c1Andy Hung int name = getTrackName_l(mTracks[i]->mChannelMask, 4724ad7dd9610b6fafa81baf69607f4ac669da88182aEric Laurent mTracks[i]->mFormat, mTracks[i]->mSessionId, mTracks[i]->uid()); 47251035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent if (name < 0) { 47261035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent break; 472781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 47281035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent mTracks[i]->mName = name; 472981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 473073e26b661af50be2c0a4ff6c9ac85f7347a8b235Eric Laurent sendIoConfigEvent_l(AUDIO_OUTPUT_CONFIG_CHANGED); 473181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 473281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 473381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 473442537be61479e59c4718e1304364551c1454f63cEric Laurent return reconfig || a2dpDeviceChanged; 473581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 473681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 473781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 473881784c37c61b09289654b979567a42bf73cd2b12Eric Laurentvoid AudioFlinger::MixerThread::dumpInternals(int fd, const Vector<String16>& args) 473981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 474081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent PlaybackThread::dumpInternals(fd, args); 474140eb1a1f8871909c272e72afaf7d5af84fea2412Andy Hung dprintf(fd, " Thread throttle time (msecs): %u\n", mThreadThrottleTimeMs); 474287cebadd48710e42474756fc3513df678de045ceElliott Hughes dprintf(fd, " AudioMixer tracks: 0x%08x\n", mAudioMixer->trackNames()); 47432ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hung dprintf(fd, " Master mono: %s\n", mMasterMono ? "on" : "off"); 474481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 47456d8018f0b7be9deec6b0acab10a0dca6e91d0fb8Glenn Kasten if (hasFastMixer()) { 47466d8018f0b7be9deec6b0acab10a0dca6e91d0fb8Glenn Kasten dprintf(fd, " FastMixer thread %p tid=%d", mFastMixer.get(), mFastMixer->getTid()); 47476d8018f0b7be9deec6b0acab10a0dca6e91d0fb8Glenn Kasten 47486d8018f0b7be9deec6b0acab10a0dca6e91d0fb8Glenn Kasten // Make a non-atomic copy of fast mixer dump state so it won't change underneath us 47496d8018f0b7be9deec6b0acab10a0dca6e91d0fb8Glenn Kasten // while we are dumping it. It may be inconsistent, but it won't mutate! 47506d8018f0b7be9deec6b0acab10a0dca6e91d0fb8Glenn Kasten // This is a large object so we place it on the heap. 47516d8018f0b7be9deec6b0acab10a0dca6e91d0fb8Glenn Kasten // FIXME 25972958: Need an intelligent copy constructor that does not touch unused pages. 47526d8018f0b7be9deec6b0acab10a0dca6e91d0fb8Glenn Kasten const FastMixerDumpState *copy = new FastMixerDumpState(mFastMixerDumpState); 47536d8018f0b7be9deec6b0acab10a0dca6e91d0fb8Glenn Kasten copy->dump(fd); 47546d8018f0b7be9deec6b0acab10a0dca6e91d0fb8Glenn Kasten delete copy; 475581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 475681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent#ifdef STATE_QUEUE_DUMP 47576d8018f0b7be9deec6b0acab10a0dca6e91d0fb8Glenn Kasten // Similar for state queue 47586d8018f0b7be9deec6b0acab10a0dca6e91d0fb8Glenn Kasten StateQueueObserverDump observerCopy = mStateQueueObserverDump; 47596d8018f0b7be9deec6b0acab10a0dca6e91d0fb8Glenn Kasten observerCopy.dump(fd); 47606d8018f0b7be9deec6b0acab10a0dca6e91d0fb8Glenn Kasten StateQueueMutatorDump mutatorCopy = mStateQueueMutatorDump; 47616d8018f0b7be9deec6b0acab10a0dca6e91d0fb8Glenn Kasten mutatorCopy.dump(fd); 476281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent#endif 476381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 47646d8018f0b7be9deec6b0acab10a0dca6e91d0fb8Glenn Kasten#ifdef AUDIO_WATCHDOG 47656d8018f0b7be9deec6b0acab10a0dca6e91d0fb8Glenn Kasten if (mAudioWatchdog != 0) { 47666d8018f0b7be9deec6b0acab10a0dca6e91d0fb8Glenn Kasten // Make a non-atomic copy of audio watchdog dump so it won't change underneath us 47676d8018f0b7be9deec6b0acab10a0dca6e91d0fb8Glenn Kasten AudioWatchdogDump wdCopy = mAudioWatchdogDump; 47686d8018f0b7be9deec6b0acab10a0dca6e91d0fb8Glenn Kasten wdCopy.dump(fd); 47696d8018f0b7be9deec6b0acab10a0dca6e91d0fb8Glenn Kasten } 47706d8018f0b7be9deec6b0acab10a0dca6e91d0fb8Glenn Kasten#endif 47716d8018f0b7be9deec6b0acab10a0dca6e91d0fb8Glenn Kasten 47726d8018f0b7be9deec6b0acab10a0dca6e91d0fb8Glenn Kasten } else { 47736d8018f0b7be9deec6b0acab10a0dca6e91d0fb8Glenn Kasten dprintf(fd, " No FastMixer\n"); 47746d8018f0b7be9deec6b0acab10a0dca6e91d0fb8Glenn Kasten } 47756d8018f0b7be9deec6b0acab10a0dca6e91d0fb8Glenn Kasten 477646909e7eb074ce1b95b8a411eb71154f53f84f77Glenn Kasten#ifdef TEE_SINK 477781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // Write the tee output to a .wav file 477881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent dumpTee(fd, mTeeSource, mId); 477946909e7eb074ce1b95b8a411eb71154f53f84f77Glenn Kasten#endif 478081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 478181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 478281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 478381784c37c61b09289654b979567a42bf73cd2b12Eric Laurentuint32_t AudioFlinger::MixerThread::idleSleepTimeUs() const 478481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 478581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent return (uint32_t)(((mNormalFrameCount * 1000) / mSampleRate) * 1000) / 2; 478681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 478781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 478881784c37c61b09289654b979567a42bf73cd2b12Eric Laurentuint32_t AudioFlinger::MixerThread::suspendSleepTimeUs() const 478981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 479081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent return (uint32_t)(((mNormalFrameCount * 1000) / mSampleRate) * 1000); 479181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 479281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 479381784c37c61b09289654b979567a42bf73cd2b12Eric Laurentvoid AudioFlinger::MixerThread::cacheParameters_l() 479481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 479581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent PlaybackThread::cacheParameters_l(); 479681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 479781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // FIXME: Relaxed timing because of a certain device that can't meet latency 479881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // Should be reduced to 2x after the vendor fixes the driver issue 479981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // increase threshold again due to low power audio mode. The way this warning 480081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // threshold is calculated and its usefulness should be reconsidered anyway. 480181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent maxPeriod = seconds(mNormalFrameCount) / mSampleRate * 15; 480281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 480381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 480481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// ---------------------------------------------------------------------------- 480581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 480681784c37c61b09289654b979567a42bf73cd2b12Eric LaurentAudioFlinger::DirectOutputThread::DirectOutputThread(const sp<AudioFlinger>& audioFlinger, 4807e93cc03da360a1a0d2ad937c745ce8c8e8be81c2Eric Laurent AudioStreamOut* output, audio_io_handle_t id, audio_devices_t device, bool systemReady) 4808e93cc03da360a1a0d2ad937c745ce8c8e8be81c2Eric Laurent : PlaybackThread(audioFlinger, output, id, device, DIRECT, systemReady) 480981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // mLeftVolFloat, mRightVolFloat 481081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 481181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 481281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 4813bfb1b832079bbb9426f72f3863199a54aefd02daEric LaurentAudioFlinger::DirectOutputThread::DirectOutputThread(const sp<AudioFlinger>& audioFlinger, 4814bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent AudioStreamOut* output, audio_io_handle_t id, uint32_t device, 4815e93cc03da360a1a0d2ad937c745ce8c8e8be81c2Eric Laurent ThreadBase::type_t type, bool systemReady) 4816e93cc03da360a1a0d2ad937c745ce8c8e8be81c2Eric Laurent : PlaybackThread(audioFlinger, output, id, device, type, systemReady) 4817bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent // mLeftVolFloat, mRightVolFloat 481810cbff139360f3f642e0e3b3ccf2d463dbed22cfAndy Hung , mVolumeShaperActive(false) 4819bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent{ 4820bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent} 4821bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent 482281784c37c61b09289654b979567a42bf73cd2b12Eric LaurentAudioFlinger::DirectOutputThread::~DirectOutputThread() 482381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 482481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 482581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 48265850c4c8eecbe0db3cee8511a4f82cb443e27d08Eric Laurentvoid AudioFlinger::DirectOutputThread::processVolume_l(Track *track, bool lastTrack) 4827bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent{ 4828bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent float left, right; 4829bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent 4830bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent if (mMasterMute || mStreamTypes[track->streamType()].mute) { 4831bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent left = right = 0; 4832bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent } else { 4833bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent float typeVolume = mStreamTypes[track->streamType()].volume; 4834bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent float v = mMasterVolume * typeVolume; 48355bba2f6916dbe00aea7c0521faa0c6ed42114a75Eric Laurent sp<AudioTrackServerProxy> proxy = track->mAudioTrackServerProxy; 48369fc8b5cd4a64ef07e84c69112461324d5c13a0b0Andy Hung 483710cbff139360f3f642e0e3b3ccf2d463dbed22cfAndy Hung // Get volumeshaper scaling 483810cbff139360f3f642e0e3b3ccf2d463dbed22cfAndy Hung std::pair<float /* volume */, bool /* active */> 483910cbff139360f3f642e0e3b3ccf2d463dbed22cfAndy Hung vh = track->getVolumeHandler()->getVolume( 48409fc8b5cd4a64ef07e84c69112461324d5c13a0b0Andy Hung track->mAudioTrackServerProxy->framesReleased()); 484110cbff139360f3f642e0e3b3ccf2d463dbed22cfAndy Hung v *= vh.first; 484210cbff139360f3f642e0e3b3ccf2d463dbed22cfAndy Hung mVolumeShaperActive = vh.second; 48439fc8b5cd4a64ef07e84c69112461324d5c13a0b0Andy Hung 4844c56f3426099a3cf2d07ccff8886050c7fbce140fGlenn Kasten gain_minifloat_packed_t vlr = proxy->getVolumeLR(); 4845c56f3426099a3cf2d07ccff8886050c7fbce140fGlenn Kasten left = float_from_gain(gain_minifloat_unpack_left(vlr)); 4846c56f3426099a3cf2d07ccff8886050c7fbce140fGlenn Kasten if (left > GAIN_FLOAT_UNITY) { 4847c56f3426099a3cf2d07ccff8886050c7fbce140fGlenn Kasten left = GAIN_FLOAT_UNITY; 4848c56f3426099a3cf2d07ccff8886050c7fbce140fGlenn Kasten } 4849c56f3426099a3cf2d07ccff8886050c7fbce140fGlenn Kasten left *= v; 4850c56f3426099a3cf2d07ccff8886050c7fbce140fGlenn Kasten right = float_from_gain(gain_minifloat_unpack_right(vlr)); 4851c56f3426099a3cf2d07ccff8886050c7fbce140fGlenn Kasten if (right > GAIN_FLOAT_UNITY) { 4852c56f3426099a3cf2d07ccff8886050c7fbce140fGlenn Kasten right = GAIN_FLOAT_UNITY; 4853c56f3426099a3cf2d07ccff8886050c7fbce140fGlenn Kasten } 4854c56f3426099a3cf2d07ccff8886050c7fbce140fGlenn Kasten right *= v; 4855bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent } 4856bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent 4857bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent if (lastTrack) { 4858bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent if (left != mLeftVolFloat || right != mRightVolFloat) { 4859bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent mLeftVolFloat = left; 4860bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent mRightVolFloat = right; 4861bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent 4862bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent // Convert volumes from float to 8.24 4863bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent uint32_t vl = (uint32_t)(left * (1 << 24)); 4864bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent uint32_t vr = (uint32_t)(right * (1 << 24)); 4865bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent 4866bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent // Delegate volume control to effect in track effect chain if needed 4867bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent // only one effect chain can be present on DirectOutputThread, so if 4868bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent // there is one, the track is connected to it 4869bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent if (!mEffectChains.isEmpty()) { 4870bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent mEffectChains[0]->setVolume_l(&vl, &vr); 4871bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent left = (float)vl / (1 << 24); 4872bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent right = (float)vr / (1 << 24); 4873bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent } 48741dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov status_t result = mOutput->stream->setVolume(left, right); 48751dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov ALOGE_IF(result != OK, "Error when setting output stream volume: %d", result); 4876bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent } 4877bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent } 4878bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent} 4879bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent 488043b4dcc660e6da96285e4672ae371070ab845401Phil Burkvoid AudioFlinger::DirectOutputThread::onAddNewTrack_l() 488143b4dcc660e6da96285e4672ae371070ab845401Phil Burk{ 488243b4dcc660e6da96285e4672ae371070ab845401Phil Burk sp<Track> previousTrack = mPreviousTrack.promote(); 4883dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hung sp<Track> latestTrack = mActiveTracks.getLatest(); 488443b4dcc660e6da96285e4672ae371070ab845401Phil Burk 48850f0631eb55b1f0a7f4b62212b78a3faa0b49919bEric Laurent if (previousTrack != 0 && latestTrack != 0) { 48860f0631eb55b1f0a7f4b62212b78a3faa0b49919bEric Laurent if (mType == DIRECT) { 48870f0631eb55b1f0a7f4b62212b78a3faa0b49919bEric Laurent if (previousTrack.get() != latestTrack.get()) { 48880f0631eb55b1f0a7f4b62212b78a3faa0b49919bEric Laurent mFlushPending = true; 48890f0631eb55b1f0a7f4b62212b78a3faa0b49919bEric Laurent } 48900f0631eb55b1f0a7f4b62212b78a3faa0b49919bEric Laurent } else /* mType == OFFLOAD */ { 48910f0631eb55b1f0a7f4b62212b78a3faa0b49919bEric Laurent if (previousTrack->sessionId() != latestTrack->sessionId()) { 48920f0631eb55b1f0a7f4b62212b78a3faa0b49919bEric Laurent mFlushPending = true; 48930f0631eb55b1f0a7f4b62212b78a3faa0b49919bEric Laurent } 48940f0631eb55b1f0a7f4b62212b78a3faa0b49919bEric Laurent } 489543b4dcc660e6da96285e4672ae371070ab845401Phil Burk } 489643b4dcc660e6da96285e4672ae371070ab845401Phil Burk PlaybackThread::onAddNewTrack_l(); 489743b4dcc660e6da96285e4672ae371070ab845401Phil Burk} 4898bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent 489981784c37c61b09289654b979567a42bf73cd2b12Eric LaurentAudioFlinger::PlaybackThread::mixer_state AudioFlinger::DirectOutputThread::prepareTracks_l( 490081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent Vector< sp<Track> > *tracksToRemove 490181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent) 490281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 4903d595b7c858c481a07745674ce2d8a6690e980e74Eric Laurent size_t count = mActiveTracks.size(); 490481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mixer_state mixerStatus = MIXER_IDLE; 4905d1f69b0b17acbd96987ecb2f3378abd394d05903Eric Laurent bool doHwPause = false; 4906d1f69b0b17acbd96987ecb2f3378abd394d05903Eric Laurent bool doHwResume = false; 490781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 490881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // find out which tracks need to be processed 4909dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hung for (const sp<Track> &t : mActiveTracks) { 49105850c4c8eecbe0db3cee8511a4f82cb443e27d08Eric Laurent if (t->isInvalid()) { 491143b4dcc660e6da96285e4672ae371070ab845401Phil Burk ALOGW("An invalidated track shouldn't be in active list"); 49125850c4c8eecbe0db3cee8511a4f82cb443e27d08Eric Laurent tracksToRemove->add(t); 491343b4dcc660e6da96285e4672ae371070ab845401Phil Burk continue; 491443b4dcc660e6da96285e4672ae371070ab845401Phil Burk } 491543b4dcc660e6da96285e4672ae371070ab845401Phil Burk 49165850c4c8eecbe0db3cee8511a4f82cb443e27d08Eric Laurent Track* const track = t.get(); 491757c4e6f7464d458eb52d209c2a63524913d6406dGlenn Kasten#ifdef VERY_VERY_VERBOSE_LOGGING 491881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent audio_track_cblk_t* cblk = track->cblk(); 491957c4e6f7464d458eb52d209c2a63524913d6406dGlenn Kasten#endif 4920fd4779740ec3e9e865d5514464df26d015354388Eric Laurent // Only consider last track started for volume and mixer state control. 4921fd4779740ec3e9e865d5514464df26d015354388Eric Laurent // In theory an older track could underrun and restart after the new one starts 4922fd4779740ec3e9e865d5514464df26d015354388Eric Laurent // but as we only care about the transition phase between two tracks on a 4923fd4779740ec3e9e865d5514464df26d015354388Eric Laurent // direct output, it is not a problem to ignore the underrun case. 4924dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hung sp<Track> l = mActiveTracks.getLatest(); 49255850c4c8eecbe0db3cee8511a4f82cb443e27d08Eric Laurent bool last = l.get() == track; 492681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 49276fc2a7c81f62b1e21487ae37e11aae6241bc3eadPhil Burk if (track->isPausing()) { 4928d1f69b0b17acbd96987ecb2f3378abd394d05903Eric Laurent track->setPaused(); 49296fc2a7c81f62b1e21487ae37e11aae6241bc3eadPhil Burk if (mHwSupportsPause && last && !mHwPaused) { 4930d1f69b0b17acbd96987ecb2f3378abd394d05903Eric Laurent doHwPause = true; 4931d1f69b0b17acbd96987ecb2f3378abd394d05903Eric Laurent mHwPaused = true; 4932d1f69b0b17acbd96987ecb2f3378abd394d05903Eric Laurent } 4933d1f69b0b17acbd96987ecb2f3378abd394d05903Eric Laurent tracksToRemove->add(track); 4934d1f69b0b17acbd96987ecb2f3378abd394d05903Eric Laurent } else if (track->isFlushPending()) { 4935d1f69b0b17acbd96987ecb2f3378abd394d05903Eric Laurent track->flushAck(); 4936d1f69b0b17acbd96987ecb2f3378abd394d05903Eric Laurent if (last) { 493743b4dcc660e6da96285e4672ae371070ab845401Phil Burk mFlushPending = true; 4938d1f69b0b17acbd96987ecb2f3378abd394d05903Eric Laurent } 49396fc2a7c81f62b1e21487ae37e11aae6241bc3eadPhil Burk } else if (track->isResumePending()) { 4940d1f69b0b17acbd96987ecb2f3378abd394d05903Eric Laurent track->resumeAck(); 49413df841a10b4d553949c518ad52f1af8dcb365058Eric Laurent if (last) { 49423df841a10b4d553949c518ad52f1af8dcb365058Eric Laurent mLeftVolFloat = mRightVolFloat = -1.0; 49433df841a10b4d553949c518ad52f1af8dcb365058Eric Laurent if (mHwPaused) { 49443df841a10b4d553949c518ad52f1af8dcb365058Eric Laurent doHwResume = true; 49453df841a10b4d553949c518ad52f1af8dcb365058Eric Laurent mHwPaused = false; 49463df841a10b4d553949c518ad52f1af8dcb365058Eric Laurent } 4947d1f69b0b17acbd96987ecb2f3378abd394d05903Eric Laurent } 4948d1f69b0b17acbd96987ecb2f3378abd394d05903Eric Laurent } 4949d1f69b0b17acbd96987ecb2f3378abd394d05903Eric Laurent 495081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // The first time a track is added we wait 495199adee3c3d9cde6819741a38163954808fea270aPhil Burk // for all its buffers to be filled before processing it. 495299adee3c3d9cde6819741a38163954808fea270aPhil Burk // Allow draining the buffer in case the client 495399adee3c3d9cde6819741a38163954808fea270aPhil Burk // app does not call stop() and relies on underrun to stop: 495499adee3c3d9cde6819741a38163954808fea270aPhil Burk // hence the test on (track->mRetryCount > 1). 495599adee3c3d9cde6819741a38163954808fea270aPhil Burk // If retryCount<=1 then track is about to underrun and be removed. 4956ca5e6143740299c877d69e97f7968cd04476d32cPhil Burk // Do not use a high threshold for compressed audio. 495781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent uint32_t minFrames; 495899adee3c3d9cde6819741a38163954808fea270aPhil Burk if ((track->sharedBuffer() == 0) && !track->isStopping_1() && !track->isPausing() 4959fdb3c07db5d44535eb8c3ec46dc78ad8446c01ebPhil Burk && (track->mRetryCount > 1) && audio_has_proportional_frames(mFormat)) { 496081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent minFrames = mNormalFrameCount; 496181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } else { 496281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent minFrames = 1; 496381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 4964bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent 4965ab5cdbaf65ca509681d2726aacdf3ac8bfb6b3faEric Laurent if ((track->framesReady() >= minFrames) && track->isReady() && !track->isPaused() && 4966ab5cdbaf65ca509681d2726aacdf3ac8bfb6b3faEric Laurent !track->isStopping_2() && !track->isStopped()) 496781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent { 4968f20e1d8df84c5fbeeace0052d100982ae39bb7a4Glenn Kasten ALOGVV("track %d s=%08x [OK]", track->name(), cblk->mServer); 496981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 497081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (track->mFillingUpStatus == Track::FS_FILLED) { 497181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent track->mFillingUpStatus = Track::FS_ACTIVE; 49723df841a10b4d553949c518ad52f1af8dcb365058Eric Laurent if (last) { 49733df841a10b4d553949c518ad52f1af8dcb365058Eric Laurent // make sure processVolume_l() will apply new volume even if 0 49743df841a10b4d553949c518ad52f1af8dcb365058Eric Laurent mLeftVolFloat = mRightVolFloat = -1.0; 49753df841a10b4d553949c518ad52f1af8dcb365058Eric Laurent } 4976d1f69b0b17acbd96987ecb2f3378abd394d05903Eric Laurent if (!mHwSupportsPause) { 4977d1f69b0b17acbd96987ecb2f3378abd394d05903Eric Laurent track->resumeAck(); 497881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 497981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 498081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 498181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // compute volume for this track 4982bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent processVolume_l(track, last); 4983bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent if (last) { 498443b4dcc660e6da96285e4672ae371070ab845401Phil Burk sp<Track> previousTrack = mPreviousTrack.promote(); 498543b4dcc660e6da96285e4672ae371070ab845401Phil Burk if (previousTrack != 0) { 498643b4dcc660e6da96285e4672ae371070ab845401Phil Burk if (track != previousTrack.get()) { 498743b4dcc660e6da96285e4672ae371070ab845401Phil Burk // Flush any data still being written from last track 498843b4dcc660e6da96285e4672ae371070ab845401Phil Burk mBytesRemaining = 0; 49890f0631eb55b1f0a7f4b62212b78a3faa0b49919bEric Laurent // Invalidate previous track to force a seek when resuming. 49900f0631eb55b1f0a7f4b62212b78a3faa0b49919bEric Laurent previousTrack->invalidate(); 499143b4dcc660e6da96285e4672ae371070ab845401Phil Burk } 499243b4dcc660e6da96285e4672ae371070ab845401Phil Burk } 499343b4dcc660e6da96285e4672ae371070ab845401Phil Burk mPreviousTrack = track; 499443b4dcc660e6da96285e4672ae371070ab845401Phil Burk 4995d595b7c858c481a07745674ce2d8a6690e980e74Eric Laurent // reset retry count 4996d595b7c858c481a07745674ce2d8a6690e980e74Eric Laurent track->mRetryCount = kMaxTrackRetriesDirect; 49975850c4c8eecbe0db3cee8511a4f82cb443e27d08Eric Laurent mActiveTrack = t; 4998d595b7c858c481a07745674ce2d8a6690e980e74Eric Laurent mixerStatus = MIXER_TRACKS_READY; 49995cff403679fc44c8293de81aed31c459c6129243Eric Laurent if (mHwPaused) { 50000f7b5f2b231caf87da9b20b74d086e5a9d6f4a9dEric Laurent doHwResume = true; 50010f7b5f2b231caf87da9b20b74d086e5a9d6f4a9dEric Laurent mHwPaused = false; 50020f7b5f2b231caf87da9b20b74d086e5a9d6f4a9dEric Laurent } 5003d595b7c858c481a07745674ce2d8a6690e980e74Eric Laurent } 500481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } else { 5005d595b7c858c481a07745674ce2d8a6690e980e74Eric Laurent // clear effect chain input buffer if the last active track started underruns 5006d595b7c858c481a07745674ce2d8a6690e980e74Eric Laurent // to avoid sending previous audio buffer again to effects 5007fd4779740ec3e9e865d5514464df26d015354388Eric Laurent if (!mEffectChains.isEmpty() && last) { 500881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mEffectChains[0]->clearInputBuffer(); 500981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 5010ab5cdbaf65ca509681d2726aacdf3ac8bfb6b3faEric Laurent if (track->isStopping_1()) { 5011ab5cdbaf65ca509681d2726aacdf3ac8bfb6b3faEric Laurent track->mState = TrackBase::STOPPING_2; 5012b369cafd67beb63dd0278dba543f519956208a7fEric Laurent if (last && mHwPaused) { 5013b369cafd67beb63dd0278dba543f519956208a7fEric Laurent doHwResume = true; 5014b369cafd67beb63dd0278dba543f519956208a7fEric Laurent mHwPaused = false; 5015b369cafd67beb63dd0278dba543f519956208a7fEric Laurent } 5016ab5cdbaf65ca509681d2726aacdf3ac8bfb6b3faEric Laurent } 5017ab5cdbaf65ca509681d2726aacdf3ac8bfb6b3faEric Laurent if ((track->sharedBuffer() != 0) || track->isStopped() || 5018ab5cdbaf65ca509681d2726aacdf3ac8bfb6b3faEric Laurent track->isStopping_2() || track->isPaused()) { 501981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // We have consumed all the buffers of this track. 502081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // Remove it from the list of active tracks. 5021ab5cdbaf65ca509681d2726aacdf3ac8bfb6b3faEric Laurent size_t audioHALFrames; 5022fdb3c07db5d44535eb8c3ec46dc78ad8446c01ebPhil Burk if (audio_has_proportional_frames(mFormat)) { 5023ab5cdbaf65ca509681d2726aacdf3ac8bfb6b3faEric Laurent audioHALFrames = (latency_l() * mSampleRate) / 1000; 5024ab5cdbaf65ca509681d2726aacdf3ac8bfb6b3faEric Laurent } else { 5025ab5cdbaf65ca509681d2726aacdf3ac8bfb6b3faEric Laurent audioHALFrames = 0; 5026ab5cdbaf65ca509681d2726aacdf3ac8bfb6b3faEric Laurent } 5027ab5cdbaf65ca509681d2726aacdf3ac8bfb6b3faEric Laurent 5028818e7a32ce3633980138aff2c2bfcc5158b3cfccAndy Hung int64_t framesWritten = mBytesWritten / mFrameSize; 5029fd4779740ec3e9e865d5514464df26d015354388Eric Laurent if (mStandby || !last || 5030fd4779740ec3e9e865d5514464df26d015354388Eric Laurent track->presentationComplete(framesWritten, audioHALFrames)) { 5031ab5cdbaf65ca509681d2726aacdf3ac8bfb6b3faEric Laurent if (track->isStopping_2()) { 5032ab5cdbaf65ca509681d2726aacdf3ac8bfb6b3faEric Laurent track->mState = TrackBase::STOPPED; 5033ab5cdbaf65ca509681d2726aacdf3ac8bfb6b3faEric Laurent } 503481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (track->isStopped()) { 503581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent track->reset(); 503681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 5037d595b7c858c481a07745674ce2d8a6690e980e74Eric Laurent tracksToRemove->add(track); 503881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 503981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } else { 504081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // No buffers for this track. Give it a few chances to 504181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // fill a buffer, then remove it from active list. 5042d595b7c858c481a07745674ce2d8a6690e980e74Eric Laurent // Only consider last track started for mixer state control 504381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (--(track->mRetryCount) <= 0) { 504481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent ALOGV("BUFFER TIMEOUT: remove(%d) from active list", track->name()); 5045d595b7c858c481a07745674ce2d8a6690e980e74Eric Laurent tracksToRemove->add(track); 5046a23f17ac334ff20a11ee63dd177cb1080e44c483Eric Laurent // indicate to client process that the track was disabled because of underrun; 5047a23f17ac334ff20a11ee63dd177cb1080e44c483Eric Laurent // it will then automatically call start() when data is available 50484d231dc0ee34380956c71cbe18a750e487a69601Eric Laurent track->disable(); 5049bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent } else if (last) { 5050ca5e6143740299c877d69e97f7968cd04476d32cPhil Burk ALOGW("pause because of UNDERRUN, framesReady = %zu," 5051ca5e6143740299c877d69e97f7968cd04476d32cPhil Burk "minFrames = %u, mFormat = %#x", 5052ca5e6143740299c877d69e97f7968cd04476d32cPhil Burk track->framesReady(), minFrames, mFormat); 505381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mixerStatus = MIXER_TRACKS_ENABLED; 50545cff403679fc44c8293de81aed31c459c6129243Eric Laurent if (mHwSupportsPause && !mHwPaused && !mStandby) { 50550f7b5f2b231caf87da9b20b74d086e5a9d6f4a9dEric Laurent doHwPause = true; 50560f7b5f2b231caf87da9b20b74d086e5a9d6f4a9dEric Laurent mHwPaused = true; 50570f7b5f2b231caf87da9b20b74d086e5a9d6f4a9dEric Laurent } 505881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 505981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 506081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 506181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 506281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 5063d1f69b0b17acbd96987ecb2f3378abd394d05903Eric Laurent // if an active track did not command a flush, check for pending flush on stopped tracks 506443b4dcc660e6da96285e4672ae371070ab845401Phil Burk if (!mFlushPending) { 5065d1f69b0b17acbd96987ecb2f3378abd394d05903Eric Laurent for (size_t i = 0; i < mTracks.size(); i++) { 5066d1f69b0b17acbd96987ecb2f3378abd394d05903Eric Laurent if (mTracks[i]->isFlushPending()) { 5067d1f69b0b17acbd96987ecb2f3378abd394d05903Eric Laurent mTracks[i]->flushAck(); 506843b4dcc660e6da96285e4672ae371070ab845401Phil Burk mFlushPending = true; 5069d1f69b0b17acbd96987ecb2f3378abd394d05903Eric Laurent } 5070d1f69b0b17acbd96987ecb2f3378abd394d05903Eric Laurent } 5071d1f69b0b17acbd96987ecb2f3378abd394d05903Eric Laurent } 5072d1f69b0b17acbd96987ecb2f3378abd394d05903Eric Laurent 5073d1f69b0b17acbd96987ecb2f3378abd394d05903Eric Laurent // make sure the pause/flush/resume sequence is executed in the right order. 5074d1f69b0b17acbd96987ecb2f3378abd394d05903Eric Laurent // If a flush is pending and a track is active but the HW is not paused, force a HW pause 5075d1f69b0b17acbd96987ecb2f3378abd394d05903Eric Laurent // before flush and then resume HW. This can happen in case of pause/flush/resume 5076d1f69b0b17acbd96987ecb2f3378abd394d05903Eric Laurent // if resume is received before pause is executed. 5077d1f69b0b17acbd96987ecb2f3378abd394d05903Eric Laurent if (mHwSupportsPause && !mStandby && 507843b4dcc660e6da96285e4672ae371070ab845401Phil Burk (doHwPause || (mFlushPending && !mHwPaused && (count != 0)))) { 50791dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov status_t result = mOutput->stream->pause(); 50801dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov ALOGE_IF(result != OK, "Error when pausing output stream: %d", result); 5081d1f69b0b17acbd96987ecb2f3378abd394d05903Eric Laurent } 508243b4dcc660e6da96285e4672ae371070ab845401Phil Burk if (mFlushPending) { 5083d1f69b0b17acbd96987ecb2f3378abd394d05903Eric Laurent flushHw_l(); 5084d1f69b0b17acbd96987ecb2f3378abd394d05903Eric Laurent } 5085d1f69b0b17acbd96987ecb2f3378abd394d05903Eric Laurent if (mHwSupportsPause && !mStandby && doHwResume) { 50861dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov status_t result = mOutput->stream->resume(); 50871dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov ALOGE_IF(result != OK, "Error when resuming output stream: %d", result); 5088d1f69b0b17acbd96987ecb2f3378abd394d05903Eric Laurent } 508981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // remove all the tracks that need to be... 5090bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent removeTracks_l(*tracksToRemove); 509181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 509281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent return mixerStatus; 509381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 509481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 509581784c37c61b09289654b979567a42bf73cd2b12Eric Laurentvoid AudioFlinger::DirectOutputThread::threadLoop_mix() 509681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 509781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent size_t frameCount = mFrameCount; 50982098f2744cedf2dc3fa36f608aa965a34602e7c0Andy Hung int8_t *curBuf = (int8_t *)mSinkBuffer; 509981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // output audio to hardware 510081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent while (frameCount) { 510134542acfa25c6413c87a94b6f7cc315a0c496277Glenn Kasten AudioBufferProvider::Buffer buffer; 510281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent buffer.frameCount = frameCount; 5103062e67a26e0553dd142be622821f493df541f0c6Phil Burk status_t status = mActiveTrack->getNextBuffer(&buffer); 5104062e67a26e0553dd142be622821f493df541f0c6Phil Burk if (status != NO_ERROR || buffer.raw == NULL) { 5105517161856d74f5fe39cce131f29b977bc1745991Eric Laurent // no need to pad with 0 for compressed audio 5106517161856d74f5fe39cce131f29b977bc1745991Eric Laurent if (audio_has_proportional_frames(mFormat)) { 5107517161856d74f5fe39cce131f29b977bc1745991Eric Laurent memset(curBuf, 0, frameCount * mFrameSize); 5108517161856d74f5fe39cce131f29b977bc1745991Eric Laurent } 510981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent break; 511081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 511181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent memcpy(curBuf, buffer.raw, buffer.frameCount * mFrameSize); 511281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent frameCount -= buffer.frameCount; 511381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent curBuf += buffer.frameCount * mFrameSize; 511481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mActiveTrack->releaseBuffer(&buffer); 511581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 51162098f2744cedf2dc3fa36f608aa965a34602e7c0Andy Hung mCurrentWriteLength = curBuf - (int8_t *)mSinkBuffer; 5117ad9cb8b88e4f8face23f01d8dc89fa769dacb50fEric Laurent mSleepTimeUs = 0; 5118ad9cb8b88e4f8face23f01d8dc89fa769dacb50fEric Laurent mStandbyTimeNs = systemTime() + mStandbyDelayNs; 511981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mActiveTrack.clear(); 512081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 512181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 512281784c37c61b09289654b979567a42bf73cd2b12Eric Laurentvoid AudioFlinger::DirectOutputThread::threadLoop_sleepTime() 512381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 5124d1f69b0b17acbd96987ecb2f3378abd394d05903Eric Laurent // do not write to HAL when paused 51250f7b5f2b231caf87da9b20b74d086e5a9d6f4a9dEric Laurent if (mHwPaused || (usesHwAvSync() && mStandby)) { 5126ad9cb8b88e4f8face23f01d8dc89fa769dacb50fEric Laurent mSleepTimeUs = mIdleSleepTimeUs; 5127d1f69b0b17acbd96987ecb2f3378abd394d05903Eric Laurent return; 5128d1f69b0b17acbd96987ecb2f3378abd394d05903Eric Laurent } 5129ad9cb8b88e4f8face23f01d8dc89fa769dacb50fEric Laurent if (mSleepTimeUs == 0) { 513081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (mMixerStatus == MIXER_TRACKS_ENABLED) { 5131e93cc03da360a1a0d2ad937c745ce8c8e8be81c2Eric Laurent mSleepTimeUs = mActiveSleepTimeUs; 513281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } else { 5133ad9cb8b88e4f8face23f01d8dc89fa769dacb50fEric Laurent mSleepTimeUs = mIdleSleepTimeUs; 513481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 5135fdb3c07db5d44535eb8c3ec46dc78ad8446c01ebPhil Burk } else if (mBytesWritten != 0 && audio_has_proportional_frames(mFormat)) { 51362098f2744cedf2dc3fa36f608aa965a34602e7c0Andy Hung memset(mSinkBuffer, 0, mFrameCount * mFrameSize); 5137ad9cb8b88e4f8face23f01d8dc89fa769dacb50fEric Laurent mSleepTimeUs = 0; 513881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 513981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 514081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 5141d1f69b0b17acbd96987ecb2f3378abd394d05903Eric Laurentvoid AudioFlinger::DirectOutputThread::threadLoop_exit() 5142d1f69b0b17acbd96987ecb2f3378abd394d05903Eric Laurent{ 5143d1f69b0b17acbd96987ecb2f3378abd394d05903Eric Laurent { 5144d1f69b0b17acbd96987ecb2f3378abd394d05903Eric Laurent Mutex::Autolock _l(mLock); 5145d1f69b0b17acbd96987ecb2f3378abd394d05903Eric Laurent for (size_t i = 0; i < mTracks.size(); i++) { 5146d1f69b0b17acbd96987ecb2f3378abd394d05903Eric Laurent if (mTracks[i]->isFlushPending()) { 5147d1f69b0b17acbd96987ecb2f3378abd394d05903Eric Laurent mTracks[i]->flushAck(); 514843b4dcc660e6da96285e4672ae371070ab845401Phil Burk mFlushPending = true; 5149d1f69b0b17acbd96987ecb2f3378abd394d05903Eric Laurent } 5150d1f69b0b17acbd96987ecb2f3378abd394d05903Eric Laurent } 515143b4dcc660e6da96285e4672ae371070ab845401Phil Burk if (mFlushPending) { 5152d1f69b0b17acbd96987ecb2f3378abd394d05903Eric Laurent flushHw_l(); 5153d1f69b0b17acbd96987ecb2f3378abd394d05903Eric Laurent } 5154d1f69b0b17acbd96987ecb2f3378abd394d05903Eric Laurent } 5155d1f69b0b17acbd96987ecb2f3378abd394d05903Eric Laurent PlaybackThread::threadLoop_exit(); 5156d1f69b0b17acbd96987ecb2f3378abd394d05903Eric Laurent} 5157d1f69b0b17acbd96987ecb2f3378abd394d05903Eric Laurent 5158d1f69b0b17acbd96987ecb2f3378abd394d05903Eric Laurent// must be called with thread mutex locked 5159d1f69b0b17acbd96987ecb2f3378abd394d05903Eric Laurentbool AudioFlinger::DirectOutputThread::shouldStandby_l() 5160d1f69b0b17acbd96987ecb2f3378abd394d05903Eric Laurent{ 5161d1f69b0b17acbd96987ecb2f3378abd394d05903Eric Laurent bool trackPaused = false; 5162b369cafd67beb63dd0278dba543f519956208a7fEric Laurent bool trackStopped = false; 5163d1f69b0b17acbd96987ecb2f3378abd394d05903Eric Laurent 51649cd7ad101315e0bff4c5f171706c6f80c7e22644vivek mehta if ((mType == DIRECT) && audio_is_linear_pcm(mFormat) && !usesHwAvSync()) { 51659cd7ad101315e0bff4c5f171706c6f80c7e22644vivek mehta return !mStandby; 51669cd7ad101315e0bff4c5f171706c6f80c7e22644vivek mehta } 51679cd7ad101315e0bff4c5f171706c6f80c7e22644vivek mehta 5168d1f69b0b17acbd96987ecb2f3378abd394d05903Eric Laurent // do not put the HAL in standby when paused. AwesomePlayer clear the offloaded AudioTrack 5169d1f69b0b17acbd96987ecb2f3378abd394d05903Eric Laurent // after a timeout and we will enter standby then. 5170d1f69b0b17acbd96987ecb2f3378abd394d05903Eric Laurent if (mTracks.size() > 0) { 5171d1f69b0b17acbd96987ecb2f3378abd394d05903Eric Laurent trackPaused = mTracks[mTracks.size() - 1]->isPaused(); 5172b369cafd67beb63dd0278dba543f519956208a7fEric Laurent trackStopped = mTracks[mTracks.size() - 1]->isStopped() || 5173b369cafd67beb63dd0278dba543f519956208a7fEric Laurent mTracks[mTracks.size() - 1]->mState == TrackBase::IDLE; 5174d1f69b0b17acbd96987ecb2f3378abd394d05903Eric Laurent } 5175d1f69b0b17acbd96987ecb2f3378abd394d05903Eric Laurent 51765cff403679fc44c8293de81aed31c459c6129243Eric Laurent return !mStandby && !(trackPaused || (mHwPaused && !trackStopped)); 5177d1f69b0b17acbd96987ecb2f3378abd394d05903Eric Laurent} 5178d1f69b0b17acbd96987ecb2f3378abd394d05903Eric Laurent 517981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// getTrackName_l() must be called with ThreadBase::mLock held 51800f11b51a57bc9062c4fe8af73747319cedabc5d6Glenn Kastenint AudioFlinger::DirectOutputThread::getTrackName_l(audio_channel_mask_t channelMask __unused, 5181ad7dd9610b6fafa81baf69607f4ac669da88182aEric Laurent audio_format_t format __unused, audio_session_t sessionId __unused, uid_t uid) 518281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 5183ad7dd9610b6fafa81baf69607f4ac669da88182aEric Laurent if (trackCountForUid_l(uid) > (PlaybackThread::kMaxTracksPerUid - 1)) { 5184ad7dd9610b6fafa81baf69607f4ac669da88182aEric Laurent return -1; 5185ad7dd9610b6fafa81baf69607f4ac669da88182aEric Laurent } 518681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent return 0; 518781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 518881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 518981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// deleteTrackName_l() must be called with ThreadBase::mLock held 51900f11b51a57bc9062c4fe8af73747319cedabc5d6Glenn Kastenvoid AudioFlinger::DirectOutputThread::deleteTrackName_l(int name __unused) 519181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 519281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 519381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 51941035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent// checkForNewParameter_l() must be called with ThreadBase::mLock held 51951035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurentbool AudioFlinger::DirectOutputThread::checkForNewParameter_l(const String8& keyValuePair, 51961035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent status_t& status) 519781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 519881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent bool reconfig = false; 519942537be61479e59c4718e1304364551c1454f63cEric Laurent bool a2dpDeviceChanged = false; 520081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 52011035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent status = NO_ERROR; 52021035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent 52031035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent AudioParameter param = AudioParameter(keyValuePair); 52041035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent int value; 52051035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent if (param.getInt(String8(AudioParameter::keyRouting), value) == NO_ERROR) { 52061035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent // forward device change to effects that have requested to be 52071035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent // aware of attached audio device. 52081035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent if (value != AUDIO_DEVICE_NONE) { 520942537be61479e59c4718e1304364551c1454f63cEric Laurent a2dpDeviceChanged = 521042537be61479e59c4718e1304364551c1454f63cEric Laurent (mOutDevice & AUDIO_DEVICE_OUT_ALL_A2DP) != (value & AUDIO_DEVICE_OUT_ALL_A2DP); 52111035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent mOutDevice = value; 52121035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent for (size_t i = 0; i < mEffectChains.size(); i++) { 52131035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent mEffectChains[i]->setDevice_l(mOutDevice); 5214c125f38cd0ae35409a01b98a99e483550daa1313Glenn Kasten } 5215c125f38cd0ae35409a01b98a99e483550daa1313Glenn Kasten } 52161035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent } 52171035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent if (param.getInt(String8(AudioParameter::keyFrameCount), value) == NO_ERROR) { 52181035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent // do not accept frame count changes if tracks are open as the track buffer 52191035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent // size depends on frame count and correct behavior would not be garantied 52201035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent // if frame count is changed after track creation 52211035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent if (!mTracks.isEmpty()) { 52221035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent status = INVALID_OPERATION; 52231035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent } else { 52241035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent reconfig = true; 522581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 52261035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent } 52271035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent if (status == NO_ERROR) { 52281dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov status = mOutput->stream->setParameters(keyValuePair); 52291035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent if (!mStandby && status == INVALID_OPERATION) { 5230062e67a26e0553dd142be622821f493df541f0c6Phil Burk mOutput->standby(); 52311035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent mStandby = true; 52321035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent mBytesWritten = 0; 52331dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov status = mOutput->stream->setParameters(keyValuePair); 52341035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent } 52351035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent if (status == NO_ERROR && reconfig) { 52361035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent readOutputParameters_l(); 523773e26b661af50be2c0a4ff6c9ac85f7347a8b235Eric Laurent sendIoConfigEvent_l(AUDIO_OUTPUT_CONFIG_CHANGED); 523881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 523981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 52401035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent 524142537be61479e59c4718e1304364551c1454f63cEric Laurent return reconfig || a2dpDeviceChanged; 524281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 524381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 524481784c37c61b09289654b979567a42bf73cd2b12Eric Laurentuint32_t AudioFlinger::DirectOutputThread::activeSleepTimeUs() const 524581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 524681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent uint32_t time; 5247fdb3c07db5d44535eb8c3ec46dc78ad8446c01ebPhil Burk if (audio_has_proportional_frames(mFormat)) { 524881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent time = PlaybackThread::activeSleepTimeUs(); 524981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } else { 5250517161856d74f5fe39cce131f29b977bc1745991Eric Laurent time = kDirectMinSleepTimeUs; 525181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 525281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent return time; 525381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 525481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 525581784c37c61b09289654b979567a42bf73cd2b12Eric Laurentuint32_t AudioFlinger::DirectOutputThread::idleSleepTimeUs() const 525681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 525781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent uint32_t time; 5258fdb3c07db5d44535eb8c3ec46dc78ad8446c01ebPhil Burk if (audio_has_proportional_frames(mFormat)) { 525981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent time = (uint32_t)(((mFrameCount * 1000) / mSampleRate) * 1000) / 2; 526081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } else { 5261517161856d74f5fe39cce131f29b977bc1745991Eric Laurent time = kDirectMinSleepTimeUs; 526281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 526381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent return time; 526481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 526581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 526681784c37c61b09289654b979567a42bf73cd2b12Eric Laurentuint32_t AudioFlinger::DirectOutputThread::suspendSleepTimeUs() const 526781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 526881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent uint32_t time; 5269fdb3c07db5d44535eb8c3ec46dc78ad8446c01ebPhil Burk if (audio_has_proportional_frames(mFormat)) { 527081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent time = (uint32_t)(((mFrameCount * 1000) / mSampleRate) * 1000); 527181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } else { 5272517161856d74f5fe39cce131f29b977bc1745991Eric Laurent time = kDirectMinSleepTimeUs; 527381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 527481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent return time; 527581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 527681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 527781784c37c61b09289654b979567a42bf73cd2b12Eric Laurentvoid AudioFlinger::DirectOutputThread::cacheParameters_l() 527881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 527981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent PlaybackThread::cacheParameters_l(); 528081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 528181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // use shorter standby delay as on normal output to release 528281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // hardware resources as soon as possible 5283b369cafd67beb63dd0278dba543f519956208a7fEric Laurent // no delay on outputs with HW A/V sync 5284b369cafd67beb63dd0278dba543f519956208a7fEric Laurent if (usesHwAvSync()) { 5285ad9cb8b88e4f8face23f01d8dc89fa769dacb50fEric Laurent mStandbyDelayNs = 0; 5286fdb3c07db5d44535eb8c3ec46dc78ad8446c01ebPhil Burk } else if ((mType == OFFLOAD) && !audio_has_proportional_frames(mFormat)) { 5287ad9cb8b88e4f8face23f01d8dc89fa769dacb50fEric Laurent mStandbyDelayNs = kOffloadStandbyDelayNs; 52885cff403679fc44c8293de81aed31c459c6129243Eric Laurent } else { 5289ad9cb8b88e4f8face23f01d8dc89fa769dacb50fEric Laurent mStandbyDelayNs = microseconds(mActiveSleepTimeUs*2); 5290972a173d7d1de1a3b5a617aae3e2abb6e05ae02dEric Laurent } 529181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 529281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 5293e659ef420dae0caae84ab78f9df8952acb9ad3a0Eric Laurentvoid AudioFlinger::DirectOutputThread::flushHw_l() 5294e659ef420dae0caae84ab78f9df8952acb9ad3a0Eric Laurent{ 5295062e67a26e0553dd142be622821f493df541f0c6Phil Burk mOutput->flush(); 5296d1f69b0b17acbd96987ecb2f3378abd394d05903Eric Laurent mHwPaused = false; 529743b4dcc660e6da96285e4672ae371070ab845401Phil Burk mFlushPending = false; 5298e659ef420dae0caae84ab78f9df8952acb9ad3a0Eric Laurent} 5299e659ef420dae0caae84ab78f9df8952acb9ad3a0Eric Laurent 530010cbff139360f3f642e0e3b3ccf2d463dbed22cfAndy Hungint64_t AudioFlinger::DirectOutputThread::computeWaitTimeNs_l() const { 530110cbff139360f3f642e0e3b3ccf2d463dbed22cfAndy Hung // If a VolumeShaper is active, we must wake up periodically to update volume. 530210cbff139360f3f642e0e3b3ccf2d463dbed22cfAndy Hung const int64_t NS_PER_MS = 1000000; 530310cbff139360f3f642e0e3b3ccf2d463dbed22cfAndy Hung return mVolumeShaperActive ? 530410cbff139360f3f642e0e3b3ccf2d463dbed22cfAndy Hung kMinNormalSinkBufferSizeMs * NS_PER_MS : PlaybackThread::computeWaitTimeNs_l(); 530510cbff139360f3f642e0e3b3ccf2d463dbed22cfAndy Hung} 530610cbff139360f3f642e0e3b3ccf2d463dbed22cfAndy Hung 530781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// ---------------------------------------------------------------------------- 530881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 5309bfb1b832079bbb9426f72f3863199a54aefd02daEric LaurentAudioFlinger::AsyncCallbackThread::AsyncCallbackThread( 53104de95592980dba88a35b3dc8f3fd045588387a4fEric Laurent const wp<AudioFlinger::PlaybackThread>& playbackThread) 5311bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent : Thread(false /*canCallJava*/), 53124de95592980dba88a35b3dc8f3fd045588387a4fEric Laurent mPlaybackThread(playbackThread), 53133b4529e03c5fc7a44c22f9091ad15a269bfca3a8Eric Laurent mWriteAckSequence(0), 53144527b9ebc6a37b861f5a3bba68bcc63dc8d69adaHaynes Mathew George mDrainSequence(0), 53154527b9ebc6a37b861f5a3bba68bcc63dc8d69adaHaynes Mathew George mAsyncError(false) 5316bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent{ 5317bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent} 5318bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent 5319bfb1b832079bbb9426f72f3863199a54aefd02daEric LaurentAudioFlinger::AsyncCallbackThread::~AsyncCallbackThread() 5320bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent{ 5321bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent} 5322bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent 5323bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurentvoid AudioFlinger::AsyncCallbackThread::onFirstRef() 5324bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent{ 5325bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent run("Offload Cbk", ANDROID_PRIORITY_URGENT_AUDIO); 5326bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent} 5327bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent 5328bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurentbool AudioFlinger::AsyncCallbackThread::threadLoop() 5329bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent{ 5330bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent while (!exitPending()) { 53313b4529e03c5fc7a44c22f9091ad15a269bfca3a8Eric Laurent uint32_t writeAckSequence; 53323b4529e03c5fc7a44c22f9091ad15a269bfca3a8Eric Laurent uint32_t drainSequence; 53334527b9ebc6a37b861f5a3bba68bcc63dc8d69adaHaynes Mathew George bool asyncError; 5334bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent 5335bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent { 5336bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent Mutex::Autolock _l(mLock); 533724a325d6f8c4bbf9330e6ce0c769d46e04266ffcHaynes Mathew George while (!((mWriteAckSequence & 1) || 533824a325d6f8c4bbf9330e6ce0c769d46e04266ffcHaynes Mathew George (mDrainSequence & 1) || 53394527b9ebc6a37b861f5a3bba68bcc63dc8d69adaHaynes Mathew George mAsyncError || 534024a325d6f8c4bbf9330e6ce0c769d46e04266ffcHaynes Mathew George exitPending())) { 534124a325d6f8c4bbf9330e6ce0c769d46e04266ffcHaynes Mathew George mWaitWorkCV.wait(mLock); 534224a325d6f8c4bbf9330e6ce0c769d46e04266ffcHaynes Mathew George } 534324a325d6f8c4bbf9330e6ce0c769d46e04266ffcHaynes Mathew George 5344bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent if (exitPending()) { 5345bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent break; 5346bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent } 53473b4529e03c5fc7a44c22f9091ad15a269bfca3a8Eric Laurent ALOGV("AsyncCallbackThread mWriteAckSequence %d mDrainSequence %d", 53483b4529e03c5fc7a44c22f9091ad15a269bfca3a8Eric Laurent mWriteAckSequence, mDrainSequence); 53493b4529e03c5fc7a44c22f9091ad15a269bfca3a8Eric Laurent writeAckSequence = mWriteAckSequence; 53503b4529e03c5fc7a44c22f9091ad15a269bfca3a8Eric Laurent mWriteAckSequence &= ~1; 53513b4529e03c5fc7a44c22f9091ad15a269bfca3a8Eric Laurent drainSequence = mDrainSequence; 53523b4529e03c5fc7a44c22f9091ad15a269bfca3a8Eric Laurent mDrainSequence &= ~1; 53534527b9ebc6a37b861f5a3bba68bcc63dc8d69adaHaynes Mathew George asyncError = mAsyncError; 53544527b9ebc6a37b861f5a3bba68bcc63dc8d69adaHaynes Mathew George mAsyncError = false; 5355bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent } 5356bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent { 53574de95592980dba88a35b3dc8f3fd045588387a4fEric Laurent sp<AudioFlinger::PlaybackThread> playbackThread = mPlaybackThread.promote(); 53584de95592980dba88a35b3dc8f3fd045588387a4fEric Laurent if (playbackThread != 0) { 53593b4529e03c5fc7a44c22f9091ad15a269bfca3a8Eric Laurent if (writeAckSequence & 1) { 53604de95592980dba88a35b3dc8f3fd045588387a4fEric Laurent playbackThread->resetWriteBlocked(writeAckSequence >> 1); 5361bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent } 53623b4529e03c5fc7a44c22f9091ad15a269bfca3a8Eric Laurent if (drainSequence & 1) { 53634de95592980dba88a35b3dc8f3fd045588387a4fEric Laurent playbackThread->resetDraining(drainSequence >> 1); 5364bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent } 53654527b9ebc6a37b861f5a3bba68bcc63dc8d69adaHaynes Mathew George if (asyncError) { 53664527b9ebc6a37b861f5a3bba68bcc63dc8d69adaHaynes Mathew George playbackThread->onAsyncError(); 53674527b9ebc6a37b861f5a3bba68bcc63dc8d69adaHaynes Mathew George } 5368bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent } 5369bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent } 5370bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent } 5371bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent return false; 5372bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent} 5373bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent 5374bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurentvoid AudioFlinger::AsyncCallbackThread::exit() 5375bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent{ 5376bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent ALOGV("AsyncCallbackThread::exit"); 5377bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent Mutex::Autolock _l(mLock); 5378bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent requestExit(); 5379bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent mWaitWorkCV.broadcast(); 5380bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent} 5381bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent 53823b4529e03c5fc7a44c22f9091ad15a269bfca3a8Eric Laurentvoid AudioFlinger::AsyncCallbackThread::setWriteBlocked(uint32_t sequence) 5383bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent{ 5384bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent Mutex::Autolock _l(mLock); 53853b4529e03c5fc7a44c22f9091ad15a269bfca3a8Eric Laurent // bit 0 is cleared 53863b4529e03c5fc7a44c22f9091ad15a269bfca3a8Eric Laurent mWriteAckSequence = sequence << 1; 53873b4529e03c5fc7a44c22f9091ad15a269bfca3a8Eric Laurent} 53883b4529e03c5fc7a44c22f9091ad15a269bfca3a8Eric Laurent 53893b4529e03c5fc7a44c22f9091ad15a269bfca3a8Eric Laurentvoid AudioFlinger::AsyncCallbackThread::resetWriteBlocked() 53903b4529e03c5fc7a44c22f9091ad15a269bfca3a8Eric Laurent{ 53913b4529e03c5fc7a44c22f9091ad15a269bfca3a8Eric Laurent Mutex::Autolock _l(mLock); 53923b4529e03c5fc7a44c22f9091ad15a269bfca3a8Eric Laurent // ignore unexpected callbacks 53933b4529e03c5fc7a44c22f9091ad15a269bfca3a8Eric Laurent if (mWriteAckSequence & 2) { 53943b4529e03c5fc7a44c22f9091ad15a269bfca3a8Eric Laurent mWriteAckSequence |= 1; 5395bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent mWaitWorkCV.signal(); 5396bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent } 5397bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent} 5398bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent 53993b4529e03c5fc7a44c22f9091ad15a269bfca3a8Eric Laurentvoid AudioFlinger::AsyncCallbackThread::setDraining(uint32_t sequence) 54003b4529e03c5fc7a44c22f9091ad15a269bfca3a8Eric Laurent{ 54013b4529e03c5fc7a44c22f9091ad15a269bfca3a8Eric Laurent Mutex::Autolock _l(mLock); 54023b4529e03c5fc7a44c22f9091ad15a269bfca3a8Eric Laurent // bit 0 is cleared 54033b4529e03c5fc7a44c22f9091ad15a269bfca3a8Eric Laurent mDrainSequence = sequence << 1; 54043b4529e03c5fc7a44c22f9091ad15a269bfca3a8Eric Laurent} 54053b4529e03c5fc7a44c22f9091ad15a269bfca3a8Eric Laurent 54063b4529e03c5fc7a44c22f9091ad15a269bfca3a8Eric Laurentvoid AudioFlinger::AsyncCallbackThread::resetDraining() 5407bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent{ 5408bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent Mutex::Autolock _l(mLock); 54093b4529e03c5fc7a44c22f9091ad15a269bfca3a8Eric Laurent // ignore unexpected callbacks 54103b4529e03c5fc7a44c22f9091ad15a269bfca3a8Eric Laurent if (mDrainSequence & 2) { 54113b4529e03c5fc7a44c22f9091ad15a269bfca3a8Eric Laurent mDrainSequence |= 1; 5412bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent mWaitWorkCV.signal(); 5413bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent } 5414bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent} 5415bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent 54164527b9ebc6a37b861f5a3bba68bcc63dc8d69adaHaynes Mathew Georgevoid AudioFlinger::AsyncCallbackThread::setAsyncError() 54174527b9ebc6a37b861f5a3bba68bcc63dc8d69adaHaynes Mathew George{ 54184527b9ebc6a37b861f5a3bba68bcc63dc8d69adaHaynes Mathew George Mutex::Autolock _l(mLock); 54194527b9ebc6a37b861f5a3bba68bcc63dc8d69adaHaynes Mathew George mAsyncError = true; 54204527b9ebc6a37b861f5a3bba68bcc63dc8d69adaHaynes Mathew George mWaitWorkCV.signal(); 54214527b9ebc6a37b861f5a3bba68bcc63dc8d69adaHaynes Mathew George} 54224527b9ebc6a37b861f5a3bba68bcc63dc8d69adaHaynes Mathew George 5423bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent 5424bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent// ---------------------------------------------------------------------------- 5425bfb1b832079bbb9426f72f3863199a54aefd02daEric LaurentAudioFlinger::OffloadThread::OffloadThread(const sp<AudioFlinger>& audioFlinger, 5426e93cc03da360a1a0d2ad937c745ce8c8e8be81c2Eric Laurent AudioStreamOut* output, audio_io_handle_t id, uint32_t device, bool systemReady) 5427e93cc03da360a1a0d2ad937c745ce8c8e8be81c2Eric Laurent : DirectOutputThread(audioFlinger, output, id, device, OFFLOAD, systemReady), 5428f804475807407442d5596ab7378ed07d50664063Andy Hung mPausedWriteLength(0), mPausedBytesRemaining(0), mKeepWakeLock(true), 5429f804475807407442d5596ab7378ed07d50664063Andy Hung mOffloadUnderrunPosition(~0LL) 5430bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent{ 5431fd4779740ec3e9e865d5514464df26d015354388Eric Laurent //FIXME: mStandby should be set to true by ThreadBase constructor 5432fd4779740ec3e9e865d5514464df26d015354388Eric Laurent mStandby = true; 5433646679779a8f952980a5d4219ad9c6f93efc4b92Eric Laurent mKeepWakeLock = property_get_bool("ro.audio.offload_wakelock", true /* default_value */); 5434bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent} 5435bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent 5436bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurentvoid AudioFlinger::OffloadThread::threadLoop_exit() 5437bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent{ 5438bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent if (mFlushPending || mHwPaused) { 5439bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent // If a flush is pending or track was paused, just discard buffered data 5440bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent flushHw_l(); 5441bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent } else { 5442bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent mMixerStatus = MIXER_DRAIN_ALL; 5443bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent threadLoop_drain(); 5444bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent } 544556604aa3a56dc8e15532597a0a74b3c7b165e006Uday Gupta if (mUseAsyncWrite) { 544656604aa3a56dc8e15532597a0a74b3c7b165e006Uday Gupta ALOG_ASSERT(mCallbackThread != 0); 544756604aa3a56dc8e15532597a0a74b3c7b165e006Uday Gupta mCallbackThread->exit(); 544856604aa3a56dc8e15532597a0a74b3c7b165e006Uday Gupta } 5449bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent PlaybackThread::threadLoop_exit(); 5450bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent} 5451bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent 5452bfb1b832079bbb9426f72f3863199a54aefd02daEric LaurentAudioFlinger::PlaybackThread::mixer_state AudioFlinger::OffloadThread::prepareTracks_l( 5453bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent Vector< sp<Track> > *tracksToRemove 5454bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent) 5455bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent{ 5456bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent size_t count = mActiveTracks.size(); 5457bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent 5458bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent mixer_state mixerStatus = MIXER_IDLE; 5459972a173d7d1de1a3b5a617aae3e2abb6e05ae02dEric Laurent bool doHwPause = false; 5460972a173d7d1de1a3b5a617aae3e2abb6e05ae02dEric Laurent bool doHwResume = false; 5461972a173d7d1de1a3b5a617aae3e2abb6e05ae02dEric Laurent 5462c42e9b462661673dff480ee71757a58b0f806370Glenn Kasten ALOGV("OffloadThread::prepareTracks_l active tracks %zu", count); 5463ede6c3b8b1147bc425f7b923882f559a513fe23bEric Laurent 5464bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent // find out which tracks need to be processed 5465dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hung for (const sp<Track> &t : mActiveTracks) { 54665850c4c8eecbe0db3cee8511a4f82cb443e27d08Eric Laurent Track* const track = t.get(); 546757c4e6f7464d458eb52d209c2a63524913d6406dGlenn Kasten#ifdef VERY_VERY_VERBOSE_LOGGING 5468bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent audio_track_cblk_t* cblk = track->cblk(); 546957c4e6f7464d458eb52d209c2a63524913d6406dGlenn Kasten#endif 5470fd4779740ec3e9e865d5514464df26d015354388Eric Laurent // Only consider last track started for volume and mixer state control. 5471fd4779740ec3e9e865d5514464df26d015354388Eric Laurent // In theory an older track could underrun and restart after the new one starts 5472fd4779740ec3e9e865d5514464df26d015354388Eric Laurent // but as we only care about the transition phase between two tracks on a 5473fd4779740ec3e9e865d5514464df26d015354388Eric Laurent // direct output, it is not a problem to ignore the underrun case. 5474dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hung sp<Track> l = mActiveTracks.getLatest(); 54755850c4c8eecbe0db3cee8511a4f82cb443e27d08Eric Laurent bool last = l.get() == track; 5476fd4779740ec3e9e865d5514464df26d015354388Eric Laurent 54777844f679be8d94c5cdf017f53754cb68ee2f00daHaynes Mathew George if (track->isInvalid()) { 54787844f679be8d94c5cdf017f53754cb68ee2f00daHaynes Mathew George ALOGW("An invalidated track shouldn't be in active list"); 54797844f679be8d94c5cdf017f53754cb68ee2f00daHaynes Mathew George tracksToRemove->add(track); 54807844f679be8d94c5cdf017f53754cb68ee2f00daHaynes Mathew George continue; 54817844f679be8d94c5cdf017f53754cb68ee2f00daHaynes Mathew George } 54827844f679be8d94c5cdf017f53754cb68ee2f00daHaynes Mathew George 54837844f679be8d94c5cdf017f53754cb68ee2f00daHaynes Mathew George if (track->mState == TrackBase::IDLE) { 54847844f679be8d94c5cdf017f53754cb68ee2f00daHaynes Mathew George ALOGW("An idle track shouldn't be in active list"); 54857844f679be8d94c5cdf017f53754cb68ee2f00daHaynes Mathew George continue; 54867844f679be8d94c5cdf017f53754cb68ee2f00daHaynes Mathew George } 54877844f679be8d94c5cdf017f53754cb68ee2f00daHaynes Mathew George 5488bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent if (track->isPausing()) { 5489bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent track->setPaused(); 5490bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent if (last) { 54915cff403679fc44c8293de81aed31c459c6129243Eric Laurent if (mHwSupportsPause && !mHwPaused) { 5492972a173d7d1de1a3b5a617aae3e2abb6e05ae02dEric Laurent doHwPause = true; 5493bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent mHwPaused = true; 5494bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent } 5495bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent // If we were part way through writing the mixbuffer to 5496bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent // the HAL we must save this until we resume 5497bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent // BUG - this will be wrong if a different track is made active, 5498bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent // in that case we want to discard the pending data in the 5499bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent // mixbuffer and tell the client to present it again when the 5500bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent // track is resumed 5501bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent mPausedWriteLength = mCurrentWriteLength; 5502bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent mPausedBytesRemaining = mBytesRemaining; 5503bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent mBytesRemaining = 0; // stop writing 5504bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent } 5505bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent tracksToRemove->add(track); 55067844f679be8d94c5cdf017f53754cb68ee2f00daHaynes Mathew George } else if (track->isFlushPending()) { 5507e93cc03da360a1a0d2ad937c745ce8c8e8be81c2Eric Laurent if (track->isStopping_1()) { 5508e93cc03da360a1a0d2ad937c745ce8c8e8be81c2Eric Laurent track->mRetryCount = kMaxTrackStopRetriesOffload; 5509e93cc03da360a1a0d2ad937c745ce8c8e8be81c2Eric Laurent } else { 5510e93cc03da360a1a0d2ad937c745ce8c8e8be81c2Eric Laurent track->mRetryCount = kMaxTrackRetriesOffload; 5511e93cc03da360a1a0d2ad937c745ce8c8e8be81c2Eric Laurent } 55127844f679be8d94c5cdf017f53754cb68ee2f00daHaynes Mathew George track->flushAck(); 55137844f679be8d94c5cdf017f53754cb68ee2f00daHaynes Mathew George if (last) { 55147844f679be8d94c5cdf017f53754cb68ee2f00daHaynes Mathew George mFlushPending = true; 55157844f679be8d94c5cdf017f53754cb68ee2f00daHaynes Mathew George } 55162d3ca68363f723fbe269d3ce52dab4985dfc7154Haynes Mathew George } else if (track->isResumePending()){ 55172d3ca68363f723fbe269d3ce52dab4985dfc7154Haynes Mathew George track->resumeAck(); 55182d3ca68363f723fbe269d3ce52dab4985dfc7154Haynes Mathew George if (last) { 55192d3ca68363f723fbe269d3ce52dab4985dfc7154Haynes Mathew George if (mPausedBytesRemaining) { 55202d3ca68363f723fbe269d3ce52dab4985dfc7154Haynes Mathew George // Need to continue write that was interrupted 55212d3ca68363f723fbe269d3ce52dab4985dfc7154Haynes Mathew George mCurrentWriteLength = mPausedWriteLength; 55222d3ca68363f723fbe269d3ce52dab4985dfc7154Haynes Mathew George mBytesRemaining = mPausedBytesRemaining; 55232d3ca68363f723fbe269d3ce52dab4985dfc7154Haynes Mathew George mPausedBytesRemaining = 0; 55242d3ca68363f723fbe269d3ce52dab4985dfc7154Haynes Mathew George } 55252d3ca68363f723fbe269d3ce52dab4985dfc7154Haynes Mathew George if (mHwPaused) { 55262d3ca68363f723fbe269d3ce52dab4985dfc7154Haynes Mathew George doHwResume = true; 55272d3ca68363f723fbe269d3ce52dab4985dfc7154Haynes Mathew George mHwPaused = false; 55282d3ca68363f723fbe269d3ce52dab4985dfc7154Haynes Mathew George // threadLoop_mix() will handle the case that we need to 55292d3ca68363f723fbe269d3ce52dab4985dfc7154Haynes Mathew George // resume an interrupted write 55302d3ca68363f723fbe269d3ce52dab4985dfc7154Haynes Mathew George } 55312d3ca68363f723fbe269d3ce52dab4985dfc7154Haynes Mathew George // enable write to audio HAL 5532ad9cb8b88e4f8face23f01d8dc89fa769dacb50fEric Laurent mSleepTimeUs = 0; 55332d3ca68363f723fbe269d3ce52dab4985dfc7154Haynes Mathew George 55343df841a10b4d553949c518ad52f1af8dcb365058Eric Laurent mLeftVolFloat = mRightVolFloat = -1.0; 55353df841a10b4d553949c518ad52f1af8dcb365058Eric Laurent 55362d3ca68363f723fbe269d3ce52dab4985dfc7154Haynes Mathew George // Do not handle new data in this iteration even if track->framesReady() 55372d3ca68363f723fbe269d3ce52dab4985dfc7154Haynes Mathew George mixerStatus = MIXER_TRACKS_ENABLED; 55382d3ca68363f723fbe269d3ce52dab4985dfc7154Haynes Mathew George } 55392d3ca68363f723fbe269d3ce52dab4985dfc7154Haynes Mathew George } else if (track->framesReady() && track->isReady() && 55403b4529e03c5fc7a44c22f9091ad15a269bfca3a8Eric Laurent !track->isPaused() && !track->isTerminated() && !track->isStopping_2()) { 5541f20e1d8df84c5fbeeace0052d100982ae39bb7a4Glenn Kasten ALOGVV("OffloadThread: track %d s=%08x [OK]", track->name(), cblk->mServer); 5542bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent if (track->mFillingUpStatus == Track::FS_FILLED) { 5543bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent track->mFillingUpStatus = Track::FS_ACTIVE; 55443df841a10b4d553949c518ad52f1af8dcb365058Eric Laurent if (last) { 55453df841a10b4d553949c518ad52f1af8dcb365058Eric Laurent // make sure processVolume_l() will apply new volume even if 0 55463df841a10b4d553949c518ad52f1af8dcb365058Eric Laurent mLeftVolFloat = mRightVolFloat = -1.0; 55473df841a10b4d553949c518ad52f1af8dcb365058Eric Laurent } 5548bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent } 5549bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent 5550bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent if (last) { 5551d7e59228caad3867794d847f6bf163c6495e9506Eric Laurent sp<Track> previousTrack = mPreviousTrack.promote(); 5552d7e59228caad3867794d847f6bf163c6495e9506Eric Laurent if (previousTrack != 0) { 5553d7e59228caad3867794d847f6bf163c6495e9506Eric Laurent if (track != previousTrack.get()) { 55549da3d9573a18ffe08365557c706cf52f09118d1cEric Laurent // Flush any data still being written from last track 55559da3d9573a18ffe08365557c706cf52f09118d1cEric Laurent mBytesRemaining = 0; 55569da3d9573a18ffe08365557c706cf52f09118d1cEric Laurent if (mPausedBytesRemaining) { 55579da3d9573a18ffe08365557c706cf52f09118d1cEric Laurent // Last track was paused so we also need to flush saved 55589da3d9573a18ffe08365557c706cf52f09118d1cEric Laurent // mixbuffer state and invalidate track so that it will 55599da3d9573a18ffe08365557c706cf52f09118d1cEric Laurent // re-submit that unwritten data when it is next resumed 55609da3d9573a18ffe08365557c706cf52f09118d1cEric Laurent mPausedBytesRemaining = 0; 55619da3d9573a18ffe08365557c706cf52f09118d1cEric Laurent // Invalidate is a bit drastic - would be more efficient 55629da3d9573a18ffe08365557c706cf52f09118d1cEric Laurent // to have a flag to tell client that some of the 55639da3d9573a18ffe08365557c706cf52f09118d1cEric Laurent // previously written data was lost 5564d7e59228caad3867794d847f6bf163c6495e9506Eric Laurent previousTrack->invalidate(); 55659da3d9573a18ffe08365557c706cf52f09118d1cEric Laurent } 55669da3d9573a18ffe08365557c706cf52f09118d1cEric Laurent // flush data already sent to the DSP if changing audio session as audio 55679da3d9573a18ffe08365557c706cf52f09118d1cEric Laurent // comes from a different source. Also invalidate previous track to force a 55689da3d9573a18ffe08365557c706cf52f09118d1cEric Laurent // seek when resuming. 5569d7e59228caad3867794d847f6bf163c6495e9506Eric Laurent if (previousTrack->sessionId() != track->sessionId()) { 5570d7e59228caad3867794d847f6bf163c6495e9506Eric Laurent previousTrack->invalidate(); 55719da3d9573a18ffe08365557c706cf52f09118d1cEric Laurent } 55729da3d9573a18ffe08365557c706cf52f09118d1cEric Laurent } 55739da3d9573a18ffe08365557c706cf52f09118d1cEric Laurent } 55749da3d9573a18ffe08365557c706cf52f09118d1cEric Laurent mPreviousTrack = track; 5575bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent // reset retry count 5576e93cc03da360a1a0d2ad937c745ce8c8e8be81c2Eric Laurent if (track->isStopping_1()) { 5577e93cc03da360a1a0d2ad937c745ce8c8e8be81c2Eric Laurent track->mRetryCount = kMaxTrackStopRetriesOffload; 5578e93cc03da360a1a0d2ad937c745ce8c8e8be81c2Eric Laurent } else { 5579e93cc03da360a1a0d2ad937c745ce8c8e8be81c2Eric Laurent track->mRetryCount = kMaxTrackRetriesOffload; 5580e93cc03da360a1a0d2ad937c745ce8c8e8be81c2Eric Laurent } 55815850c4c8eecbe0db3cee8511a4f82cb443e27d08Eric Laurent mActiveTrack = t; 5582bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent mixerStatus = MIXER_TRACKS_READY; 5583bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent } 5584bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent } else { 5585f20e1d8df84c5fbeeace0052d100982ae39bb7a4Glenn Kasten ALOGVV("OffloadThread: track %d s=%08x [NOT READY]", track->name(), cblk->mServer); 5586bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent if (track->isStopping_1()) { 5587e93cc03da360a1a0d2ad937c745ce8c8e8be81c2Eric Laurent if (--(track->mRetryCount) <= 0) { 5588e93cc03da360a1a0d2ad937c745ce8c8e8be81c2Eric Laurent // Hardware buffer can hold a large amount of audio so we must 5589e93cc03da360a1a0d2ad937c745ce8c8e8be81c2Eric Laurent // wait for all current track's data to drain before we say 5590e93cc03da360a1a0d2ad937c745ce8c8e8be81c2Eric Laurent // that the track is stopped. 5591e93cc03da360a1a0d2ad937c745ce8c8e8be81c2Eric Laurent if (mBytesRemaining == 0) { 5592e93cc03da360a1a0d2ad937c745ce8c8e8be81c2Eric Laurent // Only start draining when all data in mixbuffer 5593e93cc03da360a1a0d2ad937c745ce8c8e8be81c2Eric Laurent // has been written 5594e93cc03da360a1a0d2ad937c745ce8c8e8be81c2Eric Laurent ALOGV("OffloadThread: underrun and STOPPING_1 -> draining, STOPPING_2"); 5595e93cc03da360a1a0d2ad937c745ce8c8e8be81c2Eric Laurent track->mState = TrackBase::STOPPING_2; // so presentation completes after 5596e93cc03da360a1a0d2ad937c745ce8c8e8be81c2Eric Laurent // drain do not drain if no data was ever sent to HAL (mStandby == true) 5597e93cc03da360a1a0d2ad937c745ce8c8e8be81c2Eric Laurent if (last && !mStandby) { 5598e93cc03da360a1a0d2ad937c745ce8c8e8be81c2Eric Laurent // do not modify drain sequence if we are already draining. This happens 5599e93cc03da360a1a0d2ad937c745ce8c8e8be81c2Eric Laurent // when resuming from pause after drain. 5600e93cc03da360a1a0d2ad937c745ce8c8e8be81c2Eric Laurent if ((mDrainSequence & 1) == 0) { 5601e93cc03da360a1a0d2ad937c745ce8c8e8be81c2Eric Laurent mSleepTimeUs = 0; 5602e93cc03da360a1a0d2ad937c745ce8c8e8be81c2Eric Laurent mStandbyTimeNs = systemTime() + mStandbyDelayNs; 5603e93cc03da360a1a0d2ad937c745ce8c8e8be81c2Eric Laurent mixerStatus = MIXER_DRAIN_TRACK; 5604e93cc03da360a1a0d2ad937c745ce8c8e8be81c2Eric Laurent mDrainSequence += 2; 5605e93cc03da360a1a0d2ad937c745ce8c8e8be81c2Eric Laurent } 5606e93cc03da360a1a0d2ad937c745ce8c8e8be81c2Eric Laurent if (mHwPaused) { 5607e93cc03da360a1a0d2ad937c745ce8c8e8be81c2Eric Laurent // It is possible to move from PAUSED to STOPPING_1 without 5608e93cc03da360a1a0d2ad937c745ce8c8e8be81c2Eric Laurent // a resume so we must ensure hardware is running 5609e93cc03da360a1a0d2ad937c745ce8c8e8be81c2Eric Laurent doHwResume = true; 5610e93cc03da360a1a0d2ad937c745ce8c8e8be81c2Eric Laurent mHwPaused = false; 5611e93cc03da360a1a0d2ad937c745ce8c8e8be81c2Eric Laurent } 5612bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent } 5613bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent } 5614e93cc03da360a1a0d2ad937c745ce8c8e8be81c2Eric Laurent } else if (last) { 5615e93cc03da360a1a0d2ad937c745ce8c8e8be81c2Eric Laurent ALOGV("stopping1 underrun retries left %d", track->mRetryCount); 5616e93cc03da360a1a0d2ad937c745ce8c8e8be81c2Eric Laurent mixerStatus = MIXER_TRACKS_ENABLED; 5617bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent } 5618bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent } else if (track->isStopping_2()) { 56196a51d7ed7062536ccc892c8850a34ed55cbc8d5cEric Laurent // Drain has completed or we are in standby, signal presentation complete 56206a51d7ed7062536ccc892c8850a34ed55cbc8d5cEric Laurent if (!(mDrainSequence & 1) || !last || mStandby) { 5621bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent track->mState = TrackBase::STOPPED; 56221dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov uint32_t latency = 0; 56231dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov status_t result = mOutput->stream->getLatency(&latency); 56241dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov ALOGE_IF(result != OK, 56251dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov "Error when retrieving output stream latency: %d", result); 56261dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov size_t audioHALFrames = (latency * mSampleRate) / 1000; 5627818e7a32ce3633980138aff2c2bfcc5158b3cfccAndy Hung int64_t framesWritten = 5628062e67a26e0553dd142be622821f493df541f0c6Phil Burk mBytesWritten / mOutput->getFrameSize(); 5629bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent track->presentationComplete(framesWritten, audioHALFrames); 5630bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent track->reset(); 5631bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent tracksToRemove->add(track); 5632bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent } 5633bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent } else { 5634bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent // No buffers for this track. Give it a few chances to 5635bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent // fill a buffer, then remove it from active list. 5636bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent if (--(track->mRetryCount) <= 0) { 5637f804475807407442d5596ab7378ed07d50664063Andy Hung bool running = false; 56381dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov uint64_t position = 0; 56391dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov struct timespec unused; 56401dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov // The running check restarts the retry counter at least once. 56411dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov status_t ret = mOutput->stream->getPresentationPosition(&position, &unused); 56421dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov if (ret == NO_ERROR && position != mOffloadUnderrunPosition) { 56431dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov running = true; 56441dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov mOffloadUnderrunPosition = position; 56451dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov } 56461dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov if (ret == NO_ERROR) { 5647f804475807407442d5596ab7378ed07d50664063Andy Hung ALOGVV("underrun counter, running(%d): %lld vs %lld", running, 5648f804475807407442d5596ab7378ed07d50664063Andy Hung (long long)position, (long long)mOffloadUnderrunPosition); 5649f804475807407442d5596ab7378ed07d50664063Andy Hung } 5650f804475807407442d5596ab7378ed07d50664063Andy Hung if (running) { // still running, give us more time. 5651f804475807407442d5596ab7378ed07d50664063Andy Hung track->mRetryCount = kMaxTrackRetriesOffload; 5652f804475807407442d5596ab7378ed07d50664063Andy Hung } else { 5653f804475807407442d5596ab7378ed07d50664063Andy Hung ALOGV("OffloadThread: BUFFER TIMEOUT: remove(%d) from active list", 5654f804475807407442d5596ab7378ed07d50664063Andy Hung track->name()); 5655f804475807407442d5596ab7378ed07d50664063Andy Hung tracksToRemove->add(track); 5656d3bb645f0b7f567b033b8664499d685f8ec10628Glenn Kasten // tell client process that the track was disabled because of underrun; 5657f804475807407442d5596ab7378ed07d50664063Andy Hung // it will then automatically call start() when data is available 5658f804475807407442d5596ab7378ed07d50664063Andy Hung track->disable(); 5659f804475807407442d5596ab7378ed07d50664063Andy Hung } 5660bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent } else if (last){ 5661bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent mixerStatus = MIXER_TRACKS_ENABLED; 5662bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent } 5663bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent } 5664bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent } 5665bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent // compute volume for this track 5666bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent processVolume_l(track, last); 5667bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent } 56686bf9ae20b3bd2dbb8f2e89ee167a6785222301cfEric Laurent 5669ea0fadeb5d81ef3cb7f9db458c9033d628bdb86aEric Laurent // make sure the pause/flush/resume sequence is executed in the right order. 5670ea0fadeb5d81ef3cb7f9db458c9033d628bdb86aEric Laurent // If a flush is pending and a track is active but the HW is not paused, force a HW pause 5671ea0fadeb5d81ef3cb7f9db458c9033d628bdb86aEric Laurent // before flush and then resume HW. This can happen in case of pause/flush/resume 5672ea0fadeb5d81ef3cb7f9db458c9033d628bdb86aEric Laurent // if resume is received before pause is executed. 5673fd4779740ec3e9e865d5514464df26d015354388Eric Laurent if (!mStandby && (doHwPause || (mFlushPending && !mHwPaused && (count != 0)))) { 56741dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov status_t result = mOutput->stream->pause(); 56751dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov ALOGE_IF(result != OK, "Error when pausing output stream: %d", result); 5676972a173d7d1de1a3b5a617aae3e2abb6e05ae02dEric Laurent } 56776bf9ae20b3bd2dbb8f2e89ee167a6785222301cfEric Laurent if (mFlushPending) { 56786bf9ae20b3bd2dbb8f2e89ee167a6785222301cfEric Laurent flushHw_l(); 56796bf9ae20b3bd2dbb8f2e89ee167a6785222301cfEric Laurent } 5680fd4779740ec3e9e865d5514464df26d015354388Eric Laurent if (!mStandby && doHwResume) { 56811dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov status_t result = mOutput->stream->resume(); 56821dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov ALOGE_IF(result != OK, "Error when resuming output stream: %d", result); 5683972a173d7d1de1a3b5a617aae3e2abb6e05ae02dEric Laurent } 56846bf9ae20b3bd2dbb8f2e89ee167a6785222301cfEric Laurent 5685bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent // remove all the tracks that need to be... 5686bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent removeTracks_l(*tracksToRemove); 5687bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent 5688bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent return mixerStatus; 5689bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent} 5690bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent 5691bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent// must be called with thread mutex locked 5692bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurentbool AudioFlinger::OffloadThread::waitingAsyncCallback_l() 5693bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent{ 56943b4529e03c5fc7a44c22f9091ad15a269bfca3a8Eric Laurent ALOGVV("waitingAsyncCallback_l mWriteAckSequence %d mDrainSequence %d", 56953b4529e03c5fc7a44c22f9091ad15a269bfca3a8Eric Laurent mWriteAckSequence, mDrainSequence); 56963b4529e03c5fc7a44c22f9091ad15a269bfca3a8Eric Laurent if (mUseAsyncWrite && ((mWriteAckSequence & 1) || (mDrainSequence & 1))) { 5697bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent return true; 5698bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent } 5699bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent return false; 5700bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent} 5701bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent 5702bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurentbool AudioFlinger::OffloadThread::waitingAsyncCallback() 5703bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent{ 5704bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent Mutex::Autolock _l(mLock); 5705bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent return waitingAsyncCallback_l(); 5706bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent} 5707bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent 5708bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurentvoid AudioFlinger::OffloadThread::flushHw_l() 5709bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent{ 5710e659ef420dae0caae84ab78f9df8952acb9ad3a0Eric Laurent DirectOutputThread::flushHw_l(); 5711bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent // Flush anything still waiting in the mixbuffer 5712bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent mCurrentWriteLength = 0; 5713bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent mBytesRemaining = 0; 5714bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent mPausedWriteLength = 0; 5715bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent mPausedBytesRemaining = 0; 57163eaf66b860f9a0d8af0dd4d5ac6adb5b67d7b73aEric Laurent // reset bytes written count to reflect that DSP buffers are empty after flush. 57173eaf66b860f9a0d8af0dd4d5ac6adb5b67d7b73aEric Laurent mBytesWritten = 0; 5718f804475807407442d5596ab7378ed07d50664063Andy Hung mOffloadUnderrunPosition = ~0LL; 57190f02f265123b7ef2fd6ac09ff70cde26eb5559adHaynes Mathew George 5720bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent if (mUseAsyncWrite) { 57213b4529e03c5fc7a44c22f9091ad15a269bfca3a8Eric Laurent // discard any pending drain or write ack by incrementing sequence 57223b4529e03c5fc7a44c22f9091ad15a269bfca3a8Eric Laurent mWriteAckSequence = (mWriteAckSequence + 2) & ~1; 57233b4529e03c5fc7a44c22f9091ad15a269bfca3a8Eric Laurent mDrainSequence = (mDrainSequence + 2) & ~1; 5724bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent ALOG_ASSERT(mCallbackThread != 0); 57253b4529e03c5fc7a44c22f9091ad15a269bfca3a8Eric Laurent mCallbackThread->setWriteBlocked(mWriteAckSequence); 57263b4529e03c5fc7a44c22f9091ad15a269bfca3a8Eric Laurent mCallbackThread->setDraining(mDrainSequence); 5727bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent } 5728bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent} 5729bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent 573005317d29b27e5fda654bea21b80d4423a03f49b3Haynes Mathew Georgevoid AudioFlinger::OffloadThread::invalidateTracks(audio_stream_type_t streamType) 573105317d29b27e5fda654bea21b80d4423a03f49b3Haynes Mathew George{ 573205317d29b27e5fda654bea21b80d4423a03f49b3Haynes Mathew George Mutex::Autolock _l(mLock); 573313084621072ea2e4c34e2a9d79793c621d9bf005Eric Laurent if (PlaybackThread::invalidateTracks_l(streamType)) { 573413084621072ea2e4c34e2a9d79793c621d9bf005Eric Laurent mFlushPending = true; 573513084621072ea2e4c34e2a9d79793c621d9bf005Eric Laurent } 573605317d29b27e5fda654bea21b80d4423a03f49b3Haynes Mathew George} 573705317d29b27e5fda654bea21b80d4423a03f49b3Haynes Mathew George 5738bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent// ---------------------------------------------------------------------------- 5739bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent 574081784c37c61b09289654b979567a42bf73cd2b12Eric LaurentAudioFlinger::DuplicatingThread::DuplicatingThread(const sp<AudioFlinger>& audioFlinger, 574172e3f39146fce4686bd96f11057c051bea376dfbEric Laurent AudioFlinger::MixerThread* mainThread, audio_io_handle_t id, bool systemReady) 574281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent : MixerThread(audioFlinger, mainThread->getOutput(), id, mainThread->outDevice(), 574372e3f39146fce4686bd96f11057c051bea376dfbEric Laurent systemReady, DUPLICATING), 574481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mWaitTimeMs(UINT_MAX) 574581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 574681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent addOutputTrack(mainThread); 574781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 574881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 574981784c37c61b09289654b979567a42bf73cd2b12Eric LaurentAudioFlinger::DuplicatingThread::~DuplicatingThread() 575081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 575181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent for (size_t i = 0; i < mOutputTracks.size(); i++) { 575281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mOutputTracks[i]->destroy(); 575381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 575481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 575581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 575681784c37c61b09289654b979567a42bf73cd2b12Eric Laurentvoid AudioFlinger::DuplicatingThread::threadLoop_mix() 575781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 575881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // mix buffers... 575981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (outputsReady(outputTracks)) { 5760d79072e9dff59f767cce2cda1caab80ce5a0815bGlenn Kasten mAudioMixer->process(); 576181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } else { 576202b5708776ba2a9b4ff8c09008483aef7dbe38c7Eric Laurent if (mMixerBufferValid) { 576302b5708776ba2a9b4ff8c09008483aef7dbe38c7Eric Laurent memset(mMixerBuffer, 0, mMixerBufferSize); 576402b5708776ba2a9b4ff8c09008483aef7dbe38c7Eric Laurent } else { 576502b5708776ba2a9b4ff8c09008483aef7dbe38c7Eric Laurent memset(mSinkBuffer, 0, mSinkBufferSize); 576602b5708776ba2a9b4ff8c09008483aef7dbe38c7Eric Laurent } 576781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 5768ad9cb8b88e4f8face23f01d8dc89fa769dacb50fEric Laurent mSleepTimeUs = 0; 576981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent writeFrames = mNormalFrameCount; 577025c2dac12114699e90deb1c579cadebce7b91a97Andy Hung mCurrentWriteLength = mSinkBufferSize; 5771ad9cb8b88e4f8face23f01d8dc89fa769dacb50fEric Laurent mStandbyTimeNs = systemTime() + mStandbyDelayNs; 577281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 577381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 577481784c37c61b09289654b979567a42bf73cd2b12Eric Laurentvoid AudioFlinger::DuplicatingThread::threadLoop_sleepTime() 577581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 5776ad9cb8b88e4f8face23f01d8dc89fa769dacb50fEric Laurent if (mSleepTimeUs == 0) { 577781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (mMixerStatus == MIXER_TRACKS_ENABLED) { 5778ad9cb8b88e4f8face23f01d8dc89fa769dacb50fEric Laurent mSleepTimeUs = mActiveSleepTimeUs; 577981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } else { 5780ad9cb8b88e4f8face23f01d8dc89fa769dacb50fEric Laurent mSleepTimeUs = mIdleSleepTimeUs; 578181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 578281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } else if (mBytesWritten != 0) { 578381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (mMixerStatus == MIXER_TRACKS_ENABLED) { 578481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent writeFrames = mNormalFrameCount; 578525c2dac12114699e90deb1c579cadebce7b91a97Andy Hung memset(mSinkBuffer, 0, mSinkBufferSize); 578681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } else { 578781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // flush remaining overflow buffers in output tracks 578881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent writeFrames = 0; 578981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 5790ad9cb8b88e4f8face23f01d8dc89fa769dacb50fEric Laurent mSleepTimeUs = 0; 579181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 579281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 579381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 5794bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurentssize_t AudioFlinger::DuplicatingThread::threadLoop_write() 579581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 579681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent for (size_t i = 0; i < outputTracks.size(); i++) { 5797c25b84abdd7ff229d0af663fbf3a37bd9512939dAndy Hung outputTracks[i]->write(mSinkBuffer, writeFrames); 579881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 57992c3740f01acca69c3e0bcc5e01bb0edc51b6777fEric Laurent mStandby = false; 580025c2dac12114699e90deb1c579cadebce7b91a97Andy Hung return (ssize_t)mSinkBufferSize; 580181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 580281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 580381784c37c61b09289654b979567a42bf73cd2b12Eric Laurentvoid AudioFlinger::DuplicatingThread::threadLoop_standby() 580481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 580581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // DuplicatingThread implements standby by stopping all tracks 580681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent for (size_t i = 0; i < outputTracks.size(); i++) { 580781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent outputTracks[i]->stop(); 580881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 580981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 581081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 581181784c37c61b09289654b979567a42bf73cd2b12Eric Laurentvoid AudioFlinger::DuplicatingThread::saveOutputTracks() 581281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 581381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent outputTracks = mOutputTracks; 581481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 581581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 581681784c37c61b09289654b979567a42bf73cd2b12Eric Laurentvoid AudioFlinger::DuplicatingThread::clearOutputTracks() 581781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 581881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent outputTracks.clear(); 581981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 582081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 582181784c37c61b09289654b979567a42bf73cd2b12Eric Laurentvoid AudioFlinger::DuplicatingThread::addOutputTrack(MixerThread *thread) 582281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 582381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent Mutex::Autolock _l(mLock); 5824c25b84abdd7ff229d0af663fbf3a37bd9512939dAndy Hung // The downstream MixerThread consumes thread->frameCount() amount of frames per mix pass. 5825c25b84abdd7ff229d0af663fbf3a37bd9512939dAndy Hung // Adjust for thread->sampleRate() to determine minimum buffer frame count. 5826c25b84abdd7ff229d0af663fbf3a37bd9512939dAndy Hung // Then triple buffer because Threads do not run synchronously and may not be clock locked. 5827c25b84abdd7ff229d0af663fbf3a37bd9512939dAndy Hung const size_t frameCount = 5828c25b84abdd7ff229d0af663fbf3a37bd9512939dAndy Hung 3 * sourceFramesNeeded(mSampleRate, thread->frameCount(), thread->sampleRate()); 5829c25b84abdd7ff229d0af663fbf3a37bd9512939dAndy Hung // TODO: Consider asynchronous sample rate conversion to handle clock disparity 5830c25b84abdd7ff229d0af663fbf3a37bd9512939dAndy Hung // from different OutputTracks and their associated MixerThreads (e.g. one may 5831c25b84abdd7ff229d0af663fbf3a37bd9512939dAndy Hung // nearly empty and the other may be dropping data). 5832c25b84abdd7ff229d0af663fbf3a37bd9512939dAndy Hung 5833c25b84abdd7ff229d0af663fbf3a37bd9512939dAndy Hung sp<OutputTrack> outputTrack = new OutputTrack(thread, 583481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent this, 583581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mSampleRate, 5836c25b84abdd7ff229d0af663fbf3a37bd9512939dAndy Hung mFormat, 583781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mChannelMask, 5838462fd2fa9eef642b0574aa7409de0bde3fec8d43Marco Nelissen frameCount, 5839462fd2fa9eef642b0574aa7409de0bde3fec8d43Marco Nelissen IPCThreadState::self()->getCallingUid()); 5840af3ec7c9a0cfc483017d4457e0e3d77de4b1a33aEric Laurent status_t status = outputTrack != 0 ? outputTrack->initCheck() : (status_t) NO_MEMORY; 5841af3ec7c9a0cfc483017d4457e0e3d77de4b1a33aEric Laurent if (status != NO_ERROR) { 5842af3ec7c9a0cfc483017d4457e0e3d77de4b1a33aEric Laurent ALOGE("addOutputTrack() initCheck failed %d", status); 5843af3ec7c9a0cfc483017d4457e0e3d77de4b1a33aEric Laurent return; 584481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 5845af3ec7c9a0cfc483017d4457e0e3d77de4b1a33aEric Laurent thread->setStreamVolume(AUDIO_STREAM_PATCH, 1.0f); 5846af3ec7c9a0cfc483017d4457e0e3d77de4b1a33aEric Laurent mOutputTracks.add(outputTrack); 5847af3ec7c9a0cfc483017d4457e0e3d77de4b1a33aEric Laurent ALOGV("addOutputTrack() track %p, on thread %p", outputTrack.get(), thread); 5848af3ec7c9a0cfc483017d4457e0e3d77de4b1a33aEric Laurent updateWaitTime_l(); 584981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 585081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 585181784c37c61b09289654b979567a42bf73cd2b12Eric Laurentvoid AudioFlinger::DuplicatingThread::removeOutputTrack(MixerThread *thread) 585281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 585381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent Mutex::Autolock _l(mLock); 585481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent for (size_t i = 0; i < mOutputTracks.size(); i++) { 585581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (mOutputTracks[i]->thread() == thread) { 585681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mOutputTracks[i]->destroy(); 585781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mOutputTracks.removeAt(i); 585881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent updateWaitTime_l(); 5859f6870aefc5e31d4220f3778c4e79ff34a61f48adEric Laurent if (thread->getOutput() == mOutput) { 5860f6870aefc5e31d4220f3778c4e79ff34a61f48adEric Laurent mOutput = NULL; 5861f6870aefc5e31d4220f3778c4e79ff34a61f48adEric Laurent } 586281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent return; 586381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 586481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 5865f6870aefc5e31d4220f3778c4e79ff34a61f48adEric Laurent ALOGV("removeOutputTrack(): unknown thread: %p", thread); 586681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 586781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 586881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// caller must hold mLock 586981784c37c61b09289654b979567a42bf73cd2b12Eric Laurentvoid AudioFlinger::DuplicatingThread::updateWaitTime_l() 587081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 587181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mWaitTimeMs = UINT_MAX; 587281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent for (size_t i = 0; i < mOutputTracks.size(); i++) { 587381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent sp<ThreadBase> strong = mOutputTracks[i]->thread().promote(); 587481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (strong != 0) { 587581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent uint32_t waitTimeMs = (strong->frameCount() * 2 * 1000) / strong->sampleRate(); 587681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (waitTimeMs < mWaitTimeMs) { 587781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mWaitTimeMs = waitTimeMs; 587881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 587981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 588081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 588181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 588281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 588381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 588481784c37c61b09289654b979567a42bf73cd2b12Eric Laurentbool AudioFlinger::DuplicatingThread::outputsReady( 588581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent const SortedVector< sp<OutputTrack> > &outputTracks) 588681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 588781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent for (size_t i = 0; i < outputTracks.size(); i++) { 588881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent sp<ThreadBase> thread = outputTracks[i]->thread().promote(); 588981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (thread == 0) { 589081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent ALOGW("DuplicatingThread::outputsReady() could not promote thread on output track %p", 589181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent outputTracks[i].get()); 589281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent return false; 589381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 589481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent PlaybackThread *playbackThread = (PlaybackThread *)thread.get(); 589581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // see note at standby() declaration 589681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (playbackThread->standby() && !playbackThread->isSuspended()) { 589781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent ALOGV("DuplicatingThread output track %p on thread %p Not Ready", outputTracks[i].get(), 589881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent thread.get()); 589981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent return false; 590081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 590181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 590281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent return true; 590381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 590481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 590581784c37c61b09289654b979567a42bf73cd2b12Eric Laurentuint32_t AudioFlinger::DuplicatingThread::activeSleepTimeUs() const 590681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 590781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent return (mWaitTimeMs * 1000) / 2; 590881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 590981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 591081784c37c61b09289654b979567a42bf73cd2b12Eric Laurentvoid AudioFlinger::DuplicatingThread::cacheParameters_l() 591181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 591281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // updateWaitTime_l() sets mWaitTimeMs, which affects activeSleepTimeUs(), so call it first 591381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent updateWaitTime_l(); 591481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 591581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent MixerThread::cacheParameters_l(); 591681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 591781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 59186acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 591981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// ---------------------------------------------------------------------------- 592081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// Record 592181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// ---------------------------------------------------------------------------- 592281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 592381784c37c61b09289654b979567a42bf73cd2b12Eric LaurentAudioFlinger::RecordThread::RecordThread(const sp<AudioFlinger>& audioFlinger, 592481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent AudioStreamIn *input, 592581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent audio_io_handle_t id, 5926d3922f72601d82c6fc067a98916fda0bd1291c5fEric Laurent audio_devices_t outDevice, 592772e3f39146fce4686bd96f11057c051bea376dfbEric Laurent audio_devices_t inDevice, 592872e3f39146fce4686bd96f11057c051bea376dfbEric Laurent bool systemReady 592946909e7eb074ce1b95b8a411eb71154f53f84f77Glenn Kasten#ifdef TEE_SINK 593046909e7eb074ce1b95b8a411eb71154f53f84f77Glenn Kasten , const sp<NBAIO_Sink>& teeSink 593146909e7eb074ce1b95b8a411eb71154f53f84f77Glenn Kasten#endif 593246909e7eb074ce1b95b8a411eb71154f53f84f77Glenn Kasten ) : 593372e3f39146fce4686bd96f11057c051bea376dfbEric Laurent ThreadBase(audioFlinger, id, outDevice, inDevice, RECORD, systemReady), 5934dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hung mInput(input), mRsmpInBuffer(NULL), 59351b291841a58ce6b2b291232dfdd56134b2185c48Glenn Kasten // mRsmpInFrames, mRsmpInFramesP2, and mRsmpInFramesOA are set by readInputParameters_l() 59364cc0a6a835c806d200ef83ef31fe5bef327c355cGlenn Kasten mRsmpInRear(0) 593746909e7eb074ce1b95b8a411eb71154f53f84f77Glenn Kasten#ifdef TEE_SINK 593846909e7eb074ce1b95b8a411eb71154f53f84f77Glenn Kasten , mTeeSink(teeSink) 593946909e7eb074ce1b95b8a411eb71154f53f84f77Glenn Kasten#endif 5940b880f5e5fc07397ddd09a94ba18bdf4fa62aae00Glenn Kasten , mReadOnlyHeap(new MemoryDealer(kRecordThreadReadOnlyHeapSize, 5941b880f5e5fc07397ddd09a94ba18bdf4fa62aae00Glenn Kasten "RecordThreadRO", MemoryHeapBase::READ_ONLY)) 59426dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten // mFastCapture below 59436dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten , mFastCaptureFutex(0) 59446dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten // mInputSource 59456dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten // mPipeSink 59466dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten // mPipeSource 59476dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten , mPipeFramesP2(0) 59486dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten // mPipeMemory 59496dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten // mFastCaptureNBLogWriter 59506e6704c06d61bc356e30c164081e5bcffb37920cGlenn Kasten , mFastTrackAvail(false) 595181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 5952d7dca050c630bddbd73a6623271b34b4290460eeGlenn Kasten snprintf(mThreadName, kThreadNameLength, "AudioIn_%X", id); 5953d7dca050c630bddbd73a6623271b34b4290460eeGlenn Kasten mNBLogWriter = audioFlinger->newWriter_l(kLogSize, mThreadName); 595481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 5955deca2ae0a7cf8bc54ff3f30b7dc39bbc78b94c0dGlenn Kasten readInputParameters_l(); 59566dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten 59576dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten // create an NBAIO source for the HAL input stream, and negotiate 5958a0c91339814f37ea78365afb436c9f3d1f0a0090Mikhail Naganov mInputSource = new AudioStreamInSource(input->stream); 59596dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten size_t numCounterOffers = 0; 59606dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten const NBAIO_Format offers[1] = {Format_from_SR_C(mSampleRate, mChannelCount, mFormat)}; 596157c4e6f7464d458eb52d209c2a63524913d6406dGlenn Kasten#if !LOG_NDEBUG 596257c4e6f7464d458eb52d209c2a63524913d6406dGlenn Kasten ssize_t index = 596357c4e6f7464d458eb52d209c2a63524913d6406dGlenn Kasten#else 596457c4e6f7464d458eb52d209c2a63524913d6406dGlenn Kasten (void) 596557c4e6f7464d458eb52d209c2a63524913d6406dGlenn Kasten#endif 596657c4e6f7464d458eb52d209c2a63524913d6406dGlenn Kasten mInputSource->negotiate(offers, 1, NULL, numCounterOffers); 59676dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten ALOG_ASSERT(index == 0); 59686dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten 59696dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten // initialize fast capture depending on configuration 59706dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten bool initFastCapture; 59716dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten switch (kUseFastCapture) { 59726dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten case FastCapture_Never: 59736dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten initFastCapture = false; 59746dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten break; 59756dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten case FastCapture_Always: 59766dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten initFastCapture = true; 59776dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten break; 59786dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten case FastCapture_Static: 5979eb9487e10294a4e73977f460f30eeaff503acd21Glenn Kasten initFastCapture = (mFrameCount * 1000) / mSampleRate < kMinNormalCaptureBufferSizeMs; 59806dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten break; 59816dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten // case FastCapture_Dynamic: 59826dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten } 59836dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten 59846dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten if (initFastCapture) { 5985d198b85a163330b03e7507c9e8bfeb5f4d958a6cGlenn Kasten // create a Pipe for FastCapture to write to, and for us and fast tracks to read from 59866dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten NBAIO_Format format = mInputSource->format(); 59871b291841a58ce6b2b291232dfdd56134b2185c48Glenn Kasten // quadruple-buffering of 20 ms each; this ensures we can sleep for 20ms in RecordThread 59881b291841a58ce6b2b291232dfdd56134b2185c48Glenn Kasten size_t pipeFramesP2 = roundup(4 * FMS_20 * mSampleRate / 1000); 59896dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten size_t pipeSize = pipeFramesP2 * Format_frameSize(format); 59906dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten void *pipeBuffer; 59916dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten const sp<MemoryDealer> roHeap(readOnlyHeap()); 59926dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten sp<IMemory> pipeMemory; 59936dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten if ((roHeap == 0) || 59946dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten (pipeMemory = roHeap->allocate(pipeSize)) == 0 || 59956dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten (pipeBuffer = pipeMemory->pointer()) == NULL) { 59966dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten ALOGE("not enough memory for pipe buffer size=%zu", pipeSize); 59976dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten goto failed; 59986dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten } 59996dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten // pipe will be shared directly with fast clients, so clear to avoid leaking old information 60006dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten memset(pipeBuffer, 0, pipeSize); 60016dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten Pipe *pipe = new Pipe(pipeFramesP2, format, pipeBuffer); 60026dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten const NBAIO_Format offers[1] = {format}; 60036dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten size_t numCounterOffers = 0; 60046dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten ssize_t index = pipe->negotiate(offers, 1, NULL, numCounterOffers); 60056dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten ALOG_ASSERT(index == 0); 60066dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten mPipeSink = pipe; 60076dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten PipeReader *pipeReader = new PipeReader(*pipe); 60086dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten numCounterOffers = 0; 60096dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten index = pipeReader->negotiate(offers, 1, NULL, numCounterOffers); 60106dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten ALOG_ASSERT(index == 0); 60116dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten mPipeSource = pipeReader; 60126dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten mPipeFramesP2 = pipeFramesP2; 60136dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten mPipeMemory = pipeMemory; 60146dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten 60156dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten // create fast capture 60166dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten mFastCapture = new FastCapture(); 60176dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten FastCaptureStateQueue *sq = mFastCapture->sq(); 60186dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten#ifdef STATE_QUEUE_DUMP 60196dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten // FIXME 60206dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten#endif 60216dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten FastCaptureState *state = sq->begin(); 60226dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten state->mCblk = NULL; 60236dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten state->mInputSource = mInputSource.get(); 60246dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten state->mInputSourceGen++; 60256dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten state->mPipeSink = pipe; 60266dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten state->mPipeSinkGen++; 60276dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten state->mFrameCount = mFrameCount; 60286dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten state->mCommand = FastCaptureState::COLD_IDLE; 60296dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten // already done in constructor initialization list 60306dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten //mFastCaptureFutex = 0; 60316dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten state->mColdFutexAddr = &mFastCaptureFutex; 60326dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten state->mColdGen++; 60336dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten state->mDumpState = &mFastCaptureDumpState; 60346dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten#ifdef TEE_SINK 60356dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten // FIXME 60366dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten#endif 60376dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten mFastCaptureNBLogWriter = audioFlinger->newWriter_l(kFastCaptureLogSize, "FastCapture"); 60386dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten state->mNBLogWriter = mFastCaptureNBLogWriter.get(); 60396dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten sq->end(); 60406dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten sq->push(FastCaptureStateQueue::BLOCK_UNTIL_PUSHED); 60416dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten 60426dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten // start the fast capture 60436dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten mFastCapture->run("FastCapture", ANDROID_PRIORITY_URGENT_AUDIO); 60446dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten pid_t tid = mFastCapture->getTid(); 604583f042776b131b149f803fff6ab184ae2c4d98cdMikhail Naganov sendPrioConfigEvent(getpid_cached, tid, kPriorityFastCapture, false); 6046e1c4b5d7a94c21b8ce0c5707b4af84de596fbb79Mikhail Naganov stream()->setHalThreadPriority(kPriorityFastCapture); 60476dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten#ifdef AUDIO_WATCHDOG 60486dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten // FIXME 60496dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten#endif 60506dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten 60516e6704c06d61bc356e30c164081e5bcffb37920cGlenn Kasten mFastTrackAvail = true; 60526dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten } 60536dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kastenfailed: ; 60546dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten 60556dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten // FIXME mNormalSource 605681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 605781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 605881784c37c61b09289654b979567a42bf73cd2b12Eric LaurentAudioFlinger::RecordThread::~RecordThread() 605981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 60606dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten if (mFastCapture != 0) { 60616dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten FastCaptureStateQueue *sq = mFastCapture->sq(); 60626dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten FastCaptureState *state = sq->begin(); 60636dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten if (state->mCommand == FastCaptureState::COLD_IDLE) { 60646dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten int32_t old = android_atomic_inc(&mFastCaptureFutex); 60656dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten if (old == -1) { 60666dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten (void) syscall(__NR_futex, &mFastCaptureFutex, FUTEX_WAKE_PRIVATE, 1); 60676dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten } 60686dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten } 60696dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten state->mCommand = FastCaptureState::EXIT; 60706dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten sq->end(); 60716dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten sq->push(FastCaptureStateQueue::BLOCK_UNTIL_PUSHED); 60726dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten mFastCapture->join(); 60736dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten mFastCapture.clear(); 60746dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten } 60756dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten mAudioFlinger->unregisterWriter(mFastCaptureNBLogWriter); 6076481fb67a595f23c5b7f5be84b06db9b84a41a42fGlenn Kasten mAudioFlinger->unregisterWriter(mNBLogWriter); 60775744661e85981f8a9456bf470e2761235fc026daAndy Hung free(mRsmpInBuffer); 607881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 607981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 608081784c37c61b09289654b979567a42bf73cd2b12Eric Laurentvoid AudioFlinger::RecordThread::onFirstRef() 608181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 6082d7dca050c630bddbd73a6623271b34b4290460eeGlenn Kasten run(mThreadName, PRIORITY_URGENT_AUDIO); 608381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 608481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 6085555530ab903504ad3586bc24cd8a4f200f5c39aeEric Laurentvoid AudioFlinger::RecordThread::preExit() 6086555530ab903504ad3586bc24cd8a4f200f5c39aeEric Laurent{ 6087555530ab903504ad3586bc24cd8a4f200f5c39aeEric Laurent ALOGV(" preExit()"); 6088555530ab903504ad3586bc24cd8a4f200f5c39aeEric Laurent Mutex::Autolock _l(mLock); 6089555530ab903504ad3586bc24cd8a4f200f5c39aeEric Laurent for (size_t i = 0; i < mTracks.size(); i++) { 6090555530ab903504ad3586bc24cd8a4f200f5c39aeEric Laurent sp<RecordTrack> track = mTracks[i]; 6091555530ab903504ad3586bc24cd8a4f200f5c39aeEric Laurent track->invalidate(); 6092555530ab903504ad3586bc24cd8a4f200f5c39aeEric Laurent } 6093555530ab903504ad3586bc24cd8a4f200f5c39aeEric Laurent mActiveTracks.clear(); 6094555530ab903504ad3586bc24cd8a4f200f5c39aeEric Laurent mStartStopCond.broadcast(); 6095555530ab903504ad3586bc24cd8a4f200f5c39aeEric Laurent} 6096555530ab903504ad3586bc24cd8a4f200f5c39aeEric Laurent 609781784c37c61b09289654b979567a42bf73cd2b12Eric Laurentbool AudioFlinger::RecordThread::threadLoop() 609881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 609981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent nsecs_t lastWarning = 0; 610081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 610181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent inputStandBy(); 610281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 6103f10ffec18f930d92e1abe9200d60e746831841a7Glenn Kastenreacquire_wakelock: 6104f10ffec18f930d92e1abe9200d60e746831841a7Glenn Kasten sp<RecordTrack> activeTrack; 6105f10ffec18f930d92e1abe9200d60e746831841a7Glenn Kasten { 6106f10ffec18f930d92e1abe9200d60e746831841a7Glenn Kasten Mutex::Autolock _l(mLock); 6107dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hung acquireWakeLock_l(); 6108f10ffec18f930d92e1abe9200d60e746831841a7Glenn Kasten } 6109f10ffec18f930d92e1abe9200d60e746831841a7Glenn Kasten 61106dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten // used to request a deferred sleep, to be executed later while mutex is unlocked 61116dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten uint32_t sleepUs = 0; 61126dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten 61136dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten // loop while there is work to do 61144ef0b463a56c19bad9197aa9f90d792090461429Glenn Kasten for (;;) { 6115c527a7c2b1bfd26e8f3086e1b653d56e521379d9Glenn Kasten Vector< sp<EffectChain> > effectChains; 61162cfbf88b89854f30b295e8ae26a031edb8d712f8Glenn Kasten 61176dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten // activeTracks accumulates a copy of a subset of mActiveTracks 61186dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten Vector< sp<RecordTrack> > activeTracks; 61196dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten 6120735f45fbc37d7905ffb722f40727edbed82319b7Glenn Kasten // reference to the (first and only) active fast track 61216dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten sp<RecordTrack> fastTrack; 61221035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent 6123735f45fbc37d7905ffb722f40727edbed82319b7Glenn Kasten // reference to a fast track which is about to be removed 6124735f45fbc37d7905ffb722f40727edbed82319b7Glenn Kasten sp<RecordTrack> fastTrackToRemove; 6125735f45fbc37d7905ffb722f40727edbed82319b7Glenn Kasten 612681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent { // scope for mLock 612781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent Mutex::Autolock _l(mLock); 6128000a4193dd82549192277fd4b9bb571d8a4c262fEric Laurent 6129021cf9634ab09c0753a40b7c9ef4ba603be5c3daEric Laurent processConfigEvents_l(); 6130f10ffec18f930d92e1abe9200d60e746831841a7Glenn Kasten 6131000a4193dd82549192277fd4b9bb571d8a4c262fEric Laurent // check exitPending here because checkForNewParameters_l() and 6132000a4193dd82549192277fd4b9bb571d8a4c262fEric Laurent // checkForNewParameters_l() can temporarily release mLock 6133000a4193dd82549192277fd4b9bb571d8a4c262fEric Laurent if (exitPending()) { 6134000a4193dd82549192277fd4b9bb571d8a4c262fEric Laurent break; 6135000a4193dd82549192277fd4b9bb571d8a4c262fEric Laurent } 6136000a4193dd82549192277fd4b9bb571d8a4c262fEric Laurent 61375c25d5637ef3406883e0fc97a713f9d5cdca426fEric Laurent // sleep with mutex unlocked 61385c25d5637ef3406883e0fc97a713f9d5cdca426fEric Laurent if (sleepUs > 0) { 6139f9715e43ea73361321663514c44129c939c5db2fGlenn Kasten ATRACE_BEGIN("sleepC"); 61405c25d5637ef3406883e0fc97a713f9d5cdca426fEric Laurent mWaitWorkCV.waitRelative(mLock, microseconds((nsecs_t)sleepUs)); 61415c25d5637ef3406883e0fc97a713f9d5cdca426fEric Laurent ATRACE_END(); 61425c25d5637ef3406883e0fc97a713f9d5cdca426fEric Laurent sleepUs = 0; 61435c25d5637ef3406883e0fc97a713f9d5cdca426fEric Laurent continue; 61445c25d5637ef3406883e0fc97a713f9d5cdca426fEric Laurent } 61455c25d5637ef3406883e0fc97a713f9d5cdca426fEric Laurent 61462b806406ac1ec680b6fe3aaa84c54bdc4e43ad8dGlenn Kasten // if no active track(s), then standby and release wakelock 61472b806406ac1ec680b6fe3aaa84c54bdc4e43ad8dGlenn Kasten size_t size = mActiveTracks.size(); 61482b806406ac1ec680b6fe3aaa84c54bdc4e43ad8dGlenn Kasten if (size == 0) { 614993e471f620454f7de73d190521568b1e25879767Glenn Kasten standbyIfNotAlreadyInStandby(); 61504ef0b463a56c19bad9197aa9f90d792090461429Glenn Kasten // exitPending() can't become true here 615181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent releaseWakeLock_l(); 615281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent ALOGV("RecordThread: loop stopping"); 615381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // go to sleep 615481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mWaitWorkCV.wait(mLock); 615581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent ALOGV("RecordThread: loop starting"); 6156f10ffec18f930d92e1abe9200d60e746831841a7Glenn Kasten goto reacquire_wakelock; 6157f10ffec18f930d92e1abe9200d60e746831841a7Glenn Kasten } 6158f10ffec18f930d92e1abe9200d60e746831841a7Glenn Kasten 61596dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten bool doBroadcast = false; 61605c25d5637ef3406883e0fc97a713f9d5cdca426fEric Laurent bool allStopped = true; 61616dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten for (size_t i = 0; i < size; ) { 61629e98235a9e9bb870e1c76911e3b4d00386a52c39Glenn Kasten 61636dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten activeTrack = mActiveTracks[i]; 61646dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten if (activeTrack->isTerminated()) { 6165735f45fbc37d7905ffb722f40727edbed82319b7Glenn Kasten if (activeTrack->isFastTrack()) { 6166735f45fbc37d7905ffb722f40727edbed82319b7Glenn Kasten ALOG_ASSERT(fastTrackToRemove == 0); 6167735f45fbc37d7905ffb722f40727edbed82319b7Glenn Kasten fastTrackToRemove = activeTrack; 6168735f45fbc37d7905ffb722f40727edbed82319b7Glenn Kasten } 61696dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten removeTrack_l(activeTrack); 61702b806406ac1ec680b6fe3aaa84c54bdc4e43ad8dGlenn Kasten mActiveTracks.remove(activeTrack); 61716dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten size--; 61729e98235a9e9bb870e1c76911e3b4d00386a52c39Glenn Kasten continue; 61739e98235a9e9bb870e1c76911e3b4d00386a52c39Glenn Kasten } 61746dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten 61756dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten TrackBase::track_state activeTrackState = activeTrack->mState; 61766dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten switch (activeTrackState) { 61776dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten 61786dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten case TrackBase::PAUSING: 61796dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten mActiveTracks.remove(activeTrack); 61806dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten doBroadcast = true; 61816dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten size--; 61826dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten continue; 61836dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten 61846dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten case TrackBase::STARTING_1: 61856dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten sleepUs = 10000; 61866dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten i++; 61875c25d5637ef3406883e0fc97a713f9d5cdca426fEric Laurent allStopped = false; 61886dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten continue; 61896dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten 61906dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten case TrackBase::STARTING_2: 61916dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten doBroadcast = true; 61926dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten mStandby = false; 61939e98235a9e9bb870e1c76911e3b4d00386a52c39Glenn Kasten activeTrack->mState = TrackBase::ACTIVE; 61945c25d5637ef3406883e0fc97a713f9d5cdca426fEric Laurent allStopped = false; 61956dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten break; 61966dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten 61976dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten case TrackBase::ACTIVE: 61985c25d5637ef3406883e0fc97a713f9d5cdca426fEric Laurent allStopped = false; 61996dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten break; 62006dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten 62016dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten case TrackBase::IDLE: 62026dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten i++; 62036dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten continue; 62046dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten 62056dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten default: 6206adad3d7d935da176ff24941b4ae9edf7340e9b96Glenn Kasten LOG_ALWAYS_FATAL("Unexpected activeTrackState %d", activeTrackState); 62079e98235a9e9bb870e1c76911e3b4d00386a52c39Glenn Kasten } 62082d94426cd3302cb1215c92c5f1c4b90c24ceb72bGlenn Kasten 62096dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten activeTracks.add(activeTrack); 62106dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten i++; 62112d94426cd3302cb1215c92c5f1c4b90c24ceb72bGlenn Kasten 62126dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten if (activeTrack->isFastTrack()) { 62136dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten ALOG_ASSERT(!mFastTrackAvail); 62146dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten ALOG_ASSERT(fastTrack == 0); 62156dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten fastTrack = activeTrack; 62166dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten } 62176dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten } 62185c25d5637ef3406883e0fc97a713f9d5cdca426fEric Laurent 6219dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hung mActiveTracks.updatePowerState(this); 6220dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hung 62215c25d5637ef3406883e0fc97a713f9d5cdca426fEric Laurent if (allStopped) { 62225c25d5637ef3406883e0fc97a713f9d5cdca426fEric Laurent standbyIfNotAlreadyInStandby(); 62235c25d5637ef3406883e0fc97a713f9d5cdca426fEric Laurent } 62246dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten if (doBroadcast) { 62256dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten mStartStopCond.broadcast(); 62266dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten } 6227d9fc34fb0fcfcc739f868b116edf50c62af19d5eGlenn Kasten 62286dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten // sleep if there are no active tracks to process 62296dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten if (activeTracks.size() == 0) { 62306dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten if (sleepUs == 0) { 62316dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten sleepUs = kRecordThreadSleepUs; 62326dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten } 62336dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten continue; 623481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 62356dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten sleepUs = 0; 62369e98235a9e9bb870e1c76911e3b4d00386a52c39Glenn Kasten 623781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent lockEffectChains_l(effectChains); 623881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 623981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 62406dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten // thread mutex is now unlocked, mActiveTracks unknown, activeTracks.size() > 0 62417165268ffa6c7b6b405b6afad82e2a346500e8eeGlenn Kasten 62426dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten size_t size = effectChains.size(); 62436dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten for (size_t i = 0; i < size; i++) { 62441ba19cd7fcdf18ab6efab2a1b831affab9a46157Glenn Kasten // thread mutex is not locked, but effect chain is locked 62451ba19cd7fcdf18ab6efab2a1b831affab9a46157Glenn Kasten effectChains[i]->process_l(); 62461ba19cd7fcdf18ab6efab2a1b831affab9a46157Glenn Kasten } 624781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 6248735f45fbc37d7905ffb722f40727edbed82319b7Glenn Kasten // Push a new fast capture state if fast capture is not already running, or cblk change 62496dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten if (mFastCapture != 0) { 62506dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten FastCaptureStateQueue *sq = mFastCapture->sq(); 62516dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten FastCaptureState *state = sq->begin(); 6252735f45fbc37d7905ffb722f40727edbed82319b7Glenn Kasten bool didModify = false; 6253735f45fbc37d7905ffb722f40727edbed82319b7Glenn Kasten FastCaptureStateQueue::block_t block = FastCaptureStateQueue::BLOCK_UNTIL_PUSHED; 62546dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten if (state->mCommand != FastCaptureState::READ_WRITE /* FIXME && 62556dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten (kUseFastMixer != FastMixer_Dynamic || state->mTrackMask > 1)*/) { 62566dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten if (state->mCommand == FastCaptureState::COLD_IDLE) { 62576dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten int32_t old = android_atomic_inc(&mFastCaptureFutex); 62586dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten if (old == -1) { 62596dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten (void) syscall(__NR_futex, &mFastCaptureFutex, FUTEX_WAKE_PRIVATE, 1); 62606dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten } 62616dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten } 62626dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten state->mCommand = FastCaptureState::READ_WRITE; 62636dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten#if 0 // FIXME 62646dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten mFastCaptureDumpState.increaseSamplingN(mAudioFlinger->isLowRamDevice() ? 6265fbdb2aceab7317aa44bc8f301a93eb49e17b2bceGlenn Kasten FastThreadDumpState::kSamplingNforLowRamDevice : 6266fbdb2aceab7317aa44bc8f301a93eb49e17b2bceGlenn Kasten FastThreadDumpState::kSamplingN); 62676dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten#endif 6268735f45fbc37d7905ffb722f40727edbed82319b7Glenn Kasten didModify = true; 6269735f45fbc37d7905ffb722f40727edbed82319b7Glenn Kasten } 6270735f45fbc37d7905ffb722f40727edbed82319b7Glenn Kasten audio_track_cblk_t *cblkOld = state->mCblk; 6271735f45fbc37d7905ffb722f40727edbed82319b7Glenn Kasten audio_track_cblk_t *cblkNew = fastTrack != 0 ? fastTrack->cblk() : NULL; 6272735f45fbc37d7905ffb722f40727edbed82319b7Glenn Kasten if (cblkNew != cblkOld) { 6273735f45fbc37d7905ffb722f40727edbed82319b7Glenn Kasten state->mCblk = cblkNew; 6274735f45fbc37d7905ffb722f40727edbed82319b7Glenn Kasten // block until acked if removing a fast track 6275735f45fbc37d7905ffb722f40727edbed82319b7Glenn Kasten if (cblkOld != NULL) { 6276735f45fbc37d7905ffb722f40727edbed82319b7Glenn Kasten block = FastCaptureStateQueue::BLOCK_UNTIL_ACKED; 6277735f45fbc37d7905ffb722f40727edbed82319b7Glenn Kasten } 6278735f45fbc37d7905ffb722f40727edbed82319b7Glenn Kasten didModify = true; 6279735f45fbc37d7905ffb722f40727edbed82319b7Glenn Kasten } 6280735f45fbc37d7905ffb722f40727edbed82319b7Glenn Kasten sq->end(didModify); 6281735f45fbc37d7905ffb722f40727edbed82319b7Glenn Kasten if (didModify) { 6282735f45fbc37d7905ffb722f40727edbed82319b7Glenn Kasten sq->push(block); 62836dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten#if 0 62846dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten if (kUseFastCapture == FastCapture_Dynamic) { 62856dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten mNormalSource = mPipeSource; 62866dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten } 62876dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten#endif 62886dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten } 62896dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten } 62906dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten 6291735f45fbc37d7905ffb722f40727edbed82319b7Glenn Kasten // now run the fast track destructor with thread mutex unlocked 6292735f45fbc37d7905ffb722f40727edbed82319b7Glenn Kasten fastTrackToRemove.clear(); 6293735f45fbc37d7905ffb722f40727edbed82319b7Glenn Kasten 62946dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten // Read from HAL to keep up with fastest client if multiple active tracks, not slowest one. 62956dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten // Only the client(s) that are too slow will overrun. But if even the fastest client is too 62966dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten // slow, then this RecordThread will overrun by not calling HAL read often enough. 62976dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten // If destination is non-contiguous, first read past the nominal end of buffer, then 62986dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten // copy to the right place. Permitted because mRsmpInBuffer was over-allocated. 62996dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten 63006dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten int32_t rear = mRsmpInRear & (mRsmpInFramesP2 - 1); 63016dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten ssize_t framesRead; 63026dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten 63036dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten // If an NBAIO source is present, use it to read the normal capture's data 63046dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten if (mPipeSource != 0) { 63056dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten size_t framesToRead = mBufferSize / mFrameSize; 63061b291841a58ce6b2b291232dfdd56134b2185c48Glenn Kasten framesToRead = min(mRsmpInFramesOA - rear, mRsmpInFramesP2 / 2); 63075744661e85981f8a9456bf470e2761235fc026daAndy Hung framesRead = mPipeSource->read((uint8_t*)mRsmpInBuffer + rear * mFrameSize, 6308d79072e9dff59f767cce2cda1caab80ce5a0815bGlenn Kasten framesToRead); 63091b291841a58ce6b2b291232dfdd56134b2185c48Glenn Kasten // since pipe is non-blocking, simulate blocking input by waiting for 1/2 of 63101b291841a58ce6b2b291232dfdd56134b2185c48Glenn Kasten // buffer size or at least for 20ms. 63111b291841a58ce6b2b291232dfdd56134b2185c48Glenn Kasten size_t sleepFrames = max( 63121b291841a58ce6b2b291232dfdd56134b2185c48Glenn Kasten min(mPipeFramesP2, mRsmpInFramesP2) / 2, FMS_20 * mSampleRate / 1000); 63131b291841a58ce6b2b291232dfdd56134b2185c48Glenn Kasten if (framesRead <= (ssize_t) sleepFrames) { 63141b291841a58ce6b2b291232dfdd56134b2185c48Glenn Kasten sleepUs = (sleepFrames * 1000000LL) / mSampleRate; 63151b291841a58ce6b2b291232dfdd56134b2185c48Glenn Kasten } 63161b291841a58ce6b2b291232dfdd56134b2185c48Glenn Kasten if (framesRead < 0) { 63171b291841a58ce6b2b291232dfdd56134b2185c48Glenn Kasten status_t status = (status_t) framesRead; 63181b291841a58ce6b2b291232dfdd56134b2185c48Glenn Kasten switch (status) { 63191b291841a58ce6b2b291232dfdd56134b2185c48Glenn Kasten case OVERRUN: 63201b291841a58ce6b2b291232dfdd56134b2185c48Glenn Kasten ALOGW("overrun on read from pipe"); 63211b291841a58ce6b2b291232dfdd56134b2185c48Glenn Kasten framesRead = 0; 63221b291841a58ce6b2b291232dfdd56134b2185c48Glenn Kasten break; 63231b291841a58ce6b2b291232dfdd56134b2185c48Glenn Kasten case NEGOTIATE: 63241b291841a58ce6b2b291232dfdd56134b2185c48Glenn Kasten ALOGE("re-negotiation is needed"); 63251b291841a58ce6b2b291232dfdd56134b2185c48Glenn Kasten framesRead = -1; // Will cause an attempt to recover. 63261b291841a58ce6b2b291232dfdd56134b2185c48Glenn Kasten break; 63271b291841a58ce6b2b291232dfdd56134b2185c48Glenn Kasten default: 63281b291841a58ce6b2b291232dfdd56134b2185c48Glenn Kasten ALOGE("unknown error %d on read from pipe", status); 63291b291841a58ce6b2b291232dfdd56134b2185c48Glenn Kasten break; 63301b291841a58ce6b2b291232dfdd56134b2185c48Glenn Kasten } 63316dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten } 63326dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten // otherwise use the HAL / AudioStreamIn directly 63336dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten } else { 6334ec6a70345fc99cd9f8461749a7656b8240874a62Glenn Kasten ATRACE_BEGIN("read"); 63351dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov size_t bytesRead; 63361dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov status_t result = mInput->stream->read( 63371dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov (uint8_t*)mRsmpInBuffer + rear * mFrameSize, mBufferSize, &bytesRead); 6338ec6a70345fc99cd9f8461749a7656b8240874a62Glenn Kasten ATRACE_END(); 63391dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov if (result < 0) { 63401dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov framesRead = result; 63416dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten } else { 63426dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten framesRead = bytesRead / mFrameSize; 63436dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten } 63446dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten } 63456dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten 63463f0c902beb53a245c9db35e871607dba05b8d391Andy Hung // Update server timestamp with server stats 63473f0c902beb53a245c9db35e871607dba05b8d391Andy Hung // systemTime() is optional if the hardware supports timestamps. 63483f0c902beb53a245c9db35e871607dba05b8d391Andy Hung mTimestamp.mPosition[ExtendedTimestamp::LOCATION_SERVER] += framesRead; 63493f0c902beb53a245c9db35e871607dba05b8d391Andy Hung mTimestamp.mTimeNs[ExtendedTimestamp::LOCATION_SERVER] = systemTime(); 63503f0c902beb53a245c9db35e871607dba05b8d391Andy Hung 63513f0c902beb53a245c9db35e871607dba05b8d391Andy Hung // Update server timestamp with kernel stats 63521dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov if (mPipeSource.get() == nullptr /* don't obtain for FastCapture, could block */) { 63533f0c902beb53a245c9db35e871607dba05b8d391Andy Hung int64_t position, time; 63541dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov int ret = mInput->stream->getCapturePosition(&position, &time); 63553f0c902beb53a245c9db35e871607dba05b8d391Andy Hung if (ret == NO_ERROR) { 63563f0c902beb53a245c9db35e871607dba05b8d391Andy Hung mTimestamp.mPosition[ExtendedTimestamp::LOCATION_KERNEL] = position; 63573f0c902beb53a245c9db35e871607dba05b8d391Andy Hung mTimestamp.mTimeNs[ExtendedTimestamp::LOCATION_KERNEL] = time; 63583f0c902beb53a245c9db35e871607dba05b8d391Andy Hung // Note: In general record buffers should tend to be empty in 63593f0c902beb53a245c9db35e871607dba05b8d391Andy Hung // a properly running pipeline. 63603f0c902beb53a245c9db35e871607dba05b8d391Andy Hung // 63613f0c902beb53a245c9db35e871607dba05b8d391Andy Hung // Also, it is not advantageous to call get_presentation_position during the read 63623f0c902beb53a245c9db35e871607dba05b8d391Andy Hung // as the read obtains a lock, preventing the timestamp call from executing. 63633f0c902beb53a245c9db35e871607dba05b8d391Andy Hung } 63643f0c902beb53a245c9db35e871607dba05b8d391Andy Hung } 63653f0c902beb53a245c9db35e871607dba05b8d391Andy Hung // Use this to track timestamp information 63663f0c902beb53a245c9db35e871607dba05b8d391Andy Hung // ALOGD("%s", mTimestamp.toString().c_str()); 63673f0c902beb53a245c9db35e871607dba05b8d391Andy Hung 63686dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten if (framesRead < 0 || (framesRead == 0 && mPipeSource == 0)) { 6369c42e9b462661673dff480ee71757a58b0f806370Glenn Kasten ALOGE("read failed: framesRead=%zd", framesRead); 63706dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten // Force input into standby so that it tries to recover at next read attempt 63716dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten inputStandBy(); 63726dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten sleepUs = kRecordThreadSleepUs; 63736dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten } 63746dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten if (framesRead <= 0) { 63753d61bc1ffc8afc8d7be3b0d4205c9b5ba6daf2e8Glenn Kasten goto unlock; 63766dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten } 63776dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten ALOG_ASSERT(framesRead > 0); 63786dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten 63796dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten if (mTeeSink != 0) { 63805744661e85981f8a9456bf470e2761235fc026daAndy Hung (void) mTeeSink->write((uint8_t*)mRsmpInBuffer + rear * mFrameSize, framesRead); 63816dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten } 63826dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten // If destination is non-contiguous, we now correct for reading past end of buffer. 63833d61bc1ffc8afc8d7be3b0d4205c9b5ba6daf2e8Glenn Kasten { 63843d61bc1ffc8afc8d7be3b0d4205c9b5ba6daf2e8Glenn Kasten size_t part1 = mRsmpInFramesP2 - rear; 63853d61bc1ffc8afc8d7be3b0d4205c9b5ba6daf2e8Glenn Kasten if ((size_t) framesRead > part1) { 63865744661e85981f8a9456bf470e2761235fc026daAndy Hung memcpy(mRsmpInBuffer, (uint8_t*)mRsmpInBuffer + mRsmpInFramesP2 * mFrameSize, 63873d61bc1ffc8afc8d7be3b0d4205c9b5ba6daf2e8Glenn Kasten (framesRead - part1) * mFrameSize); 63883d61bc1ffc8afc8d7be3b0d4205c9b5ba6daf2e8Glenn Kasten } 63896dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten } 63906dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten rear = mRsmpInRear += framesRead; 63916dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten 63926dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten size = activeTracks.size(); 63936dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten // loop over each active track 63946dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten for (size_t i = 0; i < size; i++) { 63956dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten activeTrack = activeTracks[i]; 63966dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten 63976dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten // skip fast tracks, as those are handled directly by FastCapture 63986dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten if (activeTrack->isFastTrack()) { 63996dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten continue; 64006dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten } 64016dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten 640273c02e4277b399c2ec1555d32b6ad5df23bb83dcAndy Hung // TODO: This code probably should be moved to RecordTrack. 640397a893eb34f8687485c88eaf15917974a203f20bAndy Hung // TODO: Update the activeTrack buffer converter in case of reconfigure. 640497a893eb34f8687485c88eaf15917974a203f20bAndy Hung 64056dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten enum { 64066dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten OVERRUN_UNKNOWN, 64076dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten OVERRUN_TRUE, 64086dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten OVERRUN_FALSE 64096dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten } overrun = OVERRUN_UNKNOWN; 64106dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten 64116dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten // loop over getNextBuffer to handle circular sink 64126dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten for (;;) { 64136dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten 64146dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten activeTrack->mSink.frameCount = ~0; 64156dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten status_t status = activeTrack->getNextBuffer(&activeTrack->mSink); 64166dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten size_t framesOut = activeTrack->mSink.frameCount; 64176dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten LOG_ALWAYS_FATAL_IF((status == OK) != (framesOut > 0)); 64186dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten 641973c02e4277b399c2ec1555d32b6ad5df23bb83dcAndy Hung // check available frames and handle overrun conditions 642073c02e4277b399c2ec1555d32b6ad5df23bb83dcAndy Hung // if the record track isn't draining fast enough. 642173c02e4277b399c2ec1555d32b6ad5df23bb83dcAndy Hung bool hasOverrun; 64226dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten size_t framesIn; 642373c02e4277b399c2ec1555d32b6ad5df23bb83dcAndy Hung activeTrack->mResamplerBufferProvider->sync(&framesIn, &hasOverrun); 642473c02e4277b399c2ec1555d32b6ad5df23bb83dcAndy Hung if (hasOverrun) { 64256dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten overrun = OVERRUN_TRUE; 64266dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten } 64274cc0a6a835c806d200ef83ef31fe5bef327c355cGlenn Kasten if (framesOut == 0 || framesIn == 0) { 64284cc0a6a835c806d200ef83ef31fe5bef327c355cGlenn Kasten break; 64294cc0a6a835c806d200ef83ef31fe5bef327c355cGlenn Kasten } 64304cc0a6a835c806d200ef83ef31fe5bef327c355cGlenn Kasten 64316770c6faa3467c92eabc5ec9b23d60eb556a0d03Andy Hung // Don't allow framesOut to be larger than what is possible with resampling 64326770c6faa3467c92eabc5ec9b23d60eb556a0d03Andy Hung // from framesIn. 64336770c6faa3467c92eabc5ec9b23d60eb556a0d03Andy Hung // This isn't strictly necessary but helps limit buffer resizing in 64346770c6faa3467c92eabc5ec9b23d60eb556a0d03Andy Hung // RecordBufferConverter. TODO: remove when no longer needed. 64356770c6faa3467c92eabc5ec9b23d60eb556a0d03Andy Hung framesOut = min(framesOut, 64366770c6faa3467c92eabc5ec9b23d60eb556a0d03Andy Hung destinationFramesPossible( 64376770c6faa3467c92eabc5ec9b23d60eb556a0d03Andy Hung framesIn, mSampleRate, activeTrack->mSampleRate)); 643897a893eb34f8687485c88eaf15917974a203f20bAndy Hung // process frames from the RecordThread buffer provider to the RecordTrack buffer 643997a893eb34f8687485c88eaf15917974a203f20bAndy Hung framesOut = activeTrack->mRecordBufferConverter->convert( 644097a893eb34f8687485c88eaf15917974a203f20bAndy Hung activeTrack->mSink.raw, activeTrack->mResamplerBufferProvider, framesOut); 64418594843c15b4722ced39436fe9e64f3e57e7ace4Glenn Kasten 64426dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten if (framesOut > 0 && (overrun == OVERRUN_UNKNOWN)) { 64436dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten overrun = OVERRUN_FALSE; 64441ba19cd7fcdf18ab6efab2a1b831affab9a46157Glenn Kasten } 644581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 64466dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten if (activeTrack->mFramesToDrop == 0) { 64476dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten if (framesOut > 0) { 64486dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten activeTrack->mSink.frameCount = framesOut; 64496dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten activeTrack->releaseBuffer(&activeTrack->mSink); 645081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 645181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } else { 64526dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten // FIXME could do a partial drop of framesOut 64536dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten if (activeTrack->mFramesToDrop > 0) { 64546dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten activeTrack->mFramesToDrop -= framesOut; 64556dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten if (activeTrack->mFramesToDrop <= 0) { 645625f4aa83efaa9179e65a20583a6d441de2c3ff3fGlenn Kasten activeTrack->clearSyncStartEvent(); 64576dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten } 64586dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten } else { 64596dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten activeTrack->mFramesToDrop += framesOut; 64606dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten if (activeTrack->mFramesToDrop >= 0 || activeTrack->mSyncStartEvent == 0 || 64616dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten activeTrack->mSyncStartEvent->isCancelled()) { 64626dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten ALOGW("Synced record %s, session %d, trigger session %d", 64636dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten (activeTrack->mFramesToDrop >= 0) ? "timed out" : "cancelled", 64646dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten activeTrack->sessionId(), 64656dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten (activeTrack->mSyncStartEvent != 0) ? 6466d848eb48c121c119e8ba7583efc75415fe102570Glenn Kasten activeTrack->mSyncStartEvent->triggerSession() : 6467d848eb48c121c119e8ba7583efc75415fe102570Glenn Kasten AUDIO_SESSION_NONE); 646825f4aa83efaa9179e65a20583a6d441de2c3ff3fGlenn Kasten activeTrack->clearSyncStartEvent(); 64696dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten } 647081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 647181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 64726dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten 64736dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten if (framesOut == 0) { 64746dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten break; 64756dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten } 647681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 64776dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten 64786dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten switch (overrun) { 64796dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten case OVERRUN_TRUE: 64806dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten // client isn't retrieving buffers fast enough 64816dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten if (!activeTrack->setOverflow()) { 64826dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten nsecs_t now = systemTime(); 64836dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten // FIXME should lastWarning per track? 64846dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten if ((now - lastWarning) > kWarningThrottleNs) { 64856dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten ALOGW("RecordThread: buffer overflow"); 64866dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten lastWarning = now; 64876dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten } 648881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 64896dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten break; 64906dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten case OVERRUN_FALSE: 64916dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten activeTrack->clearOverflow(); 64926dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten break; 64936dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten case OVERRUN_UNKNOWN: 64946dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten break; 649581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 64966dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten 64973f0c902beb53a245c9db35e871607dba05b8d391Andy Hung // update frame information and push timestamp out 64983f0c902beb53a245c9db35e871607dba05b8d391Andy Hung activeTrack->updateTrackFrameInfo( 64996ae5843c281301a9ffd1059d185620a9337e15a2Andy Hung activeTrack->mServerProxy->framesReleased(), 65003f0c902beb53a245c9db35e871607dba05b8d391Andy Hung mTimestamp.mPosition[ExtendedTimestamp::LOCATION_SERVER], 65013f0c902beb53a245c9db35e871607dba05b8d391Andy Hung mSampleRate, mTimestamp); 650281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 65031ba19cd7fcdf18ab6efab2a1b831affab9a46157Glenn Kasten 65043d61bc1ffc8afc8d7be3b0d4205c9b5ba6daf2e8Glenn Kastenunlock: 650581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // enable changes in effect chain 650681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent unlockEffectChains(effectChains); 6507c527a7c2b1bfd26e8f3086e1b653d56e521379d9Glenn Kasten // effectChains doesn't need to be cleared, since it is cleared by destructor at scope end 650881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 650981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 651093e471f620454f7de73d190521568b1e25879767Glenn Kasten standbyIfNotAlreadyInStandby(); 651181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 651281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent { 651381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent Mutex::Autolock _l(mLock); 65149a54bc27876acd5d8be5b1fc3dc46701fe76fbb3Eric Laurent for (size_t i = 0; i < mTracks.size(); i++) { 65159a54bc27876acd5d8be5b1fc3dc46701fe76fbb3Eric Laurent sp<RecordTrack> track = mTracks[i]; 65169a54bc27876acd5d8be5b1fc3dc46701fe76fbb3Eric Laurent track->invalidate(); 65179a54bc27876acd5d8be5b1fc3dc46701fe76fbb3Eric Laurent } 65182b806406ac1ec680b6fe3aaa84c54bdc4e43ad8dGlenn Kasten mActiveTracks.clear(); 651981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mStartStopCond.broadcast(); 652081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 652181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 652281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent releaseWakeLock(); 652381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 652481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent ALOGV("RecordThread %p exiting", this); 652581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent return false; 652681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 652781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 652893e471f620454f7de73d190521568b1e25879767Glenn Kastenvoid AudioFlinger::RecordThread::standbyIfNotAlreadyInStandby() 652981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 653081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (!mStandby) { 653181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent inputStandBy(); 653281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mStandby = true; 653381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 653481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 653581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 653681784c37c61b09289654b979567a42bf73cd2b12Eric Laurentvoid AudioFlinger::RecordThread::inputStandBy() 653781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 65386dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten // Idle the fast capture if it's currently running 65396dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten if (mFastCapture != 0) { 65406dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten FastCaptureStateQueue *sq = mFastCapture->sq(); 65416dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten FastCaptureState *state = sq->begin(); 65426dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten if (!(state->mCommand & FastCaptureState::IDLE)) { 65436dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten state->mCommand = FastCaptureState::COLD_IDLE; 65446dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten state->mColdFutexAddr = &mFastCaptureFutex; 65456dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten state->mColdGen++; 65466dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten mFastCaptureFutex = 0; 65476dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten sq->end(); 65486dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten // BLOCK_UNTIL_PUSHED would be insufficient, as we need it to stop doing I/O now 65496dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten sq->push(FastCaptureStateQueue::BLOCK_UNTIL_ACKED); 65506dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten#if 0 65516dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten if (kUseFastCapture == FastCapture_Dynamic) { 65526dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten // FIXME 65536dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten } 65546dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten#endif 65556dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten#ifdef AUDIO_WATCHDOG 65566dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten // FIXME 65576dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten#endif 65586dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten } else { 65596dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten sq->end(false /*didModify*/); 65606dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten } 65616dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten } 65621dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov status_t result = mInput->stream->standby(); 65631dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov ALOGE_IF(result != OK, "Error when putting input stream into standby: %d", result); 6564ad6d52d38917069e3d8e68cec1625855b9d96200Andy Hung 6565ad6d52d38917069e3d8e68cec1625855b9d96200Andy Hung // If going into standby, flush the pipe source. 6566ad6d52d38917069e3d8e68cec1625855b9d96200Andy Hung if (mPipeSource.get() != nullptr) { 6567ad6d52d38917069e3d8e68cec1625855b9d96200Andy Hung const ssize_t flushed = mPipeSource->flush(); 6568ad6d52d38917069e3d8e68cec1625855b9d96200Andy Hung if (flushed > 0) { 6569ad6d52d38917069e3d8e68cec1625855b9d96200Andy Hung ALOGV("Input standby flushed PipeSource %zd frames", flushed); 6570ad6d52d38917069e3d8e68cec1625855b9d96200Andy Hung mTimestamp.mPosition[ExtendedTimestamp::LOCATION_SERVER] += flushed; 6571ad6d52d38917069e3d8e68cec1625855b9d96200Andy Hung mTimestamp.mTimeNs[ExtendedTimestamp::LOCATION_SERVER] = systemTime(); 6572ad6d52d38917069e3d8e68cec1625855b9d96200Andy Hung } 6573ad6d52d38917069e3d8e68cec1625855b9d96200Andy Hung } 657481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 657581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 657605997e21af6c4517f375def6563af4b9ebe95f39Glenn Kasten// RecordThread::createRecordTrack_l() must be called with AudioFlinger::mLock held 6577e198c360d5e75a9b2097844c495c10902e7e8500Glenn Kastensp<AudioFlinger::RecordThread::RecordTrack> AudioFlinger::RecordThread::createRecordTrack_l( 657881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent const sp<AudioFlinger::Client>& client, 657981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent uint32_t sampleRate, 658081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent audio_format_t format, 658181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent audio_channel_mask_t channelMask, 658274935e44734c1ec235c2b6677db3e0dbefa5ddb8Glenn Kasten size_t *pFrameCount, 6583d848eb48c121c119e8ba7583efc75415fe102570Glenn Kasten audio_session_t sessionId, 65847df8c0b799d8f52d6386e03313286dbd7d5cdc7cGlenn Kasten size_t *notificationFrames, 65851f12a8ad958344c50733b948628ffa06db9c5bc6Andy Hung uid_t uid, 6586050677873c10d4da308ac222f8533c96cca3207eEric Laurent audio_input_flags_t *flags, 658781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent pid_t tid, 658820b9ef0b55c9150ae11057ab997ae61be2d496efEric Laurent status_t *status, 658920b9ef0b55c9150ae11057ab997ae61be2d496efEric Laurent audio_port_handle_t portId) 659081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 659174935e44734c1ec235c2b6677db3e0dbefa5ddb8Glenn Kasten size_t frameCount = *pFrameCount; 659281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent sp<RecordTrack> track; 659381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent status_t lStatus; 6594050677873c10d4da308ac222f8533c96cca3207eEric Laurent audio_input_flags_t inputFlags = mInput->flags; 6595050677873c10d4da308ac222f8533c96cca3207eEric Laurent 6596050677873c10d4da308ac222f8533c96cca3207eEric Laurent // special case for FAST flag considered OK if fast capture is present 6597050677873c10d4da308ac222f8533c96cca3207eEric Laurent if (hasFastCapture()) { 6598050677873c10d4da308ac222f8533c96cca3207eEric Laurent inputFlags = (audio_input_flags_t)(inputFlags | AUDIO_INPUT_FLAG_FAST); 6599050677873c10d4da308ac222f8533c96cca3207eEric Laurent } 6600050677873c10d4da308ac222f8533c96cca3207eEric Laurent 6601050677873c10d4da308ac222f8533c96cca3207eEric Laurent // Check if requested flags are compatible with output stream flags 6602050677873c10d4da308ac222f8533c96cca3207eEric Laurent if ((*flags & inputFlags) != *flags) { 6603050677873c10d4da308ac222f8533c96cca3207eEric Laurent ALOGW("createRecordTrack_l(): mismatch between requested flags (%08x) and" 6604050677873c10d4da308ac222f8533c96cca3207eEric Laurent " input flags (%08x)", 6605050677873c10d4da308ac222f8533c96cca3207eEric Laurent *flags, inputFlags); 6606050677873c10d4da308ac222f8533c96cca3207eEric Laurent *flags = (audio_input_flags_t)(*flags & inputFlags); 6607050677873c10d4da308ac222f8533c96cca3207eEric Laurent } 660881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 660990e58b1fefc8caf70b34301a92bc86179580b6fcGlenn Kasten // client expresses a preference for FAST, but we get the final say 6610050677873c10d4da308ac222f8533c96cca3207eEric Laurent if (*flags & AUDIO_INPUT_FLAG_FAST) { 661190e58b1fefc8caf70b34301a92bc86179580b6fcGlenn Kasten if ( 6612b7fbf7ecc6b034243ec64f79f3113675b5e3c941Glenn Kasten // we formerly checked for a callback handler (non-0 tid), 6613b7fbf7ecc6b034243ec64f79f3113675b5e3c941Glenn Kasten // but that is no longer required for TRANSFER_OBTAIN mode 6614b7fbf7ecc6b034243ec64f79f3113675b5e3c941Glenn Kasten // 66157410591dad836434c72ddee66680802708b70c10Glenn Kasten // frame count is not specified, or is exactly the pipe depth 66167410591dad836434c72ddee66680802708b70c10Glenn Kasten ((frameCount == 0) || (frameCount == mPipeFramesP2)) && 66173a6c90aa0617666d9abc94c02b752d9eb3d64772Glenn Kasten // PCM data 66183a6c90aa0617666d9abc94c02b752d9eb3d64772Glenn Kasten audio_is_linear_pcm(format) && 66197fd0422fbd17af3b24eb04421d37fce50f3826e2Glenn Kasten // hardware format 66206dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten (format == mFormat) && 66217fd0422fbd17af3b24eb04421d37fce50f3826e2Glenn Kasten // hardware channel mask 66226dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten (channelMask == mChannelMask) && 66237fd0422fbd17af3b24eb04421d37fce50f3826e2Glenn Kasten // hardware sample rate 662490e58b1fefc8caf70b34301a92bc86179580b6fcGlenn Kasten (sampleRate == mSampleRate) && 66253a6c90aa0617666d9abc94c02b752d9eb3d64772Glenn Kasten // record thread has an associated fast capture 66266dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten hasFastCapture() && 66276dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten // there are sufficient fast track slots available 66286dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten mFastTrackAvail 662990e58b1fefc8caf70b34301a92bc86179580b6fcGlenn Kasten ) { 66304c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent // check compatibility with audio effects. 66314c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent Mutex::Autolock _l(mLock); 66324c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent // Do not accept FAST flag if the session has software effects 66334c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent sp<EffectChain> chain = getEffectChain_l(sessionId); 66344c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent if (chain != 0) { 6635d3bb0adfe40e60bb94e9a87e8d5bffb4ea6863b0Andy Hung audio_input_flags_t old = *flags; 6636d3bb0adfe40e60bb94e9a87e8d5bffb4ea6863b0Andy Hung chain->checkInputFlagCompatibility(flags); 6637d3bb0adfe40e60bb94e9a87e8d5bffb4ea6863b0Andy Hung if (old != *flags) { 6638d3bb0adfe40e60bb94e9a87e8d5bffb4ea6863b0Andy Hung ALOGV("AUDIO_INPUT_FLAGS denied by effect old=%#x new=%#x", 6639d3bb0adfe40e60bb94e9a87e8d5bffb4ea6863b0Andy Hung (int)old, (int)*flags); 66404c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent } 66414c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent } 6642122f7e793fe6fb8904634cc6d2e35ac4b014ea72Eric Laurent ALOGV_IF((*flags & AUDIO_INPUT_FLAG_FAST) != 0, 66434c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent "AUDIO_INPUT_FLAG_FAST accepted: frameCount=%zu mFrameCount=%zu", 66444c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent frameCount, mFrameCount); 664590e58b1fefc8caf70b34301a92bc86179580b6fcGlenn Kasten } else { 6646c42e9b462661673dff480ee71757a58b0f806370Glenn Kasten ALOGV("AUDIO_INPUT_FLAG_FAST denied: frameCount=%zu mFrameCount=%zu mPipeFramesP2=%zu " 66477410591dad836434c72ddee66680802708b70c10Glenn Kasten "format=%#x isLinear=%d channelMask=%#x sampleRate=%u mSampleRate=%u " 66486dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten "hasFastCapture=%d tid=%d mFastTrackAvail=%d", 66497410591dad836434c72ddee66680802708b70c10Glenn Kasten frameCount, mFrameCount, mPipeFramesP2, 66507410591dad836434c72ddee66680802708b70c10Glenn Kasten format, audio_is_linear_pcm(format), channelMask, sampleRate, mSampleRate, 66517410591dad836434c72ddee66680802708b70c10Glenn Kasten hasFastCapture(), tid, mFastTrackAvail); 6652050677873c10d4da308ac222f8533c96cca3207eEric Laurent *flags = (audio_input_flags_t)(*flags & ~AUDIO_INPUT_FLAG_FAST); 66537410591dad836434c72ddee66680802708b70c10Glenn Kasten } 66547410591dad836434c72ddee66680802708b70c10Glenn Kasten } 66557410591dad836434c72ddee66680802708b70c10Glenn Kasten 66567410591dad836434c72ddee66680802708b70c10Glenn Kasten // compute track buffer size in frames, and suggest the notification frame count 6657050677873c10d4da308ac222f8533c96cca3207eEric Laurent if (*flags & AUDIO_INPUT_FLAG_FAST) { 66587410591dad836434c72ddee66680802708b70c10Glenn Kasten // fast track: frame count is exactly the pipe depth 66597410591dad836434c72ddee66680802708b70c10Glenn Kasten frameCount = mPipeFramesP2; 66607410591dad836434c72ddee66680802708b70c10Glenn Kasten // ignore requested notificationFrames, and always notify exactly once every HAL buffer 66617410591dad836434c72ddee66680802708b70c10Glenn Kasten *notificationFrames = mFrameCount; 66627410591dad836434c72ddee66680802708b70c10Glenn Kasten } else { 666349d00ad9164ea5ce48c85765a2b6460d9b457d38Glenn Kasten // not fast track: max notification period is resampled equivalent of one HAL buffer time 666449d00ad9164ea5ce48c85765a2b6460d9b457d38Glenn Kasten // or 20 ms if there is a fast capture 666549d00ad9164ea5ce48c85765a2b6460d9b457d38Glenn Kasten // TODO This could be a roundupRatio inline, and const 666649d00ad9164ea5ce48c85765a2b6460d9b457d38Glenn Kasten size_t maxNotificationFrames = ((int64_t) (hasFastCapture() ? mSampleRate/50 : mFrameCount) 666749d00ad9164ea5ce48c85765a2b6460d9b457d38Glenn Kasten * sampleRate + mSampleRate - 1) / mSampleRate; 666849d00ad9164ea5ce48c85765a2b6460d9b457d38Glenn Kasten // minimum number of notification periods is at least kMinNotifications, 666949d00ad9164ea5ce48c85765a2b6460d9b457d38Glenn Kasten // and at least kMinMs rounded up to a whole notification period (minNotificationsByMs) 667049d00ad9164ea5ce48c85765a2b6460d9b457d38Glenn Kasten static const size_t kMinNotifications = 3; 667149d00ad9164ea5ce48c85765a2b6460d9b457d38Glenn Kasten static const uint32_t kMinMs = 30; 667249d00ad9164ea5ce48c85765a2b6460d9b457d38Glenn Kasten // TODO This could be a roundupRatio inline 667349d00ad9164ea5ce48c85765a2b6460d9b457d38Glenn Kasten const size_t minFramesByMs = (sampleRate * kMinMs + 1000 - 1) / 1000; 667449d00ad9164ea5ce48c85765a2b6460d9b457d38Glenn Kasten // TODO This could be a roundupRatio inline 667549d00ad9164ea5ce48c85765a2b6460d9b457d38Glenn Kasten const size_t minNotificationsByMs = (minFramesByMs + maxNotificationFrames - 1) / 667649d00ad9164ea5ce48c85765a2b6460d9b457d38Glenn Kasten maxNotificationFrames; 667749d00ad9164ea5ce48c85765a2b6460d9b457d38Glenn Kasten const size_t minFrameCount = maxNotificationFrames * 667849d00ad9164ea5ce48c85765a2b6460d9b457d38Glenn Kasten max(kMinNotifications, minNotificationsByMs); 667949d00ad9164ea5ce48c85765a2b6460d9b457d38Glenn Kasten frameCount = max(frameCount, minFrameCount); 668049d00ad9164ea5ce48c85765a2b6460d9b457d38Glenn Kasten if (*notificationFrames == 0 || *notificationFrames > maxNotificationFrames) { 668149d00ad9164ea5ce48c85765a2b6460d9b457d38Glenn Kasten *notificationFrames = maxNotificationFrames; 66827410591dad836434c72ddee66680802708b70c10Glenn Kasten } 668390e58b1fefc8caf70b34301a92bc86179580b6fcGlenn Kasten } 668474935e44734c1ec235c2b6677db3e0dbefa5ddb8Glenn Kasten *pFrameCount = frameCount; 668590e58b1fefc8caf70b34301a92bc86179580b6fcGlenn Kasten 668615e5798908ccac14e10c84834eaf08c42931bd06Glenn Kasten lStatus = initCheck(); 668715e5798908ccac14e10c84834eaf08c42931bd06Glenn Kasten if (lStatus != NO_ERROR) { 668815e5798908ccac14e10c84834eaf08c42931bd06Glenn Kasten ALOGE("createRecordTrack_l() audio driver not initialized"); 668915e5798908ccac14e10c84834eaf08c42931bd06Glenn Kasten goto Exit; 669015e5798908ccac14e10c84834eaf08c42931bd06Glenn Kasten } 669181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 669281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent { // scope for mLock 669381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent Mutex::Autolock _l(mLock); 669481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 669581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent track = new RecordTrack(this, client, sampleRate, 669683b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent format, channelMask, frameCount, NULL, sessionId, uid, 669720b9ef0b55c9150ae11057ab997ae61be2d496efEric Laurent *flags, TrackBase::TYPE_DEFAULT, portId); 669881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 6699030033342a6ea17003e6af38a56c7edc6d2ead01Glenn Kasten lStatus = track->initCheck(); 6700030033342a6ea17003e6af38a56c7edc6d2ead01Glenn Kasten if (lStatus != NO_ERROR) { 670135295078ab59c8c5d143a54d5a55557c3ca62c51Glenn Kasten ALOGE("createRecordTrack_l() initCheck failed %d; no control block?", lStatus); 670203e9e83c47ab4a518da0a1f36b8f702f59221c95Haynes Mathew George // track must be cleared from the caller as the caller has the AF lock 670381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent goto Exit; 670481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 670581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mTracks.add(track); 670681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 670781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // disable AEC and NS if the device is a BT SCO headset supporting those pre processings 670881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent bool suspend = audio_is_bluetooth_sco_device(mInDevice) && 670981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mAudioFlinger->btNrecIsOff(); 671081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent setEffectSuspended_l(FX_IID_AEC, suspend, sessionId); 671181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent setEffectSuspended_l(FX_IID_NS, suspend, sessionId); 671290e58b1fefc8caf70b34301a92bc86179580b6fcGlenn Kasten 6713050677873c10d4da308ac222f8533c96cca3207eEric Laurent if ((*flags & AUDIO_INPUT_FLAG_FAST) && (tid != -1)) { 671490e58b1fefc8caf70b34301a92bc86179580b6fcGlenn Kasten pid_t callingPid = IPCThreadState::self()->getCallingPid(); 671590e58b1fefc8caf70b34301a92bc86179580b6fcGlenn Kasten // we don't have CAP_SYS_NICE, nor do we want to have it as it's too powerful, 671690e58b1fefc8caf70b34301a92bc86179580b6fcGlenn Kasten // so ask activity manager to do this on our behalf 671783f042776b131b149f803fff6ab184ae2c4d98cdMikhail Naganov sendPrioConfigEvent_l(callingPid, tid, kPriorityAudioApp, true); 671890e58b1fefc8caf70b34301a92bc86179580b6fcGlenn Kasten } 671981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 672005997e21af6c4517f375def6563af4b9ebe95f39Glenn Kasten 672181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent lStatus = NO_ERROR; 672281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 672381784c37c61b09289654b979567a42bf73cd2b12Eric LaurentExit: 67249156ef3e11b68cc4b6d3cea77f1f63673855a6d1Glenn Kasten *status = lStatus; 672581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent return track; 672681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 672781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 672881784c37c61b09289654b979567a42bf73cd2b12Eric Laurentstatus_t AudioFlinger::RecordThread::start(RecordThread::RecordTrack* recordTrack, 672981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent AudioSystem::sync_event_t event, 6730d848eb48c121c119e8ba7583efc75415fe102570Glenn Kasten audio_session_t triggerSession) 673181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 673281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent ALOGV("RecordThread::start event %d, triggerSession %d", event, triggerSession); 673381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent sp<ThreadBase> strongMe = this; 673481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent status_t status = NO_ERROR; 673581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 673681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (event == AudioSystem::SYNC_EVENT_NONE) { 673725f4aa83efaa9179e65a20583a6d441de2c3ff3fGlenn Kasten recordTrack->clearSyncStartEvent(); 673881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } else if (event != AudioSystem::SYNC_EVENT_SAME) { 67396dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten recordTrack->mSyncStartEvent = mAudioFlinger->createSyncEvent(event, 674081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent triggerSession, 674181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent recordTrack->sessionId(), 674281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent syncStartEventCallback, 67436dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten recordTrack); 674481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // Sync event can be cancelled by the trigger session if the track is not in a 674581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // compatible state in which case we start record immediately 67466dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten if (recordTrack->mSyncStartEvent->isCancelled()) { 674725f4aa83efaa9179e65a20583a6d441de2c3ff3fGlenn Kasten recordTrack->clearSyncStartEvent(); 674881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } else { 674981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // do not wait for the event for more than AudioSystem::kSyncRecordStartTimeOutMs 67506dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten recordTrack->mFramesToDrop = - 67514cc0a6a835c806d200ef83ef31fe5bef327c355cGlenn Kasten ((AudioSystem::kSyncRecordStartTimeOutMs * recordTrack->mSampleRate) / 1000); 675281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 675381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 675481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 675581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent { 675647c2070b2ce8aedb7300c0aad91caccf3c383841Glenn Kasten // This section is a rendezvous between binder thread executing start() and RecordThread 675781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent AutoMutex lock(mLock); 67586dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten if (mActiveTracks.indexOf(recordTrack) >= 0) { 67596dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten if (recordTrack->mState == TrackBase::PAUSING) { 67606dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten ALOGV("active record track PAUSING -> ACTIVE"); 6761f10ffec18f930d92e1abe9200d60e746831841a7Glenn Kasten recordTrack->mState = TrackBase::ACTIVE; 67626dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten } else { 67636dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten ALOGV("active record track state %d", recordTrack->mState); 676481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 676581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent return status; 676681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 676781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 67684cc0a6a835c806d200ef83ef31fe5bef327c355cGlenn Kasten // TODO consider other ways of handling this, such as changing the state to :STARTING and 67694cc0a6a835c806d200ef83ef31fe5bef327c355cGlenn Kasten // adding the track to mActiveTracks after returning from AudioSystem::startInput(), 67704cc0a6a835c806d200ef83ef31fe5bef327c355cGlenn Kasten // or using a separate command thread 67716dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten recordTrack->mState = TrackBase::STARTING_1; 67722b806406ac1ec680b6fe3aaa84c54bdc4e43ad8dGlenn Kasten mActiveTracks.add(recordTrack); 677383b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent status_t status = NO_ERROR; 677483b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent if (recordTrack->isExternalTrack()) { 677583b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent mLock.unlock(); 6776d848eb48c121c119e8ba7583efc75415fe102570Glenn Kasten status = AudioSystem::startInput(mId, recordTrack->sessionId()); 677783b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent mLock.lock(); 677883b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent // FIXME should verify that recordTrack is still in mActiveTracks 677983b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent if (status != NO_ERROR) { 678083b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent mActiveTracks.remove(recordTrack); 678183b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent recordTrack->clearSyncStartEvent(); 678283b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent ALOGV("RecordThread::start error %d", status); 678383b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent return status; 678483b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent } 678581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 67866dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten // Catch up with current buffer indices if thread is already running. 67876dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten // This is what makes a new client discard all buffered data. If the track's mRsmpInFront 67886dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten // was initialized to some value closer to the thread's mRsmpInFront, then the track could 67896dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten // see previously buffered data before it called start(), but with greater risk of overrun. 67906dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten 679173c02e4277b399c2ec1555d32b6ad5df23bb83dcAndy Hung recordTrack->mResamplerBufferProvider->reset(); 679297a893eb34f8687485c88eaf15917974a203f20bAndy Hung // clear any converter state as new data will be discontinuous 679397a893eb34f8687485c88eaf15917974a203f20bAndy Hung recordTrack->mRecordBufferConverter->reset(); 67946dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten recordTrack->mState = TrackBase::STARTING_2; 679581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // signal thread to start 679681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mWaitWorkCV.broadcast(); 67972b806406ac1ec680b6fe3aaa84c54bdc4e43ad8dGlenn Kasten if (mActiveTracks.indexOf(recordTrack) < 0) { 679881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent ALOGV("Record failed to start"); 679981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent status = BAD_VALUE; 680081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent goto startError; 680181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 680281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent return status; 680381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 68047c027248e1a4ccd5b22bc4deafb03e2d87ac8f38Glenn Kasten 680581784c37c61b09289654b979567a42bf73cd2b12Eric LaurentstartError: 680683b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent if (recordTrack->isExternalTrack()) { 6807d848eb48c121c119e8ba7583efc75415fe102570Glenn Kasten AudioSystem::stopInput(mId, recordTrack->sessionId()); 680883b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent } 680925f4aa83efaa9179e65a20583a6d441de2c3ff3fGlenn Kasten recordTrack->clearSyncStartEvent(); 68106dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten // FIXME I wonder why we do not reset the state here? 681181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent return status; 681281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 681381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 681481784c37c61b09289654b979567a42bf73cd2b12Eric Laurentvoid AudioFlinger::RecordThread::syncStartEventCallback(const wp<SyncEvent>& event) 681581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 681681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent sp<SyncEvent> strongEvent = event.promote(); 681781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 681881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (strongEvent != 0) { 68198ea16e4b0a7d398d26887c18675b3899de5d779dEric Laurent sp<RefBase> ptr = strongEvent->cookie().promote(); 68208ea16e4b0a7d398d26887c18675b3899de5d779dEric Laurent if (ptr != 0) { 68218ea16e4b0a7d398d26887c18675b3899de5d779dEric Laurent RecordTrack *recordTrack = (RecordTrack *)ptr.get(); 68228ea16e4b0a7d398d26887c18675b3899de5d779dEric Laurent recordTrack->handleSyncStartEvent(strongEvent); 68238ea16e4b0a7d398d26887c18675b3899de5d779dEric Laurent } 682481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 682581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 682681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 6827a8356f663014e7d4c27869629af83d8bb3441e19Glenn Kastenbool AudioFlinger::RecordThread::stop(RecordThread::RecordTrack* recordTrack) { 682881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent ALOGV("RecordThread::stop"); 6829a8356f663014e7d4c27869629af83d8bb3441e19Glenn Kasten AutoMutex _l(mLock); 683038f86713cbd22caae9fdd4ac2f0bb76ff91df34dJean-Michel Trivi if (mActiveTracks.indexOf(recordTrack) < 0 || recordTrack->mState == TrackBase::PAUSING) { 683181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent return false; 683281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 683347c2070b2ce8aedb7300c0aad91caccf3c383841Glenn Kasten // note that threadLoop may still be processing the track at this point [without lock] 683481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent recordTrack->mState = TrackBase::PAUSING; 68355c25d5637ef3406883e0fc97a713f9d5cdca426fEric Laurent // signal thread to stop 68365c25d5637ef3406883e0fc97a713f9d5cdca426fEric Laurent mWaitWorkCV.broadcast(); 683781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // do not wait for mStartStopCond if exiting 683881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (exitPending()) { 683981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent return true; 684081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 684147c2070b2ce8aedb7300c0aad91caccf3c383841Glenn Kasten // FIXME incorrect usage of wait: no explicit predicate or loop 684281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mStartStopCond.wait(mLock); 68432b806406ac1ec680b6fe3aaa84c54bdc4e43ad8dGlenn Kasten // if we have been restarted, recordTrack is in mActiveTracks here 684438f86713cbd22caae9fdd4ac2f0bb76ff91df34dJean-Michel Trivi if (exitPending() || mActiveTracks.indexOf(recordTrack) < 0) { 684581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent ALOGV("Record stopped OK"); 684681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent return true; 684781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 684881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent return false; 684981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 685081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 68510f11b51a57bc9062c4fe8af73747319cedabc5d6Glenn Kastenbool AudioFlinger::RecordThread::isValidSyncEvent(const sp<SyncEvent>& event __unused) const 685281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 685381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent return false; 685481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 685581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 68560f11b51a57bc9062c4fe8af73747319cedabc5d6Glenn Kastenstatus_t AudioFlinger::RecordThread::setSyncEvent(const sp<SyncEvent>& event __unused) 685781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 685881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent#if 0 // This branch is currently dead code, but is preserved in case it will be needed in future 685981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (!isValidSyncEvent(event)) { 686081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent return BAD_VALUE; 686181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 686281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 6863d848eb48c121c119e8ba7583efc75415fe102570Glenn Kasten audio_session_t eventSession = event->triggerSession(); 686481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent status_t ret = NAME_NOT_FOUND; 686581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 686681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent Mutex::Autolock _l(mLock); 686781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 686881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent for (size_t i = 0; i < mTracks.size(); i++) { 686981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent sp<RecordTrack> track = mTracks[i]; 687081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (eventSession == track->sessionId()) { 687181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent (void) track->setSyncEvent(event); 687281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent ret = NO_ERROR; 687381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 687481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 687581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent return ret; 687681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent#else 687781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent return BAD_VALUE; 687881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent#endif 687981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 688081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 688181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// destroyTrack_l() must be called with ThreadBase::mLock held 688281784c37c61b09289654b979567a42bf73cd2b12Eric Laurentvoid AudioFlinger::RecordThread::destroyTrack_l(const sp<RecordTrack>& track) 688381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 6884bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent track->terminate(); 6885bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent track->mState = TrackBase::STOPPED; 688681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // active tracks are removed by threadLoop() 68872b806406ac1ec680b6fe3aaa84c54bdc4e43ad8dGlenn Kasten if (mActiveTracks.indexOf(track) < 0) { 688881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent removeTrack_l(track); 688981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 689081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 689181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 689281784c37c61b09289654b979567a42bf73cd2b12Eric Laurentvoid AudioFlinger::RecordThread::removeTrack_l(const sp<RecordTrack>& track) 689381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 689481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mTracks.remove(track); 689581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // need anything related to effects here? 68966dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten if (track->isFastTrack()) { 68976dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten ALOG_ASSERT(!mFastTrackAvail); 68986dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten mFastTrackAvail = true; 68996dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten } 690081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 690181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 690281784c37c61b09289654b979567a42bf73cd2b12Eric Laurentvoid AudioFlinger::RecordThread::dump(int fd, const Vector<String16>& args) 690381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 690481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent dumpInternals(fd, args); 690581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent dumpTracks(fd, args); 690681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent dumpEffectChains(fd, args); 690781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 690881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 690981784c37c61b09289654b979567a42bf73cd2b12Eric Laurentvoid AudioFlinger::RecordThread::dumpInternals(int fd, const Vector<String16>& args) 691081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 691144182c206f7c5584ef2cf504da6be98fab665dbfGlenn Kasten dumpBase(fd, args); 691244182c206f7c5584ef2cf504da6be98fab665dbfGlenn Kasten 6913913d06c099bd689375483a839e11057ccf284d1cMikhail Naganov AudioStreamIn *input = mInput; 6914913d06c099bd689375483a839e11057ccf284d1cMikhail Naganov audio_input_flags_t flags = input != NULL ? input->flags : AUDIO_INPUT_FLAG_NONE; 6915913d06c099bd689375483a839e11057ccf284d1cMikhail Naganov dprintf(fd, " AudioStreamIn: %p flags %#x (%s)\n", 6916913d06c099bd689375483a839e11057ccf284d1cMikhail Naganov input, flags, inputFlagsToString(flags).c_str()); 691744182c206f7c5584ef2cf504da6be98fab665dbfGlenn Kasten if (mActiveTracks.size() == 0) { 691887cebadd48710e42474756fc3513df678de045ceElliott Hughes dprintf(fd, " No active record clients\n"); 691981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 69206e6704c06d61bc356e30c164081e5bcffb37920cGlenn Kasten dprintf(fd, " Fast capture thread: %s\n", hasFastCapture() ? "yes" : "no"); 69216dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten dprintf(fd, " Fast track available: %s\n", mFastTrackAvail ? "yes" : "no"); 692217c9c998afed5ed9df7495eeed5822f3ed53ebecGlenn Kasten 69232f90c51d42efa881a9e54e4f4efadf99398304f9Glenn Kasten // Make a non-atomic copy of fast capture dump state so it won't change underneath us 69242f90c51d42efa881a9e54e4f4efadf99398304f9Glenn Kasten // while we are dumping it. It may be inconsistent, but it won't mutate! 69252f90c51d42efa881a9e54e4f4efadf99398304f9Glenn Kasten // This is a large object so we place it on the heap. 69262f90c51d42efa881a9e54e4f4efadf99398304f9Glenn Kasten // FIXME 25972958: Need an intelligent copy constructor that does not touch unused pages. 69272f90c51d42efa881a9e54e4f4efadf99398304f9Glenn Kasten const FastCaptureDumpState *copy = new FastCaptureDumpState(mFastCaptureDumpState); 69282f90c51d42efa881a9e54e4f4efadf99398304f9Glenn Kasten copy->dump(fd); 69292f90c51d42efa881a9e54e4f4efadf99398304f9Glenn Kasten delete copy; 693081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 693181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 69320f11b51a57bc9062c4fe8af73747319cedabc5d6Glenn Kastenvoid AudioFlinger::RecordThread::dumpTracks(int fd, const Vector<String16>& args __unused) 693381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 693481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent const size_t SIZE = 256; 693581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent char buffer[SIZE]; 693681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent String8 result; 693781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 6938b220884bf3129253cc5bc8d030bc475411ea4911Marco Nelissen size_t numtracks = mTracks.size(); 6939b220884bf3129253cc5bc8d030bc475411ea4911Marco Nelissen size_t numactive = mActiveTracks.size(); 6940b220884bf3129253cc5bc8d030bc475411ea4911Marco Nelissen size_t numactiveseen = 0; 6941c42e9b462661673dff480ee71757a58b0f806370Glenn Kasten dprintf(fd, " %zu Tracks", numtracks); 6942b220884bf3129253cc5bc8d030bc475411ea4911Marco Nelissen if (numtracks) { 6943c42e9b462661673dff480ee71757a58b0f806370Glenn Kasten dprintf(fd, " of which %zu are active\n", numactive); 6944b220884bf3129253cc5bc8d030bc475411ea4911Marco Nelissen RecordTrack::appendDumpHeader(result); 6945b220884bf3129253cc5bc8d030bc475411ea4911Marco Nelissen for (size_t i = 0; i < numtracks ; ++i) { 6946b220884bf3129253cc5bc8d030bc475411ea4911Marco Nelissen sp<RecordTrack> track = mTracks[i]; 6947b220884bf3129253cc5bc8d030bc475411ea4911Marco Nelissen if (track != 0) { 6948b220884bf3129253cc5bc8d030bc475411ea4911Marco Nelissen bool active = mActiveTracks.indexOf(track) >= 0; 6949b220884bf3129253cc5bc8d030bc475411ea4911Marco Nelissen if (active) { 6950b220884bf3129253cc5bc8d030bc475411ea4911Marco Nelissen numactiveseen++; 6951b220884bf3129253cc5bc8d030bc475411ea4911Marco Nelissen } 6952b220884bf3129253cc5bc8d030bc475411ea4911Marco Nelissen track->dump(buffer, SIZE, active); 6953b220884bf3129253cc5bc8d030bc475411ea4911Marco Nelissen result.append(buffer); 6954b220884bf3129253cc5bc8d030bc475411ea4911Marco Nelissen } 695581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 6956b220884bf3129253cc5bc8d030bc475411ea4911Marco Nelissen } else { 695787cebadd48710e42474756fc3513df678de045ceElliott Hughes dprintf(fd, "\n"); 695881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 695981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 6960b220884bf3129253cc5bc8d030bc475411ea4911Marco Nelissen if (numactiveseen != numactive) { 6961b220884bf3129253cc5bc8d030bc475411ea4911Marco Nelissen snprintf(buffer, SIZE, " The following tracks are in the active list but" 6962b220884bf3129253cc5bc8d030bc475411ea4911Marco Nelissen " not in the track list\n"); 696381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent result.append(buffer); 696481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent RecordTrack::appendDumpHeader(result); 6965b220884bf3129253cc5bc8d030bc475411ea4911Marco Nelissen for (size_t i = 0; i < numactive; ++i) { 69662b806406ac1ec680b6fe3aaa84c54bdc4e43ad8dGlenn Kasten sp<RecordTrack> track = mActiveTracks[i]; 6967b220884bf3129253cc5bc8d030bc475411ea4911Marco Nelissen if (mTracks.indexOf(track) < 0) { 6968b220884bf3129253cc5bc8d030bc475411ea4911Marco Nelissen track->dump(buffer, SIZE, true); 6969b220884bf3129253cc5bc8d030bc475411ea4911Marco Nelissen result.append(buffer); 6970b220884bf3129253cc5bc8d030bc475411ea4911Marco Nelissen } 69712b806406ac1ec680b6fe3aaa84c54bdc4e43ad8dGlenn Kasten } 697281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 697381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 697481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent write(fd, result.string(), result.size()); 697581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 697681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 697773c02e4277b399c2ec1555d32b6ad5df23bb83dcAndy Hung 697873c02e4277b399c2ec1555d32b6ad5df23bb83dcAndy Hungvoid AudioFlinger::RecordThread::ResamplerBufferProvider::reset() 697973c02e4277b399c2ec1555d32b6ad5df23bb83dcAndy Hung{ 698073c02e4277b399c2ec1555d32b6ad5df23bb83dcAndy Hung sp<ThreadBase> threadBase = mRecordTrack->mThread.promote(); 698173c02e4277b399c2ec1555d32b6ad5df23bb83dcAndy Hung RecordThread *recordThread = (RecordThread *) threadBase.get(); 698273c02e4277b399c2ec1555d32b6ad5df23bb83dcAndy Hung mRsmpInFront = recordThread->mRsmpInRear; 698373c02e4277b399c2ec1555d32b6ad5df23bb83dcAndy Hung mRsmpInUnrel = 0; 698473c02e4277b399c2ec1555d32b6ad5df23bb83dcAndy Hung} 698573c02e4277b399c2ec1555d32b6ad5df23bb83dcAndy Hung 698673c02e4277b399c2ec1555d32b6ad5df23bb83dcAndy Hungvoid AudioFlinger::RecordThread::ResamplerBufferProvider::sync( 698773c02e4277b399c2ec1555d32b6ad5df23bb83dcAndy Hung size_t *framesAvailable, bool *hasOverrun) 698873c02e4277b399c2ec1555d32b6ad5df23bb83dcAndy Hung{ 698973c02e4277b399c2ec1555d32b6ad5df23bb83dcAndy Hung sp<ThreadBase> threadBase = mRecordTrack->mThread.promote(); 699073c02e4277b399c2ec1555d32b6ad5df23bb83dcAndy Hung RecordThread *recordThread = (RecordThread *) threadBase.get(); 699173c02e4277b399c2ec1555d32b6ad5df23bb83dcAndy Hung const int32_t rear = recordThread->mRsmpInRear; 699273c02e4277b399c2ec1555d32b6ad5df23bb83dcAndy Hung const int32_t front = mRsmpInFront; 699373c02e4277b399c2ec1555d32b6ad5df23bb83dcAndy Hung const ssize_t filled = rear - front; 699473c02e4277b399c2ec1555d32b6ad5df23bb83dcAndy Hung 699573c02e4277b399c2ec1555d32b6ad5df23bb83dcAndy Hung size_t framesIn; 699673c02e4277b399c2ec1555d32b6ad5df23bb83dcAndy Hung bool overrun = false; 699773c02e4277b399c2ec1555d32b6ad5df23bb83dcAndy Hung if (filled < 0) { 699873c02e4277b399c2ec1555d32b6ad5df23bb83dcAndy Hung // should not happen, but treat like a massive overrun and re-sync 699973c02e4277b399c2ec1555d32b6ad5df23bb83dcAndy Hung framesIn = 0; 700073c02e4277b399c2ec1555d32b6ad5df23bb83dcAndy Hung mRsmpInFront = rear; 700173c02e4277b399c2ec1555d32b6ad5df23bb83dcAndy Hung overrun = true; 700273c02e4277b399c2ec1555d32b6ad5df23bb83dcAndy Hung } else if ((size_t) filled <= recordThread->mRsmpInFrames) { 700373c02e4277b399c2ec1555d32b6ad5df23bb83dcAndy Hung framesIn = (size_t) filled; 700473c02e4277b399c2ec1555d32b6ad5df23bb83dcAndy Hung } else { 700573c02e4277b399c2ec1555d32b6ad5df23bb83dcAndy Hung // client is not keeping up with server, but give it latest data 700673c02e4277b399c2ec1555d32b6ad5df23bb83dcAndy Hung framesIn = recordThread->mRsmpInFrames; 700773c02e4277b399c2ec1555d32b6ad5df23bb83dcAndy Hung mRsmpInFront = /* front = */ rear - framesIn; 700873c02e4277b399c2ec1555d32b6ad5df23bb83dcAndy Hung overrun = true; 700973c02e4277b399c2ec1555d32b6ad5df23bb83dcAndy Hung } 701073c02e4277b399c2ec1555d32b6ad5df23bb83dcAndy Hung if (framesAvailable != NULL) { 701173c02e4277b399c2ec1555d32b6ad5df23bb83dcAndy Hung *framesAvailable = framesIn; 701273c02e4277b399c2ec1555d32b6ad5df23bb83dcAndy Hung } 701373c02e4277b399c2ec1555d32b6ad5df23bb83dcAndy Hung if (hasOverrun != NULL) { 701473c02e4277b399c2ec1555d32b6ad5df23bb83dcAndy Hung *hasOverrun = overrun; 701573c02e4277b399c2ec1555d32b6ad5df23bb83dcAndy Hung } 701673c02e4277b399c2ec1555d32b6ad5df23bb83dcAndy Hung} 701773c02e4277b399c2ec1555d32b6ad5df23bb83dcAndy Hung 701881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// AudioBufferProvider interface 70196dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kastenstatus_t AudioFlinger::RecordThread::ResamplerBufferProvider::getNextBuffer( 7020d79072e9dff59f767cce2cda1caab80ce5a0815bGlenn Kasten AudioBufferProvider::Buffer* buffer) 702181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 702273c02e4277b399c2ec1555d32b6ad5df23bb83dcAndy Hung sp<ThreadBase> threadBase = mRecordTrack->mThread.promote(); 70236dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten if (threadBase == 0) { 70246dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten buffer->frameCount = 0; 7025607fa3e928de696eba49f198af72d68e4591ca1bGlenn Kasten buffer->raw = NULL; 70266dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten return NOT_ENOUGH_DATA; 70276dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten } 70286dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten RecordThread *recordThread = (RecordThread *) threadBase.get(); 70296dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten int32_t rear = recordThread->mRsmpInRear; 703073c02e4277b399c2ec1555d32b6ad5df23bb83dcAndy Hung int32_t front = mRsmpInFront; 70318594843c15b4722ced39436fe9e64f3e57e7ace4Glenn Kasten ssize_t filled = rear - front; 70326dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten // FIXME should not be P2 (don't want to increase latency) 70336dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten // FIXME if client not keeping up, discard 7034607fa3e928de696eba49f198af72d68e4591ca1bGlenn Kasten LOG_ALWAYS_FATAL_IF(!(0 <= filled && (size_t) filled <= recordThread->mRsmpInFrames)); 70358594843c15b4722ced39436fe9e64f3e57e7ace4Glenn Kasten // 'filled' may be non-contiguous, so return only the first contiguous chunk 70366dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten front &= recordThread->mRsmpInFramesP2 - 1; 70376dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten size_t part1 = recordThread->mRsmpInFramesP2 - front; 70388594843c15b4722ced39436fe9e64f3e57e7ace4Glenn Kasten if (part1 > (size_t) filled) { 70398594843c15b4722ced39436fe9e64f3e57e7ace4Glenn Kasten part1 = filled; 70408594843c15b4722ced39436fe9e64f3e57e7ace4Glenn Kasten } 70418594843c15b4722ced39436fe9e64f3e57e7ace4Glenn Kasten size_t ask = buffer->frameCount; 70428594843c15b4722ced39436fe9e64f3e57e7ace4Glenn Kasten ALOG_ASSERT(ask > 0); 70438594843c15b4722ced39436fe9e64f3e57e7ace4Glenn Kasten if (part1 > ask) { 70448594843c15b4722ced39436fe9e64f3e57e7ace4Glenn Kasten part1 = ask; 70458594843c15b4722ced39436fe9e64f3e57e7ace4Glenn Kasten } 70468594843c15b4722ced39436fe9e64f3e57e7ace4Glenn Kasten if (part1 == 0) { 704773c02e4277b399c2ec1555d32b6ad5df23bb83dcAndy Hung // out of data is fine since the resampler will return a short-count. 70488594843c15b4722ced39436fe9e64f3e57e7ace4Glenn Kasten buffer->raw = NULL; 70498594843c15b4722ced39436fe9e64f3e57e7ace4Glenn Kasten buffer->frameCount = 0; 705073c02e4277b399c2ec1555d32b6ad5df23bb83dcAndy Hung mRsmpInUnrel = 0; 70518594843c15b4722ced39436fe9e64f3e57e7ace4Glenn Kasten return NOT_ENOUGH_DATA; 70528594843c15b4722ced39436fe9e64f3e57e7ace4Glenn Kasten } 70538594843c15b4722ced39436fe9e64f3e57e7ace4Glenn Kasten 70545744661e85981f8a9456bf470e2761235fc026daAndy Hung buffer->raw = (uint8_t*)recordThread->mRsmpInBuffer + front * recordThread->mFrameSize; 70558594843c15b4722ced39436fe9e64f3e57e7ace4Glenn Kasten buffer->frameCount = part1; 705673c02e4277b399c2ec1555d32b6ad5df23bb83dcAndy Hung mRsmpInUnrel = part1; 705781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent return NO_ERROR; 705881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 705981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 706081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// AudioBufferProvider interface 70616dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kastenvoid AudioFlinger::RecordThread::ResamplerBufferProvider::releaseBuffer( 70626dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten AudioBufferProvider::Buffer* buffer) 706381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 70648594843c15b4722ced39436fe9e64f3e57e7ace4Glenn Kasten size_t stepCount = buffer->frameCount; 70658594843c15b4722ced39436fe9e64f3e57e7ace4Glenn Kasten if (stepCount == 0) { 70668594843c15b4722ced39436fe9e64f3e57e7ace4Glenn Kasten return; 70678594843c15b4722ced39436fe9e64f3e57e7ace4Glenn Kasten } 706873c02e4277b399c2ec1555d32b6ad5df23bb83dcAndy Hung ALOG_ASSERT(stepCount <= mRsmpInUnrel); 706973c02e4277b399c2ec1555d32b6ad5df23bb83dcAndy Hung mRsmpInUnrel -= stepCount; 707073c02e4277b399c2ec1555d32b6ad5df23bb83dcAndy Hung mRsmpInFront += stepCount; 70718594843c15b4722ced39436fe9e64f3e57e7ace4Glenn Kasten buffer->raw = NULL; 707281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent buffer->frameCount = 0; 707381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 707481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 707597a893eb34f8687485c88eaf15917974a203f20bAndy Hung 70761035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurentbool AudioFlinger::RecordThread::checkForNewParameter_l(const String8& keyValuePair, 70771035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent status_t& status) 707881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 707981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent bool reconfig = false; 708081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 70811035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent status = NO_ERROR; 70821035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent 70831035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent audio_format_t reqFormat = mFormat; 70841035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent uint32_t samplingRate = mSampleRate; 7085e1635ec096d1110c33a5aa46847af59c261fb7faGlenn Kasten // TODO this may change if we want to support capture from HDMI PCM multi channel (e.g on TVs). 70861035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent audio_channel_mask_t channelMask = audio_channel_in_mask_from_count(mChannelCount); 70871035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent 70881035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent AudioParameter param = AudioParameter(keyValuePair); 70891035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent int value; 70909ce67b524236db52eadf558e7765775acad89f1fHaynes Mathew George 70919ce67b524236db52eadf558e7765775acad89f1fHaynes Mathew George // scope for AutoPark extends to end of method 70929ce67b524236db52eadf558e7765775acad89f1fHaynes Mathew George AutoPark<FastCapture> park(mFastCapture); 70939ce67b524236db52eadf558e7765775acad89f1fHaynes Mathew George 70941035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent // TODO Investigate when this code runs. Check with audio policy when a sample rate and 70951035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent // channel count change can be requested. Do we mandate the first client defines the 70961035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent // HAL sampling rate and channel count or do we allow changes on the fly? 70971035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent if (param.getInt(String8(AudioParameter::keySamplingRate), value) == NO_ERROR) { 70981035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent samplingRate = value; 70991035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent reconfig = true; 71001035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent } 71011035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent if (param.getInt(String8(AudioParameter::keyFormat), value) == NO_ERROR) { 710297a893eb34f8687485c88eaf15917974a203f20bAndy Hung if (!audio_is_linear_pcm((audio_format_t) value)) { 71031035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent status = BAD_VALUE; 71041035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent } else { 71051035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent reqFormat = (audio_format_t) value; 710681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent reconfig = true; 710781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 71081035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent } 71091035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent if (param.getInt(String8(AudioParameter::keyChannels), value) == NO_ERROR) { 71101035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent audio_channel_mask_t mask = (audio_channel_mask_t) value; 7111d330ee46022f34da76d14d0c4d2910526ecc2321Andy Hung if (!audio_is_input_channel(mask) || 7112d330ee46022f34da76d14d0c4d2910526ecc2321Andy Hung audio_channel_count_from_in_mask(mask) > FCC_8) { 71131035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent status = BAD_VALUE; 71141035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent } else { 71151035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent channelMask = mask; 71161035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent reconfig = true; 711781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 71181035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent } 71191035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent if (param.getInt(String8(AudioParameter::keyFrameCount), value) == NO_ERROR) { 71201035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent // do not accept frame count changes if tracks are open as the track buffer 71211035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent // size depends on frame count and correct behavior would not be guaranteed 71221035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent // if frame count is changed after track creation 71231035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent if (mActiveTracks.size() > 0) { 71241035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent status = INVALID_OPERATION; 71251035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent } else { 71261035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent reconfig = true; 712781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 71281035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent } 71291035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent if (param.getInt(String8(AudioParameter::keyRouting), value) == NO_ERROR) { 71301035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent // forward device change to effects that have requested to be 71311035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent // aware of attached audio device. 71321035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent for (size_t i = 0; i < mEffectChains.size(); i++) { 71331035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent mEffectChains[i]->setDevice_l(value); 713481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 713581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 71361035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent // store input device and output device but do not forward output device to audio HAL. 71371035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent // Note that status is ignored by the caller for output device 71381035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent // (see AudioFlinger::setParameters() 71391035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent if (audio_is_output_devices(value)) { 71401035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent mOutDevice = value; 71411035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent status = BAD_VALUE; 71421035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent } else { 71431035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent mInDevice = value; 7144e8726fea8a53bf3474aa3c6deaf2f6c1f565e694Eric Laurent if (value != AUDIO_DEVICE_NONE) { 7145e8726fea8a53bf3474aa3c6deaf2f6c1f565e694Eric Laurent mPrevInDevice = value; 7146e8726fea8a53bf3474aa3c6deaf2f6c1f565e694Eric Laurent } 71471035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent // disable AEC and NS if the device is a BT SCO headset supporting those 71481035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent // pre processings 71491035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent if (mTracks.size() > 0) { 71501035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent bool suspend = audio_is_bluetooth_sco_device(mInDevice) && 71511035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent mAudioFlinger->btNrecIsOff(); 71521035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent for (size_t i = 0; i < mTracks.size(); i++) { 71531035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent sp<RecordTrack> track = mTracks[i]; 71541035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent setEffectSuspended_l(FX_IID_AEC, suspend, track->sessionId()); 71551035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent setEffectSuspended_l(FX_IID_NS, suspend, track->sessionId()); 715681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 715781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 715881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 71591035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent } 71601035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent if (param.getInt(String8(AudioParameter::keyInputSource), value) == NO_ERROR && 71611035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent mAudioSource != (audio_source_t)value) { 71621035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent // forward device change to effects that have requested to be 71631035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent // aware of attached audio device. 71641035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent for (size_t i = 0; i < mEffectChains.size(); i++) { 71651035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent mEffectChains[i]->setAudioSource_l((audio_source_t)value); 716681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 71671035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent mAudioSource = (audio_source_t)value; 71681035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent } 7169e198c360d5e75a9b2097844c495c10902e7e8500Glenn Kasten 71701035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent if (status == NO_ERROR) { 71711dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov status = mInput->stream->setParameters(keyValuePair); 71721035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent if (status == INVALID_OPERATION) { 71731035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent inputStandBy(); 71741dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov status = mInput->stream->setParameters(keyValuePair); 71751035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent } 71761035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent if (reconfig) { 71771dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov if (status == BAD_VALUE) { 71781dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov uint32_t sRate; 71791dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov audio_channel_mask_t channelMask; 71801dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov audio_format_t format; 71811dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov if (mInput->stream->getAudioProperties(&sRate, &channelMask, &format) == OK && 71821dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov audio_is_linear_pcm(format) && audio_is_linear_pcm(reqFormat) && 71831dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov sRate <= (AUDIO_RESAMPLER_DOWN_RATIO_MAX * samplingRate) && 71841dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov audio_channel_count_from_in_mask(channelMask) <= FCC_8) { 71851dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov status = NO_ERROR; 71861dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov } 718781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 71881035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent if (status == NO_ERROR) { 71891035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent readInputParameters_l(); 719073e26b661af50be2c0a4ff6c9ac85f7347a8b235Eric Laurent sendIoConfigEvent_l(AUDIO_INPUT_CONFIG_CHANGED); 719181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 719281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 719381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 71941035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent 719581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent return reconfig; 719681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 719781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 719881784c37c61b09289654b979567a42bf73cd2b12Eric LaurentString8 AudioFlinger::RecordThread::getParameters(const String8& keys) 719981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 720081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent Mutex::Autolock _l(mLock); 72011dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov if (initCheck() == NO_ERROR) { 72021dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov String8 out_s8; 72031dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov if (mInput->stream->getParameters(keys, &out_s8) == OK) { 72041dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov return out_s8; 72051dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov } 720681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 72071dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov return String8(); 720881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 720981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 72107c1ec5f038e63a5eb8b04434577c25bc23f5f410Eric Laurentvoid AudioFlinger::RecordThread::ioConfigChanged(audio_io_config_event event, pid_t pid) { 721173e26b661af50be2c0a4ff6c9ac85f7347a8b235Eric Laurent sp<AudioIoDescriptor> desc = new AudioIoDescriptor(); 721273e26b661af50be2c0a4ff6c9ac85f7347a8b235Eric Laurent 721373e26b661af50be2c0a4ff6c9ac85f7347a8b235Eric Laurent desc->mIoHandle = mId; 721481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 721581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent switch (event) { 721673e26b661af50be2c0a4ff6c9ac85f7347a8b235Eric Laurent case AUDIO_INPUT_OPENED: 721773e26b661af50be2c0a4ff6c9ac85f7347a8b235Eric Laurent case AUDIO_INPUT_CONFIG_CHANGED: 7218296fb13dd9b5e90d6a05cce897c3b1e7914a478aEric Laurent desc->mPatch = mPatch; 721973e26b661af50be2c0a4ff6c9ac85f7347a8b235Eric Laurent desc->mChannelMask = mChannelMask; 722073e26b661af50be2c0a4ff6c9ac85f7347a8b235Eric Laurent desc->mSamplingRate = mSampleRate; 722173e26b661af50be2c0a4ff6c9ac85f7347a8b235Eric Laurent desc->mFormat = mFormat; 722273e26b661af50be2c0a4ff6c9ac85f7347a8b235Eric Laurent desc->mFrameCount = mFrameCount; 72234a8308b11b92e608cdaf29f73f7919e75706f9a2Glenn Kasten desc->mFrameCountHAL = mFrameCount; 722473e26b661af50be2c0a4ff6c9ac85f7347a8b235Eric Laurent desc->mLatency = 0; 722581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent break; 722681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 722773e26b661af50be2c0a4ff6c9ac85f7347a8b235Eric Laurent case AUDIO_INPUT_CLOSED: 722881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent default: 722981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent break; 723081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 72317c1ec5f038e63a5eb8b04434577c25bc23f5f410Eric Laurent mAudioFlinger->ioConfigChanged(event, desc, pid); 723281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 723381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 7234deca2ae0a7cf8bc54ff3f30b7dc39bbc78b94c0dGlenn Kastenvoid AudioFlinger::RecordThread::readInputParameters_l() 723581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 72361dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov status_t result = mInput->stream->getAudioProperties(&mSampleRate, &mChannelMask, &mHALFormat); 72371dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov LOG_ALWAYS_FATAL_IF(result != OK, "Error retrieving audio properties from HAL: %d", result); 7238e541269be94f3a1072932d51537905b120ef4733Andy Hung mChannelCount = audio_channel_count_from_in_mask(mChannelMask); 72391dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov LOG_ALWAYS_FATAL_IF(mChannelCount > FCC_8, "HAL channel count %d > %d", mChannelCount, FCC_8); 7240463be250de73907965faa6a216c00312bf81e049Andy Hung mFormat = mHALFormat; 72411dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov LOG_ALWAYS_FATAL_IF(!audio_is_linear_pcm(mFormat), "HAL format %#x is not linear pcm", mFormat); 72421dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov result = mInput->stream->getFrameSize(&mFrameSize); 72431dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov LOG_ALWAYS_FATAL_IF(result != OK, "Error retrieving frame size from HAL: %d", result); 72441dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov result = mInput->stream->getBufferSize(&mBufferSize); 72451dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov LOG_ALWAYS_FATAL_IF(result != OK, "Error retrieving buffer size from HAL: %d", result); 7246548efc94813c1dec6e8cf6c085ae41ccb04827f1Glenn Kasten mFrameCount = mBufferSize / mFrameSize; 72476dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten // This is the formula for calculating the temporary buffer size. 7248e842614837e5401adf77e90485300c288b9a7876Glenn Kasten // With 7 HAL buffers, we can guarantee ability to down-sample the input by ratio of 6:1 to 72498594843c15b4722ced39436fe9e64f3e57e7ace4Glenn Kasten // 1 full output buffer, regardless of the alignment of the available input. 7250e842614837e5401adf77e90485300c288b9a7876Glenn Kasten // The value is somewhat arbitrary, and could probably be even larger. 72516dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten // A larger value should allow more old data to be read after a track calls start(), 72526dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten // without increasing latency. 725397a893eb34f8687485c88eaf15917974a203f20bAndy Hung // 725497a893eb34f8687485c88eaf15917974a203f20bAndy Hung // Note this is independent of the maximum downsampling ratio permitted for capture. 7255e842614837e5401adf77e90485300c288b9a7876Glenn Kasten mRsmpInFrames = mFrameCount * 7; 72568594843c15b4722ced39436fe9e64f3e57e7ace4Glenn Kasten mRsmpInFramesP2 = roundup(mRsmpInFrames); 72575744661e85981f8a9456bf470e2761235fc026daAndy Hung free(mRsmpInBuffer); 72580a01c2fb68e6f35905de8dfaf938d099cd48587dAndy Hung mRsmpInBuffer = NULL; 725949d00ad9164ea5ce48c85765a2b6460d9b457d38Glenn Kasten 726049d00ad9164ea5ce48c85765a2b6460d9b457d38Glenn Kasten // TODO optimize audio capture buffer sizes ... 726149d00ad9164ea5ce48c85765a2b6460d9b457d38Glenn Kasten // Here we calculate the size of the sliding buffer used as a source 726249d00ad9164ea5ce48c85765a2b6460d9b457d38Glenn Kasten // for resampling. mRsmpInFramesP2 is currently roundup(mFrameCount * 7). 726349d00ad9164ea5ce48c85765a2b6460d9b457d38Glenn Kasten // For current HAL frame counts, this is usually 2048 = 40 ms. It would 726449d00ad9164ea5ce48c85765a2b6460d9b457d38Glenn Kasten // be better to have it derived from the pipe depth in the long term. 726549d00ad9164ea5ce48c85765a2b6460d9b457d38Glenn Kasten // The current value is higher than necessary. However it should not add to latency. 726649d00ad9164ea5ce48c85765a2b6460d9b457d38Glenn Kasten 72678594843c15b4722ced39436fe9e64f3e57e7ace4Glenn Kasten // Over-allocate beyond mRsmpInFramesP2 to permit a HAL read past end of buffer 72681b291841a58ce6b2b291232dfdd56134b2185c48Glenn Kasten mRsmpInFramesOA = mRsmpInFramesP2 + mFrameCount - 1; 72691b291841a58ce6b2b291232dfdd56134b2185c48Glenn Kasten (void)posix_memalign(&mRsmpInBuffer, 32, mRsmpInFramesOA * mFrameSize); 7270d3bb645f0b7f567b033b8664499d685f8ec10628Glenn Kasten // if posix_memalign fails, will segv here. 7271d3bb645f0b7f567b033b8664499d685f8ec10628Glenn Kasten memset(mRsmpInBuffer, 0, mRsmpInFramesOA * mFrameSize); 72726dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten 72734cc0a6a835c806d200ef83ef31fe5bef327c355cGlenn Kasten // AudioRecord mSampleRate and mChannelCount are constant due to AudioRecord API constraints. 72744cc0a6a835c806d200ef83ef31fe5bef327c355cGlenn Kasten // But if thread's mSampleRate or mChannelCount changes, how will that affect active tracks? 727581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 727681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 72775f972c031d4061f4f037c9fda1ea4bd9b6a756cdGlenn Kastenuint32_t AudioFlinger::RecordThread::getInputFramesLost() 727881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 727981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent Mutex::Autolock _l(mLock); 72801dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov uint32_t result; 72811dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov if (initCheck() == NO_ERROR && mInput->stream->getInputFramesLost(&result) == OK) { 72821dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov return result; 728381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 72841dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov return 0; 728581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 728681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 72874c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent// hasAudioSession_l() must be called with ThreadBase::mLock held 72884c415062ad1bb53e9af8f644d8215837262b79bbEric Laurentuint32_t AudioFlinger::RecordThread::hasAudioSession_l(audio_session_t sessionId) const 728981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 729081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent uint32_t result = 0; 729181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (getEffectChain_l(sessionId) != 0) { 729281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent result = EFFECT_SESSION; 729381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 729481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 729581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent for (size_t i = 0; i < mTracks.size(); ++i) { 729681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (sessionId == mTracks[i]->sessionId()) { 729781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent result |= TRACK_SESSION; 72984c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent if (mTracks[i]->isFastTrack()) { 72994c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent result |= FAST_SESSION; 73004c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent } 730181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent break; 730281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 730381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 730481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 730581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent return result; 730681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 730781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 7308d848eb48c121c119e8ba7583efc75415fe102570Glenn KastenKeyedVector<audio_session_t, bool> AudioFlinger::RecordThread::sessionIds() const 730981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 7310d848eb48c121c119e8ba7583efc75415fe102570Glenn Kasten KeyedVector<audio_session_t, bool> ids; 731181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent Mutex::Autolock _l(mLock); 731281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent for (size_t j = 0; j < mTracks.size(); ++j) { 731381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent sp<RecordThread::RecordTrack> track = mTracks[j]; 7314d848eb48c121c119e8ba7583efc75415fe102570Glenn Kasten audio_session_t sessionId = track->sessionId(); 731581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (ids.indexOfKey(sessionId) < 0) { 731681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent ids.add(sessionId, true); 731781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 731881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 731981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent return ids; 732081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 732181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 732281784c37c61b09289654b979567a42bf73cd2b12Eric LaurentAudioFlinger::AudioStreamIn* AudioFlinger::RecordThread::clearInput() 732381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 732481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent Mutex::Autolock _l(mLock); 732581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent AudioStreamIn *input = mInput; 732681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mInput = NULL; 732781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent return input; 732881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 732981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 733081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// this method must always be called either with ThreadBase mLock held or inside the thread loop 73311dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganovsp<StreamHalInterface> AudioFlinger::RecordThread::stream() const 733281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 733381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (mInput == NULL) { 733481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent return NULL; 733581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 73361dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov return mInput->stream; 733781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 733881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 733981784c37c61b09289654b979567a42bf73cd2b12Eric Laurentstatus_t AudioFlinger::RecordThread::addEffectChain_l(const sp<EffectChain>& chain) 734081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 734181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // only one chain per input thread 734281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (mEffectChains.size() != 0) { 7343aaa44478a373232d8416657035a9020f9c7aa7c3Eric Laurent ALOGW("addEffectChain_l() already one chain %p on thread %p", chain.get(), this); 734481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent return INVALID_OPERATION; 734581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 734681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent ALOGV("addEffectChain_l() %p on thread %p", chain.get(), this); 7347aaa44478a373232d8416657035a9020f9c7aa7c3Eric Laurent chain->setThread(this); 734881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent chain->setInBuffer(NULL); 734981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent chain->setOutBuffer(NULL); 735081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 735181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent checkSuspendOnAddEffectChain_l(chain); 735281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 73531b92868010b5c1409692a86f6b27e4a265b64c1aEric Laurent // make sure enabled pre processing effects state is communicated to the HAL as we 73541b92868010b5c1409692a86f6b27e4a265b64c1aEric Laurent // just moved them to a new input stream. 73551b92868010b5c1409692a86f6b27e4a265b64c1aEric Laurent chain->syncHalEffectsState(); 73561b92868010b5c1409692a86f6b27e4a265b64c1aEric Laurent 735781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mEffectChains.add(chain); 735881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 735981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent return NO_ERROR; 736081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 736181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 736281784c37c61b09289654b979567a42bf73cd2b12Eric Laurentsize_t AudioFlinger::RecordThread::removeEffectChain_l(const sp<EffectChain>& chain) 736381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 736481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent ALOGV("removeEffectChain_l() %p from thread %p", chain.get(), this); 736581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent ALOGW_IF(mEffectChains.size() != 1, 7366c42e9b462661673dff480ee71757a58b0f806370Glenn Kasten "removeEffectChain_l() %p invalid chain size %zu on thread %p", 736781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent chain.get(), mEffectChains.size(), this); 736881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (mEffectChains.size() == 1) { 736981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mEffectChains.removeAt(0); 737081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 737181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent return 0; 737281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 737381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 73741c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurentstatus_t AudioFlinger::RecordThread::createAudioPatch_l(const struct audio_patch *patch, 73751c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent audio_patch_handle_t *handle) 73761c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent{ 73771c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent status_t status = NO_ERROR; 7378054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurent 7379054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurent // store new device and send to effects 7380054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurent mInDevice = patch->sources[0].ext.device.type; 7381296fb13dd9b5e90d6a05cce897c3b1e7914a478aEric Laurent mPatch = *patch; 7382054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurent for (size_t i = 0; i < mEffectChains.size(); i++) { 7383054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurent mEffectChains[i]->setDevice_l(mInDevice); 7384054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurent } 7385054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurent 7386054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurent // disable AEC and NS if the device is a BT SCO headset supporting those 7387054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurent // pre processings 7388054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurent if (mTracks.size() > 0) { 7389054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurent bool suspend = audio_is_bluetooth_sco_device(mInDevice) && 7390054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurent mAudioFlinger->btNrecIsOff(); 7391054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurent for (size_t i = 0; i < mTracks.size(); i++) { 7392054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurent sp<RecordTrack> track = mTracks[i]; 7393054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurent setEffectSuspended_l(FX_IID_AEC, suspend, track->sessionId()); 7394054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurent setEffectSuspended_l(FX_IID_NS, suspend, track->sessionId()); 73951c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent } 7396054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurent } 73971c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent 7398054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurent // store new source and send to effects 7399054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurent if (mAudioSource != patch->sinks[0].ext.mix.usecase.source) { 7400054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurent mAudioSource = patch->sinks[0].ext.mix.usecase.source; 7401054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurent for (size_t i = 0; i < mEffectChains.size(); i++) { 7402054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurent mEffectChains[i]->setAudioSource_l(mAudioSource); 74031c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent } 7404054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurent } 74051c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent 74069ee0540d3a61bff03d561ca431a371c3d9335d2bMikhail Naganov if (mInput->audioHwDev->supportsAudioPatches()) { 7407e4f1f63a2c54ee8687ad8cca18df0f6639ad7c81Mikhail Naganov sp<DeviceHalInterface> hwDevice = mInput->audioHwDev->hwDevice(); 7408e4f1f63a2c54ee8687ad8cca18df0f6639ad7c81Mikhail Naganov status = hwDevice->createAudioPatch(patch->num_sources, 7409e4f1f63a2c54ee8687ad8cca18df0f6639ad7c81Mikhail Naganov patch->sources, 7410e4f1f63a2c54ee8687ad8cca18df0f6639ad7c81Mikhail Naganov patch->num_sinks, 7411e4f1f63a2c54ee8687ad8cca18df0f6639ad7c81Mikhail Naganov patch->sinks, 7412e4f1f63a2c54ee8687ad8cca18df0f6639ad7c81Mikhail Naganov handle); 74131c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent } else { 7414054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurent char *address; 7415054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurent if (strcmp(patch->sources[0].ext.device.address, "") != 0) { 7416054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurent address = audio_device_address_to_parameter( 7417054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurent patch->sources[0].ext.device.type, 7418054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurent patch->sources[0].ext.device.address); 7419054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurent } else { 7420054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurent address = (char *)calloc(1, 1); 7421054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurent } 7422054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurent AudioParameter param = AudioParameter(String8(address)); 7423054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurent free(address); 742400260b5e6996b0a4b12f71c5b84e44adea040534Mikhail Naganov param.addInt(String8(AudioParameter::keyRouting), 7425054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurent (int)patch->sources[0].ext.device.type); 742600260b5e6996b0a4b12f71c5b84e44adea040534Mikhail Naganov param.addInt(String8(AudioParameter::keyInputSource), 7427054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurent (int)patch->sinks[0].ext.mix.usecase.source); 74281dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov status = mInput->stream->setParameters(param.toString()); 7429054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurent *handle = AUDIO_PATCH_HANDLE_NONE; 74301c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent } 7431054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurent 7432e8726fea8a53bf3474aa3c6deaf2f6c1f565e694Eric Laurent if (mInDevice != mPrevInDevice) { 7433e8726fea8a53bf3474aa3c6deaf2f6c1f565e694Eric Laurent sendIoConfigEvent_l(AUDIO_INPUT_CONFIG_CHANGED); 7434e8726fea8a53bf3474aa3c6deaf2f6c1f565e694Eric Laurent mPrevInDevice = mInDevice; 7435e8726fea8a53bf3474aa3c6deaf2f6c1f565e694Eric Laurent } 7436296fb13dd9b5e90d6a05cce897c3b1e7914a478aEric Laurent 74371c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent return status; 74381c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent} 74391c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent 74401c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurentstatus_t AudioFlinger::RecordThread::releaseAudioPatch_l(const audio_patch_handle_t handle) 74411c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent{ 74421c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent status_t status = NO_ERROR; 7443054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurent 7444054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurent mInDevice = AUDIO_DEVICE_NONE; 7445054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurent 74469ee0540d3a61bff03d561ca431a371c3d9335d2bMikhail Naganov if (mInput->audioHwDev->supportsAudioPatches()) { 7447e4f1f63a2c54ee8687ad8cca18df0f6639ad7c81Mikhail Naganov sp<DeviceHalInterface> hwDevice = mInput->audioHwDev->hwDevice(); 7448e4f1f63a2c54ee8687ad8cca18df0f6639ad7c81Mikhail Naganov status = hwDevice->releaseAudioPatch(handle); 74491c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent } else { 7450054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurent AudioParameter param; 745100260b5e6996b0a4b12f71c5b84e44adea040534Mikhail Naganov param.addInt(String8(AudioParameter::keyRouting), 0); 74521dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov status = mInput->stream->setParameters(param.toString()); 74531c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent } 74541c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent return status; 74551c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent} 74561c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent 745783b8808faad1e91690c64d7007348be8d9ebde73Eric Laurentvoid AudioFlinger::RecordThread::addPatchRecord(const sp<PatchRecord>& record) 745883b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent{ 745983b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent Mutex::Autolock _l(mLock); 746083b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent mTracks.add(record); 746183b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent} 746283b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent 746383b8808faad1e91690c64d7007348be8d9ebde73Eric Laurentvoid AudioFlinger::RecordThread::deletePatchRecord(const sp<PatchRecord>& record) 746483b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent{ 746583b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent Mutex::Autolock _l(mLock); 746683b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent destroyTrack_l(record); 746783b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent} 746883b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent 746983b8808faad1e91690c64d7007348be8d9ebde73Eric Laurentvoid AudioFlinger::RecordThread::getAudioPortConfig(struct audio_port_config *config) 747083b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent{ 747183b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent ThreadBase::getAudioPortConfig(config); 747283b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent config->role = AUDIO_PORT_ROLE_SINK; 747383b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent config->ext.mix.hw_module = mInput->audioHwDev->handle(); 747483b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent config->ext.mix.usecase.source = mAudioSource; 747583b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent} 74761c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent 74776acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent// ---------------------------------------------------------------------------- 74786acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent// Mmap 74796acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent// ---------------------------------------------------------------------------- 74806acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 74816acd1d432f526ae9a055ddaece28bf93b474a776Eric LaurentAudioFlinger::MmapThreadHandle::MmapThreadHandle(const sp<MmapThread>& thread) 74826acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent : mThread(thread) 74836acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent{ 74846acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent} 74856acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 74866acd1d432f526ae9a055ddaece28bf93b474a776Eric LaurentAudioFlinger::MmapThreadHandle::~MmapThreadHandle() 74876acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent{ 74886acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent MmapThread *thread = mThread.get(); 74896acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent // clear our strong reference before disconnecting the thread: the last strong reference 749018b570146c971fe729c391bfbb869391084e623dEric Laurent // will be removed when closeInput/closeOutput is executed upon call from audio policy manager 74916acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent // and the thread removed from mMMapThreads list causing the thread destruction. 74926acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent mThread.clear(); 74936acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent if (thread != nullptr) { 74946acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent thread->disconnect(); 74956acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } 74966acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent} 74976acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 74986acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurentstatus_t AudioFlinger::MmapThreadHandle::createMmapBuffer(int32_t minSizeFrames, 74996acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent struct audio_mmap_buffer_info *info) 75006acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent{ 75016acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent if (mThread == 0) { 75026acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent return NO_INIT; 75036acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } 75046acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent return mThread->createMmapBuffer(minSizeFrames, info); 75056acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent} 75066acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 75076acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurentstatus_t AudioFlinger::MmapThreadHandle::getMmapPosition(struct audio_mmap_position *position) 75086acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent{ 75096acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent if (mThread == 0) { 75106acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent return NO_INIT; 75116acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } 75126acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent return mThread->getMmapPosition(position); 75136acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent} 75146acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 7515d3bb645f0b7f567b033b8664499d685f8ec10628Glenn Kastenstatus_t AudioFlinger::MmapThreadHandle::start(const MmapStreamInterface::Client& client, 7516d3bb645f0b7f567b033b8664499d685f8ec10628Glenn Kasten audio_port_handle_t *handle) 75176acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 75186acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent{ 75196acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent if (mThread == 0) { 75206acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent return NO_INIT; 75216acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } 75226acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent return mThread->start(client, handle); 75236acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent} 75246acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 75256acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurentstatus_t AudioFlinger::MmapThreadHandle::stop(audio_port_handle_t handle) 75266acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent{ 75276acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent if (mThread == 0) { 75286acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent return NO_INIT; 75296acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } 75306acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent return mThread->stop(handle); 75316acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent} 75326acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 753318b570146c971fe729c391bfbb869391084e623dEric Laurentstatus_t AudioFlinger::MmapThreadHandle::standby() 753418b570146c971fe729c391bfbb869391084e623dEric Laurent{ 753518b570146c971fe729c391bfbb869391084e623dEric Laurent if (mThread == 0) { 753618b570146c971fe729c391bfbb869391084e623dEric Laurent return NO_INIT; 753718b570146c971fe729c391bfbb869391084e623dEric Laurent } 753818b570146c971fe729c391bfbb869391084e623dEric Laurent return mThread->standby(); 753918b570146c971fe729c391bfbb869391084e623dEric Laurent} 754018b570146c971fe729c391bfbb869391084e623dEric Laurent 75416acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 75426acd1d432f526ae9a055ddaece28bf93b474a776Eric LaurentAudioFlinger::MmapThread::MmapThread( 75436acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent const sp<AudioFlinger>& audioFlinger, audio_io_handle_t id, 75446acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent AudioHwDevice *hwDev, sp<StreamHalInterface> stream, 75456acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent audio_devices_t outDevice, audio_devices_t inDevice, bool systemReady) 75466acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent : ThreadBase(audioFlinger, id, outDevice, inDevice, MMAP, systemReady), 75476acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent mHalStream(stream), mHalDevice(hwDev->hwDevice()), mAudioHwDev(hwDev) 75486acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent{ 754918b570146c971fe729c391bfbb869391084e623dEric Laurent mStandby = true; 75506acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent readHalParameters_l(); 75516acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent} 75526acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 75536acd1d432f526ae9a055ddaece28bf93b474a776Eric LaurentAudioFlinger::MmapThread::~MmapThread() 75546acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent{ 755518b570146c971fe729c391bfbb869391084e623dEric Laurent releaseWakeLock_l(); 75566acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent} 75576acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 75586acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurentvoid AudioFlinger::MmapThread::onFirstRef() 75596acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent{ 75606acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent run(mThreadName, ANDROID_PRIORITY_URGENT_AUDIO); 75616acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent} 75626acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 75636acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurentvoid AudioFlinger::MmapThread::disconnect() 75646acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent{ 75656acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent for (const sp<MmapTrack> &t : mActiveTracks) { 75666acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent stop(t->portId()); 75676acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } 75686acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent // this will cause the destruction of this thread. 75696acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent if (isOutput()) { 75706acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent AudioSystem::releaseOutput(mId, streamType(), mSessionId); 75716acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } else { 75726acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent AudioSystem::releaseInput(mId, mSessionId); 75736acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } 75746acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent} 75756acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 75766acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 75776acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurentvoid AudioFlinger::MmapThread::configure(const audio_attributes_t *attr, 75786acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent audio_stream_type_t streamType __unused, 75796acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent audio_session_t sessionId, 75806acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent const sp<MmapStreamCallback>& callback, 75816acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent audio_port_handle_t portId) 75826acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent{ 75836acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent mAttr = *attr; 75846acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent mSessionId = sessionId; 75856acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent mCallback = callback; 75866acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent mPortId = portId; 75876acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent} 75886acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 75896acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurentstatus_t AudioFlinger::MmapThread::createMmapBuffer(int32_t minSizeFrames, 75906acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent struct audio_mmap_buffer_info *info) 75916acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent{ 75926acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent if (mHalStream == 0) { 75936acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent return NO_INIT; 75946acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } 759518b570146c971fe729c391bfbb869391084e623dEric Laurent mStandby = true; 759618b570146c971fe729c391bfbb869391084e623dEric Laurent acquireWakeLock(); 75976acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent return mHalStream->createMmapBuffer(minSizeFrames, info); 75986acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent} 75996acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 76006acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurentstatus_t AudioFlinger::MmapThread::getMmapPosition(struct audio_mmap_position *position) 76016acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent{ 76026acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent if (mHalStream == 0) { 76036acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent return NO_INIT; 76046acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } 76056acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent return mHalStream->getMmapPosition(position); 76066acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent} 76076acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 76086acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurentstatus_t AudioFlinger::MmapThread::start(const MmapStreamInterface::Client& client, 76096acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent audio_port_handle_t *handle) 76106acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent{ 761118b570146c971fe729c391bfbb869391084e623dEric Laurent ALOGV("%s clientUid %d mStandby %d", __FUNCTION__, client.clientUid, mStandby); 76126acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent if (mHalStream == 0) { 76136acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent return NO_INIT; 76146acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } 76156acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 76166acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent status_t ret; 76176acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent audio_session_t sessionId; 76186acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent audio_port_handle_t portId; 76196acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 76206acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent if (mActiveTracks.size() == 0) { 76216acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent // for the first track, reuse portId and session allocated when the stream was opened 7622c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk ret = mHalStream->start(); 7623c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk if (ret != NO_ERROR) { 7624c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk ALOGE("%s: error mHalStream->start() = %d for first track", __FUNCTION__, ret); 7625c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk return ret; 7626c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk } 76276acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent portId = mPortId; 76286acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent sessionId = mSessionId; 762918b570146c971fe729c391bfbb869391084e623dEric Laurent mStandby = false; 76306acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } else { 76316acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent // for other tracks than first one, get a new port ID from APM. 76326acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent sessionId = (audio_session_t)mAudioFlinger->newAudioUniqueId(AUDIO_UNIQUE_ID_USE_SESSION); 76336acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent audio_io_handle_t io; 76346acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent if (isOutput()) { 76356acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent audio_config_t config = AUDIO_CONFIG_INITIALIZER; 76366acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent config.sample_rate = mSampleRate; 76376acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent config.channel_mask = mChannelMask; 76386acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent config.format = mFormat; 76396acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent audio_stream_type_t stream = streamType(); 76406acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent audio_output_flags_t flags = 76416acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent (audio_output_flags_t)(AUDIO_OUTPUT_FLAG_MMAP_NOIRQ | AUDIO_OUTPUT_FLAG_DIRECT); 76426acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent ret = AudioSystem::getOutputForAttr(&mAttr, &io, 76436acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent sessionId, 76446acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent &stream, 76456acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent client.clientUid, 76466acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent &config, 76476acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent flags, 76486acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent AUDIO_PORT_HANDLE_NONE, 76496acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent &portId); 76506acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } else { 76516acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent audio_config_base_t config; 76526acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent config.sample_rate = mSampleRate; 76536acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent config.channel_mask = mChannelMask; 76546acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent config.format = mFormat; 76556acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent ret = AudioSystem::getInputForAttr(&mAttr, &io, 76566acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent sessionId, 76576acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent client.clientPid, 76586acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent client.clientUid, 76596acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent &config, 76606acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent AUDIO_INPUT_FLAG_MMAP_NOIRQ, 76616acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent AUDIO_PORT_HANDLE_NONE, 76626acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent &portId); 76636acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } 76646acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent // APM should not chose a different input or output stream for the same set of attributes 76656acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent // and audo configuration 76666acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent if (ret != NO_ERROR || io != mId) { 76676acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent ALOGE("%s: error getting output or input from APM (error %d, io %d expected io %d)", 76686acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent __FUNCTION__, ret, io, mId); 76696acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent return BAD_VALUE; 76706acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } 76716acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } 76726acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 76736acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent if (isOutput()) { 76746acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent ret = AudioSystem::startOutput(mId, streamType(), sessionId); 76756acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } else { 76766acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent ret = AudioSystem::startInput(mId, sessionId); 76776acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } 76786acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 76796acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent // abort if start is rejected by audio policy manager 76806acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent if (ret != NO_ERROR) { 7681c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk ALOGE("%s: error start rejected by AudioPolicyManager = %d", __FUNCTION__, ret); 76826acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent if (mActiveTracks.size() != 0) { 76836acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent if (isOutput()) { 76846acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent AudioSystem::releaseOutput(mId, streamType(), sessionId); 76856acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } else { 76866acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent AudioSystem::releaseInput(mId, sessionId); 76876acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } 768818b570146c971fe729c391bfbb869391084e623dEric Laurent } else { 768918b570146c971fe729c391bfbb869391084e623dEric Laurent mHalStream->stop(); 76906acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } 76916acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent return PERMISSION_DENIED; 76926acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } 76936acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 76946acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent sp<MmapTrack> track = new MmapTrack(this, mSampleRate, mFormat, mChannelMask, sessionId, 76956acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent client.clientUid, portId); 76966acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 76976acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent mActiveTracks.add(track); 76986acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent sp<EffectChain> chain = getEffectChain_l(sessionId); 76996acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent if (chain != 0) { 77006acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent chain->setStrategy(AudioSystem::getStrategyForStream(streamType())); 77016acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent chain->incTrackCnt(); 77026acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent chain->incActiveTrackCnt(); 77036acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } 77046acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 77056acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent *handle = portId; 77066acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 77076acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent broadcast_l(); 77086acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 770918b570146c971fe729c391bfbb869391084e623dEric Laurent ALOGV("%s DONE handle %d stream %p", __FUNCTION__, portId, mHalStream.get()); 77106acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 77116acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent return NO_ERROR; 77126acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent} 77136acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 77146acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurentstatus_t AudioFlinger::MmapThread::stop(audio_port_handle_t handle) 77156acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent{ 77166acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent ALOGV("%s handle %d", __FUNCTION__, handle); 77176acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 77186acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent if (mHalStream == 0) { 77196acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent return NO_INIT; 77206acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } 77216acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 77226acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent sp<MmapTrack> track; 77236acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent for (const sp<MmapTrack> &t : mActiveTracks) { 77246acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent if (handle == t->portId()) { 77256acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent track = t; 77266acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent break; 77276acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } 77286acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } 77296acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent if (track == 0) { 77306acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent return BAD_VALUE; 77316acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } 77326acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 77336acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent mActiveTracks.remove(track); 77346acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 77356acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent if (isOutput()) { 77366acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent AudioSystem::stopOutput(mId, streamType(), track->sessionId()); 77376acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent if (mActiveTracks.size() != 0) { 77386acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent AudioSystem::releaseOutput(mId, streamType(), track->sessionId()); 77396acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } 77406acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } else { 77416acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent AudioSystem::stopInput(mId, track->sessionId()); 77426acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent if (mActiveTracks.size() != 0) { 77436acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent AudioSystem::releaseInput(mId, track->sessionId()); 77446acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } 77456acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } 77466acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 77476acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent sp<EffectChain> chain = getEffectChain_l(track->sessionId()); 77486acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent if (chain != 0) { 77496acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent chain->decActiveTrackCnt(); 77506acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent chain->decTrackCnt(); 77516acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } 77526acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 77536acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent broadcast_l(); 77546acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 77556acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent if (mActiveTracks.size() == 0) { 77566acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent mHalStream->stop(); 77576acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } 77586acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent return NO_ERROR; 77596acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent} 77606acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 776118b570146c971fe729c391bfbb869391084e623dEric Laurentstatus_t AudioFlinger::MmapThread::standby() 776218b570146c971fe729c391bfbb869391084e623dEric Laurent{ 776318b570146c971fe729c391bfbb869391084e623dEric Laurent ALOGV("%s", __FUNCTION__); 776418b570146c971fe729c391bfbb869391084e623dEric Laurent 776518b570146c971fe729c391bfbb869391084e623dEric Laurent if (mHalStream == 0) { 776618b570146c971fe729c391bfbb869391084e623dEric Laurent return NO_INIT; 776718b570146c971fe729c391bfbb869391084e623dEric Laurent } 776818b570146c971fe729c391bfbb869391084e623dEric Laurent if (mActiveTracks.size() != 0) { 776918b570146c971fe729c391bfbb869391084e623dEric Laurent return INVALID_OPERATION; 777018b570146c971fe729c391bfbb869391084e623dEric Laurent } 777118b570146c971fe729c391bfbb869391084e623dEric Laurent mHalStream->standby(); 777218b570146c971fe729c391bfbb869391084e623dEric Laurent mStandby = true; 777318b570146c971fe729c391bfbb869391084e623dEric Laurent releaseWakeLock(); 777418b570146c971fe729c391bfbb869391084e623dEric Laurent return NO_ERROR; 777518b570146c971fe729c391bfbb869391084e623dEric Laurent} 777618b570146c971fe729c391bfbb869391084e623dEric Laurent 77776acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 77786acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurentvoid AudioFlinger::MmapThread::readHalParameters_l() 77796acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent{ 77806acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent status_t result = mHalStream->getAudioProperties(&mSampleRate, &mChannelMask, &mHALFormat); 77816acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent LOG_ALWAYS_FATAL_IF(result != OK, "Error retrieving audio properties from HAL: %d", result); 77826acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent mFormat = mHALFormat; 77836acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent LOG_ALWAYS_FATAL_IF(!audio_is_linear_pcm(mFormat), "HAL format %#x is not linear pcm", mFormat); 77846acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent result = mHalStream->getFrameSize(&mFrameSize); 77856acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent LOG_ALWAYS_FATAL_IF(result != OK, "Error retrieving frame size from HAL: %d", result); 77866acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent result = mHalStream->getBufferSize(&mBufferSize); 77876acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent LOG_ALWAYS_FATAL_IF(result != OK, "Error retrieving buffer size from HAL: %d", result); 77886acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent mFrameCount = mBufferSize / mFrameSize; 77896acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent} 77906acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 77916acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurentbool AudioFlinger::MmapThread::threadLoop() 77926acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent{ 77936acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent checkSilentMode_l(); 77946acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 77956acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent const String8 myName(String8::format("thread %p type %d TID %d", this, mType, gettid())); 77966acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 77976acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent while (!exitPending()) 77986acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent { 77996acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent Mutex::Autolock _l(mLock); 78006acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent Vector< sp<EffectChain> > effectChains; 78016acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 78026acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent if (mSignalPending) { 78036acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent // A signal was raised while we were unlocked 78046acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent mSignalPending = false; 78056acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } else { 78066acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent if (mConfigEvents.isEmpty()) { 78076acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent // we're about to wait, flush the binder command buffer 78086acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent IPCThreadState::self()->flushCommands(); 78096acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 78106acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent if (exitPending()) { 78116acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent break; 78126acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } 78136acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 78146acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent // wait until we have something to do... 78156acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent ALOGV("%s going to sleep", myName.string()); 78166acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent mWaitWorkCV.wait(mLock); 78176acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent ALOGV("%s waking up", myName.string()); 78186acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 78196acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent checkSilentMode_l(); 78206acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 78216acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent continue; 78226acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } 78236acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } 78246acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 78256acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent processConfigEvents_l(); 78266acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 78276acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent processVolume_l(); 78286acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 78296acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent checkInvalidTracks_l(); 78306acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 78316acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent mActiveTracks.updatePowerState(this); 78326acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 78336acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent lockEffectChains_l(effectChains); 78346acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent for (size_t i = 0; i < effectChains.size(); i ++) { 78356acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent effectChains[i]->process_l(); 78366acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } 78376acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent // enable changes in effect chain 78386acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent unlockEffectChains(effectChains); 78396acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent // Effect chains will be actually deleted here if they were removed from 78406acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent // mEffectChains list during mixing or effects processing 78416acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } 78426acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 78436acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent threadLoop_exit(); 78446acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 78456acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent if (!mStandby) { 78466acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent threadLoop_standby(); 78476acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent mStandby = true; 78486acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } 78496acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 78506acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent ALOGV("Thread %p type %d exiting", this, mType); 78516acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent return false; 78526acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent} 78536acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 78546acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent// checkForNewParameter_l() must be called with ThreadBase::mLock held 78556acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurentbool AudioFlinger::MmapThread::checkForNewParameter_l(const String8& keyValuePair, 78566acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent status_t& status) 78576acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent{ 78586acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent AudioParameter param = AudioParameter(keyValuePair); 78596acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent int value; 78606acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent if (param.getInt(String8(AudioParameter::keyRouting), value) == NO_ERROR) { 78616acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent // forward device change to effects that have requested to be 78626acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent // aware of attached audio device. 78636acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent if (value != AUDIO_DEVICE_NONE) { 78646acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent mOutDevice = value; 78656acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent for (size_t i = 0; i < mEffectChains.size(); i++) { 78666acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent mEffectChains[i]->setDevice_l(mOutDevice); 78676acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } 78686acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } 78696acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } 78706acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent status = mHalStream->setParameters(keyValuePair); 78716acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 78726acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent return false; 78736acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent} 78746acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 78756acd1d432f526ae9a055ddaece28bf93b474a776Eric LaurentString8 AudioFlinger::MmapThread::getParameters(const String8& keys) 78766acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent{ 78776acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent Mutex::Autolock _l(mLock); 78786acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent String8 out_s8; 78796acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent if (initCheck() == NO_ERROR && mHalStream->getParameters(keys, &out_s8) == OK) { 78806acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent return out_s8; 78816acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } 78826acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent return String8(); 78836acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent} 78846acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 78856acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurentvoid AudioFlinger::MmapThread::ioConfigChanged(audio_io_config_event event, pid_t pid) { 78866acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent sp<AudioIoDescriptor> desc = new AudioIoDescriptor(); 78876acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 78886acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent desc->mIoHandle = mId; 78896acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 78906acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent switch (event) { 78916acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent case AUDIO_INPUT_OPENED: 78926acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent case AUDIO_INPUT_CONFIG_CHANGED: 78936acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent case AUDIO_OUTPUT_OPENED: 78946acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent case AUDIO_OUTPUT_CONFIG_CHANGED: 78956acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent desc->mPatch = mPatch; 78966acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent desc->mChannelMask = mChannelMask; 78976acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent desc->mSamplingRate = mSampleRate; 78986acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent desc->mFormat = mFormat; 78996acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent desc->mFrameCount = mFrameCount; 79006acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent desc->mFrameCountHAL = mFrameCount; 79016acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent desc->mLatency = 0; 79026acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent break; 79036acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 79046acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent case AUDIO_INPUT_CLOSED: 79056acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent case AUDIO_OUTPUT_CLOSED: 79066acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent default: 79076acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent break; 79086acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } 79096acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent mAudioFlinger->ioConfigChanged(event, desc, pid); 79106acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent} 79116acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 79126acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurentstatus_t AudioFlinger::MmapThread::createAudioPatch_l(const struct audio_patch *patch, 79136acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent audio_patch_handle_t *handle) 79146acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent{ 79156acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent status_t status = NO_ERROR; 79166acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 79176acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent // store new device and send to effects 79186acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent audio_devices_t type = AUDIO_DEVICE_NONE; 79196acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent audio_port_handle_t deviceId; 79206acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent if (isOutput()) { 79216acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent for (unsigned int i = 0; i < patch->num_sinks; i++) { 79226acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent type |= patch->sinks[i].ext.device.type; 79236acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } 79246acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent deviceId = patch->sinks[0].id; 79256acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } else { 79266acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent type = patch->sources[0].ext.device.type; 79276acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent deviceId = patch->sources[0].id; 79286acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } 79296acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 79306acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent for (size_t i = 0; i < mEffectChains.size(); i++) { 79316acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent mEffectChains[i]->setDevice_l(type); 79326acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } 79336acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 79346acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent if (isOutput()) { 79356acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent mOutDevice = type; 79366acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } else { 79376acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent mInDevice = type; 79386acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent // store new source and send to effects 79396acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent if (mAudioSource != patch->sinks[0].ext.mix.usecase.source) { 79406acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent mAudioSource = patch->sinks[0].ext.mix.usecase.source; 79416acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent for (size_t i = 0; i < mEffectChains.size(); i++) { 79426acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent mEffectChains[i]->setAudioSource_l(mAudioSource); 79436acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } 79446acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } 79456acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } 79466acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 79476acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent if (mAudioHwDev->supportsAudioPatches()) { 79486acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent status = mHalDevice->createAudioPatch(patch->num_sources, 79496acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent patch->sources, 79506acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent patch->num_sinks, 79516acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent patch->sinks, 79526acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent handle); 79536acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } else { 79546acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent char *address; 79556acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent if (strcmp(patch->sinks[0].ext.device.address, "") != 0) { 79566acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent //FIXME: we only support address on first sink with HAL version < 3.0 79576acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent address = audio_device_address_to_parameter( 79586acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent patch->sinks[0].ext.device.type, 79596acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent patch->sinks[0].ext.device.address); 79606acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } else { 79616acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent address = (char *)calloc(1, 1); 79626acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } 79636acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent AudioParameter param = AudioParameter(String8(address)); 79646acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent free(address); 79656acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent param.addInt(String8(AudioParameter::keyRouting), (int)type); 79666acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent if (!isOutput()) { 79676acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent param.addInt(String8(AudioParameter::keyInputSource), 79686acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent (int)patch->sinks[0].ext.mix.usecase.source); 79696acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } 79706acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent status = mHalStream->setParameters(param.toString()); 79716acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent *handle = AUDIO_PATCH_HANDLE_NONE; 79726acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } 79736acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 79746acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent if (isOutput() && mPrevOutDevice != mOutDevice) { 79756acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent mPrevOutDevice = type; 79766acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent sendIoConfigEvent_l(AUDIO_OUTPUT_CONFIG_CHANGED); 7977c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk sp<MmapStreamCallback> callback = mCallback.promote(); 7978c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk if (callback != 0) { 7979c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk callback->onRoutingChanged(deviceId); 79806acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } 79816acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } 79826acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent if (!isOutput() && mPrevInDevice != mInDevice) { 79836acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent mPrevInDevice = type; 79846acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent sendIoConfigEvent_l(AUDIO_INPUT_CONFIG_CHANGED); 7985c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk sp<MmapStreamCallback> callback = mCallback.promote(); 7986c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk if (callback != 0) { 7987c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk callback->onRoutingChanged(deviceId); 79886acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } 79896acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } 79906acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent return status; 79916acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent} 79926acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 79936acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurentstatus_t AudioFlinger::MmapThread::releaseAudioPatch_l(const audio_patch_handle_t handle) 79946acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent{ 79956acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent status_t status = NO_ERROR; 79966acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 79976acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent mInDevice = AUDIO_DEVICE_NONE; 79986acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 79996acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent bool supportsAudioPatches = mHalDevice->supportsAudioPatches(&supportsAudioPatches) == OK ? 80006acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent supportsAudioPatches : false; 80016acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 80026acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent if (supportsAudioPatches) { 80036acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent status = mHalDevice->releaseAudioPatch(handle); 80046acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } else { 80056acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent AudioParameter param; 80066acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent param.addInt(String8(AudioParameter::keyRouting), 0); 80076acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent status = mHalStream->setParameters(param.toString()); 80086acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } 80096acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent return status; 80106acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent} 80116acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 80126acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurentvoid AudioFlinger::MmapThread::getAudioPortConfig(struct audio_port_config *config) 80136acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent{ 80146acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent ThreadBase::getAudioPortConfig(config); 80156acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent if (isOutput()) { 80166acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent config->role = AUDIO_PORT_ROLE_SOURCE; 80176acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent config->ext.mix.hw_module = mAudioHwDev->handle(); 80186acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent config->ext.mix.usecase.stream = AUDIO_STREAM_DEFAULT; 80196acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } else { 80206acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent config->role = AUDIO_PORT_ROLE_SINK; 80216acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent config->ext.mix.hw_module = mAudioHwDev->handle(); 80226acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent config->ext.mix.usecase.source = mAudioSource; 80236acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } 80246acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent} 80256acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 80266acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurentstatus_t AudioFlinger::MmapThread::addEffectChain_l(const sp<EffectChain>& chain) 80276acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent{ 80286acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent audio_session_t session = chain->sessionId(); 80296acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 80306acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent ALOGV("addEffectChain_l() %p on thread %p for session %d", chain.get(), this, session); 80316acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent // Attach all tracks with same session ID to this chain. 80326acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent // indicate all active tracks in the chain 80336acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent for (const sp<MmapTrack> &track : mActiveTracks) { 80346acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent if (session == track->sessionId()) { 80356acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent chain->incTrackCnt(); 80366acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent chain->incActiveTrackCnt(); 80376acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } 80386acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } 80396acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 80406acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent chain->setThread(this); 80416acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent chain->setInBuffer(nullptr); 80426acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent chain->setOutBuffer(nullptr); 80436acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent chain->syncHalEffectsState(); 80446acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 80456acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent mEffectChains.add(chain); 80466acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent checkSuspendOnAddEffectChain_l(chain); 80476acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent return NO_ERROR; 80486acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent} 80496acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 80506acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurentsize_t AudioFlinger::MmapThread::removeEffectChain_l(const sp<EffectChain>& chain) 80516acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent{ 80526acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent audio_session_t session = chain->sessionId(); 80536acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 80546acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent ALOGV("removeEffectChain_l() %p from thread %p for session %d", chain.get(), this, session); 80556acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 80566acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent for (size_t i = 0; i < mEffectChains.size(); i++) { 80576acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent if (chain == mEffectChains[i]) { 80586acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent mEffectChains.removeAt(i); 80596acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent // detach all active tracks from the chain 80606acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent // detach all tracks with same session ID from this chain 80616acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent for (const sp<MmapTrack> &track : mActiveTracks) { 80626acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent if (session == track->sessionId()) { 80636acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent chain->decActiveTrackCnt(); 80646acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent chain->decTrackCnt(); 80656acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } 80666acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } 80676acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent break; 80686acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } 80696acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } 80706acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent return mEffectChains.size(); 80716acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent} 80726acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 80736acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent// hasAudioSession_l() must be called with ThreadBase::mLock held 80746acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurentuint32_t AudioFlinger::MmapThread::hasAudioSession_l(audio_session_t sessionId) const 80756acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent{ 80766acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent uint32_t result = 0; 80776acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent if (getEffectChain_l(sessionId) != 0) { 80786acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent result = EFFECT_SESSION; 80796acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } 80806acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 80816acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent for (size_t i = 0; i < mActiveTracks.size(); i++) { 80826acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent sp<MmapTrack> track = mActiveTracks[i]; 80836acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent if (sessionId == track->sessionId()) { 80846acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent result |= TRACK_SESSION; 80856acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent if (track->isFastTrack()) { 80866acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent result |= FAST_SESSION; 80876acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } 80886acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent break; 80896acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } 80906acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } 80916acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 80926acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent return result; 80936acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent} 80946acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 80956acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurentvoid AudioFlinger::MmapThread::threadLoop_standby() 80966acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent{ 80976acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent mHalStream->standby(); 80986acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent} 80996acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 81006acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurentvoid AudioFlinger::MmapThread::threadLoop_exit() 81016acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent{ 8102c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk sp<MmapStreamCallback> callback = mCallback.promote(); 8103c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk if (callback != 0) { 8104c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk callback->onTearDown(); 81056acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } 81066acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent} 81076acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 81086acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurentstatus_t AudioFlinger::MmapThread::setSyncEvent(const sp<SyncEvent>& event __unused) 81096acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent{ 81106acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent return BAD_VALUE; 81116acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent} 81126acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 81136acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurentbool AudioFlinger::MmapThread::isValidSyncEvent(const sp<SyncEvent>& event __unused) const 81146acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent{ 81156acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent return false; 81166acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent} 81176acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 81186acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurentstatus_t AudioFlinger::MmapThread::checkEffectCompatibility_l( 81196acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent const effect_descriptor_t *desc, audio_session_t sessionId) 81206acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent{ 81216acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent // No global effect sessions on mmap threads 81226acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent if (sessionId == AUDIO_SESSION_OUTPUT_MIX || sessionId == AUDIO_SESSION_OUTPUT_STAGE) { 81236acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent ALOGW("checkEffectCompatibility_l(): global effect %s on record thread %s", 81246acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent desc->name, mThreadName); 81256acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent return BAD_VALUE; 81266acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } 81276acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 81286acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent if (!isOutput() && ((desc->flags & EFFECT_FLAG_TYPE_MASK) != EFFECT_FLAG_TYPE_PRE_PROC)) { 81296acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent ALOGW("checkEffectCompatibility_l(): non pre processing effect %s on capture mmap thread", 81306acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent desc->name); 81316acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent return BAD_VALUE; 81326acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } 81336acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent if (isOutput() && ((desc->flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_PRE_PROC)) { 8134d3bb645f0b7f567b033b8664499d685f8ec10628Glenn Kasten ALOGW("checkEffectCompatibility_l(): pre processing effect %s created on playback mmap " 8135d3bb645f0b7f567b033b8664499d685f8ec10628Glenn Kasten "thread", desc->name); 81366acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent return BAD_VALUE; 81376acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } 81386acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 81396acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent // Only allow effects without processing load or latency 81406acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent if ((desc->flags & EFFECT_FLAG_NO_PROCESS_MASK) != EFFECT_FLAG_NO_PROCESS) { 81416acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent return BAD_VALUE; 81426acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } 81436acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 81446acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent return NO_ERROR; 81456acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 81466acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent} 81476acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 81486acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurentvoid AudioFlinger::MmapThread::checkInvalidTracks_l() 81496acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent{ 81506acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent for (const sp<MmapTrack> &track : mActiveTracks) { 81516acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent if (track->isInvalid()) { 8152c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk sp<MmapStreamCallback> callback = mCallback.promote(); 8153c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk if (callback != 0) { 8154c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk callback->onTearDown(); 81556acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } 81566acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent break; 81576acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } 81586acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } 81596acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent} 81606acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 81616acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurentvoid AudioFlinger::MmapThread::dump(int fd, const Vector<String16>& args) 81626acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent{ 81636acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent dumpInternals(fd, args); 81646acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent dumpTracks(fd, args); 81656acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent dumpEffectChains(fd, args); 81666acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent} 81676acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 81686acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurentvoid AudioFlinger::MmapThread::dumpInternals(int fd, const Vector<String16>& args) 81696acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent{ 81706acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent dumpBase(fd, args); 81716acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 81726acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent dprintf(fd, " Attributes: content type %d usage %d source %d\n", 81736acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent mAttr.content_type, mAttr.usage, mAttr.source); 81746acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent dprintf(fd, " Session: %d port Id: %d\n", mSessionId, mPortId); 81756acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent if (mActiveTracks.size() == 0) { 81766acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent dprintf(fd, " No active clients\n"); 81776acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } 81786acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent} 81796acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 81806acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurentvoid AudioFlinger::MmapThread::dumpTracks(int fd, const Vector<String16>& args __unused) 81816acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent{ 81826acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent const size_t SIZE = 256; 81836acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent char buffer[SIZE]; 81846acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent String8 result; 81856acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 81866acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent size_t numtracks = mActiveTracks.size(); 81876acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent dprintf(fd, " %zu Tracks", numtracks); 81886acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent if (numtracks) { 81896acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent MmapTrack::appendDumpHeader(result); 81906acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent for (size_t i = 0; i < numtracks ; ++i) { 81916acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent sp<MmapTrack> track = mActiveTracks[i]; 81926acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent track->dump(buffer, SIZE); 81936acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent result.append(buffer); 81946acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } 81956acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } else { 81966acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent dprintf(fd, "\n"); 81976acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } 81986acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent write(fd, result.string(), result.size()); 81996acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent} 82006acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 82016acd1d432f526ae9a055ddaece28bf93b474a776Eric LaurentAudioFlinger::MmapPlaybackThread::MmapPlaybackThread( 82026acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent const sp<AudioFlinger>& audioFlinger, audio_io_handle_t id, 82036acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent AudioHwDevice *hwDev, AudioStreamOut *output, 82046acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent audio_devices_t outDevice, audio_devices_t inDevice, bool systemReady) 82056acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent : MmapThread(audioFlinger, id, hwDev, output->stream, outDevice, inDevice, systemReady), 82066acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent mStreamType(AUDIO_STREAM_MUSIC), 82076acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent mStreamVolume(1.0), mStreamMute(false), mOutput(output) 82086acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent{ 82096acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent snprintf(mThreadName, kThreadNameLength, "AudioMmapOut_%X", id); 82106acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent mChannelCount = audio_channel_count_from_out_mask(mChannelMask); 82116acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent mMasterVolume = audioFlinger->masterVolume_l(); 82126acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent mMasterMute = audioFlinger->masterMute_l(); 82136acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent if (mAudioHwDev) { 82146acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent if (mAudioHwDev->canSetMasterVolume()) { 82156acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent mMasterVolume = 1.0; 82166acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } 82176acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 82186acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent if (mAudioHwDev->canSetMasterMute()) { 82196acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent mMasterMute = false; 82206acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } 82216acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } 82226acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent} 82236acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 82246acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurentvoid AudioFlinger::MmapPlaybackThread::configure(const audio_attributes_t *attr, 82256acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent audio_stream_type_t streamType, 82266acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent audio_session_t sessionId, 82276acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent const sp<MmapStreamCallback>& callback, 82286acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent audio_port_handle_t portId) 82296acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent{ 82306acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent MmapThread::configure(attr, streamType, sessionId, callback, portId); 82316acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent mStreamType = streamType; 82326acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent} 82336acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 82346acd1d432f526ae9a055ddaece28bf93b474a776Eric LaurentAudioStreamOut* AudioFlinger::MmapPlaybackThread::clearOutput() 82356acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent{ 82366acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent Mutex::Autolock _l(mLock); 82376acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent AudioStreamOut *output = mOutput; 82386acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent mOutput = NULL; 82396acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent return output; 82406acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent} 82416acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 82426acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurentvoid AudioFlinger::MmapPlaybackThread::setMasterVolume(float value) 82436acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent{ 82446acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent Mutex::Autolock _l(mLock); 82456acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent // Don't apply master volume in SW if our HAL can do it for us. 82466acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent if (mAudioHwDev && 82476acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent mAudioHwDev->canSetMasterVolume()) { 82486acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent mMasterVolume = 1.0; 82496acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } else { 82506acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent mMasterVolume = value; 82516acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } 82526acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent} 82536acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 82546acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurentvoid AudioFlinger::MmapPlaybackThread::setMasterMute(bool muted) 82556acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent{ 82566acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent Mutex::Autolock _l(mLock); 82576acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent // Don't apply master mute in SW if our HAL can do it for us. 82586acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent if (mAudioHwDev && mAudioHwDev->canSetMasterMute()) { 82596acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent mMasterMute = false; 82606acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } else { 82616acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent mMasterMute = muted; 82626acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } 82636acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent} 82646acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 82656acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurentvoid AudioFlinger::MmapPlaybackThread::setStreamVolume(audio_stream_type_t stream, float value) 82666acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent{ 82676acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent Mutex::Autolock _l(mLock); 82686acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent if (stream == mStreamType) { 82696acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent mStreamVolume = value; 82706acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent broadcast_l(); 82716acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } 82726acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent} 82736acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 82746acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurentfloat AudioFlinger::MmapPlaybackThread::streamVolume(audio_stream_type_t stream) const 82756acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent{ 82766acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent Mutex::Autolock _l(mLock); 82776acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent if (stream == mStreamType) { 82786acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent return mStreamVolume; 82796acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } 82806acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent return 0.0f; 82816acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent} 82826acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 82836acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurentvoid AudioFlinger::MmapPlaybackThread::setStreamMute(audio_stream_type_t stream, bool muted) 82846acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent{ 82856acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent Mutex::Autolock _l(mLock); 82866acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent if (stream == mStreamType) { 82876acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent mStreamMute= muted; 82886acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent broadcast_l(); 82896acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } 82906acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent} 82916acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 82926acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurentvoid AudioFlinger::MmapPlaybackThread::invalidateTracks(audio_stream_type_t streamType) 82936acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent{ 82946acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent Mutex::Autolock _l(mLock); 82956acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent if (streamType == mStreamType) { 82966acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent for (const sp<MmapTrack> &track : mActiveTracks) { 82976acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent track->invalidate(); 82986acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } 82996acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent broadcast_l(); 83006acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } 83016acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent} 83026acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 83036acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurentvoid AudioFlinger::MmapPlaybackThread::processVolume_l() 83046acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent{ 83056acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent float volume; 83066acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 83076acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent if (mMasterMute || mStreamMute) { 83086acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent volume = 0; 83096acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } else { 83106acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent volume = mMasterVolume * mStreamVolume; 83116acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } 83126acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 83136acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent if (volume != mHalVolFloat) { 83146acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent mHalVolFloat = volume; 83156acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 83166acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent // Convert volumes from float to 8.24 83176acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent uint32_t vol = (uint32_t)(volume * (1 << 24)); 83186acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 83196acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent // Delegate volume control to effect in track effect chain if needed 83206acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent // only one effect chain can be present on DirectOutputThread, so if 83216acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent // there is one, the track is connected to it 83226acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent if (!mEffectChains.isEmpty()) { 83236acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent mEffectChains[0]->setVolume_l(&vol, &vol); 83246acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent volume = (float)vol / (1 << 24); 83256acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } 8326dff774afa22569774eb2c8c25b1b3f934badea4bEric Laurent // Try to use HW volume control and fall back to SW control if not implemented 8327dff774afa22569774eb2c8c25b1b3f934badea4bEric Laurent if (mOutput->stream->setVolume(volume, volume) != NO_ERROR) { 8328dff774afa22569774eb2c8c25b1b3f934badea4bEric Laurent sp<MmapStreamCallback> callback = mCallback.promote(); 8329dff774afa22569774eb2c8c25b1b3f934badea4bEric Laurent if (callback != 0) { 8330dff774afa22569774eb2c8c25b1b3f934badea4bEric Laurent int channelCount; 8331dff774afa22569774eb2c8c25b1b3f934badea4bEric Laurent if (isOutput()) { 8332dff774afa22569774eb2c8c25b1b3f934badea4bEric Laurent channelCount = audio_channel_count_from_out_mask(mChannelMask); 8333dff774afa22569774eb2c8c25b1b3f934badea4bEric Laurent } else { 8334dff774afa22569774eb2c8c25b1b3f934badea4bEric Laurent channelCount = audio_channel_count_from_in_mask(mChannelMask); 8335dff774afa22569774eb2c8c25b1b3f934badea4bEric Laurent } 8336dff774afa22569774eb2c8c25b1b3f934badea4bEric Laurent Vector<float> values; 8337dff774afa22569774eb2c8c25b1b3f934badea4bEric Laurent for (int i = 0; i < channelCount; i++) { 8338dff774afa22569774eb2c8c25b1b3f934badea4bEric Laurent values.add(volume); 8339dff774afa22569774eb2c8c25b1b3f934badea4bEric Laurent } 8340dff774afa22569774eb2c8c25b1b3f934badea4bEric Laurent callback->onVolumeChanged(mChannelMask, values); 83416acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } else { 8342dff774afa22569774eb2c8c25b1b3f934badea4bEric Laurent ALOGW("Could not set MMAP stream volume: no volume callback!"); 83436acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } 83446acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } 83456acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } 83466acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent} 83476acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 83486acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurentvoid AudioFlinger::MmapPlaybackThread::checkSilentMode_l() 83496acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent{ 83506acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent if (!mMasterMute) { 83516acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent char value[PROPERTY_VALUE_MAX]; 83526acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent if (property_get("ro.audio.silent", value, "0") > 0) { 83536acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent char *endptr; 83546acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent unsigned long ul = strtoul(value, &endptr, 0); 83556acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent if (*endptr == '\0' && ul != 0) { 83566acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent ALOGD("Silence is golden"); 83576acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent // The setprop command will not allow a property to be changed after 83586acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent // the first time it is set, so we don't have to worry about un-muting. 83596acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent setMasterMute_l(true); 83606acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } 83616acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } 83626acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } 83636acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent} 83646acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 83656acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurentvoid AudioFlinger::MmapPlaybackThread::dumpInternals(int fd, const Vector<String16>& args) 83666acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent{ 83676acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent MmapThread::dumpInternals(fd, args); 83686acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 8369d3bb645f0b7f567b033b8664499d685f8ec10628Glenn Kasten dprintf(fd, " Stream type: %d Stream volume: %f HAL volume: %f Stream mute %d\n", 8370d3bb645f0b7f567b033b8664499d685f8ec10628Glenn Kasten mStreamType, mStreamVolume, mHalVolFloat, mStreamMute); 83716acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent dprintf(fd, " Master volume: %f Master mute %d\n", mMasterVolume, mMasterMute); 83726acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent} 83736acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 83746acd1d432f526ae9a055ddaece28bf93b474a776Eric LaurentAudioFlinger::MmapCaptureThread::MmapCaptureThread( 83756acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent const sp<AudioFlinger>& audioFlinger, audio_io_handle_t id, 83766acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent AudioHwDevice *hwDev, AudioStreamIn *input, 83776acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent audio_devices_t outDevice, audio_devices_t inDevice, bool systemReady) 83786acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent : MmapThread(audioFlinger, id, hwDev, input->stream, outDevice, inDevice, systemReady), 83796acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent mInput(input) 83806acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent{ 83816acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent snprintf(mThreadName, kThreadNameLength, "AudioMmapIn_%X", id); 83826acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent mChannelCount = audio_channel_count_from_in_mask(mChannelMask); 83836acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent} 83846acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 83856acd1d432f526ae9a055ddaece28bf93b474a776Eric LaurentAudioFlinger::AudioStreamIn* AudioFlinger::MmapCaptureThread::clearInput() 83866acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent{ 83876acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent Mutex::Autolock _l(mLock); 83886acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent AudioStreamIn *input = mInput; 83896acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent mInput = NULL; 83906acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent return input; 83916acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent} 839263238efb0d674758902918e3cdaac322126484b7Glenn Kasten} // namespace android 8393