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 597588ff418aca63b1dc43a85afc1e86c40dd889a3Kevin Rocard#include <media/audiohal/EffectsFactoryHalInterface.h> 60069c2719e753732d5af9ba51e5fcc34342b0c9f2Kevin Rocard#include <media/audiohal/StreamHalInterface.h> 617588ff418aca63b1dc43a85afc1e86c40dd889a3Kevin Rocard 6281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent#include "AudioFlinger.h" 6381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent#include "FastMixer.h" 646dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten#include "FastCapture.h" 6581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent#include "ServiceUtilities.h" 66f99498ee4de7123e2fd71778c6877be44fbd1506Eino-Ville Talvala#include "mediautils/SchedulingPolicyService.h" 6781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 6881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent#ifdef ADD_BATTERY_DATA 6981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent#include <media/IMediaPlayerService.h> 7081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent#include <media/IMediaDeathNotifier.h> 7181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent#endif 7281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 7381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent#ifdef DEBUG_CPU_USAGE 7481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent#include <cpustats/CentralTendencyStatistics.h> 7581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent#include <cpustats/ThreadCpuUsage.h> 7681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent#endif 7781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 78c05b8d7df46619d3474356241d47655478b8bc82Glenn Kasten#include "AutoPark.h" 79c05b8d7df46619d3474356241d47655478b8bc82Glenn Kasten 80fe1e1449cadff4f946c33403aecc73b4b4a11e56Nicolas Roulet#include <pthread.h> 81fe1e1449cadff4f946c33403aecc73b4b4a11e56Nicolas Roulet#include "TypedLogger.h" 82fe1e1449cadff4f946c33403aecc73b4b4a11e56Nicolas Roulet 8381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// ---------------------------------------------------------------------------- 8481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 8581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// Note: the following macro is used for extremely verbose logging message. In 8681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// order to run with ALOG_ASSERT turned on, we need to have LOG_NDEBUG set to 8781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// 0; but one side effect of this is to turn all LOGV's as well. Some messages 8881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// are so verbose that we want to suppress them even when we have ALOG_ASSERT 8981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// turned on. Do not uncomment the #def below unless you really know what you 9081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// are doing and want to see all of the extremely verbose messages. 9181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent//#define VERY_VERY_VERBOSE_LOGGING 9281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent#ifdef VERY_VERY_VERBOSE_LOGGING 9381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent#define ALOGVV ALOGV 9481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent#else 9581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent#define ALOGVV(a...) do { } while(0) 9681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent#endif 9781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 986770c6faa3467c92eabc5ec9b23d60eb556a0d03Andy Hung// TODO: Move these macro/inlines to a header file. 9949d00ad9164ea5ce48c85765a2b6460d9b457d38Glenn Kasten#define max(a, b) ((a) > (b) ? (a) : (b)) 1006770c6faa3467c92eabc5ec9b23d60eb556a0d03Andy Hungtemplate <typename T> 1016770c6faa3467c92eabc5ec9b23d60eb556a0d03Andy Hungstatic inline T min(const T& a, const T& b) 1026770c6faa3467c92eabc5ec9b23d60eb556a0d03Andy Hung{ 1036770c6faa3467c92eabc5ec9b23d60eb556a0d03Andy Hung return a < b ? a : b; 1046770c6faa3467c92eabc5ec9b23d60eb556a0d03Andy Hung} 10549d00ad9164ea5ce48c85765a2b6460d9b457d38Glenn Kasten 10681784c37c61b09289654b979567a42bf73cd2b12Eric Laurentnamespace android { 10781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 10881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// retry counts for buffer fill timeout 10981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// 50 * ~20msecs = 1 second 11081784c37c61b09289654b979567a42bf73cd2b12Eric Laurentstatic const int8_t kMaxTrackRetries = 50; 11181784c37c61b09289654b979567a42bf73cd2b12Eric Laurentstatic const int8_t kMaxTrackStartupRetries = 50; 11281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// allow less retry attempts on direct output thread. 11381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// direct outputs can be a scarce resource in audio hardware and should 11481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// be released as quickly as possible. 11581784c37c61b09289654b979567a42bf73cd2b12Eric Laurentstatic const int8_t kMaxTrackRetriesDirect = 2; 116e93cc03da360a1a0d2ad937c745ce8c8e8be81c2Eric Laurent 117517161856d74f5fe39cce131f29b977bc1745991Eric Laurent 11881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 11981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// don't warn about blocked writes or record buffer overflows more often than this 12081784c37c61b09289654b979567a42bf73cd2b12Eric Laurentstatic const nsecs_t kWarningThrottleNs = seconds(5); 12181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 12281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// RecordThread loop sleep time upon application overrun or audio HAL read error 12381784c37c61b09289654b979567a42bf73cd2b12Eric Laurentstatic const int kRecordThreadSleepUs = 5000; 12481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 1251035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent// maximum time to wait in sendConfigEvent_l() for a status to be received 1261035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurentstatic const nsecs_t kConfigEventTimeoutNs = seconds(2); 12781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 12881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// minimum sleep time for the mixer thread loop when tracks are active but in underrun 12981784c37c61b09289654b979567a42bf73cd2b12Eric Laurentstatic const uint32_t kMinThreadSleepTimeUs = 5000; 13081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// maximum divider applied to the active sleep time in the mixer thread loop 13181784c37c61b09289654b979567a42bf73cd2b12Eric Laurentstatic const uint32_t kMaxThreadSleepTimeShift = 2; 13281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 13309a5007b17acb49d25cfa386a2e2534d942e8854Andy Hung// minimum normal sink buffer size, expressed in milliseconds rather than frames 134eb9487e10294a4e73977f460f30eeaff503acd21Glenn Kasten// FIXME This should be based on experimentally observed scheduling jitter 13509a5007b17acb49d25cfa386a2e2534d942e8854Andy Hungstatic const uint32_t kMinNormalSinkBufferSizeMs = 20; 13609a5007b17acb49d25cfa386a2e2534d942e8854Andy Hung// maximum normal sink buffer size 13709a5007b17acb49d25cfa386a2e2534d942e8854Andy Hungstatic const uint32_t kMaxNormalSinkBufferSizeMs = 24; 13881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 139eb9487e10294a4e73977f460f30eeaff503acd21Glenn Kasten// minimum capture buffer size in milliseconds to _not_ need a fast capture thread 140eb9487e10294a4e73977f460f30eeaff503acd21Glenn Kasten// FIXME This should be based on experimentally observed scheduling jitter 141eb9487e10294a4e73977f460f30eeaff503acd21Glenn Kastenstatic const uint32_t kMinNormalCaptureBufferSizeMs = 12; 142eb9487e10294a4e73977f460f30eeaff503acd21Glenn Kasten 143972a173d7d1de1a3b5a617aae3e2abb6e05ae02dEric Laurent// Offloaded output thread standby delay: allows track transition without going to standby 144972a173d7d1de1a3b5a617aae3e2abb6e05ae02dEric Laurentstatic const nsecs_t kOffloadStandbyDelayNs = seconds(1); 145972a173d7d1de1a3b5a617aae3e2abb6e05ae02dEric Laurent 146517161856d74f5fe39cce131f29b977bc1745991Eric Laurent// Direct output thread minimum sleep time in idle or active(underrun) state 147517161856d74f5fe39cce131f29b977bc1745991Eric Laurentstatic const nsecs_t kDirectMinSleepTimeUs = 10000; 148517161856d74f5fe39cce131f29b977bc1745991Eric Laurent 1491b291841a58ce6b2b291232dfdd56134b2185c48Glenn Kasten// The universal constant for ubiquitous 20ms value. The value of 20ms seems to provide a good 1501b291841a58ce6b2b291232dfdd56134b2185c48Glenn Kasten// balance between power consumption and latency, and allows threads to be scheduled reliably 1511b291841a58ce6b2b291232dfdd56134b2185c48Glenn Kasten// by the CFS scheduler. 1521b291841a58ce6b2b291232dfdd56134b2185c48Glenn Kasten// FIXME Express other hardcoded references to 20ms with references to this constant and move 1531b291841a58ce6b2b291232dfdd56134b2185c48Glenn Kasten// it appropriately. 1541b291841a58ce6b2b291232dfdd56134b2185c48Glenn Kasten#define FMS_20 20 155517161856d74f5fe39cce131f29b977bc1745991Eric Laurent 15681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// Whether to use fast mixer 15781784c37c61b09289654b979567a42bf73cd2b12Eric Laurentstatic const enum { 15881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent FastMixer_Never, // never initialize or use: for debugging only 15981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent FastMixer_Always, // always initialize and use, even if not needed: for debugging only 16081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // normal mixer multiplier is 1 16181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent FastMixer_Static, // initialize if needed, then use all the time if initialized, 16281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // multiplier is calculated based on min & max normal mixer buffer size 16381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent FastMixer_Dynamic, // initialize if needed, then use dynamically depending on track load, 16481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // multiplier is calculated based on min & max normal mixer buffer size 16581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // FIXME for FastMixer_Dynamic: 16681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // Supporting this option will require fixing HALs that can't handle large writes. 16781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // For example, one HAL implementation returns an error from a large write, 16881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // and another HAL implementation corrupts memory, possibly in the sample rate converter. 16981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // We could either fix the HAL implementations, or provide a wrapper that breaks 17081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // up large writes into smaller ones, and the wrapper would need to deal with scheduler. 17181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} kUseFastMixer = FastMixer_Static; 17281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 1736dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten// Whether to use fast capture 1746dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kastenstatic const enum { 1756dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten FastCapture_Never, // never initialize or use: for debugging only 1766dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten FastCapture_Always, // always initialize and use, even if not needed: for debugging only 1776dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten FastCapture_Static, // initialize if needed, then use all the time if initialized 1786dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten} kUseFastCapture = FastCapture_Static; 1796dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten 18081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// Priorities for requestPriority 18181784c37c61b09289654b979567a42bf73cd2b12Eric Laurentstatic const int kPriorityAudioApp = 2; 18281784c37c61b09289654b979567a42bf73cd2b12Eric Laurentstatic const int kPriorityFastMixer = 3; 1836dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kastenstatic const int kPriorityFastCapture = 3; 18481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 185ea38ee7742e799b23bd8675f5801ef72f94de0f4Glenn Kasten// IAudioFlinger::createTrack() has an in/out parameter 'pFrameCount' for the total size of the 186ea38ee7742e799b23bd8675f5801ef72f94de0f4Glenn Kasten// track buffer in shared memory. Zero on input means to use a default value. For fast tracks, 187ea38ee7742e799b23bd8675f5801ef72f94de0f4Glenn Kasten// AudioFlinger derives the default from HAL buffer size and 'fast track multiplier'. 1880349009fd19f89f8414c428f6b71b369f7546085Glenn Kasten 1890349009fd19f89f8414c428f6b71b369f7546085Glenn Kasten// This is the default value, if not specified by property. 190b5fed68bcdd6f44424c9e4d12bfe9a3ff51bd62eGlenn Kastenstatic const int kFastTrackMultiplier = 2; 19181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 1920349009fd19f89f8414c428f6b71b369f7546085Glenn Kasten// The minimum and maximum allowed values 1930349009fd19f89f8414c428f6b71b369f7546085Glenn Kastenstatic const int kFastTrackMultiplierMin = 1; 1940349009fd19f89f8414c428f6b71b369f7546085Glenn Kastenstatic const int kFastTrackMultiplierMax = 2; 1950349009fd19f89f8414c428f6b71b369f7546085Glenn Kasten 1960349009fd19f89f8414c428f6b71b369f7546085Glenn Kasten// The actual value to use, which can be specified per-device via property af.fast_track_multiplier. 1970349009fd19f89f8414c428f6b71b369f7546085Glenn Kastenstatic int sFastTrackMultiplier = kFastTrackMultiplier; 1980349009fd19f89f8414c428f6b71b369f7546085Glenn Kasten 199b880f5e5fc07397ddd09a94ba18bdf4fa62aae00Glenn Kasten// See Thread::readOnlyHeap(). 200b880f5e5fc07397ddd09a94ba18bdf4fa62aae00Glenn Kasten// Initially this heap is used to allocate client buffers for "fast" AudioRecord. 201b880f5e5fc07397ddd09a94ba18bdf4fa62aae00Glenn Kasten// Eventually it will be the single buffer that FastCapture writes into via HAL read(), 202b880f5e5fc07397ddd09a94ba18bdf4fa62aae00Glenn Kasten// and that all "fast" AudioRecord clients read from. In either case, the size can be small. 203691b02a18796810ddbf7371dbb69b6629f95d1d7Glenn Kastenstatic const size_t kRecordThreadReadOnlyHeapSize = 0x4000; 204b880f5e5fc07397ddd09a94ba18bdf4fa62aae00Glenn Kasten 20581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// ---------------------------------------------------------------------------- 20681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 2070349009fd19f89f8414c428f6b71b369f7546085Glenn Kastenstatic pthread_once_t sFastTrackMultiplierOnce = PTHREAD_ONCE_INIT; 2080349009fd19f89f8414c428f6b71b369f7546085Glenn Kasten 2090349009fd19f89f8414c428f6b71b369f7546085Glenn Kastenstatic void sFastTrackMultiplierInit() 2100349009fd19f89f8414c428f6b71b369f7546085Glenn Kasten{ 2110349009fd19f89f8414c428f6b71b369f7546085Glenn Kasten char value[PROPERTY_VALUE_MAX]; 2120349009fd19f89f8414c428f6b71b369f7546085Glenn Kasten if (property_get("af.fast_track_multiplier", value, NULL) > 0) { 2130349009fd19f89f8414c428f6b71b369f7546085Glenn Kasten char *endptr; 2140349009fd19f89f8414c428f6b71b369f7546085Glenn Kasten unsigned long ul = strtoul(value, &endptr, 0); 2150349009fd19f89f8414c428f6b71b369f7546085Glenn Kasten if (*endptr == '\0' && kFastTrackMultiplierMin <= ul && ul <= kFastTrackMultiplierMax) { 2160349009fd19f89f8414c428f6b71b369f7546085Glenn Kasten sFastTrackMultiplier = (int) ul; 2170349009fd19f89f8414c428f6b71b369f7546085Glenn Kasten } 2180349009fd19f89f8414c428f6b71b369f7546085Glenn Kasten } 2190349009fd19f89f8414c428f6b71b369f7546085Glenn Kasten} 2200349009fd19f89f8414c428f6b71b369f7546085Glenn Kasten 2210349009fd19f89f8414c428f6b71b369f7546085Glenn Kasten// ---------------------------------------------------------------------------- 2220349009fd19f89f8414c428f6b71b369f7546085Glenn Kasten 22381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent#ifdef ADD_BATTERY_DATA 22481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// To collect the amplifier usage 22581784c37c61b09289654b979567a42bf73cd2b12Eric Laurentstatic void addBatteryData(uint32_t params) { 22681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent sp<IMediaPlayerService> service = IMediaDeathNotifier::getMediaPlayerService(); 22781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (service == NULL) { 22881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // it already logged 22981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent return; 23081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 23181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 23281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent service->addBatteryData(params); 23381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 23481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent#endif 23581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 2363f0c902beb53a245c9db35e871607dba05b8d391Andy Hung// Track the CLOCK_BOOTTIME versus CLOCK_MONOTONIC timebase offset 2373f0c902beb53a245c9db35e871607dba05b8d391Andy Hungstruct { 2383f0c902beb53a245c9db35e871607dba05b8d391Andy Hung // call when you acquire a partial wakelock 2393f0c902beb53a245c9db35e871607dba05b8d391Andy Hung void acquire(const sp<IBinder> &wakeLockToken) { 2403f0c902beb53a245c9db35e871607dba05b8d391Andy Hung pthread_mutex_lock(&mLock); 2413f0c902beb53a245c9db35e871607dba05b8d391Andy Hung if (wakeLockToken.get() == nullptr) { 2423f0c902beb53a245c9db35e871607dba05b8d391Andy Hung adjustTimebaseOffset(&mBoottimeOffset, ExtendedTimestamp::TIMEBASE_BOOTTIME); 2433f0c902beb53a245c9db35e871607dba05b8d391Andy Hung } else { 2443f0c902beb53a245c9db35e871607dba05b8d391Andy Hung if (mCount == 0) { 2453f0c902beb53a245c9db35e871607dba05b8d391Andy Hung adjustTimebaseOffset(&mBoottimeOffset, ExtendedTimestamp::TIMEBASE_BOOTTIME); 2463f0c902beb53a245c9db35e871607dba05b8d391Andy Hung } 2473f0c902beb53a245c9db35e871607dba05b8d391Andy Hung ++mCount; 2483f0c902beb53a245c9db35e871607dba05b8d391Andy Hung } 2493f0c902beb53a245c9db35e871607dba05b8d391Andy Hung pthread_mutex_unlock(&mLock); 2503f0c902beb53a245c9db35e871607dba05b8d391Andy Hung } 2513f0c902beb53a245c9db35e871607dba05b8d391Andy Hung 2523f0c902beb53a245c9db35e871607dba05b8d391Andy Hung // call when you release a partial wakelock. 2533f0c902beb53a245c9db35e871607dba05b8d391Andy Hung void release(const sp<IBinder> &wakeLockToken) { 2543f0c902beb53a245c9db35e871607dba05b8d391Andy Hung if (wakeLockToken.get() == nullptr) { 2553f0c902beb53a245c9db35e871607dba05b8d391Andy Hung return; 2563f0c902beb53a245c9db35e871607dba05b8d391Andy Hung } 2573f0c902beb53a245c9db35e871607dba05b8d391Andy Hung pthread_mutex_lock(&mLock); 2583f0c902beb53a245c9db35e871607dba05b8d391Andy Hung if (--mCount < 0) { 2593f0c902beb53a245c9db35e871607dba05b8d391Andy Hung ALOGE("negative wakelock count"); 2603f0c902beb53a245c9db35e871607dba05b8d391Andy Hung mCount = 0; 2613f0c902beb53a245c9db35e871607dba05b8d391Andy Hung } 2623f0c902beb53a245c9db35e871607dba05b8d391Andy Hung pthread_mutex_unlock(&mLock); 2633f0c902beb53a245c9db35e871607dba05b8d391Andy Hung } 2643f0c902beb53a245c9db35e871607dba05b8d391Andy Hung 2653f0c902beb53a245c9db35e871607dba05b8d391Andy Hung // retrieves the boottime timebase offset from monotonic. 2663f0c902beb53a245c9db35e871607dba05b8d391Andy Hung int64_t getBoottimeOffset() { 2673f0c902beb53a245c9db35e871607dba05b8d391Andy Hung pthread_mutex_lock(&mLock); 2683f0c902beb53a245c9db35e871607dba05b8d391Andy Hung int64_t boottimeOffset = mBoottimeOffset; 2693f0c902beb53a245c9db35e871607dba05b8d391Andy Hung pthread_mutex_unlock(&mLock); 2703f0c902beb53a245c9db35e871607dba05b8d391Andy Hung return boottimeOffset; 2713f0c902beb53a245c9db35e871607dba05b8d391Andy Hung } 2723f0c902beb53a245c9db35e871607dba05b8d391Andy Hung 2733f0c902beb53a245c9db35e871607dba05b8d391Andy Hung // Adjusts the timebase offset between TIMEBASE_MONOTONIC 2743f0c902beb53a245c9db35e871607dba05b8d391Andy Hung // and the selected timebase. 2753f0c902beb53a245c9db35e871607dba05b8d391Andy Hung // Currently only TIMEBASE_BOOTTIME is allowed. 2763f0c902beb53a245c9db35e871607dba05b8d391Andy Hung // 2773f0c902beb53a245c9db35e871607dba05b8d391Andy Hung // This only needs to be called upon acquiring the first partial wakelock 2783f0c902beb53a245c9db35e871607dba05b8d391Andy Hung // after all other partial wakelocks are released. 2793f0c902beb53a245c9db35e871607dba05b8d391Andy Hung // 2803f0c902beb53a245c9db35e871607dba05b8d391Andy Hung // We do an empirical measurement of the offset rather than parsing 2813f0c902beb53a245c9db35e871607dba05b8d391Andy Hung // /proc/timer_list since the latter is not a formal kernel ABI. 2823f0c902beb53a245c9db35e871607dba05b8d391Andy Hung static void adjustTimebaseOffset(int64_t *offset, ExtendedTimestamp::Timebase timebase) { 2833f0c902beb53a245c9db35e871607dba05b8d391Andy Hung int clockbase; 2843f0c902beb53a245c9db35e871607dba05b8d391Andy Hung switch (timebase) { 2853f0c902beb53a245c9db35e871607dba05b8d391Andy Hung case ExtendedTimestamp::TIMEBASE_BOOTTIME: 2863f0c902beb53a245c9db35e871607dba05b8d391Andy Hung clockbase = SYSTEM_TIME_BOOTTIME; 2873f0c902beb53a245c9db35e871607dba05b8d391Andy Hung break; 2883f0c902beb53a245c9db35e871607dba05b8d391Andy Hung default: 2893f0c902beb53a245c9db35e871607dba05b8d391Andy Hung LOG_ALWAYS_FATAL("invalid timebase %d", timebase); 2903f0c902beb53a245c9db35e871607dba05b8d391Andy Hung break; 2913f0c902beb53a245c9db35e871607dba05b8d391Andy Hung } 2923f0c902beb53a245c9db35e871607dba05b8d391Andy Hung // try three times to get the clock offset, choose the one 2933f0c902beb53a245c9db35e871607dba05b8d391Andy Hung // with the minimum gap in measurements. 2943f0c902beb53a245c9db35e871607dba05b8d391Andy Hung const int tries = 3; 2953f0c902beb53a245c9db35e871607dba05b8d391Andy Hung nsecs_t bestGap, measured; 2963f0c902beb53a245c9db35e871607dba05b8d391Andy Hung for (int i = 0; i < tries; ++i) { 2973f0c902beb53a245c9db35e871607dba05b8d391Andy Hung const nsecs_t tmono = systemTime(SYSTEM_TIME_MONOTONIC); 2983f0c902beb53a245c9db35e871607dba05b8d391Andy Hung const nsecs_t tbase = systemTime(clockbase); 2993f0c902beb53a245c9db35e871607dba05b8d391Andy Hung const nsecs_t tmono2 = systemTime(SYSTEM_TIME_MONOTONIC); 3003f0c902beb53a245c9db35e871607dba05b8d391Andy Hung const nsecs_t gap = tmono2 - tmono; 3013f0c902beb53a245c9db35e871607dba05b8d391Andy Hung if (i == 0 || gap < bestGap) { 3023f0c902beb53a245c9db35e871607dba05b8d391Andy Hung bestGap = gap; 3033f0c902beb53a245c9db35e871607dba05b8d391Andy Hung measured = tbase - ((tmono + tmono2) >> 1); 3043f0c902beb53a245c9db35e871607dba05b8d391Andy Hung } 3053f0c902beb53a245c9db35e871607dba05b8d391Andy Hung } 3063f0c902beb53a245c9db35e871607dba05b8d391Andy Hung 3073f0c902beb53a245c9db35e871607dba05b8d391Andy Hung // to avoid micro-adjusting, we don't change the timebase 3083f0c902beb53a245c9db35e871607dba05b8d391Andy Hung // unless it is significantly different. 3093f0c902beb53a245c9db35e871607dba05b8d391Andy Hung // 3103f0c902beb53a245c9db35e871607dba05b8d391Andy Hung // Assumption: It probably takes more than toleranceNs to 3113f0c902beb53a245c9db35e871607dba05b8d391Andy Hung // suspend and resume the device. 3123f0c902beb53a245c9db35e871607dba05b8d391Andy Hung static int64_t toleranceNs = 10000; // 10 us 3133f0c902beb53a245c9db35e871607dba05b8d391Andy Hung if (llabs(*offset - measured) > toleranceNs) { 3143f0c902beb53a245c9db35e871607dba05b8d391Andy Hung ALOGV("Adjusting timebase offset old: %lld new: %lld", 3153f0c902beb53a245c9db35e871607dba05b8d391Andy Hung (long long)*offset, (long long)measured); 3163f0c902beb53a245c9db35e871607dba05b8d391Andy Hung *offset = measured; 3173f0c902beb53a245c9db35e871607dba05b8d391Andy Hung } 3183f0c902beb53a245c9db35e871607dba05b8d391Andy Hung } 3193f0c902beb53a245c9db35e871607dba05b8d391Andy Hung 3203f0c902beb53a245c9db35e871607dba05b8d391Andy Hung pthread_mutex_t mLock; 3213f0c902beb53a245c9db35e871607dba05b8d391Andy Hung int32_t mCount; 3223f0c902beb53a245c9db35e871607dba05b8d391Andy Hung int64_t mBoottimeOffset; 3233f0c902beb53a245c9db35e871607dba05b8d391Andy Hung} gBoottime = { PTHREAD_MUTEX_INITIALIZER, 0, 0 }; // static, so use POD initialization 32481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 32581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// ---------------------------------------------------------------------------- 32681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// CPU Stats 32781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// ---------------------------------------------------------------------------- 32881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 32981784c37c61b09289654b979567a42bf73cd2b12Eric Laurentclass CpuStats { 33081784c37c61b09289654b979567a42bf73cd2b12Eric Laurentpublic: 33181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent CpuStats(); 33281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent void sample(const String8 &title); 33381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent#ifdef DEBUG_CPU_USAGE 33481784c37c61b09289654b979567a42bf73cd2b12Eric Laurentprivate: 33581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent ThreadCpuUsage mCpuUsage; // instantaneous thread CPU usage in wall clock ns 33681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent CentralTendencyStatistics mWcStats; // statistics on thread CPU usage in wall clock ns 33781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 33881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent CentralTendencyStatistics mHzStats; // statistics on thread CPU usage in cycles 33981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 34081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent int mCpuNum; // thread's current CPU number 34181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent int mCpukHz; // frequency of thread's current CPU in kHz 34281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent#endif 34381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}; 34481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 34581784c37c61b09289654b979567a42bf73cd2b12Eric LaurentCpuStats::CpuStats() 34681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent#ifdef DEBUG_CPU_USAGE 34781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent : mCpuNum(-1), mCpukHz(-1) 34881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent#endif 34981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 35081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 35181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 3520f11b51a57bc9062c4fe8af73747319cedabc5d6Glenn Kastenvoid CpuStats::sample(const String8 &title 3530f11b51a57bc9062c4fe8af73747319cedabc5d6Glenn Kasten#ifndef DEBUG_CPU_USAGE 3540f11b51a57bc9062c4fe8af73747319cedabc5d6Glenn Kasten __unused 3550f11b51a57bc9062c4fe8af73747319cedabc5d6Glenn Kasten#endif 3560f11b51a57bc9062c4fe8af73747319cedabc5d6Glenn Kasten ) { 35781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent#ifdef DEBUG_CPU_USAGE 35881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // get current thread's delta CPU time in wall clock ns 35981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent double wcNs; 36081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent bool valid = mCpuUsage.sampleAndEnable(wcNs); 36181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 36281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // record sample for wall clock statistics 36381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (valid) { 36481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mWcStats.sample(wcNs); 36581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 36681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 36781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // get the current CPU number 36881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent int cpuNum = sched_getcpu(); 36981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 37081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // get the current CPU frequency in kHz 37181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent int cpukHz = mCpuUsage.getCpukHz(cpuNum); 37281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 37381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // check if either CPU number or frequency changed 37481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (cpuNum != mCpuNum || cpukHz != mCpukHz) { 37581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mCpuNum = cpuNum; 37681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mCpukHz = cpukHz; 37781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // ignore sample for purposes of cycles 37881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent valid = false; 37981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 38081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 38181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // if no change in CPU number or frequency, then record sample for cycle statistics 38281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (valid && mCpukHz > 0) { 38381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent double cycles = wcNs * cpukHz * 0.000001; 38481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mHzStats.sample(cycles); 38581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 38681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 38781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent unsigned n = mWcStats.n(); 38881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // mCpuUsage.elapsed() is expensive, so don't call it every loop 38981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if ((n & 127) == 1) { 39081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent long long elapsed = mCpuUsage.elapsed(); 39181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (elapsed >= DEBUG_CPU_USAGE * 1000000000LL) { 39281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent double perLoop = elapsed / (double) n; 39381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent double perLoop100 = perLoop * 0.01; 39481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent double perLoop1k = perLoop * 0.001; 39581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent double mean = mWcStats.mean(); 39681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent double stddev = mWcStats.stddev(); 39781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent double minimum = mWcStats.minimum(); 39881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent double maximum = mWcStats.maximum(); 39981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent double meanCycles = mHzStats.mean(); 40081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent double stddevCycles = mHzStats.stddev(); 40181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent double minCycles = mHzStats.minimum(); 40281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent double maxCycles = mHzStats.maximum(); 40381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mCpuUsage.resetElapsed(); 40481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mWcStats.reset(); 40581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mHzStats.reset(); 40681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent ALOGD("CPU usage for %s over past %.1f secs\n" 40781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent " (%u mixer loops at %.1f mean ms per loop):\n" 40881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent " us per mix loop: mean=%.0f stddev=%.0f min=%.0f max=%.0f\n" 40981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent " %% of wall: mean=%.1f stddev=%.1f min=%.1f max=%.1f\n" 41081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent " MHz: mean=%.1f, stddev=%.1f, min=%.1f max=%.1f", 41181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent title.string(), 41281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent elapsed * .000000001, n, perLoop * .000001, 41381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mean * .001, 41481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent stddev * .001, 41581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent minimum * .001, 41681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent maximum * .001, 41781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mean / perLoop100, 41881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent stddev / perLoop100, 41981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent minimum / perLoop100, 42081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent maximum / perLoop100, 42181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent meanCycles / perLoop1k, 42281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent stddevCycles / perLoop1k, 42381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent minCycles / perLoop1k, 42481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent maxCycles / perLoop1k); 42581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 42681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 42781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 42881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent#endif 42981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent}; 43081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 43181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// ---------------------------------------------------------------------------- 43281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// ThreadBase 43381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// ---------------------------------------------------------------------------- 43481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 43597b7b75b6a31330e213bdb96ccc60916218ad903Glenn Kasten// static 43697b7b75b6a31330e213bdb96ccc60916218ad903Glenn Kastenconst char *AudioFlinger::ThreadBase::threadTypeToString(AudioFlinger::ThreadBase::type_t type) 43797b7b75b6a31330e213bdb96ccc60916218ad903Glenn Kasten{ 43897b7b75b6a31330e213bdb96ccc60916218ad903Glenn Kasten switch (type) { 43997b7b75b6a31330e213bdb96ccc60916218ad903Glenn Kasten case MIXER: 44097b7b75b6a31330e213bdb96ccc60916218ad903Glenn Kasten return "MIXER"; 44197b7b75b6a31330e213bdb96ccc60916218ad903Glenn Kasten case DIRECT: 44297b7b75b6a31330e213bdb96ccc60916218ad903Glenn Kasten return "DIRECT"; 44397b7b75b6a31330e213bdb96ccc60916218ad903Glenn Kasten case DUPLICATING: 44497b7b75b6a31330e213bdb96ccc60916218ad903Glenn Kasten return "DUPLICATING"; 44597b7b75b6a31330e213bdb96ccc60916218ad903Glenn Kasten case RECORD: 44697b7b75b6a31330e213bdb96ccc60916218ad903Glenn Kasten return "RECORD"; 44797b7b75b6a31330e213bdb96ccc60916218ad903Glenn Kasten case OFFLOAD: 44897b7b75b6a31330e213bdb96ccc60916218ad903Glenn Kasten return "OFFLOAD"; 4491bfe09a0b1755a79abd32b41c0dd433b88fc260cGlenn Kasten case MMAP: 4501bfe09a0b1755a79abd32b41c0dd433b88fc260cGlenn Kasten return "MMAP"; 45197b7b75b6a31330e213bdb96ccc60916218ad903Glenn Kasten default: 45297b7b75b6a31330e213bdb96ccc60916218ad903Glenn Kasten return "unknown"; 45397b7b75b6a31330e213bdb96ccc60916218ad903Glenn Kasten } 45497b7b75b6a31330e213bdb96ccc60916218ad903Glenn Kasten} 45597b7b75b6a31330e213bdb96ccc60916218ad903Glenn Kasten 456913d06c099bd689375483a839e11057ccf284d1cMikhail Naganovstd::string devicesToString(audio_devices_t devices) 457913d06c099bd689375483a839e11057ccf284d1cMikhail Naganov{ 458913d06c099bd689375483a839e11057ccf284d1cMikhail Naganov std::string result; 4590f5b562737d6b5457aa83a4fdce9c6fb32584d9dGlenn Kasten if (devices & AUDIO_DEVICE_BIT_IN) { 460913d06c099bd689375483a839e11057ccf284d1cMikhail Naganov InputDeviceConverter::maskToString(devices, result); 4610f5b562737d6b5457aa83a4fdce9c6fb32584d9dGlenn Kasten } else { 462913d06c099bd689375483a839e11057ccf284d1cMikhail Naganov OutputDeviceConverter::maskToString(devices, result); 4630f5b562737d6b5457aa83a4fdce9c6fb32584d9dGlenn Kasten } 4640f5b562737d6b5457aa83a4fdce9c6fb32584d9dGlenn Kasten return result; 4650f5b562737d6b5457aa83a4fdce9c6fb32584d9dGlenn Kasten} 4660f5b562737d6b5457aa83a4fdce9c6fb32584d9dGlenn Kasten 467913d06c099bd689375483a839e11057ccf284d1cMikhail Naganovstd::string inputFlagsToString(audio_input_flags_t flags) 4680f5b562737d6b5457aa83a4fdce9c6fb32584d9dGlenn Kasten{ 469913d06c099bd689375483a839e11057ccf284d1cMikhail Naganov std::string result; 470913d06c099bd689375483a839e11057ccf284d1cMikhail Naganov InputFlagConverter::maskToString(flags, result); 4710f5b562737d6b5457aa83a4fdce9c6fb32584d9dGlenn Kasten return result; 4720f5b562737d6b5457aa83a4fdce9c6fb32584d9dGlenn Kasten} 4730f5b562737d6b5457aa83a4fdce9c6fb32584d9dGlenn Kasten 474913d06c099bd689375483a839e11057ccf284d1cMikhail Naganovstd::string outputFlagsToString(audio_output_flags_t flags) 475913d06c099bd689375483a839e11057ccf284d1cMikhail Naganov{ 476913d06c099bd689375483a839e11057ccf284d1cMikhail Naganov std::string result; 477913d06c099bd689375483a839e11057ccf284d1cMikhail Naganov OutputFlagConverter::maskToString(flags, result); 47897b7b75b6a31330e213bdb96ccc60916218ad903Glenn Kasten return result; 47997b7b75b6a31330e213bdb96ccc60916218ad903Glenn Kasten} 48097b7b75b6a31330e213bdb96ccc60916218ad903Glenn Kasten 4810f5b562737d6b5457aa83a4fdce9c6fb32584d9dGlenn Kastenconst char *sourceToString(audio_source_t source) 4820f5b562737d6b5457aa83a4fdce9c6fb32584d9dGlenn Kasten{ 4830f5b562737d6b5457aa83a4fdce9c6fb32584d9dGlenn Kasten switch (source) { 4840f5b562737d6b5457aa83a4fdce9c6fb32584d9dGlenn Kasten case AUDIO_SOURCE_DEFAULT: return "default"; 4850f5b562737d6b5457aa83a4fdce9c6fb32584d9dGlenn Kasten case AUDIO_SOURCE_MIC: return "mic"; 4860f5b562737d6b5457aa83a4fdce9c6fb32584d9dGlenn Kasten case AUDIO_SOURCE_VOICE_UPLINK: return "voice uplink"; 4870f5b562737d6b5457aa83a4fdce9c6fb32584d9dGlenn Kasten case AUDIO_SOURCE_VOICE_DOWNLINK: return "voice downlink"; 4880f5b562737d6b5457aa83a4fdce9c6fb32584d9dGlenn Kasten case AUDIO_SOURCE_VOICE_CALL: return "voice call"; 4890f5b562737d6b5457aa83a4fdce9c6fb32584d9dGlenn Kasten case AUDIO_SOURCE_CAMCORDER: return "camcorder"; 4900f5b562737d6b5457aa83a4fdce9c6fb32584d9dGlenn Kasten case AUDIO_SOURCE_VOICE_RECOGNITION: return "voice recognition"; 4910f5b562737d6b5457aa83a4fdce9c6fb32584d9dGlenn Kasten case AUDIO_SOURCE_VOICE_COMMUNICATION: return "voice communication"; 4920f5b562737d6b5457aa83a4fdce9c6fb32584d9dGlenn Kasten case AUDIO_SOURCE_REMOTE_SUBMIX: return "remote submix"; 4938a397d583a4f4cf24ad88facaf2fd33990cfb811rago case AUDIO_SOURCE_UNPROCESSED: return "unprocessed"; 4940f5b562737d6b5457aa83a4fdce9c6fb32584d9dGlenn Kasten case AUDIO_SOURCE_FM_TUNER: return "FM tuner"; 4950f5b562737d6b5457aa83a4fdce9c6fb32584d9dGlenn Kasten case AUDIO_SOURCE_HOTWORD: return "hotword"; 4960f5b562737d6b5457aa83a4fdce9c6fb32584d9dGlenn Kasten default: return "unknown"; 4970f5b562737d6b5457aa83a4fdce9c6fb32584d9dGlenn Kasten } 4980f5b562737d6b5457aa83a4fdce9c6fb32584d9dGlenn Kasten} 4990f5b562737d6b5457aa83a4fdce9c6fb32584d9dGlenn Kasten 50081784c37c61b09289654b979567a42bf73cd2b12Eric LaurentAudioFlinger::ThreadBase::ThreadBase(const sp<AudioFlinger>& audioFlinger, audio_io_handle_t id, 50172e3f39146fce4686bd96f11057c051bea376dfbEric Laurent audio_devices_t outDevice, audio_devices_t inDevice, type_t type, bool systemReady) 50281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent : Thread(false /*canCallJava*/), 50381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mType(type), 5049b58f63e45ef2fdfb839b9b9bb3411d81eb96128Glenn Kasten mAudioFlinger(audioFlinger), 50570949c47fbae3f836d15f040551d7631be3ed7c2Glenn Kasten // mSampleRate, mFrameCount, mChannelMask, mChannelCount, mFrameSize, mFormat, mBufferSize 506deca2ae0a7cf8bc54ff3f30b7dc39bbc78b94c0dGlenn Kasten // are set by PlaybackThread::readOutputParameters_l() or 507deca2ae0a7cf8bc54ff3f30b7dc39bbc78b94c0dGlenn Kasten // RecordThread::readInputParameters_l() 508fd4779740ec3e9e865d5514464df26d015354388Eric Laurent //FIXME: mStandby should be true here. Is this some kind of hack? 50981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mStandby(false), mOutDevice(outDevice), mInDevice(inDevice), 5107c1ec5f038e63a5eb8b04434577c25bc23f5f410Eric Laurent mPrevOutDevice(AUDIO_DEVICE_NONE), mPrevInDevice(AUDIO_DEVICE_NONE), 5117c1ec5f038e63a5eb8b04434577c25bc23f5f410Eric Laurent mAudioSource(AUDIO_SOURCE_DEFAULT), mId(id), 51281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // mName will be set by concrete (non-virtual) subclass 51372e3f39146fce4686bd96f11057c051bea376dfbEric Laurent mDeathRecipient(new PMDeathRecipient(this)), 5146acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent mSystemReady(systemReady), 5156acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent mSignalPending(false) 51681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 517296fb13dd9b5e90d6a05cce897c3b1e7914a478aEric Laurent memset(&mPatch, 0, sizeof(struct audio_patch)); 51881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 51981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 52081784c37c61b09289654b979567a42bf73cd2b12Eric LaurentAudioFlinger::ThreadBase::~ThreadBase() 52181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 522c6ae3c8a261794fd4445e4e152d1ada074a3f92fGlenn Kasten // mConfigEvents should be empty, but just in case it isn't, free the memory it owns 523c6ae3c8a261794fd4445e4e152d1ada074a3f92fGlenn Kasten mConfigEvents.clear(); 524c6ae3c8a261794fd4445e4e152d1ada074a3f92fGlenn Kasten 52581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // do not lock the mutex in destructor 52681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent releaseWakeLock_l(); 52781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (mPowerManager != 0) { 52806b46062d2f8bc82ca3061a23d197734ae51918bMarco Nelissen sp<IBinder> binder = IInterface::asBinder(mPowerManager); 52981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent binder->unlinkToDeath(mDeathRecipient); 53081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 53181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 53281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 533cf04c2cb8e031acc03c1c91cb1ccab15098c89b6Glenn Kastenstatus_t AudioFlinger::ThreadBase::readyToRun() 534cf04c2cb8e031acc03c1c91cb1ccab15098c89b6Glenn Kasten{ 535cf04c2cb8e031acc03c1c91cb1ccab15098c89b6Glenn Kasten status_t status = initCheck(); 536cf04c2cb8e031acc03c1c91cb1ccab15098c89b6Glenn Kasten if (status == NO_ERROR) { 5371bfe09a0b1755a79abd32b41c0dd433b88fc260cGlenn Kasten ALOGI("AudioFlinger's thread %p tid=%d ready to run", this, getTid()); 538cf04c2cb8e031acc03c1c91cb1ccab15098c89b6Glenn Kasten } else { 539cf04c2cb8e031acc03c1c91cb1ccab15098c89b6Glenn Kasten ALOGE("No working audio driver found."); 540cf04c2cb8e031acc03c1c91cb1ccab15098c89b6Glenn Kasten } 541cf04c2cb8e031acc03c1c91cb1ccab15098c89b6Glenn Kasten return status; 542cf04c2cb8e031acc03c1c91cb1ccab15098c89b6Glenn Kasten} 543cf04c2cb8e031acc03c1c91cb1ccab15098c89b6Glenn Kasten 54481784c37c61b09289654b979567a42bf73cd2b12Eric Laurentvoid AudioFlinger::ThreadBase::exit() 54581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 54681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent ALOGV("ThreadBase::exit"); 54781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // do any cleanup required for exit to succeed 54881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent preExit(); 54981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent { 55081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // This lock prevents the following race in thread (uniprocessor for illustration): 55181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // if (!exitPending()) { 55281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // // context switch from here to exit() 55381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // // exit() calls requestExit(), what exitPending() observes 55481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // // exit() calls signal(), which is dropped since no waiters 55581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // // context switch back from exit() to here 55681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // mWaitWorkCV.wait(...); 55781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // // now thread is hung 55881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // } 55981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent AutoMutex lock(mLock); 56081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent requestExit(); 56181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mWaitWorkCV.broadcast(); 56281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 56381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // When Thread::requestExitAndWait is made virtual and this method is renamed to 56481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // "virtual status_t requestExitAndWait()", replace by "return Thread::requestExitAndWait();" 56581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent requestExitAndWait(); 56681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 56781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 56881784c37c61b09289654b979567a42bf73cd2b12Eric Laurentstatus_t AudioFlinger::ThreadBase::setParameters(const String8& keyValuePairs) 56981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 57081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent ALOGV("ThreadBase::setParameters() %s", keyValuePairs.string()); 57181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent Mutex::Autolock _l(mLock); 57281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 5731035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent return sendSetParameterConfigEvent_l(keyValuePairs); 5741035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent} 5751035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent 5761035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent// sendConfigEvent_l() must be called with ThreadBase::mLock held 5771035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent// Can temporarily release the lock if waiting for a reply from processConfigEvents_l(). 5781035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurentstatus_t AudioFlinger::ThreadBase::sendConfigEvent_l(sp<ConfigEvent>& event) 5791035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent{ 5801035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent status_t status = NO_ERROR; 5811035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent 58272e3f39146fce4686bd96f11057c051bea376dfbEric Laurent if (event->mRequiresSystemReady && !mSystemReady) { 58372e3f39146fce4686bd96f11057c051bea376dfbEric Laurent event->mWaitStatus = false; 58472e3f39146fce4686bd96f11057c051bea376dfbEric Laurent mPendingConfigEvents.add(event); 58572e3f39146fce4686bd96f11057c051bea376dfbEric Laurent return status; 58672e3f39146fce4686bd96f11057c051bea376dfbEric Laurent } 5871035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent mConfigEvents.add(event); 588c42e9b462661673dff480ee71757a58b0f806370Glenn Kasten ALOGV("sendConfigEvent_l() num events %zu event %d", mConfigEvents.size(), event->mType); 58981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mWaitWorkCV.signal(); 5901035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent mLock.unlock(); 5911035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent { 5921035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent Mutex::Autolock _l(event->mLock); 5931035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent while (event->mWaitStatus) { 5941035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent if (event->mCond.waitRelative(event->mLock, kConfigEventTimeoutNs) != NO_ERROR) { 5951035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent event->mStatus = TIMED_OUT; 5961035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent event->mWaitStatus = false; 5971035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent } 5981035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent } 5991035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent status = event->mStatus; 60081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 6011035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent mLock.lock(); 60281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent return status; 60381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 60481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 6057c1ec5f038e63a5eb8b04434577c25bc23f5f410Eric Laurentvoid AudioFlinger::ThreadBase::sendIoConfigEvent(audio_io_config_event event, pid_t pid) 60681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 60781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent Mutex::Autolock _l(mLock); 6087c1ec5f038e63a5eb8b04434577c25bc23f5f410Eric Laurent sendIoConfigEvent_l(event, pid); 60981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 61081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 61181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// sendIoConfigEvent_l() must be called with ThreadBase::mLock held 6127c1ec5f038e63a5eb8b04434577c25bc23f5f410Eric Laurentvoid AudioFlinger::ThreadBase::sendIoConfigEvent_l(audio_io_config_event event, pid_t pid) 61381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 6147c1ec5f038e63a5eb8b04434577c25bc23f5f410Eric Laurent sp<ConfigEvent> configEvent = (ConfigEvent *)new IoConfigEvent(event, pid); 6151035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent sendConfigEvent_l(configEvent); 61681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 61781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 61883f042776b131b149f803fff6ab184ae2c4d98cdMikhail Naganovvoid AudioFlinger::ThreadBase::sendPrioConfigEvent(pid_t pid, pid_t tid, int32_t prio, bool forApp) 61972e3f39146fce4686bd96f11057c051bea376dfbEric Laurent{ 62072e3f39146fce4686bd96f11057c051bea376dfbEric Laurent Mutex::Autolock _l(mLock); 62183f042776b131b149f803fff6ab184ae2c4d98cdMikhail Naganov sendPrioConfigEvent_l(pid, tid, prio, forApp); 62272e3f39146fce4686bd96f11057c051bea376dfbEric Laurent} 62372e3f39146fce4686bd96f11057c051bea376dfbEric Laurent 62481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// sendPrioConfigEvent_l() must be called with ThreadBase::mLock held 62583f042776b131b149f803fff6ab184ae2c4d98cdMikhail Naganovvoid AudioFlinger::ThreadBase::sendPrioConfigEvent_l( 62683f042776b131b149f803fff6ab184ae2c4d98cdMikhail Naganov pid_t pid, pid_t tid, int32_t prio, bool forApp) 62781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 62883f042776b131b149f803fff6ab184ae2c4d98cdMikhail Naganov sp<ConfigEvent> configEvent = (ConfigEvent *)new PrioConfigEvent(pid, tid, prio, forApp); 6291035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent sendConfigEvent_l(configEvent); 63081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 63181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 6321035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent// sendSetParameterConfigEvent_l() must be called with ThreadBase::mLock held 6331035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurentstatus_t AudioFlinger::ThreadBase::sendSetParameterConfigEvent_l(const String8& keyValuePair) 63481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 6352ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hung sp<ConfigEvent> configEvent; 6362ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hung AudioParameter param(keyValuePair); 6372ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hung int value; 63800260b5e6996b0a4b12f71c5b84e44adea040534Mikhail Naganov if (param.getInt(String8(AudioParameter::keyMonoOutput), value) == NO_ERROR) { 6392ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hung setMasterMono_l(value != 0); 6402ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hung if (param.size() == 1) { 6412ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hung return NO_ERROR; // should be a solo parameter - we don't pass down 6422ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hung } 64300260b5e6996b0a4b12f71c5b84e44adea040534Mikhail Naganov param.remove(String8(AudioParameter::keyMonoOutput)); 6442ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hung configEvent = new SetParameterConfigEvent(param.toString()); 6452ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hung } else { 6462ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hung configEvent = new SetParameterConfigEvent(keyValuePair); 6472ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hung } 6481035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent return sendConfigEvent_l(configEvent); 649f777331418a86cd9fd709af898ef24a69967aeb4Glenn Kasten} 650f777331418a86cd9fd709af898ef24a69967aeb4Glenn Kasten 6511c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurentstatus_t AudioFlinger::ThreadBase::sendCreateAudioPatchConfigEvent( 6521c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent const struct audio_patch *patch, 6531c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent audio_patch_handle_t *handle) 6541c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent{ 6551c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent Mutex::Autolock _l(mLock); 6561c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent sp<ConfigEvent> configEvent = (ConfigEvent *)new CreateAudioPatchConfigEvent(*patch, *handle); 6571c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent status_t status = sendConfigEvent_l(configEvent); 6581c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent if (status == NO_ERROR) { 6591c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent CreateAudioPatchConfigEventData *data = 6601c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent (CreateAudioPatchConfigEventData *)configEvent->mData.get(); 6611c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent *handle = data->mHandle; 6621c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent } 6631c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent return status; 6641c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent} 6651c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent 6661c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurentstatus_t AudioFlinger::ThreadBase::sendReleaseAudioPatchConfigEvent( 6671c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent const audio_patch_handle_t handle) 6681c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent{ 6691c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent Mutex::Autolock _l(mLock); 6701c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent sp<ConfigEvent> configEvent = (ConfigEvent *)new ReleaseAudioPatchConfigEvent(handle); 6711c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent return sendConfigEvent_l(configEvent); 6721c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent} 6731c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent 6741c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent 6752cfbf88b89854f30b295e8ae26a031edb8d712f8Glenn Kasten// post condition: mConfigEvents.isEmpty() 676021cf9634ab09c0753a40b7c9ef4ba603be5c3daEric Laurentvoid AudioFlinger::ThreadBase::processConfigEvents_l() 677f777331418a86cd9fd709af898ef24a69967aeb4Glenn Kasten{ 6781035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent bool configChanged = false; 6791035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent 68081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent while (!mConfigEvents.isEmpty()) { 681c42e9b462661673dff480ee71757a58b0f806370Glenn Kasten ALOGV("processConfigEvents_l() remaining events %zu", mConfigEvents.size()); 6821035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent sp<ConfigEvent> event = mConfigEvents[0]; 68381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mConfigEvents.removeAt(0); 6841035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent switch (event->mType) { 6853468e8a4d79cc6a7bb0f03f8382426195bed44dfGlenn Kasten case CFG_EVENT_PRIO: { 6861035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent PrioConfigEventData *data = (PrioConfigEventData *)event->mData.get(); 6871035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent // FIXME Need to understand why this has to be done asynchronously 68883f042776b131b149f803fff6ab184ae2c4d98cdMikhail Naganov int err = requestPriority(data->mPid, data->mTid, data->mPrio, data->mForApp, 6893468e8a4d79cc6a7bb0f03f8382426195bed44dfGlenn Kasten true /*asynchronous*/); 6903468e8a4d79cc6a7bb0f03f8382426195bed44dfGlenn Kasten if (err != 0) { 6913468e8a4d79cc6a7bb0f03f8382426195bed44dfGlenn Kasten ALOGW("Policy SCHED_FIFO priority %d is unavailable for pid %d tid %d; error %d", 6921035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent data->mPrio, data->mPid, data->mTid, err); 6933468e8a4d79cc6a7bb0f03f8382426195bed44dfGlenn Kasten } 6943468e8a4d79cc6a7bb0f03f8382426195bed44dfGlenn Kasten } break; 6953468e8a4d79cc6a7bb0f03f8382426195bed44dfGlenn Kasten case CFG_EVENT_IO: { 6961035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent IoConfigEventData *data = (IoConfigEventData *)event->mData.get(); 6977c1ec5f038e63a5eb8b04434577c25bc23f5f410Eric Laurent ioConfigChanged(data->mEvent, data->mPid); 6981035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent } break; 6991035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent case CFG_EVENT_SET_PARAMETER: { 7001035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent SetParameterConfigEventData *data = (SetParameterConfigEventData *)event->mData.get(); 7011035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent if (checkForNewParameter_l(data->mKeyValuePairs, event->mStatus)) { 7021035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent configChanged = true; 703293558ad1977e24e65f7ba78f47382d33fc77d64Andy Hung mLocalLog.log("CFG_EVENT_SET_PARAMETER: (%s) configuration changed", 704293558ad1977e24e65f7ba78f47382d33fc77d64Andy Hung data->mKeyValuePairs.string()); 705d5418eb594435c958d6c37fa9938161a0112adbdGlenn Kasten } 7063468e8a4d79cc6a7bb0f03f8382426195bed44dfGlenn Kasten } break; 7071c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent case CFG_EVENT_CREATE_AUDIO_PATCH: { 708293558ad1977e24e65f7ba78f47382d33fc77d64Andy Hung const audio_devices_t oldDevice = getDevice(); 7091c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent CreateAudioPatchConfigEventData *data = 7101c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent (CreateAudioPatchConfigEventData *)event->mData.get(); 7111c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent event->mStatus = createAudioPatch_l(&data->mPatch, &data->mHandle); 712293558ad1977e24e65f7ba78f47382d33fc77d64Andy Hung const audio_devices_t newDevice = getDevice(); 713293558ad1977e24e65f7ba78f47382d33fc77d64Andy Hung mLocalLog.log("CFG_EVENT_CREATE_AUDIO_PATCH: old device %#x (%s) new device %#x (%s)", 714293558ad1977e24e65f7ba78f47382d33fc77d64Andy Hung (unsigned)oldDevice, devicesToString(oldDevice).c_str(), 715293558ad1977e24e65f7ba78f47382d33fc77d64Andy Hung (unsigned)newDevice, devicesToString(newDevice).c_str()); 7161c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent } break; 7171c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent case CFG_EVENT_RELEASE_AUDIO_PATCH: { 718293558ad1977e24e65f7ba78f47382d33fc77d64Andy Hung const audio_devices_t oldDevice = getDevice(); 7191c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent ReleaseAudioPatchConfigEventData *data = 7201c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent (ReleaseAudioPatchConfigEventData *)event->mData.get(); 7211c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent event->mStatus = releaseAudioPatch_l(data->mHandle); 722293558ad1977e24e65f7ba78f47382d33fc77d64Andy Hung const audio_devices_t newDevice = getDevice(); 723293558ad1977e24e65f7ba78f47382d33fc77d64Andy Hung mLocalLog.log("CFG_EVENT_RELEASE_AUDIO_PATCH: old device %#x (%s) new device %#x (%s)", 724293558ad1977e24e65f7ba78f47382d33fc77d64Andy Hung (unsigned)oldDevice, devicesToString(oldDevice).c_str(), 725293558ad1977e24e65f7ba78f47382d33fc77d64Andy Hung (unsigned)newDevice, devicesToString(newDevice).c_str()); 7261c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent } break; 7273468e8a4d79cc6a7bb0f03f8382426195bed44dfGlenn Kasten default: 7281035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent ALOG_ASSERT(false, "processConfigEvents_l() unknown event type %d", event->mType); 7293468e8a4d79cc6a7bb0f03f8382426195bed44dfGlenn Kasten break; 73081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 7311035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent { 7321035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent Mutex::Autolock _l(event->mLock); 7331035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent if (event->mWaitStatus) { 7341035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent event->mWaitStatus = false; 7351035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent event->mCond.signal(); 7361035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent } 7371035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent } 7381035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent ALOGV_IF(mConfigEvents.isEmpty(), "processConfigEvents_l() DONE thread %p", this); 7391035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent } 7401035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent 7411035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent if (configChanged) { 7421035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent cacheParameters_l(); 74381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 74481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 74581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 746b220884bf3129253cc5bc8d030bc475411ea4911Marco NelissenString8 channelMaskToString(audio_channel_mask_t mask, bool output) { 747b220884bf3129253cc5bc8d030bc475411ea4911Marco Nelissen String8 s; 748e1635ec096d1110c33a5aa46847af59c261fb7faGlenn Kasten const audio_channel_representation_t representation = 749e1635ec096d1110c33a5aa46847af59c261fb7faGlenn Kasten audio_channel_mask_get_representation(mask); 750f98ec8d0d42e6952c0a7cc5027935851073f7426Andy Hung 751f98ec8d0d42e6952c0a7cc5027935851073f7426Andy Hung switch (representation) { 752f98ec8d0d42e6952c0a7cc5027935851073f7426Andy Hung case AUDIO_CHANNEL_REPRESENTATION_POSITION: { 753f98ec8d0d42e6952c0a7cc5027935851073f7426Andy Hung if (output) { 754f98ec8d0d42e6952c0a7cc5027935851073f7426Andy Hung if (mask & AUDIO_CHANNEL_OUT_FRONT_LEFT) s.append("front-left, "); 755f98ec8d0d42e6952c0a7cc5027935851073f7426Andy Hung if (mask & AUDIO_CHANNEL_OUT_FRONT_RIGHT) s.append("front-right, "); 756f98ec8d0d42e6952c0a7cc5027935851073f7426Andy Hung if (mask & AUDIO_CHANNEL_OUT_FRONT_CENTER) s.append("front-center, "); 757f98ec8d0d42e6952c0a7cc5027935851073f7426Andy Hung if (mask & AUDIO_CHANNEL_OUT_LOW_FREQUENCY) s.append("low freq, "); 758f98ec8d0d42e6952c0a7cc5027935851073f7426Andy Hung if (mask & AUDIO_CHANNEL_OUT_BACK_LEFT) s.append("back-left, "); 759f98ec8d0d42e6952c0a7cc5027935851073f7426Andy Hung if (mask & AUDIO_CHANNEL_OUT_BACK_RIGHT) s.append("back-right, "); 760f98ec8d0d42e6952c0a7cc5027935851073f7426Andy Hung if (mask & AUDIO_CHANNEL_OUT_FRONT_LEFT_OF_CENTER) s.append("front-left-of-center, "); 761f98ec8d0d42e6952c0a7cc5027935851073f7426Andy Hung if (mask & AUDIO_CHANNEL_OUT_FRONT_RIGHT_OF_CENTER) s.append("front-right-of-center, "); 762f98ec8d0d42e6952c0a7cc5027935851073f7426Andy Hung if (mask & AUDIO_CHANNEL_OUT_BACK_CENTER) s.append("back-center, "); 763f98ec8d0d42e6952c0a7cc5027935851073f7426Andy Hung if (mask & AUDIO_CHANNEL_OUT_SIDE_LEFT) s.append("side-left, "); 764f98ec8d0d42e6952c0a7cc5027935851073f7426Andy Hung if (mask & AUDIO_CHANNEL_OUT_SIDE_RIGHT) s.append("side-right, "); 765f98ec8d0d42e6952c0a7cc5027935851073f7426Andy Hung if (mask & AUDIO_CHANNEL_OUT_TOP_CENTER) s.append("top-center ,"); 766f98ec8d0d42e6952c0a7cc5027935851073f7426Andy Hung if (mask & AUDIO_CHANNEL_OUT_TOP_FRONT_LEFT) s.append("top-front-left, "); 767f98ec8d0d42e6952c0a7cc5027935851073f7426Andy Hung if (mask & AUDIO_CHANNEL_OUT_TOP_FRONT_CENTER) s.append("top-front-center, "); 768f98ec8d0d42e6952c0a7cc5027935851073f7426Andy Hung if (mask & AUDIO_CHANNEL_OUT_TOP_FRONT_RIGHT) s.append("top-front-right, "); 769f98ec8d0d42e6952c0a7cc5027935851073f7426Andy Hung if (mask & AUDIO_CHANNEL_OUT_TOP_BACK_LEFT) s.append("top-back-left, "); 770f98ec8d0d42e6952c0a7cc5027935851073f7426Andy Hung if (mask & AUDIO_CHANNEL_OUT_TOP_BACK_CENTER) s.append("top-back-center, " ); 771f98ec8d0d42e6952c0a7cc5027935851073f7426Andy Hung if (mask & AUDIO_CHANNEL_OUT_TOP_BACK_RIGHT) s.append("top-back-right, " ); 772f98ec8d0d42e6952c0a7cc5027935851073f7426Andy Hung if (mask & ~AUDIO_CHANNEL_OUT_ALL) s.append("unknown, "); 773f98ec8d0d42e6952c0a7cc5027935851073f7426Andy Hung } else { 774f98ec8d0d42e6952c0a7cc5027935851073f7426Andy Hung if (mask & AUDIO_CHANNEL_IN_LEFT) s.append("left, "); 775f98ec8d0d42e6952c0a7cc5027935851073f7426Andy Hung if (mask & AUDIO_CHANNEL_IN_RIGHT) s.append("right, "); 776f98ec8d0d42e6952c0a7cc5027935851073f7426Andy Hung if (mask & AUDIO_CHANNEL_IN_FRONT) s.append("front, "); 777f98ec8d0d42e6952c0a7cc5027935851073f7426Andy Hung if (mask & AUDIO_CHANNEL_IN_BACK) s.append("back, "); 778f98ec8d0d42e6952c0a7cc5027935851073f7426Andy Hung if (mask & AUDIO_CHANNEL_IN_LEFT_PROCESSED) s.append("left-processed, "); 779f98ec8d0d42e6952c0a7cc5027935851073f7426Andy Hung if (mask & AUDIO_CHANNEL_IN_RIGHT_PROCESSED) s.append("right-processed, "); 780f98ec8d0d42e6952c0a7cc5027935851073f7426Andy Hung if (mask & AUDIO_CHANNEL_IN_FRONT_PROCESSED) s.append("front-processed, "); 781f98ec8d0d42e6952c0a7cc5027935851073f7426Andy Hung if (mask & AUDIO_CHANNEL_IN_BACK_PROCESSED) s.append("back-processed, "); 782f98ec8d0d42e6952c0a7cc5027935851073f7426Andy Hung if (mask & AUDIO_CHANNEL_IN_PRESSURE) s.append("pressure, "); 783f98ec8d0d42e6952c0a7cc5027935851073f7426Andy Hung if (mask & AUDIO_CHANNEL_IN_X_AXIS) s.append("X, "); 784f98ec8d0d42e6952c0a7cc5027935851073f7426Andy Hung if (mask & AUDIO_CHANNEL_IN_Y_AXIS) s.append("Y, "); 785f98ec8d0d42e6952c0a7cc5027935851073f7426Andy Hung if (mask & AUDIO_CHANNEL_IN_Z_AXIS) s.append("Z, "); 786f98ec8d0d42e6952c0a7cc5027935851073f7426Andy Hung if (mask & AUDIO_CHANNEL_IN_VOICE_UPLINK) s.append("voice-uplink, "); 787f98ec8d0d42e6952c0a7cc5027935851073f7426Andy Hung if (mask & AUDIO_CHANNEL_IN_VOICE_DNLINK) s.append("voice-dnlink, "); 788f98ec8d0d42e6952c0a7cc5027935851073f7426Andy Hung if (mask & ~AUDIO_CHANNEL_IN_ALL) s.append("unknown, "); 789f98ec8d0d42e6952c0a7cc5027935851073f7426Andy Hung } 790f98ec8d0d42e6952c0a7cc5027935851073f7426Andy Hung const int len = s.length(); 791f98ec8d0d42e6952c0a7cc5027935851073f7426Andy Hung if (len > 2) { 79257c4e6f7464d458eb52d209c2a63524913d6406dGlenn Kasten (void) s.lockBuffer(len); // needed? 793f98ec8d0d42e6952c0a7cc5027935851073f7426Andy Hung s.unlockBuffer(len - 2); // remove trailing ", " 794f98ec8d0d42e6952c0a7cc5027935851073f7426Andy Hung } 795f98ec8d0d42e6952c0a7cc5027935851073f7426Andy Hung return s; 796b220884bf3129253cc5bc8d030bc475411ea4911Marco Nelissen } 797f98ec8d0d42e6952c0a7cc5027935851073f7426Andy Hung case AUDIO_CHANNEL_REPRESENTATION_INDEX: 798f98ec8d0d42e6952c0a7cc5027935851073f7426Andy Hung s.appendFormat("index mask, bits:%#x", audio_channel_mask_get_bits(mask)); 799f98ec8d0d42e6952c0a7cc5027935851073f7426Andy Hung return s; 800f98ec8d0d42e6952c0a7cc5027935851073f7426Andy Hung default: 801f98ec8d0d42e6952c0a7cc5027935851073f7426Andy Hung s.appendFormat("unknown mask, representation:%d bits:%#x", 802f98ec8d0d42e6952c0a7cc5027935851073f7426Andy Hung representation, audio_channel_mask_get_bits(mask)); 803f98ec8d0d42e6952c0a7cc5027935851073f7426Andy Hung return s; 804b220884bf3129253cc5bc8d030bc475411ea4911Marco Nelissen } 805b220884bf3129253cc5bc8d030bc475411ea4911Marco Nelissen} 806b220884bf3129253cc5bc8d030bc475411ea4911Marco Nelissen 8070f11b51a57bc9062c4fe8af73747319cedabc5d6Glenn Kastenvoid AudioFlinger::ThreadBase::dumpBase(int fd, const Vector<String16>& args __unused) 80881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 80981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent const size_t SIZE = 256; 81081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent char buffer[SIZE]; 81181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent String8 result; 81281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 8131bfe09a0b1755a79abd32b41c0dd433b88fc260cGlenn Kasten dprintf(fd, "\n%s thread %p, name %s, tid %d, type %d (%s):\n", isOutput() ? "Output" : "Input", 8141bfe09a0b1755a79abd32b41c0dd433b88fc260cGlenn Kasten this, mThreadName, getTid(), type(), threadTypeToString(type())); 8151bfe09a0b1755a79abd32b41c0dd433b88fc260cGlenn Kasten 81681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent bool locked = AudioFlinger::dumpTryLock(mLock); 81781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (!locked) { 8181bfe09a0b1755a79abd32b41c0dd433b88fc260cGlenn Kasten dprintf(fd, " Thread may be deadlocked\n"); 819b220884bf3129253cc5bc8d030bc475411ea4911Marco Nelissen } 820b220884bf3129253cc5bc8d030bc475411ea4911Marco Nelissen 82187cebadd48710e42474756fc3513df678de045ceElliott Hughes dprintf(fd, " I/O handle: %d\n", mId); 82287cebadd48710e42474756fc3513df678de045ceElliott Hughes dprintf(fd, " Standby: %s\n", mStandby ? "yes" : "no"); 82397b7b75b6a31330e213bdb96ccc60916218ad903Glenn Kasten dprintf(fd, " Sample rate: %u Hz\n", mSampleRate); 82487cebadd48710e42474756fc3513df678de045ceElliott Hughes dprintf(fd, " HAL frame count: %zu\n", mFrameCount); 825913d06c099bd689375483a839e11057ccf284d1cMikhail Naganov dprintf(fd, " HAL format: 0x%x (%s)\n", mHALFormat, formatToString(mHALFormat).c_str()); 826c42e9b462661673dff480ee71757a58b0f806370Glenn Kasten dprintf(fd, " HAL buffer size: %zu bytes\n", mBufferSize); 82797b7b75b6a31330e213bdb96ccc60916218ad903Glenn Kasten dprintf(fd, " Channel count: %u\n", mChannelCount); 82897b7b75b6a31330e213bdb96ccc60916218ad903Glenn Kasten dprintf(fd, " Channel mask: 0x%08x (%s)\n", mChannelMask, 829b220884bf3129253cc5bc8d030bc475411ea4911Marco Nelissen channelMaskToString(mChannelMask, mType != RECORD).string()); 830913d06c099bd689375483a839e11057ccf284d1cMikhail Naganov dprintf(fd, " Processing format: 0x%x (%s)\n", mFormat, formatToString(mFormat).c_str()); 831f87c2f5eb4e37f0950962e31b9ca49e32f5b0864Glenn Kasten dprintf(fd, " Processing frame size: %zu bytes\n", mFrameSize); 83287cebadd48710e42474756fc3513df678de045ceElliott Hughes dprintf(fd, " Pending config events:"); 833b220884bf3129253cc5bc8d030bc475411ea4911Marco Nelissen size_t numConfig = mConfigEvents.size(); 834b220884bf3129253cc5bc8d030bc475411ea4911Marco Nelissen if (numConfig) { 835b220884bf3129253cc5bc8d030bc475411ea4911Marco Nelissen for (size_t i = 0; i < numConfig; i++) { 836b220884bf3129253cc5bc8d030bc475411ea4911Marco Nelissen mConfigEvents[i]->dump(buffer, SIZE); 83787cebadd48710e42474756fc3513df678de045ceElliott Hughes dprintf(fd, "\n %s", buffer); 838b220884bf3129253cc5bc8d030bc475411ea4911Marco Nelissen } 83987cebadd48710e42474756fc3513df678de045ceElliott Hughes dprintf(fd, "\n"); 840b220884bf3129253cc5bc8d030bc475411ea4911Marco Nelissen } else { 84187cebadd48710e42474756fc3513df678de045ceElliott Hughes dprintf(fd, " none\n"); 84281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 843293558ad1977e24e65f7ba78f47382d33fc77d64Andy Hung // Note: output device may be used by capture threads for effects such as AEC. 844913d06c099bd689375483a839e11057ccf284d1cMikhail Naganov dprintf(fd, " Output device: %#x (%s)\n", mOutDevice, devicesToString(mOutDevice).c_str()); 845913d06c099bd689375483a839e11057ccf284d1cMikhail Naganov dprintf(fd, " Input device: %#x (%s)\n", mInDevice, devicesToString(mInDevice).c_str()); 8460b89bc0d285b8fd4798df1ff0ba9f93851a3bd48Glenn Kasten dprintf(fd, " Audio source: %d (%s)\n", mAudioSource, sourceToString(mAudioSource)); 84781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 84881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (locked) { 84981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mLock.unlock(); 85081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 85181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 85281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 85381784c37c61b09289654b979567a42bf73cd2b12Eric Laurentvoid AudioFlinger::ThreadBase::dumpEffectChains(int fd, const Vector<String16>& args) 85481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 85581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent const size_t SIZE = 256; 85681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent char buffer[SIZE]; 85781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent String8 result; 85881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 859b220884bf3129253cc5bc8d030bc475411ea4911Marco Nelissen size_t numEffectChains = mEffectChains.size(); 8601d6fa7af1288b550faabe4ec2cf98684236723dbNarayan Kamath snprintf(buffer, SIZE, " %zu Effect Chains\n", numEffectChains); 86181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent write(fd, buffer, strlen(buffer)); 86281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 863b220884bf3129253cc5bc8d030bc475411ea4911Marco Nelissen for (size_t i = 0; i < numEffectChains; ++i) { 86481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent sp<EffectChain> chain = mEffectChains[i]; 86581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (chain != 0) { 86681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent chain->dump(fd, args); 86781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 86881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 86981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 87081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 871dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hungvoid AudioFlinger::ThreadBase::acquireWakeLock() 87281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 87381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent Mutex::Autolock _l(mLock); 874dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hung acquireWakeLock_l(); 87581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 87681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 877014e7fa2e90827d911c37bb0ce4d2e10e14d0bb3Narayan KamathString16 AudioFlinger::ThreadBase::getWakeLockTag() 878014e7fa2e90827d911c37bb0ce4d2e10e14d0bb3Narayan Kamath{ 879014e7fa2e90827d911c37bb0ce4d2e10e14d0bb3Narayan Kamath switch (mType) { 880bcb1486d052e329ae4790d93055d1c51017286c3Glenn Kasten case MIXER: 881bcb1486d052e329ae4790d93055d1c51017286c3Glenn Kasten return String16("AudioMix"); 882bcb1486d052e329ae4790d93055d1c51017286c3Glenn Kasten case DIRECT: 883bcb1486d052e329ae4790d93055d1c51017286c3Glenn Kasten return String16("AudioDirectOut"); 884bcb1486d052e329ae4790d93055d1c51017286c3Glenn Kasten case DUPLICATING: 885bcb1486d052e329ae4790d93055d1c51017286c3Glenn Kasten return String16("AudioDup"); 886bcb1486d052e329ae4790d93055d1c51017286c3Glenn Kasten case RECORD: 887bcb1486d052e329ae4790d93055d1c51017286c3Glenn Kasten return String16("AudioIn"); 888bcb1486d052e329ae4790d93055d1c51017286c3Glenn Kasten case OFFLOAD: 889bcb1486d052e329ae4790d93055d1c51017286c3Glenn Kasten return String16("AudioOffload"); 8906acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent case MMAP: 8916acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent return String16("Mmap"); 892bcb1486d052e329ae4790d93055d1c51017286c3Glenn Kasten default: 893bcb1486d052e329ae4790d93055d1c51017286c3Glenn Kasten ALOG_ASSERT(false); 894bcb1486d052e329ae4790d93055d1c51017286c3Glenn Kasten return String16("AudioUnknown"); 895014e7fa2e90827d911c37bb0ce4d2e10e14d0bb3Narayan Kamath } 896014e7fa2e90827d911c37bb0ce4d2e10e14d0bb3Narayan Kamath} 897014e7fa2e90827d911c37bb0ce4d2e10e14d0bb3Narayan Kamath 898dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hungvoid AudioFlinger::ThreadBase::acquireWakeLock_l() 89981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 900462fd2fa9eef642b0574aa7409de0bde3fec8d43Marco Nelissen getPowerManager_l(); 90181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (mPowerManager != 0) { 90281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent sp<IBinder> binder = new BBinder(); 903dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hung // Uses AID_AUDIOSERVER for wakelock. updateWakeLockUids_l() updates with client uids. 904dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hung status_t status = mPowerManager->acquireWakeLock(POWERMANAGER_PARTIAL_WAKE_LOCK, 9059cab746b116b8aed38ca6b97bfea35103535e522Eric Laurent binder, 9069cab746b116b8aed38ca6b97bfea35103535e522Eric Laurent getWakeLockTag(), 9079cab746b116b8aed38ca6b97bfea35103535e522Eric Laurent String16("audioserver"), 9089cab746b116b8aed38ca6b97bfea35103535e522Eric Laurent true /* FIXME force oneway contrary to .aidl */); 90981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (status == NO_ERROR) { 91081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mWakeLockToken = binder; 91181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 912d7dca050c630bddbd73a6623271b34b4290460eeGlenn Kasten ALOGV("acquireWakeLock_l() %s status %d", mThreadName, status); 91381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 9143f273d10817ddb2f792ae043de692efcdf1988aeWei Jia 9153f0c902beb53a245c9db35e871607dba05b8d391Andy Hung gBoottime.acquire(mWakeLockToken); 916818e7a32ce3633980138aff2c2bfcc5158b3cfccAndy Hung mTimestamp.mTimebaseOffset[ExtendedTimestamp::TIMEBASE_BOOTTIME] = 917818e7a32ce3633980138aff2c2bfcc5158b3cfccAndy Hung gBoottime.getBoottimeOffset(); 91881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 91981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 92081784c37c61b09289654b979567a42bf73cd2b12Eric Laurentvoid AudioFlinger::ThreadBase::releaseWakeLock() 92181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 92281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent Mutex::Autolock _l(mLock); 92381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent releaseWakeLock_l(); 92481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 92581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 92681784c37c61b09289654b979567a42bf73cd2b12Eric Laurentvoid AudioFlinger::ThreadBase::releaseWakeLock_l() 92781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 9283f0c902beb53a245c9db35e871607dba05b8d391Andy Hung gBoottime.release(mWakeLockToken); 92981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (mWakeLockToken != 0) { 930d7dca050c630bddbd73a6623271b34b4290460eeGlenn Kasten ALOGV("releaseWakeLock_l() %s", mThreadName); 93181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (mPowerManager != 0) { 9323abc2ded40066f3b1df23aceb553f22d569c5cd3Glenn Kasten mPowerManager->releaseWakeLock(mWakeLockToken, 0, 9333abc2ded40066f3b1df23aceb553f22d569c5cd3Glenn Kasten true /* FIXME force oneway contrary to .aidl */); 93481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 93581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mWakeLockToken.clear(); 93681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 937462fd2fa9eef642b0574aa7409de0bde3fec8d43Marco Nelissen} 938462fd2fa9eef642b0574aa7409de0bde3fec8d43Marco Nelissen 939462fd2fa9eef642b0574aa7409de0bde3fec8d43Marco Nelissenvoid AudioFlinger::ThreadBase::getPowerManager_l() { 94072e3f39146fce4686bd96f11057c051bea376dfbEric Laurent if (mSystemReady && mPowerManager == 0) { 941462fd2fa9eef642b0574aa7409de0bde3fec8d43Marco Nelissen // use checkService() to avoid blocking if power service is not up yet 942462fd2fa9eef642b0574aa7409de0bde3fec8d43Marco Nelissen sp<IBinder> binder = 943462fd2fa9eef642b0574aa7409de0bde3fec8d43Marco Nelissen defaultServiceManager()->checkService(String16("power")); 944462fd2fa9eef642b0574aa7409de0bde3fec8d43Marco Nelissen if (binder == 0) { 945d7dca050c630bddbd73a6623271b34b4290460eeGlenn Kasten ALOGW("Thread %s cannot connect to the power manager service", mThreadName); 946462fd2fa9eef642b0574aa7409de0bde3fec8d43Marco Nelissen } else { 947462fd2fa9eef642b0574aa7409de0bde3fec8d43Marco Nelissen mPowerManager = interface_cast<IPowerManager>(binder); 948462fd2fa9eef642b0574aa7409de0bde3fec8d43Marco Nelissen binder->linkToDeath(mDeathRecipient); 949462fd2fa9eef642b0574aa7409de0bde3fec8d43Marco Nelissen } 950462fd2fa9eef642b0574aa7409de0bde3fec8d43Marco Nelissen } 951462fd2fa9eef642b0574aa7409de0bde3fec8d43Marco Nelissen} 952462fd2fa9eef642b0574aa7409de0bde3fec8d43Marco Nelissen 953d01b0f18491c355d808a57cb272404480e69618fAndy Hungvoid AudioFlinger::ThreadBase::updateWakeLockUids_l(const SortedVector<uid_t> &uids) { 954462fd2fa9eef642b0574aa7409de0bde3fec8d43Marco Nelissen getPowerManager_l(); 955dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hung 956dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hung#if !LOG_NDEBUG 957dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hung std::stringstream s; 958d01b0f18491c355d808a57cb272404480e69618fAndy Hung for (uid_t uid : uids) { 959dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hung s << uid << " "; 960dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hung } 961dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hung ALOGD("updateWakeLockUids_l %s uids:%s", mThreadName, s.str().c_str()); 962dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hung#endif 963dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hung 964438e7572c83674f4b9e6184f32f3dc94cd50524eAndy Hung if (mWakeLockToken == NULL) { // token may be NULL if AudioFlinger::systemReady() not called. 965438e7572c83674f4b9e6184f32f3dc94cd50524eAndy Hung if (mSystemReady) { 966438e7572c83674f4b9e6184f32f3dc94cd50524eAndy Hung ALOGE("no wake lock to update, but system ready!"); 967438e7572c83674f4b9e6184f32f3dc94cd50524eAndy Hung } else { 968438e7572c83674f4b9e6184f32f3dc94cd50524eAndy Hung ALOGW("no wake lock to update, system not ready yet"); 969438e7572c83674f4b9e6184f32f3dc94cd50524eAndy Hung } 970462fd2fa9eef642b0574aa7409de0bde3fec8d43Marco Nelissen return; 971462fd2fa9eef642b0574aa7409de0bde3fec8d43Marco Nelissen } 972462fd2fa9eef642b0574aa7409de0bde3fec8d43Marco Nelissen if (mPowerManager != 0) { 9731f12a8ad958344c50733b948628ffa06db9c5bc6Andy Hung std::vector<int> uidsAsInt(uids.begin(), uids.end()); // powermanager expects uids as ints 9741f12a8ad958344c50733b948628ffa06db9c5bc6Andy Hung status_t status = mPowerManager->updateWakeLockUids( 9751f12a8ad958344c50733b948628ffa06db9c5bc6Andy Hung mWakeLockToken, uidsAsInt.size(), uidsAsInt.data(), 9761f12a8ad958344c50733b948628ffa06db9c5bc6Andy Hung true /* FIXME force oneway contrary to .aidl */); 9774d231dc0ee34380956c71cbe18a750e487a69601Eric Laurent ALOGV("updateWakeLockUids_l() %s status %d", mThreadName, status); 978462fd2fa9eef642b0574aa7409de0bde3fec8d43Marco Nelissen } 979462fd2fa9eef642b0574aa7409de0bde3fec8d43Marco Nelissen} 980462fd2fa9eef642b0574aa7409de0bde3fec8d43Marco Nelissen 98181784c37c61b09289654b979567a42bf73cd2b12Eric Laurentvoid AudioFlinger::ThreadBase::clearPowerManager() 98281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 98381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent Mutex::Autolock _l(mLock); 98481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent releaseWakeLock_l(); 98581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mPowerManager.clear(); 98681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 98781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 9880f11b51a57bc9062c4fe8af73747319cedabc5d6Glenn Kastenvoid AudioFlinger::ThreadBase::PMDeathRecipient::binderDied(const wp<IBinder>& who __unused) 98981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 99081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent sp<ThreadBase> thread = mThread.promote(); 99181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (thread != 0) { 99281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent thread->clearPowerManager(); 99381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 99481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent ALOGW("power manager service died !!!"); 99581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 99681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 99781784c37c61b09289654b979567a42bf73cd2b12Eric Laurentvoid AudioFlinger::ThreadBase::setEffectSuspended_l( 998d848eb48c121c119e8ba7583efc75415fe102570Glenn Kasten const effect_uuid_t *type, bool suspend, audio_session_t sessionId) 99981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 100081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent sp<EffectChain> chain = getEffectChain_l(sessionId); 100181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (chain != 0) { 100281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (type != NULL) { 100381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent chain->setEffectSuspended_l(type, suspend); 100481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } else { 100581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent chain->setEffectSuspendedAll_l(suspend); 100681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 100781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 100881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 100981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent updateSuspendedSessions_l(type, suspend, sessionId); 101081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 101181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 101281784c37c61b09289654b979567a42bf73cd2b12Eric Laurentvoid AudioFlinger::ThreadBase::checkSuspendOnAddEffectChain_l(const sp<EffectChain>& chain) 101381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 101481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent ssize_t index = mSuspendedSessions.indexOfKey(chain->sessionId()); 101581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (index < 0) { 101681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent return; 101781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 101881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 101981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent const KeyedVector <int, sp<SuspendedSessionDesc> >& sessionEffects = 102081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mSuspendedSessions.valueAt(index); 102181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 102281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent for (size_t i = 0; i < sessionEffects.size(); i++) { 1023e964d4e421e2d1ca937227a580c0c837091a11e3Chih-Hung Hsieh const sp<SuspendedSessionDesc>& desc = sessionEffects.valueAt(i); 102481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent for (int j = 0; j < desc->mRefCount; j++) { 102581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (sessionEffects.keyAt(i) == EffectChain::kKeyForSuspendAll) { 102681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent chain->setEffectSuspendedAll_l(true); 102781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } else { 102881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent ALOGV("checkSuspendOnAddEffectChain_l() suspending effects %08x", 102981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent desc->mType.timeLow); 103081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent chain->setEffectSuspended_l(&desc->mType, true); 103181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 103281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 103381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 103481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 103581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 103681784c37c61b09289654b979567a42bf73cd2b12Eric Laurentvoid AudioFlinger::ThreadBase::updateSuspendedSessions_l(const effect_uuid_t *type, 103781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent bool suspend, 1038d848eb48c121c119e8ba7583efc75415fe102570Glenn Kasten audio_session_t sessionId) 103981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 104081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent ssize_t index = mSuspendedSessions.indexOfKey(sessionId); 104181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 104281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent KeyedVector <int, sp<SuspendedSessionDesc> > sessionEffects; 104381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 104481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (suspend) { 104581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (index >= 0) { 104681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent sessionEffects = mSuspendedSessions.valueAt(index); 104781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } else { 104881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mSuspendedSessions.add(sessionId, sessionEffects); 104981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 105081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } else { 105181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (index < 0) { 105281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent return; 105381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 105481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent sessionEffects = mSuspendedSessions.valueAt(index); 105581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 105681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 105781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 105881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent int key = EffectChain::kKeyForSuspendAll; 105981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (type != NULL) { 106081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent key = type->timeLow; 106181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 106281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent index = sessionEffects.indexOfKey(key); 106381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 106481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent sp<SuspendedSessionDesc> desc; 106581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (suspend) { 106681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (index >= 0) { 106781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent desc = sessionEffects.valueAt(index); 106881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } else { 106981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent desc = new SuspendedSessionDesc(); 107081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (type != NULL) { 107181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent desc->mType = *type; 107281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 107381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent sessionEffects.add(key, desc); 107481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent ALOGV("updateSuspendedSessions_l() suspend adding effect %08x", key); 107581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 107681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent desc->mRefCount++; 107781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } else { 107881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (index < 0) { 107981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent return; 108081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 108181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent desc = sessionEffects.valueAt(index); 108281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (--desc->mRefCount == 0) { 108381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent ALOGV("updateSuspendedSessions_l() restore removing effect %08x", key); 108481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent sessionEffects.removeItemsAt(index); 108581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (sessionEffects.isEmpty()) { 108681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent ALOGV("updateSuspendedSessions_l() restore removing session %d", 108781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent sessionId); 108881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mSuspendedSessions.removeItem(sessionId); 108981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 109081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 109181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 109281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (!sessionEffects.isEmpty()) { 109381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mSuspendedSessions.replaceValueFor(sessionId, sessionEffects); 109481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 109581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 109681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 109781784c37c61b09289654b979567a42bf73cd2b12Eric Laurentvoid AudioFlinger::ThreadBase::checkSuspendOnEffectEnabled(const sp<EffectModule>& effect, 109881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent bool enabled, 1099d848eb48c121c119e8ba7583efc75415fe102570Glenn Kasten audio_session_t sessionId) 110081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 110181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent Mutex::Autolock _l(mLock); 110281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent checkSuspendOnEffectEnabled_l(effect, enabled, sessionId); 110381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 110481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 110581784c37c61b09289654b979567a42bf73cd2b12Eric Laurentvoid AudioFlinger::ThreadBase::checkSuspendOnEffectEnabled_l(const sp<EffectModule>& effect, 110681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent bool enabled, 1107d848eb48c121c119e8ba7583efc75415fe102570Glenn Kasten audio_session_t sessionId) 110881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 110981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (mType != RECORD) { 111081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // suspend all effects in AUDIO_SESSION_OUTPUT_MIX when enabling any effect on 111181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // another session. This gives the priority to well behaved effect control panels 111281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // and applications not using global effects. 111381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // Enabling post processing in AUDIO_SESSION_OUTPUT_STAGE session does not affect 111481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // global effects 111581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if ((sessionId != AUDIO_SESSION_OUTPUT_MIX) && (sessionId != AUDIO_SESSION_OUTPUT_STAGE)) { 111681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent setEffectSuspended_l(NULL, enabled, AUDIO_SESSION_OUTPUT_MIX); 111781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 111881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 111981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 112081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent sp<EffectChain> chain = getEffectChain_l(sessionId); 112181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (chain != 0) { 112281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent chain->checkSuspendOnEffectEnabled(effect, enabled); 112381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 112481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 112581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 11264c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent// checkEffectCompatibility_l() must be called with ThreadBase::mLock held 11274c415062ad1bb53e9af8f644d8215837262b79bbEric Laurentstatus_t AudioFlinger::RecordThread::checkEffectCompatibility_l( 11284c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent const effect_descriptor_t *desc, audio_session_t sessionId) 11294c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent{ 11304c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent // No global effect sessions on record threads 11314c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent if (sessionId == AUDIO_SESSION_OUTPUT_MIX || sessionId == AUDIO_SESSION_OUTPUT_STAGE) { 11324c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent ALOGW("checkEffectCompatibility_l(): global effect %s on record thread %s", 11334c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent desc->name, mThreadName); 11344c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent return BAD_VALUE; 11354c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent } 11364c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent // only pre processing effects on record thread 11374c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent if ((desc->flags & EFFECT_FLAG_TYPE_MASK) != EFFECT_FLAG_TYPE_PRE_PROC) { 11384c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent ALOGW("checkEffectCompatibility_l(): non pre processing effect %s on record thread %s", 11394c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent desc->name, mThreadName); 11404c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent return BAD_VALUE; 11414c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent } 11426dd0fd92d6cdeb2cf5b7127c0e880e5eacfd4574Eric Laurent 11436dd0fd92d6cdeb2cf5b7127c0e880e5eacfd4574Eric Laurent // always allow effects without processing load or latency 11446dd0fd92d6cdeb2cf5b7127c0e880e5eacfd4574Eric Laurent if ((desc->flags & EFFECT_FLAG_NO_PROCESS_MASK) == EFFECT_FLAG_NO_PROCESS) { 11456dd0fd92d6cdeb2cf5b7127c0e880e5eacfd4574Eric Laurent return NO_ERROR; 11466dd0fd92d6cdeb2cf5b7127c0e880e5eacfd4574Eric Laurent } 11476dd0fd92d6cdeb2cf5b7127c0e880e5eacfd4574Eric Laurent 11484c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent audio_input_flags_t flags = mInput->flags; 11494c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent if (hasFastCapture() || (flags & AUDIO_INPUT_FLAG_FAST)) { 11504c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent if (flags & AUDIO_INPUT_FLAG_RAW) { 11514c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent ALOGW("checkEffectCompatibility_l(): effect %s on record thread %s in raw mode", 11524c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent desc->name, mThreadName); 11534c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent return BAD_VALUE; 11544c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent } 11554c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent if ((desc->flags & EFFECT_FLAG_HW_ACC_TUNNEL) == 0) { 11564c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent ALOGW("checkEffectCompatibility_l(): non HW effect %s on record thread %s in fast mode", 11574c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent desc->name, mThreadName); 11584c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent return BAD_VALUE; 11594c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent } 11604c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent } 11614c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent return NO_ERROR; 11624c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent} 11634c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent 11644c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent// checkEffectCompatibility_l() must be called with ThreadBase::mLock held 11654c415062ad1bb53e9af8f644d8215837262b79bbEric Laurentstatus_t AudioFlinger::PlaybackThread::checkEffectCompatibility_l( 11664c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent const effect_descriptor_t *desc, audio_session_t sessionId) 11674c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent{ 11684c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent // no preprocessing on playback threads 11694c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent if ((desc->flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_PRE_PROC) { 11704c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent ALOGW("checkEffectCompatibility_l(): pre processing effect %s created on playback" 11714c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent " thread %s", desc->name, mThreadName); 11724c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent return BAD_VALUE; 11734c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent } 11744c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent 11753e4de776665ff287cfd487ca4c7df87fbf73efa4Eric Laurent // always allow effects without processing load or latency 11763e4de776665ff287cfd487ca4c7df87fbf73efa4Eric Laurent if ((desc->flags & EFFECT_FLAG_NO_PROCESS_MASK) == EFFECT_FLAG_NO_PROCESS) { 11773e4de776665ff287cfd487ca4c7df87fbf73efa4Eric Laurent return NO_ERROR; 11783e4de776665ff287cfd487ca4c7df87fbf73efa4Eric Laurent } 11793e4de776665ff287cfd487ca4c7df87fbf73efa4Eric Laurent 11804c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent switch (mType) { 11814c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent case MIXER: { 11829aad48c31ee3557eddbcaf301539f7d19673f018Andy Hung#ifndef MULTICHANNEL_EFFECT_CHAIN 11834c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent // Reject any effect on mixer multichannel sinks. 11844c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent // TODO: fix both format and multichannel issues with effects. 11854c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent if (mChannelCount != FCC_2) { 11864c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent ALOGW("checkEffectCompatibility_l(): effect %s for multichannel(%d) on MIXER" 11874c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent " thread %s", desc->name, mChannelCount, mThreadName); 11884c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent return BAD_VALUE; 11894c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent } 11909aad48c31ee3557eddbcaf301539f7d19673f018Andy Hung#endif 11914c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent audio_output_flags_t flags = mOutput->flags; 11924c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent if (hasFastMixer() || (flags & AUDIO_OUTPUT_FLAG_FAST)) { 11934c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent if (sessionId == AUDIO_SESSION_OUTPUT_MIX) { 11944c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent // global effects are applied only to non fast tracks if they are SW 11954c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent if ((desc->flags & EFFECT_FLAG_HW_ACC_TUNNEL) == 0) { 11964c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent break; 11974c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent } 11984c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent } else if (sessionId == AUDIO_SESSION_OUTPUT_STAGE) { 11994c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent // only post processing on output stage session 12004c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent if ((desc->flags & EFFECT_FLAG_TYPE_MASK) != EFFECT_FLAG_TYPE_POST_PROC) { 12014c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent ALOGW("checkEffectCompatibility_l(): non post processing effect %s not allowed" 12024c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent " on output stage session", desc->name); 12034c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent return BAD_VALUE; 12044c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent } 12054c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent } else { 12064c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent // no restriction on effects applied on non fast tracks 12074c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent if ((hasAudioSession_l(sessionId) & ThreadBase::FAST_SESSION) == 0) { 12084c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent break; 12094c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent } 12104c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent } 12116dd0fd92d6cdeb2cf5b7127c0e880e5eacfd4574Eric Laurent 12124c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent if (flags & AUDIO_OUTPUT_FLAG_RAW) { 12134c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent ALOGW("checkEffectCompatibility_l(): effect %s on playback thread in raw mode", 12144c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent desc->name); 12154c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent return BAD_VALUE; 12164c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent } 12174c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent if ((desc->flags & EFFECT_FLAG_HW_ACC_TUNNEL) == 0) { 12184c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent ALOGW("checkEffectCompatibility_l(): non HW effect %s on playback thread" 12194c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent " in fast mode", desc->name); 12204c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent return BAD_VALUE; 12214c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent } 12224c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent } 12234c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent } break; 12244c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent case OFFLOAD: 1225773ee957aadbe86ee53ac96a108ce47f8e02b961Jean-Michel Trivi // nothing actionable on offload threads, if the effect: 1226773ee957aadbe86ee53ac96a108ce47f8e02b961Jean-Michel Trivi // - is offloadable: the effect can be created 1227773ee957aadbe86ee53ac96a108ce47f8e02b961Jean-Michel Trivi // - is NOT offloadable: the effect should still be created, but EffectHandle::enable() 1228773ee957aadbe86ee53ac96a108ce47f8e02b961Jean-Michel Trivi // will take care of invalidating the tracks of the thread 12294c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent break; 12304c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent case DIRECT: 12314c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent // Reject any effect on Direct output threads for now, since the format of 12324c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent // mSinkBuffer is not guaranteed to be compatible with effect processing (PCM 16 stereo). 12334c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent ALOGW("checkEffectCompatibility_l(): effect %s on DIRECT output thread %s", 12344c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent desc->name, mThreadName); 12354c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent return BAD_VALUE; 12364c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent case DUPLICATING: 12379aad48c31ee3557eddbcaf301539f7d19673f018Andy Hung#ifndef MULTICHANNEL_EFFECT_CHAIN 12384c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent // Reject any effect on mixer multichannel sinks. 12394c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent // TODO: fix both format and multichannel issues with effects. 12404c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent if (mChannelCount != FCC_2) { 12414c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent ALOGW("checkEffectCompatibility_l(): effect %s for multichannel(%d)" 12424c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent " on DUPLICATING thread %s", desc->name, mChannelCount, mThreadName); 12434c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent return BAD_VALUE; 12444c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent } 12459aad48c31ee3557eddbcaf301539f7d19673f018Andy Hung#endif 12464c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent if ((sessionId == AUDIO_SESSION_OUTPUT_STAGE) || (sessionId == AUDIO_SESSION_OUTPUT_MIX)) { 12474c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent ALOGW("checkEffectCompatibility_l(): global effect %s on DUPLICATING" 12484c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent " thread %s", desc->name, mThreadName); 12494c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent return BAD_VALUE; 12504c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent } 12514c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent if ((desc->flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_POST_PROC) { 12524c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent ALOGW("checkEffectCompatibility_l(): post processing effect %s on" 12534c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent " DUPLICATING thread %s", desc->name, mThreadName); 12544c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent return BAD_VALUE; 12554c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent } 12564c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent if ((desc->flags & EFFECT_FLAG_HW_ACC_TUNNEL) != 0) { 12574c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent ALOGW("checkEffectCompatibility_l(): HW tunneled effect %s on" 12584c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent " DUPLICATING thread %s", desc->name, mThreadName); 12594c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent return BAD_VALUE; 12604c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent } 12614c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent break; 12624c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent default: 12634c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent LOG_ALWAYS_FATAL("checkEffectCompatibility_l(): wrong thread type %d", mType); 12644c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent } 12654c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent 12664c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent return NO_ERROR; 12674c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent} 12684c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent 126981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// ThreadBase::createEffect_l() must be called with AudioFlinger::mLock held 127081784c37c61b09289654b979567a42bf73cd2b12Eric Laurentsp<AudioFlinger::EffectHandle> AudioFlinger::ThreadBase::createEffect_l( 127181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent const sp<AudioFlinger::Client>& client, 127281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent const sp<IEffectClient>& effectClient, 127381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent int32_t priority, 1274d848eb48c121c119e8ba7583efc75415fe102570Glenn Kasten audio_session_t sessionId, 127581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent effect_descriptor_t *desc, 127681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent int *enabled, 12770d5a2ed0a05a2bf337c68edb54f24c60e18032c1Eric Laurent status_t *status, 12780d5a2ed0a05a2bf337c68edb54f24c60e18032c1Eric Laurent bool pinned) 127981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 128081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent sp<EffectModule> effect; 128181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent sp<EffectHandle> handle; 128281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent status_t lStatus; 128381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent sp<EffectChain> chain; 128481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent bool chainCreated = false; 128581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent bool effectCreated = false; 128681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent bool effectRegistered = false; 12872247f7b84bf0ce3cc9c909ef987eedb086e3b4e8Mikhail Naganov audio_unique_id_t effectId = AUDIO_UNIQUE_ID_USE_UNSPECIFIED; 128881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 128981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent lStatus = initCheck(); 129081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (lStatus != NO_ERROR) { 129181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent ALOGW("createEffect_l() Audio driver not initialized."); 129281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent goto Exit; 129381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 129481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 129581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent ALOGV("createEffect_l() thread %p effect %s on session %d", this, desc->name, sessionId); 129681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 129781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent { // scope for mLock 129881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent Mutex::Autolock _l(mLock); 129981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 13004c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent lStatus = checkEffectCompatibility_l(desc, sessionId); 13014c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent if (lStatus != NO_ERROR) { 13024c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent goto Exit; 13034c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent } 13044c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent 130581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // check for existing effect chain with the requested audio session 130681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent chain = getEffectChain_l(sessionId); 130781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (chain == 0) { 130881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // create a new chain for this session 130981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent ALOGV("createEffect_l() new effect chain for session %d", sessionId); 131081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent chain = new EffectChain(this, sessionId); 131181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent addEffectChain_l(chain); 131281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent chain->setStrategy(getStrategyForSession_l(sessionId)); 131381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent chainCreated = true; 131481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } else { 131581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent effect = chain->getEffectFromDesc_l(desc); 131681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 131781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 131881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent ALOGV("createEffect_l() got effect %p on chain %p", effect.get(), chain.get()); 131981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 132081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (effect == 0) { 13212247f7b84bf0ce3cc9c909ef987eedb086e3b4e8Mikhail Naganov effectId = mAudioFlinger->nextUniqueId(AUDIO_UNIQUE_ID_USE_EFFECT); 132281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // Check CPU and memory usage 13232247f7b84bf0ce3cc9c909ef987eedb086e3b4e8Mikhail Naganov lStatus = AudioSystem::registerEffect( 13242247f7b84bf0ce3cc9c909ef987eedb086e3b4e8Mikhail Naganov desc, mId, chain->strategy(), sessionId, effectId); 132581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (lStatus != NO_ERROR) { 132681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent goto Exit; 132781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 132881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent effectRegistered = true; 132981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // create a new effect module if none present in the chain 13302247f7b84bf0ce3cc9c909ef987eedb086e3b4e8Mikhail Naganov lStatus = chain->createEffect_l(effect, this, desc, effectId, sessionId, pinned); 133181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (lStatus != NO_ERROR) { 133281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent goto Exit; 133381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 133481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent effectCreated = true; 133581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 133681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent effect->setDevice(mOutDevice); 133781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent effect->setDevice(mInDevice); 133881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent effect->setMode(mAudioFlinger->getMode()); 133981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent effect->setAudioSource(mAudioSource); 134081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 134181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // create effect handle and connect it to effect module 134281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent handle = new EffectHandle(effect, client, effectClient, priority); 1343e75da4004b2c814987aa2adf8a76190f92d99c65Glenn Kasten lStatus = handle->initCheck(); 1344e75da4004b2c814987aa2adf8a76190f92d99c65Glenn Kasten if (lStatus == OK) { 1345e75da4004b2c814987aa2adf8a76190f92d99c65Glenn Kasten lStatus = effect->addHandle(handle.get()); 1346e75da4004b2c814987aa2adf8a76190f92d99c65Glenn Kasten } 134781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (enabled != NULL) { 134881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent *enabled = (int)effect->isEnabled(); 134981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 135081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 135181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 135281784c37c61b09289654b979567a42bf73cd2b12Eric LaurentExit: 135381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (lStatus != NO_ERROR && lStatus != ALREADY_EXISTS) { 135481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent Mutex::Autolock _l(mLock); 135581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (effectCreated) { 135681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent chain->removeEffect_l(effect); 135781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 135881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (effectRegistered) { 13592247f7b84bf0ce3cc9c909ef987eedb086e3b4e8Mikhail Naganov AudioSystem::unregisterEffect(effectId); 136081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 136181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (chainCreated) { 136281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent removeEffectChain_l(chain); 136381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 13645ff7b0da6f51af96b530951c72fe06a711280282haobo // handle must be cleared by caller to avoid deadlock. 136581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 136681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 13679156ef3e11b68cc4b6d3cea77f1f63673855a6d1Glenn Kasten *status = lStatus; 136881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent return handle; 136981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 137081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 13710d5a2ed0a05a2bf337c68edb54f24c60e18032c1Eric Laurentvoid AudioFlinger::ThreadBase::disconnectEffectHandle(EffectHandle *handle, 13720d5a2ed0a05a2bf337c68edb54f24c60e18032c1Eric Laurent bool unpinIfLast) 13730d5a2ed0a05a2bf337c68edb54f24c60e18032c1Eric Laurent{ 13740d5a2ed0a05a2bf337c68edb54f24c60e18032c1Eric Laurent bool remove = false; 13750d5a2ed0a05a2bf337c68edb54f24c60e18032c1Eric Laurent sp<EffectModule> effect; 13760d5a2ed0a05a2bf337c68edb54f24c60e18032c1Eric Laurent { 13770d5a2ed0a05a2bf337c68edb54f24c60e18032c1Eric Laurent Mutex::Autolock _l(mLock); 13780d5a2ed0a05a2bf337c68edb54f24c60e18032c1Eric Laurent 13790d5a2ed0a05a2bf337c68edb54f24c60e18032c1Eric Laurent effect = handle->effect().promote(); 13800d5a2ed0a05a2bf337c68edb54f24c60e18032c1Eric Laurent if (effect == 0) { 13810d5a2ed0a05a2bf337c68edb54f24c60e18032c1Eric Laurent return; 13820d5a2ed0a05a2bf337c68edb54f24c60e18032c1Eric Laurent } 13830d5a2ed0a05a2bf337c68edb54f24c60e18032c1Eric Laurent // restore suspended effects if the disconnected handle was enabled and the last one. 13840d5a2ed0a05a2bf337c68edb54f24c60e18032c1Eric Laurent remove = (effect->removeHandle(handle) == 0) && (!effect->isPinned() || unpinIfLast); 13850d5a2ed0a05a2bf337c68edb54f24c60e18032c1Eric Laurent if (remove) { 13860d5a2ed0a05a2bf337c68edb54f24c60e18032c1Eric Laurent removeEffect_l(effect, true); 13870d5a2ed0a05a2bf337c68edb54f24c60e18032c1Eric Laurent } 13880d5a2ed0a05a2bf337c68edb54f24c60e18032c1Eric Laurent } 13890d5a2ed0a05a2bf337c68edb54f24c60e18032c1Eric Laurent if (remove) { 13900d5a2ed0a05a2bf337c68edb54f24c60e18032c1Eric Laurent mAudioFlinger->updateOrphanEffectChains(effect); 13910d5a2ed0a05a2bf337c68edb54f24c60e18032c1Eric Laurent AudioSystem::unregisterEffect(effect->id()); 13920d5a2ed0a05a2bf337c68edb54f24c60e18032c1Eric Laurent if (handle->enabled()) { 13930d5a2ed0a05a2bf337c68edb54f24c60e18032c1Eric Laurent checkSuspendOnEffectEnabled(effect, false, effect->sessionId()); 13940d5a2ed0a05a2bf337c68edb54f24c60e18032c1Eric Laurent } 13950d5a2ed0a05a2bf337c68edb54f24c60e18032c1Eric Laurent } 13960d5a2ed0a05a2bf337c68edb54f24c60e18032c1Eric Laurent} 13970d5a2ed0a05a2bf337c68edb54f24c60e18032c1Eric Laurent 1398d848eb48c121c119e8ba7583efc75415fe102570Glenn Kastensp<AudioFlinger::EffectModule> AudioFlinger::ThreadBase::getEffect(audio_session_t sessionId, 1399d848eb48c121c119e8ba7583efc75415fe102570Glenn Kasten int effectId) 140081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 140181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent Mutex::Autolock _l(mLock); 140281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent return getEffect_l(sessionId, effectId); 140381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 140481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 1405d848eb48c121c119e8ba7583efc75415fe102570Glenn Kastensp<AudioFlinger::EffectModule> AudioFlinger::ThreadBase::getEffect_l(audio_session_t sessionId, 1406d848eb48c121c119e8ba7583efc75415fe102570Glenn Kasten int effectId) 140781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 140881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent sp<EffectChain> chain = getEffectChain_l(sessionId); 140981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent return chain != 0 ? chain->getEffectFromId_l(effectId) : 0; 141081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 141181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 141281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// PlaybackThread::addEffect_l() must be called with AudioFlinger::mLock and 141381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// PlaybackThread::mLock held 141481784c37c61b09289654b979567a42bf73cd2b12Eric Laurentstatus_t AudioFlinger::ThreadBase::addEffect_l(const sp<EffectModule>& effect) 141581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 141681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // check for existing effect chain with the requested audio session 1417d848eb48c121c119e8ba7583efc75415fe102570Glenn Kasten audio_session_t sessionId = effect->sessionId(); 141881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent sp<EffectChain> chain = getEffectChain_l(sessionId); 141981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent bool chainCreated = false; 142081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 14215baf2af52cd186633b7173196c1e4a4cd3435f22Eric Laurent ALOGD_IF((mType == OFFLOAD) && !effect->isOffloadable(), 142249f36ba3b4624ddd3d7efa34c95128a73bda6208Glenn Kasten "addEffect_l() on offloaded thread %p: effect %s does not support offload flags %#x", 14235baf2af52cd186633b7173196c1e4a4cd3435f22Eric Laurent this, effect->desc().name, effect->desc().flags); 14245baf2af52cd186633b7173196c1e4a4cd3435f22Eric Laurent 142581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (chain == 0) { 142681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // create a new chain for this session 142781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent ALOGV("addEffect_l() new effect chain for session %d", sessionId); 142881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent chain = new EffectChain(this, sessionId); 142981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent addEffectChain_l(chain); 143081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent chain->setStrategy(getStrategyForSession_l(sessionId)); 143181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent chainCreated = true; 143281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 143381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent ALOGV("addEffect_l() %p chain %p effect %p", this, chain.get(), effect.get()); 143481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 143581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (chain->getEffectFromId_l(effect->id()) != 0) { 143681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent ALOGW("addEffect_l() %p effect %s already present in chain %p", 143781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent this, effect->desc().name, chain.get()); 143881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent return BAD_VALUE; 143981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 144081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 14415baf2af52cd186633b7173196c1e4a4cd3435f22Eric Laurent effect->setOffloaded(mType == OFFLOAD, mId); 14425baf2af52cd186633b7173196c1e4a4cd3435f22Eric Laurent 144381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent status_t status = chain->addEffect_l(effect); 144481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (status != NO_ERROR) { 144581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (chainCreated) { 144681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent removeEffectChain_l(chain); 144781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 144881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent return status; 144981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 145081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 145181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent effect->setDevice(mOutDevice); 145281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent effect->setDevice(mInDevice); 145381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent effect->setMode(mAudioFlinger->getMode()); 145481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent effect->setAudioSource(mAudioSource); 1455d8365c54d049aade9e02ccae722f311f846cad9aEric Laurent 145681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent return NO_ERROR; 145781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 145881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 14590d5a2ed0a05a2bf337c68edb54f24c60e18032c1Eric Laurentvoid AudioFlinger::ThreadBase::removeEffect_l(const sp<EffectModule>& effect, bool release) { 146081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 14610d5a2ed0a05a2bf337c68edb54f24c60e18032c1Eric Laurent ALOGV("%s %p effect %p", __FUNCTION__, this, effect.get()); 146281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent effect_descriptor_t desc = effect->desc(); 146381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if ((desc.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_AUXILIARY) { 146481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent detachAuxEffect_l(effect->id()); 146581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 146681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 146781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent sp<EffectChain> chain = effect->chain().promote(); 146881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (chain != 0) { 146981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // remove effect chain if removing last effect 14700d5a2ed0a05a2bf337c68edb54f24c60e18032c1Eric Laurent if (chain->removeEffect_l(effect, release) == 0) { 147181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent removeEffectChain_l(chain); 147281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 147381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } else { 147481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent ALOGW("removeEffect_l() %p cannot promote chain for effect %p", this, effect.get()); 147581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 147681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 147781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 147881784c37c61b09289654b979567a42bf73cd2b12Eric Laurentvoid AudioFlinger::ThreadBase::lockEffectChains_l( 147981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent Vector< sp<AudioFlinger::EffectChain> >& effectChains) 148081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 148181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent effectChains = mEffectChains; 148281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent for (size_t i = 0; i < mEffectChains.size(); i++) { 148381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mEffectChains[i]->lock(); 148481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 148581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 148681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 148781784c37c61b09289654b979567a42bf73cd2b12Eric Laurentvoid AudioFlinger::ThreadBase::unlockEffectChains( 148881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent const Vector< sp<AudioFlinger::EffectChain> >& effectChains) 148981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 149081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent for (size_t i = 0; i < effectChains.size(); i++) { 149181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent effectChains[i]->unlock(); 149281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 149381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 149481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 1495d848eb48c121c119e8ba7583efc75415fe102570Glenn Kastensp<AudioFlinger::EffectChain> AudioFlinger::ThreadBase::getEffectChain(audio_session_t sessionId) 149681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 149781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent Mutex::Autolock _l(mLock); 149881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent return getEffectChain_l(sessionId); 149981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 150081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 1501d848eb48c121c119e8ba7583efc75415fe102570Glenn Kastensp<AudioFlinger::EffectChain> AudioFlinger::ThreadBase::getEffectChain_l(audio_session_t sessionId) 1502d848eb48c121c119e8ba7583efc75415fe102570Glenn Kasten const 150381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 150481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent size_t size = mEffectChains.size(); 150581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent for (size_t i = 0; i < size; i++) { 150681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (mEffectChains[i]->sessionId() == sessionId) { 150781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent return mEffectChains[i]; 150881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 150981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 151081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent return 0; 151181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 151281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 151381784c37c61b09289654b979567a42bf73cd2b12Eric Laurentvoid AudioFlinger::ThreadBase::setMode(audio_mode_t mode) 151481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 151581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent Mutex::Autolock _l(mLock); 151681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent size_t size = mEffectChains.size(); 151781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent for (size_t i = 0; i < size; i++) { 151881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mEffectChains[i]->setMode_l(mode); 151981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 152081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 152181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 152283b8808faad1e91690c64d7007348be8d9ebde73Eric Laurentvoid AudioFlinger::ThreadBase::getAudioPortConfig(struct audio_port_config *config) 152383b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent{ 152483b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent config->type = AUDIO_PORT_TYPE_MIX; 152583b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent config->ext.mix.handle = mId; 152683b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent config->sample_rate = mSampleRate; 152783b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent config->format = mFormat; 152883b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent config->channel_mask = mChannelMask; 152983b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent config->config_mask = AUDIO_PORT_CONFIG_SAMPLE_RATE|AUDIO_PORT_CONFIG_CHANNEL_MASK| 153083b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent AUDIO_PORT_CONFIG_FORMAT; 153183b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent} 153283b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent 153372e3f39146fce4686bd96f11057c051bea376dfbEric Laurentvoid AudioFlinger::ThreadBase::systemReady() 153472e3f39146fce4686bd96f11057c051bea376dfbEric Laurent{ 153572e3f39146fce4686bd96f11057c051bea376dfbEric Laurent Mutex::Autolock _l(mLock); 153672e3f39146fce4686bd96f11057c051bea376dfbEric Laurent if (mSystemReady) { 153772e3f39146fce4686bd96f11057c051bea376dfbEric Laurent return; 153872e3f39146fce4686bd96f11057c051bea376dfbEric Laurent } 153972e3f39146fce4686bd96f11057c051bea376dfbEric Laurent mSystemReady = true; 154072e3f39146fce4686bd96f11057c051bea376dfbEric Laurent 154172e3f39146fce4686bd96f11057c051bea376dfbEric Laurent for (size_t i = 0; i < mPendingConfigEvents.size(); i++) { 154272e3f39146fce4686bd96f11057c051bea376dfbEric Laurent sendConfigEvent_l(mPendingConfigEvents.editItemAt(i)); 154372e3f39146fce4686bd96f11057c051bea376dfbEric Laurent } 154472e3f39146fce4686bd96f11057c051bea376dfbEric Laurent mPendingConfigEvents.clear(); 154572e3f39146fce4686bd96f11057c051bea376dfbEric Laurent} 154672e3f39146fce4686bd96f11057c051bea376dfbEric Laurent 1547dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hungtemplate <typename T> 1548dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hungssize_t AudioFlinger::ThreadBase::ActiveTracks<T>::add(const sp<T> &track) { 1549dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hung ssize_t index = mActiveTracks.indexOf(track); 1550dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hung if (index >= 0) { 1551dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hung ALOGW("ActiveTracks<T>::add track %p already there", track.get()); 1552dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hung return index; 1553dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hung } 15542c6c3bb76b2fa18ed3536331a1700250bd04c7ceAndy Hung logTrack("add", track); 1555dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hung mActiveTracksGeneration++; 1556dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hung mLatestActiveTrack = track; 1557dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hung ++mBatteryCounter[track->uid()].second; 1558069c2719e753732d5af9ba51e5fcc34342b0c9f2Kevin Rocard mHasChanged = true; 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 } 15692c6c3bb76b2fa18ed3536331a1700250bd04c7ceAndy Hung logTrack("remove", track); 1570dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hung mActiveTracksGeneration++; 1571dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hung --mBatteryCounter[track->uid()].second; 1572dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hung // mLatestActiveTrack is not cleared even if is the same as track. 1573069c2719e753732d5af9ba51e5fcc34342b0c9f2Kevin Rocard mHasChanged = true; 1574dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hung return index; 1575dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hung} 1576dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hung 1577dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hungtemplate <typename T> 1578dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hungvoid AudioFlinger::ThreadBase::ActiveTracks<T>::clear() { 1579dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hung for (const sp<T> &track : mActiveTracks) { 1580dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hung BatteryNotifier::getInstance().noteStopAudio(track->uid()); 15812c6c3bb76b2fa18ed3536331a1700250bd04c7ceAndy Hung logTrack("clear", track); 1582dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hung } 1583dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hung mLastActiveTracksGeneration = mActiveTracksGeneration; 1584069c2719e753732d5af9ba51e5fcc34342b0c9f2Kevin Rocard if (!mActiveTracks.empty()) { mHasChanged = true; } 1585dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hung mActiveTracks.clear(); 1586dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hung mLatestActiveTrack.clear(); 1587dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hung mBatteryCounter.clear(); 1588dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hung} 1589dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hung 1590dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hungtemplate <typename T> 1591dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hungvoid AudioFlinger::ThreadBase::ActiveTracks<T>::updatePowerState( 1592dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hung sp<ThreadBase> thread, bool force) { 1593dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hung // Updates ActiveTracks client uids to the thread wakelock. 1594dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hung if (mActiveTracksGeneration != mLastActiveTracksGeneration || force) { 1595dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hung thread->updateWakeLockUids_l(getWakeLockUids()); 1596dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hung mLastActiveTracksGeneration = mActiveTracksGeneration; 1597dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hung } 1598dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hung 1599dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hung // Updates BatteryNotifier uids 1600dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hung for (auto it = mBatteryCounter.begin(); it != mBatteryCounter.end();) { 1601dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hung const uid_t uid = it->first; 1602dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hung ssize_t &previous = it->second.first; 1603dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hung ssize_t ¤t = it->second.second; 1604dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hung if (current > 0) { 1605dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hung if (previous == 0) { 1606dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hung BatteryNotifier::getInstance().noteStartAudio(uid); 1607dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hung } 1608dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hung previous = current; 1609dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hung ++it; 1610dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hung } else if (current == 0) { 1611dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hung if (previous > 0) { 1612dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hung BatteryNotifier::getInstance().noteStopAudio(uid); 1613dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hung } 1614dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hung it = mBatteryCounter.erase(it); // std::map<> is stable on iterator erase. 1615dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hung } else /* (current < 0) */ { 1616dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hung LOG_ALWAYS_FATAL("negative battery count %zd", current); 1617dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hung } 1618dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hung } 1619dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hung} 162083b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent 16212c6c3bb76b2fa18ed3536331a1700250bd04c7ceAndy Hungtemplate <typename T> 1622069c2719e753732d5af9ba51e5fcc34342b0c9f2Kevin Rocardbool AudioFlinger::ThreadBase::ActiveTracks<T>::readAndClearHasChanged() { 1623069c2719e753732d5af9ba51e5fcc34342b0c9f2Kevin Rocard const bool hasChanged = mHasChanged; 1624069c2719e753732d5af9ba51e5fcc34342b0c9f2Kevin Rocard mHasChanged = false; 1625069c2719e753732d5af9ba51e5fcc34342b0c9f2Kevin Rocard return hasChanged; 1626069c2719e753732d5af9ba51e5fcc34342b0c9f2Kevin Rocard} 1627069c2719e753732d5af9ba51e5fcc34342b0c9f2Kevin Rocard 1628069c2719e753732d5af9ba51e5fcc34342b0c9f2Kevin Rocardtemplate <typename T> 16292c6c3bb76b2fa18ed3536331a1700250bd04c7ceAndy Hungvoid AudioFlinger::ThreadBase::ActiveTracks<T>::logTrack( 16302c6c3bb76b2fa18ed3536331a1700250bd04c7ceAndy Hung const char *funcName, const sp<T> &track) const { 16312c6c3bb76b2fa18ed3536331a1700250bd04c7ceAndy Hung if (mLocalLog != nullptr) { 16322c6c3bb76b2fa18ed3536331a1700250bd04c7ceAndy Hung String8 result; 16332c6c3bb76b2fa18ed3536331a1700250bd04c7ceAndy Hung track->appendDump(result, false /* active */); 16342c6c3bb76b2fa18ed3536331a1700250bd04c7ceAndy Hung mLocalLog->log("AT::%-10s(%p) %s", funcName, track.get(), result.string()); 16352c6c3bb76b2fa18ed3536331a1700250bd04c7ceAndy Hung } 16362c6c3bb76b2fa18ed3536331a1700250bd04c7ceAndy Hung} 16372c6c3bb76b2fa18ed3536331a1700250bd04c7ceAndy Hung 16386acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurentvoid AudioFlinger::ThreadBase::broadcast_l() 16396acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent{ 16406acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent // Thread could be blocked waiting for async 16416acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent // so signal it to handle state changes immediately 16426acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent // If threadLoop is currently unlocked a signal of mWaitWorkCV will 16436acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent // be lost so we also flag to prevent it blocking on mWaitWorkCV 16446acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent mSignalPending = true; 16456acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent mWaitWorkCV.broadcast(); 16466acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent} 16476acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 164881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// ---------------------------------------------------------------------------- 164981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// Playback 165081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// ---------------------------------------------------------------------------- 165181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 165281784c37c61b09289654b979567a42bf73cd2b12Eric LaurentAudioFlinger::PlaybackThread::PlaybackThread(const sp<AudioFlinger>& audioFlinger, 165381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent AudioStreamOut* output, 165481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent audio_io_handle_t id, 165581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent audio_devices_t device, 165672e3f39146fce4686bd96f11057c051bea376dfbEric Laurent type_t type, 1657e93cc03da360a1a0d2ad937c745ce8c8e8be81c2Eric Laurent bool systemReady) 165872e3f39146fce4686bd96f11057c051bea376dfbEric Laurent : ThreadBase(audioFlinger, id, device, AUDIO_DEVICE_NONE, type, systemReady), 16592098f2744cedf2dc3fa36f608aa965a34602e7c0Andy Hung mNormalFrameCount(0), mSinkBuffer(NULL), 16606146c08f0c3dd8b9e5788063aa433f304a810602Andy Hung mMixerBufferEnabled(AudioFlinger::kEnableExtendedPrecision), 166169aed5f0f4a3be3996d1e78a0473e1a72c1547daAndy Hung mMixerBuffer(NULL), 166269aed5f0f4a3be3996d1e78a0473e1a72c1547daAndy Hung mMixerBufferSize(0), 166369aed5f0f4a3be3996d1e78a0473e1a72c1547daAndy Hung mMixerBufferFormat(AUDIO_FORMAT_INVALID), 166469aed5f0f4a3be3996d1e78a0473e1a72c1547daAndy Hung mMixerBufferValid(false), 16656146c08f0c3dd8b9e5788063aa433f304a810602Andy Hung mEffectBufferEnabled(AudioFlinger::kEnableExtendedPrecision), 166698ef978df4e928f486d244c4d7f7ad9f13111e98Andy Hung mEffectBuffer(NULL), 166798ef978df4e928f486d244c4d7f7ad9f13111e98Andy Hung mEffectBufferSize(0), 166898ef978df4e928f486d244c4d7f7ad9f13111e98Andy Hung mEffectBufferFormat(AUDIO_FORMAT_INVALID), 166998ef978df4e928f486d244c4d7f7ad9f13111e98Andy Hung mEffectBufferValid(false), 1670c1fac191069774c7bfcb062edbb821ea56e7dbc0Glenn Kasten mSuspended(0), mBytesWritten(0), 1671c54b1ffc92b8ad27608a8af21033d7cab33cb3a0Andy Hung mFramesWritten(0), 1672238fa3deff26d7e4d9e81bd0a88c936f16226c4eAndy Hung mSuspendedFrames(0), 16732c6c3bb76b2fa18ed3536331a1700250bd04c7ceAndy Hung mActiveTracks(&this->mLocalLog), 167481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // mStreamTypes[] initialized in constructor body 16751bc088a918d7038603230637d640941953b314d4Andy Hung mTracks(type == MIXER), 167681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mOutput(output), 167769488c4ef115c9de52c85f4fcae27c7774720298Andy Hung mLastWriteTime(-1), mNumWrites(0), mNumDelayedWrites(0), mInWrite(false), 167881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mMixerStatus(MIXER_IDLE), 167981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mMixerStatusIgnoringFastTracks(MIXER_IDLE), 1680ad9cb8b88e4f8face23f01d8dc89fa769dacb50fEric Laurent mStandbyDelayNs(AudioFlinger::mStandbyTimeInNsecs), 1681bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent mBytesRemaining(0), 1682bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent mCurrentWriteLength(0), 1683bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent mUseAsyncWrite(false), 16843b4529e03c5fc7a44c22f9091ad15a269bfca3a8Eric Laurent mWriteAckSequence(0), 16853b4529e03c5fc7a44c22f9091ad15a269bfca3a8Eric Laurent mDrainSequence(0), 168681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mScreenState(AudioFlinger::mScreenState), 168781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // index 0 is reserved for normal mixer's submix 1688dc2c50bad491d2c0c8a2efc0e24491076701c63cGlenn Kasten mFastTrackAvailMask(((1 << FastMixerState::sMaxFastTracks) - 1) & ~1), 16897c29ec95f494d241faa07d0d70579729520e3114Eric Laurent mHwSupportsPause(false), mHwPaused(false), mFlushPending(false), 16907c29ec95f494d241faa07d0d70579729520e3114Eric Laurent mLeftVolFloat(-1.0), mRightVolFloat(-1.0) 169181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 1692d7dca050c630bddbd73a6623271b34b4290460eeGlenn Kasten snprintf(mThreadName, kThreadNameLength, "AudioOut_%X", id); 1693d7dca050c630bddbd73a6623271b34b4290460eeGlenn Kasten mNBLogWriter = audioFlinger->newWriter_l(kLogSize, mThreadName); 169481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 169581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // Assumes constructor is called by AudioFlinger with it's mLock held, but 169681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // it would be safer to explicitly pass initial masterVolume/masterMute as 169781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // parameter. 169881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // 169981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // If the HAL we are using has support for master volume or master mute, 170081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // then do not attenuate or mute during mixing (just leave the volume at 1.0 170181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // and the mute set to false). 170281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mMasterVolume = audioFlinger->masterVolume_l(); 170381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mMasterMute = audioFlinger->masterMute_l(); 170481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (mOutput && mOutput->audioHwDev) { 170581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (mOutput->audioHwDev->canSetMasterVolume()) { 170681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mMasterVolume = 1.0; 170781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 170881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 170981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (mOutput->audioHwDev->canSetMasterMute()) { 171081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mMasterMute = false; 171181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 171281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 171381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 1714deca2ae0a7cf8bc54ff3f30b7dc39bbc78b94c0dGlenn Kasten readOutputParameters_l(); 171581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 1716223fd5c9738e9665e495904d37d4632414b68c1eEric Laurent // ++ operator does not compile 171798e38191c37d3e324b34a6aafeef8e43366003efEric Laurent for (audio_stream_type_t stream = AUDIO_STREAM_MIN; stream < AUDIO_STREAM_FOR_POLICY_CNT; 171881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent stream = (audio_stream_type_t) (stream + 1)) { 171998e38191c37d3e324b34a6aafeef8e43366003efEric Laurent mStreamTypes[stream].volume = 0.0f; 172081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mStreamTypes[stream].mute = mAudioFlinger->streamMute_l(stream); 172181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 172298e38191c37d3e324b34a6aafeef8e43366003efEric Laurent // Audio patch volume is always max 172398e38191c37d3e324b34a6aafeef8e43366003efEric Laurent mStreamTypes[AUDIO_STREAM_PATCH].volume = 1.0f; 172498e38191c37d3e324b34a6aafeef8e43366003efEric Laurent mStreamTypes[AUDIO_STREAM_PATCH].mute = false; 172581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 172681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 172781784c37c61b09289654b979567a42bf73cd2b12Eric LaurentAudioFlinger::PlaybackThread::~PlaybackThread() 172881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 17299e58b552f51b00b3b674102876bd6c77ef3da806Glenn Kasten mAudioFlinger->unregisterWriter(mNBLogWriter); 1730010a1a1a552cdaad362cea8a0333b8906402dbcbAndy Hung free(mSinkBuffer); 173169aed5f0f4a3be3996d1e78a0473e1a72c1547daAndy Hung free(mMixerBuffer); 173298ef978df4e928f486d244c4d7f7ad9f13111e98Andy Hung free(mEffectBuffer); 173381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 173481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 173581784c37c61b09289654b979567a42bf73cd2b12Eric Laurentvoid AudioFlinger::PlaybackThread::dump(int fd, const Vector<String16>& args) 173681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 173781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent dumpInternals(fd, args); 173881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent dumpTracks(fd, args); 173981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent dumpEffectChains(fd, args); 1740293558ad1977e24e65f7ba78f47382d33fc77d64Andy Hung dprintf(fd, " Local log:\n"); 1741293558ad1977e24e65f7ba78f47382d33fc77d64Andy Hung mLocalLog.dump(fd, " " /* prefix */, 40 /* lines */); 174281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 174381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 17440f11b51a57bc9062c4fe8af73747319cedabc5d6Glenn Kastenvoid AudioFlinger::PlaybackThread::dumpTracks(int fd, const Vector<String16>& args __unused) 174581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 174681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent String8 result; 174781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 1748b220884bf3129253cc5bc8d030bc475411ea4911Marco Nelissen result.appendFormat(" Stream volumes in dB: "); 174981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent for (int i = 0; i < AUDIO_STREAM_CNT; ++i) { 175081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent const stream_type_t *st = &mStreamTypes[i]; 175181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (i > 0) { 175281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent result.appendFormat(", "); 175381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 175481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent result.appendFormat("%d:%.2g", i, 20.0 * log10(st->volume)); 175581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (st->mute) { 175681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent result.append("M"); 175781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 175881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 175981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent result.append("\n"); 176081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent write(fd, result.string(), result.length()); 176181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent result.clear(); 176281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 1763b220884bf3129253cc5bc8d030bc475411ea4911Marco Nelissen // These values are "raw"; they will wrap around. See prepareTracks_l() for a better way. 1764b220884bf3129253cc5bc8d030bc475411ea4911Marco Nelissen FastTrackUnderruns underruns = getFastTrackUnderruns(0); 176587cebadd48710e42474756fc3513df678de045ceElliott Hughes dprintf(fd, " Normal mixer raw underrun counters: partial=%u empty=%u\n", 1766b220884bf3129253cc5bc8d030bc475411ea4911Marco Nelissen underruns.mBitFields.mPartial, underruns.mBitFields.mEmpty); 1767b220884bf3129253cc5bc8d030bc475411ea4911Marco Nelissen 1768b220884bf3129253cc5bc8d030bc475411ea4911Marco Nelissen size_t numtracks = mTracks.size(); 1769b220884bf3129253cc5bc8d030bc475411ea4911Marco Nelissen size_t numactive = mActiveTracks.size(); 1770c42e9b462661673dff480ee71757a58b0f806370Glenn Kasten dprintf(fd, " %zu Tracks", numtracks); 1771b220884bf3129253cc5bc8d030bc475411ea4911Marco Nelissen size_t numactiveseen = 0; 17722c6c3bb76b2fa18ed3536331a1700250bd04c7ceAndy Hung const char *prefix = " "; 1773b220884bf3129253cc5bc8d030bc475411ea4911Marco Nelissen if (numtracks) { 1774c42e9b462661673dff480ee71757a58b0f806370Glenn Kasten dprintf(fd, " of which %zu are active\n", numactive); 17752c6c3bb76b2fa18ed3536331a1700250bd04c7ceAndy Hung result.append(prefix); 1776b220884bf3129253cc5bc8d030bc475411ea4911Marco Nelissen Track::appendDumpHeader(result); 1777b220884bf3129253cc5bc8d030bc475411ea4911Marco Nelissen for (size_t i = 0; i < numtracks; ++i) { 1778b220884bf3129253cc5bc8d030bc475411ea4911Marco Nelissen sp<Track> track = mTracks[i]; 1779b220884bf3129253cc5bc8d030bc475411ea4911Marco Nelissen if (track != 0) { 1780b220884bf3129253cc5bc8d030bc475411ea4911Marco Nelissen bool active = mActiveTracks.indexOf(track) >= 0; 1781b220884bf3129253cc5bc8d030bc475411ea4911Marco Nelissen if (active) { 1782b220884bf3129253cc5bc8d030bc475411ea4911Marco Nelissen numactiveseen++; 1783b220884bf3129253cc5bc8d030bc475411ea4911Marco Nelissen } 17842c6c3bb76b2fa18ed3536331a1700250bd04c7ceAndy Hung result.append(prefix); 17852c6c3bb76b2fa18ed3536331a1700250bd04c7ceAndy Hung track->appendDump(result, active); 1786b220884bf3129253cc5bc8d030bc475411ea4911Marco Nelissen } 178781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 1788b220884bf3129253cc5bc8d030bc475411ea4911Marco Nelissen } else { 1789b220884bf3129253cc5bc8d030bc475411ea4911Marco Nelissen result.append("\n"); 179081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 1791b220884bf3129253cc5bc8d030bc475411ea4911Marco Nelissen if (numactiveseen != numactive) { 1792b220884bf3129253cc5bc8d030bc475411ea4911Marco Nelissen // some tracks in the active list were not in the tracks list 17932c6c3bb76b2fa18ed3536331a1700250bd04c7ceAndy Hung result.append(" The following tracks are in the active list but" 1794b220884bf3129253cc5bc8d030bc475411ea4911Marco Nelissen " not in the track list\n"); 17952c6c3bb76b2fa18ed3536331a1700250bd04c7ceAndy Hung result.append(prefix); 1796b220884bf3129253cc5bc8d030bc475411ea4911Marco Nelissen Track::appendDumpHeader(result); 1797b220884bf3129253cc5bc8d030bc475411ea4911Marco Nelissen for (size_t i = 0; i < numactive; ++i) { 1798dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hung sp<Track> track = mActiveTracks[i]; 1799dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hung if (mTracks.indexOf(track) < 0) { 18002c6c3bb76b2fa18ed3536331a1700250bd04c7ceAndy Hung result.append(prefix); 18012c6c3bb76b2fa18ed3536331a1700250bd04c7ceAndy Hung track->appendDump(result, true /* active */); 1802b220884bf3129253cc5bc8d030bc475411ea4911Marco Nelissen } 180381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 180481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 1805b220884bf3129253cc5bc8d030bc475411ea4911Marco Nelissen 180681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent write(fd, result.string(), result.size()); 180781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 180881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 180981784c37c61b09289654b979567a42bf73cd2b12Eric Laurentvoid AudioFlinger::PlaybackThread::dumpInternals(int fd, const Vector<String16>& args) 181081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 181144182c206f7c5584ef2cf504da6be98fab665dbfGlenn Kasten dumpBase(fd, args); 181244182c206f7c5584ef2cf504da6be98fab665dbfGlenn Kasten 181387cebadd48710e42474756fc3513df678de045ceElliott Hughes dprintf(fd, " Normal frame count: %zu\n", mNormalFrameCount); 1814c42e9b462661673dff480ee71757a58b0f806370Glenn Kasten dprintf(fd, " Last write occurred (msecs): %llu\n", 1815c42e9b462661673dff480ee71757a58b0f806370Glenn Kasten (unsigned long long) ns2ms(systemTime() - mLastWriteTime)); 181687cebadd48710e42474756fc3513df678de045ceElliott Hughes dprintf(fd, " Total writes: %d\n", mNumWrites); 181787cebadd48710e42474756fc3513df678de045ceElliott Hughes dprintf(fd, " Delayed writes: %d\n", mNumDelayedWrites); 181887cebadd48710e42474756fc3513df678de045ceElliott Hughes dprintf(fd, " Blocked in write: %s\n", mInWrite ? "yes" : "no"); 181987cebadd48710e42474756fc3513df678de045ceElliott Hughes dprintf(fd, " Suspend count: %d\n", mSuspended); 182087cebadd48710e42474756fc3513df678de045ceElliott Hughes dprintf(fd, " Sink buffer : %p\n", mSinkBuffer); 182187cebadd48710e42474756fc3513df678de045ceElliott Hughes dprintf(fd, " Mixer buffer: %p\n", mMixerBuffer); 182287cebadd48710e42474756fc3513df678de045ceElliott Hughes dprintf(fd, " Effect buffer: %p\n", mEffectBuffer); 182387cebadd48710e42474756fc3513df678de045ceElliott Hughes dprintf(fd, " Fast track availMask=%#x\n", mFastTrackAvailMask); 182442537be61479e59c4718e1304364551c1454f63cEric Laurent dprintf(fd, " Standby delay ns=%lld\n", (long long)mStandbyDelayNs); 182597b7b75b6a31330e213bdb96ccc60916218ad903Glenn Kasten AudioStreamOut *output = mOutput; 182697b7b75b6a31330e213bdb96ccc60916218ad903Glenn Kasten audio_output_flags_t flags = output != NULL ? output->flags : AUDIO_OUTPUT_FLAG_NONE; 1827913d06c099bd689375483a839e11057ccf284d1cMikhail Naganov dprintf(fd, " AudioStreamOut: %p flags %#x (%s)\n", 1828913d06c099bd689375483a839e11057ccf284d1cMikhail Naganov output, flags, outputFlagsToString(flags).c_str()); 1829b54c854d1ef1bb66e093c94099f915178eac570eAndy Hung dprintf(fd, " Frames written: %lld\n", (long long)mFramesWritten); 1830b54c854d1ef1bb66e093c94099f915178eac570eAndy Hung dprintf(fd, " Suspended frames: %lld\n", (long long)mSuspendedFrames); 1831b54c854d1ef1bb66e093c94099f915178eac570eAndy Hung if (mPipeSink.get() != nullptr) { 1832b54c854d1ef1bb66e093c94099f915178eac570eAndy Hung dprintf(fd, " PipeSink frames written: %lld\n", (long long)mPipeSink->framesWritten()); 1833b54c854d1ef1bb66e093c94099f915178eac570eAndy Hung } 1834b54c854d1ef1bb66e093c94099f915178eac570eAndy Hung if (output != nullptr) { 1835b54c854d1ef1bb66e093c94099f915178eac570eAndy Hung dprintf(fd, " Hal stream dump:\n"); 1836b54c854d1ef1bb66e093c94099f915178eac570eAndy Hung (void)output->stream->dump(fd); 1837b54c854d1ef1bb66e093c94099f915178eac570eAndy Hung } 183881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 183981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 184081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// Thread virtuals 184181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 184281784c37c61b09289654b979567a42bf73cd2b12Eric Laurentvoid AudioFlinger::PlaybackThread::onFirstRef() 184381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 1844d7dca050c630bddbd73a6623271b34b4290460eeGlenn Kasten run(mThreadName, ANDROID_PRIORITY_URGENT_AUDIO); 184581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 184681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 184781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// ThreadBase virtuals 184881784c37c61b09289654b979567a42bf73cd2b12Eric Laurentvoid AudioFlinger::PlaybackThread::preExit() 184981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 185081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent ALOGV(" preExit()"); 1851ad9c7e47d26bbeb2f3be96b3ad6988a6023a1021Mikhail Naganov // FIXME this is using hard-coded strings but in the future, this functionality will be 1852ad9c7e47d26bbeb2f3be96b3ad6988a6023a1021Mikhail Naganov // converted to use audio HAL extensions required to support tunneling 1853ad9c7e47d26bbeb2f3be96b3ad6988a6023a1021Mikhail Naganov status_t result = mOutput->stream->setParameters(String8("exiting=1")); 1854ad9c7e47d26bbeb2f3be96b3ad6988a6023a1021Mikhail Naganov ALOGE_IF(result != OK, "Error when setting parameters on exit: %d", result); 185581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 185681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 185781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// PlaybackThread::createTrack_l() must be called with AudioFlinger::mLock held 185881784c37c61b09289654b979567a42bf73cd2b12Eric Laurentsp<AudioFlinger::PlaybackThread::Track> AudioFlinger::PlaybackThread::createTrack_l( 185981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent const sp<AudioFlinger::Client>& client, 186081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent audio_stream_type_t streamType, 18611f564acca544826daaf7dca44e39cec6016b82fdKevin Rocard const audio_attributes_t& attr, 186221da647792c0b78ab3943be0f32066015d5e8c34Eric Laurent uint32_t *pSampleRate, 186381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent audio_format_t format, 186481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent audio_channel_mask_t channelMask, 186574935e44734c1ec235c2b6677db3e0dbefa5ddb8Glenn Kasten size_t *pFrameCount, 186621da647792c0b78ab3943be0f32066015d5e8c34Eric Laurent size_t *pNotificationFrameCount, 186721da647792c0b78ab3943be0f32066015d5e8c34Eric Laurent uint32_t notificationsPerBuffer, 186821da647792c0b78ab3943be0f32066015d5e8c34Eric Laurent float speed, 186981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent const sp<IMemory>& sharedBuffer, 1870d848eb48c121c119e8ba7583efc75415fe102570Glenn Kasten audio_session_t sessionId, 1871050677873c10d4da308ac222f8533c96cca3207eEric Laurent audio_output_flags_t *flags, 187281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent pid_t tid, 18731f12a8ad958344c50733b948628ffa06db9c5bc6Andy Hung uid_t uid, 187420b9ef0b55c9150ae11057ab997ae61be2d496efEric Laurent status_t *status, 187520b9ef0b55c9150ae11057ab997ae61be2d496efEric Laurent audio_port_handle_t portId) 187681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 187774935e44734c1ec235c2b6677db3e0dbefa5ddb8Glenn Kasten size_t frameCount = *pFrameCount; 187821da647792c0b78ab3943be0f32066015d5e8c34Eric Laurent size_t notificationFrameCount = *pNotificationFrameCount; 187981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent sp<Track> track; 188081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent status_t lStatus; 1881050677873c10d4da308ac222f8533c96cca3207eEric Laurent audio_output_flags_t outputFlags = mOutput->flags; 188221da647792c0b78ab3943be0f32066015d5e8c34Eric Laurent audio_output_flags_t requestedFlags = *flags; 188321da647792c0b78ab3943be0f32066015d5e8c34Eric Laurent 188421da647792c0b78ab3943be0f32066015d5e8c34Eric Laurent if (*pSampleRate == 0) { 188521da647792c0b78ab3943be0f32066015d5e8c34Eric Laurent *pSampleRate = mSampleRate; 188621da647792c0b78ab3943be0f32066015d5e8c34Eric Laurent } 188721da647792c0b78ab3943be0f32066015d5e8c34Eric Laurent uint32_t sampleRate = *pSampleRate; 1888050677873c10d4da308ac222f8533c96cca3207eEric Laurent 1889050677873c10d4da308ac222f8533c96cca3207eEric Laurent // special case for FAST flag considered OK if fast mixer is present 1890050677873c10d4da308ac222f8533c96cca3207eEric Laurent if (hasFastMixer()) { 1891050677873c10d4da308ac222f8533c96cca3207eEric Laurent outputFlags = (audio_output_flags_t)(outputFlags | AUDIO_OUTPUT_FLAG_FAST); 1892050677873c10d4da308ac222f8533c96cca3207eEric Laurent } 1893050677873c10d4da308ac222f8533c96cca3207eEric Laurent 1894050677873c10d4da308ac222f8533c96cca3207eEric Laurent // Check if requested flags are compatible with output stream flags 1895050677873c10d4da308ac222f8533c96cca3207eEric Laurent if ((*flags & outputFlags) != *flags) { 1896050677873c10d4da308ac222f8533c96cca3207eEric Laurent ALOGW("createTrack_l(): mismatch between requested flags (%08x) and output flags (%08x)", 1897050677873c10d4da308ac222f8533c96cca3207eEric Laurent *flags, outputFlags); 1898050677873c10d4da308ac222f8533c96cca3207eEric Laurent *flags = (audio_output_flags_t)(*flags & outputFlags); 1899050677873c10d4da308ac222f8533c96cca3207eEric Laurent } 190081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 190181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // client expresses a preference for FAST, but we get the final say 1902050677873c10d4da308ac222f8533c96cca3207eEric Laurent if (*flags & AUDIO_OUTPUT_FLAG_FAST) { 190381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if ( 190481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // PCM data 190581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent audio_is_linear_pcm(format) && 19061f439e1cf16a29347288ba9ddd06c0b6d086a145Andy Hung // TODO: extract as a data library function that checks that a computationally 19071f439e1cf16a29347288ba9ddd06c0b6d086a145Andy Hung // expensive downmixer is not required: isFastOutputChannelConversion() 19089a59276fb465e492138e0576523b54079671e8f4Andy Hung (channelMask == mChannelMask || 19091f439e1cf16a29347288ba9ddd06c0b6d086a145Andy Hung mChannelMask != AUDIO_CHANNEL_OUT_STEREO || 19101f439e1cf16a29347288ba9ddd06c0b6d086a145Andy Hung (channelMask == AUDIO_CHANNEL_OUT_MONO 19111f439e1cf16a29347288ba9ddd06c0b6d086a145Andy Hung /* && mChannelMask == AUDIO_CHANNEL_OUT_STEREO */)) && 191281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // hardware sample rate 191381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent (sampleRate == mSampleRate) && 191481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // normal mixer has an associated fast mixer 191581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent hasFastMixer() && 191681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // there are sufficient fast track slots available 191781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent (mFastTrackAvailMask != 0) 191881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // FIXME test that MixerThread for this fast track has a capable output HAL 191981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // FIXME add a permission test also? 192081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent ) { 1921e0a269a5f75956efdf78a9cacaefc428b352730cAndy Hung // static tracks can have any nonzero framecount, streaming tracks check against minimum. 1922e0a269a5f75956efdf78a9cacaefc428b352730cAndy Hung if (sharedBuffer == 0) { 19230349009fd19f89f8414c428f6b71b369f7546085Glenn Kasten // read the fast track multiplier property the first time it is needed 19240349009fd19f89f8414c428f6b71b369f7546085Glenn Kasten int ok = pthread_once(&sFastTrackMultiplierOnce, sFastTrackMultiplierInit); 19250349009fd19f89f8414c428f6b71b369f7546085Glenn Kasten if (ok != 0) { 19260349009fd19f89f8414c428f6b71b369f7546085Glenn Kasten ALOGE("%s pthread_once failed: %d", __func__, ok); 19270349009fd19f89f8414c428f6b71b369f7546085Glenn Kasten } 1928e0a269a5f75956efdf78a9cacaefc428b352730cAndy Hung frameCount = max(frameCount, mFrameCount * sFastTrackMultiplier); // incl framecount 0 192981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 19304c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent 19314c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent // check compatibility with audio effects. 19324c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent { // scope for mLock 19334c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent Mutex::Autolock _l(mLock); 1934d3bb0adfe40e60bb94e9a87e8d5bffb4ea6863b0Andy Hung for (audio_session_t session : { 1935d3bb0adfe40e60bb94e9a87e8d5bffb4ea6863b0Andy Hung AUDIO_SESSION_OUTPUT_STAGE, 1936d3bb0adfe40e60bb94e9a87e8d5bffb4ea6863b0Andy Hung AUDIO_SESSION_OUTPUT_MIX, 1937d3bb0adfe40e60bb94e9a87e8d5bffb4ea6863b0Andy Hung sessionId, 1938d3bb0adfe40e60bb94e9a87e8d5bffb4ea6863b0Andy Hung }) { 1939d3bb0adfe40e60bb94e9a87e8d5bffb4ea6863b0Andy Hung sp<EffectChain> chain = getEffectChain_l(session); 1940d3bb0adfe40e60bb94e9a87e8d5bffb4ea6863b0Andy Hung if (chain.get() != nullptr) { 1941d3bb0adfe40e60bb94e9a87e8d5bffb4ea6863b0Andy Hung audio_output_flags_t old = *flags; 1942d3bb0adfe40e60bb94e9a87e8d5bffb4ea6863b0Andy Hung chain->checkOutputFlagCompatibility(flags); 1943d3bb0adfe40e60bb94e9a87e8d5bffb4ea6863b0Andy Hung if (old != *flags) { 1944d3bb0adfe40e60bb94e9a87e8d5bffb4ea6863b0Andy Hung ALOGV("AUDIO_OUTPUT_FLAGS denied by effect, session=%d old=%#x new=%#x", 1945d3bb0adfe40e60bb94e9a87e8d5bffb4ea6863b0Andy Hung (int)session, (int)old, (int)*flags); 1946d3bb0adfe40e60bb94e9a87e8d5bffb4ea6863b0Andy Hung } 19474c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent } 19484c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent } 19494c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent } 1950122f7e793fe6fb8904634cc6d2e35ac4b014ea72Eric Laurent ALOGV_IF((*flags & AUDIO_OUTPUT_FLAG_FAST) != 0, 19514c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent "AUDIO_OUTPUT_FLAG_FAST accepted: frameCount=%zu mFrameCount=%zu", 19524c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent frameCount, mFrameCount); 195381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } else { 1954c42e9b462661673dff480ee71757a58b0f806370Glenn Kasten ALOGV("AUDIO_OUTPUT_FLAG_FAST denied: sharedBuffer=%p frameCount=%zu " 1955c42e9b462661673dff480ee71757a58b0f806370Glenn Kasten "mFrameCount=%zu format=%#x mFormat=%#x isLinear=%d channelMask=%#x " 19566146c08f0c3dd8b9e5788063aa433f304a810602Andy Hung "sampleRate=%u mSampleRate=%u " 195781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent "hasFastMixer=%d tid=%d fastTrackAvailMask=%#x", 1958d79072e9dff59f767cce2cda1caab80ce5a0815bGlenn Kasten sharedBuffer.get(), frameCount, mFrameCount, format, mFormat, 195981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent audio_is_linear_pcm(format), 196081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent channelMask, sampleRate, mSampleRate, hasFastMixer(), tid, mFastTrackAvailMask); 19614c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent *flags = (audio_output_flags_t)(*flags & ~AUDIO_OUTPUT_FLAG_FAST); 19620e48d25606c82def035ad10a5b3923767a765cddAndy Hung } 19630e48d25606c82def035ad10a5b3923767a765cddAndy Hung } 196421da647792c0b78ab3943be0f32066015d5e8c34Eric Laurent 196521da647792c0b78ab3943be0f32066015d5e8c34Eric Laurent if (!audio_has_proportional_frames(format)) { 196621da647792c0b78ab3943be0f32066015d5e8c34Eric Laurent if (sharedBuffer != 0) { 196721da647792c0b78ab3943be0f32066015d5e8c34Eric Laurent // Same comment as below about ignoring frameCount parameter for set() 196821da647792c0b78ab3943be0f32066015d5e8c34Eric Laurent frameCount = sharedBuffer->size(); 196921da647792c0b78ab3943be0f32066015d5e8c34Eric Laurent } else if (frameCount == 0) { 197021da647792c0b78ab3943be0f32066015d5e8c34Eric Laurent frameCount = mNormalFrameCount; 197121da647792c0b78ab3943be0f32066015d5e8c34Eric Laurent } 197221da647792c0b78ab3943be0f32066015d5e8c34Eric Laurent if (notificationFrameCount != frameCount) { 197321da647792c0b78ab3943be0f32066015d5e8c34Eric Laurent notificationFrameCount = frameCount; 197421da647792c0b78ab3943be0f32066015d5e8c34Eric Laurent } 197521da647792c0b78ab3943be0f32066015d5e8c34Eric Laurent } else if (sharedBuffer != 0) { 197621da647792c0b78ab3943be0f32066015d5e8c34Eric Laurent // FIXME: Ensure client side memory buffers need 197721da647792c0b78ab3943be0f32066015d5e8c34Eric Laurent // not have additional alignment beyond sample 197821da647792c0b78ab3943be0f32066015d5e8c34Eric Laurent // (e.g. 16 bit stereo accessed as 32 bit frame). 197921da647792c0b78ab3943be0f32066015d5e8c34Eric Laurent size_t alignment = audio_bytes_per_sample(format); 198021da647792c0b78ab3943be0f32066015d5e8c34Eric Laurent if (alignment & 1) { 198121da647792c0b78ab3943be0f32066015d5e8c34Eric Laurent // for AUDIO_FORMAT_PCM_24_BIT_PACKED (not exposed through Java). 198221da647792c0b78ab3943be0f32066015d5e8c34Eric Laurent alignment = 1; 198321da647792c0b78ab3943be0f32066015d5e8c34Eric Laurent } 198421da647792c0b78ab3943be0f32066015d5e8c34Eric Laurent uint32_t channelCount = audio_channel_count_from_out_mask(channelMask); 198521da647792c0b78ab3943be0f32066015d5e8c34Eric Laurent size_t frameSize = channelCount * audio_bytes_per_sample(format); 198621da647792c0b78ab3943be0f32066015d5e8c34Eric Laurent if (channelCount > 1) { 198721da647792c0b78ab3943be0f32066015d5e8c34Eric Laurent // More than 2 channels does not require stronger alignment than stereo 198821da647792c0b78ab3943be0f32066015d5e8c34Eric Laurent alignment <<= 1; 198921da647792c0b78ab3943be0f32066015d5e8c34Eric Laurent } 199021da647792c0b78ab3943be0f32066015d5e8c34Eric Laurent if (((uintptr_t)sharedBuffer->pointer() & (alignment - 1)) != 0) { 199121da647792c0b78ab3943be0f32066015d5e8c34Eric Laurent ALOGE("Invalid buffer alignment: address %p, channel count %u", 199221da647792c0b78ab3943be0f32066015d5e8c34Eric Laurent sharedBuffer->pointer(), channelCount); 199321da647792c0b78ab3943be0f32066015d5e8c34Eric Laurent lStatus = BAD_VALUE; 19941dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov goto Exit; 19951dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov } 199621da647792c0b78ab3943be0f32066015d5e8c34Eric Laurent 199721da647792c0b78ab3943be0f32066015d5e8c34Eric Laurent // When initializing a shared buffer AudioTrack via constructors, 199821da647792c0b78ab3943be0f32066015d5e8c34Eric Laurent // there's no frameCount parameter. 199921da647792c0b78ab3943be0f32066015d5e8c34Eric Laurent // But when initializing a shared buffer AudioTrack via set(), 200021da647792c0b78ab3943be0f32066015d5e8c34Eric Laurent // there _is_ a frameCount parameter. We silently ignore it. 200121da647792c0b78ab3943be0f32066015d5e8c34Eric Laurent frameCount = sharedBuffer->size() / frameSize; 200221da647792c0b78ab3943be0f32066015d5e8c34Eric Laurent } else { 200321da647792c0b78ab3943be0f32066015d5e8c34Eric Laurent size_t minFrameCount = 0; 200421da647792c0b78ab3943be0f32066015d5e8c34Eric Laurent // For fast tracks we try to respect the application's request for notifications per buffer. 200521da647792c0b78ab3943be0f32066015d5e8c34Eric Laurent if (*flags & AUDIO_OUTPUT_FLAG_FAST) { 200621da647792c0b78ab3943be0f32066015d5e8c34Eric Laurent if (notificationsPerBuffer > 0) { 200721da647792c0b78ab3943be0f32066015d5e8c34Eric Laurent // Avoid possible arithmetic overflow during multiplication. 200821da647792c0b78ab3943be0f32066015d5e8c34Eric Laurent if (notificationsPerBuffer > SIZE_MAX / mFrameCount) { 200921da647792c0b78ab3943be0f32066015d5e8c34Eric Laurent ALOGE("Requested notificationPerBuffer=%u ignored for HAL frameCount=%zu", 201021da647792c0b78ab3943be0f32066015d5e8c34Eric Laurent notificationsPerBuffer, mFrameCount); 201121da647792c0b78ab3943be0f32066015d5e8c34Eric Laurent } else { 201221da647792c0b78ab3943be0f32066015d5e8c34Eric Laurent minFrameCount = mFrameCount * notificationsPerBuffer; 201321da647792c0b78ab3943be0f32066015d5e8c34Eric Laurent } 201421da647792c0b78ab3943be0f32066015d5e8c34Eric Laurent } 201521da647792c0b78ab3943be0f32066015d5e8c34Eric Laurent } else { 201621da647792c0b78ab3943be0f32066015d5e8c34Eric Laurent // For normal PCM streaming tracks, update minimum frame count. 201721da647792c0b78ab3943be0f32066015d5e8c34Eric Laurent // Buffer depth is forced to be at least 2 x the normal mixer frame count and 201821da647792c0b78ab3943be0f32066015d5e8c34Eric Laurent // cover audio hardware latency. 201921da647792c0b78ab3943be0f32066015d5e8c34Eric Laurent // This is probably too conservative, but legacy application code may depend on it. 202021da647792c0b78ab3943be0f32066015d5e8c34Eric Laurent // If you change this calculation, also review the start threshold which is related. 202121da647792c0b78ab3943be0f32066015d5e8c34Eric Laurent uint32_t latencyMs = latency_l(); 202221da647792c0b78ab3943be0f32066015d5e8c34Eric Laurent if (latencyMs == 0) { 202321da647792c0b78ab3943be0f32066015d5e8c34Eric Laurent ALOGE("Error when retrieving output stream latency"); 202421da647792c0b78ab3943be0f32066015d5e8c34Eric Laurent lStatus = UNKNOWN_ERROR; 202521da647792c0b78ab3943be0f32066015d5e8c34Eric Laurent goto Exit; 202621da647792c0b78ab3943be0f32066015d5e8c34Eric Laurent } 202721da647792c0b78ab3943be0f32066015d5e8c34Eric Laurent 202821da647792c0b78ab3943be0f32066015d5e8c34Eric Laurent minFrameCount = AudioSystem::calculateMinFrameCount(latencyMs, mNormalFrameCount, 202921da647792c0b78ab3943be0f32066015d5e8c34Eric Laurent mSampleRate, sampleRate, speed /*, 0 mNotificationsPerBufferReq*/); 203021da647792c0b78ab3943be0f32066015d5e8c34Eric Laurent 203121da647792c0b78ab3943be0f32066015d5e8c34Eric Laurent } 203221da647792c0b78ab3943be0f32066015d5e8c34Eric Laurent if (frameCount < minFrameCount) { 203381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent frameCount = minFrameCount; 203481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 203581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 203621da647792c0b78ab3943be0f32066015d5e8c34Eric Laurent 203721da647792c0b78ab3943be0f32066015d5e8c34Eric Laurent // Make sure that application is notified with sufficient margin before underrun. 203821da647792c0b78ab3943be0f32066015d5e8c34Eric Laurent // The client can divide the AudioTrack buffer into sub-buffers, 203921da647792c0b78ab3943be0f32066015d5e8c34Eric Laurent // and expresses its desire to server as the notification frame count. 204021da647792c0b78ab3943be0f32066015d5e8c34Eric Laurent if (sharedBuffer == 0 && audio_is_linear_pcm(format)) { 204121da647792c0b78ab3943be0f32066015d5e8c34Eric Laurent size_t maxNotificationFrames; 204221da647792c0b78ab3943be0f32066015d5e8c34Eric Laurent if (*flags & AUDIO_OUTPUT_FLAG_FAST) { 204321da647792c0b78ab3943be0f32066015d5e8c34Eric Laurent // notify every HAL buffer, regardless of the size of the track buffer 204421da647792c0b78ab3943be0f32066015d5e8c34Eric Laurent maxNotificationFrames = mFrameCount; 204521da647792c0b78ab3943be0f32066015d5e8c34Eric Laurent } else { 204621da647792c0b78ab3943be0f32066015d5e8c34Eric Laurent // For normal tracks, use at least double-buffering if no sample rate conversion, 204721da647792c0b78ab3943be0f32066015d5e8c34Eric Laurent // or at least triple-buffering if there is sample rate conversion 204821da647792c0b78ab3943be0f32066015d5e8c34Eric Laurent const int nBuffering = sampleRate == mSampleRate ? 2 : 3; 204921da647792c0b78ab3943be0f32066015d5e8c34Eric Laurent maxNotificationFrames = frameCount / nBuffering; 205021da647792c0b78ab3943be0f32066015d5e8c34Eric Laurent // If client requested a fast track but this was denied, then use the smaller maximum. 205121da647792c0b78ab3943be0f32066015d5e8c34Eric Laurent if (requestedFlags & AUDIO_OUTPUT_FLAG_FAST) { 205221da647792c0b78ab3943be0f32066015d5e8c34Eric Laurent size_t maxNotificationFramesFastDenied = FMS_20 * sampleRate / 1000; 205321da647792c0b78ab3943be0f32066015d5e8c34Eric Laurent if (maxNotificationFrames > maxNotificationFramesFastDenied) { 205421da647792c0b78ab3943be0f32066015d5e8c34Eric Laurent maxNotificationFrames = maxNotificationFramesFastDenied; 205521da647792c0b78ab3943be0f32066015d5e8c34Eric Laurent } 205621da647792c0b78ab3943be0f32066015d5e8c34Eric Laurent } 205721da647792c0b78ab3943be0f32066015d5e8c34Eric Laurent } 205821da647792c0b78ab3943be0f32066015d5e8c34Eric Laurent if (notificationFrameCount == 0 || notificationFrameCount > maxNotificationFrames) { 205921da647792c0b78ab3943be0f32066015d5e8c34Eric Laurent if (notificationFrameCount == 0) { 206021da647792c0b78ab3943be0f32066015d5e8c34Eric Laurent ALOGD("Client defaulted notificationFrames to %zu for frameCount %zu", 206121da647792c0b78ab3943be0f32066015d5e8c34Eric Laurent maxNotificationFrames, frameCount); 206221da647792c0b78ab3943be0f32066015d5e8c34Eric Laurent } else { 206321da647792c0b78ab3943be0f32066015d5e8c34Eric Laurent ALOGW("Client adjusted notificationFrames from %zu to %zu for frameCount %zu", 206421da647792c0b78ab3943be0f32066015d5e8c34Eric Laurent notificationFrameCount, maxNotificationFrames, frameCount); 206521da647792c0b78ab3943be0f32066015d5e8c34Eric Laurent } 206621da647792c0b78ab3943be0f32066015d5e8c34Eric Laurent notificationFrameCount = maxNotificationFrames; 206721da647792c0b78ab3943be0f32066015d5e8c34Eric Laurent } 206821da647792c0b78ab3943be0f32066015d5e8c34Eric Laurent } 206921da647792c0b78ab3943be0f32066015d5e8c34Eric Laurent 207074935e44734c1ec235c2b6677db3e0dbefa5ddb8Glenn Kasten *pFrameCount = frameCount; 207121da647792c0b78ab3943be0f32066015d5e8c34Eric Laurent *pNotificationFrameCount = notificationFrameCount; 207281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 2073c3df838434b37d8400eea2438083cc01a4c1cc71Glenn Kasten switch (mType) { 2074c3df838434b37d8400eea2438083cc01a4c1cc71Glenn Kasten 2075c3df838434b37d8400eea2438083cc01a4c1cc71Glenn Kasten case DIRECT: 2076fdb3c07db5d44535eb8c3ec46dc78ad8446c01ebPhil Burk if (audio_is_linear_pcm(format)) { // TODO maybe use audio_has_proportional_frames()? 207781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (sampleRate != mSampleRate || format != mFormat || channelMask != mChannelMask) { 2078cac3daa6332bf6d1f7d26adc4a9915f3d7992dd9Glenn Kasten ALOGE("createTrack_l() Bad parameter: sampleRate %u format %#x, channelMask 0x%08x " 2079cac3daa6332bf6d1f7d26adc4a9915f3d7992dd9Glenn Kasten "for output %p with format %#x", 208081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent sampleRate, format, channelMask, mOutput, mFormat); 208181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent lStatus = BAD_VALUE; 208281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent goto Exit; 208381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 208481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 2085c3df838434b37d8400eea2438083cc01a4c1cc71Glenn Kasten break; 2086c3df838434b37d8400eea2438083cc01a4c1cc71Glenn Kasten 2087c3df838434b37d8400eea2438083cc01a4c1cc71Glenn Kasten case OFFLOAD: 2088bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent if (sampleRate != mSampleRate || format != mFormat || channelMask != mChannelMask) { 2089cac3daa6332bf6d1f7d26adc4a9915f3d7992dd9Glenn Kasten ALOGE("createTrack_l() Bad parameter: sampleRate %d format %#x, channelMask 0x%08x \"" 2090cac3daa6332bf6d1f7d26adc4a9915f3d7992dd9Glenn Kasten "for output %p with format %#x", 2091bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent sampleRate, format, channelMask, mOutput, mFormat); 2092bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent lStatus = BAD_VALUE; 2093bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent goto Exit; 2094bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent } 2095c3df838434b37d8400eea2438083cc01a4c1cc71Glenn Kasten break; 2096c3df838434b37d8400eea2438083cc01a4c1cc71Glenn Kasten 2097c3df838434b37d8400eea2438083cc01a4c1cc71Glenn Kasten default: 2098993fa0603707e94ce259e95e56838a85b5ccbdc5Glenn Kasten if (!audio_is_linear_pcm(format)) { 2099cac3daa6332bf6d1f7d26adc4a9915f3d7992dd9Glenn Kasten ALOGE("createTrack_l() Bad parameter: format %#x \"" 2100cac3daa6332bf6d1f7d26adc4a9915f3d7992dd9Glenn Kasten "for output %p with format %#x", 2101bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent format, mOutput, mFormat); 2102bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent lStatus = BAD_VALUE; 2103bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent goto Exit; 2104bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent } 2105cd04484f4837b8ca0041d118286ab6a98e84fc75Andy Hung if (sampleRate > mSampleRate * AUDIO_RESAMPLER_DOWN_RATIO_MAX) { 210681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent ALOGE("Sample rate out of range: %u mSampleRate %u", sampleRate, mSampleRate); 210781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent lStatus = BAD_VALUE; 210881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent goto Exit; 210981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 2110c3df838434b37d8400eea2438083cc01a4c1cc71Glenn Kasten break; 2111c3df838434b37d8400eea2438083cc01a4c1cc71Glenn Kasten 211281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 211381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 211481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent lStatus = initCheck(); 211581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (lStatus != NO_ERROR) { 211615e5798908ccac14e10c84834eaf08c42931bd06Glenn Kasten ALOGE("createTrack_l() audio driver not initialized"); 211781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent goto Exit; 211881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 211981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 212081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent { // scope for mLock 212181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent Mutex::Autolock _l(mLock); 212281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 212381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // all tracks in same audio session must share the same routing strategy otherwise 212481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // conflicts will happen when tracks are moved from one output to another by audio policy 212581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // manager 212681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent uint32_t strategy = AudioSystem::getStrategyForStream(streamType); 212781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent for (size_t i = 0; i < mTracks.size(); ++i) { 212881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent sp<Track> t = mTracks[i]; 212983b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent if (t != 0 && t->isExternalTrack()) { 213081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent uint32_t actual = AudioSystem::getStrategyForStream(t->streamType()); 213181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (sessionId == t->sessionId() && strategy != actual) { 213281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent ALOGE("createTrack_l() mismatched strategy; expected %u but found %u", 213381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent strategy, actual); 213481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent lStatus = BAD_VALUE; 213581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent goto Exit; 213681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 213781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 213881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 213981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 21401f564acca544826daaf7dca44e39cec6016b82fdKevin Rocard track = new Track(this, client, streamType, attr, sampleRate, format, 21418fe68036c2a670abb9eb0cc67ab9830c2c23de81Andy Hung channelMask, frameCount, 21428fe68036c2a670abb9eb0cc67ab9830c2c23de81Andy Hung nullptr /* buffer */, (size_t)0 /* bufferSize */, sharedBuffer, 214320b9ef0b55c9150ae11057ab997ae61be2d496efEric Laurent sessionId, uid, *flags, TrackBase::TYPE_DEFAULT, portId); 2144030033342a6ea17003e6af38a56c7edc6d2ead01Glenn Kasten 2145030033342a6ea17003e6af38a56c7edc6d2ead01Glenn Kasten lStatus = track != 0 ? track->initCheck() : (status_t) NO_MEMORY; 2146030033342a6ea17003e6af38a56c7edc6d2ead01Glenn Kasten if (lStatus != NO_ERROR) { 21470cde076ddb283c84c3801a2df4cc3df99bd1577fGlenn Kasten ALOGE("createTrack_l() initCheck failed %d; no control block?", lStatus); 214803e9e83c47ab4a518da0a1f36b8f702f59221c95Haynes Mathew George // track must be cleared from the caller as the caller has the AF lock 214981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent goto Exit; 215081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 215181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mTracks.add(track); 215281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 215381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent sp<EffectChain> chain = getEffectChain_l(sessionId); 215481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (chain != 0) { 215581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent ALOGV("createTrack_l() setting main buffer %p", chain->inBuffer()); 215681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent track->setMainBuffer(chain->inBuffer()); 215781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent chain->setStrategy(AudioSystem::getStrategyForStream(track->streamType())); 215881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent chain->incTrackCnt(); 215981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 216081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 2161050677873c10d4da308ac222f8533c96cca3207eEric Laurent if ((*flags & AUDIO_OUTPUT_FLAG_FAST) && (tid != -1)) { 216281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent pid_t callingPid = IPCThreadState::self()->getCallingPid(); 216381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // we don't have CAP_SYS_NICE, nor do we want to have it as it's too powerful, 216481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // so ask activity manager to do this on our behalf 2165af9a7b52b2273ea5c2b30350bdd0fce39a8b16d2Glenn Kasten sendPrioConfigEvent_l(callingPid, tid, kPriorityAudioApp, true /*forApp*/); 216681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 216781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 216881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 216981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent lStatus = NO_ERROR; 217081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 217181784c37c61b09289654b979567a42bf73cd2b12Eric LaurentExit: 21729156ef3e11b68cc4b6d3cea77f1f63673855a6d1Glenn Kasten *status = lStatus; 217381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent return track; 217481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 217581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 21761bc088a918d7038603230637d640941953b314d4Andy Hungtemplate<typename T> 21771bc088a918d7038603230637d640941953b314d4Andy Hungssize_t AudioFlinger::PlaybackThread::Tracks<T>::add(const sp<T> &track) 21781bc088a918d7038603230637d640941953b314d4Andy Hung{ 21791bc088a918d7038603230637d640941953b314d4Andy Hung const ssize_t index = mTracks.add(track); 21801bc088a918d7038603230637d640941953b314d4Andy Hung if (index >= 0) { 21811bc088a918d7038603230637d640941953b314d4Andy Hung // set name for track when adding. 21821bc088a918d7038603230637d640941953b314d4Andy Hung int name; 21831bc088a918d7038603230637d640941953b314d4Andy Hung if (mUnusedTrackNames.empty()) { 21841bc088a918d7038603230637d640941953b314d4Andy Hung name = mTracks.size() - 1; // new name {0 ... size-1}. 21851bc088a918d7038603230637d640941953b314d4Andy Hung } else { 21861bc088a918d7038603230637d640941953b314d4Andy Hung // reuse smallest name for deleted track. 21871bc088a918d7038603230637d640941953b314d4Andy Hung auto it = mUnusedTrackNames.begin(); 21881bc088a918d7038603230637d640941953b314d4Andy Hung name = *it; 21891bc088a918d7038603230637d640941953b314d4Andy Hung (void)mUnusedTrackNames.erase(it); 21901bc088a918d7038603230637d640941953b314d4Andy Hung } 21911bc088a918d7038603230637d640941953b314d4Andy Hung track->setName(name); 21921bc088a918d7038603230637d640941953b314d4Andy Hung } else { 21931bc088a918d7038603230637d640941953b314d4Andy Hung LOG_ALWAYS_FATAL("cannot add track"); 21941bc088a918d7038603230637d640941953b314d4Andy Hung } 21951bc088a918d7038603230637d640941953b314d4Andy Hung return index; 21961bc088a918d7038603230637d640941953b314d4Andy Hung} 21971bc088a918d7038603230637d640941953b314d4Andy Hung 21981bc088a918d7038603230637d640941953b314d4Andy Hungtemplate<typename T> 21991bc088a918d7038603230637d640941953b314d4Andy Hungssize_t AudioFlinger::PlaybackThread::Tracks<T>::remove(const sp<T> &track) 22001bc088a918d7038603230637d640941953b314d4Andy Hung{ 22011bc088a918d7038603230637d640941953b314d4Andy Hung const int name = track->name(); 22021bc088a918d7038603230637d640941953b314d4Andy Hung const ssize_t index = mTracks.remove(track); 22031bc088a918d7038603230637d640941953b314d4Andy Hung if (index >= 0) { 22041bc088a918d7038603230637d640941953b314d4Andy Hung // invalidate name when removing from mTracks. 22051bc088a918d7038603230637d640941953b314d4Andy Hung LOG_ALWAYS_FATAL_IF(name < 0, "invalid name %d for track on mTracks", name); 22061bc088a918d7038603230637d640941953b314d4Andy Hung 22071bc088a918d7038603230637d640941953b314d4Andy Hung if (mSaveDeletedTrackNames) { 22081bc088a918d7038603230637d640941953b314d4Andy Hung // We can't directly access mAudioMixer since the caller may be outside of threadLoop. 22091bc088a918d7038603230637d640941953b314d4Andy Hung // Instead, we add to mDeletedTrackNames which is solely used for mAudioMixer update, 22101bc088a918d7038603230637d640941953b314d4Andy Hung // to be handled when MixerThread::prepareTracks_l() next changes mAudioMixer. 22111bc088a918d7038603230637d640941953b314d4Andy Hung mDeletedTrackNames.emplace(name); 22121bc088a918d7038603230637d640941953b314d4Andy Hung } 22131bc088a918d7038603230637d640941953b314d4Andy Hung 22141bc088a918d7038603230637d640941953b314d4Andy Hung mUnusedTrackNames.emplace(name); 22151bc088a918d7038603230637d640941953b314d4Andy Hung track->setName(T::TRACK_NAME_PENDING); 22161bc088a918d7038603230637d640941953b314d4Andy Hung } else { 22171bc088a918d7038603230637d640941953b314d4Andy Hung LOG_ALWAYS_FATAL_IF(name >= 0, 22181bc088a918d7038603230637d640941953b314d4Andy Hung "valid name %d for track not in mTracks (returned %zd)", name, index); 22191bc088a918d7038603230637d640941953b314d4Andy Hung } 22201bc088a918d7038603230637d640941953b314d4Andy Hung return index; 22211bc088a918d7038603230637d640941953b314d4Andy Hung} 22221bc088a918d7038603230637d640941953b314d4Andy Hung 222381784c37c61b09289654b979567a42bf73cd2b12Eric Laurentuint32_t AudioFlinger::PlaybackThread::correctLatency_l(uint32_t latency) const 222481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 222581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent return latency; 222681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 222781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 222881784c37c61b09289654b979567a42bf73cd2b12Eric Laurentuint32_t AudioFlinger::PlaybackThread::latency() const 222981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 223081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent Mutex::Autolock _l(mLock); 223181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent return latency_l(); 223281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 223381784c37c61b09289654b979567a42bf73cd2b12Eric Laurentuint32_t AudioFlinger::PlaybackThread::latency_l() const 223481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 22351dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov uint32_t latency; 22361dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov if (initCheck() == NO_ERROR && mOutput->stream->getLatency(&latency) == OK) { 22371dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov return correctLatency_l(latency); 223881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 22391dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov return 0; 224081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 224181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 224281784c37c61b09289654b979567a42bf73cd2b12Eric Laurentvoid AudioFlinger::PlaybackThread::setMasterVolume(float value) 224381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 224481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent Mutex::Autolock _l(mLock); 224581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // Don't apply master volume in SW if our HAL can do it for us. 224681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (mOutput && mOutput->audioHwDev && 224781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mOutput->audioHwDev->canSetMasterVolume()) { 224881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mMasterVolume = 1.0; 224981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } else { 225081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mMasterVolume = value; 225181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 225281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 225381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 225481784c37c61b09289654b979567a42bf73cd2b12Eric Laurentvoid AudioFlinger::PlaybackThread::setMasterMute(bool muted) 225581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 22566acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent if (isDuplicating()) { 22576acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent return; 22586acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } 225981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent Mutex::Autolock _l(mLock); 226081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // Don't apply master mute in SW if our HAL can do it for us. 226181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (mOutput && mOutput->audioHwDev && 226281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mOutput->audioHwDev->canSetMasterMute()) { 226381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mMasterMute = false; 226481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } else { 226581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mMasterMute = muted; 226681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 226781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 226881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 226981784c37c61b09289654b979567a42bf73cd2b12Eric Laurentvoid AudioFlinger::PlaybackThread::setStreamVolume(audio_stream_type_t stream, float value) 227081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 227181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent Mutex::Autolock _l(mLock); 227281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mStreamTypes[stream].volume = value; 2273ede6c3b8b1147bc425f7b923882f559a513fe23bEric Laurent broadcast_l(); 227481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 227581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 227681784c37c61b09289654b979567a42bf73cd2b12Eric Laurentvoid AudioFlinger::PlaybackThread::setStreamMute(audio_stream_type_t stream, bool muted) 227781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 227881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent Mutex::Autolock _l(mLock); 227981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mStreamTypes[stream].mute = muted; 2280ede6c3b8b1147bc425f7b923882f559a513fe23bEric Laurent broadcast_l(); 228181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 228281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 228381784c37c61b09289654b979567a42bf73cd2b12Eric Laurentfloat AudioFlinger::PlaybackThread::streamVolume(audio_stream_type_t stream) const 228481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 228581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent Mutex::Autolock _l(mLock); 228681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent return mStreamTypes[stream].volume; 228781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 228881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 228981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// addTrack_l() must be called with ThreadBase::mLock held 229081784c37c61b09289654b979567a42bf73cd2b12Eric Laurentstatus_t AudioFlinger::PlaybackThread::addTrack_l(const sp<Track>& track) 229181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 229281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent status_t status = ALREADY_EXISTS; 229381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 229481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (mActiveTracks.indexOf(track) < 0) { 229581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // the track is newly added, make sure it fills up all its 229681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // buffers before playing. This is to ensure the client will 229781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // effectively get the latency it requested. 229883b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent if (track->isExternalTrack()) { 2299bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent TrackBase::track_state state = track->mState; 2300bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent mLock.unlock(); 2301e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent status = AudioSystem::startOutput(mId, track->streamType(), 2302d848eb48c121c119e8ba7583efc75415fe102570Glenn Kasten track->sessionId()); 2303bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent mLock.lock(); 2304bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent // abort track was stopped/paused while we released the lock 2305bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent if (state != track->mState) { 2306bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent if (status == NO_ERROR) { 2307bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent mLock.unlock(); 2308e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent AudioSystem::stopOutput(mId, track->streamType(), 2309d848eb48c121c119e8ba7583efc75415fe102570Glenn Kasten track->sessionId()); 2310bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent mLock.lock(); 2311bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent } 2312bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent return INVALID_OPERATION; 2313bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent } 2314bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent // abort if start is rejected by audio policy manager 2315bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent if (status != NO_ERROR) { 2316bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent return PERMISSION_DENIED; 2317bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent } 2318bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent#ifdef ADD_BATTERY_DATA 2319bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent // to track the speaker usage 2320bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent addBatteryData(IMediaPlayerService::kBatteryDataAudioFlingerStart); 2321bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent#endif 2322bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent } 2323bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent 2324517161856d74f5fe39cce131f29b977bc1745991Eric Laurent // set retry count for buffer fill 2325517161856d74f5fe39cce131f29b977bc1745991Eric Laurent if (track->isOffloaded()) { 2326e93cc03da360a1a0d2ad937c745ce8c8e8be81c2Eric Laurent if (track->isStopping_1()) { 2327e93cc03da360a1a0d2ad937c745ce8c8e8be81c2Eric Laurent track->mRetryCount = kMaxTrackStopRetriesOffload; 2328e93cc03da360a1a0d2ad937c745ce8c8e8be81c2Eric Laurent } else { 2329e93cc03da360a1a0d2ad937c745ce8c8e8be81c2Eric Laurent track->mRetryCount = kMaxTrackStartupRetriesOffload; 2330e93cc03da360a1a0d2ad937c745ce8c8e8be81c2Eric Laurent } 2331e93cc03da360a1a0d2ad937c745ce8c8e8be81c2Eric Laurent track->mFillingUpStatus = mStandby ? Track::FS_FILLING : Track::FS_FILLED; 2332517161856d74f5fe39cce131f29b977bc1745991Eric Laurent } else { 2333517161856d74f5fe39cce131f29b977bc1745991Eric Laurent track->mRetryCount = kMaxTrackStartupRetries; 2334e93cc03da360a1a0d2ad937c745ce8c8e8be81c2Eric Laurent track->mFillingUpStatus = 2335e93cc03da360a1a0d2ad937c745ce8c8e8be81c2Eric Laurent track->sharedBuffer() != 0 ? Track::FS_FILLED : Track::FS_FILLING; 2336517161856d74f5fe39cce131f29b977bc1745991Eric Laurent } 2337517161856d74f5fe39cce131f29b977bc1745991Eric Laurent 233881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent track->mResetDone = false; 233981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent track->mPresentationCompleteFrames = 0; 234081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mActiveTracks.add(track); 2341d0107bcd44fe608b0c00a8843d19fb6356c4cb69Eric Laurent sp<EffectChain> chain = getEffectChain_l(track->sessionId()); 2342d0107bcd44fe608b0c00a8843d19fb6356c4cb69Eric Laurent if (chain != 0) { 2343d0107bcd44fe608b0c00a8843d19fb6356c4cb69Eric Laurent ALOGV("addTrack_l() starting track on chain %p for session %d", chain.get(), 2344d0107bcd44fe608b0c00a8843d19fb6356c4cb69Eric Laurent track->sessionId()); 2345d0107bcd44fe608b0c00a8843d19fb6356c4cb69Eric Laurent chain->incActiveTrackCnt(); 234681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 234781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 234881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent status = NO_ERROR; 234981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 235081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 23514c6a433d74d5ae8b9bc0557207e3ced43bf34a25Haynes Mathew George onAddNewTrack_l(); 235281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent return status; 235381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 235481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 2355bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurentbool AudioFlinger::PlaybackThread::destroyTrack_l(const sp<Track>& track) 235681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 2357bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent track->terminate(); 235881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // active tracks are removed by threadLoop() 2359bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent bool trackActive = (mActiveTracks.indexOf(track) >= 0); 2360bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent track->mState = TrackBase::STOPPED; 2361bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent if (!trackActive) { 236281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent removeTrack_l(track); 2363ab5cdbaf65ca509681d2726aacdf3ac8bfb6b3faEric Laurent } else if (track->isFastTrack() || track->isOffloaded() || track->isDirect()) { 2364bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent track->mState = TrackBase::STOPPING_1; 236581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 2366bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent 2367bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent return trackActive; 236881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 236981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 237081784c37c61b09289654b979567a42bf73cd2b12Eric Laurentvoid AudioFlinger::PlaybackThread::removeTrack_l(const sp<Track>& track) 237181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 237281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent track->triggerEvents(AudioSystem::SYNC_EVENT_PRESENTATION_COMPLETE); 23732148bf0e79c436b8764b9edc4c8f2730cce98a32Andy Hung 23742c6c3bb76b2fa18ed3536331a1700250bd04c7ceAndy Hung String8 result; 23752c6c3bb76b2fa18ed3536331a1700250bd04c7ceAndy Hung track->appendDump(result, false /* active */); 23762c6c3bb76b2fa18ed3536331a1700250bd04c7ceAndy Hung mLocalLog.log("removeTrack_l (%p) %s", track.get(), result.string()); 23772148bf0e79c436b8764b9edc4c8f2730cce98a32Andy Hung 237881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mTracks.remove(track); 237981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (track->isFastTrack()) { 238081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent int index = track->mFastIndex; 2381dc2c50bad491d2c0c8a2efc0e24491076701c63cGlenn Kasten ALOG_ASSERT(0 < index && index < (int)FastMixerState::sMaxFastTracks); 238281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent ALOG_ASSERT(!(mFastTrackAvailMask & (1 << index))); 238381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mFastTrackAvailMask |= 1 << index; 238481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // redundant as track is about to be destroyed, for dumpsys only 238581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent track->mFastIndex = -1; 238681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 238781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent sp<EffectChain> chain = getEffectChain_l(track->sessionId()); 238881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (chain != 0) { 238981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent chain->decTrackCnt(); 239081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 239181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 239281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 239381784c37c61b09289654b979567a42bf73cd2b12Eric LaurentString8 AudioFlinger::PlaybackThread::getParameters(const String8& keys) 239481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 239581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent Mutex::Autolock _l(mLock); 23961dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov String8 out_s8; 23971dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov if (initCheck() == NO_ERROR && mOutput->stream->getParameters(keys, &out_s8) == OK) { 23981dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov return out_s8; 239981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 24001dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov return String8(); 240181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 240281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 24037c1ec5f038e63a5eb8b04434577c25bc23f5f410Eric Laurentvoid AudioFlinger::PlaybackThread::ioConfigChanged(audio_io_config_event event, pid_t pid) { 240473e26b661af50be2c0a4ff6c9ac85f7347a8b235Eric Laurent sp<AudioIoDescriptor> desc = new AudioIoDescriptor(); 240573e26b661af50be2c0a4ff6c9ac85f7347a8b235Eric Laurent ALOGV("PlaybackThread::ioConfigChanged, thread %p, event %d", this, event); 240681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 240773e26b661af50be2c0a4ff6c9ac85f7347a8b235Eric Laurent desc->mIoHandle = mId; 240881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 240981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent switch (event) { 241073e26b661af50be2c0a4ff6c9ac85f7347a8b235Eric Laurent case AUDIO_OUTPUT_OPENED: 2411ad2e7b902c0432a0db40906a4b1f5b693ce439ddEric Laurent case AUDIO_OUTPUT_REGISTERED: 241273e26b661af50be2c0a4ff6c9ac85f7347a8b235Eric Laurent case AUDIO_OUTPUT_CONFIG_CHANGED: 2413296fb13dd9b5e90d6a05cce897c3b1e7914a478aEric Laurent desc->mPatch = mPatch; 241473e26b661af50be2c0a4ff6c9ac85f7347a8b235Eric Laurent desc->mChannelMask = mChannelMask; 241573e26b661af50be2c0a4ff6c9ac85f7347a8b235Eric Laurent desc->mSamplingRate = mSampleRate; 241673e26b661af50be2c0a4ff6c9ac85f7347a8b235Eric Laurent desc->mFormat = mFormat; 241773e26b661af50be2c0a4ff6c9ac85f7347a8b235Eric Laurent desc->mFrameCount = mNormalFrameCount; // FIXME see 241881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // AudioFlinger::frameCount(audio_io_handle_t) 24194a8308b11b92e608cdaf29f73f7919e75706f9a2Glenn Kasten desc->mFrameCountHAL = mFrameCount; 242073e26b661af50be2c0a4ff6c9ac85f7347a8b235Eric Laurent desc->mLatency = latency_l(); 242181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent break; 242281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 242373e26b661af50be2c0a4ff6c9ac85f7347a8b235Eric Laurent case AUDIO_OUTPUT_CLOSED: 242481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent default: 242581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent break; 242681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 24277c1ec5f038e63a5eb8b04434577c25bc23f5f410Eric Laurent mAudioFlinger->ioConfigChanged(event, desc, pid); 242881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 242981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 24301dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganovvoid AudioFlinger::PlaybackThread::onWriteReady() 2431bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent{ 24323b4529e03c5fc7a44c22f9091ad15a269bfca3a8Eric Laurent mCallbackThread->resetWriteBlocked(); 2433bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent} 2434bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent 24351dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganovvoid AudioFlinger::PlaybackThread::onDrainReady() 2436bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent{ 24373b4529e03c5fc7a44c22f9091ad15a269bfca3a8Eric Laurent mCallbackThread->resetDraining(); 2438bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent} 2439bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent 24401dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganovvoid AudioFlinger::PlaybackThread::onError() 24414527b9ebc6a37b861f5a3bba68bcc63dc8d69adaHaynes Mathew George{ 24424527b9ebc6a37b861f5a3bba68bcc63dc8d69adaHaynes Mathew George mCallbackThread->setAsyncError(); 24434527b9ebc6a37b861f5a3bba68bcc63dc8d69adaHaynes Mathew George} 24444527b9ebc6a37b861f5a3bba68bcc63dc8d69adaHaynes Mathew George 24453b4529e03c5fc7a44c22f9091ad15a269bfca3a8Eric Laurentvoid AudioFlinger::PlaybackThread::resetWriteBlocked(uint32_t sequence) 2446bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent{ 2447bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent Mutex::Autolock _l(mLock); 24483b4529e03c5fc7a44c22f9091ad15a269bfca3a8Eric Laurent // reject out of sequence requests 24493b4529e03c5fc7a44c22f9091ad15a269bfca3a8Eric Laurent if ((mWriteAckSequence & 1) && (sequence == mWriteAckSequence)) { 24503b4529e03c5fc7a44c22f9091ad15a269bfca3a8Eric Laurent mWriteAckSequence &= ~1; 2451bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent mWaitWorkCV.signal(); 2452bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent } 2453bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent} 2454bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent 24553b4529e03c5fc7a44c22f9091ad15a269bfca3a8Eric Laurentvoid AudioFlinger::PlaybackThread::resetDraining(uint32_t sequence) 2456bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent{ 2457bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent Mutex::Autolock _l(mLock); 24583b4529e03c5fc7a44c22f9091ad15a269bfca3a8Eric Laurent // reject out of sequence requests 24593b4529e03c5fc7a44c22f9091ad15a269bfca3a8Eric Laurent if ((mDrainSequence & 1) && (sequence == mDrainSequence)) { 24603b4529e03c5fc7a44c22f9091ad15a269bfca3a8Eric Laurent mDrainSequence &= ~1; 2461bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent mWaitWorkCV.signal(); 2462bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent } 2463bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent} 2464bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent 2465deca2ae0a7cf8bc54ff3f30b7dc39bbc78b94c0dGlenn Kastenvoid AudioFlinger::PlaybackThread::readOutputParameters_l() 246681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 2467adad3d7d935da176ff24941b4ae9edf7340e9b96Glenn Kasten // unfortunately we have no way of recovering from errors here, hence the LOG_ALWAYS_FATAL 2468ca5e6143740299c877d69e97f7968cd04476d32cPhil Burk mSampleRate = mOutput->getSampleRate(); 2469ca5e6143740299c877d69e97f7968cd04476d32cPhil Burk mChannelMask = mOutput->getChannelMask(); 24707fc97ba08e2850f3f16db704b78ce78e3dbe1ff0Glenn Kasten if (!audio_is_output_channel(mChannelMask)) { 2471adad3d7d935da176ff24941b4ae9edf7340e9b96Glenn Kasten LOG_ALWAYS_FATAL("HAL channel mask %#x not valid for output", mChannelMask); 24727fc97ba08e2850f3f16db704b78ce78e3dbe1ff0Glenn Kasten } 24739a59276fb465e492138e0576523b54079671e8f4Andy Hung if ((mType == MIXER || mType == DUPLICATING) 24749a59276fb465e492138e0576523b54079671e8f4Andy Hung && !isValidPcmSinkChannelMask(mChannelMask)) { 24759a59276fb465e492138e0576523b54079671e8f4Andy Hung LOG_ALWAYS_FATAL("HAL channel mask %#x not supported for mixed output", 24769a59276fb465e492138e0576523b54079671e8f4Andy Hung mChannelMask); 24777fc97ba08e2850f3f16db704b78ce78e3dbe1ff0Glenn Kasten } 2478e541269be94f3a1072932d51537905b120ef4733Andy Hung mChannelCount = audio_channel_count_from_out_mask(mChannelMask); 2479ca5e6143740299c877d69e97f7968cd04476d32cPhil Burk 2480ca5e6143740299c877d69e97f7968cd04476d32cPhil Burk // Get actual HAL format. 24811dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov status_t result = mOutput->stream->getFormat(&mHALFormat); 24821dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov LOG_ALWAYS_FATAL_IF(result != OK, "Error when retrieving output stream format: %d", result); 2483ca5e6143740299c877d69e97f7968cd04476d32cPhil Burk // Get format from the shim, which will be different than the HAL format 2484ca5e6143740299c877d69e97f7968cd04476d32cPhil Burk // if playing compressed audio over HDMI passthrough. 2485ca5e6143740299c877d69e97f7968cd04476d32cPhil Burk mFormat = mOutput->getFormat(); 24867fc97ba08e2850f3f16db704b78ce78e3dbe1ff0Glenn Kasten if (!audio_is_valid_format(mFormat)) { 2487adad3d7d935da176ff24941b4ae9edf7340e9b96Glenn Kasten LOG_ALWAYS_FATAL("HAL format %#x not valid for output", mFormat); 24887fc97ba08e2850f3f16db704b78ce78e3dbe1ff0Glenn Kasten } 24896146c08f0c3dd8b9e5788063aa433f304a810602Andy Hung if ((mType == MIXER || mType == DUPLICATING) 24906146c08f0c3dd8b9e5788063aa433f304a810602Andy Hung && !isValidPcmSinkFormat(mFormat)) { 24916146c08f0c3dd8b9e5788063aa433f304a810602Andy Hung LOG_FATAL("HAL format %#x not supported for mixed output", 24926146c08f0c3dd8b9e5788063aa433f304a810602Andy Hung mFormat); 24937fc97ba08e2850f3f16db704b78ce78e3dbe1ff0Glenn Kasten } 2494062e67a26e0553dd142be622821f493df541f0c6Phil Burk mFrameSize = mOutput->getFrameSize(); 24951dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov result = mOutput->stream->getBufferSize(&mBufferSize); 24961dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov LOG_ALWAYS_FATAL_IF(result != OK, 24971dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov "Error when retrieving output stream buffer size: %d", result); 249870949c47fbae3f836d15f040551d7631be3ed7c2Glenn Kasten mFrameCount = mBufferSize / mFrameSize; 249981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (mFrameCount & 15) { 2500c42e9b462661673dff480ee71757a58b0f806370Glenn Kasten ALOGW("HAL output buffer size is %zu frames but AudioMixer requires multiples of 16 frames", 250181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mFrameCount); 250281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 250381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 25041dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov if (mOutput->flags & AUDIO_OUTPUT_FLAG_NON_BLOCKING) { 25051dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov if (mOutput->stream->setCallback(this) == OK) { 2506bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent mUseAsyncWrite = true; 25074de95592980dba88a35b3dc8f3fd045588387a4fEric Laurent mCallbackThread = new AudioFlinger::AsyncCallbackThread(this); 2508bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent } 2509bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent } 2510bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent 2511d1f69b0b17acbd96987ecb2f3378abd394d05903Eric Laurent mHwSupportsPause = false; 2512d1f69b0b17acbd96987ecb2f3378abd394d05903Eric Laurent if (mOutput->flags & AUDIO_OUTPUT_FLAG_DIRECT) { 25131dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov bool supportsPause = false, supportsResume = false; 25141dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov if (mOutput->stream->supportsPauseAndResume(&supportsPause, &supportsResume) == OK) { 25151dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov if (supportsPause && supportsResume) { 2516d1f69b0b17acbd96987ecb2f3378abd394d05903Eric Laurent mHwSupportsPause = true; 25171dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov } else if (supportsPause) { 2518d1f69b0b17acbd96987ecb2f3378abd394d05903Eric Laurent ALOGW("direct output implements pause but not resume"); 25191dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov } else if (supportsResume) { 25201dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov ALOGW("direct output implements resume but not pause"); 2521d1f69b0b17acbd96987ecb2f3378abd394d05903Eric Laurent } 2522d1f69b0b17acbd96987ecb2f3378abd394d05903Eric Laurent } 2523d1f69b0b17acbd96987ecb2f3378abd394d05903Eric Laurent } 25246fc2a7c81f62b1e21487ae37e11aae6241bc3eadPhil Burk if (!mHwSupportsPause && mOutput->flags & AUDIO_OUTPUT_FLAG_HW_AV_SYNC) { 25256fc2a7c81f62b1e21487ae37e11aae6241bc3eadPhil Burk LOG_ALWAYS_FATAL("HW_AV_SYNC requested but HAL does not implement pause and resume"); 25266fc2a7c81f62b1e21487ae37e11aae6241bc3eadPhil Burk } 2527d1f69b0b17acbd96987ecb2f3378abd394d05903Eric Laurent 2528fbfc3959f4aac839445edc7075532067fef497c2Andy Hung if (mType == DUPLICATING && mMixerBufferEnabled && mEffectBufferEnabled) { 2529fbfc3959f4aac839445edc7075532067fef497c2Andy Hung // For best precision, we use float instead of the associated output 2530fbfc3959f4aac839445edc7075532067fef497c2Andy Hung // device format (typically PCM 16 bit). 2531fbfc3959f4aac839445edc7075532067fef497c2Andy Hung 2532fbfc3959f4aac839445edc7075532067fef497c2Andy Hung mFormat = AUDIO_FORMAT_PCM_FLOAT; 2533fbfc3959f4aac839445edc7075532067fef497c2Andy Hung mFrameSize = mChannelCount * audio_bytes_per_sample(mFormat); 2534fbfc3959f4aac839445edc7075532067fef497c2Andy Hung mBufferSize = mFrameSize * mFrameCount; 2535fbfc3959f4aac839445edc7075532067fef497c2Andy Hung 2536fbfc3959f4aac839445edc7075532067fef497c2Andy Hung // TODO: We currently use the associated output device channel mask and sample rate. 2537fbfc3959f4aac839445edc7075532067fef497c2Andy Hung // (1) Perhaps use the ORed channel mask of all downstream MixerThreads 2538fbfc3959f4aac839445edc7075532067fef497c2Andy Hung // (if a valid mask) to avoid premature downmix. 2539fbfc3959f4aac839445edc7075532067fef497c2Andy Hung // (2) Perhaps use the maximum sample rate of all downstream MixerThreads 2540fbfc3959f4aac839445edc7075532067fef497c2Andy Hung // instead of the output device sample rate to avoid loss of high frequency information. 2541fbfc3959f4aac839445edc7075532067fef497c2Andy Hung // This may need to be updated as MixerThread/OutputTracks are added and not here. 2542fbfc3959f4aac839445edc7075532067fef497c2Andy Hung } 2543fbfc3959f4aac839445edc7075532067fef497c2Andy Hung 254409a5007b17acb49d25cfa386a2e2534d942e8854Andy Hung // Calculate size of normal sink buffer relative to the HAL output buffer size 254581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent double multiplier = 1.0; 254681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (mType == MIXER && (kUseFastMixer == FastMixer_Static || 254781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent kUseFastMixer == FastMixer_Dynamic)) { 254809a5007b17acb49d25cfa386a2e2534d942e8854Andy Hung size_t minNormalFrameCount = (kMinNormalSinkBufferSizeMs * mSampleRate) / 1000; 254909a5007b17acb49d25cfa386a2e2534d942e8854Andy Hung size_t maxNormalFrameCount = (kMaxNormalSinkBufferSizeMs * mSampleRate) / 1000; 2550227a14be87e8c63eb7a464b857a1d29c86c90e7cHaynes Mathew George 255181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // round up minimum and round down maximum to nearest 16 frames to satisfy AudioMixer 255281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent minNormalFrameCount = (minNormalFrameCount + 15) & ~15; 255381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent maxNormalFrameCount = maxNormalFrameCount & ~15; 255481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (maxNormalFrameCount < minNormalFrameCount) { 255581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent maxNormalFrameCount = minNormalFrameCount; 255681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 255781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent multiplier = (double) minNormalFrameCount / (double) mFrameCount; 255881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (multiplier <= 1.0) { 255981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent multiplier = 1.0; 256081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } else if (multiplier <= 2.0) { 256181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (2 * mFrameCount <= maxNormalFrameCount) { 256281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent multiplier = 2.0; 256381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } else { 256481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent multiplier = (double) maxNormalFrameCount / (double) mFrameCount; 256581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 256681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } else { 2567227a14be87e8c63eb7a464b857a1d29c86c90e7cHaynes Mathew George multiplier = floor(multiplier); 256881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 256981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 257081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mNormalFrameCount = multiplier * mFrameCount; 257181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // round up to nearest 16 frames to satisfy AudioMixer 2572ab5cdbaf65ca509681d2726aacdf3ac8bfb6b3faEric Laurent if (mType == MIXER || mType == DUPLICATING) { 2573ab5cdbaf65ca509681d2726aacdf3ac8bfb6b3faEric Laurent mNormalFrameCount = (mNormalFrameCount + 15) & ~15; 2574ab5cdbaf65ca509681d2726aacdf3ac8bfb6b3faEric Laurent } 2575c42e9b462661673dff480ee71757a58b0f806370Glenn Kasten ALOGI("HAL output buffer size %zu frames, normal sink buffer size %zu frames", mFrameCount, 257681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mNormalFrameCount); 257781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 257808fb1743f80437c38b4094070d851ea7f6d485e5Andy Hung // Check if we want to throttle the processing to no more than 2x normal rate 257908fb1743f80437c38b4094070d851ea7f6d485e5Andy Hung mThreadThrottle = property_get_bool("af.thread.throttle", true /* default_value */); 258040eb1a1f8871909c272e72afaf7d5af84fea2412Andy Hung mThreadThrottleTimeMs = 0; 258140eb1a1f8871909c272e72afaf7d5af84fea2412Andy Hung mThreadThrottleEndMs = 0; 258208fb1743f80437c38b4094070d851ea7f6d485e5Andy Hung mHalfBufferMs = mNormalFrameCount * 1000 / (2 * mSampleRate); 258308fb1743f80437c38b4094070d851ea7f6d485e5Andy Hung 2584010a1a1a552cdaad362cea8a0333b8906402dbcbAndy Hung // mSinkBuffer is the sink buffer. Size is always multiple-of-16 frames. 2585010a1a1a552cdaad362cea8a0333b8906402dbcbAndy Hung // Originally this was int16_t[] array, need to remove legacy implications. 2586010a1a1a552cdaad362cea8a0333b8906402dbcbAndy Hung free(mSinkBuffer); 2587010a1a1a552cdaad362cea8a0333b8906402dbcbAndy Hung mSinkBuffer = NULL; 25885b10a2037a835e790994b9ebec3c2e55052f1f3bAndy Hung // For sink buffer size, we use the frame size from the downstream sink to avoid problems 25895b10a2037a835e790994b9ebec3c2e55052f1f3bAndy Hung // with non PCM formats for compressed music, e.g. AAC, and Offload threads. 25905b10a2037a835e790994b9ebec3c2e55052f1f3bAndy Hung const size_t sinkBufferSize = mNormalFrameCount * mFrameSize; 2591010a1a1a552cdaad362cea8a0333b8906402dbcbAndy Hung (void)posix_memalign(&mSinkBuffer, 32, sinkBufferSize); 259281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 259369aed5f0f4a3be3996d1e78a0473e1a72c1547daAndy Hung // We resize the mMixerBuffer according to the requirements of the sink buffer which 259469aed5f0f4a3be3996d1e78a0473e1a72c1547daAndy Hung // drives the output. 259569aed5f0f4a3be3996d1e78a0473e1a72c1547daAndy Hung free(mMixerBuffer); 259669aed5f0f4a3be3996d1e78a0473e1a72c1547daAndy Hung mMixerBuffer = NULL; 259769aed5f0f4a3be3996d1e78a0473e1a72c1547daAndy Hung if (mMixerBufferEnabled) { 259869aed5f0f4a3be3996d1e78a0473e1a72c1547daAndy Hung mMixerBufferFormat = AUDIO_FORMAT_PCM_FLOAT; // also valid: AUDIO_FORMAT_PCM_16_BIT. 259969aed5f0f4a3be3996d1e78a0473e1a72c1547daAndy Hung mMixerBufferSize = mNormalFrameCount * mChannelCount 260069aed5f0f4a3be3996d1e78a0473e1a72c1547daAndy Hung * audio_bytes_per_sample(mMixerBufferFormat); 260169aed5f0f4a3be3996d1e78a0473e1a72c1547daAndy Hung (void)posix_memalign(&mMixerBuffer, 32, mMixerBufferSize); 260269aed5f0f4a3be3996d1e78a0473e1a72c1547daAndy Hung } 260398ef978df4e928f486d244c4d7f7ad9f13111e98Andy Hung free(mEffectBuffer); 260498ef978df4e928f486d244c4d7f7ad9f13111e98Andy Hung mEffectBuffer = NULL; 260598ef978df4e928f486d244c4d7f7ad9f13111e98Andy Hung if (mEffectBufferEnabled) { 260694a1ee822686e920a33e312f4032f991731aea07rago mEffectBufferFormat = EFFECT_BUFFER_FORMAT; 260798ef978df4e928f486d244c4d7f7ad9f13111e98Andy Hung mEffectBufferSize = mNormalFrameCount * mChannelCount 260898ef978df4e928f486d244c4d7f7ad9f13111e98Andy Hung * audio_bytes_per_sample(mEffectBufferFormat); 260998ef978df4e928f486d244c4d7f7ad9f13111e98Andy Hung (void)posix_memalign(&mEffectBuffer, 32, mEffectBufferSize); 261098ef978df4e928f486d244c4d7f7ad9f13111e98Andy Hung } 261169aed5f0f4a3be3996d1e78a0473e1a72c1547daAndy Hung 261281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // force reconfiguration of effect chains and engines to take new buffer size and audio 261381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // parameters into account 2614deca2ae0a7cf8bc54ff3f30b7dc39bbc78b94c0dGlenn Kasten // Note that mLock is not held when readOutputParameters_l() is called from the constructor 261581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // but in this case nothing is done below as no audio sessions have effect yet so it doesn't 261681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // matter. 261781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // create a copy of mEffectChains as calling moveEffectChain_l() can reorder some effect chains 261881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent Vector< sp<EffectChain> > effectChains = mEffectChains; 261981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent for (size_t i = 0; i < effectChains.size(); i ++) { 262081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mAudioFlinger->moveEffectChain_l(effectChains[i]->sessionId(), this, this, false); 262181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 262281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 262381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 2624069c2719e753732d5af9ba51e5fcc34342b0c9f2Kevin Rocardvoid AudioFlinger::PlaybackThread::updateMetadata_l() 2625069c2719e753732d5af9ba51e5fcc34342b0c9f2Kevin Rocard{ 262612381092fdb5810cb27f738435ea8a0e3d2d0f42Kevin Rocard if (mOutput == nullptr || mOutput->stream == nullptr ) { 262712381092fdb5810cb27f738435ea8a0e3d2d0f42Kevin Rocard return; // That should not happen 262812381092fdb5810cb27f738435ea8a0e3d2d0f42Kevin Rocard } 262912381092fdb5810cb27f738435ea8a0e3d2d0f42Kevin Rocard bool hasChanged = mActiveTracks.readAndClearHasChanged(); 263012381092fdb5810cb27f738435ea8a0e3d2d0f42Kevin Rocard for (const sp<Track> &track : mActiveTracks) { 263112381092fdb5810cb27f738435ea8a0e3d2d0f42Kevin Rocard // Do not short-circuit as all hasChanged states must be reset 263212381092fdb5810cb27f738435ea8a0e3d2d0f42Kevin Rocard // as all the metadata are going to be sent 263312381092fdb5810cb27f738435ea8a0e3d2d0f42Kevin Rocard hasChanged |= track->readAndClearHasChanged(); 263412381092fdb5810cb27f738435ea8a0e3d2d0f42Kevin Rocard } 263512381092fdb5810cb27f738435ea8a0e3d2d0f42Kevin Rocard if (!hasChanged) { 263612381092fdb5810cb27f738435ea8a0e3d2d0f42Kevin Rocard return; // nothing to do 2637069c2719e753732d5af9ba51e5fcc34342b0c9f2Kevin Rocard } 2638069c2719e753732d5af9ba51e5fcc34342b0c9f2Kevin Rocard StreamOutHalInterface::SourceMetadata metadata; 263912381092fdb5810cb27f738435ea8a0e3d2d0f42Kevin Rocard auto backInserter = std::back_inserter(metadata.tracks); 2640069c2719e753732d5af9ba51e5fcc34342b0c9f2Kevin Rocard for (const sp<Track> &track : mActiveTracks) { 2641069c2719e753732d5af9ba51e5fcc34342b0c9f2Kevin Rocard // No track is invalid as this is called after prepareTrack_l in the same critical section 264212381092fdb5810cb27f738435ea8a0e3d2d0f42Kevin Rocard track->copyMetadataTo(backInserter); 2643069c2719e753732d5af9ba51e5fcc34342b0c9f2Kevin Rocard } 264412381092fdb5810cb27f738435ea8a0e3d2d0f42Kevin Rocard sendMetadataToBackend_l(metadata); 264580ee2722d64a73777fa76027b1568e61dec8d910Kevin Rocard} 2646c86a7f7de52f0ff0059e8c6c4fa4619aa7fae5c5Kevin Rocard 264712381092fdb5810cb27f738435ea8a0e3d2d0f42Kevin Rocardvoid AudioFlinger::PlaybackThread::sendMetadataToBackend_l( 264812381092fdb5810cb27f738435ea8a0e3d2d0f42Kevin Rocard const StreamOutHalInterface::SourceMetadata& metadata) 264912381092fdb5810cb27f738435ea8a0e3d2d0f42Kevin Rocard{ 265012381092fdb5810cb27f738435ea8a0e3d2d0f42Kevin Rocard mOutput->stream->updateSourceMetadata(metadata); 265112381092fdb5810cb27f738435ea8a0e3d2d0f42Kevin Rocard}; 265212381092fdb5810cb27f738435ea8a0e3d2d0f42Kevin Rocard 2653377b2ec9a2885f9b6405b07ba900a9e3f4349c38Kévin PETITstatus_t AudioFlinger::PlaybackThread::getRenderPosition(uint32_t *halFrames, uint32_t *dspFrames) 265481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 265581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (halFrames == NULL || dspFrames == NULL) { 265681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent return BAD_VALUE; 265781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 265881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent Mutex::Autolock _l(mLock); 265981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (initCheck() != NO_ERROR) { 266081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent return INVALID_OPERATION; 266181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 2662818e7a32ce3633980138aff2c2bfcc5158b3cfccAndy Hung int64_t framesWritten = mBytesWritten / mFrameSize; 266381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent *halFrames = framesWritten; 266481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 266581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (isSuspended()) { 266681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // return an estimation of rendered frames when the output is suspended 266781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent size_t latencyFrames = (latency_l() * mSampleRate) / 1000; 2668818e7a32ce3633980138aff2c2bfcc5158b3cfccAndy Hung *dspFrames = (uint32_t) 2669818e7a32ce3633980138aff2c2bfcc5158b3cfccAndy Hung (framesWritten >= (int64_t)latencyFrames ? framesWritten - latencyFrames : 0); 267081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent return NO_ERROR; 267181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } else { 2672377b2ec9a2885f9b6405b07ba900a9e3f4349c38Kévin PETIT status_t status; 2673377b2ec9a2885f9b6405b07ba900a9e3f4349c38Kévin PETIT uint32_t frames; 2674062e67a26e0553dd142be622821f493df541f0c6Phil Burk status = mOutput->getRenderPosition(&frames); 2675377b2ec9a2885f9b6405b07ba900a9e3f4349c38Kévin PETIT *dspFrames = (size_t)frames; 2676377b2ec9a2885f9b6405b07ba900a9e3f4349c38Kévin PETIT return status; 267781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 267881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 267981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 26804c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent// hasAudioSession_l() must be called with ThreadBase::mLock held 26814c415062ad1bb53e9af8f644d8215837262b79bbEric Laurentuint32_t AudioFlinger::PlaybackThread::hasAudioSession_l(audio_session_t sessionId) const 268281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 268381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent uint32_t result = 0; 268481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (getEffectChain_l(sessionId) != 0) { 268581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent result = EFFECT_SESSION; 268681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 268781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 268881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent for (size_t i = 0; i < mTracks.size(); ++i) { 268981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent sp<Track> track = mTracks[i]; 26905736c35b841de56ce394b4879389f669b61425e6Glenn Kasten if (sessionId == track->sessionId() && !track->isInvalid()) { 269181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent result |= TRACK_SESSION; 26924c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent if (track->isFastTrack()) { 26934c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent result |= FAST_SESSION; 26944c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent } 269581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent break; 269681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 269781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 269881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 269981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent return result; 270081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 270181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 2702d848eb48c121c119e8ba7583efc75415fe102570Glenn Kastenuint32_t AudioFlinger::PlaybackThread::getStrategyForSession_l(audio_session_t sessionId) 270381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 270481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // session AUDIO_SESSION_OUTPUT_MIX is placed in same strategy as MUSIC stream so that 270581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // it is moved to correct output by audio policy manager when A2DP is connected or disconnected 270681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (sessionId == AUDIO_SESSION_OUTPUT_MIX) { 270781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent return AudioSystem::getStrategyForStream(AUDIO_STREAM_MUSIC); 270881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 270981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent for (size_t i = 0; i < mTracks.size(); i++) { 271081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent sp<Track> track = mTracks[i]; 27115736c35b841de56ce394b4879389f669b61425e6Glenn Kasten if (sessionId == track->sessionId() && !track->isInvalid()) { 271281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent return AudioSystem::getStrategyForStream(track->streamType()); 271381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 271481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 271581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent return AudioSystem::getStrategyForStream(AUDIO_STREAM_MUSIC); 271681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 271781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 271881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 2719062e67a26e0553dd142be622821f493df541f0c6Phil BurkAudioStreamOut* AudioFlinger::PlaybackThread::getOutput() const 272081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 272181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent Mutex::Autolock _l(mLock); 272281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent return mOutput; 272381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 272481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 2725062e67a26e0553dd142be622821f493df541f0c6Phil BurkAudioStreamOut* AudioFlinger::PlaybackThread::clearOutput() 272681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 272781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent Mutex::Autolock _l(mLock); 272881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent AudioStreamOut *output = mOutput; 272981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mOutput = NULL; 273081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // FIXME FastMixer might also have a raw ptr to mOutputSink; 273181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // must push a NULL and wait for ack 273281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mOutputSink.clear(); 273381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mPipeSink.clear(); 273481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mNormalSink.clear(); 273581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent return output; 273681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 273781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 273881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// this method must always be called either with ThreadBase mLock held or inside the thread loop 27391dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganovsp<StreamHalInterface> AudioFlinger::PlaybackThread::stream() const 274081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 274181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (mOutput == NULL) { 274281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent return NULL; 274381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 27441dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov return mOutput->stream; 274581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 274681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 274781784c37c61b09289654b979567a42bf73cd2b12Eric Laurentuint32_t AudioFlinger::PlaybackThread::activeSleepTimeUs() const 274881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 274981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent return (uint32_t)((uint32_t)((mNormalFrameCount * 1000) / mSampleRate) * 1000); 275081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 275181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 275281784c37c61b09289654b979567a42bf73cd2b12Eric Laurentstatus_t AudioFlinger::PlaybackThread::setSyncEvent(const sp<SyncEvent>& event) 275381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 275481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (!isValidSyncEvent(event)) { 275581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent return BAD_VALUE; 275681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 275781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 275881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent Mutex::Autolock _l(mLock); 275981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 276081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent for (size_t i = 0; i < mTracks.size(); ++i) { 276181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent sp<Track> track = mTracks[i]; 276281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (event->triggerSession() == track->sessionId()) { 276381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent (void) track->setSyncEvent(event); 276481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent return NO_ERROR; 276581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 276681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 276781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 276881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent return NAME_NOT_FOUND; 276981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 277081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 277181784c37c61b09289654b979567a42bf73cd2b12Eric Laurentbool AudioFlinger::PlaybackThread::isValidSyncEvent(const sp<SyncEvent>& event) const 277281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 277381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent return event->type() == AudioSystem::SYNC_EVENT_PRESENTATION_COMPLETE; 277481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 277581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 277681784c37c61b09289654b979567a42bf73cd2b12Eric Laurentvoid AudioFlinger::PlaybackThread::threadLoop_removeTracks( 277781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent const Vector< sp<Track> >& tracksToRemove) 277881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 277981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent size_t count = tracksToRemove.size(); 278034fca34606b448e6b71c2942f63cb13a0aebd620Glenn Kasten if (count > 0) { 278181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent for (size_t i = 0 ; i < count ; i++) { 278281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent const sp<Track>& track = tracksToRemove.itemAt(i); 278383b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent if (track->isExternalTrack()) { 2784e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent AudioSystem::stopOutput(mId, track->streamType(), 2785d848eb48c121c119e8ba7583efc75415fe102570Glenn Kasten track->sessionId()); 2786bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent#ifdef ADD_BATTERY_DATA 2787bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent // to track the speaker usage 2788bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent addBatteryData(IMediaPlayerService::kBatteryDataAudioFlingerStop); 2789bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent#endif 2790bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent if (track->isTerminated()) { 2791e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent AudioSystem::releaseOutput(mId, track->streamType(), 2792d848eb48c121c119e8ba7583efc75415fe102570Glenn Kasten track->sessionId()); 2793bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent } 279481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 279581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 279681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 279781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 279881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 279981784c37c61b09289654b979567a42bf73cd2b12Eric Laurentvoid AudioFlinger::PlaybackThread::checkSilentMode_l() 280081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 280181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (!mMasterMute) { 280281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent char value[PROPERTY_VALUE_MAX]; 280332f37c22f60b7a1a6ccfa351700f80c03918d4feJean-Michel Trivi if (mOutDevice == AUDIO_DEVICE_OUT_REMOTE_SUBMIX) { 280432f37c22f60b7a1a6ccfa351700f80c03918d4feJean-Michel Trivi ALOGD("ro.audio.silent will be ignored for threads on AUDIO_DEVICE_OUT_REMOTE_SUBMIX"); 280532f37c22f60b7a1a6ccfa351700f80c03918d4feJean-Michel Trivi return; 280632f37c22f60b7a1a6ccfa351700f80c03918d4feJean-Michel Trivi } 280781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (property_get("ro.audio.silent", value, "0") > 0) { 280881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent char *endptr; 280981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent unsigned long ul = strtoul(value, &endptr, 0); 281081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (*endptr == '\0' && ul != 0) { 281181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent ALOGD("Silence is golden"); 281281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // The setprop command will not allow a property to be changed after 281381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // the first time it is set, so we don't have to worry about un-muting. 281481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent setMasterMute_l(true); 281581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 281681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 281781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 281881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 281981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 282081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// shared by MIXER and DIRECT, overridden by DUPLICATING 2821bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurentssize_t AudioFlinger::PlaybackThread::threadLoop_write() 282281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 28232a6a945d65c986dcc779f70f18afde1d7a74397bSanna Catherine de Treville Wager LOG_HIST_TS(); 282481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mInWrite = true; 2825bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent ssize_t bytesWritten; 2826010a1a1a552cdaad362cea8a0333b8906402dbcbAndy Hung const size_t offset = mCurrentWriteLength - mBytesRemaining; 282781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 282881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // If an NBAIO sink is present, use it to write the normal mixer's submix 282981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (mNormalSink != 0) { 28304c053ea158b29fa2cdd4c6f39d3c8da4ee5a7a02Glenn Kasten 2831010a1a1a552cdaad362cea8a0333b8906402dbcbAndy Hung const size_t count = mBytesRemaining / mFrameSize; 2832010a1a1a552cdaad362cea8a0333b8906402dbcbAndy Hung 28332d590964aa58e137d17a43e095e6443dd0fe2e98Simon Wilson ATRACE_BEGIN("write"); 283481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // update the setpoint when AudioFlinger::mScreenState changes 283581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent uint32_t screenState = AudioFlinger::mScreenState; 283681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (screenState != mScreenState) { 283781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mScreenState = screenState; 283881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent MonoPipe *pipe = (MonoPipe *)mPipeSink.get(); 283981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (pipe != NULL) { 284081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent pipe->setAvgFrames((mScreenState & 1) ? 284181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent (pipe->maxFrames() * 7) / 8 : mNormalFrameCount * 2); 284281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 284381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 2844010a1a1a552cdaad362cea8a0333b8906402dbcbAndy Hung ssize_t framesWritten = mNormalSink->write((char *)mSinkBuffer + offset, count); 28452d590964aa58e137d17a43e095e6443dd0fe2e98Simon Wilson ATRACE_END(); 284681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (framesWritten > 0) { 2847010a1a1a552cdaad362cea8a0333b8906402dbcbAndy Hung bytesWritten = framesWritten * mFrameSize; 284881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } else { 284981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent bytesWritten = framesWritten; 285081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 285181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // otherwise use the HAL / AudioStreamOut directly 285281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } else { 2853bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent // Direct output and offload threads 2854010a1a1a552cdaad362cea8a0333b8906402dbcbAndy Hung 2855bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent if (mUseAsyncWrite) { 28563b4529e03c5fc7a44c22f9091ad15a269bfca3a8Eric Laurent ALOGW_IF(mWriteAckSequence & 1, "threadLoop_write(): out of sequence write request"); 28573b4529e03c5fc7a44c22f9091ad15a269bfca3a8Eric Laurent mWriteAckSequence += 2; 28583b4529e03c5fc7a44c22f9091ad15a269bfca3a8Eric Laurent mWriteAckSequence |= 1; 2859bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent ALOG_ASSERT(mCallbackThread != 0); 28603b4529e03c5fc7a44c22f9091ad15a269bfca3a8Eric Laurent mCallbackThread->setWriteBlocked(mWriteAckSequence); 2861bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent } 2862767094dd98b01baf21de2ad09c27b3c98776cf73Glenn Kasten // FIXME We should have an implementation of timestamps for direct output threads. 2863767094dd98b01baf21de2ad09c27b3c98776cf73Glenn Kasten // They are used e.g for multichannel PCM playback over HDMI. 2864062e67a26e0553dd142be622821f493df541f0c6Phil Burk bytesWritten = mOutput->write((char *)mSinkBuffer + offset, mBytesRemaining); 2865517161856d74f5fe39cce131f29b977bc1745991Eric Laurent 2866bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent if (mUseAsyncWrite && 2867bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent ((bytesWritten < 0) || (bytesWritten == (ssize_t)mBytesRemaining))) { 2868bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent // do not wait for async callback in case of error of full write 28693b4529e03c5fc7a44c22f9091ad15a269bfca3a8Eric Laurent mWriteAckSequence &= ~1; 2870bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent ALOG_ASSERT(mCallbackThread != 0); 28713b4529e03c5fc7a44c22f9091ad15a269bfca3a8Eric Laurent mCallbackThread->setWriteBlocked(mWriteAckSequence); 2872bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent } 287381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 287481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 287581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mNumWrites++; 287681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mInWrite = false; 2877fd4779740ec3e9e865d5514464df26d015354388Eric Laurent mStandby = false; 2878bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent return bytesWritten; 2879bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent} 2880bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent 2881bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurentvoid AudioFlinger::PlaybackThread::threadLoop_drain() 2882bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent{ 28831dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov bool supportsDrain = false; 28841dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov if (mOutput->stream->supportsDrain(&supportsDrain) == OK && supportsDrain) { 2885bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent ALOGV("draining %s", (mMixerStatus == MIXER_DRAIN_TRACK) ? "early" : "full"); 2886bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent if (mUseAsyncWrite) { 28873b4529e03c5fc7a44c22f9091ad15a269bfca3a8Eric Laurent ALOGW_IF(mDrainSequence & 1, "threadLoop_drain(): out of sequence drain request"); 28883b4529e03c5fc7a44c22f9091ad15a269bfca3a8Eric Laurent mDrainSequence |= 1; 2889bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent ALOG_ASSERT(mCallbackThread != 0); 28903b4529e03c5fc7a44c22f9091ad15a269bfca3a8Eric Laurent mCallbackThread->setDraining(mDrainSequence); 2891bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent } 2892cbc8f617c1aebef5d041fa40dcd38a5466690b99Mikhail Naganov status_t result = mOutput->stream->drain(mMixerStatus == MIXER_DRAIN_TRACK); 28931dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov ALOGE_IF(result != OK, "Error when draining stream: %d", result); 2894bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent } 2895bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent} 2896bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent 2897bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurentvoid AudioFlinger::PlaybackThread::threadLoop_exit() 2898bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent{ 2899275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent { 2900275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent Mutex::Autolock _l(mLock); 2901275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent for (size_t i = 0; i < mTracks.size(); i++) { 2902275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent sp<Track> track = mTracks[i]; 2903275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent track->invalidate(); 2904275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent } 2905dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hung // Clear ActiveTracks to update BatteryNotifier in case active tracks remain. 2906dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hung // After we exit there are no more track changes sent to BatteryNotifier 2907dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hung // because that requires an active threadLoop. 2908dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hung // TODO: should we decActiveTrackCnt() of the cleared track effect chain? 2909dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hung mActiveTracks.clear(); 2910275e8e9de2e11b4b344f5a201f1f0e51fda02d9cEric Laurent } 291181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 291281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 291381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent/* 291481784c37c61b09289654b979567a42bf73cd2b12Eric LaurentThe derived values that are cached: 291525c2dac12114699e90deb1c579cadebce7b91a97Andy Hung - mSinkBufferSize from frame count * frame size 2916ad9cb8b88e4f8face23f01d8dc89fa769dacb50fEric Laurent - mActiveSleepTimeUs from activeSleepTimeUs() 2917ad9cb8b88e4f8face23f01d8dc89fa769dacb50fEric Laurent - mIdleSleepTimeUs from idleSleepTimeUs() 291842537be61479e59c4718e1304364551c1454f63cEric Laurent - mStandbyDelayNs from mActiveSleepTimeUs (DIRECT only) or forced to at least 291942537be61479e59c4718e1304364551c1454f63cEric Laurent kDefaultStandbyTimeInNsecs when connected to an A2DP device. 292081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent - maxPeriod from frame count and sample rate (MIXER only) 292181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 292281784c37c61b09289654b979567a42bf73cd2b12Eric LaurentThe parameters that affect these derived values are: 292381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent - frame count 292481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent - frame size 292581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent - sample rate 292681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent - device type: A2DP or not 292781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent - device latency 292881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent - format: PCM or not 292981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent - active sleep time 293081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent - idle sleep time 293181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent*/ 293281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 293381784c37c61b09289654b979567a42bf73cd2b12Eric Laurentvoid AudioFlinger::PlaybackThread::cacheParameters_l() 293481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 293525c2dac12114699e90deb1c579cadebce7b91a97Andy Hung mSinkBufferSize = mNormalFrameCount * mFrameSize; 2936ad9cb8b88e4f8face23f01d8dc89fa769dacb50fEric Laurent mActiveSleepTimeUs = activeSleepTimeUs(); 2937ad9cb8b88e4f8face23f01d8dc89fa769dacb50fEric Laurent mIdleSleepTimeUs = idleSleepTimeUs(); 293842537be61479e59c4718e1304364551c1454f63cEric Laurent 293942537be61479e59c4718e1304364551c1454f63cEric Laurent // make sure standby delay is not too short when connected to an A2DP sink to avoid 294042537be61479e59c4718e1304364551c1454f63cEric Laurent // truncating audio when going to standby. 294142537be61479e59c4718e1304364551c1454f63cEric Laurent mStandbyDelayNs = AudioFlinger::mStandbyTimeInNsecs; 294242537be61479e59c4718e1304364551c1454f63cEric Laurent if ((mOutDevice & AUDIO_DEVICE_OUT_ALL_A2DP) != 0) { 294342537be61479e59c4718e1304364551c1454f63cEric Laurent if (mStandbyDelayNs < kDefaultStandbyTimeInNsecs) { 294442537be61479e59c4718e1304364551c1454f63cEric Laurent mStandbyDelayNs = kDefaultStandbyTimeInNsecs; 294542537be61479e59c4718e1304364551c1454f63cEric Laurent } 294642537be61479e59c4718e1304364551c1454f63cEric Laurent } 294781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 294881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 294913084621072ea2e4c34e2a9d79793c621d9bf005Eric Laurentbool AudioFlinger::PlaybackThread::invalidateTracks_l(audio_stream_type_t streamType) 295081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 2951c42e9b462661673dff480ee71757a58b0f806370Glenn Kasten ALOGV("MixerThread::invalidateTracks() mixer %p, streamType %d, mTracks.size %zu", 295281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent this, streamType, mTracks.size()); 295313084621072ea2e4c34e2a9d79793c621d9bf005Eric Laurent bool trackMatch = false; 295481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent size_t size = mTracks.size(); 295581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent for (size_t i = 0; i < size; i++) { 295681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent sp<Track> t = mTracks[i]; 2957d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent if (t->streamType() == streamType && t->isExternalTrack()) { 29585736c35b841de56ce394b4879389f669b61425e6Glenn Kasten t->invalidate(); 295913084621072ea2e4c34e2a9d79793c621d9bf005Eric Laurent trackMatch = true; 296081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 296181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 296213084621072ea2e4c34e2a9d79793c621d9bf005Eric Laurent return trackMatch; 296381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 296481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 296505317d29b27e5fda654bea21b80d4423a03f49b3Haynes Mathew Georgevoid AudioFlinger::PlaybackThread::invalidateTracks(audio_stream_type_t streamType) 296605317d29b27e5fda654bea21b80d4423a03f49b3Haynes Mathew George{ 296705317d29b27e5fda654bea21b80d4423a03f49b3Haynes Mathew George Mutex::Autolock _l(mLock); 296805317d29b27e5fda654bea21b80d4423a03f49b3Haynes Mathew George invalidateTracks_l(streamType); 296905317d29b27e5fda654bea21b80d4423a03f49b3Haynes Mathew George} 297005317d29b27e5fda654bea21b80d4423a03f49b3Haynes Mathew George 297181784c37c61b09289654b979567a42bf73cd2b12Eric Laurentstatus_t AudioFlinger::PlaybackThread::addEffectChain_l(const sp<EffectChain>& chain) 297281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 2973d848eb48c121c119e8ba7583efc75415fe102570Glenn Kasten audio_session_t session = chain->sessionId(); 2974022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov sp<EffectBufferHalInterface> halInBuffer, halOutBuffer; 29757588ff418aca63b1dc43a85afc1e86c40dd889a3Kevin Rocard status_t result = mAudioFlinger->mEffectsFactoryHal->mirrorBuffer( 2976022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov mEffectBufferEnabled ? mEffectBuffer : mSinkBuffer, 2977022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov mEffectBufferEnabled ? mEffectBufferSize : mSinkBufferSize, 2978022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov &halInBuffer); 2979022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov if (result != OK) return result; 2980022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov halOutBuffer = halInBuffer; 298194a1ee822686e920a33e312f4032f991731aea07rago effect_buffer_t *buffer = reinterpret_cast<effect_buffer_t*>(halInBuffer->externalData()); 298281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent ALOGV("addEffectChain_l() %p on thread %p for session %d", chain.get(), this, session); 2983d848eb48c121c119e8ba7583efc75415fe102570Glenn Kasten if (session > AUDIO_SESSION_OUTPUT_MIX) { 298481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // Only one effect chain can be present in direct output thread and it uses 29852098f2744cedf2dc3fa36f608aa965a34602e7c0Andy Hung // the sink buffer as input 298681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (mType != DIRECT) { 298781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent size_t numSamples = mNormalFrameCount * mChannelCount; 29887588ff418aca63b1dc43a85afc1e86c40dd889a3Kevin Rocard status_t result = mAudioFlinger->mEffectsFactoryHal->allocateBuffer( 298994a1ee822686e920a33e312f4032f991731aea07rago numSamples * sizeof(effect_buffer_t), 2990022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov &halInBuffer); 2991022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov if (result != OK) return result; 299294a1ee822686e920a33e312f4032f991731aea07rago#ifdef FLOAT_EFFECT_CHAIN 299394a1ee822686e920a33e312f4032f991731aea07rago buffer = halInBuffer->audioBuffer()->f32; 299494a1ee822686e920a33e312f4032f991731aea07rago#else 2995022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov buffer = halInBuffer->audioBuffer()->s16; 299694a1ee822686e920a33e312f4032f991731aea07rago#endif 2997022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov ALOGV("addEffectChain_l() creating new input buffer %p session %d", 2998022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov buffer, session); 299981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 300081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 300181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // Attach all tracks with same session ID to this chain. 300281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent for (size_t i = 0; i < mTracks.size(); ++i) { 300381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent sp<Track> track = mTracks[i]; 300481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (session == track->sessionId()) { 300581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent ALOGV("addEffectChain_l() track->setMainBuffer track %p buffer %p", track.get(), 300681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent buffer); 300781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent track->setMainBuffer(buffer); 300881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent chain->incTrackCnt(); 300981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 301081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 301181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 301281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // indicate all active tracks in the chain 3013dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hung for (const sp<Track> &track : mActiveTracks) { 301481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (session == track->sessionId()) { 301581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent ALOGV("addEffectChain_l() activating track %p on session %d", track.get(), session); 301681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent chain->incActiveTrackCnt(); 301781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 301881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 301981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 3020aaa44478a373232d8416657035a9020f9c7aa7c3Eric Laurent chain->setThread(this); 3021022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov chain->setInBuffer(halInBuffer); 3022022b9953153bdb1984f0abb17d21ef8c1826ad49Mikhail Naganov chain->setOutBuffer(halOutBuffer); 302381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // Effect chain for session AUDIO_SESSION_OUTPUT_STAGE is inserted at end of effect 3024d848eb48c121c119e8ba7583efc75415fe102570Glenn Kasten // chains list in order to be processed last as it contains output stage effects. 302581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // Effect chain for session AUDIO_SESSION_OUTPUT_MIX is inserted before 302681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // session AUDIO_SESSION_OUTPUT_STAGE to be processed 3027d848eb48c121c119e8ba7583efc75415fe102570Glenn Kasten // after track specific effects and before output stage. 302881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // It is therefore mandatory that AUDIO_SESSION_OUTPUT_MIX == 0 and 3029d848eb48c121c119e8ba7583efc75415fe102570Glenn Kasten // that AUDIO_SESSION_OUTPUT_STAGE < AUDIO_SESSION_OUTPUT_MIX. 303081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // Effect chain for other sessions are inserted at beginning of effect 303181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // chains list to be processed before output mix effects. Relative order between other 3032d848eb48c121c119e8ba7583efc75415fe102570Glenn Kasten // sessions is not important. 3033d848eb48c121c119e8ba7583efc75415fe102570Glenn Kasten static_assert(AUDIO_SESSION_OUTPUT_MIX == 0 && 3034d848eb48c121c119e8ba7583efc75415fe102570Glenn Kasten AUDIO_SESSION_OUTPUT_STAGE < AUDIO_SESSION_OUTPUT_MIX, 3035d848eb48c121c119e8ba7583efc75415fe102570Glenn Kasten "audio_session_t constants misdefined"); 303681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent size_t size = mEffectChains.size(); 303781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent size_t i = 0; 303881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent for (i = 0; i < size; i++) { 303981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (mEffectChains[i]->sessionId() < session) { 304081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent break; 304181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 304281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 304381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mEffectChains.insertAt(chain, i); 304481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent checkSuspendOnAddEffectChain_l(chain); 304581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 304681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent return NO_ERROR; 304781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 304881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 304981784c37c61b09289654b979567a42bf73cd2b12Eric Laurentsize_t AudioFlinger::PlaybackThread::removeEffectChain_l(const sp<EffectChain>& chain) 305081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 3051d848eb48c121c119e8ba7583efc75415fe102570Glenn Kasten audio_session_t session = chain->sessionId(); 305281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 305381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent ALOGV("removeEffectChain_l() %p from thread %p for session %d", chain.get(), this, session); 305481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 305581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent for (size_t i = 0; i < mEffectChains.size(); i++) { 305681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (chain == mEffectChains[i]) { 305781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mEffectChains.removeAt(i); 305881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // detach all active tracks from the chain 3059dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hung for (const sp<Track> &track : mActiveTracks) { 306081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (session == track->sessionId()) { 306181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent ALOGV("removeEffectChain_l(): stopping track on chain %p for session Id: %d", 306281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent chain.get(), session); 306381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent chain->decActiveTrackCnt(); 306481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 306581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 306681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 306781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // detach all tracks with same session ID from this chain 306881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent for (size_t i = 0; i < mTracks.size(); ++i) { 306981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent sp<Track> track = mTracks[i]; 307081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (session == track->sessionId()) { 307194a1ee822686e920a33e312f4032f991731aea07rago track->setMainBuffer(reinterpret_cast<effect_buffer_t*>(mSinkBuffer)); 307281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent chain->decTrackCnt(); 307381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 307481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 307581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent break; 307681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 307781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 307881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent return mEffectChains.size(); 307981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 308081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 308181784c37c61b09289654b979567a42bf73cd2b12Eric Laurentstatus_t AudioFlinger::PlaybackThread::attachAuxEffect( 3082e964d4e421e2d1ca937227a580c0c837091a11e3Chih-Hung Hsieh const sp<AudioFlinger::PlaybackThread::Track>& track, int EffectId) 308381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 308481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent Mutex::Autolock _l(mLock); 308581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent return attachAuxEffect_l(track, EffectId); 308681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 308781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 308881784c37c61b09289654b979567a42bf73cd2b12Eric Laurentstatus_t AudioFlinger::PlaybackThread::attachAuxEffect_l( 3089e964d4e421e2d1ca937227a580c0c837091a11e3Chih-Hung Hsieh const sp<AudioFlinger::PlaybackThread::Track>& track, int EffectId) 309081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 309181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent status_t status = NO_ERROR; 309281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 309381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (EffectId == 0) { 309481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent track->setAuxBuffer(0, NULL); 309581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } else { 309681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // Auxiliary effects are always in audio session AUDIO_SESSION_OUTPUT_MIX 309781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent sp<EffectModule> effect = getEffect_l(AUDIO_SESSION_OUTPUT_MIX, EffectId); 309881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (effect != 0) { 309981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if ((effect->desc().flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_AUXILIARY) { 310081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent track->setAuxBuffer(EffectId, (int32_t *)effect->inBuffer()); 310181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } else { 310281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent status = INVALID_OPERATION; 310381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 310481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } else { 310581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent status = BAD_VALUE; 310681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 310781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 310881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent return status; 310981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 311081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 311181784c37c61b09289654b979567a42bf73cd2b12Eric Laurentvoid AudioFlinger::PlaybackThread::detachAuxEffect_l(int effectId) 311281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 311381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent for (size_t i = 0; i < mTracks.size(); ++i) { 311481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent sp<Track> track = mTracks[i]; 311581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (track->auxEffectId() == effectId) { 311681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent attachAuxEffect_l(track, 0); 311781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 311881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 311981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 312081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 312181784c37c61b09289654b979567a42bf73cd2b12Eric Laurentbool AudioFlinger::PlaybackThread::threadLoop() 312281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 3123388d57148e8bd330e855be0f51c72d577feb2ee9Glenn Kasten tlNBLogWriter = mNBLogWriter.get(); 3124fe1e1449cadff4f946c33403aecc73b4b4a11e56Nicolas Roulet 312581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent Vector< sp<Track> > tracksToRemove; 312681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 3127ad9cb8b88e4f8face23f01d8dc89fa769dacb50fEric Laurent mStandbyTimeNs = systemTime(); 312869488c4ef115c9de52c85f4fcae27c7774720298Andy Hung nsecs_t lastWriteFinished = -1; // time last server write completed 312969488c4ef115c9de52c85f4fcae27c7774720298Andy Hung int64_t lastFramesWritten = -1; // track changes in timestamp server frames written 313081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 313181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // MIXER 313281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent nsecs_t lastWarning = 0; 313381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 313481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // DUPLICATING 313581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // FIXME could this be made local to while loop? 313681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent writeFrames = 0; 313781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 313881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent cacheParameters_l(); 3139ad9cb8b88e4f8face23f01d8dc89fa769dacb50fEric Laurent mSleepTimeUs = mIdleSleepTimeUs; 314081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 314181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (mType == MIXER) { 314281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent sleepTimeShift = 0; 314381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 314481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 314581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent CpuStats cpuStats; 314681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent const String8 myName(String8::format("thread %p type %d TID %d", this, mType, gettid())); 314781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 314881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent acquireWakeLock(); 314981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 3150eef598c5539aa2be5a106f2483b19e368e4b8c0eGlenn Kasten // mNBLogWriter logging APIs can only be called by a single thread, typically the 3151eef598c5539aa2be5a106f2483b19e368e4b8c0eGlenn Kasten // thread associated with this PlaybackThread. 3152eef598c5539aa2be5a106f2483b19e368e4b8c0eGlenn Kasten // If you want to share the mNBLogWriter with other threads (for example, binder threads) 3153eef598c5539aa2be5a106f2483b19e368e4b8c0eGlenn Kasten // then all such threads must agree to hold a common mutex before logging. 31549e58b552f51b00b3b674102876bd6c77ef3da806Glenn Kasten // So if you need to log when mutex is unlocked, set logString to a non-NULL string, 31559e58b552f51b00b3b674102876bd6c77ef3da806Glenn Kasten // and then that string will be logged at the next convenient opportunity. 3156eef598c5539aa2be5a106f2483b19e368e4b8c0eGlenn Kasten // See reference to logString below. 31579e58b552f51b00b3b674102876bd6c77ef3da806Glenn Kasten const char *logString = NULL; 31589e58b552f51b00b3b674102876bd6c77ef3da806Glenn Kasten 31591bb9082596c9cac2995dc9b4465a7c6d5666d099rago // Estimated time for next buffer to be written to hal. This is used only on 31601bb9082596c9cac2995dc9b4465a7c6d5666d099rago // suspended mode (for now) to help schedule the wait time until next iteration. 31611bb9082596c9cac2995dc9b4465a7c6d5666d099rago nsecs_t timeLoopNextNs = 0; 31621bb9082596c9cac2995dc9b4465a7c6d5666d099rago 3163664539d25180ab8f77e0521533ea2821cf28985fEric Laurent checkSilentMode_l(); 3164eef598c5539aa2be5a106f2483b19e368e4b8c0eGlenn Kasten 316581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent while (!exitPending()) 316681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent { 3167dcdfaecc1fa630a799e1fdb508a9b92da55abc36Nicolas Roulet // Log merge requests are performed during AudioFlinger binder transactions, but 3168dcdfaecc1fa630a799e1fdb508a9b92da55abc36Nicolas Roulet // that does not cover audio playback. It's requested here for that reason. 3169dcdfaecc1fa630a799e1fdb508a9b92da55abc36Nicolas Roulet mAudioFlinger->requestLogMerge(); 3170dcdfaecc1fa630a799e1fdb508a9b92da55abc36Nicolas Roulet 317181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent cpuStats.sample(myName); 317281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 317381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent Vector< sp<EffectChain> > effectChains; 317481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 317581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent { // scope for mLock 317681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 317781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent Mutex::Autolock _l(mLock); 317881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 3179021cf9634ab09c0753a40b7c9ef4ba603be5c3daEric Laurent processConfigEvents_l(); 31801035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent 3181eef598c5539aa2be5a106f2483b19e368e4b8c0eGlenn Kasten // See comment at declaration of logString for why this is done under mLock 31829e58b552f51b00b3b674102876bd6c77ef3da806Glenn Kasten if (logString != NULL) { 31839e58b552f51b00b3b674102876bd6c77ef3da806Glenn Kasten mNBLogWriter->logTimestamp(); 31849e58b552f51b00b3b674102876bd6c77ef3da806Glenn Kasten mNBLogWriter->log(logString); 31859e58b552f51b00b3b674102876bd6c77ef3da806Glenn Kasten logString = NULL; 31869e58b552f51b00b3b674102876bd6c77ef3da806Glenn Kasten } 31879e58b552f51b00b3b674102876bd6c77ef3da806Glenn Kasten 31884c053ea158b29fa2cdd4c6f39d3c8da4ee5a7a02Glenn Kasten // Gather the framesReleased counters for all active tracks, 3189e10393e72454bfd8298017dc193faf424f4e9a8fAndy Hung // and associate with the sink frames written out. We need 3190e10393e72454bfd8298017dc193faf424f4e9a8fAndy Hung // this to convert the sink timestamp to the track timestamp. 319169488c4ef115c9de52c85f4fcae27c7774720298Andy Hung bool kernelLocationUpdate = false; 3192e10393e72454bfd8298017dc193faf424f4e9a8fAndy Hung if (mNormalSink != 0) { 3193c54b1ffc92b8ad27608a8af21033d7cab33cb3a0Andy Hung // Note: The DuplicatingThread may not have a mNormalSink. 3194818e7a32ce3633980138aff2c2bfcc5158b3cfccAndy Hung // We always fetch the timestamp here because often the downstream 319569488c4ef115c9de52c85f4fcae27c7774720298Andy Hung // sink will block while writing. 3196818e7a32ce3633980138aff2c2bfcc5158b3cfccAndy Hung ExtendedTimestamp timestamp; // use private copy to fetch 3197818e7a32ce3633980138aff2c2bfcc5158b3cfccAndy Hung (void) mNormalSink->getTimestamp(timestamp); 31986d7b119a416c9f10288051e562f294365e5d954cAndy Hung 31996d7b119a416c9f10288051e562f294365e5d954cAndy Hung // We keep track of the last valid kernel position in case we are in underrun 32006d7b119a416c9f10288051e562f294365e5d954cAndy Hung // and the normal mixer period is the same as the fast mixer period, or there 32016d7b119a416c9f10288051e562f294365e5d954cAndy Hung // is some error from the HAL. 32026d7b119a416c9f10288051e562f294365e5d954cAndy Hung if (mTimestamp.mTimeNs[ExtendedTimestamp::LOCATION_KERNEL] >= 0) { 32036d7b119a416c9f10288051e562f294365e5d954cAndy Hung mTimestamp.mPosition[ExtendedTimestamp::LOCATION_KERNEL_LASTKERNELOK] = 32046d7b119a416c9f10288051e562f294365e5d954cAndy Hung mTimestamp.mPosition[ExtendedTimestamp::LOCATION_KERNEL]; 32056d7b119a416c9f10288051e562f294365e5d954cAndy Hung mTimestamp.mTimeNs[ExtendedTimestamp::LOCATION_KERNEL_LASTKERNELOK] = 32066d7b119a416c9f10288051e562f294365e5d954cAndy Hung mTimestamp.mTimeNs[ExtendedTimestamp::LOCATION_KERNEL]; 32076d7b119a416c9f10288051e562f294365e5d954cAndy Hung 32086d7b119a416c9f10288051e562f294365e5d954cAndy Hung mTimestamp.mPosition[ExtendedTimestamp::LOCATION_SERVER_LASTKERNELOK] = 32096d7b119a416c9f10288051e562f294365e5d954cAndy Hung mTimestamp.mPosition[ExtendedTimestamp::LOCATION_SERVER]; 32106d7b119a416c9f10288051e562f294365e5d954cAndy Hung mTimestamp.mTimeNs[ExtendedTimestamp::LOCATION_SERVER_LASTKERNELOK] = 32116d7b119a416c9f10288051e562f294365e5d954cAndy Hung mTimestamp.mTimeNs[ExtendedTimestamp::LOCATION_SERVER]; 321269488c4ef115c9de52c85f4fcae27c7774720298Andy Hung } 321369488c4ef115c9de52c85f4fcae27c7774720298Andy Hung 321469488c4ef115c9de52c85f4fcae27c7774720298Andy Hung if (timestamp.mTimeNs[ExtendedTimestamp::LOCATION_KERNEL] >= 0) { 321569488c4ef115c9de52c85f4fcae27c7774720298Andy Hung kernelLocationUpdate = true; 32166d7b119a416c9f10288051e562f294365e5d954cAndy Hung } else { 3217122f7e793fe6fb8904634cc6d2e35ac4b014ea72Eric Laurent ALOGVV("getTimestamp error - no valid kernel position"); 32186d7b119a416c9f10288051e562f294365e5d954cAndy Hung } 32196d7b119a416c9f10288051e562f294365e5d954cAndy Hung 3220818e7a32ce3633980138aff2c2bfcc5158b3cfccAndy Hung // copy over kernel info 3221818e7a32ce3633980138aff2c2bfcc5158b3cfccAndy Hung mTimestamp.mPosition[ExtendedTimestamp::LOCATION_KERNEL] = 3222238fa3deff26d7e4d9e81bd0a88c936f16226c4eAndy Hung timestamp.mPosition[ExtendedTimestamp::LOCATION_KERNEL] 3223238fa3deff26d7e4d9e81bd0a88c936f16226c4eAndy Hung + mSuspendedFrames; // add frames discarded when suspended 3224818e7a32ce3633980138aff2c2bfcc5158b3cfccAndy Hung mTimestamp.mTimeNs[ExtendedTimestamp::LOCATION_KERNEL] = 3225818e7a32ce3633980138aff2c2bfcc5158b3cfccAndy Hung timestamp.mTimeNs[ExtendedTimestamp::LOCATION_KERNEL]; 3226c54b1ffc92b8ad27608a8af21033d7cab33cb3a0Andy Hung } 3227c54b1ffc92b8ad27608a8af21033d7cab33cb3a0Andy Hung // mFramesWritten for non-offloaded tracks are contiguous 3228c54b1ffc92b8ad27608a8af21033d7cab33cb3a0Andy Hung // even after standby() is called. This is useful for the track frame 3229c54b1ffc92b8ad27608a8af21033d7cab33cb3a0Andy Hung // to sink frame mapping. 323069488c4ef115c9de52c85f4fcae27c7774720298Andy Hung bool serverLocationUpdate = false; 323169488c4ef115c9de52c85f4fcae27c7774720298Andy Hung if (mFramesWritten != lastFramesWritten) { 323269488c4ef115c9de52c85f4fcae27c7774720298Andy Hung serverLocationUpdate = true; 323369488c4ef115c9de52c85f4fcae27c7774720298Andy Hung lastFramesWritten = mFramesWritten; 323469488c4ef115c9de52c85f4fcae27c7774720298Andy Hung } 323569488c4ef115c9de52c85f4fcae27c7774720298Andy Hung // Only update timestamps if there is a meaningful change. 323669488c4ef115c9de52c85f4fcae27c7774720298Andy Hung // Either the kernel timestamp must be valid or we have written something. 323769488c4ef115c9de52c85f4fcae27c7774720298Andy Hung if (kernelLocationUpdate || serverLocationUpdate) { 323869488c4ef115c9de52c85f4fcae27c7774720298Andy Hung if (serverLocationUpdate) { 323969488c4ef115c9de52c85f4fcae27c7774720298Andy Hung // use the time before we called the HAL write - it is a bit more accurate 324069488c4ef115c9de52c85f4fcae27c7774720298Andy Hung // to when the server last read data than the current time here. 324169488c4ef115c9de52c85f4fcae27c7774720298Andy Hung // 324269488c4ef115c9de52c85f4fcae27c7774720298Andy Hung // If we haven't written anything, mLastWriteTime will be -1 324369488c4ef115c9de52c85f4fcae27c7774720298Andy Hung // and we use systemTime(). 324469488c4ef115c9de52c85f4fcae27c7774720298Andy Hung mTimestamp.mPosition[ExtendedTimestamp::LOCATION_SERVER] = mFramesWritten; 324569488c4ef115c9de52c85f4fcae27c7774720298Andy Hung mTimestamp.mTimeNs[ExtendedTimestamp::LOCATION_SERVER] = mLastWriteTime == -1 324669488c4ef115c9de52c85f4fcae27c7774720298Andy Hung ? systemTime() : mLastWriteTime; 324769488c4ef115c9de52c85f4fcae27c7774720298Andy Hung } 3248dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hung 3249dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hung for (const sp<Track> &t : mActiveTracks) { 3250dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hung if (!t->isFastTrack()) { 325169488c4ef115c9de52c85f4fcae27c7774720298Andy Hung t->updateTrackFrameInfo( 325269488c4ef115c9de52c85f4fcae27c7774720298Andy Hung t->mAudioTrackServerProxy->framesReleased(), 325369488c4ef115c9de52c85f4fcae27c7774720298Andy Hung mFramesWritten, 325469488c4ef115c9de52c85f4fcae27c7774720298Andy Hung mTimestamp); 325569488c4ef115c9de52c85f4fcae27c7774720298Andy Hung } 32564c053ea158b29fa2cdd4c6f39d3c8da4ee5a7a02Glenn Kasten } 3257bd096fd9d8e5fc0e62f98807f4818a06f70d0812Glenn Kasten } 3258fe1e1449cadff4f946c33403aecc73b4b4a11e56Nicolas Roulet#if 0 3259fe1e1449cadff4f946c33403aecc73b4b4a11e56Nicolas Roulet // logFormat example 3260c20cb50c1c14cd765874511872f087c875f43ed9Nicolas Roulet if (z % 100 == 0) { 3261fe1e1449cadff4f946c33403aecc73b4b4a11e56Nicolas Roulet timespec ts; 3262fe1e1449cadff4f946c33403aecc73b4b4a11e56Nicolas Roulet clock_gettime(CLOCK_MONOTONIC, &ts); 32634da7820be451847bad698ac0f687b964d9b5d34fNicolas Roulet LOGT("This is an integer %d, this is a float %f, this is my " 3264fe1e1449cadff4f946c33403aecc73b4b4a11e56Nicolas Roulet "pid %p %% %s %t", 42, 3.14, "and this is a timestamp", ts); 32654da7820be451847bad698ac0f687b964d9b5d34fNicolas Roulet LOGT("A deceptive null-terminated string %\0"); 3266fe1e1449cadff4f946c33403aecc73b4b4a11e56Nicolas Roulet } 3267fe1e1449cadff4f946c33403aecc73b4b4a11e56Nicolas Roulet ++z; 3268fe1e1449cadff4f946c33403aecc73b4b4a11e56Nicolas Roulet#endif 326981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent saveOutputTracks(); 3270bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent if (mSignalPending) { 3271bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent // A signal was raised while we were unlocked 3272bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent mSignalPending = false; 3273bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent } else if (waitingAsyncCallback_l()) { 3274bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent if (exitPending()) { 3275bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent break; 3276bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent } 3277078538cfc6c4682889ed52de460d29c0d15bb9ebMarco Nelissen bool released = false; 3278646679779a8f952980a5d4219ad9c6f93efc4b92Eric Laurent if (!keepWakeLock()) { 3279078538cfc6c4682889ed52de460d29c0d15bb9ebMarco Nelissen releaseWakeLock_l(); 3280078538cfc6c4682889ed52de460d29c0d15bb9ebMarco Nelissen released = true; 3281078538cfc6c4682889ed52de460d29c0d15bb9ebMarco Nelissen } 328210cbff139360f3f642e0e3b3ccf2d463dbed22cfAndy Hung 328310cbff139360f3f642e0e3b3ccf2d463dbed22cfAndy Hung const int64_t waitNs = computeWaitTimeNs_l(); 328410cbff139360f3f642e0e3b3ccf2d463dbed22cfAndy Hung ALOGV("wait async completion (wait time: %lld)", (long long)waitNs); 328510cbff139360f3f642e0e3b3ccf2d463dbed22cfAndy Hung status_t status = mWaitWorkCV.waitRelative(mLock, waitNs); 328610cbff139360f3f642e0e3b3ccf2d463dbed22cfAndy Hung if (status == TIMED_OUT) { 328710cbff139360f3f642e0e3b3ccf2d463dbed22cfAndy Hung mSignalPending = true; // if timeout recheck everything 328810cbff139360f3f642e0e3b3ccf2d463dbed22cfAndy Hung } 3289bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent ALOGV("async completion/wake"); 3290078538cfc6c4682889ed52de460d29c0d15bb9ebMarco Nelissen if (released) { 3291078538cfc6c4682889ed52de460d29c0d15bb9ebMarco Nelissen acquireWakeLock_l(); 3292078538cfc6c4682889ed52de460d29c0d15bb9ebMarco Nelissen } 3293ad9cb8b88e4f8face23f01d8dc89fa769dacb50fEric Laurent mStandbyTimeNs = systemTime() + mStandbyDelayNs; 3294ad9cb8b88e4f8face23f01d8dc89fa769dacb50fEric Laurent mSleepTimeUs = 0; 3295ede6c3b8b1147bc425f7b923882f559a513fe23bEric Laurent 3296ede6c3b8b1147bc425f7b923882f559a513fe23bEric Laurent continue; 3297ede6c3b8b1147bc425f7b923882f559a513fe23bEric Laurent } 3298ad9cb8b88e4f8face23f01d8dc89fa769dacb50fEric Laurent if ((!mActiveTracks.size() && systemTime() > mStandbyTimeNs) || 3299bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent isSuspended()) { 3300bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent // put audio hardware into standby after short delay 3301bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent if (shouldStandby_l()) { 330281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 330381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent threadLoop_standby(); 330481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 33052a6a945d65c986dcc779f70f18afde1d7a74397bSanna Catherine de Treville Wager // This is where we go into standby 33062a6a945d65c986dcc779f70f18afde1d7a74397bSanna Catherine de Treville Wager if (!mStandby) { 33072a6a945d65c986dcc779f70f18afde1d7a74397bSanna Catherine de Treville Wager LOG_AUDIO_STATE(); 33082a6a945d65c986dcc779f70f18afde1d7a74397bSanna Catherine de Treville Wager } 330981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mStandby = true; 331081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 331181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 331281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (!mActiveTracks.size() && mConfigEvents.isEmpty()) { 331381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // we're about to wait, flush the binder command buffer 331481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent IPCThreadState::self()->flushCommands(); 331581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 331681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent clearOutputTracks(); 331781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 331881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (exitPending()) { 331981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent break; 332081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 332181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 332281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent releaseWakeLock_l(); 332381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // wait until we have something to do... 332481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent ALOGV("%s going to sleep", myName.string()); 332581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mWaitWorkCV.wait(mLock); 332681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent ALOGV("%s waking up", myName.string()); 332781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent acquireWakeLock_l(); 332881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 332981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mMixerStatus = MIXER_IDLE; 333081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mMixerStatusIgnoringFastTracks = MIXER_IDLE; 333181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mBytesWritten = 0; 3332bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent mBytesRemaining = 0; 333381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent checkSilentMode_l(); 333481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 3335ad9cb8b88e4f8face23f01d8dc89fa769dacb50fEric Laurent mStandbyTimeNs = systemTime() + mStandbyDelayNs; 3336ad9cb8b88e4f8face23f01d8dc89fa769dacb50fEric Laurent mSleepTimeUs = mIdleSleepTimeUs; 333781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (mType == MIXER) { 333881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent sleepTimeShift = 0; 333981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 334081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 334181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent continue; 334281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 334381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 334481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // mMixerStatusIgnoringFastTracks is also updated internally 334581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mMixerStatus = prepareTracks_l(&tracksToRemove); 334681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 3347dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hung mActiveTracks.updatePowerState(this); 3348462fd2fa9eef642b0574aa7409de0bde3fec8d43Marco Nelissen 3349069c2719e753732d5af9ba51e5fcc34342b0c9f2Kevin Rocard updateMetadata_l(); 3350069c2719e753732d5af9ba51e5fcc34342b0c9f2Kevin Rocard 335181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // prevent any changes in effect chain list and in each effect chain 335281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // during mixing and effect process as the audio buffers could be deleted 335381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // or modified if an effect is created or deleted 335481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent lockEffectChains_l(effectChains); 3355462fd2fa9eef642b0574aa7409de0bde3fec8d43Marco Nelissen } // mLock scope ends 335681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 3357bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent if (mBytesRemaining == 0) { 3358bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent mCurrentWriteLength = 0; 3359bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent if (mMixerStatus == MIXER_TRACKS_READY) { 3360bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent // threadLoop_mix() sets mCurrentWriteLength 3361bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent threadLoop_mix(); 3362bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent } else if ((mMixerStatus != MIXER_DRAIN_TRACK) 3363bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent && (mMixerStatus != MIXER_DRAIN_ALL)) { 3364ad9cb8b88e4f8face23f01d8dc89fa769dacb50fEric Laurent // threadLoop_sleepTime sets mSleepTimeUs to 0 if data 3365bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent // must be written to HAL 3366bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent threadLoop_sleepTime(); 3367ad9cb8b88e4f8face23f01d8dc89fa769dacb50fEric Laurent if (mSleepTimeUs == 0) { 336825c2dac12114699e90deb1c579cadebce7b91a97Andy Hung mCurrentWriteLength = mSinkBufferSize; 3369bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent } 3370bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent } 337198ef978df4e928f486d244c4d7f7ad9f13111e98Andy Hung // Either threadLoop_mix() or threadLoop_sleepTime() should have set 3372ad9cb8b88e4f8face23f01d8dc89fa769dacb50fEric Laurent // mMixerBuffer with data if mMixerBufferValid is true and mSleepTimeUs == 0. 337398ef978df4e928f486d244c4d7f7ad9f13111e98Andy Hung // Merge mMixerBuffer data into mEffectBuffer (if any effects are valid) 337498ef978df4e928f486d244c4d7f7ad9f13111e98Andy Hung // or mSinkBuffer (if there are no effects). 337598ef978df4e928f486d244c4d7f7ad9f13111e98Andy Hung // 337698ef978df4e928f486d244c4d7f7ad9f13111e98Andy Hung // This is done pre-effects computation; if effects change to 337798ef978df4e928f486d244c4d7f7ad9f13111e98Andy Hung // support higher precision, this needs to move. 337898ef978df4e928f486d244c4d7f7ad9f13111e98Andy Hung // 337998ef978df4e928f486d244c4d7f7ad9f13111e98Andy Hung // mMixerBufferValid is only set true by MixerThread::prepareTracks_l(). 3380ad9cb8b88e4f8face23f01d8dc89fa769dacb50fEric Laurent // TODO use mSleepTimeUs == 0 as an additional condition. 338198ef978df4e928f486d244c4d7f7ad9f13111e98Andy Hung if (mMixerBufferValid) { 338298ef978df4e928f486d244c4d7f7ad9f13111e98Andy Hung void *buffer = mEffectBufferValid ? mEffectBuffer : mSinkBuffer; 338398ef978df4e928f486d244c4d7f7ad9f13111e98Andy Hung audio_format_t format = mEffectBufferValid ? mEffectBufferFormat : mFormat; 338498ef978df4e928f486d244c4d7f7ad9f13111e98Andy Hung 33852ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hung // mono blend occurs for mixer threads only (not direct or offloaded) 33862ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hung // and is handled here if we're going directly to the sink. 33872ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hung if (requireMonoBlend() && !mEffectBufferValid) { 338803c48d5afcb3dfc1e43df93e1f3b3b3e9292e148Glenn Kasten mono_blend(mMixerBuffer, mMixerBufferFormat, mChannelCount, mNormalFrameCount, 338903c48d5afcb3dfc1e43df93e1f3b3b3e9292e148Glenn Kasten true /*limit*/); 33902ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hung } 33912ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hung 339298ef978df4e928f486d244c4d7f7ad9f13111e98Andy Hung memcpy_by_audio_format(buffer, format, mMixerBuffer, mMixerBufferFormat, 339398ef978df4e928f486d244c4d7f7ad9f13111e98Andy Hung mNormalFrameCount * mChannelCount); 339498ef978df4e928f486d244c4d7f7ad9f13111e98Andy Hung } 339598ef978df4e928f486d244c4d7f7ad9f13111e98Andy Hung 3396bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent mBytesRemaining = mCurrentWriteLength; 3397bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent if (isSuspended()) { 3398238fa3deff26d7e4d9e81bd0a88c936f16226c4eAndy Hung // Simulate write to HAL when suspended (e.g. BT SCO phone call). 3399238fa3deff26d7e4d9e81bd0a88c936f16226c4eAndy Hung mSleepTimeUs = suspendSleepTimeUs(); // assumes full buffer. 3400238fa3deff26d7e4d9e81bd0a88c936f16226c4eAndy Hung const size_t framesRemaining = mBytesRemaining / mFrameSize; 3401238fa3deff26d7e4d9e81bd0a88c936f16226c4eAndy Hung mBytesWritten += mBytesRemaining; 3402238fa3deff26d7e4d9e81bd0a88c936f16226c4eAndy Hung mFramesWritten += framesRemaining; 3403238fa3deff26d7e4d9e81bd0a88c936f16226c4eAndy Hung mSuspendedFrames += framesRemaining; // to adjust kernel HAL position 3404bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent mBytesRemaining = 0; 3405bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent } 340681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 3407bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent // only process effects if we're going to write 3408ad9cb8b88e4f8face23f01d8dc89fa769dacb50fEric Laurent if (mSleepTimeUs == 0 && mType != OFFLOAD) { 3409bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent for (size_t i = 0; i < effectChains.size(); i ++) { 3410bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent effectChains[i]->process_l(); 3411bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent } 341281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 341381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 341459fe010bcc072597852454a2ec53d7b0a2002a3bEric Laurent // Process effect chains for offloaded thread even if no audio 341559fe010bcc072597852454a2ec53d7b0a2002a3bEric Laurent // was read from audio track: process only updates effect state 341659fe010bcc072597852454a2ec53d7b0a2002a3bEric Laurent // and thus does have to be synchronized with audio writes but may have 341759fe010bcc072597852454a2ec53d7b0a2002a3bEric Laurent // to be called while waiting for async write callback 341859fe010bcc072597852454a2ec53d7b0a2002a3bEric Laurent if (mType == OFFLOAD) { 341959fe010bcc072597852454a2ec53d7b0a2002a3bEric Laurent for (size_t i = 0; i < effectChains.size(); i ++) { 342059fe010bcc072597852454a2ec53d7b0a2002a3bEric Laurent effectChains[i]->process_l(); 342159fe010bcc072597852454a2ec53d7b0a2002a3bEric Laurent } 342259fe010bcc072597852454a2ec53d7b0a2002a3bEric Laurent } 342381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 342498ef978df4e928f486d244c4d7f7ad9f13111e98Andy Hung // Only if the Effects buffer is enabled and there is data in the 342598ef978df4e928f486d244c4d7f7ad9f13111e98Andy Hung // Effects buffer (buffer valid), we need to 342698ef978df4e928f486d244c4d7f7ad9f13111e98Andy Hung // copy into the sink buffer. 3427ad9cb8b88e4f8face23f01d8dc89fa769dacb50fEric Laurent // TODO use mSleepTimeUs == 0 as an additional condition. 342898ef978df4e928f486d244c4d7f7ad9f13111e98Andy Hung if (mEffectBufferValid) { 342998ef978df4e928f486d244c4d7f7ad9f13111e98Andy Hung //ALOGV("writing effect buffer to sink buffer format %#x", mFormat); 34302ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hung 34312ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hung if (requireMonoBlend()) { 343203c48d5afcb3dfc1e43df93e1f3b3b3e9292e148Glenn Kasten mono_blend(mEffectBuffer, mEffectBufferFormat, mChannelCount, mNormalFrameCount, 343303c48d5afcb3dfc1e43df93e1f3b3b3e9292e148Glenn Kasten true /*limit*/); 34342ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hung } 34352ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hung 343698ef978df4e928f486d244c4d7f7ad9f13111e98Andy Hung memcpy_by_audio_format(mSinkBuffer, mFormat, mEffectBuffer, mEffectBufferFormat, 343798ef978df4e928f486d244c4d7f7ad9f13111e98Andy Hung mNormalFrameCount * mChannelCount); 343898ef978df4e928f486d244c4d7f7ad9f13111e98Andy Hung } 343998ef978df4e928f486d244c4d7f7ad9f13111e98Andy Hung 344081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // enable changes in effect chain 344181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent unlockEffectChains(effectChains); 344281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 3443bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent if (!waitingAsyncCallback()) { 3444ad9cb8b88e4f8face23f01d8dc89fa769dacb50fEric Laurent // mSleepTimeUs == 0 means we must write to audio hardware 3445ad9cb8b88e4f8face23f01d8dc89fa769dacb50fEric Laurent if (mSleepTimeUs == 0) { 344608fb1743f80437c38b4094070d851ea7f6d485e5Andy Hung ssize_t ret = 0; 344769488c4ef115c9de52c85f4fcae27c7774720298Andy Hung // We save lastWriteFinished here, as previousLastWriteFinished, 344869488c4ef115c9de52c85f4fcae27c7774720298Andy Hung // for throttling. On thread start, previousLastWriteFinished will be 344969488c4ef115c9de52c85f4fcae27c7774720298Andy Hung // set to -1, which properly results in no throttling after the first write. 345069488c4ef115c9de52c85f4fcae27c7774720298Andy Hung nsecs_t previousLastWriteFinished = lastWriteFinished; 345169488c4ef115c9de52c85f4fcae27c7774720298Andy Hung nsecs_t delta = 0; 3452bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent if (mBytesRemaining) { 345369488c4ef115c9de52c85f4fcae27c7774720298Andy Hung // FIXME rewrite to reduce number of system calls 345469488c4ef115c9de52c85f4fcae27c7774720298Andy Hung mLastWriteTime = systemTime(); // also used for dumpsys 345508fb1743f80437c38b4094070d851ea7f6d485e5Andy Hung ret = threadLoop_write(); 345669488c4ef115c9de52c85f4fcae27c7774720298Andy Hung lastWriteFinished = systemTime(); 345769488c4ef115c9de52c85f4fcae27c7774720298Andy Hung delta = lastWriteFinished - mLastWriteTime; 3458bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent if (ret < 0) { 3459bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent mBytesRemaining = 0; 3460bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent } else { 3461bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent mBytesWritten += ret; 3462bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent mBytesRemaining -= ret; 3463c54b1ffc92b8ad27608a8af21033d7cab33cb3a0Andy Hung mFramesWritten += ret / mFrameSize; 3464bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent } 3465bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent } else if ((mMixerStatus == MIXER_DRAIN_TRACK) || 3466bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent (mMixerStatus == MIXER_DRAIN_ALL)) { 3467bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent threadLoop_drain(); 3468bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent } 346908fb1743f80437c38b4094070d851ea7f6d485e5Andy Hung if (mType == MIXER && !mStandby) { 34704944acb7355b3aa25748fd25945a363a69d65444Glenn Kasten // write blocked detection 347108fb1743f80437c38b4094070d851ea7f6d485e5Andy Hung if (delta > maxPeriod) { 34724944acb7355b3aa25748fd25945a363a69d65444Glenn Kasten mNumDelayedWrites++; 347369488c4ef115c9de52c85f4fcae27c7774720298Andy Hung if ((lastWriteFinished - lastWarning) > kWarningThrottleNs) { 34744944acb7355b3aa25748fd25945a363a69d65444Glenn Kasten ATRACE_NAME("underrun"); 34754944acb7355b3aa25748fd25945a363a69d65444Glenn Kasten ALOGW("write blocked for %llu msecs, %d delayed writes, thread %p", 3476c42e9b462661673dff480ee71757a58b0f806370Glenn Kasten (unsigned long long) ns2ms(delta), mNumDelayedWrites, this); 347769488c4ef115c9de52c85f4fcae27c7774720298Andy Hung lastWarning = lastWriteFinished; 34784944acb7355b3aa25748fd25945a363a69d65444Glenn Kasten } 3479bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent } 348008fb1743f80437c38b4094070d851ea7f6d485e5Andy Hung 348108fb1743f80437c38b4094070d851ea7f6d485e5Andy Hung if (mThreadThrottle 348208fb1743f80437c38b4094070d851ea7f6d485e5Andy Hung && mMixerStatus == MIXER_TRACKS_READY // we are mixing (active tracks) 348308fb1743f80437c38b4094070d851ea7f6d485e5Andy Hung && ret > 0) { // we wrote something 348408fb1743f80437c38b4094070d851ea7f6d485e5Andy Hung // Limit MixerThread data processing to no more than twice the 348508fb1743f80437c38b4094070d851ea7f6d485e5Andy Hung // expected processing rate. 348608fb1743f80437c38b4094070d851ea7f6d485e5Andy Hung // 348708fb1743f80437c38b4094070d851ea7f6d485e5Andy Hung // This helps prevent underruns with NuPlayer and other applications 348808fb1743f80437c38b4094070d851ea7f6d485e5Andy Hung // which may set up buffers that are close to the minimum size, or use 348908fb1743f80437c38b4094070d851ea7f6d485e5Andy Hung // deep buffers, and rely on a double-buffering sleep strategy to fill. 349008fb1743f80437c38b4094070d851ea7f6d485e5Andy Hung // 349108fb1743f80437c38b4094070d851ea7f6d485e5Andy Hung // The throttle smooths out sudden large data drains from the device, 349208fb1743f80437c38b4094070d851ea7f6d485e5Andy Hung // e.g. when it comes out of standby, which often causes problems with 349308fb1743f80437c38b4094070d851ea7f6d485e5Andy Hung // (1) mixer threads without a fast mixer (which has its own warm-up) 349408fb1743f80437c38b4094070d851ea7f6d485e5Andy Hung // (2) minimum buffer sized tracks (even if the track is full, 349508fb1743f80437c38b4094070d851ea7f6d485e5Andy Hung // the app won't fill fast enough to handle the sudden draw). 3496f92b2175cd4a8d0fa9aca6e660ed4e85f6b7078bHaynes Mathew George // 3497f92b2175cd4a8d0fa9aca6e660ed4e85f6b7078bHaynes Mathew George // Total time spent in last processing cycle equals time spent in 3498f92b2175cd4a8d0fa9aca6e660ed4e85f6b7078bHaynes Mathew George // 1. threadLoop_write, as well as time spent in 3499f92b2175cd4a8d0fa9aca6e660ed4e85f6b7078bHaynes Mathew George // 2. threadLoop_mix (significant for heavy mixing, especially 3500f92b2175cd4a8d0fa9aca6e660ed4e85f6b7078bHaynes Mathew George // on low tier processors) 350108fb1743f80437c38b4094070d851ea7f6d485e5Andy Hung 3502e02bc544a7af12bfad32679bc5443fa1cb7b9052Ivan Lozano // it's OK if deltaMs (and deltaNs) is an overestimate. 3503e02bc544a7af12bfad32679bc5443fa1cb7b9052Ivan Lozano nsecs_t deltaNs; 3504e02bc544a7af12bfad32679bc5443fa1cb7b9052Ivan Lozano // deltaNs = lastWriteFinished - previousLastWriteFinished; 3505e02bc544a7af12bfad32679bc5443fa1cb7b9052Ivan Lozano __builtin_sub_overflow( 3506e02bc544a7af12bfad32679bc5443fa1cb7b9052Ivan Lozano lastWriteFinished,previousLastWriteFinished, &deltaNs); 3507e02bc544a7af12bfad32679bc5443fa1cb7b9052Ivan Lozano const int32_t deltaMs = deltaNs / 1000000; 3508e02bc544a7af12bfad32679bc5443fa1cb7b9052Ivan Lozano 3509ea04d3913f9c10b5ef559ec794e3584f5505ce2dIvan Lozano const int32_t throttleMs = (int32_t)mHalfBufferMs - deltaMs; 351008fb1743f80437c38b4094070d851ea7f6d485e5Andy Hung if ((signed)mHalfBufferMs >= throttleMs && throttleMs > 0) { 351108fb1743f80437c38b4094070d851ea7f6d485e5Andy Hung usleep(throttleMs * 1000); 351240eb1a1f8871909c272e72afaf7d5af84fea2412Andy Hung // notify of throttle start on verbose log 351340eb1a1f8871909c272e72afaf7d5af84fea2412Andy Hung ALOGV_IF(mThreadThrottleEndMs == mThreadThrottleTimeMs, 351440eb1a1f8871909c272e72afaf7d5af84fea2412Andy Hung "mixer(%p) throttle begin:" 351540eb1a1f8871909c272e72afaf7d5af84fea2412Andy Hung " ret(%zd) deltaMs(%d) requires sleep %d ms", 351608fb1743f80437c38b4094070d851ea7f6d485e5Andy Hung this, ret, deltaMs, throttleMs); 351740eb1a1f8871909c272e72afaf7d5af84fea2412Andy Hung mThreadThrottleTimeMs += throttleMs; 35180a31dddf67e739684f60aecc85311ff446fb68f9Andy Hung // Throttle must be attributed to the previous mixer loop's write time 35190a31dddf67e739684f60aecc85311ff446fb68f9Andy Hung // to allow back-to-back throttling. 35200a31dddf67e739684f60aecc85311ff446fb68f9Andy Hung lastWriteFinished += throttleMs * 1000000; 352140eb1a1f8871909c272e72afaf7d5af84fea2412Andy Hung } else { 352240eb1a1f8871909c272e72afaf7d5af84fea2412Andy Hung uint32_t diff = mThreadThrottleTimeMs - mThreadThrottleEndMs; 352340eb1a1f8871909c272e72afaf7d5af84fea2412Andy Hung if (diff > 0) { 352440eb1a1f8871909c272e72afaf7d5af84fea2412Andy Hung // notify of throttle end on debug log 35253ea004dd80c06c5b366e1a2547ea9b28fffc1865Andy Hung // but prevent spamming for bluetooth 35260568dedb5008a24c2aca661a6891f9923abfa6d2Jakub Pawlowski ALOGD_IF(!audio_is_a2dp_out_device(outDevice()) && 35270568dedb5008a24c2aca661a6891f9923abfa6d2Jakub Pawlowski !audio_is_hearing_aid_out_device(outDevice()), 35283ea004dd80c06c5b366e1a2547ea9b28fffc1865Andy Hung "mixer(%p) throttle end: throttle time(%u)", this, diff); 352940eb1a1f8871909c272e72afaf7d5af84fea2412Andy Hung mThreadThrottleEndMs = mThreadThrottleTimeMs; 353040eb1a1f8871909c272e72afaf7d5af84fea2412Andy Hung } 353108fb1743f80437c38b4094070d851ea7f6d485e5Andy Hung } 353208fb1743f80437c38b4094070d851ea7f6d485e5Andy Hung } 353381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 353481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 3535bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent } else { 3536e77540228e1f60b1129a1615d2e43e0bf8015d3cGlenn Kasten ATRACE_BEGIN("sleep"); 3537e93cc03da360a1a0d2ad937c745ce8c8e8be81c2Eric Laurent Mutex::Autolock _l(mLock); 35381bb9082596c9cac2995dc9b4465a7c6d5666d099rago // suspended requires accurate metering of sleep time. 35391bb9082596c9cac2995dc9b4465a7c6d5666d099rago if (isSuspended()) { 35401bb9082596c9cac2995dc9b4465a7c6d5666d099rago // advance by expected sleepTime 35411bb9082596c9cac2995dc9b4465a7c6d5666d099rago timeLoopNextNs += microseconds((nsecs_t)mSleepTimeUs); 35421bb9082596c9cac2995dc9b4465a7c6d5666d099rago const nsecs_t nowNs = systemTime(); 35431bb9082596c9cac2995dc9b4465a7c6d5666d099rago 35441bb9082596c9cac2995dc9b4465a7c6d5666d099rago // compute expected next time vs current time. 35451bb9082596c9cac2995dc9b4465a7c6d5666d099rago // (negative deltas are treated as delays). 35461bb9082596c9cac2995dc9b4465a7c6d5666d099rago nsecs_t deltaNs = timeLoopNextNs - nowNs; 35471bb9082596c9cac2995dc9b4465a7c6d5666d099rago if (deltaNs < -kMaxNextBufferDelayNs) { 35481bb9082596c9cac2995dc9b4465a7c6d5666d099rago // Delays longer than the max allowed trigger a reset. 35491bb9082596c9cac2995dc9b4465a7c6d5666d099rago ALOGV("DelayNs: %lld, resetting timeLoopNextNs", (long long) deltaNs); 35501bb9082596c9cac2995dc9b4465a7c6d5666d099rago deltaNs = microseconds((nsecs_t)mSleepTimeUs); 35511bb9082596c9cac2995dc9b4465a7c6d5666d099rago timeLoopNextNs = nowNs + deltaNs; 35521bb9082596c9cac2995dc9b4465a7c6d5666d099rago } else if (deltaNs < 0) { 35531bb9082596c9cac2995dc9b4465a7c6d5666d099rago // Delays within the max delay allowed: zero the delta/sleepTime 35541bb9082596c9cac2995dc9b4465a7c6d5666d099rago // to help the system catch up in the next iteration(s) 35551bb9082596c9cac2995dc9b4465a7c6d5666d099rago ALOGV("DelayNs: %lld, catching-up", (long long) deltaNs); 35561bb9082596c9cac2995dc9b4465a7c6d5666d099rago deltaNs = 0; 35571bb9082596c9cac2995dc9b4465a7c6d5666d099rago } 35581bb9082596c9cac2995dc9b4465a7c6d5666d099rago // update sleep time (which is >= 0) 35591bb9082596c9cac2995dc9b4465a7c6d5666d099rago mSleepTimeUs = deltaNs / 1000; 35601bb9082596c9cac2995dc9b4465a7c6d5666d099rago } 3561e93cc03da360a1a0d2ad937c745ce8c8e8be81c2Eric Laurent if (!mSignalPending && mConfigEvents.isEmpty() && !exitPending()) { 3562e93cc03da360a1a0d2ad937c745ce8c8e8be81c2Eric Laurent mWaitWorkCV.waitRelative(mLock, microseconds((nsecs_t)mSleepTimeUs)); 3563517161856d74f5fe39cce131f29b977bc1745991Eric Laurent } 3564e77540228e1f60b1129a1615d2e43e0bf8015d3cGlenn Kasten ATRACE_END(); 3565bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent } 356681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 356781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 356881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // Finally let go of removed track(s), without the lock held 356981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // since we can't guarantee the destructors won't acquire that 357081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // same lock. This will also mutate and push a new fast mixer state. 357181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent threadLoop_removeTracks(tracksToRemove); 357281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent tracksToRemove.clear(); 357381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 357481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // FIXME I don't understand the need for this here; 357581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // it was in the original code but maybe the 357681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // assignment in saveOutputTracks() makes this unnecessary? 357781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent clearOutputTracks(); 357881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 357981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // Effect chains will be actually deleted here if they were removed from 358081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // mEffectChains list during mixing or effects processing 358181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent effectChains.clear(); 358281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 358381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // FIXME Note that the above .clear() is no longer necessary since effectChains 358481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // is now local to this block, but will keep it for now (at least until merge done). 358581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 358681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 3587bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent threadLoop_exit(); 3588bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent 3589cf817a2330936947df94c11859f48771f5596a59Eric Laurent if (!mStandby) { 3590cf817a2330936947df94c11859f48771f5596a59Eric Laurent threadLoop_standby(); 3591cf817a2330936947df94c11859f48771f5596a59Eric Laurent mStandby = true; 359281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 359381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 359481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent releaseWakeLock(); 359581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 359681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent ALOGV("Thread %p type %d exiting", this, mType); 359781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent return false; 359881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 359981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 3600bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent// removeTracks_l() must be called with ThreadBase::mLock held 3601bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurentvoid AudioFlinger::PlaybackThread::removeTracks_l(const Vector< sp<Track> >& tracksToRemove) 3602bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent{ 3603bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent size_t count = tracksToRemove.size(); 360434fca34606b448e6b71c2942f63cb13a0aebd620Glenn Kasten if (count > 0) { 3605bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent for (size_t i=0 ; i<count ; i++) { 3606bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent const sp<Track>& track = tracksToRemove.itemAt(i); 3607bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent mActiveTracks.remove(track); 3608bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent ALOGV("removeTracks_l removing track on session %d", track->sessionId()); 3609bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent sp<EffectChain> chain = getEffectChain_l(track->sessionId()); 3610bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent if (chain != 0) { 3611bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent ALOGV("stopping track on chain %p for session Id: %d", chain.get(), 3612bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent track->sessionId()); 3613bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent chain->decActiveTrackCnt(); 3614bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent } 3615bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent if (track->isTerminated()) { 3616bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent removeTrack_l(track); 3617bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent } 3618bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent } 3619bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent } 3620bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent 3621bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent} 362281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 3623accc147666bfd37fc8b4ef745f18a8c751555ec2Eric Laurentstatus_t AudioFlinger::PlaybackThread::getTimestamp_l(AudioTimestamp& timestamp) 3624accc147666bfd37fc8b4ef745f18a8c751555ec2Eric Laurent{ 3625accc147666bfd37fc8b4ef745f18a8c751555ec2Eric Laurent if (mNormalSink != 0) { 3626818e7a32ce3633980138aff2c2bfcc5158b3cfccAndy Hung ExtendedTimestamp ets; 3627818e7a32ce3633980138aff2c2bfcc5158b3cfccAndy Hung status_t status = mNormalSink->getTimestamp(ets); 3628818e7a32ce3633980138aff2c2bfcc5158b3cfccAndy Hung if (status == NO_ERROR) { 3629818e7a32ce3633980138aff2c2bfcc5158b3cfccAndy Hung status = ets.getBestTimestamp(×tamp); 3630818e7a32ce3633980138aff2c2bfcc5158b3cfccAndy Hung } 3631818e7a32ce3633980138aff2c2bfcc5158b3cfccAndy Hung return status; 3632accc147666bfd37fc8b4ef745f18a8c751555ec2Eric Laurent } 36331dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov if ((mType == OFFLOAD || mType == DIRECT) && mOutput != NULL) { 3634accc147666bfd37fc8b4ef745f18a8c751555ec2Eric Laurent uint64_t position64; 36351dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov if (mOutput->getPresentationPosition(&position64, ×tamp.mTime) == OK) { 3636accc147666bfd37fc8b4ef745f18a8c751555ec2Eric Laurent timestamp.mPosition = (uint32_t)position64; 3637accc147666bfd37fc8b4ef745f18a8c751555ec2Eric Laurent return NO_ERROR; 3638accc147666bfd37fc8b4ef745f18a8c751555ec2Eric Laurent } 3639accc147666bfd37fc8b4ef745f18a8c751555ec2Eric Laurent } 3640accc147666bfd37fc8b4ef745f18a8c751555ec2Eric Laurent return INVALID_OPERATION; 3641accc147666bfd37fc8b4ef745f18a8c751555ec2Eric Laurent} 36421c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent 3643054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurentstatus_t AudioFlinger::MixerThread::createAudioPatch_l(const struct audio_patch *patch, 3644054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurent audio_patch_handle_t *handle) 3645054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurent{ 3646f60abceac70c7a30dc2f888c4b80256b4a01a6ddAndy Hung status_t status; 3647f60abceac70c7a30dc2f888c4b80256b4a01a6ddAndy Hung if (property_get_bool("af.patch_park", false /* default_value */)) { 3648f60abceac70c7a30dc2f888c4b80256b4a01a6ddAndy Hung // Park FastMixer to avoid potential DOS issues with writing to the HAL 3649f60abceac70c7a30dc2f888c4b80256b4a01a6ddAndy Hung // or if HAL does not properly lock against access. 3650f60abceac70c7a30dc2f888c4b80256b4a01a6ddAndy Hung AutoPark<FastMixer> park(mFastMixer); 3651f60abceac70c7a30dc2f888c4b80256b4a01a6ddAndy Hung status = PlaybackThread::createAudioPatch_l(patch, handle); 3652f60abceac70c7a30dc2f888c4b80256b4a01a6ddAndy Hung } else { 3653f60abceac70c7a30dc2f888c4b80256b4a01a6ddAndy Hung status = PlaybackThread::createAudioPatch_l(patch, handle); 3654f60abceac70c7a30dc2f888c4b80256b4a01a6ddAndy Hung } 3655054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurent return status; 3656054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurent} 3657054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurent 36581c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurentstatus_t AudioFlinger::PlaybackThread::createAudioPatch_l(const struct audio_patch *patch, 36591c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent audio_patch_handle_t *handle) 36601c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent{ 36611c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent status_t status = NO_ERROR; 3662054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurent 3663054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurent // store new device and send to effects 3664054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurent audio_devices_t type = AUDIO_DEVICE_NONE; 3665054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurent for (unsigned int i = 0; i < patch->num_sinks; i++) { 3666054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurent type |= patch->sinks[i].ext.device.type; 3667054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurent } 3668054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurent 3669054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurent#ifdef ADD_BATTERY_DATA 3670054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurent // when changing the audio output device, call addBatteryData to notify 3671054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurent // the change 3672054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurent if (mOutDevice != type) { 3673054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurent uint32_t params = 0; 3674054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurent // check whether speaker is on 3675054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurent if (type & AUDIO_DEVICE_OUT_SPEAKER) { 3676054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurent params |= IMediaPlayerService::kBatteryDataSpeakerOn; 36771c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent } 3678054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurent 3679054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurent audio_devices_t deviceWithoutSpeaker 3680054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurent = AUDIO_DEVICE_OUT_ALL & ~AUDIO_DEVICE_OUT_SPEAKER; 3681054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurent // check if any other device (except speaker) is on 3682054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurent if (type & deviceWithoutSpeaker) { 3683054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurent params |= IMediaPlayerService::kBatteryDataOtherAudioDeviceOn; 3684054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurent } 3685054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurent 3686054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurent if (params != 0) { 3687054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurent addBatteryData(params); 36881c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent } 3689054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurent } 3690054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurent#endif 36911c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent 3692054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurent for (size_t i = 0; i < mEffectChains.size(); i++) { 3693054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurent mEffectChains[i]->setDevice_l(type); 3694054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurent } 36957c1ec5f038e63a5eb8b04434577c25bc23f5f410Eric Laurent 36967c1ec5f038e63a5eb8b04434577c25bc23f5f410Eric Laurent // mPrevOutDevice is the latest device set by createAudioPatch_l(). It is not set when 36977c1ec5f038e63a5eb8b04434577c25bc23f5f410Eric Laurent // the thread is created so that the first patch creation triggers an ioConfigChanged callback 36987c1ec5f038e63a5eb8b04434577c25bc23f5f410Eric Laurent bool configChanged = mPrevOutDevice != type; 3699054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurent mOutDevice = type; 3700296fb13dd9b5e90d6a05cce897c3b1e7914a478aEric Laurent mPatch = *patch; 3701054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurent 37029ee0540d3a61bff03d561ca431a371c3d9335d2bMikhail Naganov if (mOutput->audioHwDev->supportsAudioPatches()) { 3703e4f1f63a2c54ee8687ad8cca18df0f6639ad7c81Mikhail Naganov sp<DeviceHalInterface> hwDevice = mOutput->audioHwDev->hwDevice(); 3704e4f1f63a2c54ee8687ad8cca18df0f6639ad7c81Mikhail Naganov status = hwDevice->createAudioPatch(patch->num_sources, 3705e4f1f63a2c54ee8687ad8cca18df0f6639ad7c81Mikhail Naganov patch->sources, 3706e4f1f63a2c54ee8687ad8cca18df0f6639ad7c81Mikhail Naganov patch->num_sinks, 3707e4f1f63a2c54ee8687ad8cca18df0f6639ad7c81Mikhail Naganov patch->sinks, 3708e4f1f63a2c54ee8687ad8cca18df0f6639ad7c81Mikhail Naganov handle); 37091c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent } else { 3710054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurent char *address; 3711054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurent if (strcmp(patch->sinks[0].ext.device.address, "") != 0) { 3712054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurent //FIXME: we only support address on first sink with HAL version < 3.0 3713054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurent address = audio_device_address_to_parameter( 3714054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurent patch->sinks[0].ext.device.type, 3715054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurent patch->sinks[0].ext.device.address); 3716054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurent } else { 3717054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurent address = (char *)calloc(1, 1); 3718054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurent } 3719054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurent AudioParameter param = AudioParameter(String8(address)); 3720054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurent free(address); 372100260b5e6996b0a4b12f71c5b84e44adea040534Mikhail Naganov param.addInt(String8(AudioParameter::keyRouting), (int)type); 37221dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov status = mOutput->stream->setParameters(param.toString()); 3723054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurent *handle = AUDIO_PATCH_HANDLE_NONE; 3724054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurent } 3725e8726fea8a53bf3474aa3c6deaf2f6c1f565e694Eric Laurent if (configChanged) { 37267c1ec5f038e63a5eb8b04434577c25bc23f5f410Eric Laurent mPrevOutDevice = type; 3727e8726fea8a53bf3474aa3c6deaf2f6c1f565e694Eric Laurent sendIoConfigEvent_l(AUDIO_OUTPUT_CONFIG_CHANGED); 3728e8726fea8a53bf3474aa3c6deaf2f6c1f565e694Eric Laurent } 3729054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurent return status; 3730054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurent} 3731054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurent 3732054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurentstatus_t AudioFlinger::MixerThread::releaseAudioPatch_l(const audio_patch_handle_t handle) 3733054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurent{ 3734f60abceac70c7a30dc2f888c4b80256b4a01a6ddAndy Hung status_t status; 3735f60abceac70c7a30dc2f888c4b80256b4a01a6ddAndy Hung if (property_get_bool("af.patch_park", false /* default_value */)) { 3736f60abceac70c7a30dc2f888c4b80256b4a01a6ddAndy Hung // Park FastMixer to avoid potential DOS issues with writing to the HAL 3737f60abceac70c7a30dc2f888c4b80256b4a01a6ddAndy Hung // or if HAL does not properly lock against access. 3738f60abceac70c7a30dc2f888c4b80256b4a01a6ddAndy Hung AutoPark<FastMixer> park(mFastMixer); 3739f60abceac70c7a30dc2f888c4b80256b4a01a6ddAndy Hung status = PlaybackThread::releaseAudioPatch_l(handle); 3740f60abceac70c7a30dc2f888c4b80256b4a01a6ddAndy Hung } else { 3741f60abceac70c7a30dc2f888c4b80256b4a01a6ddAndy Hung status = PlaybackThread::releaseAudioPatch_l(handle); 3742f60abceac70c7a30dc2f888c4b80256b4a01a6ddAndy Hung } 37431c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent return status; 37441c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent} 37451c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent 37461c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurentstatus_t AudioFlinger::PlaybackThread::releaseAudioPatch_l(const audio_patch_handle_t handle) 37471c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent{ 37481c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent status_t status = NO_ERROR; 3749054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurent 3750054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurent mOutDevice = AUDIO_DEVICE_NONE; 3751054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurent 37529ee0540d3a61bff03d561ca431a371c3d9335d2bMikhail Naganov if (mOutput->audioHwDev->supportsAudioPatches()) { 3753e4f1f63a2c54ee8687ad8cca18df0f6639ad7c81Mikhail Naganov sp<DeviceHalInterface> hwDevice = mOutput->audioHwDev->hwDevice(); 3754e4f1f63a2c54ee8687ad8cca18df0f6639ad7c81Mikhail Naganov status = hwDevice->releaseAudioPatch(handle); 37551c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent } else { 3756054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurent AudioParameter param; 375700260b5e6996b0a4b12f71c5b84e44adea040534Mikhail Naganov param.addInt(String8(AudioParameter::keyRouting), 0); 37581dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov status = mOutput->stream->setParameters(param.toString()); 37591c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent } 37601c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent return status; 37611c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent} 37621c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent 376383b8808faad1e91690c64d7007348be8d9ebde73Eric Laurentvoid AudioFlinger::PlaybackThread::addPatchTrack(const sp<PatchTrack>& track) 376483b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent{ 376583b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent Mutex::Autolock _l(mLock); 376683b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent mTracks.add(track); 376783b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent} 376883b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent 376983b8808faad1e91690c64d7007348be8d9ebde73Eric Laurentvoid AudioFlinger::PlaybackThread::deletePatchTrack(const sp<PatchTrack>& track) 377083b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent{ 377183b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent Mutex::Autolock _l(mLock); 377283b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent destroyTrack_l(track); 377383b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent} 377483b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent 377583b8808faad1e91690c64d7007348be8d9ebde73Eric Laurentvoid AudioFlinger::PlaybackThread::getAudioPortConfig(struct audio_port_config *config) 377683b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent{ 377783b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent ThreadBase::getAudioPortConfig(config); 377883b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent config->role = AUDIO_PORT_ROLE_SOURCE; 377983b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent config->ext.mix.hw_module = mOutput->audioHwDev->handle(); 378083b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent config->ext.mix.usecase.stream = AUDIO_STREAM_DEFAULT; 378183b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent} 378283b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent 378381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// ---------------------------------------------------------------------------- 378481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 378581784c37c61b09289654b979567a42bf73cd2b12Eric LaurentAudioFlinger::MixerThread::MixerThread(const sp<AudioFlinger>& audioFlinger, AudioStreamOut* output, 378672e3f39146fce4686bd96f11057c051bea376dfbEric Laurent audio_io_handle_t id, audio_devices_t device, bool systemReady, type_t type) 378772e3f39146fce4686bd96f11057c051bea376dfbEric Laurent : PlaybackThread(audioFlinger, output, id, device, type, systemReady), 378881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // mAudioMixer below 378981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // mFastMixer below 37902ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hung mFastMixerFutex(0), 37912ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hung mMasterMono(false) 379281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // mOutputSink below 379381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // mPipeSink below 379481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // mNormalSink below 379581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 379681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent ALOGV("MixerThread() id=%d device=%#x type=%d", id, device, type); 379749f36ba3b4624ddd3d7efa34c95128a73bda6208Glenn Kasten ALOGV("mSampleRate=%u, mChannelMask=%#x, mChannelCount=%u, mFormat=%#x, mFrameSize=%zu, " 3798c42e9b462661673dff480ee71757a58b0f806370Glenn Kasten "mFrameCount=%zu, mNormalFrameCount=%zu", 379981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mSampleRate, mChannelMask, mChannelCount, mFormat, mFrameSize, mFrameCount, 380081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mNormalFrameCount); 380181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mAudioMixer = new AudioMixer(mNormalFrameCount, mSampleRate); 380281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 3803fbfc3959f4aac839445edc7075532067fef497c2Andy Hung if (type == DUPLICATING) { 3804fbfc3959f4aac839445edc7075532067fef497c2Andy Hung // The Duplicating thread uses the AudioMixer and delivers data to OutputTracks 3805fbfc3959f4aac839445edc7075532067fef497c2Andy Hung // (downstream MixerThreads) in DuplicatingThread::threadLoop_write(). 3806fbfc3959f4aac839445edc7075532067fef497c2Andy Hung // Do not create or use mFastMixer, mOutputSink, mPipeSink, or mNormalSink. 3807fbfc3959f4aac839445edc7075532067fef497c2Andy Hung return; 3808fbfc3959f4aac839445edc7075532067fef497c2Andy Hung } 380981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // create an NBAIO sink for the HAL output stream, and negotiate 3810a0c91339814f37ea78365afb436c9f3d1f0a0090Mikhail Naganov mOutputSink = new AudioStreamOutSink(output->stream); 381181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent size_t numCounterOffers = 0; 3812f69f9869514730aebe5724c461768507084dfff7Glenn Kasten const NBAIO_Format offers[1] = {Format_from_SR_C(mSampleRate, mChannelCount, mFormat)}; 381357c4e6f7464d458eb52d209c2a63524913d6406dGlenn Kasten#if !LOG_NDEBUG 381457c4e6f7464d458eb52d209c2a63524913d6406dGlenn Kasten ssize_t index = 381557c4e6f7464d458eb52d209c2a63524913d6406dGlenn Kasten#else 381657c4e6f7464d458eb52d209c2a63524913d6406dGlenn Kasten (void) 381757c4e6f7464d458eb52d209c2a63524913d6406dGlenn Kasten#endif 381857c4e6f7464d458eb52d209c2a63524913d6406dGlenn Kasten mOutputSink->negotiate(offers, 1, NULL, numCounterOffers); 381981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent ALOG_ASSERT(index == 0); 382081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 382181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // initialize fast mixer depending on configuration 382281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent bool initFastMixer; 382381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent switch (kUseFastMixer) { 382481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent case FastMixer_Never: 382581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent initFastMixer = false; 382681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent break; 382781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent case FastMixer_Always: 382881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent initFastMixer = true; 382981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent break; 383081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent case FastMixer_Static: 383181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent case FastMixer_Dynamic: 3832fda69406966f8578a7827e889bff615f0144b441Andy Hung // FastMixer was designed to operate with a HAL that pulls at a regular rate, 3833fda69406966f8578a7827e889bff615f0144b441Andy Hung // where the period is less than an experimentally determined threshold that can be 3834fda69406966f8578a7827e889bff615f0144b441Andy Hung // scheduled reliably with CFS. However, the BT A2DP HAL is 3835fda69406966f8578a7827e889bff615f0144b441Andy Hung // bursty (does not pull at a regular rate) and so cannot operate with FastMixer. 3836fda69406966f8578a7827e889bff615f0144b441Andy Hung initFastMixer = mFrameCount < mNormalFrameCount 3837fda69406966f8578a7827e889bff615f0144b441Andy Hung && (mOutDevice & AUDIO_DEVICE_OUT_ALL_A2DP) == 0; 383881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent break; 383981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 3840fda69406966f8578a7827e889bff615f0144b441Andy Hung ALOGW_IF(initFastMixer == false && mFrameCount < mNormalFrameCount, 3841fda69406966f8578a7827e889bff615f0144b441Andy Hung "FastMixer is preferred for this sink as frameCount %zu is less than threshold %zu", 3842fda69406966f8578a7827e889bff615f0144b441Andy Hung mFrameCount, mNormalFrameCount); 384381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (initFastMixer) { 38441258c1ab592a899fabb1e31eb5db2ef413b6f38aAndy Hung audio_format_t fastMixerFormat; 38451258c1ab592a899fabb1e31eb5db2ef413b6f38aAndy Hung if (mMixerBufferEnabled && mEffectBufferEnabled) { 38461258c1ab592a899fabb1e31eb5db2ef413b6f38aAndy Hung fastMixerFormat = AUDIO_FORMAT_PCM_FLOAT; 38471258c1ab592a899fabb1e31eb5db2ef413b6f38aAndy Hung } else { 38481258c1ab592a899fabb1e31eb5db2ef413b6f38aAndy Hung fastMixerFormat = AUDIO_FORMAT_PCM_16_BIT; 38491258c1ab592a899fabb1e31eb5db2ef413b6f38aAndy Hung } 38501258c1ab592a899fabb1e31eb5db2ef413b6f38aAndy Hung if (mFormat != fastMixerFormat) { 38511258c1ab592a899fabb1e31eb5db2ef413b6f38aAndy Hung // change our Sink format to accept our intermediate precision 38521258c1ab592a899fabb1e31eb5db2ef413b6f38aAndy Hung mFormat = fastMixerFormat; 38531258c1ab592a899fabb1e31eb5db2ef413b6f38aAndy Hung free(mSinkBuffer); 38541258c1ab592a899fabb1e31eb5db2ef413b6f38aAndy Hung mFrameSize = mChannelCount * audio_bytes_per_sample(mFormat); 38551258c1ab592a899fabb1e31eb5db2ef413b6f38aAndy Hung const size_t sinkBufferSize = mNormalFrameCount * mFrameSize; 38561258c1ab592a899fabb1e31eb5db2ef413b6f38aAndy Hung (void)posix_memalign(&mSinkBuffer, 32, sinkBufferSize); 38571258c1ab592a899fabb1e31eb5db2ef413b6f38aAndy Hung } 385881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 385981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // create a MonoPipe to connect our submix to FastMixer 386081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent NBAIO_Format format = mOutputSink->format(); 386157c4e6f7464d458eb52d209c2a63524913d6406dGlenn Kasten#ifdef TEE_SINK 3862ba0b34c18da93681c0813ecdab19b0e215b6d261Glenn Kasten NBAIO_Format origformat = format; 386357c4e6f7464d458eb52d209c2a63524913d6406dGlenn Kasten#endif 38641258c1ab592a899fabb1e31eb5db2ef413b6f38aAndy Hung // adjust format to match that of the Fast Mixer 386549f36ba3b4624ddd3d7efa34c95128a73bda6208Glenn Kasten ALOGV("format changed from %#x to %#x", format.mFormat, fastMixerFormat); 38661258c1ab592a899fabb1e31eb5db2ef413b6f38aAndy Hung format.mFormat = fastMixerFormat; 38671258c1ab592a899fabb1e31eb5db2ef413b6f38aAndy Hung format.mFrameSize = audio_bytes_per_sample(format.mFormat) * format.mChannelCount; 38681258c1ab592a899fabb1e31eb5db2ef413b6f38aAndy Hung 386981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // This pipe depth compensates for scheduling latency of the normal mixer thread. 387081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // When it wakes up after a maximum latency, it runs a few cycles quickly before 387181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // finally blocking. Note the pipe implementation rounds up the request to a power of 2. 387281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent MonoPipe *monoPipe = new MonoPipe(mNormalFrameCount * 4, format, true /*writeCanBlock*/); 387381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent const NBAIO_Format offers[1] = {format}; 387481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent size_t numCounterOffers = 0; 3875fc302fd9e2d2cbafef771de77c47799488e1c044Glenn Kasten#if !LOG_NDEBUG || defined(TEE_SINK) 387657c4e6f7464d458eb52d209c2a63524913d6406dGlenn Kasten ssize_t index = 387757c4e6f7464d458eb52d209c2a63524913d6406dGlenn Kasten#else 387857c4e6f7464d458eb52d209c2a63524913d6406dGlenn Kasten (void) 387957c4e6f7464d458eb52d209c2a63524913d6406dGlenn Kasten#endif 388057c4e6f7464d458eb52d209c2a63524913d6406dGlenn Kasten monoPipe->negotiate(offers, 1, NULL, numCounterOffers); 388181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent ALOG_ASSERT(index == 0); 388281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent monoPipe->setAvgFrames((mScreenState & 1) ? 388381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent (monoPipe->maxFrames() * 7) / 8 : mNormalFrameCount * 2); 388481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mPipeSink = monoPipe; 388581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 388646909e7eb074ce1b95b8a411eb71154f53f84f77Glenn Kasten#ifdef TEE_SINK 3887da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten if (mTeeSinkOutputEnabled) { 3888da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten // create a Pipe to archive a copy of FastMixer's output for dumpsys 3889ba0b34c18da93681c0813ecdab19b0e215b6d261Glenn Kasten Pipe *teeSink = new Pipe(mTeeSinkOutputFrames, origformat); 3890ba0b34c18da93681c0813ecdab19b0e215b6d261Glenn Kasten const NBAIO_Format offers2[1] = {origformat}; 3891da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten numCounterOffers = 0; 3892ba0b34c18da93681c0813ecdab19b0e215b6d261Glenn Kasten index = teeSink->negotiate(offers2, 1, NULL, numCounterOffers); 3893da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten ALOG_ASSERT(index == 0); 3894da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten mTeeSink = teeSink; 3895da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten PipeReader *teeSource = new PipeReader(*teeSink); 3896da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten numCounterOffers = 0; 3897ba0b34c18da93681c0813ecdab19b0e215b6d261Glenn Kasten index = teeSource->negotiate(offers2, 1, NULL, numCounterOffers); 3898da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten ALOG_ASSERT(index == 0); 3899da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten mTeeSource = teeSource; 3900da6ef1320d0161b1640dc84d7a9c5a25860c3619Glenn Kasten } 390146909e7eb074ce1b95b8a411eb71154f53f84f77Glenn Kasten#endif 390281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 390381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // create fast mixer and configure it initially with just one fast track for our submix 390481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mFastMixer = new FastMixer(); 390581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent FastMixerStateQueue *sq = mFastMixer->sq(); 390681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent#ifdef STATE_QUEUE_DUMP 390781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent sq->setObserverDump(&mStateQueueObserverDump); 390881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent sq->setMutatorDump(&mStateQueueMutatorDump); 390981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent#endif 391081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent FastMixerState *state = sq->begin(); 391181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent FastTrack *fastTrack = &state->mFastTracks[0]; 391281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // wrap the source side of the MonoPipe to make it an AudioBufferProvider 391381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent fastTrack->mBufferProvider = new SourceAudioBufferProvider(new MonoPipeReader(monoPipe)); 391481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent fastTrack->mVolumeProvider = NULL; 3915e8a1ced4da17dc6c07803dc2af8060f62a8389c1Andy Hung fastTrack->mChannelMask = mChannelMask; // mPipeSink channel mask for audio to FastMixer 3916e8a1ced4da17dc6c07803dc2af8060f62a8389c1Andy Hung fastTrack->mFormat = mFormat; // mPipeSink format for audio to FastMixer 391781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent fastTrack->mGeneration++; 391881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent state->mFastTracksGen++; 391981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent state->mTrackMask = 1; 392081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // fast mixer will use the HAL output sink 392181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent state->mOutputSink = mOutputSink.get(); 392281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent state->mOutputSinkGen++; 392381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent state->mFrameCount = mFrameCount; 392481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent state->mCommand = FastMixerState::COLD_IDLE; 392581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // already done in constructor initialization list 392681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent //mFastMixerFutex = 0; 392781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent state->mColdFutexAddr = &mFastMixerFutex; 392881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent state->mColdGen++; 392981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent state->mDumpState = &mFastMixerDumpState; 393046909e7eb074ce1b95b8a411eb71154f53f84f77Glenn Kasten#ifdef TEE_SINK 393181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent state->mTeeSink = mTeeSink.get(); 393246909e7eb074ce1b95b8a411eb71154f53f84f77Glenn Kasten#endif 39339e58b552f51b00b3b674102876bd6c77ef3da806Glenn Kasten mFastMixerNBLogWriter = audioFlinger->newWriter_l(kFastMixerLogSize, "FastMixer"); 39349e58b552f51b00b3b674102876bd6c77ef3da806Glenn Kasten state->mNBLogWriter = mFastMixerNBLogWriter.get(); 393581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent sq->end(); 393681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent sq->push(FastMixerStateQueue::BLOCK_UNTIL_PUSHED); 393781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 393881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // start the fast mixer 393981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mFastMixer->run("FastMixer", PRIORITY_URGENT_AUDIO); 394081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent pid_t tid = mFastMixer->getTid(); 3941af9a7b52b2273ea5c2b30350bdd0fce39a8b16d2Glenn Kasten sendPrioConfigEvent(getpid_cached, tid, kPriorityFastMixer, false /*forApp*/); 3942e1c4b5d7a94c21b8ce0c5707b4af84de596fbb79Mikhail Naganov stream()->setHalThreadPriority(kPriorityFastMixer); 394381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 394481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent#ifdef AUDIO_WATCHDOG 394581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // create and start the watchdog 394681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mAudioWatchdog = new AudioWatchdog(); 394781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mAudioWatchdog->setDump(&mAudioWatchdogDump); 394881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mAudioWatchdog->run("AudioWatchdog", PRIORITY_URGENT_AUDIO); 394981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent tid = mAudioWatchdog->getTid(); 3950af9a7b52b2273ea5c2b30350bdd0fce39a8b16d2Glenn Kasten sendPrioConfigEvent(getpid_cached, tid, kPriorityFastMixer, false /*forApp*/); 395181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent#endif 395281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 395381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 395481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 395581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent switch (kUseFastMixer) { 395681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent case FastMixer_Never: 395781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent case FastMixer_Dynamic: 395881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mNormalSink = mOutputSink; 395981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent break; 396081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent case FastMixer_Always: 396181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mNormalSink = mPipeSink; 396281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent break; 396381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent case FastMixer_Static: 396481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mNormalSink = initFastMixer ? mPipeSink : mOutputSink; 396581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent break; 396681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 396781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 396881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 396981784c37c61b09289654b979567a42bf73cd2b12Eric LaurentAudioFlinger::MixerThread::~MixerThread() 397081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 39714d23ca370dd0ce584f49a80ef9dfcdbb75ba2c8eGlenn Kasten if (mFastMixer != 0) { 397281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent FastMixerStateQueue *sq = mFastMixer->sq(); 397381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent FastMixerState *state = sq->begin(); 397481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (state->mCommand == FastMixerState::COLD_IDLE) { 397581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent int32_t old = android_atomic_inc(&mFastMixerFutex); 397681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (old == -1) { 3977ee499291404a192b059f2e04c5afc65aa6cdd74cElliott Hughes (void) syscall(__NR_futex, &mFastMixerFutex, FUTEX_WAKE_PRIVATE, 1); 397881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 397981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 398081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent state->mCommand = FastMixerState::EXIT; 398181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent sq->end(); 398281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent sq->push(FastMixerStateQueue::BLOCK_UNTIL_PUSHED); 398381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mFastMixer->join(); 398481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // Though the fast mixer thread has exited, it's state queue is still valid. 398581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // We'll use that extract the final state which contains one remaining fast track 398681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // corresponding to our sub-mix. 398781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent state = sq->begin(); 398881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent ALOG_ASSERT(state->mTrackMask == 1); 398981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent FastTrack *fastTrack = &state->mFastTracks[0]; 399081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent ALOG_ASSERT(fastTrack->mBufferProvider != NULL); 399181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent delete fastTrack->mBufferProvider; 399281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent sq->end(false /*didModify*/); 39934d23ca370dd0ce584f49a80ef9dfcdbb75ba2c8eGlenn Kasten mFastMixer.clear(); 399481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent#ifdef AUDIO_WATCHDOG 399581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (mAudioWatchdog != 0) { 399681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mAudioWatchdog->requestExit(); 399781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mAudioWatchdog->requestExitAndWait(); 399881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mAudioWatchdog.clear(); 399981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 400081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent#endif 400181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 40029e58b552f51b00b3b674102876bd6c77ef3da806Glenn Kasten mAudioFlinger->unregisterWriter(mFastMixerNBLogWriter); 400381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent delete mAudioMixer; 400481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 400581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 400681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 400781784c37c61b09289654b979567a42bf73cd2b12Eric Laurentuint32_t AudioFlinger::MixerThread::correctLatency_l(uint32_t latency) const 400881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 40094d23ca370dd0ce584f49a80ef9dfcdbb75ba2c8eGlenn Kasten if (mFastMixer != 0) { 401081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent MonoPipe *pipe = (MonoPipe *)mPipeSink.get(); 401181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent latency += (pipe->getAvgFrames() * 1000) / mSampleRate; 401281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 401381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent return latency; 401481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 401581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 401681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 401781784c37c61b09289654b979567a42bf73cd2b12Eric Laurentvoid AudioFlinger::MixerThread::threadLoop_removeTracks(const Vector< sp<Track> >& tracksToRemove) 401881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 401981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent PlaybackThread::threadLoop_removeTracks(tracksToRemove); 402081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 402181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 4022bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurentssize_t AudioFlinger::MixerThread::threadLoop_write() 402381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 402481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // FIXME we should only do one push per cycle; confirm this is true 402581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // Start the fast mixer if it's not already running 40264d23ca370dd0ce584f49a80ef9dfcdbb75ba2c8eGlenn Kasten if (mFastMixer != 0) { 402781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent FastMixerStateQueue *sq = mFastMixer->sq(); 402881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent FastMixerState *state = sq->begin(); 402981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (state->mCommand != FastMixerState::MIX_WRITE && 403081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent (kUseFastMixer != FastMixer_Dynamic || state->mTrackMask > 1)) { 403181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (state->mCommand == FastMixerState::COLD_IDLE) { 4032a2ab4505c807f42afe34809409c4e85d91618a8cEric Laurent 4033a2ab4505c807f42afe34809409c4e85d91618a8cEric Laurent // FIXME workaround for first HAL write being CPU bound on some devices 4034a2ab4505c807f42afe34809409c4e85d91618a8cEric Laurent ATRACE_BEGIN("write"); 4035a2ab4505c807f42afe34809409c4e85d91618a8cEric Laurent mOutput->write((char *)mSinkBuffer, 0); 4036a2ab4505c807f42afe34809409c4e85d91618a8cEric Laurent ATRACE_END(); 4037a2ab4505c807f42afe34809409c4e85d91618a8cEric Laurent 403881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent int32_t old = android_atomic_inc(&mFastMixerFutex); 403981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (old == -1) { 4040ee499291404a192b059f2e04c5afc65aa6cdd74cElliott Hughes (void) syscall(__NR_futex, &mFastMixerFutex, FUTEX_WAKE_PRIVATE, 1); 404181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 404281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent#ifdef AUDIO_WATCHDOG 404381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (mAudioWatchdog != 0) { 404481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mAudioWatchdog->resume(); 404581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 404681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent#endif 404781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 404881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent state->mCommand = FastMixerState::MIX_WRITE; 4049d797a9d5daad3051f9ac1d348abc2f434ea3ddcfGlenn Kasten#ifdef FAST_THREAD_STATISTICS 40504182c4e2a07e2441fcd5c22eaff0ddfe7f826f61Glenn Kasten mFastMixerDumpState.increaseSamplingN(mAudioFlinger->isLowRamDevice() ? 4051fbdb2aceab7317aa44bc8f301a93eb49e17b2bceGlenn Kasten FastThreadDumpState::kSamplingNforLowRamDevice : FastThreadDumpState::kSamplingN); 4052d797a9d5daad3051f9ac1d348abc2f434ea3ddcfGlenn Kasten#endif 405381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent sq->end(); 405481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent sq->push(FastMixerStateQueue::BLOCK_UNTIL_PUSHED); 405581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (kUseFastMixer == FastMixer_Dynamic) { 405681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mNormalSink = mPipeSink; 405781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 405881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } else { 405981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent sq->end(false /*didModify*/); 406081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 406181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 4062bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent return PlaybackThread::threadLoop_write(); 406381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 406481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 406581784c37c61b09289654b979567a42bf73cd2b12Eric Laurentvoid AudioFlinger::MixerThread::threadLoop_standby() 406681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 406781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // Idle the fast mixer if it's currently running 40684d23ca370dd0ce584f49a80ef9dfcdbb75ba2c8eGlenn Kasten if (mFastMixer != 0) { 406981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent FastMixerStateQueue *sq = mFastMixer->sq(); 407081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent FastMixerState *state = sq->begin(); 407181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (!(state->mCommand & FastMixerState::IDLE)) { 40722148bf0e79c436b8764b9edc4c8f2730cce98a32Andy Hung // Report any frames trapped in the Monopipe 40732148bf0e79c436b8764b9edc4c8f2730cce98a32Andy Hung MonoPipe *monoPipe = (MonoPipe *)mPipeSink.get(); 40742148bf0e79c436b8764b9edc4c8f2730cce98a32Andy Hung const long long pipeFrames = monoPipe->maxFrames() - monoPipe->availableToWrite(); 40752148bf0e79c436b8764b9edc4c8f2730cce98a32Andy Hung mLocalLog.log("threadLoop_standby: framesWritten:%lld suspendedFrames:%lld " 40762148bf0e79c436b8764b9edc4c8f2730cce98a32Andy Hung "monoPipeWritten:%lld monoPipeLeft:%lld", 40772148bf0e79c436b8764b9edc4c8f2730cce98a32Andy Hung (long long)mFramesWritten, (long long)mSuspendedFrames, 40782148bf0e79c436b8764b9edc4c8f2730cce98a32Andy Hung (long long)mPipeSink->framesWritten(), pipeFrames); 40792148bf0e79c436b8764b9edc4c8f2730cce98a32Andy Hung mLocalLog.log("threadLoop_standby: %s", mTimestamp.toString().c_str()); 40802148bf0e79c436b8764b9edc4c8f2730cce98a32Andy Hung 408181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent state->mCommand = FastMixerState::COLD_IDLE; 408281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent state->mColdFutexAddr = &mFastMixerFutex; 408381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent state->mColdGen++; 408481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mFastMixerFutex = 0; 408581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent sq->end(); 408681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // BLOCK_UNTIL_PUSHED would be insufficient, as we need it to stop doing I/O now 408781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent sq->push(FastMixerStateQueue::BLOCK_UNTIL_ACKED); 408881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (kUseFastMixer == FastMixer_Dynamic) { 408981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mNormalSink = mOutputSink; 409081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 409181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent#ifdef AUDIO_WATCHDOG 409281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (mAudioWatchdog != 0) { 409381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mAudioWatchdog->pause(); 409481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 409581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent#endif 409681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } else { 409781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent sq->end(false /*didModify*/); 409881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 409981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 410081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent PlaybackThread::threadLoop_standby(); 410181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 410281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 4103bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurentbool AudioFlinger::PlaybackThread::waitingAsyncCallback_l() 4104bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent{ 4105bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent return false; 4106bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent} 4107bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent 4108bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurentbool AudioFlinger::PlaybackThread::shouldStandby_l() 4109bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent{ 4110bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent return !mStandby; 4111bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent} 4112bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent 4113bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurentbool AudioFlinger::PlaybackThread::waitingAsyncCallback() 4114bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent{ 4115bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent Mutex::Autolock _l(mLock); 4116bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent return waitingAsyncCallback_l(); 4117bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent} 4118bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent 411981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// shared by MIXER and DIRECT, overridden by DUPLICATING 412081784c37c61b09289654b979567a42bf73cd2b12Eric Laurentvoid AudioFlinger::PlaybackThread::threadLoop_standby() 412181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 412281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent ALOGV("Audio hardware entering standby, mixer %p, suspend count %d", this, mSuspended); 4123062e67a26e0553dd142be622821f493df541f0c6Phil Burk mOutput->standby(); 4124bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent if (mUseAsyncWrite != 0) { 41253b4529e03c5fc7a44c22f9091ad15a269bfca3a8Eric Laurent // discard any pending drain or write ack by incrementing sequence 41263b4529e03c5fc7a44c22f9091ad15a269bfca3a8Eric Laurent mWriteAckSequence = (mWriteAckSequence + 2) & ~1; 41273b4529e03c5fc7a44c22f9091ad15a269bfca3a8Eric Laurent mDrainSequence = (mDrainSequence + 2) & ~1; 4128bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent ALOG_ASSERT(mCallbackThread != 0); 41293b4529e03c5fc7a44c22f9091ad15a269bfca3a8Eric Laurent mCallbackThread->setWriteBlocked(mWriteAckSequence); 41303b4529e03c5fc7a44c22f9091ad15a269bfca3a8Eric Laurent mCallbackThread->setDraining(mDrainSequence); 4131bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent } 4132d1f69b0b17acbd96987ecb2f3378abd394d05903Eric Laurent mHwPaused = false; 413381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 413481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 41354c6a433d74d5ae8b9bc0557207e3ced43bf34a25Haynes Mathew Georgevoid AudioFlinger::PlaybackThread::onAddNewTrack_l() 41364c6a433d74d5ae8b9bc0557207e3ced43bf34a25Haynes Mathew George{ 41374c6a433d74d5ae8b9bc0557207e3ced43bf34a25Haynes Mathew George ALOGV("signal playback thread"); 41384c6a433d74d5ae8b9bc0557207e3ced43bf34a25Haynes Mathew George broadcast_l(); 41394c6a433d74d5ae8b9bc0557207e3ced43bf34a25Haynes Mathew George} 41404c6a433d74d5ae8b9bc0557207e3ced43bf34a25Haynes Mathew George 41414527b9ebc6a37b861f5a3bba68bcc63dc8d69adaHaynes Mathew Georgevoid AudioFlinger::PlaybackThread::onAsyncError() 41424527b9ebc6a37b861f5a3bba68bcc63dc8d69adaHaynes Mathew George{ 41434527b9ebc6a37b861f5a3bba68bcc63dc8d69adaHaynes Mathew George for (int i = AUDIO_STREAM_SYSTEM; i < (int)AUDIO_STREAM_CNT; i++) { 41444527b9ebc6a37b861f5a3bba68bcc63dc8d69adaHaynes Mathew George invalidateTracks((audio_stream_type_t)i); 41454527b9ebc6a37b861f5a3bba68bcc63dc8d69adaHaynes Mathew George } 41464527b9ebc6a37b861f5a3bba68bcc63dc8d69adaHaynes Mathew George} 41474527b9ebc6a37b861f5a3bba68bcc63dc8d69adaHaynes Mathew George 414881784c37c61b09289654b979567a42bf73cd2b12Eric Laurentvoid AudioFlinger::MixerThread::threadLoop_mix() 414981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 415081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // mix buffers... 4151d79072e9dff59f767cce2cda1caab80ce5a0815bGlenn Kasten mAudioMixer->process(); 415225c2dac12114699e90deb1c579cadebce7b91a97Andy Hung mCurrentWriteLength = mSinkBufferSize; 415381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // increase sleep time progressively when application underrun condition clears. 415481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // Only increase sleep time if the mixer is ready for two consecutive times to avoid 415581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // that a steady state of alternating ready/not ready conditions keeps the sleep time 415681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // such that we would underrun the audio HAL. 4157ad9cb8b88e4f8face23f01d8dc89fa769dacb50fEric Laurent if ((mSleepTimeUs == 0) && (sleepTimeShift > 0)) { 415881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent sleepTimeShift--; 415981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 4160ad9cb8b88e4f8face23f01d8dc89fa769dacb50fEric Laurent mSleepTimeUs = 0; 4161ad9cb8b88e4f8face23f01d8dc89fa769dacb50fEric Laurent mStandbyTimeNs = systemTime() + mStandbyDelayNs; 416281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent //TODO: delay standby when effects have a tail 41634c053ea158b29fa2cdd4c6f39d3c8da4ee5a7a02Glenn Kasten 416481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 416581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 416681784c37c61b09289654b979567a42bf73cd2b12Eric Laurentvoid AudioFlinger::MixerThread::threadLoop_sleepTime() 416781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 416881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // If no tracks are ready, sleep once for the duration of an output 416981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // buffer size, then write 0s to the output 4170ad9cb8b88e4f8face23f01d8dc89fa769dacb50fEric Laurent if (mSleepTimeUs == 0) { 417181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (mMixerStatus == MIXER_TRACKS_ENABLED) { 417206d13227bed31bf4a2dfa30e19198620eb5b120eAndy Hung if (mPipeSink.get() != nullptr && mPipeSink == mNormalSink) { 417306d13227bed31bf4a2dfa30e19198620eb5b120eAndy Hung // Using the Monopipe availableToWrite, we estimate the 417406d13227bed31bf4a2dfa30e19198620eb5b120eAndy Hung // sleep time to retry for more data (before we underrun). 417506d13227bed31bf4a2dfa30e19198620eb5b120eAndy Hung MonoPipe *monoPipe = static_cast<MonoPipe *>(mPipeSink.get()); 417606d13227bed31bf4a2dfa30e19198620eb5b120eAndy Hung const ssize_t availableToWrite = mPipeSink->availableToWrite(); 417706d13227bed31bf4a2dfa30e19198620eb5b120eAndy Hung const size_t pipeFrames = monoPipe->maxFrames(); 417806d13227bed31bf4a2dfa30e19198620eb5b120eAndy Hung const size_t framesLeft = pipeFrames - max(availableToWrite, 0); 417906d13227bed31bf4a2dfa30e19198620eb5b120eAndy Hung // HAL_framecount <= framesDelay ~ framesLeft / 2 <= Normal_Mixer_framecount 418006d13227bed31bf4a2dfa30e19198620eb5b120eAndy Hung const size_t framesDelay = std::min( 418106d13227bed31bf4a2dfa30e19198620eb5b120eAndy Hung mNormalFrameCount, max(framesLeft / 2, mFrameCount)); 418206d13227bed31bf4a2dfa30e19198620eb5b120eAndy Hung ALOGV("pipeFrames:%zu framesLeft:%zu framesDelay:%zu", 418306d13227bed31bf4a2dfa30e19198620eb5b120eAndy Hung pipeFrames, framesLeft, framesDelay); 418406d13227bed31bf4a2dfa30e19198620eb5b120eAndy Hung mSleepTimeUs = framesDelay * MICROS_PER_SECOND / mSampleRate; 418506d13227bed31bf4a2dfa30e19198620eb5b120eAndy Hung } else { 418606d13227bed31bf4a2dfa30e19198620eb5b120eAndy Hung mSleepTimeUs = mActiveSleepTimeUs >> sleepTimeShift; 418706d13227bed31bf4a2dfa30e19198620eb5b120eAndy Hung if (mSleepTimeUs < kMinThreadSleepTimeUs) { 418806d13227bed31bf4a2dfa30e19198620eb5b120eAndy Hung mSleepTimeUs = kMinThreadSleepTimeUs; 418906d13227bed31bf4a2dfa30e19198620eb5b120eAndy Hung } 419006d13227bed31bf4a2dfa30e19198620eb5b120eAndy Hung // reduce sleep time in case of consecutive application underruns to avoid 419106d13227bed31bf4a2dfa30e19198620eb5b120eAndy Hung // starving the audio HAL. As activeSleepTimeUs() is larger than a buffer 419206d13227bed31bf4a2dfa30e19198620eb5b120eAndy Hung // duration we would end up writing less data than needed by the audio HAL if 419306d13227bed31bf4a2dfa30e19198620eb5b120eAndy Hung // the condition persists. 419406d13227bed31bf4a2dfa30e19198620eb5b120eAndy Hung if (sleepTimeShift < kMaxThreadSleepTimeShift) { 419506d13227bed31bf4a2dfa30e19198620eb5b120eAndy Hung sleepTimeShift++; 419606d13227bed31bf4a2dfa30e19198620eb5b120eAndy Hung } 419781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 419881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } else { 4199ad9cb8b88e4f8face23f01d8dc89fa769dacb50fEric Laurent mSleepTimeUs = mIdleSleepTimeUs; 420081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 420181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } else if (mBytesWritten != 0 || (mMixerStatus == MIXER_TRACKS_ENABLED)) { 420298ef978df4e928f486d244c4d7f7ad9f13111e98Andy Hung // clear out mMixerBuffer or mSinkBuffer, to ensure buffers are cleared 420398ef978df4e928f486d244c4d7f7ad9f13111e98Andy Hung // before effects processing or output. 420498ef978df4e928f486d244c4d7f7ad9f13111e98Andy Hung if (mMixerBufferValid) { 420598ef978df4e928f486d244c4d7f7ad9f13111e98Andy Hung memset(mMixerBuffer, 0, mMixerBufferSize); 420698ef978df4e928f486d244c4d7f7ad9f13111e98Andy Hung } else { 420798ef978df4e928f486d244c4d7f7ad9f13111e98Andy Hung memset(mSinkBuffer, 0, mSinkBufferSize); 420898ef978df4e928f486d244c4d7f7ad9f13111e98Andy Hung } 4209ad9cb8b88e4f8face23f01d8dc89fa769dacb50fEric Laurent mSleepTimeUs = 0; 421081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent ALOGV_IF(mBytesWritten == 0 && (mMixerStatus == MIXER_TRACKS_ENABLED), 421181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent "anticipated start"); 421281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 421381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // TODO add standby time extension fct of effect tail 421481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 421581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 421681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// prepareTracks_l() must be called with ThreadBase::mLock held 421781784c37c61b09289654b979567a42bf73cd2b12Eric LaurentAudioFlinger::PlaybackThread::mixer_state AudioFlinger::MixerThread::prepareTracks_l( 421881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent Vector< sp<Track> > *tracksToRemove) 421981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 42201bc088a918d7038603230637d640941953b314d4Andy Hung // clean up deleted track names in AudioMixer before allocating new tracks 42211bc088a918d7038603230637d640941953b314d4Andy Hung (void)mTracks.processDeletedTrackNames([this](int name) { 42221bc088a918d7038603230637d640941953b314d4Andy Hung // for each name, destroy it in the AudioMixer 42231bc088a918d7038603230637d640941953b314d4Andy Hung if (mAudioMixer->exists(name)) { 42241bc088a918d7038603230637d640941953b314d4Andy Hung mAudioMixer->destroy(name); 42251bc088a918d7038603230637d640941953b314d4Andy Hung } 42261bc088a918d7038603230637d640941953b314d4Andy Hung }); 42271bc088a918d7038603230637d640941953b314d4Andy Hung mTracks.clearDeletedTrackNames(); 422881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 422981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mixer_state mixerStatus = MIXER_IDLE; 423081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // find out which tracks need to be processed 423181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent size_t count = mActiveTracks.size(); 423281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent size_t mixedTracks = 0; 423381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent size_t tracksWithEffect = 0; 423481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // counts only _active_ fast tracks 423581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent size_t fastTracks = 0; 423681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent uint32_t resetMask = 0; // bit mask of fast tracks that need to be reset 423781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 423881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent float masterVolume = mMasterVolume; 423981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent bool masterMute = mMasterMute; 424081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 424181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (masterMute) { 424281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent masterVolume = 0; 424381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 424481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // Delegate master volume control to effect in output mix effect chain if needed 424581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent sp<EffectChain> chain = getEffectChain_l(AUDIO_SESSION_OUTPUT_MIX); 424681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (chain != 0) { 424781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent uint32_t v = (uint32_t)(masterVolume * (1 << 24)); 424881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent chain->setVolume_l(&v, &v); 424981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent masterVolume = (float)((v + (1 << 23)) >> 24); 425081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent chain.clear(); 425181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 425281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 425381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // prepare a new state to push 425481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent FastMixerStateQueue *sq = NULL; 425581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent FastMixerState *state = NULL; 425681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent bool didModify = false; 425781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent FastMixerStateQueue::block_t block = FastMixerStateQueue::BLOCK_UNTIL_PUSHED; 4258f228531c5d01f497f5802c44545e0000ec44ab83Andy Hung bool coldIdle = false; 42594d23ca370dd0ce584f49a80ef9dfcdbb75ba2c8eGlenn Kasten if (mFastMixer != 0) { 426081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent sq = mFastMixer->sq(); 426181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent state = sq->begin(); 4262f228531c5d01f497f5802c44545e0000ec44ab83Andy Hung coldIdle = state->mCommand == FastMixerState::COLD_IDLE; 426381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 426481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 426569aed5f0f4a3be3996d1e78a0473e1a72c1547daAndy Hung mMixerBufferValid = false; // mMixerBuffer has no valid data until appropriate tracks found. 426698ef978df4e928f486d244c4d7f7ad9f13111e98Andy Hung mEffectBufferValid = false; // mEffectBuffer has no valid data until tracks found. 426769aed5f0f4a3be3996d1e78a0473e1a72c1547daAndy Hung 426881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent for (size_t i=0 ; i<count ; i++) { 4269dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hung const sp<Track> t = mActiveTracks[i]; 427081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 427181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // this const just means the local variable doesn't change 427281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent Track* const track = t.get(); 427381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 427481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // process fast tracks 427581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (track->isFastTrack()) { 427681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 427781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // It's theoretically possible (though unlikely) for a fast track to be created 427881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // and then removed within the same normal mix cycle. This is not a problem, as 427981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // the track never becomes active so it's fast mixer slot is never touched. 428081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // The converse, of removing an (active) track and then creating a new track 428181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // at the identical fast mixer slot within the same normal mix cycle, 428281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // is impossible because the slot isn't marked available until the end of each cycle. 428381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent int j = track->mFastIndex; 4284dc2c50bad491d2c0c8a2efc0e24491076701c63cGlenn Kasten ALOG_ASSERT(0 < j && j < (int)FastMixerState::sMaxFastTracks); 428581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent ALOG_ASSERT(!(mFastTrackAvailMask & (1 << j))); 428681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent FastTrack *fastTrack = &state->mFastTracks[j]; 428781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 428881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // Determine whether the track is currently in underrun condition, 428981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // and whether it had a recent underrun. 429081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent FastTrackDump *ftDump = &mFastMixerDumpState.mTracks[j]; 429181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent FastTrackUnderruns underruns = ftDump->mUnderruns; 429281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent uint32_t recentFull = (underruns.mBitFields.mFull - 429381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent track->mObservedUnderruns.mBitFields.mFull) & UNDERRUN_MASK; 429481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent uint32_t recentPartial = (underruns.mBitFields.mPartial - 429581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent track->mObservedUnderruns.mBitFields.mPartial) & UNDERRUN_MASK; 429681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent uint32_t recentEmpty = (underruns.mBitFields.mEmpty - 429781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent track->mObservedUnderruns.mBitFields.mEmpty) & UNDERRUN_MASK; 429881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent uint32_t recentUnderruns = recentPartial + recentEmpty; 429981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent track->mObservedUnderruns = underruns; 430081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // don't count underruns that occur while stopping or pausing 430181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // or stopped which can occur when flush() is called while active 430282aaf94a5b18939e4d790bbc752031f3070704a3Glenn Kasten if (!(track->isStopping() || track->isPausing() || track->isStopped()) && 430382aaf94a5b18939e4d790bbc752031f3070704a3Glenn Kasten recentUnderruns > 0) { 430482aaf94a5b18939e4d790bbc752031f3070704a3Glenn Kasten // FIXME fast mixer will pull & mix partial buffers, but we count as a full underrun 430582aaf94a5b18939e4d790bbc752031f3070704a3Glenn Kasten track->mAudioTrackServerProxy->tallyUnderrunFrames(recentUnderruns * mFrameCount); 43062812d9ea3a3a33142dd8e23c9d949c498d6f7a12Phil Burk } else { 43072812d9ea3a3a33142dd8e23c9d949c498d6f7a12Phil Burk track->mAudioTrackServerProxy->tallyUnderrunFrames(0); 430881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 430981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 431081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // This is similar to the state machine for normal tracks, 431181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // with a few modifications for fast tracks. 431281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent bool isActive = true; 431381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent switch (track->mState) { 431481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent case TrackBase::STOPPING_1: 431581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // track stays active in STOPPING_1 state until first underrun 4316bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent if (recentUnderruns > 0 || track->isTerminated()) { 431781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent track->mState = TrackBase::STOPPING_2; 431881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 431981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent break; 432081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent case TrackBase::PAUSING: 432181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // ramp down is not yet implemented 432281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent track->setPaused(); 432381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent break; 432481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent case TrackBase::RESUMING: 432581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // ramp up is not yet implemented 432681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent track->mState = TrackBase::ACTIVE; 432781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent break; 432881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent case TrackBase::ACTIVE: 432981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (recentFull > 0 || recentPartial > 0) { 433081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // track has provided at least some frames recently: reset retry count 433181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent track->mRetryCount = kMaxTrackRetries; 433281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 433381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (recentUnderruns == 0) { 433481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // no recent underruns: stay active 433581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent break; 433681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 433781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // there has recently been an underrun of some kind 433881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (track->sharedBuffer() == 0) { 433981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // were any of the recent underruns "empty" (no frames available)? 434081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (recentEmpty == 0) { 434181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // no, then ignore the partial underruns as they are allowed indefinitely 434281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent break; 434381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 434481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // there has recently been an "empty" underrun: decrement the retry counter 434581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (--(track->mRetryCount) > 0) { 434681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent break; 434781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 434881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // indicate to client process that the track was disabled because of underrun; 434981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // it will then automatically call start() when data is available 43504d231dc0ee34380956c71cbe18a750e487a69601Eric Laurent track->disable(); 435181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // remove from active list, but state remains ACTIVE [confusing but true] 435281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent isActive = false; 435381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent break; 435481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 435581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // fall through 435681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent case TrackBase::STOPPING_2: 435781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent case TrackBase::PAUSED: 435881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent case TrackBase::STOPPED: 435981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent case TrackBase::FLUSHED: // flush() while active 436081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // Check for presentation complete if track is inactive 436181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // We have consumed all the buffers of this track. 436281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // This would be incomplete if we auto-paused on underrun 436381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent { 43641dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov uint32_t latency = 0; 43651dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov status_t result = mOutput->stream->getLatency(&latency); 43661dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov ALOGE_IF(result != OK, 43671dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov "Error when retrieving output stream latency: %d", result); 43681dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov size_t audioHALFrames = (latency * mSampleRate) / 1000; 4369818e7a32ce3633980138aff2c2bfcc5158b3cfccAndy Hung int64_t framesWritten = mBytesWritten / mFrameSize; 437081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (!(mStandby || track->presentationComplete(framesWritten, audioHALFrames))) { 437181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // track stays in active list until presentation is complete 437281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent break; 437381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 437481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 437581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (track->isStopping_2()) { 437681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent track->mState = TrackBase::STOPPED; 437781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 437881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (track->isStopped()) { 437981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // Can't reset directly, as fast mixer is still polling this track 438081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // track->reset(); 438181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // So instead mark this track as needing to be reset after push with ack 438281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent resetMask |= 1 << i; 438381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 438481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent isActive = false; 438581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent break; 438681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent case TrackBase::IDLE: 438781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent default: 4388adad3d7d935da176ff24941b4ae9edf7340e9b96Glenn Kasten LOG_ALWAYS_FATAL("unexpected track state %d", track->mState); 438981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 439081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 439181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (isActive) { 439281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // was it previously inactive? 439381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (!(state->mTrackMask & (1 << j))) { 439481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent ExtendedAudioBufferProvider *eabp = track; 439581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent VolumeProvider *vp = track; 439681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent fastTrack->mBufferProvider = eabp; 439781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent fastTrack->mVolumeProvider = vp; 439881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent fastTrack->mChannelMask = track->mChannelMask; 4399e8a1ced4da17dc6c07803dc2af8060f62a8389c1Andy Hung fastTrack->mFormat = track->mFormat; 440081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent fastTrack->mGeneration++; 440181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent state->mTrackMask |= 1 << j; 440281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent didModify = true; 440381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // no acknowledgement required for newly active tracks 440481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 440512381092fdb5810cb27f738435ea8a0e3d2d0f42Kevin Rocard sp<AudioTrackServerProxy> proxy = track->mAudioTrackServerProxy; 440681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // cache the combined master volume and stream type volume for fast mixer; this 440781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // lacks any synchronization or barrier so VolumeProvider may read a stale value 44089fc8b5cd4a64ef07e84c69112461324d5c13a0b0Andy Hung const float vh = track->getVolumeHandler()->getVolume( 440912381092fdb5810cb27f738435ea8a0e3d2d0f42Kevin Rocard proxy->framesReleased()).first; 441012381092fdb5810cb27f738435ea8a0e3d2d0f42Kevin Rocard float volume = masterVolume 44119fc8b5cd4a64ef07e84c69112461324d5c13a0b0Andy Hung * mStreamTypes[track->streamType()].volume 44129fc8b5cd4a64ef07e84c69112461324d5c13a0b0Andy Hung * vh; 4413b0eeaf121e896f7158ee9961cb9009554d37e53eKevin Rocard track->mCachedVolume = volume; 441412381092fdb5810cb27f738435ea8a0e3d2d0f42Kevin Rocard gain_minifloat_packed_t vlr = proxy->getVolumeLR(); 441512381092fdb5810cb27f738435ea8a0e3d2d0f42Kevin Rocard float vlf = volume * float_from_gain(gain_minifloat_unpack_left(vlr)); 441612381092fdb5810cb27f738435ea8a0e3d2d0f42Kevin Rocard float vrf = volume * float_from_gain(gain_minifloat_unpack_right(vlr)); 441712381092fdb5810cb27f738435ea8a0e3d2d0f42Kevin Rocard track->setFinalVolume((vlf + vrf) / 2.f); 441881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent ++fastTracks; 441981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } else { 442081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // was it previously active? 442181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (state->mTrackMask & (1 << j)) { 442281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent fastTrack->mBufferProvider = NULL; 442381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent fastTrack->mGeneration++; 442481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent state->mTrackMask &= ~(1 << j); 442581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent didModify = true; 442681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // If any fast tracks were removed, we must wait for acknowledgement 442781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // because we're about to decrement the last sp<> on those tracks. 442881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent block = FastMixerStateQueue::BLOCK_UNTIL_ACKED; 442981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } else { 4430bf848afa185669971def54404f176308e3bafebcGlenn Kasten // ALOGW rather than LOG_ALWAYS_FATAL because it seems there are cases where an 4431bf848afa185669971def54404f176308e3bafebcGlenn Kasten // AudioTrack may start (which may not be with a start() but with a write() 4432bf848afa185669971def54404f176308e3bafebcGlenn Kasten // after underrun) and immediately paused or released. In that case the 4433bf848afa185669971def54404f176308e3bafebcGlenn Kasten // FastTrack state hasn't had time to update. 4434bf848afa185669971def54404f176308e3bafebcGlenn Kasten // TODO Remove the ALOGW when this theory is confirmed. 4435bf848afa185669971def54404f176308e3bafebcGlenn Kasten ALOGW("fast track %d should have been active; " 4436f7d65ee34f64e8fad9c5af3f11da783193caf5f9Glenn Kasten "mState=%d, mTrackMask=%#x, recentUnderruns=%u, isShared=%d", 4437f7d65ee34f64e8fad9c5af3f11da783193caf5f9Glenn Kasten j, track->mState, state->mTrackMask, recentUnderruns, 4438f7d65ee34f64e8fad9c5af3f11da783193caf5f9Glenn Kasten track->sharedBuffer() != 0); 4439bf848afa185669971def54404f176308e3bafebcGlenn Kasten // Since the FastMixer state already has the track inactive, do nothing here. 444081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 444181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent tracksToRemove->add(track); 444281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // Avoids a misleading display in dumpsys 444381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent track->mObservedUnderruns.mBitFields.mMostRecent = UNDERRUN_FULL; 444481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 444581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent continue; 444681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 444781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 444881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent { // local variable scope to avoid goto warning 444981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 445081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent audio_track_cblk_t* cblk = track->cblk(); 445181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 445281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // The first time a track is added we wait 445381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // for all its buffers to be filled before processing it 445481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent int name = track->name(); 44551bc088a918d7038603230637d640941953b314d4Andy Hung 44561bc088a918d7038603230637d640941953b314d4Andy Hung // if an active track doesn't exist in the AudioMixer, create it. 44571bc088a918d7038603230637d640941953b314d4Andy Hung if (!mAudioMixer->exists(name)) { 44581bc088a918d7038603230637d640941953b314d4Andy Hung status_t status = mAudioMixer->create( 44591bc088a918d7038603230637d640941953b314d4Andy Hung name, 44601bc088a918d7038603230637d640941953b314d4Andy Hung track->mChannelMask, 44611bc088a918d7038603230637d640941953b314d4Andy Hung track->mFormat, 44621bc088a918d7038603230637d640941953b314d4Andy Hung track->mSessionId); 44631bc088a918d7038603230637d640941953b314d4Andy Hung if (status != OK) { 44641bc088a918d7038603230637d640941953b314d4Andy Hung ALOGW("%s: cannot create track name" 44651bc088a918d7038603230637d640941953b314d4Andy Hung " %d, mask %#x, format %#x, sessionId %d in AudioMixer", 44661bc088a918d7038603230637d640941953b314d4Andy Hung __func__, name, track->mChannelMask, track->mFormat, track->mSessionId); 44671bc088a918d7038603230637d640941953b314d4Andy Hung tracksToRemove->add(track); 44681bc088a918d7038603230637d640941953b314d4Andy Hung track->invalidate(); // consider it dead. 44691bc088a918d7038603230637d640941953b314d4Andy Hung continue; 44701bc088a918d7038603230637d640941953b314d4Andy Hung } 44711bc088a918d7038603230637d640941953b314d4Andy Hung } 44721bc088a918d7038603230637d640941953b314d4Andy Hung 447381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // make sure that we have enough frames to mix one full buffer. 447481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // enforce this condition only once to enable draining the buffer in case the client 447581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // app does not call stop() and relies on underrun to stop: 447681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // hence the test on (mMixerStatus == MIXER_TRACKS_READY) meaning the track was mixed 447781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // during last round 44789f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten size_t desiredFrames; 44798edb8dc44b8a2f81bdb5db645b6b708548771a31Andy Hung const uint32_t sampleRate = track->mAudioTrackServerProxy->getSampleRate(); 44805a8a95de6dad1a3bcf3da5a37b35766e89086e13Ricardo Garcia AudioPlaybackRate playbackRate = track->mAudioTrackServerProxy->getPlaybackRate(); 44818edb8dc44b8a2f81bdb5db645b6b708548771a31Andy Hung 44828edb8dc44b8a2f81bdb5db645b6b708548771a31Andy Hung desiredFrames = sourceFramesNeededWithTimestretch( 44835a8a95de6dad1a3bcf3da5a37b35766e89086e13Ricardo Garcia sampleRate, mNormalFrameCount, mSampleRate, playbackRate.mSpeed); 44848edb8dc44b8a2f81bdb5db645b6b708548771a31Andy Hung // TODO: ONLY USED FOR LEGACY RESAMPLERS, remove when they are removed. 44858edb8dc44b8a2f81bdb5db645b6b708548771a31Andy Hung // add frames already consumed but not yet released by the resampler 44868edb8dc44b8a2f81bdb5db645b6b708548771a31Andy Hung // because mAudioTrackServerProxy->framesReady() will include these frames 44878edb8dc44b8a2f81bdb5db645b6b708548771a31Andy Hung desiredFrames += mAudioMixer->getUnreleasedFrames(track->name()); 44888edb8dc44b8a2f81bdb5db645b6b708548771a31Andy Hung 448981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent uint32_t minFrames = 1; 449081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if ((track->sharedBuffer() == 0) && !track->isStopped() && !track->isPausing() && 449181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent (mMixerStatusIgnoringFastTracks == MIXER_TRACKS_READY)) { 44929f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten minFrames = desiredFrames; 44939f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten } 449413e4c960ea3db03a43e084fbd85d52aa77f7b871Eric Laurent 449513e4c960ea3db03a43e084fbd85d52aa77f7b871Eric Laurent size_t framesReady = track->framesReady(); 4496e77540228e1f60b1129a1615d2e43e0bf8015d3cGlenn Kasten if (ATRACE_ENABLED()) { 4497e77540228e1f60b1129a1615d2e43e0bf8015d3cGlenn Kasten // I wish we had formatted trace names 44981bc088a918d7038603230637d640941953b314d4Andy Hung std::string traceName("nRdy"); 44991bc088a918d7038603230637d640941953b314d4Andy Hung traceName += std::to_string(track->name()); 45001bc088a918d7038603230637d640941953b314d4Andy Hung ATRACE_INT(traceName.c_str(), framesReady); 4501e77540228e1f60b1129a1615d2e43e0bf8015d3cGlenn Kasten } 45029f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten if ((framesReady >= minFrames) && track->isReady() && 450381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent !track->isPaused() && !track->isTerminated()) 450481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent { 4505f20e1d8df84c5fbeeace0052d100982ae39bb7a4Glenn Kasten ALOGVV("track %d s=%08x [OK] on thread %p", name, cblk->mServer, this); 450681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 450781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mixedTracks++; 450881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 450969aed5f0f4a3be3996d1e78a0473e1a72c1547daAndy Hung // track->mainBuffer() != mSinkBuffer or mMixerBuffer means 451069aed5f0f4a3be3996d1e78a0473e1a72c1547daAndy Hung // there is an effect chain connected to the track 451181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent chain.clear(); 451269aed5f0f4a3be3996d1e78a0473e1a72c1547daAndy Hung if (track->mainBuffer() != mSinkBuffer && 451369aed5f0f4a3be3996d1e78a0473e1a72c1547daAndy Hung track->mainBuffer() != mMixerBuffer) { 451498ef978df4e928f486d244c4d7f7ad9f13111e98Andy Hung if (mEffectBufferEnabled) { 451598ef978df4e928f486d244c4d7f7ad9f13111e98Andy Hung mEffectBufferValid = true; // Later can set directly. 451698ef978df4e928f486d244c4d7f7ad9f13111e98Andy Hung } 451781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent chain = getEffectChain_l(track->sessionId()); 451881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // Delegate volume control to effect in track effect chain if needed 451981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (chain != 0) { 452081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent tracksWithEffect++; 452181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } else { 452281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent ALOGW("prepareTracks_l(): track %d attached to effect but no chain found on " 452381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent "session %d", 452481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent name, track->sessionId()); 452581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 452681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 452781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 452881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 452981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent int param = AudioMixer::VOLUME; 453081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (track->mFillingUpStatus == Track::FS_FILLED) { 453181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // no ramp for the first volume setting 453281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent track->mFillingUpStatus = Track::FS_ACTIVE; 453381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (track->mState == TrackBase::RESUMING) { 453481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent track->mState = TrackBase::ACTIVE; 453581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent param = AudioMixer::RAMP_VOLUME; 453681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 453781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mAudioMixer->setParameter(name, AudioMixer::RESAMPLE, AudioMixer::RESET, NULL); 45387c29ec95f494d241faa07d0d70579729520e3114Eric Laurent mLeftVolFloat = -1.0; 4539f20e1d8df84c5fbeeace0052d100982ae39bb7a4Glenn Kasten // FIXME should not make a decision based on mServer 4540f20e1d8df84c5fbeeace0052d100982ae39bb7a4Glenn Kasten } else if (cblk->mServer != 0) { 454181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // If the track is stopped before the first frame was mixed, 454281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // do not apply ramp 454381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent param = AudioMixer::RAMP_VOLUME; 454481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 454581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 454681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // compute volume for this track 45476be494077f8d7970f3a88129c5d139c5a0c88f6dAndy Hung uint32_t vl, vr; // in U8.24 integer format 45486be494077f8d7970f3a88129c5d139c5a0c88f6dAndy Hung float vlf, vrf, vaf; // in [0.0, 1.0] float format 45497c29ec95f494d241faa07d0d70579729520e3114Eric Laurent // read original volumes with volume control 45507c29ec95f494d241faa07d0d70579729520e3114Eric Laurent float typeVolume = mStreamTypes[track->streamType()].volume; 45517c29ec95f494d241faa07d0d70579729520e3114Eric Laurent float v = masterVolume * typeVolume; 45527c29ec95f494d241faa07d0d70579729520e3114Eric Laurent 4553e4756fe3a387615acb63c6a05788c8db9b5786cbGlenn Kasten if (track->isPausing() || mStreamTypes[track->streamType()].mute) { 45546be494077f8d7970f3a88129c5d139c5a0c88f6dAndy Hung vl = vr = 0; 45556be494077f8d7970f3a88129c5d139c5a0c88f6dAndy Hung vlf = vrf = vaf = 0.; 455681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (track->isPausing()) { 455781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent track->setPaused(); 455881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 455981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } else { 45605bba2f6916dbe00aea7c0521faa0c6ed42114a75Eric Laurent sp<AudioTrackServerProxy> proxy = track->mAudioTrackServerProxy; 4561c56f3426099a3cf2d07ccff8886050c7fbce140fGlenn Kasten gain_minifloat_packed_t vlr = proxy->getVolumeLR(); 45626be494077f8d7970f3a88129c5d139c5a0c88f6dAndy Hung vlf = float_from_gain(gain_minifloat_unpack_left(vlr)); 45636be494077f8d7970f3a88129c5d139c5a0c88f6dAndy Hung vrf = float_from_gain(gain_minifloat_unpack_right(vlr)); 456481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // track volumes come from shared memory, so can't be trusted and must be clamped 4565c56f3426099a3cf2d07ccff8886050c7fbce140fGlenn Kasten if (vlf > GAIN_FLOAT_UNITY) { 4566c56f3426099a3cf2d07ccff8886050c7fbce140fGlenn Kasten ALOGV("Track left volume out of range: %.3g", vlf); 4567c56f3426099a3cf2d07ccff8886050c7fbce140fGlenn Kasten vlf = GAIN_FLOAT_UNITY; 456881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 4569c56f3426099a3cf2d07ccff8886050c7fbce140fGlenn Kasten if (vrf > GAIN_FLOAT_UNITY) { 4570c56f3426099a3cf2d07ccff8886050c7fbce140fGlenn Kasten ALOGV("Track right volume out of range: %.3g", vrf); 4571c56f3426099a3cf2d07ccff8886050c7fbce140fGlenn Kasten vrf = GAIN_FLOAT_UNITY; 457281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 45739fc8b5cd4a64ef07e84c69112461324d5c13a0b0Andy Hung const float vh = track->getVolumeHandler()->getVolume( 457410cbff139360f3f642e0e3b3ccf2d463dbed22cfAndy Hung track->mAudioTrackServerProxy->framesReleased()).first; 45759fc8b5cd4a64ef07e84c69112461324d5c13a0b0Andy Hung // now apply the master volume and stream type volume and shaper volume 45769fc8b5cd4a64ef07e84c69112461324d5c13a0b0Andy Hung vlf *= v * vh; 45779fc8b5cd4a64ef07e84c69112461324d5c13a0b0Andy Hung vrf *= v * vh; 457881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // assuming master volume and stream type volume each go up to 1.0, 45796be494077f8d7970f3a88129c5d139c5a0c88f6dAndy Hung // then derive vl and vr as U8.24 versions for the effect chain 45806be494077f8d7970f3a88129c5d139c5a0c88f6dAndy Hung const float scaleto8_24 = MAX_GAIN_INT * MAX_GAIN_INT; 45816be494077f8d7970f3a88129c5d139c5a0c88f6dAndy Hung vl = (uint32_t) (scaleto8_24 * vlf); 45826be494077f8d7970f3a88129c5d139c5a0c88f6dAndy Hung vr = (uint32_t) (scaleto8_24 * vrf); 45836be494077f8d7970f3a88129c5d139c5a0c88f6dAndy Hung // vl and vr are now in U8.24 format 4584e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten uint16_t sendLevel = proxy->getSendLevel_U4_12(); 458581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // send level comes from shared memory and so may be corrupt 458681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (sendLevel > MAX_GAIN_INT) { 458781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent ALOGV("Track send level out of range: %04X", sendLevel); 458881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent sendLevel = MAX_GAIN_INT; 458981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 45906be494077f8d7970f3a88129c5d139c5a0c88f6dAndy Hung // vaf is represented as [0.0, 1.0] float by rescaling sendLevel 45916be494077f8d7970f3a88129c5d139c5a0c88f6dAndy Hung vaf = v * sendLevel * (1. / MAX_GAIN_INT); 459281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 4593bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent 459412381092fdb5810cb27f738435ea8a0e3d2d0f42Kevin Rocard track->setFinalVolume((vrf + vlf) / 2.f); 459512381092fdb5810cb27f738435ea8a0e3d2d0f42Kevin Rocard 459681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // Delegate volume control to effect in track effect chain if needed 459781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (chain != 0 && chain->setVolume_l(&vl, &vr)) { 459881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // Do not ramp volume if volume is controlled by effect 459981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent param = AudioMixer::VOLUME; 4600b6be7f22a82ee3bad8bcc709d21e72fc4727da09Bryant Liu // Update remaining floating point volume levels 4601b6be7f22a82ee3bad8bcc709d21e72fc4727da09Bryant Liu vlf = (float)vl / (1 << 24); 4602b6be7f22a82ee3bad8bcc709d21e72fc4727da09Bryant Liu vrf = (float)vr / (1 << 24); 460381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent track->mHasVolumeController = true; 460481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } else { 460581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // force no volume ramp when volume controller was just disabled or removed 460681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // from effect chain to avoid volume spike 460781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (track->mHasVolumeController) { 460881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent param = AudioMixer::VOLUME; 460981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 461081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent track->mHasVolumeController = false; 461181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 461281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 46137c29ec95f494d241faa07d0d70579729520e3114Eric Laurent // For dedicated VoIP outputs, let the HAL apply the stream volume. Track volume is 46147c29ec95f494d241faa07d0d70579729520e3114Eric Laurent // still applied by the mixer. 46157c29ec95f494d241faa07d0d70579729520e3114Eric Laurent if ((mOutput->flags & AUDIO_OUTPUT_FLAG_VOIP_RX) != 0) { 46167c29ec95f494d241faa07d0d70579729520e3114Eric Laurent v = mStreamTypes[track->streamType()].mute ? 0.0f : v; 46177c29ec95f494d241faa07d0d70579729520e3114Eric Laurent if (v != mLeftVolFloat) { 46187c29ec95f494d241faa07d0d70579729520e3114Eric Laurent status_t result = mOutput->stream->setVolume(v, v); 46197c29ec95f494d241faa07d0d70579729520e3114Eric Laurent ALOGE_IF(result != OK, "Error when setting output stream volume: %d", result); 46207c29ec95f494d241faa07d0d70579729520e3114Eric Laurent if (result == OK) { 46217c29ec95f494d241faa07d0d70579729520e3114Eric Laurent mLeftVolFloat = v; 46227c29ec95f494d241faa07d0d70579729520e3114Eric Laurent } 46237c29ec95f494d241faa07d0d70579729520e3114Eric Laurent } 46247c29ec95f494d241faa07d0d70579729520e3114Eric Laurent // if stream volume was successfully sent to the HAL, mLeftVolFloat == v here and we 46257c29ec95f494d241faa07d0d70579729520e3114Eric Laurent // remove stream volume contribution from software volume. 46267c29ec95f494d241faa07d0d70579729520e3114Eric Laurent if (v != 0.0f && mLeftVolFloat == v) { 46277c29ec95f494d241faa07d0d70579729520e3114Eric Laurent vlf = min(1.0f, vlf / v); 46287c29ec95f494d241faa07d0d70579729520e3114Eric Laurent vrf = min(1.0f, vrf / v); 46297c29ec95f494d241faa07d0d70579729520e3114Eric Laurent vaf = min(1.0f, vaf / v); 46307c29ec95f494d241faa07d0d70579729520e3114Eric Laurent } 46317c29ec95f494d241faa07d0d70579729520e3114Eric Laurent } 463281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // XXX: these things DON'T need to be done each time 463381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mAudioMixer->setBufferProvider(name, track); 463481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mAudioMixer->enable(name); 463581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 46366be494077f8d7970f3a88129c5d139c5a0c88f6dAndy Hung mAudioMixer->setParameter(name, param, AudioMixer::VOLUME0, &vlf); 46376be494077f8d7970f3a88129c5d139c5a0c88f6dAndy Hung mAudioMixer->setParameter(name, param, AudioMixer::VOLUME1, &vrf); 46386be494077f8d7970f3a88129c5d139c5a0c88f6dAndy Hung mAudioMixer->setParameter(name, param, AudioMixer::AUXLEVEL, &vaf); 463981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mAudioMixer->setParameter( 464081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent name, 464181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent AudioMixer::TRACK, 464281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent AudioMixer::FORMAT, (void *)track->format()); 464381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mAudioMixer->setParameter( 464481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent name, 464581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent AudioMixer::TRACK, 4646377b2ec9a2885f9b6405b07ba900a9e3f4349c38Kévin PETIT AudioMixer::CHANNEL_MASK, (void *)(uintptr_t)track->channelMask()); 46479a59276fb465e492138e0576523b54079671e8f4Andy Hung mAudioMixer->setParameter( 46489a59276fb465e492138e0576523b54079671e8f4Andy Hung name, 46499a59276fb465e492138e0576523b54079671e8f4Andy Hung AudioMixer::TRACK, 46509a59276fb465e492138e0576523b54079671e8f4Andy Hung AudioMixer::MIXER_CHANNEL_MASK, (void *)(uintptr_t)mChannelMask); 4651e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten // limit track sample rate to 2 x output sample rate, which changes at re-configuration 4652cd04484f4837b8ca0041d118286ab6a98e84fc75Andy Hung uint32_t maxSampleRate = mSampleRate * AUDIO_RESAMPLER_DOWN_RATIO_MAX; 46539f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten uint32_t reqSampleRate = track->mAudioTrackServerProxy->getSampleRate(); 4654e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten if (reqSampleRate == 0) { 4655e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten reqSampleRate = mSampleRate; 4656e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten } else if (reqSampleRate > maxSampleRate) { 4657e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten reqSampleRate = maxSampleRate; 4658e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39Glenn Kasten } 465981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mAudioMixer->setParameter( 466081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent name, 466181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent AudioMixer::RESAMPLE, 466281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent AudioMixer::SAMPLE_RATE, 4663377b2ec9a2885f9b6405b07ba900a9e3f4349c38Kévin PETIT (void *)(uintptr_t)reqSampleRate); 46648edb8dc44b8a2f81bdb5db645b6b708548771a31Andy Hung 46655a8a95de6dad1a3bcf3da5a37b35766e89086e13Ricardo Garcia AudioPlaybackRate playbackRate = track->mAudioTrackServerProxy->getPlaybackRate(); 46668edb8dc44b8a2f81bdb5db645b6b708548771a31Andy Hung mAudioMixer->setParameter( 46678edb8dc44b8a2f81bdb5db645b6b708548771a31Andy Hung name, 46688edb8dc44b8a2f81bdb5db645b6b708548771a31Andy Hung AudioMixer::TIMESTRETCH, 46698edb8dc44b8a2f81bdb5db645b6b708548771a31Andy Hung AudioMixer::PLAYBACK_RATE, 46705a8a95de6dad1a3bcf3da5a37b35766e89086e13Ricardo Garcia &playbackRate); 46718edb8dc44b8a2f81bdb5db645b6b708548771a31Andy Hung 467269aed5f0f4a3be3996d1e78a0473e1a72c1547daAndy Hung /* 467369aed5f0f4a3be3996d1e78a0473e1a72c1547daAndy Hung * Select the appropriate output buffer for the track. 467469aed5f0f4a3be3996d1e78a0473e1a72c1547daAndy Hung * 467598ef978df4e928f486d244c4d7f7ad9f13111e98Andy Hung * Tracks with effects go into their own effects chain buffer 467698ef978df4e928f486d244c4d7f7ad9f13111e98Andy Hung * and from there into either mEffectBuffer or mSinkBuffer. 467769aed5f0f4a3be3996d1e78a0473e1a72c1547daAndy Hung * 467869aed5f0f4a3be3996d1e78a0473e1a72c1547daAndy Hung * Other tracks can use mMixerBuffer for higher precision 467969aed5f0f4a3be3996d1e78a0473e1a72c1547daAndy Hung * channel accumulation. If this buffer is enabled 468069aed5f0f4a3be3996d1e78a0473e1a72c1547daAndy Hung * (mMixerBufferEnabled true), then selected tracks will accumulate 468169aed5f0f4a3be3996d1e78a0473e1a72c1547daAndy Hung * into it. 468269aed5f0f4a3be3996d1e78a0473e1a72c1547daAndy Hung * 468369aed5f0f4a3be3996d1e78a0473e1a72c1547daAndy Hung */ 468469aed5f0f4a3be3996d1e78a0473e1a72c1547daAndy Hung if (mMixerBufferEnabled 468569aed5f0f4a3be3996d1e78a0473e1a72c1547daAndy Hung && (track->mainBuffer() == mSinkBuffer 468669aed5f0f4a3be3996d1e78a0473e1a72c1547daAndy Hung || track->mainBuffer() == mMixerBuffer)) { 468769aed5f0f4a3be3996d1e78a0473e1a72c1547daAndy Hung mAudioMixer->setParameter( 468869aed5f0f4a3be3996d1e78a0473e1a72c1547daAndy Hung name, 468969aed5f0f4a3be3996d1e78a0473e1a72c1547daAndy Hung AudioMixer::TRACK, 4690788207057ed4b8df4719ed8089f376ef52de9ca1Andy Hung AudioMixer::MIXER_FORMAT, (void *)mMixerBufferFormat); 469169aed5f0f4a3be3996d1e78a0473e1a72c1547daAndy Hung mAudioMixer->setParameter( 469269aed5f0f4a3be3996d1e78a0473e1a72c1547daAndy Hung name, 469369aed5f0f4a3be3996d1e78a0473e1a72c1547daAndy Hung AudioMixer::TRACK, 469469aed5f0f4a3be3996d1e78a0473e1a72c1547daAndy Hung AudioMixer::MAIN_BUFFER, (void *)mMixerBuffer); 469569aed5f0f4a3be3996d1e78a0473e1a72c1547daAndy Hung // TODO: override track->mainBuffer()? 469669aed5f0f4a3be3996d1e78a0473e1a72c1547daAndy Hung mMixerBufferValid = true; 469769aed5f0f4a3be3996d1e78a0473e1a72c1547daAndy Hung } else { 469869aed5f0f4a3be3996d1e78a0473e1a72c1547daAndy Hung mAudioMixer->setParameter( 469969aed5f0f4a3be3996d1e78a0473e1a72c1547daAndy Hung name, 470069aed5f0f4a3be3996d1e78a0473e1a72c1547daAndy Hung AudioMixer::TRACK, 470194a1ee822686e920a33e312f4032f991731aea07rago AudioMixer::MIXER_FORMAT, (void *)EFFECT_BUFFER_FORMAT); 470269aed5f0f4a3be3996d1e78a0473e1a72c1547daAndy Hung mAudioMixer->setParameter( 470369aed5f0f4a3be3996d1e78a0473e1a72c1547daAndy Hung name, 470469aed5f0f4a3be3996d1e78a0473e1a72c1547daAndy Hung AudioMixer::TRACK, 470569aed5f0f4a3be3996d1e78a0473e1a72c1547daAndy Hung AudioMixer::MAIN_BUFFER, (void *)track->mainBuffer()); 470669aed5f0f4a3be3996d1e78a0473e1a72c1547daAndy Hung } 470781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mAudioMixer->setParameter( 470881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent name, 470981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent AudioMixer::TRACK, 471081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent AudioMixer::AUX_BUFFER, (void *)track->auxBuffer()); 471181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 471281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // reset retry count 471381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent track->mRetryCount = kMaxTrackRetries; 471481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 471581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // If one track is ready, set the mixer ready if: 471681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // - the mixer was not ready during previous round OR 471781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // - no other track is not ready 471881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (mMixerStatusIgnoringFastTracks != MIXER_TRACKS_READY || 471981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mixerStatus != MIXER_TRACKS_ENABLED) { 472081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mixerStatus = MIXER_TRACKS_READY; 472181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 472281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } else { 47239f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten if (framesReady < desiredFrames && !track->isStopped() && !track->isPaused()) { 472408fb1743f80437c38b4094070d851ea7f6d485e5Andy Hung ALOGV("track(%p) underrun, framesReady(%zu) < framesDesired(%zd)", 472508fb1743f80437c38b4094070d851ea7f6d485e5Andy Hung track, framesReady, desiredFrames); 472682aaf94a5b18939e4d790bbc752031f3070704a3Glenn Kasten track->mAudioTrackServerProxy->tallyUnderrunFrames(desiredFrames); 47272812d9ea3a3a33142dd8e23c9d949c498d6f7a12Phil Burk } else { 47282812d9ea3a3a33142dd8e23c9d949c498d6f7a12Phil Burk track->mAudioTrackServerProxy->tallyUnderrunFrames(0); 47299f80dd223d83d9bb9077fb6baee056cee4eaf7e5Glenn Kasten } 47302812d9ea3a3a33142dd8e23c9d949c498d6f7a12Phil Burk 473181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // clear effect chain input buffer if an active track underruns to avoid sending 473281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // previous audio buffer again to effects 473381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent chain = getEffectChain_l(track->sessionId()); 473481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (chain != 0) { 473581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent chain->clearInputBuffer(); 473681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 473781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 4738f20e1d8df84c5fbeeace0052d100982ae39bb7a4Glenn Kasten ALOGVV("track %d s=%08x [NOT READY] on thread %p", name, cblk->mServer, this); 473981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if ((track->sharedBuffer() != 0) || track->isTerminated() || 474081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent track->isStopped() || track->isPaused()) { 474181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // We have consumed all the buffers of this track. 474281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // Remove it from the list of active tracks. 474381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // TODO: use actual buffer filling status instead of latency when available from 474481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // audio HAL 474581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent size_t audioHALFrames = (latency_l() * mSampleRate) / 1000; 4746818e7a32ce3633980138aff2c2bfcc5158b3cfccAndy Hung int64_t framesWritten = mBytesWritten / mFrameSize; 474781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (mStandby || track->presentationComplete(framesWritten, audioHALFrames)) { 474881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (track->isStopped()) { 474981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent track->reset(); 475081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 475181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent tracksToRemove->add(track); 475281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 475381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } else { 475481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // No buffers for this track. Give it a few chances to 475581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // fill a buffer, then remove it from active list. 475681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (--(track->mRetryCount) <= 0) { 4757c9b2e20f7c9a71e07ef398152709c76079decbcdGlenn Kasten ALOGI("BUFFER TIMEOUT: remove(%d) from active list on thread %p", name, this); 475881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent tracksToRemove->add(track); 475981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // indicate to client process that the track was disabled because of underrun; 476081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // it will then automatically call start() when data is available 47614d231dc0ee34380956c71cbe18a750e487a69601Eric Laurent track->disable(); 476281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // If one track is not ready, mark the mixer also not ready if: 476381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // - the mixer was ready during previous round OR 476481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // - no other track is ready 476581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } else if (mMixerStatusIgnoringFastTracks == MIXER_TRACKS_READY || 476681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mixerStatus != MIXER_TRACKS_READY) { 476781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mixerStatus = MIXER_TRACKS_ENABLED; 476881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 476981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 477081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mAudioMixer->disable(name); 477181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 477281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 477381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } // local variable scope to avoid goto warning 477481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 477581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 477681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 477781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // Push the new FastMixer state if necessary 477881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent bool pauseAudioWatchdog = false; 477981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (didModify) { 478081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent state->mFastTracksGen++; 478181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // if the fast mixer was active, but now there are no fast tracks, then put it in cold idle 478281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (kUseFastMixer == FastMixer_Dynamic && 478381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent state->mCommand == FastMixerState::MIX_WRITE && state->mTrackMask <= 1) { 478481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent state->mCommand = FastMixerState::COLD_IDLE; 478581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent state->mColdFutexAddr = &mFastMixerFutex; 478681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent state->mColdGen++; 478781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mFastMixerFutex = 0; 478881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (kUseFastMixer == FastMixer_Dynamic) { 478981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mNormalSink = mOutputSink; 479081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 479181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // If we go into cold idle, need to wait for acknowledgement 479281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // so that fast mixer stops doing I/O. 479381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent block = FastMixerStateQueue::BLOCK_UNTIL_ACKED; 479481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent pauseAudioWatchdog = true; 479581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 479681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 479781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (sq != NULL) { 479881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent sq->end(didModify); 4799f228531c5d01f497f5802c44545e0000ec44ab83Andy Hung // No need to block if the FastMixer is in COLD_IDLE as the FastThread 4800f228531c5d01f497f5802c44545e0000ec44ab83Andy Hung // is not active. (We BLOCK_UNTIL_ACKED when entering COLD_IDLE 4801f228531c5d01f497f5802c44545e0000ec44ab83Andy Hung // when bringing the output sink into standby.) 4802f228531c5d01f497f5802c44545e0000ec44ab83Andy Hung // 4803f228531c5d01f497f5802c44545e0000ec44ab83Andy Hung // We will get the latest FastMixer state when we come out of COLD_IDLE. 4804f228531c5d01f497f5802c44545e0000ec44ab83Andy Hung // 4805f228531c5d01f497f5802c44545e0000ec44ab83Andy Hung // This occurs with BT suspend when we idle the FastMixer with 4806f228531c5d01f497f5802c44545e0000ec44ab83Andy Hung // active tracks, which may be added or removed. 4807f228531c5d01f497f5802c44545e0000ec44ab83Andy Hung sq->push(coldIdle ? FastMixerStateQueue::BLOCK_NEVER : block); 480881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 480981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent#ifdef AUDIO_WATCHDOG 481081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (pauseAudioWatchdog && mAudioWatchdog != 0) { 481181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mAudioWatchdog->pause(); 481281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 481381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent#endif 481481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 481581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // Now perform the deferred reset on fast tracks that have stopped 481681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent while (resetMask != 0) { 481781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent size_t i = __builtin_ctz(resetMask); 481881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent ALOG_ASSERT(i < count); 481981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent resetMask &= ~(1 << i); 4820dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hung sp<Track> track = mActiveTracks[i]; 482181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent ALOG_ASSERT(track->isFastTrack() && track->isStopped()); 482281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent track->reset(); 482381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 482481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 482580d03d292e006e7c474e12d06450f63b5ea3b197Andy Hung // Track destruction may occur outside of threadLoop once it is removed from active tracks. 482680d03d292e006e7c474e12d06450f63b5ea3b197Andy Hung // Ensure the AudioMixer doesn't have a raw "buffer provider" pointer to the track if 482780d03d292e006e7c474e12d06450f63b5ea3b197Andy Hung // it ceases to be active, to allow safe removal from the AudioMixer at the start 482880d03d292e006e7c474e12d06450f63b5ea3b197Andy Hung // of prepareTracks_l(); this releases any outstanding buffer back to the track. 482980d03d292e006e7c474e12d06450f63b5ea3b197Andy Hung // See also the implementation of destroyTrack_l(). 483080d03d292e006e7c474e12d06450f63b5ea3b197Andy Hung for (const auto &track : *tracksToRemove) { 483180d03d292e006e7c474e12d06450f63b5ea3b197Andy Hung const int name = track->name(); 483280d03d292e006e7c474e12d06450f63b5ea3b197Andy Hung if (mAudioMixer->exists(name)) { // Normal tracks here, fast tracks in FastMixer. 483380d03d292e006e7c474e12d06450f63b5ea3b197Andy Hung mAudioMixer->setBufferProvider(name, nullptr /* bufferProvider */); 483480d03d292e006e7c474e12d06450f63b5ea3b197Andy Hung } 483580d03d292e006e7c474e12d06450f63b5ea3b197Andy Hung } 483680d03d292e006e7c474e12d06450f63b5ea3b197Andy Hung 483781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // remove all the tracks that need to be... 4838bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent removeTracks_l(*tracksToRemove); 483981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 484097d547da43c9c41711d1ed1e3f4fa87c2ee3cb9aEric Laurent if (getEffectChain_l(AUDIO_SESSION_OUTPUT_MIX) != 0) { 484197d547da43c9c41711d1ed1e3f4fa87c2ee3cb9aEric Laurent mEffectBufferValid = true; 4842ac302143551a8b964f026385a524dda9ff8ea5baMarco Nelissen } 4843ac302143551a8b964f026385a524dda9ff8ea5baMarco Nelissen 4844ac302143551a8b964f026385a524dda9ff8ea5baMarco Nelissen if (mEffectBufferValid) { 484557088b5c8e76855b99b3e6b3e410de5b6382670eMarco Nelissen // as long as there are effects we should clear the effects buffer, to avoid 484657088b5c8e76855b99b3e6b3e410de5b6382670eMarco Nelissen // passing a non-clean buffer to the effect chain 484757088b5c8e76855b99b3e6b3e410de5b6382670eMarco Nelissen memset(mEffectBuffer, 0, mEffectBufferSize); 484897d547da43c9c41711d1ed1e3f4fa87c2ee3cb9aEric Laurent } 484969aed5f0f4a3be3996d1e78a0473e1a72c1547daAndy Hung // sink or mix buffer must be cleared if all tracks are connected to an 485069aed5f0f4a3be3996d1e78a0473e1a72c1547daAndy Hung // effect chain as in this case the mixer will not write to the sink or mix buffer 485169aed5f0f4a3be3996d1e78a0473e1a72c1547daAndy Hung // and track effects will accumulate into it 4852bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent if ((mBytesRemaining == 0) && ((mixedTracks != 0 && mixedTracks == tracksWithEffect) || 4853bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent (mixedTracks == 0 && fastTracks > 0))) { 485481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // FIXME as a performance optimization, should remember previous zero status 485569aed5f0f4a3be3996d1e78a0473e1a72c1547daAndy Hung if (mMixerBufferValid) { 485669aed5f0f4a3be3996d1e78a0473e1a72c1547daAndy Hung memset(mMixerBuffer, 0, mMixerBufferSize); 485769aed5f0f4a3be3996d1e78a0473e1a72c1547daAndy Hung // TODO: In testing, mSinkBuffer below need not be cleared because 485869aed5f0f4a3be3996d1e78a0473e1a72c1547daAndy Hung // the PlaybackThread::threadLoop() copies mMixerBuffer into mSinkBuffer 485969aed5f0f4a3be3996d1e78a0473e1a72c1547daAndy Hung // after mixing. 486069aed5f0f4a3be3996d1e78a0473e1a72c1547daAndy Hung // 486169aed5f0f4a3be3996d1e78a0473e1a72c1547daAndy Hung // To enforce this guarantee: 486269aed5f0f4a3be3996d1e78a0473e1a72c1547daAndy Hung // ((mixedTracks != 0 && mixedTracks == tracksWithEffect) || 486369aed5f0f4a3be3996d1e78a0473e1a72c1547daAndy Hung // (mixedTracks == 0 && fastTracks > 0)) 486469aed5f0f4a3be3996d1e78a0473e1a72c1547daAndy Hung // must imply MIXER_TRACKS_READY. 486569aed5f0f4a3be3996d1e78a0473e1a72c1547daAndy Hung // Later, we may clear buffers regardless, and skip much of this logic. 486669aed5f0f4a3be3996d1e78a0473e1a72c1547daAndy Hung } 486798ef978df4e928f486d244c4d7f7ad9f13111e98Andy Hung // FIXME as a performance optimization, should remember previous zero status 48685567aaf4818007cd8e77329683a91c0f5d7a8837Andy Hung memset(mSinkBuffer, 0, mNormalFrameCount * mFrameSize); 486981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 487081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 487181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // if any fast tracks, then status is ready 487281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mMixerStatusIgnoringFastTracks = mixerStatus; 487381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (fastTracks > 0) { 487481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mixerStatus = MIXER_TRACKS_READY; 487581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 487681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent return mixerStatus; 487781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 487881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 4879ad7dd9610b6fafa81baf69607f4ac669da88182aEric Laurent// trackCountForUid_l() must be called with ThreadBase::mLock held 48801bc088a918d7038603230637d640941953b314d4Andy Hunguint32_t AudioFlinger::PlaybackThread::trackCountForUid_l(uid_t uid) const 4881ad7dd9610b6fafa81baf69607f4ac669da88182aEric Laurent{ 4882ad7dd9610b6fafa81baf69607f4ac669da88182aEric Laurent uint32_t trackCount = 0; 4883ad7dd9610b6fafa81baf69607f4ac669da88182aEric Laurent for (size_t i = 0; i < mTracks.size() ; i++) { 48841f12a8ad958344c50733b948628ffa06db9c5bc6Andy Hung if (mTracks[i]->uid() == uid) { 4885ad7dd9610b6fafa81baf69607f4ac669da88182aEric Laurent trackCount++; 4886ad7dd9610b6fafa81baf69607f4ac669da88182aEric Laurent } 4887ad7dd9610b6fafa81baf69607f4ac669da88182aEric Laurent } 4888ad7dd9610b6fafa81baf69607f4ac669da88182aEric Laurent return trackCount; 4889ad7dd9610b6fafa81baf69607f4ac669da88182aEric Laurent} 4890ad7dd9610b6fafa81baf69607f4ac669da88182aEric Laurent 48911bc088a918d7038603230637d640941953b314d4Andy Hung// isTrackAllowed_l() must be called with ThreadBase::mLock held 48921bc088a918d7038603230637d640941953b314d4Andy Hungbool AudioFlinger::MixerThread::isTrackAllowed_l( 48931bc088a918d7038603230637d640941953b314d4Andy Hung audio_channel_mask_t channelMask, audio_format_t format, 48941bc088a918d7038603230637d640941953b314d4Andy Hung audio_session_t sessionId, uid_t uid) const 489581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 48961bc088a918d7038603230637d640941953b314d4Andy Hung if (!PlaybackThread::isTrackAllowed_l(channelMask, format, sessionId, uid)) { 48971bc088a918d7038603230637d640941953b314d4Andy Hung return false; 4898ad7dd9610b6fafa81baf69607f4ac669da88182aEric Laurent } 48991bc088a918d7038603230637d640941953b314d4Andy Hung // Check validity as we don't call AudioMixer::create() here. 49001bc088a918d7038603230637d640941953b314d4Andy Hung if (!AudioMixer::isValidFormat(format)) { 49011bc088a918d7038603230637d640941953b314d4Andy Hung ALOGW("%s: invalid format: %#x", __func__, format); 49021bc088a918d7038603230637d640941953b314d4Andy Hung return false; 49031bc088a918d7038603230637d640941953b314d4Andy Hung } 49041bc088a918d7038603230637d640941953b314d4Andy Hung if (!AudioMixer::isValidChannelMask(channelMask)) { 49051bc088a918d7038603230637d640941953b314d4Andy Hung ALOGW("%s: invalid channelMask: %#x", __func__, channelMask); 49061bc088a918d7038603230637d640941953b314d4Andy Hung return false; 49071bc088a918d7038603230637d640941953b314d4Andy Hung } 49081bc088a918d7038603230637d640941953b314d4Andy Hung return true; 490981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 491081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 49111035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent// checkForNewParameter_l() must be called with ThreadBase::mLock held 49121035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurentbool AudioFlinger::MixerThread::checkForNewParameter_l(const String8& keyValuePair, 49131035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent status_t& status) 491481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 491581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent bool reconfig = false; 491642537be61479e59c4718e1304364551c1454f63cEric Laurent bool a2dpDeviceChanged = false; 491781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 49181035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent status = NO_ERROR; 491981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 4920c05b8d7df46619d3474356241d47655478b8bc82Glenn Kasten AutoPark<FastMixer> park(mFastMixer); 492181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 49221035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent AudioParameter param = AudioParameter(keyValuePair); 49231035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent int value; 49241035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent if (param.getInt(String8(AudioParameter::keySamplingRate), value) == NO_ERROR) { 49251035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent reconfig = true; 49261035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent } 49271035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent if (param.getInt(String8(AudioParameter::keyFormat), value) == NO_ERROR) { 49289a59276fb465e492138e0576523b54079671e8f4Andy Hung if (!isValidPcmSinkFormat((audio_format_t) value)) { 49291035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent status = BAD_VALUE; 49301035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent } else { 49311035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent // no need to save value, since it's constant 493281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent reconfig = true; 493381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 49341035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent } 49351035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent if (param.getInt(String8(AudioParameter::keyChannels), value) == NO_ERROR) { 49369a59276fb465e492138e0576523b54079671e8f4Andy Hung if (!isValidPcmSinkChannelMask((audio_channel_mask_t) value)) { 49371035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent status = BAD_VALUE; 49381035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent } else { 49391035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent // no need to save value, since it's constant 49401035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent reconfig = true; 494181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 49421035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent } 49431035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent if (param.getInt(String8(AudioParameter::keyFrameCount), value) == NO_ERROR) { 49441035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent // do not accept frame count changes if tracks are open as the track buffer 49451035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent // size depends on frame count and correct behavior would not be guaranteed 49461035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent // if frame count is changed after track creation 49471035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent if (!mTracks.isEmpty()) { 49481035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent status = INVALID_OPERATION; 49491035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent } else { 49501035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent reconfig = true; 495181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 49521035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent } 49531035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent if (param.getInt(String8(AudioParameter::keyRouting), value) == NO_ERROR) { 495481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent#ifdef ADD_BATTERY_DATA 49551035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent // when changing the audio output device, call addBatteryData to notify 49561035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent // the change 49571035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent if (mOutDevice != value) { 49581035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent uint32_t params = 0; 49591035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent // check whether speaker is on 49601035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent if (value & AUDIO_DEVICE_OUT_SPEAKER) { 49611035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent params |= IMediaPlayerService::kBatteryDataSpeakerOn; 49621035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent } 496381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 49641035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent audio_devices_t deviceWithoutSpeaker 49651035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent = AUDIO_DEVICE_OUT_ALL & ~AUDIO_DEVICE_OUT_SPEAKER; 49661035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent // check if any other device (except speaker) is on 4967054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurent if (value & deviceWithoutSpeaker) { 49681035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent params |= IMediaPlayerService::kBatteryDataOtherAudioDeviceOn; 49691035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent } 497081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 49711035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent if (params != 0) { 49721035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent addBatteryData(params); 497381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 49741035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent } 497581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent#endif 497681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 49771035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent // forward device change to effects that have requested to be 49781035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent // aware of attached audio device. 49791035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent if (value != AUDIO_DEVICE_NONE) { 498042537be61479e59c4718e1304364551c1454f63cEric Laurent a2dpDeviceChanged = 498142537be61479e59c4718e1304364551c1454f63cEric Laurent (mOutDevice & AUDIO_DEVICE_OUT_ALL_A2DP) != (value & AUDIO_DEVICE_OUT_ALL_A2DP); 49821035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent mOutDevice = value; 49831035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent for (size_t i = 0; i < mEffectChains.size(); i++) { 49841035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent mEffectChains[i]->setDevice_l(mOutDevice); 498581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 498681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 49871035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent } 498881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 49891035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent if (status == NO_ERROR) { 49901dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov status = mOutput->stream->setParameters(keyValuePair); 49911035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent if (!mStandby && status == INVALID_OPERATION) { 4992062e67a26e0553dd142be622821f493df541f0c6Phil Burk mOutput->standby(); 49931035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent mStandby = true; 49941035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent mBytesWritten = 0; 49951dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov status = mOutput->stream->setParameters(keyValuePair); 49961035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent } 49971035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent if (status == NO_ERROR && reconfig) { 49981035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent readOutputParameters_l(); 49991035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent delete mAudioMixer; 50001035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent mAudioMixer = new AudioMixer(mNormalFrameCount, mSampleRate); 50011bc088a918d7038603230637d640941953b314d4Andy Hung for (const auto &track : mTracks) { 50021bc088a918d7038603230637d640941953b314d4Andy Hung const int name = track->name(); 50031bc088a918d7038603230637d640941953b314d4Andy Hung status_t status = mAudioMixer->create( 50041bc088a918d7038603230637d640941953b314d4Andy Hung name, 50051bc088a918d7038603230637d640941953b314d4Andy Hung track->mChannelMask, 50061bc088a918d7038603230637d640941953b314d4Andy Hung track->mFormat, 50071bc088a918d7038603230637d640941953b314d4Andy Hung track->mSessionId); 50081bc088a918d7038603230637d640941953b314d4Andy Hung ALOGW_IF(status != NO_ERROR, 50091bc088a918d7038603230637d640941953b314d4Andy Hung "%s: cannot create track name" 50101bc088a918d7038603230637d640941953b314d4Andy Hung " %d, mask %#x, format %#x, sessionId %d in AudioMixer", 50111bc088a918d7038603230637d640941953b314d4Andy Hung __func__, 50121bc088a918d7038603230637d640941953b314d4Andy Hung name, track->mChannelMask, track->mFormat, track->mSessionId); 501381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 501473e26b661af50be2c0a4ff6c9ac85f7347a8b235Eric Laurent sendIoConfigEvent_l(AUDIO_OUTPUT_CONFIG_CHANGED); 501581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 501681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 501781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 501842537be61479e59c4718e1304364551c1454f63cEric Laurent return reconfig || a2dpDeviceChanged; 501981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 502081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 502181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 502281784c37c61b09289654b979567a42bf73cd2b12Eric Laurentvoid AudioFlinger::MixerThread::dumpInternals(int fd, const Vector<String16>& args) 502381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 502481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent PlaybackThread::dumpInternals(fd, args); 502540eb1a1f8871909c272e72afaf7d5af84fea2412Andy Hung dprintf(fd, " Thread throttle time (msecs): %u\n", mThreadThrottleTimeMs); 50268ed196ac0f4aa8ae811c012dfa6f596fddebf1bfAndy Hung dprintf(fd, " AudioMixer tracks: %s\n", mAudioMixer->trackNames().c_str()); 50272ddee19245641e86bca436dda23a0f5089bf2ab5Andy Hung dprintf(fd, " Master mono: %s\n", mMasterMono ? "on" : "off"); 502881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 50291bfe09a0b1755a79abd32b41c0dd433b88fc260cGlenn Kasten if (hasFastMixer()) { 50301bfe09a0b1755a79abd32b41c0dd433b88fc260cGlenn Kasten dprintf(fd, " FastMixer thread %p tid=%d", mFastMixer.get(), mFastMixer->getTid()); 50311bfe09a0b1755a79abd32b41c0dd433b88fc260cGlenn Kasten 50321bfe09a0b1755a79abd32b41c0dd433b88fc260cGlenn Kasten // Make a non-atomic copy of fast mixer dump state so it won't change underneath us 50331bfe09a0b1755a79abd32b41c0dd433b88fc260cGlenn Kasten // while we are dumping it. It may be inconsistent, but it won't mutate! 50341bfe09a0b1755a79abd32b41c0dd433b88fc260cGlenn Kasten // This is a large object so we place it on the heap. 50351bfe09a0b1755a79abd32b41c0dd433b88fc260cGlenn Kasten // FIXME 25972958: Need an intelligent copy constructor that does not touch unused pages. 50361bfe09a0b1755a79abd32b41c0dd433b88fc260cGlenn Kasten const FastMixerDumpState *copy = new FastMixerDumpState(mFastMixerDumpState); 50371bfe09a0b1755a79abd32b41c0dd433b88fc260cGlenn Kasten copy->dump(fd); 50381bfe09a0b1755a79abd32b41c0dd433b88fc260cGlenn Kasten delete copy; 503981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 504081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent#ifdef STATE_QUEUE_DUMP 50411bfe09a0b1755a79abd32b41c0dd433b88fc260cGlenn Kasten // Similar for state queue 50421bfe09a0b1755a79abd32b41c0dd433b88fc260cGlenn Kasten StateQueueObserverDump observerCopy = mStateQueueObserverDump; 50431bfe09a0b1755a79abd32b41c0dd433b88fc260cGlenn Kasten observerCopy.dump(fd); 50441bfe09a0b1755a79abd32b41c0dd433b88fc260cGlenn Kasten StateQueueMutatorDump mutatorCopy = mStateQueueMutatorDump; 50451bfe09a0b1755a79abd32b41c0dd433b88fc260cGlenn Kasten mutatorCopy.dump(fd); 504681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent#endif 504781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 50481bfe09a0b1755a79abd32b41c0dd433b88fc260cGlenn Kasten#ifdef AUDIO_WATCHDOG 50491bfe09a0b1755a79abd32b41c0dd433b88fc260cGlenn Kasten if (mAudioWatchdog != 0) { 50501bfe09a0b1755a79abd32b41c0dd433b88fc260cGlenn Kasten // Make a non-atomic copy of audio watchdog dump so it won't change underneath us 50511bfe09a0b1755a79abd32b41c0dd433b88fc260cGlenn Kasten AudioWatchdogDump wdCopy = mAudioWatchdogDump; 50521bfe09a0b1755a79abd32b41c0dd433b88fc260cGlenn Kasten wdCopy.dump(fd); 50531bfe09a0b1755a79abd32b41c0dd433b88fc260cGlenn Kasten } 50541bfe09a0b1755a79abd32b41c0dd433b88fc260cGlenn Kasten#endif 50551bfe09a0b1755a79abd32b41c0dd433b88fc260cGlenn Kasten 50561bfe09a0b1755a79abd32b41c0dd433b88fc260cGlenn Kasten } else { 50571bfe09a0b1755a79abd32b41c0dd433b88fc260cGlenn Kasten dprintf(fd, " No FastMixer\n"); 50581bfe09a0b1755a79abd32b41c0dd433b88fc260cGlenn Kasten } 50591bfe09a0b1755a79abd32b41c0dd433b88fc260cGlenn Kasten 506046909e7eb074ce1b95b8a411eb71154f53f84f77Glenn Kasten#ifdef TEE_SINK 506181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // Write the tee output to a .wav file 50625b2191a4a36746b66ba3e8f73b711f49fdb83b4bGlenn Kasten dumpTee(fd, mTeeSource, mId, 'M'); 506346909e7eb074ce1b95b8a411eb71154f53f84f77Glenn Kasten#endif 506481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 506581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 506681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 506781784c37c61b09289654b979567a42bf73cd2b12Eric Laurentuint32_t AudioFlinger::MixerThread::idleSleepTimeUs() const 506881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 506981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent return (uint32_t)(((mNormalFrameCount * 1000) / mSampleRate) * 1000) / 2; 507081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 507181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 507281784c37c61b09289654b979567a42bf73cd2b12Eric Laurentuint32_t AudioFlinger::MixerThread::suspendSleepTimeUs() const 507381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 507481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent return (uint32_t)(((mNormalFrameCount * 1000) / mSampleRate) * 1000); 507581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 507681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 507781784c37c61b09289654b979567a42bf73cd2b12Eric Laurentvoid AudioFlinger::MixerThread::cacheParameters_l() 507881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 507981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent PlaybackThread::cacheParameters_l(); 508081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 508181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // FIXME: Relaxed timing because of a certain device that can't meet latency 508281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // Should be reduced to 2x after the vendor fixes the driver issue 508381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // increase threshold again due to low power audio mode. The way this warning 508481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // threshold is calculated and its usefulness should be reconsidered anyway. 508581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent maxPeriod = seconds(mNormalFrameCount) / mSampleRate * 15; 508681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 508781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 508881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// ---------------------------------------------------------------------------- 508981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 509081784c37c61b09289654b979567a42bf73cd2b12Eric LaurentAudioFlinger::DirectOutputThread::DirectOutputThread(const sp<AudioFlinger>& audioFlinger, 5091e93cc03da360a1a0d2ad937c745ce8c8e8be81c2Eric Laurent AudioStreamOut* output, audio_io_handle_t id, audio_devices_t device, bool systemReady) 5092e93cc03da360a1a0d2ad937c745ce8c8e8be81c2Eric Laurent : PlaybackThread(audioFlinger, output, id, device, DIRECT, systemReady) 509381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 509481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 509581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 5096bfb1b832079bbb9426f72f3863199a54aefd02daEric LaurentAudioFlinger::DirectOutputThread::DirectOutputThread(const sp<AudioFlinger>& audioFlinger, 5097bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent AudioStreamOut* output, audio_io_handle_t id, uint32_t device, 5098e93cc03da360a1a0d2ad937c745ce8c8e8be81c2Eric Laurent ThreadBase::type_t type, bool systemReady) 5099e93cc03da360a1a0d2ad937c745ce8c8e8be81c2Eric Laurent : PlaybackThread(audioFlinger, output, id, device, type, systemReady) 510010cbff139360f3f642e0e3b3ccf2d463dbed22cfAndy Hung , mVolumeShaperActive(false) 5101bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent{ 5102bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent} 5103bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent 510481784c37c61b09289654b979567a42bf73cd2b12Eric LaurentAudioFlinger::DirectOutputThread::~DirectOutputThread() 510581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 510681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 510781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 51085850c4c8eecbe0db3cee8511a4f82cb443e27d08Eric Laurentvoid AudioFlinger::DirectOutputThread::processVolume_l(Track *track, bool lastTrack) 5109bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent{ 5110bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent float left, right; 5111bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent 5112bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent if (mMasterMute || mStreamTypes[track->streamType()].mute) { 5113bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent left = right = 0; 5114bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent } else { 5115bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent float typeVolume = mStreamTypes[track->streamType()].volume; 5116bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent float v = mMasterVolume * typeVolume; 51175bba2f6916dbe00aea7c0521faa0c6ed42114a75Eric Laurent sp<AudioTrackServerProxy> proxy = track->mAudioTrackServerProxy; 51189fc8b5cd4a64ef07e84c69112461324d5c13a0b0Andy Hung 511910cbff139360f3f642e0e3b3ccf2d463dbed22cfAndy Hung // Get volumeshaper scaling 512010cbff139360f3f642e0e3b3ccf2d463dbed22cfAndy Hung std::pair<float /* volume */, bool /* active */> 512110cbff139360f3f642e0e3b3ccf2d463dbed22cfAndy Hung vh = track->getVolumeHandler()->getVolume( 51229fc8b5cd4a64ef07e84c69112461324d5c13a0b0Andy Hung track->mAudioTrackServerProxy->framesReleased()); 512310cbff139360f3f642e0e3b3ccf2d463dbed22cfAndy Hung v *= vh.first; 512410cbff139360f3f642e0e3b3ccf2d463dbed22cfAndy Hung mVolumeShaperActive = vh.second; 51259fc8b5cd4a64ef07e84c69112461324d5c13a0b0Andy Hung 5126c56f3426099a3cf2d07ccff8886050c7fbce140fGlenn Kasten gain_minifloat_packed_t vlr = proxy->getVolumeLR(); 5127c56f3426099a3cf2d07ccff8886050c7fbce140fGlenn Kasten left = float_from_gain(gain_minifloat_unpack_left(vlr)); 5128c56f3426099a3cf2d07ccff8886050c7fbce140fGlenn Kasten if (left > GAIN_FLOAT_UNITY) { 5129c56f3426099a3cf2d07ccff8886050c7fbce140fGlenn Kasten left = GAIN_FLOAT_UNITY; 5130c56f3426099a3cf2d07ccff8886050c7fbce140fGlenn Kasten } 5131c56f3426099a3cf2d07ccff8886050c7fbce140fGlenn Kasten left *= v; 5132c56f3426099a3cf2d07ccff8886050c7fbce140fGlenn Kasten right = float_from_gain(gain_minifloat_unpack_right(vlr)); 5133c56f3426099a3cf2d07ccff8886050c7fbce140fGlenn Kasten if (right > GAIN_FLOAT_UNITY) { 5134c56f3426099a3cf2d07ccff8886050c7fbce140fGlenn Kasten right = GAIN_FLOAT_UNITY; 5135c56f3426099a3cf2d07ccff8886050c7fbce140fGlenn Kasten } 5136c56f3426099a3cf2d07ccff8886050c7fbce140fGlenn Kasten right *= v; 5137bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent } 5138bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent 5139bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent if (lastTrack) { 514012381092fdb5810cb27f738435ea8a0e3d2d0f42Kevin Rocard track->setFinalVolume((left + right) / 2.f); 5141bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent if (left != mLeftVolFloat || right != mRightVolFloat) { 5142bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent mLeftVolFloat = left; 5143bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent mRightVolFloat = right; 5144bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent 5145bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent // Convert volumes from float to 8.24 5146bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent uint32_t vl = (uint32_t)(left * (1 << 24)); 5147bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent uint32_t vr = (uint32_t)(right * (1 << 24)); 5148bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent 5149bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent // Delegate volume control to effect in track effect chain if needed 5150bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent // only one effect chain can be present on DirectOutputThread, so if 5151bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent // there is one, the track is connected to it 5152bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent if (!mEffectChains.isEmpty()) { 5153bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent mEffectChains[0]->setVolume_l(&vl, &vr); 5154bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent left = (float)vl / (1 << 24); 5155bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent right = (float)vr / (1 << 24); 5156bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent } 51571dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov status_t result = mOutput->stream->setVolume(left, right); 51581dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov ALOGE_IF(result != OK, "Error when setting output stream volume: %d", result); 5159bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent } 5160bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent } 5161bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent} 5162bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent 516343b4dcc660e6da96285e4672ae371070ab845401Phil Burkvoid AudioFlinger::DirectOutputThread::onAddNewTrack_l() 516443b4dcc660e6da96285e4672ae371070ab845401Phil Burk{ 516543b4dcc660e6da96285e4672ae371070ab845401Phil Burk sp<Track> previousTrack = mPreviousTrack.promote(); 5166dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hung sp<Track> latestTrack = mActiveTracks.getLatest(); 516743b4dcc660e6da96285e4672ae371070ab845401Phil Burk 51680f0631eb55b1f0a7f4b62212b78a3faa0b49919bEric Laurent if (previousTrack != 0 && latestTrack != 0) { 51690f0631eb55b1f0a7f4b62212b78a3faa0b49919bEric Laurent if (mType == DIRECT) { 51700f0631eb55b1f0a7f4b62212b78a3faa0b49919bEric Laurent if (previousTrack.get() != latestTrack.get()) { 51710f0631eb55b1f0a7f4b62212b78a3faa0b49919bEric Laurent mFlushPending = true; 51720f0631eb55b1f0a7f4b62212b78a3faa0b49919bEric Laurent } 51730f0631eb55b1f0a7f4b62212b78a3faa0b49919bEric Laurent } else /* mType == OFFLOAD */ { 51740f0631eb55b1f0a7f4b62212b78a3faa0b49919bEric Laurent if (previousTrack->sessionId() != latestTrack->sessionId()) { 51750f0631eb55b1f0a7f4b62212b78a3faa0b49919bEric Laurent mFlushPending = true; 51760f0631eb55b1f0a7f4b62212b78a3faa0b49919bEric Laurent } 51770f0631eb55b1f0a7f4b62212b78a3faa0b49919bEric Laurent } 517843b4dcc660e6da96285e4672ae371070ab845401Phil Burk } 517943b4dcc660e6da96285e4672ae371070ab845401Phil Burk PlaybackThread::onAddNewTrack_l(); 518043b4dcc660e6da96285e4672ae371070ab845401Phil Burk} 5181bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent 518281784c37c61b09289654b979567a42bf73cd2b12Eric LaurentAudioFlinger::PlaybackThread::mixer_state AudioFlinger::DirectOutputThread::prepareTracks_l( 518381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent Vector< sp<Track> > *tracksToRemove 518481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent) 518581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 5186d595b7c858c481a07745674ce2d8a6690e980e74Eric Laurent size_t count = mActiveTracks.size(); 518781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mixer_state mixerStatus = MIXER_IDLE; 5188d1f69b0b17acbd96987ecb2f3378abd394d05903Eric Laurent bool doHwPause = false; 5189d1f69b0b17acbd96987ecb2f3378abd394d05903Eric Laurent bool doHwResume = false; 519081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 519181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // find out which tracks need to be processed 5192dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hung for (const sp<Track> &t : mActiveTracks) { 51935850c4c8eecbe0db3cee8511a4f82cb443e27d08Eric Laurent if (t->isInvalid()) { 519443b4dcc660e6da96285e4672ae371070ab845401Phil Burk ALOGW("An invalidated track shouldn't be in active list"); 51955850c4c8eecbe0db3cee8511a4f82cb443e27d08Eric Laurent tracksToRemove->add(t); 519643b4dcc660e6da96285e4672ae371070ab845401Phil Burk continue; 519743b4dcc660e6da96285e4672ae371070ab845401Phil Burk } 519843b4dcc660e6da96285e4672ae371070ab845401Phil Burk 51995850c4c8eecbe0db3cee8511a4f82cb443e27d08Eric Laurent Track* const track = t.get(); 520057c4e6f7464d458eb52d209c2a63524913d6406dGlenn Kasten#ifdef VERY_VERY_VERBOSE_LOGGING 520181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent audio_track_cblk_t* cblk = track->cblk(); 520257c4e6f7464d458eb52d209c2a63524913d6406dGlenn Kasten#endif 5203fd4779740ec3e9e865d5514464df26d015354388Eric Laurent // Only consider last track started for volume and mixer state control. 5204fd4779740ec3e9e865d5514464df26d015354388Eric Laurent // In theory an older track could underrun and restart after the new one starts 5205fd4779740ec3e9e865d5514464df26d015354388Eric Laurent // but as we only care about the transition phase between two tracks on a 5206fd4779740ec3e9e865d5514464df26d015354388Eric Laurent // direct output, it is not a problem to ignore the underrun case. 5207dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hung sp<Track> l = mActiveTracks.getLatest(); 52085850c4c8eecbe0db3cee8511a4f82cb443e27d08Eric Laurent bool last = l.get() == track; 520981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 52106fc2a7c81f62b1e21487ae37e11aae6241bc3eadPhil Burk if (track->isPausing()) { 5211d1f69b0b17acbd96987ecb2f3378abd394d05903Eric Laurent track->setPaused(); 52126fc2a7c81f62b1e21487ae37e11aae6241bc3eadPhil Burk if (mHwSupportsPause && last && !mHwPaused) { 5213d1f69b0b17acbd96987ecb2f3378abd394d05903Eric Laurent doHwPause = true; 5214d1f69b0b17acbd96987ecb2f3378abd394d05903Eric Laurent mHwPaused = true; 5215d1f69b0b17acbd96987ecb2f3378abd394d05903Eric Laurent } 5216d1f69b0b17acbd96987ecb2f3378abd394d05903Eric Laurent tracksToRemove->add(track); 5217d1f69b0b17acbd96987ecb2f3378abd394d05903Eric Laurent } else if (track->isFlushPending()) { 5218d1f69b0b17acbd96987ecb2f3378abd394d05903Eric Laurent track->flushAck(); 5219d1f69b0b17acbd96987ecb2f3378abd394d05903Eric Laurent if (last) { 522043b4dcc660e6da96285e4672ae371070ab845401Phil Burk mFlushPending = true; 5221d1f69b0b17acbd96987ecb2f3378abd394d05903Eric Laurent } 52226fc2a7c81f62b1e21487ae37e11aae6241bc3eadPhil Burk } else if (track->isResumePending()) { 5223d1f69b0b17acbd96987ecb2f3378abd394d05903Eric Laurent track->resumeAck(); 52243df841a10b4d553949c518ad52f1af8dcb365058Eric Laurent if (last) { 52253df841a10b4d553949c518ad52f1af8dcb365058Eric Laurent mLeftVolFloat = mRightVolFloat = -1.0; 52263df841a10b4d553949c518ad52f1af8dcb365058Eric Laurent if (mHwPaused) { 52273df841a10b4d553949c518ad52f1af8dcb365058Eric Laurent doHwResume = true; 52283df841a10b4d553949c518ad52f1af8dcb365058Eric Laurent mHwPaused = false; 52293df841a10b4d553949c518ad52f1af8dcb365058Eric Laurent } 5230d1f69b0b17acbd96987ecb2f3378abd394d05903Eric Laurent } 5231d1f69b0b17acbd96987ecb2f3378abd394d05903Eric Laurent } 5232d1f69b0b17acbd96987ecb2f3378abd394d05903Eric Laurent 523381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // The first time a track is added we wait 523499adee3c3d9cde6819741a38163954808fea270aPhil Burk // for all its buffers to be filled before processing it. 523599adee3c3d9cde6819741a38163954808fea270aPhil Burk // Allow draining the buffer in case the client 523699adee3c3d9cde6819741a38163954808fea270aPhil Burk // app does not call stop() and relies on underrun to stop: 523799adee3c3d9cde6819741a38163954808fea270aPhil Burk // hence the test on (track->mRetryCount > 1). 523899adee3c3d9cde6819741a38163954808fea270aPhil Burk // If retryCount<=1 then track is about to underrun and be removed. 5239ca5e6143740299c877d69e97f7968cd04476d32cPhil Burk // Do not use a high threshold for compressed audio. 524081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent uint32_t minFrames; 524199adee3c3d9cde6819741a38163954808fea270aPhil Burk if ((track->sharedBuffer() == 0) && !track->isStopping_1() && !track->isPausing() 5242fdb3c07db5d44535eb8c3ec46dc78ad8446c01ebPhil Burk && (track->mRetryCount > 1) && audio_has_proportional_frames(mFormat)) { 524381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent minFrames = mNormalFrameCount; 524481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } else { 524581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent minFrames = 1; 524681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 5247bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent 5248ab5cdbaf65ca509681d2726aacdf3ac8bfb6b3faEric Laurent if ((track->framesReady() >= minFrames) && track->isReady() && !track->isPaused() && 5249ab5cdbaf65ca509681d2726aacdf3ac8bfb6b3faEric Laurent !track->isStopping_2() && !track->isStopped()) 525081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent { 5251f20e1d8df84c5fbeeace0052d100982ae39bb7a4Glenn Kasten ALOGVV("track %d s=%08x [OK]", track->name(), cblk->mServer); 525281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 525381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (track->mFillingUpStatus == Track::FS_FILLED) { 525481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent track->mFillingUpStatus = Track::FS_ACTIVE; 52553df841a10b4d553949c518ad52f1af8dcb365058Eric Laurent if (last) { 52563df841a10b4d553949c518ad52f1af8dcb365058Eric Laurent // make sure processVolume_l() will apply new volume even if 0 52573df841a10b4d553949c518ad52f1af8dcb365058Eric Laurent mLeftVolFloat = mRightVolFloat = -1.0; 52583df841a10b4d553949c518ad52f1af8dcb365058Eric Laurent } 5259d1f69b0b17acbd96987ecb2f3378abd394d05903Eric Laurent if (!mHwSupportsPause) { 5260d1f69b0b17acbd96987ecb2f3378abd394d05903Eric Laurent track->resumeAck(); 526181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 526281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 526381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 526481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // compute volume for this track 5265bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent processVolume_l(track, last); 5266bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent if (last) { 526743b4dcc660e6da96285e4672ae371070ab845401Phil Burk sp<Track> previousTrack = mPreviousTrack.promote(); 526843b4dcc660e6da96285e4672ae371070ab845401Phil Burk if (previousTrack != 0) { 526943b4dcc660e6da96285e4672ae371070ab845401Phil Burk if (track != previousTrack.get()) { 527043b4dcc660e6da96285e4672ae371070ab845401Phil Burk // Flush any data still being written from last track 527143b4dcc660e6da96285e4672ae371070ab845401Phil Burk mBytesRemaining = 0; 52720f0631eb55b1f0a7f4b62212b78a3faa0b49919bEric Laurent // Invalidate previous track to force a seek when resuming. 52730f0631eb55b1f0a7f4b62212b78a3faa0b49919bEric Laurent previousTrack->invalidate(); 527443b4dcc660e6da96285e4672ae371070ab845401Phil Burk } 527543b4dcc660e6da96285e4672ae371070ab845401Phil Burk } 527643b4dcc660e6da96285e4672ae371070ab845401Phil Burk mPreviousTrack = track; 527743b4dcc660e6da96285e4672ae371070ab845401Phil Burk 5278d595b7c858c481a07745674ce2d8a6690e980e74Eric Laurent // reset retry count 5279d595b7c858c481a07745674ce2d8a6690e980e74Eric Laurent track->mRetryCount = kMaxTrackRetriesDirect; 52805850c4c8eecbe0db3cee8511a4f82cb443e27d08Eric Laurent mActiveTrack = t; 5281d595b7c858c481a07745674ce2d8a6690e980e74Eric Laurent mixerStatus = MIXER_TRACKS_READY; 52825cff403679fc44c8293de81aed31c459c6129243Eric Laurent if (mHwPaused) { 52830f7b5f2b231caf87da9b20b74d086e5a9d6f4a9dEric Laurent doHwResume = true; 52840f7b5f2b231caf87da9b20b74d086e5a9d6f4a9dEric Laurent mHwPaused = false; 52850f7b5f2b231caf87da9b20b74d086e5a9d6f4a9dEric Laurent } 5286d595b7c858c481a07745674ce2d8a6690e980e74Eric Laurent } 528781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } else { 5288d595b7c858c481a07745674ce2d8a6690e980e74Eric Laurent // clear effect chain input buffer if the last active track started underruns 5289d595b7c858c481a07745674ce2d8a6690e980e74Eric Laurent // to avoid sending previous audio buffer again to effects 5290fd4779740ec3e9e865d5514464df26d015354388Eric Laurent if (!mEffectChains.isEmpty() && last) { 529181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mEffectChains[0]->clearInputBuffer(); 529281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 5293ab5cdbaf65ca509681d2726aacdf3ac8bfb6b3faEric Laurent if (track->isStopping_1()) { 5294ab5cdbaf65ca509681d2726aacdf3ac8bfb6b3faEric Laurent track->mState = TrackBase::STOPPING_2; 5295b369cafd67beb63dd0278dba543f519956208a7fEric Laurent if (last && mHwPaused) { 5296b369cafd67beb63dd0278dba543f519956208a7fEric Laurent doHwResume = true; 5297b369cafd67beb63dd0278dba543f519956208a7fEric Laurent mHwPaused = false; 5298b369cafd67beb63dd0278dba543f519956208a7fEric Laurent } 5299ab5cdbaf65ca509681d2726aacdf3ac8bfb6b3faEric Laurent } 5300ab5cdbaf65ca509681d2726aacdf3ac8bfb6b3faEric Laurent if ((track->sharedBuffer() != 0) || track->isStopped() || 5301ab5cdbaf65ca509681d2726aacdf3ac8bfb6b3faEric Laurent track->isStopping_2() || track->isPaused()) { 530281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // We have consumed all the buffers of this track. 530381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // Remove it from the list of active tracks. 5304ab5cdbaf65ca509681d2726aacdf3ac8bfb6b3faEric Laurent size_t audioHALFrames; 5305fdb3c07db5d44535eb8c3ec46dc78ad8446c01ebPhil Burk if (audio_has_proportional_frames(mFormat)) { 5306ab5cdbaf65ca509681d2726aacdf3ac8bfb6b3faEric Laurent audioHALFrames = (latency_l() * mSampleRate) / 1000; 5307ab5cdbaf65ca509681d2726aacdf3ac8bfb6b3faEric Laurent } else { 5308ab5cdbaf65ca509681d2726aacdf3ac8bfb6b3faEric Laurent audioHALFrames = 0; 5309ab5cdbaf65ca509681d2726aacdf3ac8bfb6b3faEric Laurent } 5310ab5cdbaf65ca509681d2726aacdf3ac8bfb6b3faEric Laurent 5311818e7a32ce3633980138aff2c2bfcc5158b3cfccAndy Hung int64_t framesWritten = mBytesWritten / mFrameSize; 5312fd4779740ec3e9e865d5514464df26d015354388Eric Laurent if (mStandby || !last || 5313fd4779740ec3e9e865d5514464df26d015354388Eric Laurent track->presentationComplete(framesWritten, audioHALFrames)) { 5314ab5cdbaf65ca509681d2726aacdf3ac8bfb6b3faEric Laurent if (track->isStopping_2()) { 5315ab5cdbaf65ca509681d2726aacdf3ac8bfb6b3faEric Laurent track->mState = TrackBase::STOPPED; 5316ab5cdbaf65ca509681d2726aacdf3ac8bfb6b3faEric Laurent } 531781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (track->isStopped()) { 531881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent track->reset(); 531981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 5320d595b7c858c481a07745674ce2d8a6690e980e74Eric Laurent tracksToRemove->add(track); 532181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 532281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } else { 532381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // No buffers for this track. Give it a few chances to 532481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // fill a buffer, then remove it from active list. 5325d595b7c858c481a07745674ce2d8a6690e980e74Eric Laurent // Only consider last track started for mixer state control 532681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (--(track->mRetryCount) <= 0) { 532781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent ALOGV("BUFFER TIMEOUT: remove(%d) from active list", track->name()); 5328d595b7c858c481a07745674ce2d8a6690e980e74Eric Laurent tracksToRemove->add(track); 5329a23f17ac334ff20a11ee63dd177cb1080e44c483Eric Laurent // indicate to client process that the track was disabled because of underrun; 5330a23f17ac334ff20a11ee63dd177cb1080e44c483Eric Laurent // it will then automatically call start() when data is available 53314d231dc0ee34380956c71cbe18a750e487a69601Eric Laurent track->disable(); 5332bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent } else if (last) { 5333ca5e6143740299c877d69e97f7968cd04476d32cPhil Burk ALOGW("pause because of UNDERRUN, framesReady = %zu," 5334ca5e6143740299c877d69e97f7968cd04476d32cPhil Burk "minFrames = %u, mFormat = %#x", 5335ca5e6143740299c877d69e97f7968cd04476d32cPhil Burk track->framesReady(), minFrames, mFormat); 533681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mixerStatus = MIXER_TRACKS_ENABLED; 53375cff403679fc44c8293de81aed31c459c6129243Eric Laurent if (mHwSupportsPause && !mHwPaused && !mStandby) { 53380f7b5f2b231caf87da9b20b74d086e5a9d6f4a9dEric Laurent doHwPause = true; 53390f7b5f2b231caf87da9b20b74d086e5a9d6f4a9dEric Laurent mHwPaused = true; 53400f7b5f2b231caf87da9b20b74d086e5a9d6f4a9dEric Laurent } 534181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 534281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 534381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 534481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 534581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 5346d1f69b0b17acbd96987ecb2f3378abd394d05903Eric Laurent // if an active track did not command a flush, check for pending flush on stopped tracks 534743b4dcc660e6da96285e4672ae371070ab845401Phil Burk if (!mFlushPending) { 5348d1f69b0b17acbd96987ecb2f3378abd394d05903Eric Laurent for (size_t i = 0; i < mTracks.size(); i++) { 5349d1f69b0b17acbd96987ecb2f3378abd394d05903Eric Laurent if (mTracks[i]->isFlushPending()) { 5350d1f69b0b17acbd96987ecb2f3378abd394d05903Eric Laurent mTracks[i]->flushAck(); 535143b4dcc660e6da96285e4672ae371070ab845401Phil Burk mFlushPending = true; 5352d1f69b0b17acbd96987ecb2f3378abd394d05903Eric Laurent } 5353d1f69b0b17acbd96987ecb2f3378abd394d05903Eric Laurent } 5354d1f69b0b17acbd96987ecb2f3378abd394d05903Eric Laurent } 5355d1f69b0b17acbd96987ecb2f3378abd394d05903Eric Laurent 5356d1f69b0b17acbd96987ecb2f3378abd394d05903Eric Laurent // make sure the pause/flush/resume sequence is executed in the right order. 5357d1f69b0b17acbd96987ecb2f3378abd394d05903Eric Laurent // If a flush is pending and a track is active but the HW is not paused, force a HW pause 5358d1f69b0b17acbd96987ecb2f3378abd394d05903Eric Laurent // before flush and then resume HW. This can happen in case of pause/flush/resume 5359d1f69b0b17acbd96987ecb2f3378abd394d05903Eric Laurent // if resume is received before pause is executed. 5360d1f69b0b17acbd96987ecb2f3378abd394d05903Eric Laurent if (mHwSupportsPause && !mStandby && 536143b4dcc660e6da96285e4672ae371070ab845401Phil Burk (doHwPause || (mFlushPending && !mHwPaused && (count != 0)))) { 53621dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov status_t result = mOutput->stream->pause(); 53631dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov ALOGE_IF(result != OK, "Error when pausing output stream: %d", result); 5364d1f69b0b17acbd96987ecb2f3378abd394d05903Eric Laurent } 536543b4dcc660e6da96285e4672ae371070ab845401Phil Burk if (mFlushPending) { 5366d1f69b0b17acbd96987ecb2f3378abd394d05903Eric Laurent flushHw_l(); 5367d1f69b0b17acbd96987ecb2f3378abd394d05903Eric Laurent } 5368d1f69b0b17acbd96987ecb2f3378abd394d05903Eric Laurent if (mHwSupportsPause && !mStandby && doHwResume) { 53691dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov status_t result = mOutput->stream->resume(); 53701dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov ALOGE_IF(result != OK, "Error when resuming output stream: %d", result); 5371d1f69b0b17acbd96987ecb2f3378abd394d05903Eric Laurent } 537281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // remove all the tracks that need to be... 5373bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent removeTracks_l(*tracksToRemove); 537481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 537581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent return mixerStatus; 537681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 537781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 537881784c37c61b09289654b979567a42bf73cd2b12Eric Laurentvoid AudioFlinger::DirectOutputThread::threadLoop_mix() 537981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 538081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent size_t frameCount = mFrameCount; 53812098f2744cedf2dc3fa36f608aa965a34602e7c0Andy Hung int8_t *curBuf = (int8_t *)mSinkBuffer; 538281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // output audio to hardware 538381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent while (frameCount) { 538434542acfa25c6413c87a94b6f7cc315a0c496277Glenn Kasten AudioBufferProvider::Buffer buffer; 538581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent buffer.frameCount = frameCount; 5386062e67a26e0553dd142be622821f493df541f0c6Phil Burk status_t status = mActiveTrack->getNextBuffer(&buffer); 5387062e67a26e0553dd142be622821f493df541f0c6Phil Burk if (status != NO_ERROR || buffer.raw == NULL) { 5388517161856d74f5fe39cce131f29b977bc1745991Eric Laurent // no need to pad with 0 for compressed audio 5389517161856d74f5fe39cce131f29b977bc1745991Eric Laurent if (audio_has_proportional_frames(mFormat)) { 5390517161856d74f5fe39cce131f29b977bc1745991Eric Laurent memset(curBuf, 0, frameCount * mFrameSize); 5391517161856d74f5fe39cce131f29b977bc1745991Eric Laurent } 539281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent break; 539381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 539481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent memcpy(curBuf, buffer.raw, buffer.frameCount * mFrameSize); 539581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent frameCount -= buffer.frameCount; 539681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent curBuf += buffer.frameCount * mFrameSize; 539781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mActiveTrack->releaseBuffer(&buffer); 539881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 53992098f2744cedf2dc3fa36f608aa965a34602e7c0Andy Hung mCurrentWriteLength = curBuf - (int8_t *)mSinkBuffer; 5400ad9cb8b88e4f8face23f01d8dc89fa769dacb50fEric Laurent mSleepTimeUs = 0; 5401ad9cb8b88e4f8face23f01d8dc89fa769dacb50fEric Laurent mStandbyTimeNs = systemTime() + mStandbyDelayNs; 540281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mActiveTrack.clear(); 540381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 540481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 540581784c37c61b09289654b979567a42bf73cd2b12Eric Laurentvoid AudioFlinger::DirectOutputThread::threadLoop_sleepTime() 540681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 5407d1f69b0b17acbd96987ecb2f3378abd394d05903Eric Laurent // do not write to HAL when paused 54080f7b5f2b231caf87da9b20b74d086e5a9d6f4a9dEric Laurent if (mHwPaused || (usesHwAvSync() && mStandby)) { 5409ad9cb8b88e4f8face23f01d8dc89fa769dacb50fEric Laurent mSleepTimeUs = mIdleSleepTimeUs; 5410d1f69b0b17acbd96987ecb2f3378abd394d05903Eric Laurent return; 5411d1f69b0b17acbd96987ecb2f3378abd394d05903Eric Laurent } 5412ad9cb8b88e4f8face23f01d8dc89fa769dacb50fEric Laurent if (mSleepTimeUs == 0) { 541381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (mMixerStatus == MIXER_TRACKS_ENABLED) { 5414e93cc03da360a1a0d2ad937c745ce8c8e8be81c2Eric Laurent mSleepTimeUs = mActiveSleepTimeUs; 541581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } else { 5416ad9cb8b88e4f8face23f01d8dc89fa769dacb50fEric Laurent mSleepTimeUs = mIdleSleepTimeUs; 541781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 5418fdb3c07db5d44535eb8c3ec46dc78ad8446c01ebPhil Burk } else if (mBytesWritten != 0 && audio_has_proportional_frames(mFormat)) { 54192098f2744cedf2dc3fa36f608aa965a34602e7c0Andy Hung memset(mSinkBuffer, 0, mFrameCount * mFrameSize); 5420ad9cb8b88e4f8face23f01d8dc89fa769dacb50fEric Laurent mSleepTimeUs = 0; 542181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 542281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 542381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 5424d1f69b0b17acbd96987ecb2f3378abd394d05903Eric Laurentvoid AudioFlinger::DirectOutputThread::threadLoop_exit() 5425d1f69b0b17acbd96987ecb2f3378abd394d05903Eric Laurent{ 5426d1f69b0b17acbd96987ecb2f3378abd394d05903Eric Laurent { 5427d1f69b0b17acbd96987ecb2f3378abd394d05903Eric Laurent Mutex::Autolock _l(mLock); 5428d1f69b0b17acbd96987ecb2f3378abd394d05903Eric Laurent for (size_t i = 0; i < mTracks.size(); i++) { 5429d1f69b0b17acbd96987ecb2f3378abd394d05903Eric Laurent if (mTracks[i]->isFlushPending()) { 5430d1f69b0b17acbd96987ecb2f3378abd394d05903Eric Laurent mTracks[i]->flushAck(); 543143b4dcc660e6da96285e4672ae371070ab845401Phil Burk mFlushPending = true; 5432d1f69b0b17acbd96987ecb2f3378abd394d05903Eric Laurent } 5433d1f69b0b17acbd96987ecb2f3378abd394d05903Eric Laurent } 543443b4dcc660e6da96285e4672ae371070ab845401Phil Burk if (mFlushPending) { 5435d1f69b0b17acbd96987ecb2f3378abd394d05903Eric Laurent flushHw_l(); 5436d1f69b0b17acbd96987ecb2f3378abd394d05903Eric Laurent } 5437d1f69b0b17acbd96987ecb2f3378abd394d05903Eric Laurent } 5438d1f69b0b17acbd96987ecb2f3378abd394d05903Eric Laurent PlaybackThread::threadLoop_exit(); 5439d1f69b0b17acbd96987ecb2f3378abd394d05903Eric Laurent} 5440d1f69b0b17acbd96987ecb2f3378abd394d05903Eric Laurent 5441d1f69b0b17acbd96987ecb2f3378abd394d05903Eric Laurent// must be called with thread mutex locked 5442d1f69b0b17acbd96987ecb2f3378abd394d05903Eric Laurentbool AudioFlinger::DirectOutputThread::shouldStandby_l() 5443d1f69b0b17acbd96987ecb2f3378abd394d05903Eric Laurent{ 5444d1f69b0b17acbd96987ecb2f3378abd394d05903Eric Laurent bool trackPaused = false; 5445b369cafd67beb63dd0278dba543f519956208a7fEric Laurent bool trackStopped = false; 5446d1f69b0b17acbd96987ecb2f3378abd394d05903Eric Laurent 54479cd7ad101315e0bff4c5f171706c6f80c7e22644vivek mehta if ((mType == DIRECT) && audio_is_linear_pcm(mFormat) && !usesHwAvSync()) { 54489cd7ad101315e0bff4c5f171706c6f80c7e22644vivek mehta return !mStandby; 54499cd7ad101315e0bff4c5f171706c6f80c7e22644vivek mehta } 54509cd7ad101315e0bff4c5f171706c6f80c7e22644vivek mehta 5451d1f69b0b17acbd96987ecb2f3378abd394d05903Eric Laurent // do not put the HAL in standby when paused. AwesomePlayer clear the offloaded AudioTrack 5452d1f69b0b17acbd96987ecb2f3378abd394d05903Eric Laurent // after a timeout and we will enter standby then. 5453d1f69b0b17acbd96987ecb2f3378abd394d05903Eric Laurent if (mTracks.size() > 0) { 5454d1f69b0b17acbd96987ecb2f3378abd394d05903Eric Laurent trackPaused = mTracks[mTracks.size() - 1]->isPaused(); 5455b369cafd67beb63dd0278dba543f519956208a7fEric Laurent trackStopped = mTracks[mTracks.size() - 1]->isStopped() || 5456b369cafd67beb63dd0278dba543f519956208a7fEric Laurent mTracks[mTracks.size() - 1]->mState == TrackBase::IDLE; 5457d1f69b0b17acbd96987ecb2f3378abd394d05903Eric Laurent } 5458d1f69b0b17acbd96987ecb2f3378abd394d05903Eric Laurent 54595cff403679fc44c8293de81aed31c459c6129243Eric Laurent return !mStandby && !(trackPaused || (mHwPaused && !trackStopped)); 5460d1f69b0b17acbd96987ecb2f3378abd394d05903Eric Laurent} 5461d1f69b0b17acbd96987ecb2f3378abd394d05903Eric Laurent 54621035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent// checkForNewParameter_l() must be called with ThreadBase::mLock held 54631035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurentbool AudioFlinger::DirectOutputThread::checkForNewParameter_l(const String8& keyValuePair, 54641035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent status_t& status) 546581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 546681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent bool reconfig = false; 546742537be61479e59c4718e1304364551c1454f63cEric Laurent bool a2dpDeviceChanged = false; 546881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 54691035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent status = NO_ERROR; 54701035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent 54711035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent AudioParameter param = AudioParameter(keyValuePair); 54721035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent int value; 54731035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent if (param.getInt(String8(AudioParameter::keyRouting), value) == NO_ERROR) { 54741035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent // forward device change to effects that have requested to be 54751035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent // aware of attached audio device. 54761035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent if (value != AUDIO_DEVICE_NONE) { 547742537be61479e59c4718e1304364551c1454f63cEric Laurent a2dpDeviceChanged = 547842537be61479e59c4718e1304364551c1454f63cEric Laurent (mOutDevice & AUDIO_DEVICE_OUT_ALL_A2DP) != (value & AUDIO_DEVICE_OUT_ALL_A2DP); 54791035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent mOutDevice = value; 54801035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent for (size_t i = 0; i < mEffectChains.size(); i++) { 54811035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent mEffectChains[i]->setDevice_l(mOutDevice); 5482c125f38cd0ae35409a01b98a99e483550daa1313Glenn Kasten } 5483c125f38cd0ae35409a01b98a99e483550daa1313Glenn Kasten } 54841035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent } 54851035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent if (param.getInt(String8(AudioParameter::keyFrameCount), value) == NO_ERROR) { 54861035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent // do not accept frame count changes if tracks are open as the track buffer 54871035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent // size depends on frame count and correct behavior would not be garantied 54881035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent // if frame count is changed after track creation 54891035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent if (!mTracks.isEmpty()) { 54901035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent status = INVALID_OPERATION; 54911035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent } else { 54921035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent reconfig = true; 549381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 54941035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent } 54951035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent if (status == NO_ERROR) { 54961dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov status = mOutput->stream->setParameters(keyValuePair); 54971035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent if (!mStandby && status == INVALID_OPERATION) { 5498062e67a26e0553dd142be622821f493df541f0c6Phil Burk mOutput->standby(); 54991035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent mStandby = true; 55001035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent mBytesWritten = 0; 55011dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov status = mOutput->stream->setParameters(keyValuePair); 55021035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent } 55031035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent if (status == NO_ERROR && reconfig) { 55041035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent readOutputParameters_l(); 550573e26b661af50be2c0a4ff6c9ac85f7347a8b235Eric Laurent sendIoConfigEvent_l(AUDIO_OUTPUT_CONFIG_CHANGED); 550681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 550781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 55081035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent 550942537be61479e59c4718e1304364551c1454f63cEric Laurent return reconfig || a2dpDeviceChanged; 551081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 551181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 551281784c37c61b09289654b979567a42bf73cd2b12Eric Laurentuint32_t AudioFlinger::DirectOutputThread::activeSleepTimeUs() const 551381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 551481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent uint32_t time; 5515fdb3c07db5d44535eb8c3ec46dc78ad8446c01ebPhil Burk if (audio_has_proportional_frames(mFormat)) { 551681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent time = PlaybackThread::activeSleepTimeUs(); 551781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } else { 5518517161856d74f5fe39cce131f29b977bc1745991Eric Laurent time = kDirectMinSleepTimeUs; 551981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 552081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent return time; 552181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 552281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 552381784c37c61b09289654b979567a42bf73cd2b12Eric Laurentuint32_t AudioFlinger::DirectOutputThread::idleSleepTimeUs() const 552481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 552581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent uint32_t time; 5526fdb3c07db5d44535eb8c3ec46dc78ad8446c01ebPhil Burk if (audio_has_proportional_frames(mFormat)) { 552781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent time = (uint32_t)(((mFrameCount * 1000) / mSampleRate) * 1000) / 2; 552881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } else { 5529517161856d74f5fe39cce131f29b977bc1745991Eric Laurent time = kDirectMinSleepTimeUs; 553081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 553181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent return time; 553281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 553381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 553481784c37c61b09289654b979567a42bf73cd2b12Eric Laurentuint32_t AudioFlinger::DirectOutputThread::suspendSleepTimeUs() const 553581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 553681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent uint32_t time; 5537fdb3c07db5d44535eb8c3ec46dc78ad8446c01ebPhil Burk if (audio_has_proportional_frames(mFormat)) { 553881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent time = (uint32_t)(((mFrameCount * 1000) / mSampleRate) * 1000); 553981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } else { 5540517161856d74f5fe39cce131f29b977bc1745991Eric Laurent time = kDirectMinSleepTimeUs; 554181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 554281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent return time; 554381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 554481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 554581784c37c61b09289654b979567a42bf73cd2b12Eric Laurentvoid AudioFlinger::DirectOutputThread::cacheParameters_l() 554681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 554781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent PlaybackThread::cacheParameters_l(); 554881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 554981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // use shorter standby delay as on normal output to release 555081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // hardware resources as soon as possible 5551b369cafd67beb63dd0278dba543f519956208a7fEric Laurent // no delay on outputs with HW A/V sync 5552b369cafd67beb63dd0278dba543f519956208a7fEric Laurent if (usesHwAvSync()) { 5553ad9cb8b88e4f8face23f01d8dc89fa769dacb50fEric Laurent mStandbyDelayNs = 0; 5554fdb3c07db5d44535eb8c3ec46dc78ad8446c01ebPhil Burk } else if ((mType == OFFLOAD) && !audio_has_proportional_frames(mFormat)) { 5555ad9cb8b88e4f8face23f01d8dc89fa769dacb50fEric Laurent mStandbyDelayNs = kOffloadStandbyDelayNs; 55565cff403679fc44c8293de81aed31c459c6129243Eric Laurent } else { 5557ad9cb8b88e4f8face23f01d8dc89fa769dacb50fEric Laurent mStandbyDelayNs = microseconds(mActiveSleepTimeUs*2); 5558972a173d7d1de1a3b5a617aae3e2abb6e05ae02dEric Laurent } 555981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 556081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 5561e659ef420dae0caae84ab78f9df8952acb9ad3a0Eric Laurentvoid AudioFlinger::DirectOutputThread::flushHw_l() 5562e659ef420dae0caae84ab78f9df8952acb9ad3a0Eric Laurent{ 5563062e67a26e0553dd142be622821f493df541f0c6Phil Burk mOutput->flush(); 5564d1f69b0b17acbd96987ecb2f3378abd394d05903Eric Laurent mHwPaused = false; 556543b4dcc660e6da96285e4672ae371070ab845401Phil Burk mFlushPending = false; 5566e659ef420dae0caae84ab78f9df8952acb9ad3a0Eric Laurent} 5567e659ef420dae0caae84ab78f9df8952acb9ad3a0Eric Laurent 556810cbff139360f3f642e0e3b3ccf2d463dbed22cfAndy Hungint64_t AudioFlinger::DirectOutputThread::computeWaitTimeNs_l() const { 556910cbff139360f3f642e0e3b3ccf2d463dbed22cfAndy Hung // If a VolumeShaper is active, we must wake up periodically to update volume. 557010cbff139360f3f642e0e3b3ccf2d463dbed22cfAndy Hung const int64_t NS_PER_MS = 1000000; 557110cbff139360f3f642e0e3b3ccf2d463dbed22cfAndy Hung return mVolumeShaperActive ? 557210cbff139360f3f642e0e3b3ccf2d463dbed22cfAndy Hung kMinNormalSinkBufferSizeMs * NS_PER_MS : PlaybackThread::computeWaitTimeNs_l(); 557310cbff139360f3f642e0e3b3ccf2d463dbed22cfAndy Hung} 557410cbff139360f3f642e0e3b3ccf2d463dbed22cfAndy Hung 557581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// ---------------------------------------------------------------------------- 557681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 5577bfb1b832079bbb9426f72f3863199a54aefd02daEric LaurentAudioFlinger::AsyncCallbackThread::AsyncCallbackThread( 55784de95592980dba88a35b3dc8f3fd045588387a4fEric Laurent const wp<AudioFlinger::PlaybackThread>& playbackThread) 5579bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent : Thread(false /*canCallJava*/), 55804de95592980dba88a35b3dc8f3fd045588387a4fEric Laurent mPlaybackThread(playbackThread), 55813b4529e03c5fc7a44c22f9091ad15a269bfca3a8Eric Laurent mWriteAckSequence(0), 55824527b9ebc6a37b861f5a3bba68bcc63dc8d69adaHaynes Mathew George mDrainSequence(0), 55834527b9ebc6a37b861f5a3bba68bcc63dc8d69adaHaynes Mathew George mAsyncError(false) 5584bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent{ 5585bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent} 5586bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent 5587bfb1b832079bbb9426f72f3863199a54aefd02daEric LaurentAudioFlinger::AsyncCallbackThread::~AsyncCallbackThread() 5588bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent{ 5589bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent} 5590bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent 5591bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurentvoid AudioFlinger::AsyncCallbackThread::onFirstRef() 5592bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent{ 5593bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent run("Offload Cbk", ANDROID_PRIORITY_URGENT_AUDIO); 5594bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent} 5595bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent 5596bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurentbool AudioFlinger::AsyncCallbackThread::threadLoop() 5597bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent{ 5598bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent while (!exitPending()) { 55993b4529e03c5fc7a44c22f9091ad15a269bfca3a8Eric Laurent uint32_t writeAckSequence; 56003b4529e03c5fc7a44c22f9091ad15a269bfca3a8Eric Laurent uint32_t drainSequence; 56014527b9ebc6a37b861f5a3bba68bcc63dc8d69adaHaynes Mathew George bool asyncError; 5602bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent 5603bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent { 5604bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent Mutex::Autolock _l(mLock); 560524a325d6f8c4bbf9330e6ce0c769d46e04266ffcHaynes Mathew George while (!((mWriteAckSequence & 1) || 560624a325d6f8c4bbf9330e6ce0c769d46e04266ffcHaynes Mathew George (mDrainSequence & 1) || 56074527b9ebc6a37b861f5a3bba68bcc63dc8d69adaHaynes Mathew George mAsyncError || 560824a325d6f8c4bbf9330e6ce0c769d46e04266ffcHaynes Mathew George exitPending())) { 560924a325d6f8c4bbf9330e6ce0c769d46e04266ffcHaynes Mathew George mWaitWorkCV.wait(mLock); 561024a325d6f8c4bbf9330e6ce0c769d46e04266ffcHaynes Mathew George } 561124a325d6f8c4bbf9330e6ce0c769d46e04266ffcHaynes Mathew George 5612bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent if (exitPending()) { 5613bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent break; 5614bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent } 56153b4529e03c5fc7a44c22f9091ad15a269bfca3a8Eric Laurent ALOGV("AsyncCallbackThread mWriteAckSequence %d mDrainSequence %d", 56163b4529e03c5fc7a44c22f9091ad15a269bfca3a8Eric Laurent mWriteAckSequence, mDrainSequence); 56173b4529e03c5fc7a44c22f9091ad15a269bfca3a8Eric Laurent writeAckSequence = mWriteAckSequence; 56183b4529e03c5fc7a44c22f9091ad15a269bfca3a8Eric Laurent mWriteAckSequence &= ~1; 56193b4529e03c5fc7a44c22f9091ad15a269bfca3a8Eric Laurent drainSequence = mDrainSequence; 56203b4529e03c5fc7a44c22f9091ad15a269bfca3a8Eric Laurent mDrainSequence &= ~1; 56214527b9ebc6a37b861f5a3bba68bcc63dc8d69adaHaynes Mathew George asyncError = mAsyncError; 56224527b9ebc6a37b861f5a3bba68bcc63dc8d69adaHaynes Mathew George mAsyncError = false; 5623bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent } 5624bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent { 56254de95592980dba88a35b3dc8f3fd045588387a4fEric Laurent sp<AudioFlinger::PlaybackThread> playbackThread = mPlaybackThread.promote(); 56264de95592980dba88a35b3dc8f3fd045588387a4fEric Laurent if (playbackThread != 0) { 56273b4529e03c5fc7a44c22f9091ad15a269bfca3a8Eric Laurent if (writeAckSequence & 1) { 56284de95592980dba88a35b3dc8f3fd045588387a4fEric Laurent playbackThread->resetWriteBlocked(writeAckSequence >> 1); 5629bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent } 56303b4529e03c5fc7a44c22f9091ad15a269bfca3a8Eric Laurent if (drainSequence & 1) { 56314de95592980dba88a35b3dc8f3fd045588387a4fEric Laurent playbackThread->resetDraining(drainSequence >> 1); 5632bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent } 56334527b9ebc6a37b861f5a3bba68bcc63dc8d69adaHaynes Mathew George if (asyncError) { 56344527b9ebc6a37b861f5a3bba68bcc63dc8d69adaHaynes Mathew George playbackThread->onAsyncError(); 56354527b9ebc6a37b861f5a3bba68bcc63dc8d69adaHaynes Mathew George } 5636bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent } 5637bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent } 5638bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent } 5639bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent return false; 5640bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent} 5641bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent 5642bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurentvoid AudioFlinger::AsyncCallbackThread::exit() 5643bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent{ 5644bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent ALOGV("AsyncCallbackThread::exit"); 5645bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent Mutex::Autolock _l(mLock); 5646bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent requestExit(); 5647bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent mWaitWorkCV.broadcast(); 5648bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent} 5649bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent 56503b4529e03c5fc7a44c22f9091ad15a269bfca3a8Eric Laurentvoid AudioFlinger::AsyncCallbackThread::setWriteBlocked(uint32_t sequence) 5651bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent{ 5652bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent Mutex::Autolock _l(mLock); 56533b4529e03c5fc7a44c22f9091ad15a269bfca3a8Eric Laurent // bit 0 is cleared 56543b4529e03c5fc7a44c22f9091ad15a269bfca3a8Eric Laurent mWriteAckSequence = sequence << 1; 56553b4529e03c5fc7a44c22f9091ad15a269bfca3a8Eric Laurent} 56563b4529e03c5fc7a44c22f9091ad15a269bfca3a8Eric Laurent 56573b4529e03c5fc7a44c22f9091ad15a269bfca3a8Eric Laurentvoid AudioFlinger::AsyncCallbackThread::resetWriteBlocked() 56583b4529e03c5fc7a44c22f9091ad15a269bfca3a8Eric Laurent{ 56593b4529e03c5fc7a44c22f9091ad15a269bfca3a8Eric Laurent Mutex::Autolock _l(mLock); 56603b4529e03c5fc7a44c22f9091ad15a269bfca3a8Eric Laurent // ignore unexpected callbacks 56613b4529e03c5fc7a44c22f9091ad15a269bfca3a8Eric Laurent if (mWriteAckSequence & 2) { 56623b4529e03c5fc7a44c22f9091ad15a269bfca3a8Eric Laurent mWriteAckSequence |= 1; 5663bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent mWaitWorkCV.signal(); 5664bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent } 5665bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent} 5666bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent 56673b4529e03c5fc7a44c22f9091ad15a269bfca3a8Eric Laurentvoid AudioFlinger::AsyncCallbackThread::setDraining(uint32_t sequence) 56683b4529e03c5fc7a44c22f9091ad15a269bfca3a8Eric Laurent{ 56693b4529e03c5fc7a44c22f9091ad15a269bfca3a8Eric Laurent Mutex::Autolock _l(mLock); 56703b4529e03c5fc7a44c22f9091ad15a269bfca3a8Eric Laurent // bit 0 is cleared 56713b4529e03c5fc7a44c22f9091ad15a269bfca3a8Eric Laurent mDrainSequence = sequence << 1; 56723b4529e03c5fc7a44c22f9091ad15a269bfca3a8Eric Laurent} 56733b4529e03c5fc7a44c22f9091ad15a269bfca3a8Eric Laurent 56743b4529e03c5fc7a44c22f9091ad15a269bfca3a8Eric Laurentvoid AudioFlinger::AsyncCallbackThread::resetDraining() 5675bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent{ 5676bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent Mutex::Autolock _l(mLock); 56773b4529e03c5fc7a44c22f9091ad15a269bfca3a8Eric Laurent // ignore unexpected callbacks 56783b4529e03c5fc7a44c22f9091ad15a269bfca3a8Eric Laurent if (mDrainSequence & 2) { 56793b4529e03c5fc7a44c22f9091ad15a269bfca3a8Eric Laurent mDrainSequence |= 1; 5680bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent mWaitWorkCV.signal(); 5681bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent } 5682bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent} 5683bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent 56844527b9ebc6a37b861f5a3bba68bcc63dc8d69adaHaynes Mathew Georgevoid AudioFlinger::AsyncCallbackThread::setAsyncError() 56854527b9ebc6a37b861f5a3bba68bcc63dc8d69adaHaynes Mathew George{ 56864527b9ebc6a37b861f5a3bba68bcc63dc8d69adaHaynes Mathew George Mutex::Autolock _l(mLock); 56874527b9ebc6a37b861f5a3bba68bcc63dc8d69adaHaynes Mathew George mAsyncError = true; 56884527b9ebc6a37b861f5a3bba68bcc63dc8d69adaHaynes Mathew George mWaitWorkCV.signal(); 56894527b9ebc6a37b861f5a3bba68bcc63dc8d69adaHaynes Mathew George} 56904527b9ebc6a37b861f5a3bba68bcc63dc8d69adaHaynes Mathew George 5691bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent 5692bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent// ---------------------------------------------------------------------------- 5693bfb1b832079bbb9426f72f3863199a54aefd02daEric LaurentAudioFlinger::OffloadThread::OffloadThread(const sp<AudioFlinger>& audioFlinger, 5694e93cc03da360a1a0d2ad937c745ce8c8e8be81c2Eric Laurent AudioStreamOut* output, audio_io_handle_t id, uint32_t device, bool systemReady) 5695e93cc03da360a1a0d2ad937c745ce8c8e8be81c2Eric Laurent : DirectOutputThread(audioFlinger, output, id, device, OFFLOAD, systemReady), 5696f804475807407442d5596ab7378ed07d50664063Andy Hung mPausedWriteLength(0), mPausedBytesRemaining(0), mKeepWakeLock(true), 5697f804475807407442d5596ab7378ed07d50664063Andy Hung mOffloadUnderrunPosition(~0LL) 5698bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent{ 56992a6a945d65c986dcc779f70f18afde1d7a74397bSanna Catherine de Treville Wager //FIXME: mStandby should be set to true by ThreadBase constructo 5700fd4779740ec3e9e865d5514464df26d015354388Eric Laurent mStandby = true; 5701646679779a8f952980a5d4219ad9c6f93efc4b92Eric Laurent mKeepWakeLock = property_get_bool("ro.audio.offload_wakelock", true /* default_value */); 5702bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent} 5703bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent 5704bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurentvoid AudioFlinger::OffloadThread::threadLoop_exit() 5705bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent{ 5706bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent if (mFlushPending || mHwPaused) { 5707bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent // If a flush is pending or track was paused, just discard buffered data 5708bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent flushHw_l(); 5709bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent } else { 5710bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent mMixerStatus = MIXER_DRAIN_ALL; 5711bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent threadLoop_drain(); 5712bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent } 571356604aa3a56dc8e15532597a0a74b3c7b165e006Uday Gupta if (mUseAsyncWrite) { 571456604aa3a56dc8e15532597a0a74b3c7b165e006Uday Gupta ALOG_ASSERT(mCallbackThread != 0); 571556604aa3a56dc8e15532597a0a74b3c7b165e006Uday Gupta mCallbackThread->exit(); 571656604aa3a56dc8e15532597a0a74b3c7b165e006Uday Gupta } 5717bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent PlaybackThread::threadLoop_exit(); 5718bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent} 5719bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent 5720bfb1b832079bbb9426f72f3863199a54aefd02daEric LaurentAudioFlinger::PlaybackThread::mixer_state AudioFlinger::OffloadThread::prepareTracks_l( 5721bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent Vector< sp<Track> > *tracksToRemove 5722bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent) 5723bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent{ 5724bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent size_t count = mActiveTracks.size(); 5725bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent 5726bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent mixer_state mixerStatus = MIXER_IDLE; 5727972a173d7d1de1a3b5a617aae3e2abb6e05ae02dEric Laurent bool doHwPause = false; 5728972a173d7d1de1a3b5a617aae3e2abb6e05ae02dEric Laurent bool doHwResume = false; 5729972a173d7d1de1a3b5a617aae3e2abb6e05ae02dEric Laurent 5730c42e9b462661673dff480ee71757a58b0f806370Glenn Kasten ALOGV("OffloadThread::prepareTracks_l active tracks %zu", count); 5731ede6c3b8b1147bc425f7b923882f559a513fe23bEric Laurent 5732bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent // find out which tracks need to be processed 5733dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hung for (const sp<Track> &t : mActiveTracks) { 57345850c4c8eecbe0db3cee8511a4f82cb443e27d08Eric Laurent Track* const track = t.get(); 573557c4e6f7464d458eb52d209c2a63524913d6406dGlenn Kasten#ifdef VERY_VERY_VERBOSE_LOGGING 5736bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent audio_track_cblk_t* cblk = track->cblk(); 573757c4e6f7464d458eb52d209c2a63524913d6406dGlenn Kasten#endif 5738fd4779740ec3e9e865d5514464df26d015354388Eric Laurent // Only consider last track started for volume and mixer state control. 5739fd4779740ec3e9e865d5514464df26d015354388Eric Laurent // In theory an older track could underrun and restart after the new one starts 5740fd4779740ec3e9e865d5514464df26d015354388Eric Laurent // but as we only care about the transition phase between two tracks on a 5741fd4779740ec3e9e865d5514464df26d015354388Eric Laurent // direct output, it is not a problem to ignore the underrun case. 5742dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hung sp<Track> l = mActiveTracks.getLatest(); 57435850c4c8eecbe0db3cee8511a4f82cb443e27d08Eric Laurent bool last = l.get() == track; 5744fd4779740ec3e9e865d5514464df26d015354388Eric Laurent 57457844f679be8d94c5cdf017f53754cb68ee2f00daHaynes Mathew George if (track->isInvalid()) { 57467844f679be8d94c5cdf017f53754cb68ee2f00daHaynes Mathew George ALOGW("An invalidated track shouldn't be in active list"); 57477844f679be8d94c5cdf017f53754cb68ee2f00daHaynes Mathew George tracksToRemove->add(track); 57487844f679be8d94c5cdf017f53754cb68ee2f00daHaynes Mathew George continue; 57497844f679be8d94c5cdf017f53754cb68ee2f00daHaynes Mathew George } 57507844f679be8d94c5cdf017f53754cb68ee2f00daHaynes Mathew George 57517844f679be8d94c5cdf017f53754cb68ee2f00daHaynes Mathew George if (track->mState == TrackBase::IDLE) { 57527844f679be8d94c5cdf017f53754cb68ee2f00daHaynes Mathew George ALOGW("An idle track shouldn't be in active list"); 57537844f679be8d94c5cdf017f53754cb68ee2f00daHaynes Mathew George continue; 57547844f679be8d94c5cdf017f53754cb68ee2f00daHaynes Mathew George } 57557844f679be8d94c5cdf017f53754cb68ee2f00daHaynes Mathew George 5756bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent if (track->isPausing()) { 5757bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent track->setPaused(); 5758bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent if (last) { 57595cff403679fc44c8293de81aed31c459c6129243Eric Laurent if (mHwSupportsPause && !mHwPaused) { 5760972a173d7d1de1a3b5a617aae3e2abb6e05ae02dEric Laurent doHwPause = true; 5761bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent mHwPaused = true; 5762bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent } 5763bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent // If we were part way through writing the mixbuffer to 5764bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent // the HAL we must save this until we resume 5765bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent // BUG - this will be wrong if a different track is made active, 5766bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent // in that case we want to discard the pending data in the 5767bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent // mixbuffer and tell the client to present it again when the 5768bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent // track is resumed 5769bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent mPausedWriteLength = mCurrentWriteLength; 5770bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent mPausedBytesRemaining = mBytesRemaining; 5771bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent mBytesRemaining = 0; // stop writing 5772bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent } 5773bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent tracksToRemove->add(track); 57747844f679be8d94c5cdf017f53754cb68ee2f00daHaynes Mathew George } else if (track->isFlushPending()) { 5775e93cc03da360a1a0d2ad937c745ce8c8e8be81c2Eric Laurent if (track->isStopping_1()) { 5776e93cc03da360a1a0d2ad937c745ce8c8e8be81c2Eric Laurent track->mRetryCount = kMaxTrackStopRetriesOffload; 5777e93cc03da360a1a0d2ad937c745ce8c8e8be81c2Eric Laurent } else { 5778e93cc03da360a1a0d2ad937c745ce8c8e8be81c2Eric Laurent track->mRetryCount = kMaxTrackRetriesOffload; 5779e93cc03da360a1a0d2ad937c745ce8c8e8be81c2Eric Laurent } 57807844f679be8d94c5cdf017f53754cb68ee2f00daHaynes Mathew George track->flushAck(); 57817844f679be8d94c5cdf017f53754cb68ee2f00daHaynes Mathew George if (last) { 57827844f679be8d94c5cdf017f53754cb68ee2f00daHaynes Mathew George mFlushPending = true; 57837844f679be8d94c5cdf017f53754cb68ee2f00daHaynes Mathew George } 57842d3ca68363f723fbe269d3ce52dab4985dfc7154Haynes Mathew George } else if (track->isResumePending()){ 57852d3ca68363f723fbe269d3ce52dab4985dfc7154Haynes Mathew George track->resumeAck(); 57862d3ca68363f723fbe269d3ce52dab4985dfc7154Haynes Mathew George if (last) { 57872d3ca68363f723fbe269d3ce52dab4985dfc7154Haynes Mathew George if (mPausedBytesRemaining) { 57882d3ca68363f723fbe269d3ce52dab4985dfc7154Haynes Mathew George // Need to continue write that was interrupted 57892d3ca68363f723fbe269d3ce52dab4985dfc7154Haynes Mathew George mCurrentWriteLength = mPausedWriteLength; 57902d3ca68363f723fbe269d3ce52dab4985dfc7154Haynes Mathew George mBytesRemaining = mPausedBytesRemaining; 57912d3ca68363f723fbe269d3ce52dab4985dfc7154Haynes Mathew George mPausedBytesRemaining = 0; 57922d3ca68363f723fbe269d3ce52dab4985dfc7154Haynes Mathew George } 57932d3ca68363f723fbe269d3ce52dab4985dfc7154Haynes Mathew George if (mHwPaused) { 57942d3ca68363f723fbe269d3ce52dab4985dfc7154Haynes Mathew George doHwResume = true; 57952d3ca68363f723fbe269d3ce52dab4985dfc7154Haynes Mathew George mHwPaused = false; 57962d3ca68363f723fbe269d3ce52dab4985dfc7154Haynes Mathew George // threadLoop_mix() will handle the case that we need to 57972d3ca68363f723fbe269d3ce52dab4985dfc7154Haynes Mathew George // resume an interrupted write 57982d3ca68363f723fbe269d3ce52dab4985dfc7154Haynes Mathew George } 57992d3ca68363f723fbe269d3ce52dab4985dfc7154Haynes Mathew George // enable write to audio HAL 5800ad9cb8b88e4f8face23f01d8dc89fa769dacb50fEric Laurent mSleepTimeUs = 0; 58012d3ca68363f723fbe269d3ce52dab4985dfc7154Haynes Mathew George 58023df841a10b4d553949c518ad52f1af8dcb365058Eric Laurent mLeftVolFloat = mRightVolFloat = -1.0; 58033df841a10b4d553949c518ad52f1af8dcb365058Eric Laurent 58042d3ca68363f723fbe269d3ce52dab4985dfc7154Haynes Mathew George // Do not handle new data in this iteration even if track->framesReady() 58052d3ca68363f723fbe269d3ce52dab4985dfc7154Haynes Mathew George mixerStatus = MIXER_TRACKS_ENABLED; 58062d3ca68363f723fbe269d3ce52dab4985dfc7154Haynes Mathew George } 58072d3ca68363f723fbe269d3ce52dab4985dfc7154Haynes Mathew George } else if (track->framesReady() && track->isReady() && 58083b4529e03c5fc7a44c22f9091ad15a269bfca3a8Eric Laurent !track->isPaused() && !track->isTerminated() && !track->isStopping_2()) { 5809f20e1d8df84c5fbeeace0052d100982ae39bb7a4Glenn Kasten ALOGVV("OffloadThread: track %d s=%08x [OK]", track->name(), cblk->mServer); 5810bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent if (track->mFillingUpStatus == Track::FS_FILLED) { 5811bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent track->mFillingUpStatus = Track::FS_ACTIVE; 58123df841a10b4d553949c518ad52f1af8dcb365058Eric Laurent if (last) { 58133df841a10b4d553949c518ad52f1af8dcb365058Eric Laurent // make sure processVolume_l() will apply new volume even if 0 58143df841a10b4d553949c518ad52f1af8dcb365058Eric Laurent mLeftVolFloat = mRightVolFloat = -1.0; 58153df841a10b4d553949c518ad52f1af8dcb365058Eric Laurent } 5816bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent } 5817bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent 5818bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent if (last) { 5819d7e59228caad3867794d847f6bf163c6495e9506Eric Laurent sp<Track> previousTrack = mPreviousTrack.promote(); 5820d7e59228caad3867794d847f6bf163c6495e9506Eric Laurent if (previousTrack != 0) { 5821d7e59228caad3867794d847f6bf163c6495e9506Eric Laurent if (track != previousTrack.get()) { 58229da3d9573a18ffe08365557c706cf52f09118d1cEric Laurent // Flush any data still being written from last track 58239da3d9573a18ffe08365557c706cf52f09118d1cEric Laurent mBytesRemaining = 0; 58249da3d9573a18ffe08365557c706cf52f09118d1cEric Laurent if (mPausedBytesRemaining) { 58259da3d9573a18ffe08365557c706cf52f09118d1cEric Laurent // Last track was paused so we also need to flush saved 58269da3d9573a18ffe08365557c706cf52f09118d1cEric Laurent // mixbuffer state and invalidate track so that it will 58279da3d9573a18ffe08365557c706cf52f09118d1cEric Laurent // re-submit that unwritten data when it is next resumed 58289da3d9573a18ffe08365557c706cf52f09118d1cEric Laurent mPausedBytesRemaining = 0; 58299da3d9573a18ffe08365557c706cf52f09118d1cEric Laurent // Invalidate is a bit drastic - would be more efficient 58309da3d9573a18ffe08365557c706cf52f09118d1cEric Laurent // to have a flag to tell client that some of the 58319da3d9573a18ffe08365557c706cf52f09118d1cEric Laurent // previously written data was lost 5832d7e59228caad3867794d847f6bf163c6495e9506Eric Laurent previousTrack->invalidate(); 58339da3d9573a18ffe08365557c706cf52f09118d1cEric Laurent } 58349da3d9573a18ffe08365557c706cf52f09118d1cEric Laurent // flush data already sent to the DSP if changing audio session as audio 58359da3d9573a18ffe08365557c706cf52f09118d1cEric Laurent // comes from a different source. Also invalidate previous track to force a 58369da3d9573a18ffe08365557c706cf52f09118d1cEric Laurent // seek when resuming. 5837d7e59228caad3867794d847f6bf163c6495e9506Eric Laurent if (previousTrack->sessionId() != track->sessionId()) { 5838d7e59228caad3867794d847f6bf163c6495e9506Eric Laurent previousTrack->invalidate(); 58399da3d9573a18ffe08365557c706cf52f09118d1cEric Laurent } 58409da3d9573a18ffe08365557c706cf52f09118d1cEric Laurent } 58419da3d9573a18ffe08365557c706cf52f09118d1cEric Laurent } 58429da3d9573a18ffe08365557c706cf52f09118d1cEric Laurent mPreviousTrack = track; 5843bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent // reset retry count 5844e93cc03da360a1a0d2ad937c745ce8c8e8be81c2Eric Laurent if (track->isStopping_1()) { 5845e93cc03da360a1a0d2ad937c745ce8c8e8be81c2Eric Laurent track->mRetryCount = kMaxTrackStopRetriesOffload; 5846e93cc03da360a1a0d2ad937c745ce8c8e8be81c2Eric Laurent } else { 5847e93cc03da360a1a0d2ad937c745ce8c8e8be81c2Eric Laurent track->mRetryCount = kMaxTrackRetriesOffload; 5848e93cc03da360a1a0d2ad937c745ce8c8e8be81c2Eric Laurent } 58495850c4c8eecbe0db3cee8511a4f82cb443e27d08Eric Laurent mActiveTrack = t; 5850bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent mixerStatus = MIXER_TRACKS_READY; 5851bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent } 5852bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent } else { 5853f20e1d8df84c5fbeeace0052d100982ae39bb7a4Glenn Kasten ALOGVV("OffloadThread: track %d s=%08x [NOT READY]", track->name(), cblk->mServer); 5854bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent if (track->isStopping_1()) { 5855e93cc03da360a1a0d2ad937c745ce8c8e8be81c2Eric Laurent if (--(track->mRetryCount) <= 0) { 5856e93cc03da360a1a0d2ad937c745ce8c8e8be81c2Eric Laurent // Hardware buffer can hold a large amount of audio so we must 5857e93cc03da360a1a0d2ad937c745ce8c8e8be81c2Eric Laurent // wait for all current track's data to drain before we say 5858e93cc03da360a1a0d2ad937c745ce8c8e8be81c2Eric Laurent // that the track is stopped. 5859e93cc03da360a1a0d2ad937c745ce8c8e8be81c2Eric Laurent if (mBytesRemaining == 0) { 5860e93cc03da360a1a0d2ad937c745ce8c8e8be81c2Eric Laurent // Only start draining when all data in mixbuffer 5861e93cc03da360a1a0d2ad937c745ce8c8e8be81c2Eric Laurent // has been written 5862e93cc03da360a1a0d2ad937c745ce8c8e8be81c2Eric Laurent ALOGV("OffloadThread: underrun and STOPPING_1 -> draining, STOPPING_2"); 5863e93cc03da360a1a0d2ad937c745ce8c8e8be81c2Eric Laurent track->mState = TrackBase::STOPPING_2; // so presentation completes after 5864e93cc03da360a1a0d2ad937c745ce8c8e8be81c2Eric Laurent // drain do not drain if no data was ever sent to HAL (mStandby == true) 5865e93cc03da360a1a0d2ad937c745ce8c8e8be81c2Eric Laurent if (last && !mStandby) { 5866e93cc03da360a1a0d2ad937c745ce8c8e8be81c2Eric Laurent // do not modify drain sequence if we are already draining. This happens 5867e93cc03da360a1a0d2ad937c745ce8c8e8be81c2Eric Laurent // when resuming from pause after drain. 5868e93cc03da360a1a0d2ad937c745ce8c8e8be81c2Eric Laurent if ((mDrainSequence & 1) == 0) { 5869e93cc03da360a1a0d2ad937c745ce8c8e8be81c2Eric Laurent mSleepTimeUs = 0; 5870e93cc03da360a1a0d2ad937c745ce8c8e8be81c2Eric Laurent mStandbyTimeNs = systemTime() + mStandbyDelayNs; 5871e93cc03da360a1a0d2ad937c745ce8c8e8be81c2Eric Laurent mixerStatus = MIXER_DRAIN_TRACK; 5872e93cc03da360a1a0d2ad937c745ce8c8e8be81c2Eric Laurent mDrainSequence += 2; 5873e93cc03da360a1a0d2ad937c745ce8c8e8be81c2Eric Laurent } 5874e93cc03da360a1a0d2ad937c745ce8c8e8be81c2Eric Laurent if (mHwPaused) { 5875e93cc03da360a1a0d2ad937c745ce8c8e8be81c2Eric Laurent // It is possible to move from PAUSED to STOPPING_1 without 5876e93cc03da360a1a0d2ad937c745ce8c8e8be81c2Eric Laurent // a resume so we must ensure hardware is running 5877e93cc03da360a1a0d2ad937c745ce8c8e8be81c2Eric Laurent doHwResume = true; 5878e93cc03da360a1a0d2ad937c745ce8c8e8be81c2Eric Laurent mHwPaused = false; 5879e93cc03da360a1a0d2ad937c745ce8c8e8be81c2Eric Laurent } 5880bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent } 5881bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent } 5882e93cc03da360a1a0d2ad937c745ce8c8e8be81c2Eric Laurent } else if (last) { 5883e93cc03da360a1a0d2ad937c745ce8c8e8be81c2Eric Laurent ALOGV("stopping1 underrun retries left %d", track->mRetryCount); 5884e93cc03da360a1a0d2ad937c745ce8c8e8be81c2Eric Laurent mixerStatus = MIXER_TRACKS_ENABLED; 5885bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent } 5886bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent } else if (track->isStopping_2()) { 58876a51d7ed7062536ccc892c8850a34ed55cbc8d5cEric Laurent // Drain has completed or we are in standby, signal presentation complete 58886a51d7ed7062536ccc892c8850a34ed55cbc8d5cEric Laurent if (!(mDrainSequence & 1) || !last || mStandby) { 5889bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent track->mState = TrackBase::STOPPED; 58901dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov uint32_t latency = 0; 58911dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov status_t result = mOutput->stream->getLatency(&latency); 58921dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov ALOGE_IF(result != OK, 58931dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov "Error when retrieving output stream latency: %d", result); 58941dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov size_t audioHALFrames = (latency * mSampleRate) / 1000; 5895818e7a32ce3633980138aff2c2bfcc5158b3cfccAndy Hung int64_t framesWritten = 5896062e67a26e0553dd142be622821f493df541f0c6Phil Burk mBytesWritten / mOutput->getFrameSize(); 5897bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent track->presentationComplete(framesWritten, audioHALFrames); 5898bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent track->reset(); 5899bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent tracksToRemove->add(track); 5900bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent } 5901bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent } else { 5902bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent // No buffers for this track. Give it a few chances to 5903bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent // fill a buffer, then remove it from active list. 5904bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent if (--(track->mRetryCount) <= 0) { 5905f804475807407442d5596ab7378ed07d50664063Andy Hung bool running = false; 59061dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov uint64_t position = 0; 59071dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov struct timespec unused; 59081dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov // The running check restarts the retry counter at least once. 59091dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov status_t ret = mOutput->stream->getPresentationPosition(&position, &unused); 59101dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov if (ret == NO_ERROR && position != mOffloadUnderrunPosition) { 59111dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov running = true; 59121dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov mOffloadUnderrunPosition = position; 59131dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov } 59141dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov if (ret == NO_ERROR) { 5915f804475807407442d5596ab7378ed07d50664063Andy Hung ALOGVV("underrun counter, running(%d): %lld vs %lld", running, 5916f804475807407442d5596ab7378ed07d50664063Andy Hung (long long)position, (long long)mOffloadUnderrunPosition); 5917f804475807407442d5596ab7378ed07d50664063Andy Hung } 5918f804475807407442d5596ab7378ed07d50664063Andy Hung if (running) { // still running, give us more time. 5919f804475807407442d5596ab7378ed07d50664063Andy Hung track->mRetryCount = kMaxTrackRetriesOffload; 5920f804475807407442d5596ab7378ed07d50664063Andy Hung } else { 5921f804475807407442d5596ab7378ed07d50664063Andy Hung ALOGV("OffloadThread: BUFFER TIMEOUT: remove(%d) from active list", 5922f804475807407442d5596ab7378ed07d50664063Andy Hung track->name()); 5923f804475807407442d5596ab7378ed07d50664063Andy Hung tracksToRemove->add(track); 5924d3bb645f0b7f567b033b8664499d685f8ec10628Glenn Kasten // tell client process that the track was disabled because of underrun; 5925f804475807407442d5596ab7378ed07d50664063Andy Hung // it will then automatically call start() when data is available 5926f804475807407442d5596ab7378ed07d50664063Andy Hung track->disable(); 5927f804475807407442d5596ab7378ed07d50664063Andy Hung } 5928bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent } else if (last){ 5929bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent mixerStatus = MIXER_TRACKS_ENABLED; 5930bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent } 5931bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent } 5932bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent } 5933bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent // compute volume for this track 5934bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent processVolume_l(track, last); 5935bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent } 59366bf9ae20b3bd2dbb8f2e89ee167a6785222301cfEric Laurent 5937ea0fadeb5d81ef3cb7f9db458c9033d628bdb86aEric Laurent // make sure the pause/flush/resume sequence is executed in the right order. 5938ea0fadeb5d81ef3cb7f9db458c9033d628bdb86aEric Laurent // If a flush is pending and a track is active but the HW is not paused, force a HW pause 5939ea0fadeb5d81ef3cb7f9db458c9033d628bdb86aEric Laurent // before flush and then resume HW. This can happen in case of pause/flush/resume 5940ea0fadeb5d81ef3cb7f9db458c9033d628bdb86aEric Laurent // if resume is received before pause is executed. 5941fd4779740ec3e9e865d5514464df26d015354388Eric Laurent if (!mStandby && (doHwPause || (mFlushPending && !mHwPaused && (count != 0)))) { 59421dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov status_t result = mOutput->stream->pause(); 59431dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov ALOGE_IF(result != OK, "Error when pausing output stream: %d", result); 5944972a173d7d1de1a3b5a617aae3e2abb6e05ae02dEric Laurent } 59456bf9ae20b3bd2dbb8f2e89ee167a6785222301cfEric Laurent if (mFlushPending) { 59466bf9ae20b3bd2dbb8f2e89ee167a6785222301cfEric Laurent flushHw_l(); 59476bf9ae20b3bd2dbb8f2e89ee167a6785222301cfEric Laurent } 5948fd4779740ec3e9e865d5514464df26d015354388Eric Laurent if (!mStandby && doHwResume) { 59491dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov status_t result = mOutput->stream->resume(); 59501dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov ALOGE_IF(result != OK, "Error when resuming output stream: %d", result); 5951972a173d7d1de1a3b5a617aae3e2abb6e05ae02dEric Laurent } 59526bf9ae20b3bd2dbb8f2e89ee167a6785222301cfEric Laurent 5953bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent // remove all the tracks that need to be... 5954bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent removeTracks_l(*tracksToRemove); 5955bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent 5956bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent return mixerStatus; 5957bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent} 5958bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent 5959bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent// must be called with thread mutex locked 5960bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurentbool AudioFlinger::OffloadThread::waitingAsyncCallback_l() 5961bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent{ 59623b4529e03c5fc7a44c22f9091ad15a269bfca3a8Eric Laurent ALOGVV("waitingAsyncCallback_l mWriteAckSequence %d mDrainSequence %d", 59633b4529e03c5fc7a44c22f9091ad15a269bfca3a8Eric Laurent mWriteAckSequence, mDrainSequence); 59643b4529e03c5fc7a44c22f9091ad15a269bfca3a8Eric Laurent if (mUseAsyncWrite && ((mWriteAckSequence & 1) || (mDrainSequence & 1))) { 5965bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent return true; 5966bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent } 5967bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent return false; 5968bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent} 5969bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent 5970bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurentbool AudioFlinger::OffloadThread::waitingAsyncCallback() 5971bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent{ 5972bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent Mutex::Autolock _l(mLock); 5973bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent return waitingAsyncCallback_l(); 5974bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent} 5975bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent 5976bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurentvoid AudioFlinger::OffloadThread::flushHw_l() 5977bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent{ 5978e659ef420dae0caae84ab78f9df8952acb9ad3a0Eric Laurent DirectOutputThread::flushHw_l(); 5979bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent // Flush anything still waiting in the mixbuffer 5980bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent mCurrentWriteLength = 0; 5981bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent mBytesRemaining = 0; 5982bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent mPausedWriteLength = 0; 5983bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent mPausedBytesRemaining = 0; 59843eaf66b860f9a0d8af0dd4d5ac6adb5b67d7b73aEric Laurent // reset bytes written count to reflect that DSP buffers are empty after flush. 59853eaf66b860f9a0d8af0dd4d5ac6adb5b67d7b73aEric Laurent mBytesWritten = 0; 5986f804475807407442d5596ab7378ed07d50664063Andy Hung mOffloadUnderrunPosition = ~0LL; 59870f02f265123b7ef2fd6ac09ff70cde26eb5559adHaynes Mathew George 5988bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent if (mUseAsyncWrite) { 59893b4529e03c5fc7a44c22f9091ad15a269bfca3a8Eric Laurent // discard any pending drain or write ack by incrementing sequence 59903b4529e03c5fc7a44c22f9091ad15a269bfca3a8Eric Laurent mWriteAckSequence = (mWriteAckSequence + 2) & ~1; 59913b4529e03c5fc7a44c22f9091ad15a269bfca3a8Eric Laurent mDrainSequence = (mDrainSequence + 2) & ~1; 5992bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent ALOG_ASSERT(mCallbackThread != 0); 59933b4529e03c5fc7a44c22f9091ad15a269bfca3a8Eric Laurent mCallbackThread->setWriteBlocked(mWriteAckSequence); 59943b4529e03c5fc7a44c22f9091ad15a269bfca3a8Eric Laurent mCallbackThread->setDraining(mDrainSequence); 5995bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent } 5996bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent} 5997bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent 599805317d29b27e5fda654bea21b80d4423a03f49b3Haynes Mathew Georgevoid AudioFlinger::OffloadThread::invalidateTracks(audio_stream_type_t streamType) 599905317d29b27e5fda654bea21b80d4423a03f49b3Haynes Mathew George{ 600005317d29b27e5fda654bea21b80d4423a03f49b3Haynes Mathew George Mutex::Autolock _l(mLock); 600113084621072ea2e4c34e2a9d79793c621d9bf005Eric Laurent if (PlaybackThread::invalidateTracks_l(streamType)) { 600213084621072ea2e4c34e2a9d79793c621d9bf005Eric Laurent mFlushPending = true; 600313084621072ea2e4c34e2a9d79793c621d9bf005Eric Laurent } 600405317d29b27e5fda654bea21b80d4423a03f49b3Haynes Mathew George} 600505317d29b27e5fda654bea21b80d4423a03f49b3Haynes Mathew George 6006bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent// ---------------------------------------------------------------------------- 6007bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent 600881784c37c61b09289654b979567a42bf73cd2b12Eric LaurentAudioFlinger::DuplicatingThread::DuplicatingThread(const sp<AudioFlinger>& audioFlinger, 600972e3f39146fce4686bd96f11057c051bea376dfbEric Laurent AudioFlinger::MixerThread* mainThread, audio_io_handle_t id, bool systemReady) 601081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent : MixerThread(audioFlinger, mainThread->getOutput(), id, mainThread->outDevice(), 601172e3f39146fce4686bd96f11057c051bea376dfbEric Laurent systemReady, DUPLICATING), 601281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mWaitTimeMs(UINT_MAX) 601381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 601481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent addOutputTrack(mainThread); 601581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 601681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 601781784c37c61b09289654b979567a42bf73cd2b12Eric LaurentAudioFlinger::DuplicatingThread::~DuplicatingThread() 601881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 601981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent for (size_t i = 0; i < mOutputTracks.size(); i++) { 602081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mOutputTracks[i]->destroy(); 602181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 602281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 602381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 602481784c37c61b09289654b979567a42bf73cd2b12Eric Laurentvoid AudioFlinger::DuplicatingThread::threadLoop_mix() 602581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 602681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // mix buffers... 602781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (outputsReady(outputTracks)) { 6028d79072e9dff59f767cce2cda1caab80ce5a0815bGlenn Kasten mAudioMixer->process(); 602981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } else { 603002b5708776ba2a9b4ff8c09008483aef7dbe38c7Eric Laurent if (mMixerBufferValid) { 603102b5708776ba2a9b4ff8c09008483aef7dbe38c7Eric Laurent memset(mMixerBuffer, 0, mMixerBufferSize); 603202b5708776ba2a9b4ff8c09008483aef7dbe38c7Eric Laurent } else { 603302b5708776ba2a9b4ff8c09008483aef7dbe38c7Eric Laurent memset(mSinkBuffer, 0, mSinkBufferSize); 603402b5708776ba2a9b4ff8c09008483aef7dbe38c7Eric Laurent } 603581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 6036ad9cb8b88e4f8face23f01d8dc89fa769dacb50fEric Laurent mSleepTimeUs = 0; 603781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent writeFrames = mNormalFrameCount; 603825c2dac12114699e90deb1c579cadebce7b91a97Andy Hung mCurrentWriteLength = mSinkBufferSize; 6039ad9cb8b88e4f8face23f01d8dc89fa769dacb50fEric Laurent mStandbyTimeNs = systemTime() + mStandbyDelayNs; 604081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 604181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 604281784c37c61b09289654b979567a42bf73cd2b12Eric Laurentvoid AudioFlinger::DuplicatingThread::threadLoop_sleepTime() 604381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 6044ad9cb8b88e4f8face23f01d8dc89fa769dacb50fEric Laurent if (mSleepTimeUs == 0) { 604581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (mMixerStatus == MIXER_TRACKS_ENABLED) { 6046ad9cb8b88e4f8face23f01d8dc89fa769dacb50fEric Laurent mSleepTimeUs = mActiveSleepTimeUs; 604781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } else { 6048ad9cb8b88e4f8face23f01d8dc89fa769dacb50fEric Laurent mSleepTimeUs = mIdleSleepTimeUs; 604981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 605081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } else if (mBytesWritten != 0) { 605181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (mMixerStatus == MIXER_TRACKS_ENABLED) { 605281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent writeFrames = mNormalFrameCount; 605325c2dac12114699e90deb1c579cadebce7b91a97Andy Hung memset(mSinkBuffer, 0, mSinkBufferSize); 605481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } else { 605581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // flush remaining overflow buffers in output tracks 605681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent writeFrames = 0; 605781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 6058ad9cb8b88e4f8face23f01d8dc89fa769dacb50fEric Laurent mSleepTimeUs = 0; 605981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 606081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 606181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 6062bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurentssize_t AudioFlinger::DuplicatingThread::threadLoop_write() 606381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 606481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent for (size_t i = 0; i < outputTracks.size(); i++) { 6065c25b84abdd7ff229d0af663fbf3a37bd9512939dAndy Hung outputTracks[i]->write(mSinkBuffer, writeFrames); 606681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 60672c3740f01acca69c3e0bcc5e01bb0edc51b6777fEric Laurent mStandby = false; 606825c2dac12114699e90deb1c579cadebce7b91a97Andy Hung return (ssize_t)mSinkBufferSize; 606981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 607081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 607181784c37c61b09289654b979567a42bf73cd2b12Eric Laurentvoid AudioFlinger::DuplicatingThread::threadLoop_standby() 607281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 607381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // DuplicatingThread implements standby by stopping all tracks 607481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent for (size_t i = 0; i < outputTracks.size(); i++) { 607581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent outputTracks[i]->stop(); 607681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 607781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 607881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 60791bc088a918d7038603230637d640941953b314d4Andy Hungvoid AudioFlinger::DuplicatingThread::dumpInternals(int fd, const Vector<String16>& args __unused) 60801bc088a918d7038603230637d640941953b314d4Andy Hung{ 60811bc088a918d7038603230637d640941953b314d4Andy Hung MixerThread::dumpInternals(fd, args); 60821bc088a918d7038603230637d640941953b314d4Andy Hung 60831bc088a918d7038603230637d640941953b314d4Andy Hung std::stringstream ss; 60841bc088a918d7038603230637d640941953b314d4Andy Hung const size_t numTracks = mOutputTracks.size(); 60851bc088a918d7038603230637d640941953b314d4Andy Hung ss << " " << numTracks << " OutputTracks"; 60861bc088a918d7038603230637d640941953b314d4Andy Hung if (numTracks > 0) { 60871bc088a918d7038603230637d640941953b314d4Andy Hung ss << ":"; 60881bc088a918d7038603230637d640941953b314d4Andy Hung for (const auto &track : mOutputTracks) { 60891bc088a918d7038603230637d640941953b314d4Andy Hung const sp<ThreadBase> thread = track->thread().promote(); 60901bc088a918d7038603230637d640941953b314d4Andy Hung ss << " (" << track->name() << " : "; 60911bc088a918d7038603230637d640941953b314d4Andy Hung if (thread.get() != nullptr) { 60921bc088a918d7038603230637d640941953b314d4Andy Hung ss << thread.get() << ", " << thread->id(); 60931bc088a918d7038603230637d640941953b314d4Andy Hung } else { 60941bc088a918d7038603230637d640941953b314d4Andy Hung ss << "null"; 60951bc088a918d7038603230637d640941953b314d4Andy Hung } 60961bc088a918d7038603230637d640941953b314d4Andy Hung ss << ")"; 60971bc088a918d7038603230637d640941953b314d4Andy Hung } 60981bc088a918d7038603230637d640941953b314d4Andy Hung } 60991bc088a918d7038603230637d640941953b314d4Andy Hung ss << "\n"; 61001bc088a918d7038603230637d640941953b314d4Andy Hung std::string result = ss.str(); 61011bc088a918d7038603230637d640941953b314d4Andy Hung write(fd, result.c_str(), result.size()); 61021bc088a918d7038603230637d640941953b314d4Andy Hung} 61031bc088a918d7038603230637d640941953b314d4Andy Hung 610481784c37c61b09289654b979567a42bf73cd2b12Eric Laurentvoid AudioFlinger::DuplicatingThread::saveOutputTracks() 610581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 610681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent outputTracks = mOutputTracks; 610781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 610881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 610981784c37c61b09289654b979567a42bf73cd2b12Eric Laurentvoid AudioFlinger::DuplicatingThread::clearOutputTracks() 611081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 611181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent outputTracks.clear(); 611281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 611381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 611481784c37c61b09289654b979567a42bf73cd2b12Eric Laurentvoid AudioFlinger::DuplicatingThread::addOutputTrack(MixerThread *thread) 611581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 611681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent Mutex::Autolock _l(mLock); 6117c25b84abdd7ff229d0af663fbf3a37bd9512939dAndy Hung // The downstream MixerThread consumes thread->frameCount() amount of frames per mix pass. 6118c25b84abdd7ff229d0af663fbf3a37bd9512939dAndy Hung // Adjust for thread->sampleRate() to determine minimum buffer frame count. 6119c25b84abdd7ff229d0af663fbf3a37bd9512939dAndy Hung // Then triple buffer because Threads do not run synchronously and may not be clock locked. 6120c25b84abdd7ff229d0af663fbf3a37bd9512939dAndy Hung const size_t frameCount = 6121c25b84abdd7ff229d0af663fbf3a37bd9512939dAndy Hung 3 * sourceFramesNeeded(mSampleRate, thread->frameCount(), thread->sampleRate()); 6122c25b84abdd7ff229d0af663fbf3a37bd9512939dAndy Hung // TODO: Consider asynchronous sample rate conversion to handle clock disparity 6123c25b84abdd7ff229d0af663fbf3a37bd9512939dAndy Hung // from different OutputTracks and their associated MixerThreads (e.g. one may 6124c25b84abdd7ff229d0af663fbf3a37bd9512939dAndy Hung // nearly empty and the other may be dropping data). 6125c25b84abdd7ff229d0af663fbf3a37bd9512939dAndy Hung 6126c25b84abdd7ff229d0af663fbf3a37bd9512939dAndy Hung sp<OutputTrack> outputTrack = new OutputTrack(thread, 612781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent this, 612881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mSampleRate, 6129c25b84abdd7ff229d0af663fbf3a37bd9512939dAndy Hung mFormat, 613081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mChannelMask, 6131462fd2fa9eef642b0574aa7409de0bde3fec8d43Marco Nelissen frameCount, 6132462fd2fa9eef642b0574aa7409de0bde3fec8d43Marco Nelissen IPCThreadState::self()->getCallingUid()); 6133af3ec7c9a0cfc483017d4457e0e3d77de4b1a33aEric Laurent status_t status = outputTrack != 0 ? outputTrack->initCheck() : (status_t) NO_MEMORY; 6134af3ec7c9a0cfc483017d4457e0e3d77de4b1a33aEric Laurent if (status != NO_ERROR) { 6135af3ec7c9a0cfc483017d4457e0e3d77de4b1a33aEric Laurent ALOGE("addOutputTrack() initCheck failed %d", status); 6136af3ec7c9a0cfc483017d4457e0e3d77de4b1a33aEric Laurent return; 613781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 6138af3ec7c9a0cfc483017d4457e0e3d77de4b1a33aEric Laurent thread->setStreamVolume(AUDIO_STREAM_PATCH, 1.0f); 6139af3ec7c9a0cfc483017d4457e0e3d77de4b1a33aEric Laurent mOutputTracks.add(outputTrack); 6140af3ec7c9a0cfc483017d4457e0e3d77de4b1a33aEric Laurent ALOGV("addOutputTrack() track %p, on thread %p", outputTrack.get(), thread); 6141af3ec7c9a0cfc483017d4457e0e3d77de4b1a33aEric Laurent updateWaitTime_l(); 614281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 614381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 614481784c37c61b09289654b979567a42bf73cd2b12Eric Laurentvoid AudioFlinger::DuplicatingThread::removeOutputTrack(MixerThread *thread) 614581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 614681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent Mutex::Autolock _l(mLock); 614781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent for (size_t i = 0; i < mOutputTracks.size(); i++) { 614881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (mOutputTracks[i]->thread() == thread) { 614981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mOutputTracks[i]->destroy(); 615081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mOutputTracks.removeAt(i); 615181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent updateWaitTime_l(); 6152f6870aefc5e31d4220f3778c4e79ff34a61f48adEric Laurent if (thread->getOutput() == mOutput) { 6153f6870aefc5e31d4220f3778c4e79ff34a61f48adEric Laurent mOutput = NULL; 6154f6870aefc5e31d4220f3778c4e79ff34a61f48adEric Laurent } 615581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent return; 615681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 615781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 6158f6870aefc5e31d4220f3778c4e79ff34a61f48adEric Laurent ALOGV("removeOutputTrack(): unknown thread: %p", thread); 615981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 616081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 616181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// caller must hold mLock 616281784c37c61b09289654b979567a42bf73cd2b12Eric Laurentvoid AudioFlinger::DuplicatingThread::updateWaitTime_l() 616381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 616481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mWaitTimeMs = UINT_MAX; 616581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent for (size_t i = 0; i < mOutputTracks.size(); i++) { 616681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent sp<ThreadBase> strong = mOutputTracks[i]->thread().promote(); 616781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (strong != 0) { 616881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent uint32_t waitTimeMs = (strong->frameCount() * 2 * 1000) / strong->sampleRate(); 616981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (waitTimeMs < mWaitTimeMs) { 617081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mWaitTimeMs = waitTimeMs; 617181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 617281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 617381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 617481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 617581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 617681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 617781784c37c61b09289654b979567a42bf73cd2b12Eric Laurentbool AudioFlinger::DuplicatingThread::outputsReady( 617881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent const SortedVector< sp<OutputTrack> > &outputTracks) 617981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 618081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent for (size_t i = 0; i < outputTracks.size(); i++) { 618181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent sp<ThreadBase> thread = outputTracks[i]->thread().promote(); 618281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (thread == 0) { 618381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent ALOGW("DuplicatingThread::outputsReady() could not promote thread on output track %p", 618481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent outputTracks[i].get()); 618581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent return false; 618681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 618781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent PlaybackThread *playbackThread = (PlaybackThread *)thread.get(); 618881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // see note at standby() declaration 618981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (playbackThread->standby() && !playbackThread->isSuspended()) { 619081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent ALOGV("DuplicatingThread output track %p on thread %p Not Ready", outputTracks[i].get(), 619181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent thread.get()); 619281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent return false; 619381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 619481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 619581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent return true; 619681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 619781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 619812381092fdb5810cb27f738435ea8a0e3d2d0f42Kevin Rocardvoid AudioFlinger::DuplicatingThread::sendMetadataToBackend_l( 619912381092fdb5810cb27f738435ea8a0e3d2d0f42Kevin Rocard const StreamOutHalInterface::SourceMetadata& metadata) 6200069c2719e753732d5af9ba51e5fcc34342b0c9f2Kevin Rocard{ 620112381092fdb5810cb27f738435ea8a0e3d2d0f42Kevin Rocard for (auto& outputTrack : outputTracks) { // not mOutputTracks 620212381092fdb5810cb27f738435ea8a0e3d2d0f42Kevin Rocard outputTrack->setMetadatas(metadata.tracks); 620312381092fdb5810cb27f738435ea8a0e3d2d0f42Kevin Rocard } 6204069c2719e753732d5af9ba51e5fcc34342b0c9f2Kevin Rocard} 6205069c2719e753732d5af9ba51e5fcc34342b0c9f2Kevin Rocard 620681784c37c61b09289654b979567a42bf73cd2b12Eric Laurentuint32_t AudioFlinger::DuplicatingThread::activeSleepTimeUs() const 620781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 620881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent return (mWaitTimeMs * 1000) / 2; 620981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 621081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 621181784c37c61b09289654b979567a42bf73cd2b12Eric Laurentvoid AudioFlinger::DuplicatingThread::cacheParameters_l() 621281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 621381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // updateWaitTime_l() sets mWaitTimeMs, which affects activeSleepTimeUs(), so call it first 621481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent updateWaitTime_l(); 621581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 621681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent MixerThread::cacheParameters_l(); 621781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 621881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 62196acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 622081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// ---------------------------------------------------------------------------- 622181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// Record 622281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// ---------------------------------------------------------------------------- 622381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 622481784c37c61b09289654b979567a42bf73cd2b12Eric LaurentAudioFlinger::RecordThread::RecordThread(const sp<AudioFlinger>& audioFlinger, 622581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent AudioStreamIn *input, 622681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent audio_io_handle_t id, 6227d3922f72601d82c6fc067a98916fda0bd1291c5fEric Laurent audio_devices_t outDevice, 622872e3f39146fce4686bd96f11057c051bea376dfbEric Laurent audio_devices_t inDevice, 622972e3f39146fce4686bd96f11057c051bea376dfbEric Laurent bool systemReady 623046909e7eb074ce1b95b8a411eb71154f53f84f77Glenn Kasten#ifdef TEE_SINK 623146909e7eb074ce1b95b8a411eb71154f53f84f77Glenn Kasten , const sp<NBAIO_Sink>& teeSink 623246909e7eb074ce1b95b8a411eb71154f53f84f77Glenn Kasten#endif 623346909e7eb074ce1b95b8a411eb71154f53f84f77Glenn Kasten ) : 623472e3f39146fce4686bd96f11057c051bea376dfbEric Laurent ThreadBase(audioFlinger, id, outDevice, inDevice, RECORD, systemReady), 62352c6c3bb76b2fa18ed3536331a1700250bd04c7ceAndy Hung mInput(input), 62362c6c3bb76b2fa18ed3536331a1700250bd04c7ceAndy Hung mActiveTracks(&this->mLocalLog), 62372c6c3bb76b2fa18ed3536331a1700250bd04c7ceAndy Hung mRsmpInBuffer(NULL), 62381b291841a58ce6b2b291232dfdd56134b2185c48Glenn Kasten // mRsmpInFrames, mRsmpInFramesP2, and mRsmpInFramesOA are set by readInputParameters_l() 62394cc0a6a835c806d200ef83ef31fe5bef327c355cGlenn Kasten mRsmpInRear(0) 624046909e7eb074ce1b95b8a411eb71154f53f84f77Glenn Kasten#ifdef TEE_SINK 624146909e7eb074ce1b95b8a411eb71154f53f84f77Glenn Kasten , mTeeSink(teeSink) 624246909e7eb074ce1b95b8a411eb71154f53f84f77Glenn Kasten#endif 6243b880f5e5fc07397ddd09a94ba18bdf4fa62aae00Glenn Kasten , mReadOnlyHeap(new MemoryDealer(kRecordThreadReadOnlyHeapSize, 6244b880f5e5fc07397ddd09a94ba18bdf4fa62aae00Glenn Kasten "RecordThreadRO", MemoryHeapBase::READ_ONLY)) 62456dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten // mFastCapture below 62466dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten , mFastCaptureFutex(0) 62476dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten // mInputSource 62486dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten // mPipeSink 62496dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten // mPipeSource 62506dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten , mPipeFramesP2(0) 62516dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten // mPipeMemory 62526dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten // mFastCaptureNBLogWriter 62536e6704c06d61bc356e30c164081e5bcffb37920cGlenn Kasten , mFastTrackAvail(false) 6254d8365c54d049aade9e02ccae722f311f846cad9aEric Laurent , mBtNrecSuspended(false) 625581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 6256d7dca050c630bddbd73a6623271b34b4290460eeGlenn Kasten snprintf(mThreadName, kThreadNameLength, "AudioIn_%X", id); 6257d7dca050c630bddbd73a6623271b34b4290460eeGlenn Kasten mNBLogWriter = audioFlinger->newWriter_l(kLogSize, mThreadName); 625881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 6259deca2ae0a7cf8bc54ff3f30b7dc39bbc78b94c0dGlenn Kasten readInputParameters_l(); 62606dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten 62616dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten // create an NBAIO source for the HAL input stream, and negotiate 6262a0c91339814f37ea78365afb436c9f3d1f0a0090Mikhail Naganov mInputSource = new AudioStreamInSource(input->stream); 62636dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten size_t numCounterOffers = 0; 62646dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten const NBAIO_Format offers[1] = {Format_from_SR_C(mSampleRate, mChannelCount, mFormat)}; 626557c4e6f7464d458eb52d209c2a63524913d6406dGlenn Kasten#if !LOG_NDEBUG 626657c4e6f7464d458eb52d209c2a63524913d6406dGlenn Kasten ssize_t index = 626757c4e6f7464d458eb52d209c2a63524913d6406dGlenn Kasten#else 626857c4e6f7464d458eb52d209c2a63524913d6406dGlenn Kasten (void) 626957c4e6f7464d458eb52d209c2a63524913d6406dGlenn Kasten#endif 627057c4e6f7464d458eb52d209c2a63524913d6406dGlenn Kasten mInputSource->negotiate(offers, 1, NULL, numCounterOffers); 62716dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten ALOG_ASSERT(index == 0); 62726dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten 62736dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten // initialize fast capture depending on configuration 62746dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten bool initFastCapture; 62756dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten switch (kUseFastCapture) { 62766dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten case FastCapture_Never: 62776dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten initFastCapture = false; 6278b3cf7e656db20c65c0d7c779640db7f5f2a52bafMikhail Naganov ALOGV("%p kUseFastCapture = Never, initFastCapture = false", this); 62796dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten break; 62806dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten case FastCapture_Always: 62816dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten initFastCapture = true; 6282b3cf7e656db20c65c0d7c779640db7f5f2a52bafMikhail Naganov ALOGV("%p kUseFastCapture = Always, initFastCapture = true", this); 62836dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten break; 62846dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten case FastCapture_Static: 6285eb9487e10294a4e73977f460f30eeaff503acd21Glenn Kasten initFastCapture = (mFrameCount * 1000) / mSampleRate < kMinNormalCaptureBufferSizeMs; 6286b3cf7e656db20c65c0d7c779640db7f5f2a52bafMikhail Naganov ALOGV("%p kUseFastCapture = Static, (%lld * 1000) / %u vs %u, initFastCapture = %d", 6287b3cf7e656db20c65c0d7c779640db7f5f2a52bafMikhail Naganov this, (long long)mFrameCount, mSampleRate, kMinNormalCaptureBufferSizeMs, 6288b3cf7e656db20c65c0d7c779640db7f5f2a52bafMikhail Naganov initFastCapture); 62896dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten break; 62906dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten // case FastCapture_Dynamic: 62916dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten } 62926dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten 62936dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten if (initFastCapture) { 6294d198b85a163330b03e7507c9e8bfeb5f4d958a6cGlenn Kasten // create a Pipe for FastCapture to write to, and for us and fast tracks to read from 62956dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten NBAIO_Format format = mInputSource->format(); 62961b291841a58ce6b2b291232dfdd56134b2185c48Glenn Kasten // quadruple-buffering of 20 ms each; this ensures we can sleep for 20ms in RecordThread 62971b291841a58ce6b2b291232dfdd56134b2185c48Glenn Kasten size_t pipeFramesP2 = roundup(4 * FMS_20 * mSampleRate / 1000); 62986dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten size_t pipeSize = pipeFramesP2 * Format_frameSize(format); 6299b3cf7e656db20c65c0d7c779640db7f5f2a52bafMikhail Naganov void *pipeBuffer = nullptr; 63006dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten const sp<MemoryDealer> roHeap(readOnlyHeap()); 63016dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten sp<IMemory> pipeMemory; 63026dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten if ((roHeap == 0) || 63036dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten (pipeMemory = roHeap->allocate(pipeSize)) == 0 || 6304b3cf7e656db20c65c0d7c779640db7f5f2a52bafMikhail Naganov (pipeBuffer = pipeMemory->pointer()) == nullptr) { 6305b3cf7e656db20c65c0d7c779640db7f5f2a52bafMikhail Naganov ALOGE("not enough memory for pipe buffer size=%zu; " 6306b3cf7e656db20c65c0d7c779640db7f5f2a52bafMikhail Naganov "roHeap=%p, pipeMemory=%p, pipeBuffer=%p; roHeapSize: %lld", 6307b3cf7e656db20c65c0d7c779640db7f5f2a52bafMikhail Naganov pipeSize, roHeap.get(), pipeMemory.get(), pipeBuffer, 6308b3cf7e656db20c65c0d7c779640db7f5f2a52bafMikhail Naganov (long long)kRecordThreadReadOnlyHeapSize); 63096dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten goto failed; 63106dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten } 63116dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten // pipe will be shared directly with fast clients, so clear to avoid leaking old information 63126dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten memset(pipeBuffer, 0, pipeSize); 63136dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten Pipe *pipe = new Pipe(pipeFramesP2, format, pipeBuffer); 63146dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten const NBAIO_Format offers[1] = {format}; 63156dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten size_t numCounterOffers = 0; 63166dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten ssize_t index = pipe->negotiate(offers, 1, NULL, numCounterOffers); 63176dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten ALOG_ASSERT(index == 0); 63186dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten mPipeSink = pipe; 63196dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten PipeReader *pipeReader = new PipeReader(*pipe); 63206dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten numCounterOffers = 0; 63216dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten index = pipeReader->negotiate(offers, 1, NULL, numCounterOffers); 63226dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten ALOG_ASSERT(index == 0); 63236dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten mPipeSource = pipeReader; 63246dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten mPipeFramesP2 = pipeFramesP2; 63256dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten mPipeMemory = pipeMemory; 63266dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten 63276dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten // create fast capture 63286dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten mFastCapture = new FastCapture(); 63296dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten FastCaptureStateQueue *sq = mFastCapture->sq(); 63306dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten#ifdef STATE_QUEUE_DUMP 63316dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten // FIXME 63326dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten#endif 63336dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten FastCaptureState *state = sq->begin(); 63346dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten state->mCblk = NULL; 63356dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten state->mInputSource = mInputSource.get(); 63366dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten state->mInputSourceGen++; 63376dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten state->mPipeSink = pipe; 63386dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten state->mPipeSinkGen++; 63396dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten state->mFrameCount = mFrameCount; 63406dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten state->mCommand = FastCaptureState::COLD_IDLE; 63416dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten // already done in constructor initialization list 63426dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten //mFastCaptureFutex = 0; 63436dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten state->mColdFutexAddr = &mFastCaptureFutex; 63446dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten state->mColdGen++; 63456dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten state->mDumpState = &mFastCaptureDumpState; 63466dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten#ifdef TEE_SINK 63476dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten // FIXME 63486dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten#endif 63496dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten mFastCaptureNBLogWriter = audioFlinger->newWriter_l(kFastCaptureLogSize, "FastCapture"); 63506dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten state->mNBLogWriter = mFastCaptureNBLogWriter.get(); 63516dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten sq->end(); 63526dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten sq->push(FastCaptureStateQueue::BLOCK_UNTIL_PUSHED); 63536dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten 63546dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten // start the fast capture 63556dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten mFastCapture->run("FastCapture", ANDROID_PRIORITY_URGENT_AUDIO); 63566dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten pid_t tid = mFastCapture->getTid(); 6357af9a7b52b2273ea5c2b30350bdd0fce39a8b16d2Glenn Kasten sendPrioConfigEvent(getpid_cached, tid, kPriorityFastCapture, false /*forApp*/); 6358e1c4b5d7a94c21b8ce0c5707b4af84de596fbb79Mikhail Naganov stream()->setHalThreadPriority(kPriorityFastCapture); 63596dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten#ifdef AUDIO_WATCHDOG 63606dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten // FIXME 63616dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten#endif 63626dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten 63636e6704c06d61bc356e30c164081e5bcffb37920cGlenn Kasten mFastTrackAvail = true; 63646dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten } 63656dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kastenfailed: ; 63666dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten 63676dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten // FIXME mNormalSource 636881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 636981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 637081784c37c61b09289654b979567a42bf73cd2b12Eric LaurentAudioFlinger::RecordThread::~RecordThread() 637181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 63726dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten if (mFastCapture != 0) { 63736dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten FastCaptureStateQueue *sq = mFastCapture->sq(); 63746dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten FastCaptureState *state = sq->begin(); 63756dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten if (state->mCommand == FastCaptureState::COLD_IDLE) { 63766dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten int32_t old = android_atomic_inc(&mFastCaptureFutex); 63776dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten if (old == -1) { 63786dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten (void) syscall(__NR_futex, &mFastCaptureFutex, FUTEX_WAKE_PRIVATE, 1); 63796dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten } 63806dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten } 63816dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten state->mCommand = FastCaptureState::EXIT; 63826dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten sq->end(); 63836dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten sq->push(FastCaptureStateQueue::BLOCK_UNTIL_PUSHED); 63846dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten mFastCapture->join(); 63856dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten mFastCapture.clear(); 63866dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten } 63876dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten mAudioFlinger->unregisterWriter(mFastCaptureNBLogWriter); 6388481fb67a595f23c5b7f5be84b06db9b84a41a42fGlenn Kasten mAudioFlinger->unregisterWriter(mNBLogWriter); 63895744661e85981f8a9456bf470e2761235fc026daAndy Hung free(mRsmpInBuffer); 639081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 639181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 639281784c37c61b09289654b979567a42bf73cd2b12Eric Laurentvoid AudioFlinger::RecordThread::onFirstRef() 639381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 6394d7dca050c630bddbd73a6623271b34b4290460eeGlenn Kasten run(mThreadName, PRIORITY_URGENT_AUDIO); 639581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 639681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 6397555530ab903504ad3586bc24cd8a4f200f5c39aeEric Laurentvoid AudioFlinger::RecordThread::preExit() 6398555530ab903504ad3586bc24cd8a4f200f5c39aeEric Laurent{ 6399555530ab903504ad3586bc24cd8a4f200f5c39aeEric Laurent ALOGV(" preExit()"); 6400555530ab903504ad3586bc24cd8a4f200f5c39aeEric Laurent Mutex::Autolock _l(mLock); 6401555530ab903504ad3586bc24cd8a4f200f5c39aeEric Laurent for (size_t i = 0; i < mTracks.size(); i++) { 6402555530ab903504ad3586bc24cd8a4f200f5c39aeEric Laurent sp<RecordTrack> track = mTracks[i]; 6403555530ab903504ad3586bc24cd8a4f200f5c39aeEric Laurent track->invalidate(); 6404555530ab903504ad3586bc24cd8a4f200f5c39aeEric Laurent } 6405555530ab903504ad3586bc24cd8a4f200f5c39aeEric Laurent mActiveTracks.clear(); 6406555530ab903504ad3586bc24cd8a4f200f5c39aeEric Laurent mStartStopCond.broadcast(); 6407555530ab903504ad3586bc24cd8a4f200f5c39aeEric Laurent} 6408555530ab903504ad3586bc24cd8a4f200f5c39aeEric Laurent 640981784c37c61b09289654b979567a42bf73cd2b12Eric Laurentbool AudioFlinger::RecordThread::threadLoop() 641081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 641181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent nsecs_t lastWarning = 0; 641281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 641381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent inputStandBy(); 641481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 6415f10ffec18f930d92e1abe9200d60e746831841a7Glenn Kastenreacquire_wakelock: 6416f10ffec18f930d92e1abe9200d60e746831841a7Glenn Kasten sp<RecordTrack> activeTrack; 6417f10ffec18f930d92e1abe9200d60e746831841a7Glenn Kasten { 6418f10ffec18f930d92e1abe9200d60e746831841a7Glenn Kasten Mutex::Autolock _l(mLock); 6419dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hung acquireWakeLock_l(); 6420f10ffec18f930d92e1abe9200d60e746831841a7Glenn Kasten } 6421f10ffec18f930d92e1abe9200d60e746831841a7Glenn Kasten 64226dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten // used to request a deferred sleep, to be executed later while mutex is unlocked 64236dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten uint32_t sleepUs = 0; 64246dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten 64256dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten // loop while there is work to do 64264ef0b463a56c19bad9197aa9f90d792090461429Glenn Kasten for (;;) { 6427c527a7c2b1bfd26e8f3086e1b653d56e521379d9Glenn Kasten Vector< sp<EffectChain> > effectChains; 64282cfbf88b89854f30b295e8ae26a031edb8d712f8Glenn Kasten 64296dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten // activeTracks accumulates a copy of a subset of mActiveTracks 64306dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten Vector< sp<RecordTrack> > activeTracks; 64316dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten 6432735f45fbc37d7905ffb722f40727edbed82319b7Glenn Kasten // reference to the (first and only) active fast track 64336dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten sp<RecordTrack> fastTrack; 64341035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent 6435735f45fbc37d7905ffb722f40727edbed82319b7Glenn Kasten // reference to a fast track which is about to be removed 6436735f45fbc37d7905ffb722f40727edbed82319b7Glenn Kasten sp<RecordTrack> fastTrackToRemove; 6437735f45fbc37d7905ffb722f40727edbed82319b7Glenn Kasten 643881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent { // scope for mLock 643981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent Mutex::Autolock _l(mLock); 6440000a4193dd82549192277fd4b9bb571d8a4c262fEric Laurent 6441021cf9634ab09c0753a40b7c9ef4ba603be5c3daEric Laurent processConfigEvents_l(); 6442f10ffec18f930d92e1abe9200d60e746831841a7Glenn Kasten 6443000a4193dd82549192277fd4b9bb571d8a4c262fEric Laurent // check exitPending here because checkForNewParameters_l() and 6444000a4193dd82549192277fd4b9bb571d8a4c262fEric Laurent // checkForNewParameters_l() can temporarily release mLock 6445000a4193dd82549192277fd4b9bb571d8a4c262fEric Laurent if (exitPending()) { 6446000a4193dd82549192277fd4b9bb571d8a4c262fEric Laurent break; 6447000a4193dd82549192277fd4b9bb571d8a4c262fEric Laurent } 6448000a4193dd82549192277fd4b9bb571d8a4c262fEric Laurent 64495c25d5637ef3406883e0fc97a713f9d5cdca426fEric Laurent // sleep with mutex unlocked 64505c25d5637ef3406883e0fc97a713f9d5cdca426fEric Laurent if (sleepUs > 0) { 6451f9715e43ea73361321663514c44129c939c5db2fGlenn Kasten ATRACE_BEGIN("sleepC"); 64525c25d5637ef3406883e0fc97a713f9d5cdca426fEric Laurent mWaitWorkCV.waitRelative(mLock, microseconds((nsecs_t)sleepUs)); 64535c25d5637ef3406883e0fc97a713f9d5cdca426fEric Laurent ATRACE_END(); 64545c25d5637ef3406883e0fc97a713f9d5cdca426fEric Laurent sleepUs = 0; 64555c25d5637ef3406883e0fc97a713f9d5cdca426fEric Laurent continue; 64565c25d5637ef3406883e0fc97a713f9d5cdca426fEric Laurent } 64575c25d5637ef3406883e0fc97a713f9d5cdca426fEric Laurent 64582b806406ac1ec680b6fe3aaa84c54bdc4e43ad8dGlenn Kasten // if no active track(s), then standby and release wakelock 64592b806406ac1ec680b6fe3aaa84c54bdc4e43ad8dGlenn Kasten size_t size = mActiveTracks.size(); 64602b806406ac1ec680b6fe3aaa84c54bdc4e43ad8dGlenn Kasten if (size == 0) { 646193e471f620454f7de73d190521568b1e25879767Glenn Kasten standbyIfNotAlreadyInStandby(); 64624ef0b463a56c19bad9197aa9f90d792090461429Glenn Kasten // exitPending() can't become true here 646381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent releaseWakeLock_l(); 646481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent ALOGV("RecordThread: loop stopping"); 646581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // go to sleep 646681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mWaitWorkCV.wait(mLock); 646781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent ALOGV("RecordThread: loop starting"); 6468f10ffec18f930d92e1abe9200d60e746831841a7Glenn Kasten goto reacquire_wakelock; 6469f10ffec18f930d92e1abe9200d60e746831841a7Glenn Kasten } 6470f10ffec18f930d92e1abe9200d60e746831841a7Glenn Kasten 64716dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten bool doBroadcast = false; 64725c25d5637ef3406883e0fc97a713f9d5cdca426fEric Laurent bool allStopped = true; 64736dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten for (size_t i = 0; i < size; ) { 64749e98235a9e9bb870e1c76911e3b4d00386a52c39Glenn Kasten 64756dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten activeTrack = mActiveTracks[i]; 64766dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten if (activeTrack->isTerminated()) { 6477735f45fbc37d7905ffb722f40727edbed82319b7Glenn Kasten if (activeTrack->isFastTrack()) { 6478735f45fbc37d7905ffb722f40727edbed82319b7Glenn Kasten ALOG_ASSERT(fastTrackToRemove == 0); 6479735f45fbc37d7905ffb722f40727edbed82319b7Glenn Kasten fastTrackToRemove = activeTrack; 6480735f45fbc37d7905ffb722f40727edbed82319b7Glenn Kasten } 64816dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten removeTrack_l(activeTrack); 64822b806406ac1ec680b6fe3aaa84c54bdc4e43ad8dGlenn Kasten mActiveTracks.remove(activeTrack); 64836dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten size--; 64849e98235a9e9bb870e1c76911e3b4d00386a52c39Glenn Kasten continue; 64859e98235a9e9bb870e1c76911e3b4d00386a52c39Glenn Kasten } 64866dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten 64876dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten TrackBase::track_state activeTrackState = activeTrack->mState; 64886dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten switch (activeTrackState) { 64896dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten 64906dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten case TrackBase::PAUSING: 64916dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten mActiveTracks.remove(activeTrack); 64926dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten doBroadcast = true; 64936dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten size--; 64946dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten continue; 64956dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten 64966dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten case TrackBase::STARTING_1: 64976dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten sleepUs = 10000; 64986dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten i++; 64995c25d5637ef3406883e0fc97a713f9d5cdca426fEric Laurent allStopped = false; 65006dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten continue; 65016dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten 65026dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten case TrackBase::STARTING_2: 65036dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten doBroadcast = true; 65046dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten mStandby = false; 65059e98235a9e9bb870e1c76911e3b4d00386a52c39Glenn Kasten activeTrack->mState = TrackBase::ACTIVE; 65065c25d5637ef3406883e0fc97a713f9d5cdca426fEric Laurent allStopped = false; 65076dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten break; 65086dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten 65096dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten case TrackBase::ACTIVE: 65105c25d5637ef3406883e0fc97a713f9d5cdca426fEric Laurent allStopped = false; 65116dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten break; 65126dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten 65136dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten case TrackBase::IDLE: 65146dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten i++; 65156dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten continue; 65166dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten 65176dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten default: 6518adad3d7d935da176ff24941b4ae9edf7340e9b96Glenn Kasten LOG_ALWAYS_FATAL("Unexpected activeTrackState %d", activeTrackState); 65199e98235a9e9bb870e1c76911e3b4d00386a52c39Glenn Kasten } 65202d94426cd3302cb1215c92c5f1c4b90c24ceb72bGlenn Kasten 65216dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten activeTracks.add(activeTrack); 65226dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten i++; 65232d94426cd3302cb1215c92c5f1c4b90c24ceb72bGlenn Kasten 65246dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten if (activeTrack->isFastTrack()) { 65256dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten ALOG_ASSERT(!mFastTrackAvail); 65266dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten ALOG_ASSERT(fastTrack == 0); 65276dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten fastTrack = activeTrack; 65286dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten } 65296dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten } 65305c25d5637ef3406883e0fc97a713f9d5cdca426fEric Laurent 6531dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hung mActiveTracks.updatePowerState(this); 6532dae27707fc7d8370eb200d25d1a7c6dd7ad5e201Andy Hung 6533069c2719e753732d5af9ba51e5fcc34342b0c9f2Kevin Rocard updateMetadata_l(); 6534069c2719e753732d5af9ba51e5fcc34342b0c9f2Kevin Rocard 65355c25d5637ef3406883e0fc97a713f9d5cdca426fEric Laurent if (allStopped) { 65365c25d5637ef3406883e0fc97a713f9d5cdca426fEric Laurent standbyIfNotAlreadyInStandby(); 65375c25d5637ef3406883e0fc97a713f9d5cdca426fEric Laurent } 65386dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten if (doBroadcast) { 65396dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten mStartStopCond.broadcast(); 65406dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten } 6541d9fc34fb0fcfcc739f868b116edf50c62af19d5eGlenn Kasten 65426dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten // sleep if there are no active tracks to process 65436dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten if (activeTracks.size() == 0) { 65446dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten if (sleepUs == 0) { 65456dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten sleepUs = kRecordThreadSleepUs; 65466dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten } 65476dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten continue; 654881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 65496dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten sleepUs = 0; 65509e98235a9e9bb870e1c76911e3b4d00386a52c39Glenn Kasten 655181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent lockEffectChains_l(effectChains); 655281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 655381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 65546dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten // thread mutex is now unlocked, mActiveTracks unknown, activeTracks.size() > 0 65557165268ffa6c7b6b405b6afad82e2a346500e8eeGlenn Kasten 65566dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten size_t size = effectChains.size(); 65576dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten for (size_t i = 0; i < size; i++) { 65581ba19cd7fcdf18ab6efab2a1b831affab9a46157Glenn Kasten // thread mutex is not locked, but effect chain is locked 65591ba19cd7fcdf18ab6efab2a1b831affab9a46157Glenn Kasten effectChains[i]->process_l(); 65601ba19cd7fcdf18ab6efab2a1b831affab9a46157Glenn Kasten } 656181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 6562735f45fbc37d7905ffb722f40727edbed82319b7Glenn Kasten // Push a new fast capture state if fast capture is not already running, or cblk change 65636dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten if (mFastCapture != 0) { 65646dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten FastCaptureStateQueue *sq = mFastCapture->sq(); 65656dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten FastCaptureState *state = sq->begin(); 6566735f45fbc37d7905ffb722f40727edbed82319b7Glenn Kasten bool didModify = false; 6567735f45fbc37d7905ffb722f40727edbed82319b7Glenn Kasten FastCaptureStateQueue::block_t block = FastCaptureStateQueue::BLOCK_UNTIL_PUSHED; 65686dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten if (state->mCommand != FastCaptureState::READ_WRITE /* FIXME && 65696dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten (kUseFastMixer != FastMixer_Dynamic || state->mTrackMask > 1)*/) { 65706dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten if (state->mCommand == FastCaptureState::COLD_IDLE) { 65716dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten int32_t old = android_atomic_inc(&mFastCaptureFutex); 65726dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten if (old == -1) { 65736dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten (void) syscall(__NR_futex, &mFastCaptureFutex, FUTEX_WAKE_PRIVATE, 1); 65746dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten } 65756dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten } 65766dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten state->mCommand = FastCaptureState::READ_WRITE; 65776dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten#if 0 // FIXME 65786dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten mFastCaptureDumpState.increaseSamplingN(mAudioFlinger->isLowRamDevice() ? 6579fbdb2aceab7317aa44bc8f301a93eb49e17b2bceGlenn Kasten FastThreadDumpState::kSamplingNforLowRamDevice : 6580fbdb2aceab7317aa44bc8f301a93eb49e17b2bceGlenn Kasten FastThreadDumpState::kSamplingN); 65816dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten#endif 6582735f45fbc37d7905ffb722f40727edbed82319b7Glenn Kasten didModify = true; 6583735f45fbc37d7905ffb722f40727edbed82319b7Glenn Kasten } 6584735f45fbc37d7905ffb722f40727edbed82319b7Glenn Kasten audio_track_cblk_t *cblkOld = state->mCblk; 6585735f45fbc37d7905ffb722f40727edbed82319b7Glenn Kasten audio_track_cblk_t *cblkNew = fastTrack != 0 ? fastTrack->cblk() : NULL; 6586735f45fbc37d7905ffb722f40727edbed82319b7Glenn Kasten if (cblkNew != cblkOld) { 6587735f45fbc37d7905ffb722f40727edbed82319b7Glenn Kasten state->mCblk = cblkNew; 6588735f45fbc37d7905ffb722f40727edbed82319b7Glenn Kasten // block until acked if removing a fast track 6589735f45fbc37d7905ffb722f40727edbed82319b7Glenn Kasten if (cblkOld != NULL) { 6590735f45fbc37d7905ffb722f40727edbed82319b7Glenn Kasten block = FastCaptureStateQueue::BLOCK_UNTIL_ACKED; 6591735f45fbc37d7905ffb722f40727edbed82319b7Glenn Kasten } 6592735f45fbc37d7905ffb722f40727edbed82319b7Glenn Kasten didModify = true; 6593735f45fbc37d7905ffb722f40727edbed82319b7Glenn Kasten } 6594735f45fbc37d7905ffb722f40727edbed82319b7Glenn Kasten sq->end(didModify); 6595735f45fbc37d7905ffb722f40727edbed82319b7Glenn Kasten if (didModify) { 6596735f45fbc37d7905ffb722f40727edbed82319b7Glenn Kasten sq->push(block); 65976dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten#if 0 65986dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten if (kUseFastCapture == FastCapture_Dynamic) { 65996dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten mNormalSource = mPipeSource; 66006dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten } 66016dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten#endif 66026dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten } 66036dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten } 66046dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten 6605735f45fbc37d7905ffb722f40727edbed82319b7Glenn Kasten // now run the fast track destructor with thread mutex unlocked 6606735f45fbc37d7905ffb722f40727edbed82319b7Glenn Kasten fastTrackToRemove.clear(); 6607735f45fbc37d7905ffb722f40727edbed82319b7Glenn Kasten 66086dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten // Read from HAL to keep up with fastest client if multiple active tracks, not slowest one. 66096dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten // Only the client(s) that are too slow will overrun. But if even the fastest client is too 66106dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten // slow, then this RecordThread will overrun by not calling HAL read often enough. 66116dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten // If destination is non-contiguous, first read past the nominal end of buffer, then 66126dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten // copy to the right place. Permitted because mRsmpInBuffer was over-allocated. 66136dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten 66146dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten int32_t rear = mRsmpInRear & (mRsmpInFramesP2 - 1); 66156dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten ssize_t framesRead; 66166dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten 66176dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten // If an NBAIO source is present, use it to read the normal capture's data 66186dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten if (mPipeSource != 0) { 66196dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten size_t framesToRead = mBufferSize / mFrameSize; 66201b291841a58ce6b2b291232dfdd56134b2185c48Glenn Kasten framesToRead = min(mRsmpInFramesOA - rear, mRsmpInFramesP2 / 2); 6621d5b638fe57c3ceaf7834d4c2181d4c4c2588f967Andy Hung 6622d5b638fe57c3ceaf7834d4c2181d4c4c2588f967Andy Hung // The audio fifo read() returns OVERRUN on overflow, and advances the read pointer 6623d5b638fe57c3ceaf7834d4c2181d4c4c2588f967Andy Hung // to the full buffer point (clearing the overflow condition). Upon OVERRUN error, 6624d5b638fe57c3ceaf7834d4c2181d4c4c2588f967Andy Hung // we immediately retry the read() to get data and prevent another overflow. 6625d5b638fe57c3ceaf7834d4c2181d4c4c2588f967Andy Hung for (int retries = 0; retries <= 2; ++retries) { 6626d5b638fe57c3ceaf7834d4c2181d4c4c2588f967Andy Hung ALOGW_IF(retries > 0, "overrun on read from pipe, retry #%d", retries); 6627d5b638fe57c3ceaf7834d4c2181d4c4c2588f967Andy Hung framesRead = mPipeSource->read((uint8_t*)mRsmpInBuffer + rear * mFrameSize, 6628d5b638fe57c3ceaf7834d4c2181d4c4c2588f967Andy Hung framesToRead); 6629d5b638fe57c3ceaf7834d4c2181d4c4c2588f967Andy Hung if (framesRead != OVERRUN) break; 6630d5b638fe57c3ceaf7834d4c2181d4c4c2588f967Andy Hung } 6631d5b638fe57c3ceaf7834d4c2181d4c4c2588f967Andy Hung 66327a3dc6bd4795a1b254d1ceef959da2b4d6ef8ba4Andy Hung const ssize_t availableToRead = mPipeSource->availableToRead(); 66337a3dc6bd4795a1b254d1ceef959da2b4d6ef8ba4Andy Hung if (availableToRead >= 0) { 66347a3dc6bd4795a1b254d1ceef959da2b4d6ef8ba4Andy Hung // PipeSource is the master clock. It is up to the AudioRecord client to keep up. 66357a3dc6bd4795a1b254d1ceef959da2b4d6ef8ba4Andy Hung LOG_ALWAYS_FATAL_IF((size_t)availableToRead > mPipeFramesP2, 66367a3dc6bd4795a1b254d1ceef959da2b4d6ef8ba4Andy Hung "more frames to read than fifo size, %zd > %zu", 66377a3dc6bd4795a1b254d1ceef959da2b4d6ef8ba4Andy Hung availableToRead, mPipeFramesP2); 66387a3dc6bd4795a1b254d1ceef959da2b4d6ef8ba4Andy Hung const size_t pipeFramesFree = mPipeFramesP2 - availableToRead; 66397a3dc6bd4795a1b254d1ceef959da2b4d6ef8ba4Andy Hung const size_t sleepFrames = min(pipeFramesFree, mRsmpInFramesP2) / 2; 66407a3dc6bd4795a1b254d1ceef959da2b4d6ef8ba4Andy Hung ALOGVV("mPipeFramesP2:%zu mRsmpInFramesP2:%zu sleepFrames:%zu availableToRead:%zd", 66417a3dc6bd4795a1b254d1ceef959da2b4d6ef8ba4Andy Hung mPipeFramesP2, mRsmpInFramesP2, sleepFrames, availableToRead); 66421b291841a58ce6b2b291232dfdd56134b2185c48Glenn Kasten sleepUs = (sleepFrames * 1000000LL) / mSampleRate; 66431b291841a58ce6b2b291232dfdd56134b2185c48Glenn Kasten } 66441b291841a58ce6b2b291232dfdd56134b2185c48Glenn Kasten if (framesRead < 0) { 66451b291841a58ce6b2b291232dfdd56134b2185c48Glenn Kasten status_t status = (status_t) framesRead; 66461b291841a58ce6b2b291232dfdd56134b2185c48Glenn Kasten switch (status) { 66471b291841a58ce6b2b291232dfdd56134b2185c48Glenn Kasten case OVERRUN: 66481b291841a58ce6b2b291232dfdd56134b2185c48Glenn Kasten ALOGW("overrun on read from pipe"); 66491b291841a58ce6b2b291232dfdd56134b2185c48Glenn Kasten framesRead = 0; 66501b291841a58ce6b2b291232dfdd56134b2185c48Glenn Kasten break; 66511b291841a58ce6b2b291232dfdd56134b2185c48Glenn Kasten case NEGOTIATE: 66521b291841a58ce6b2b291232dfdd56134b2185c48Glenn Kasten ALOGE("re-negotiation is needed"); 66531b291841a58ce6b2b291232dfdd56134b2185c48Glenn Kasten framesRead = -1; // Will cause an attempt to recover. 66541b291841a58ce6b2b291232dfdd56134b2185c48Glenn Kasten break; 66551b291841a58ce6b2b291232dfdd56134b2185c48Glenn Kasten default: 66561b291841a58ce6b2b291232dfdd56134b2185c48Glenn Kasten ALOGE("unknown error %d on read from pipe", status); 66571b291841a58ce6b2b291232dfdd56134b2185c48Glenn Kasten break; 66581b291841a58ce6b2b291232dfdd56134b2185c48Glenn Kasten } 66596dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten } 66606dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten // otherwise use the HAL / AudioStreamIn directly 66616dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten } else { 6662ec6a70345fc99cd9f8461749a7656b8240874a62Glenn Kasten ATRACE_BEGIN("read"); 66631dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov size_t bytesRead; 66641dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov status_t result = mInput->stream->read( 66651dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov (uint8_t*)mRsmpInBuffer + rear * mFrameSize, mBufferSize, &bytesRead); 6666ec6a70345fc99cd9f8461749a7656b8240874a62Glenn Kasten ATRACE_END(); 66671dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov if (result < 0) { 66681dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov framesRead = result; 66696dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten } else { 66706dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten framesRead = bytesRead / mFrameSize; 66716dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten } 66726dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten } 66736dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten 66743f0c902beb53a245c9db35e871607dba05b8d391Andy Hung // Update server timestamp with server stats 66753f0c902beb53a245c9db35e871607dba05b8d391Andy Hung // systemTime() is optional if the hardware supports timestamps. 66763f0c902beb53a245c9db35e871607dba05b8d391Andy Hung mTimestamp.mPosition[ExtendedTimestamp::LOCATION_SERVER] += framesRead; 66773f0c902beb53a245c9db35e871607dba05b8d391Andy Hung mTimestamp.mTimeNs[ExtendedTimestamp::LOCATION_SERVER] = systemTime(); 66783f0c902beb53a245c9db35e871607dba05b8d391Andy Hung 66793f0c902beb53a245c9db35e871607dba05b8d391Andy Hung // Update server timestamp with kernel stats 66801dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov if (mPipeSource.get() == nullptr /* don't obtain for FastCapture, could block */) { 66813f0c902beb53a245c9db35e871607dba05b8d391Andy Hung int64_t position, time; 66821dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov int ret = mInput->stream->getCapturePosition(&position, &time); 66833f0c902beb53a245c9db35e871607dba05b8d391Andy Hung if (ret == NO_ERROR) { 66843f0c902beb53a245c9db35e871607dba05b8d391Andy Hung mTimestamp.mPosition[ExtendedTimestamp::LOCATION_KERNEL] = position; 66853f0c902beb53a245c9db35e871607dba05b8d391Andy Hung mTimestamp.mTimeNs[ExtendedTimestamp::LOCATION_KERNEL] = time; 66863f0c902beb53a245c9db35e871607dba05b8d391Andy Hung // Note: In general record buffers should tend to be empty in 66873f0c902beb53a245c9db35e871607dba05b8d391Andy Hung // a properly running pipeline. 66883f0c902beb53a245c9db35e871607dba05b8d391Andy Hung // 66893f0c902beb53a245c9db35e871607dba05b8d391Andy Hung // Also, it is not advantageous to call get_presentation_position during the read 66903f0c902beb53a245c9db35e871607dba05b8d391Andy Hung // as the read obtains a lock, preventing the timestamp call from executing. 66913f0c902beb53a245c9db35e871607dba05b8d391Andy Hung } 66923f0c902beb53a245c9db35e871607dba05b8d391Andy Hung } 66933f0c902beb53a245c9db35e871607dba05b8d391Andy Hung // Use this to track timestamp information 66943f0c902beb53a245c9db35e871607dba05b8d391Andy Hung // ALOGD("%s", mTimestamp.toString().c_str()); 66953f0c902beb53a245c9db35e871607dba05b8d391Andy Hung 66966dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten if (framesRead < 0 || (framesRead == 0 && mPipeSource == 0)) { 6697c42e9b462661673dff480ee71757a58b0f806370Glenn Kasten ALOGE("read failed: framesRead=%zd", framesRead); 66986dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten // Force input into standby so that it tries to recover at next read attempt 66996dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten inputStandBy(); 67006dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten sleepUs = kRecordThreadSleepUs; 67016dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten } 67026dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten if (framesRead <= 0) { 67033d61bc1ffc8afc8d7be3b0d4205c9b5ba6daf2e8Glenn Kasten goto unlock; 67046dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten } 67056dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten ALOG_ASSERT(framesRead > 0); 67066dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten 67076dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten if (mTeeSink != 0) { 67085744661e85981f8a9456bf470e2761235fc026daAndy Hung (void) mTeeSink->write((uint8_t*)mRsmpInBuffer + rear * mFrameSize, framesRead); 67096dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten } 67106dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten // If destination is non-contiguous, we now correct for reading past end of buffer. 67113d61bc1ffc8afc8d7be3b0d4205c9b5ba6daf2e8Glenn Kasten { 67123d61bc1ffc8afc8d7be3b0d4205c9b5ba6daf2e8Glenn Kasten size_t part1 = mRsmpInFramesP2 - rear; 67133d61bc1ffc8afc8d7be3b0d4205c9b5ba6daf2e8Glenn Kasten if ((size_t) framesRead > part1) { 67145744661e85981f8a9456bf470e2761235fc026daAndy Hung memcpy(mRsmpInBuffer, (uint8_t*)mRsmpInBuffer + mRsmpInFramesP2 * mFrameSize, 67153d61bc1ffc8afc8d7be3b0d4205c9b5ba6daf2e8Glenn Kasten (framesRead - part1) * mFrameSize); 67163d61bc1ffc8afc8d7be3b0d4205c9b5ba6daf2e8Glenn Kasten } 67176dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten } 67186dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten rear = mRsmpInRear += framesRead; 67196dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten 67206dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten size = activeTracks.size(); 6721f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov 67226dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten // loop over each active track 67236dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten for (size_t i = 0; i < size; i++) { 67246dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten activeTrack = activeTracks[i]; 67256dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten 67266dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten // skip fast tracks, as those are handled directly by FastCapture 67276dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten if (activeTrack->isFastTrack()) { 67286dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten continue; 67296dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten } 67306dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten 673173c02e4277b399c2ec1555d32b6ad5df23bb83dcAndy Hung // TODO: This code probably should be moved to RecordTrack. 673297a893eb34f8687485c88eaf15917974a203f20bAndy Hung // TODO: Update the activeTrack buffer converter in case of reconfigure. 673397a893eb34f8687485c88eaf15917974a203f20bAndy Hung 67346dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten enum { 67356dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten OVERRUN_UNKNOWN, 67366dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten OVERRUN_TRUE, 67376dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten OVERRUN_FALSE 67386dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten } overrun = OVERRUN_UNKNOWN; 67396dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten 67406dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten // loop over getNextBuffer to handle circular sink 67416dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten for (;;) { 67426dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten 67436dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten activeTrack->mSink.frameCount = ~0; 67446dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten status_t status = activeTrack->getNextBuffer(&activeTrack->mSink); 67456dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten size_t framesOut = activeTrack->mSink.frameCount; 67466dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten LOG_ALWAYS_FATAL_IF((status == OK) != (framesOut > 0)); 67476dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten 674873c02e4277b399c2ec1555d32b6ad5df23bb83dcAndy Hung // check available frames and handle overrun conditions 674973c02e4277b399c2ec1555d32b6ad5df23bb83dcAndy Hung // if the record track isn't draining fast enough. 675073c02e4277b399c2ec1555d32b6ad5df23bb83dcAndy Hung bool hasOverrun; 67516dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten size_t framesIn; 675273c02e4277b399c2ec1555d32b6ad5df23bb83dcAndy Hung activeTrack->mResamplerBufferProvider->sync(&framesIn, &hasOverrun); 675373c02e4277b399c2ec1555d32b6ad5df23bb83dcAndy Hung if (hasOverrun) { 67546dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten overrun = OVERRUN_TRUE; 67556dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten } 67564cc0a6a835c806d200ef83ef31fe5bef327c355cGlenn Kasten if (framesOut == 0 || framesIn == 0) { 67574cc0a6a835c806d200ef83ef31fe5bef327c355cGlenn Kasten break; 67584cc0a6a835c806d200ef83ef31fe5bef327c355cGlenn Kasten } 67594cc0a6a835c806d200ef83ef31fe5bef327c355cGlenn Kasten 67606770c6faa3467c92eabc5ec9b23d60eb556a0d03Andy Hung // Don't allow framesOut to be larger than what is possible with resampling 67616770c6faa3467c92eabc5ec9b23d60eb556a0d03Andy Hung // from framesIn. 67626770c6faa3467c92eabc5ec9b23d60eb556a0d03Andy Hung // This isn't strictly necessary but helps limit buffer resizing in 67636770c6faa3467c92eabc5ec9b23d60eb556a0d03Andy Hung // RecordBufferConverter. TODO: remove when no longer needed. 67646770c6faa3467c92eabc5ec9b23d60eb556a0d03Andy Hung framesOut = min(framesOut, 67656770c6faa3467c92eabc5ec9b23d60eb556a0d03Andy Hung destinationFramesPossible( 67666770c6faa3467c92eabc5ec9b23d60eb556a0d03Andy Hung framesIn, mSampleRate, activeTrack->mSampleRate)); 676797a893eb34f8687485c88eaf15917974a203f20bAndy Hung // process frames from the RecordThread buffer provider to the RecordTrack buffer 676897a893eb34f8687485c88eaf15917974a203f20bAndy Hung framesOut = activeTrack->mRecordBufferConverter->convert( 676997a893eb34f8687485c88eaf15917974a203f20bAndy Hung activeTrack->mSink.raw, activeTrack->mResamplerBufferProvider, framesOut); 67708594843c15b4722ced39436fe9e64f3e57e7ace4Glenn Kasten 67716dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten if (framesOut > 0 && (overrun == OVERRUN_UNKNOWN)) { 67726dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten overrun = OVERRUN_FALSE; 67731ba19cd7fcdf18ab6efab2a1b831affab9a46157Glenn Kasten } 677481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 67756dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten if (activeTrack->mFramesToDrop == 0) { 67766dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten if (framesOut > 0) { 67776dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten activeTrack->mSink.frameCount = framesOut; 6778f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov // Sanitize before releasing if the track has no access to the source data 6779f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov // An idle UID receives silence from non virtual devices until active 6780f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov if (activeTrack->isSilenced()) { 6781f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov memset(activeTrack->mSink.raw, 0, framesOut * mFrameSize); 6782f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov } 67836dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten activeTrack->releaseBuffer(&activeTrack->mSink); 678481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 678581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } else { 67866dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten // FIXME could do a partial drop of framesOut 67876dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten if (activeTrack->mFramesToDrop > 0) { 67886dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten activeTrack->mFramesToDrop -= framesOut; 67896dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten if (activeTrack->mFramesToDrop <= 0) { 679025f4aa83efaa9179e65a20583a6d441de2c3ff3fGlenn Kasten activeTrack->clearSyncStartEvent(); 67916dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten } 67926dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten } else { 67936dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten activeTrack->mFramesToDrop += framesOut; 67946dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten if (activeTrack->mFramesToDrop >= 0 || activeTrack->mSyncStartEvent == 0 || 67956dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten activeTrack->mSyncStartEvent->isCancelled()) { 67966dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten ALOGW("Synced record %s, session %d, trigger session %d", 67976dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten (activeTrack->mFramesToDrop >= 0) ? "timed out" : "cancelled", 67986dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten activeTrack->sessionId(), 67996dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten (activeTrack->mSyncStartEvent != 0) ? 6800d848eb48c121c119e8ba7583efc75415fe102570Glenn Kasten activeTrack->mSyncStartEvent->triggerSession() : 6801d848eb48c121c119e8ba7583efc75415fe102570Glenn Kasten AUDIO_SESSION_NONE); 680225f4aa83efaa9179e65a20583a6d441de2c3ff3fGlenn Kasten activeTrack->clearSyncStartEvent(); 68036dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten } 680481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 680581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 68066dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten 68076dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten if (framesOut == 0) { 68086dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten break; 68096dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten } 681081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 68116dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten 68126dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten switch (overrun) { 68136dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten case OVERRUN_TRUE: 68146dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten // client isn't retrieving buffers fast enough 68156dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten if (!activeTrack->setOverflow()) { 68166dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten nsecs_t now = systemTime(); 68176dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten // FIXME should lastWarning per track? 68186dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten if ((now - lastWarning) > kWarningThrottleNs) { 68196dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten ALOGW("RecordThread: buffer overflow"); 68206dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten lastWarning = now; 68216dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten } 682281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 68236dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten break; 68246dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten case OVERRUN_FALSE: 68256dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten activeTrack->clearOverflow(); 68266dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten break; 68276dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten case OVERRUN_UNKNOWN: 68286dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten break; 682981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 68306dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten 68313f0c902beb53a245c9db35e871607dba05b8d391Andy Hung // update frame information and push timestamp out 68323f0c902beb53a245c9db35e871607dba05b8d391Andy Hung activeTrack->updateTrackFrameInfo( 68336ae5843c281301a9ffd1059d185620a9337e15a2Andy Hung activeTrack->mServerProxy->framesReleased(), 68343f0c902beb53a245c9db35e871607dba05b8d391Andy Hung mTimestamp.mPosition[ExtendedTimestamp::LOCATION_SERVER], 68353f0c902beb53a245c9db35e871607dba05b8d391Andy Hung mSampleRate, mTimestamp); 683681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 68371ba19cd7fcdf18ab6efab2a1b831affab9a46157Glenn Kasten 68383d61bc1ffc8afc8d7be3b0d4205c9b5ba6daf2e8Glenn Kastenunlock: 683981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // enable changes in effect chain 684081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent unlockEffectChains(effectChains); 6841c527a7c2b1bfd26e8f3086e1b653d56e521379d9Glenn Kasten // effectChains doesn't need to be cleared, since it is cleared by destructor at scope end 684281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 684381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 684493e471f620454f7de73d190521568b1e25879767Glenn Kasten standbyIfNotAlreadyInStandby(); 684581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 684681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent { 684781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent Mutex::Autolock _l(mLock); 68489a54bc27876acd5d8be5b1fc3dc46701fe76fbb3Eric Laurent for (size_t i = 0; i < mTracks.size(); i++) { 68499a54bc27876acd5d8be5b1fc3dc46701fe76fbb3Eric Laurent sp<RecordTrack> track = mTracks[i]; 68509a54bc27876acd5d8be5b1fc3dc46701fe76fbb3Eric Laurent track->invalidate(); 68519a54bc27876acd5d8be5b1fc3dc46701fe76fbb3Eric Laurent } 68522b806406ac1ec680b6fe3aaa84c54bdc4e43ad8dGlenn Kasten mActiveTracks.clear(); 685381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mStartStopCond.broadcast(); 685481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 685581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 685681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent releaseWakeLock(); 685781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 685881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent ALOGV("RecordThread %p exiting", this); 685981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent return false; 686081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 686181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 686293e471f620454f7de73d190521568b1e25879767Glenn Kastenvoid AudioFlinger::RecordThread::standbyIfNotAlreadyInStandby() 686381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 686481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (!mStandby) { 686581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent inputStandBy(); 686681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mStandby = true; 686781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 686881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 686981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 687081784c37c61b09289654b979567a42bf73cd2b12Eric Laurentvoid AudioFlinger::RecordThread::inputStandBy() 687181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 68726dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten // Idle the fast capture if it's currently running 68736dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten if (mFastCapture != 0) { 68746dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten FastCaptureStateQueue *sq = mFastCapture->sq(); 68756dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten FastCaptureState *state = sq->begin(); 68766dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten if (!(state->mCommand & FastCaptureState::IDLE)) { 68776dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten state->mCommand = FastCaptureState::COLD_IDLE; 68786dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten state->mColdFutexAddr = &mFastCaptureFutex; 68796dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten state->mColdGen++; 68806dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten mFastCaptureFutex = 0; 68816dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten sq->end(); 68826dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten // BLOCK_UNTIL_PUSHED would be insufficient, as we need it to stop doing I/O now 68836dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten sq->push(FastCaptureStateQueue::BLOCK_UNTIL_ACKED); 68846dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten#if 0 68856dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten if (kUseFastCapture == FastCapture_Dynamic) { 68866dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten // FIXME 68876dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten } 68886dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten#endif 68896dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten#ifdef AUDIO_WATCHDOG 68906dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten // FIXME 68916dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten#endif 68926dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten } else { 68936dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten sq->end(false /*didModify*/); 68946dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten } 68956dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten } 68961dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov status_t result = mInput->stream->standby(); 68971dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov ALOGE_IF(result != OK, "Error when putting input stream into standby: %d", result); 6898ad6d52d38917069e3d8e68cec1625855b9d96200Andy Hung 6899ad6d52d38917069e3d8e68cec1625855b9d96200Andy Hung // If going into standby, flush the pipe source. 6900ad6d52d38917069e3d8e68cec1625855b9d96200Andy Hung if (mPipeSource.get() != nullptr) { 6901ad6d52d38917069e3d8e68cec1625855b9d96200Andy Hung const ssize_t flushed = mPipeSource->flush(); 6902ad6d52d38917069e3d8e68cec1625855b9d96200Andy Hung if (flushed > 0) { 6903ad6d52d38917069e3d8e68cec1625855b9d96200Andy Hung ALOGV("Input standby flushed PipeSource %zd frames", flushed); 6904ad6d52d38917069e3d8e68cec1625855b9d96200Andy Hung mTimestamp.mPosition[ExtendedTimestamp::LOCATION_SERVER] += flushed; 6905ad6d52d38917069e3d8e68cec1625855b9d96200Andy Hung mTimestamp.mTimeNs[ExtendedTimestamp::LOCATION_SERVER] = systemTime(); 6906ad6d52d38917069e3d8e68cec1625855b9d96200Andy Hung } 6907ad6d52d38917069e3d8e68cec1625855b9d96200Andy Hung } 690881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 690981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 691005997e21af6c4517f375def6563af4b9ebe95f39Glenn Kasten// RecordThread::createRecordTrack_l() must be called with AudioFlinger::mLock held 6911e198c360d5e75a9b2097844c495c10902e7e8500Glenn Kastensp<AudioFlinger::RecordThread::RecordTrack> AudioFlinger::RecordThread::createRecordTrack_l( 691281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent const sp<AudioFlinger::Client>& client, 69131f564acca544826daaf7dca44e39cec6016b82fdKevin Rocard const audio_attributes_t& attr, 6914f14db3c3ebc1ea29b3eb5b7e9b944cabcb5f83ffEric Laurent uint32_t *pSampleRate, 691581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent audio_format_t format, 691681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent audio_channel_mask_t channelMask, 691774935e44734c1ec235c2b6677db3e0dbefa5ddb8Glenn Kasten size_t *pFrameCount, 6918d848eb48c121c119e8ba7583efc75415fe102570Glenn Kasten audio_session_t sessionId, 6919f14db3c3ebc1ea29b3eb5b7e9b944cabcb5f83ffEric Laurent size_t *pNotificationFrameCount, 69201f12a8ad958344c50733b948628ffa06db9c5bc6Andy Hung uid_t uid, 6921050677873c10d4da308ac222f8533c96cca3207eEric Laurent audio_input_flags_t *flags, 692281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent pid_t tid, 692320b9ef0b55c9150ae11057ab997ae61be2d496efEric Laurent status_t *status, 692420b9ef0b55c9150ae11057ab997ae61be2d496efEric Laurent audio_port_handle_t portId) 692581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 692674935e44734c1ec235c2b6677db3e0dbefa5ddb8Glenn Kasten size_t frameCount = *pFrameCount; 6927f14db3c3ebc1ea29b3eb5b7e9b944cabcb5f83ffEric Laurent size_t notificationFrameCount = *pNotificationFrameCount; 692881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent sp<RecordTrack> track; 692981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent status_t lStatus; 6930050677873c10d4da308ac222f8533c96cca3207eEric Laurent audio_input_flags_t inputFlags = mInput->flags; 6931f14db3c3ebc1ea29b3eb5b7e9b944cabcb5f83ffEric Laurent audio_input_flags_t requestedFlags = *flags; 6932f14db3c3ebc1ea29b3eb5b7e9b944cabcb5f83ffEric Laurent uint32_t sampleRate; 6933f14db3c3ebc1ea29b3eb5b7e9b944cabcb5f83ffEric Laurent 6934f14db3c3ebc1ea29b3eb5b7e9b944cabcb5f83ffEric Laurent lStatus = initCheck(); 6935f14db3c3ebc1ea29b3eb5b7e9b944cabcb5f83ffEric Laurent if (lStatus != NO_ERROR) { 6936f14db3c3ebc1ea29b3eb5b7e9b944cabcb5f83ffEric Laurent ALOGE("createRecordTrack_l() audio driver not initialized"); 6937f14db3c3ebc1ea29b3eb5b7e9b944cabcb5f83ffEric Laurent goto Exit; 6938f14db3c3ebc1ea29b3eb5b7e9b944cabcb5f83ffEric Laurent } 6939f14db3c3ebc1ea29b3eb5b7e9b944cabcb5f83ffEric Laurent 6940f14db3c3ebc1ea29b3eb5b7e9b944cabcb5f83ffEric Laurent if (*pSampleRate == 0) { 6941f14db3c3ebc1ea29b3eb5b7e9b944cabcb5f83ffEric Laurent *pSampleRate = mSampleRate; 6942f14db3c3ebc1ea29b3eb5b7e9b944cabcb5f83ffEric Laurent } 6943f14db3c3ebc1ea29b3eb5b7e9b944cabcb5f83ffEric Laurent sampleRate = *pSampleRate; 6944050677873c10d4da308ac222f8533c96cca3207eEric Laurent 6945050677873c10d4da308ac222f8533c96cca3207eEric Laurent // special case for FAST flag considered OK if fast capture is present 6946050677873c10d4da308ac222f8533c96cca3207eEric Laurent if (hasFastCapture()) { 6947050677873c10d4da308ac222f8533c96cca3207eEric Laurent inputFlags = (audio_input_flags_t)(inputFlags | AUDIO_INPUT_FLAG_FAST); 6948050677873c10d4da308ac222f8533c96cca3207eEric Laurent } 6949050677873c10d4da308ac222f8533c96cca3207eEric Laurent 6950f14db3c3ebc1ea29b3eb5b7e9b944cabcb5f83ffEric Laurent // Check if requested flags are compatible with input stream flags 6951050677873c10d4da308ac222f8533c96cca3207eEric Laurent if ((*flags & inputFlags) != *flags) { 6952050677873c10d4da308ac222f8533c96cca3207eEric Laurent ALOGW("createRecordTrack_l(): mismatch between requested flags (%08x) and" 6953050677873c10d4da308ac222f8533c96cca3207eEric Laurent " input flags (%08x)", 6954050677873c10d4da308ac222f8533c96cca3207eEric Laurent *flags, inputFlags); 6955050677873c10d4da308ac222f8533c96cca3207eEric Laurent *flags = (audio_input_flags_t)(*flags & inputFlags); 6956050677873c10d4da308ac222f8533c96cca3207eEric Laurent } 695781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 695890e58b1fefc8caf70b34301a92bc86179580b6fcGlenn Kasten // client expresses a preference for FAST, but we get the final say 6959050677873c10d4da308ac222f8533c96cca3207eEric Laurent if (*flags & AUDIO_INPUT_FLAG_FAST) { 696090e58b1fefc8caf70b34301a92bc86179580b6fcGlenn Kasten if ( 6961b7fbf7ecc6b034243ec64f79f3113675b5e3c941Glenn Kasten // we formerly checked for a callback handler (non-0 tid), 6962b7fbf7ecc6b034243ec64f79f3113675b5e3c941Glenn Kasten // but that is no longer required for TRANSFER_OBTAIN mode 6963b7fbf7ecc6b034243ec64f79f3113675b5e3c941Glenn Kasten // 69647410591dad836434c72ddee66680802708b70c10Glenn Kasten // frame count is not specified, or is exactly the pipe depth 69657410591dad836434c72ddee66680802708b70c10Glenn Kasten ((frameCount == 0) || (frameCount == mPipeFramesP2)) && 69663a6c90aa0617666d9abc94c02b752d9eb3d64772Glenn Kasten // PCM data 69673a6c90aa0617666d9abc94c02b752d9eb3d64772Glenn Kasten audio_is_linear_pcm(format) && 69687fd0422fbd17af3b24eb04421d37fce50f3826e2Glenn Kasten // hardware format 69696dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten (format == mFormat) && 69707fd0422fbd17af3b24eb04421d37fce50f3826e2Glenn Kasten // hardware channel mask 69716dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten (channelMask == mChannelMask) && 69727fd0422fbd17af3b24eb04421d37fce50f3826e2Glenn Kasten // hardware sample rate 697390e58b1fefc8caf70b34301a92bc86179580b6fcGlenn Kasten (sampleRate == mSampleRate) && 69743a6c90aa0617666d9abc94c02b752d9eb3d64772Glenn Kasten // record thread has an associated fast capture 69756dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten hasFastCapture() && 69766dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten // there are sufficient fast track slots available 69776dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten mFastTrackAvail 697890e58b1fefc8caf70b34301a92bc86179580b6fcGlenn Kasten ) { 69794c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent // check compatibility with audio effects. 69804c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent Mutex::Autolock _l(mLock); 69814c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent // Do not accept FAST flag if the session has software effects 69824c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent sp<EffectChain> chain = getEffectChain_l(sessionId); 69834c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent if (chain != 0) { 6984d3bb0adfe40e60bb94e9a87e8d5bffb4ea6863b0Andy Hung audio_input_flags_t old = *flags; 6985d3bb0adfe40e60bb94e9a87e8d5bffb4ea6863b0Andy Hung chain->checkInputFlagCompatibility(flags); 6986d3bb0adfe40e60bb94e9a87e8d5bffb4ea6863b0Andy Hung if (old != *flags) { 6987b3cf7e656db20c65c0d7c779640db7f5f2a52bafMikhail Naganov ALOGV("%p AUDIO_INPUT_FLAGS denied by effect old=%#x new=%#x", 6988b3cf7e656db20c65c0d7c779640db7f5f2a52bafMikhail Naganov this, (int)old, (int)*flags); 69894c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent } 69904c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent } 6991122f7e793fe6fb8904634cc6d2e35ac4b014ea72Eric Laurent ALOGV_IF((*flags & AUDIO_INPUT_FLAG_FAST) != 0, 6992b3cf7e656db20c65c0d7c779640db7f5f2a52bafMikhail Naganov "%p AUDIO_INPUT_FLAG_FAST accepted: frameCount=%zu mFrameCount=%zu", 6993b3cf7e656db20c65c0d7c779640db7f5f2a52bafMikhail Naganov this, frameCount, mFrameCount); 699490e58b1fefc8caf70b34301a92bc86179580b6fcGlenn Kasten } else { 6995b3cf7e656db20c65c0d7c779640db7f5f2a52bafMikhail Naganov ALOGV("%p AUDIO_INPUT_FLAG_FAST denied: frameCount=%zu mFrameCount=%zu mPipeFramesP2=%zu " 6996b3cf7e656db20c65c0d7c779640db7f5f2a52bafMikhail Naganov "format=%#x isLinear=%d mFormat=%#x channelMask=%#x sampleRate=%u mSampleRate=%u " 69976dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten "hasFastCapture=%d tid=%d mFastTrackAvail=%d", 6998b3cf7e656db20c65c0d7c779640db7f5f2a52bafMikhail Naganov this, frameCount, mFrameCount, mPipeFramesP2, 6999b3cf7e656db20c65c0d7c779640db7f5f2a52bafMikhail Naganov format, audio_is_linear_pcm(format), mFormat, channelMask, sampleRate, mSampleRate, 70007410591dad836434c72ddee66680802708b70c10Glenn Kasten hasFastCapture(), tid, mFastTrackAvail); 7001050677873c10d4da308ac222f8533c96cca3207eEric Laurent *flags = (audio_input_flags_t)(*flags & ~AUDIO_INPUT_FLAG_FAST); 70027410591dad836434c72ddee66680802708b70c10Glenn Kasten } 70037410591dad836434c72ddee66680802708b70c10Glenn Kasten } 70047410591dad836434c72ddee66680802708b70c10Glenn Kasten 7005f14db3c3ebc1ea29b3eb5b7e9b944cabcb5f83ffEric Laurent // If FAST or RAW flags were corrected, ask caller to request new input from audio policy 7006f14db3c3ebc1ea29b3eb5b7e9b944cabcb5f83ffEric Laurent if ((*flags & AUDIO_INPUT_FLAG_FAST) != 7007f14db3c3ebc1ea29b3eb5b7e9b944cabcb5f83ffEric Laurent (requestedFlags & AUDIO_INPUT_FLAG_FAST)) { 7008f14db3c3ebc1ea29b3eb5b7e9b944cabcb5f83ffEric Laurent *flags = (audio_input_flags_t) (*flags & ~(AUDIO_INPUT_FLAG_FAST | AUDIO_INPUT_FLAG_RAW)); 7009f14db3c3ebc1ea29b3eb5b7e9b944cabcb5f83ffEric Laurent lStatus = BAD_TYPE; 7010f14db3c3ebc1ea29b3eb5b7e9b944cabcb5f83ffEric Laurent goto Exit; 7011f14db3c3ebc1ea29b3eb5b7e9b944cabcb5f83ffEric Laurent } 7012f14db3c3ebc1ea29b3eb5b7e9b944cabcb5f83ffEric Laurent 70137410591dad836434c72ddee66680802708b70c10Glenn Kasten // compute track buffer size in frames, and suggest the notification frame count 7014050677873c10d4da308ac222f8533c96cca3207eEric Laurent if (*flags & AUDIO_INPUT_FLAG_FAST) { 70157410591dad836434c72ddee66680802708b70c10Glenn Kasten // fast track: frame count is exactly the pipe depth 70167410591dad836434c72ddee66680802708b70c10Glenn Kasten frameCount = mPipeFramesP2; 70177410591dad836434c72ddee66680802708b70c10Glenn Kasten // ignore requested notificationFrames, and always notify exactly once every HAL buffer 7018f14db3c3ebc1ea29b3eb5b7e9b944cabcb5f83ffEric Laurent notificationFrameCount = mFrameCount; 70197410591dad836434c72ddee66680802708b70c10Glenn Kasten } else { 702049d00ad9164ea5ce48c85765a2b6460d9b457d38Glenn Kasten // not fast track: max notification period is resampled equivalent of one HAL buffer time 702149d00ad9164ea5ce48c85765a2b6460d9b457d38Glenn Kasten // or 20 ms if there is a fast capture 702249d00ad9164ea5ce48c85765a2b6460d9b457d38Glenn Kasten // TODO This could be a roundupRatio inline, and const 702349d00ad9164ea5ce48c85765a2b6460d9b457d38Glenn Kasten size_t maxNotificationFrames = ((int64_t) (hasFastCapture() ? mSampleRate/50 : mFrameCount) 702449d00ad9164ea5ce48c85765a2b6460d9b457d38Glenn Kasten * sampleRate + mSampleRate - 1) / mSampleRate; 702549d00ad9164ea5ce48c85765a2b6460d9b457d38Glenn Kasten // minimum number of notification periods is at least kMinNotifications, 702649d00ad9164ea5ce48c85765a2b6460d9b457d38Glenn Kasten // and at least kMinMs rounded up to a whole notification period (minNotificationsByMs) 702749d00ad9164ea5ce48c85765a2b6460d9b457d38Glenn Kasten static const size_t kMinNotifications = 3; 702849d00ad9164ea5ce48c85765a2b6460d9b457d38Glenn Kasten static const uint32_t kMinMs = 30; 702949d00ad9164ea5ce48c85765a2b6460d9b457d38Glenn Kasten // TODO This could be a roundupRatio inline 703049d00ad9164ea5ce48c85765a2b6460d9b457d38Glenn Kasten const size_t minFramesByMs = (sampleRate * kMinMs + 1000 - 1) / 1000; 703149d00ad9164ea5ce48c85765a2b6460d9b457d38Glenn Kasten // TODO This could be a roundupRatio inline 703249d00ad9164ea5ce48c85765a2b6460d9b457d38Glenn Kasten const size_t minNotificationsByMs = (minFramesByMs + maxNotificationFrames - 1) / 703349d00ad9164ea5ce48c85765a2b6460d9b457d38Glenn Kasten maxNotificationFrames; 703449d00ad9164ea5ce48c85765a2b6460d9b457d38Glenn Kasten const size_t minFrameCount = maxNotificationFrames * 703549d00ad9164ea5ce48c85765a2b6460d9b457d38Glenn Kasten max(kMinNotifications, minNotificationsByMs); 703649d00ad9164ea5ce48c85765a2b6460d9b457d38Glenn Kasten frameCount = max(frameCount, minFrameCount); 7037f14db3c3ebc1ea29b3eb5b7e9b944cabcb5f83ffEric Laurent if (notificationFrameCount == 0 || notificationFrameCount > maxNotificationFrames) { 7038f14db3c3ebc1ea29b3eb5b7e9b944cabcb5f83ffEric Laurent notificationFrameCount = maxNotificationFrames; 70397410591dad836434c72ddee66680802708b70c10Glenn Kasten } 704090e58b1fefc8caf70b34301a92bc86179580b6fcGlenn Kasten } 704174935e44734c1ec235c2b6677db3e0dbefa5ddb8Glenn Kasten *pFrameCount = frameCount; 7042f14db3c3ebc1ea29b3eb5b7e9b944cabcb5f83ffEric Laurent *pNotificationFrameCount = notificationFrameCount; 704381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 704481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent { // scope for mLock 704581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent Mutex::Autolock _l(mLock); 704681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 70471f564acca544826daaf7dca44e39cec6016b82fdKevin Rocard track = new RecordTrack(this, client, attr, sampleRate, 70488fe68036c2a670abb9eb0cc67ab9830c2c23de81Andy Hung format, channelMask, frameCount, 70498fe68036c2a670abb9eb0cc67ab9830c2c23de81Andy Hung nullptr /* buffer */, (size_t)0 /* bufferSize */, sessionId, uid, 705020b9ef0b55c9150ae11057ab997ae61be2d496efEric Laurent *flags, TrackBase::TYPE_DEFAULT, portId); 705181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 7052030033342a6ea17003e6af38a56c7edc6d2ead01Glenn Kasten lStatus = track->initCheck(); 7053030033342a6ea17003e6af38a56c7edc6d2ead01Glenn Kasten if (lStatus != NO_ERROR) { 705435295078ab59c8c5d143a54d5a55557c3ca62c51Glenn Kasten ALOGE("createRecordTrack_l() initCheck failed %d; no control block?", lStatus); 705503e9e83c47ab4a518da0a1f36b8f702f59221c95Haynes Mathew George // track must be cleared from the caller as the caller has the AF lock 705681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent goto Exit; 705781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 705881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mTracks.add(track); 705981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 7060050677873c10d4da308ac222f8533c96cca3207eEric Laurent if ((*flags & AUDIO_INPUT_FLAG_FAST) && (tid != -1)) { 706190e58b1fefc8caf70b34301a92bc86179580b6fcGlenn Kasten pid_t callingPid = IPCThreadState::self()->getCallingPid(); 706290e58b1fefc8caf70b34301a92bc86179580b6fcGlenn Kasten // we don't have CAP_SYS_NICE, nor do we want to have it as it's too powerful, 706390e58b1fefc8caf70b34301a92bc86179580b6fcGlenn Kasten // so ask activity manager to do this on our behalf 7064af9a7b52b2273ea5c2b30350bdd0fce39a8b16d2Glenn Kasten sendPrioConfigEvent_l(callingPid, tid, kPriorityAudioApp, true /*forApp*/); 706590e58b1fefc8caf70b34301a92bc86179580b6fcGlenn Kasten } 706681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 706705997e21af6c4517f375def6563af4b9ebe95f39Glenn Kasten 706881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent lStatus = NO_ERROR; 706981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 707081784c37c61b09289654b979567a42bf73cd2b12Eric LaurentExit: 70719156ef3e11b68cc4b6d3cea77f1f63673855a6d1Glenn Kasten *status = lStatus; 707281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent return track; 707381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 707481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 707581784c37c61b09289654b979567a42bf73cd2b12Eric Laurentstatus_t AudioFlinger::RecordThread::start(RecordThread::RecordTrack* recordTrack, 707681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent AudioSystem::sync_event_t event, 7077d848eb48c121c119e8ba7583efc75415fe102570Glenn Kasten audio_session_t triggerSession) 707881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 707981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent ALOGV("RecordThread::start event %d, triggerSession %d", event, triggerSession); 708081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent sp<ThreadBase> strongMe = this; 708181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent status_t status = NO_ERROR; 708281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 708381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (event == AudioSystem::SYNC_EVENT_NONE) { 708425f4aa83efaa9179e65a20583a6d441de2c3ff3fGlenn Kasten recordTrack->clearSyncStartEvent(); 708581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } else if (event != AudioSystem::SYNC_EVENT_SAME) { 70866dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten recordTrack->mSyncStartEvent = mAudioFlinger->createSyncEvent(event, 708781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent triggerSession, 708881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent recordTrack->sessionId(), 708981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent syncStartEventCallback, 70906dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten recordTrack); 709181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // Sync event can be cancelled by the trigger session if the track is not in a 709281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // compatible state in which case we start record immediately 70936dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten if (recordTrack->mSyncStartEvent->isCancelled()) { 709425f4aa83efaa9179e65a20583a6d441de2c3ff3fGlenn Kasten recordTrack->clearSyncStartEvent(); 709581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } else { 709681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // do not wait for the event for more than AudioSystem::kSyncRecordStartTimeOutMs 70971b35dd6ec11bfb96fd946d6d2ec18e6938bfa090Ivan Lozano recordTrack->mFramesToDrop = -(ssize_t) 70984cc0a6a835c806d200ef83ef31fe5bef327c355cGlenn Kasten ((AudioSystem::kSyncRecordStartTimeOutMs * recordTrack->mSampleRate) / 1000); 709981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 710081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 710181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 710281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent { 710347c2070b2ce8aedb7300c0aad91caccf3c383841Glenn Kasten // This section is a rendezvous between binder thread executing start() and RecordThread 710481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent AutoMutex lock(mLock); 71056dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten if (mActiveTracks.indexOf(recordTrack) >= 0) { 71066dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten if (recordTrack->mState == TrackBase::PAUSING) { 71076dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten ALOGV("active record track PAUSING -> ACTIVE"); 7108f10ffec18f930d92e1abe9200d60e746831841a7Glenn Kasten recordTrack->mState = TrackBase::ACTIVE; 71096dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten } else { 71106dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten ALOGV("active record track state %d", recordTrack->mState); 711181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 711281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent return status; 711381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 711481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 71154cc0a6a835c806d200ef83ef31fe5bef327c355cGlenn Kasten // TODO consider other ways of handling this, such as changing the state to :STARTING and 71164cc0a6a835c806d200ef83ef31fe5bef327c355cGlenn Kasten // adding the track to mActiveTracks after returning from AudioSystem::startInput(), 71174cc0a6a835c806d200ef83ef31fe5bef327c355cGlenn Kasten // or using a separate command thread 71186dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten recordTrack->mState = TrackBase::STARTING_1; 71192b806406ac1ec680b6fe3aaa84c54bdc4e43ad8dGlenn Kasten mActiveTracks.add(recordTrack); 712083b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent status_t status = NO_ERROR; 712183b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent if (recordTrack->isExternalTrack()) { 712283b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent mLock.unlock(); 7123f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov bool silenced; 7124fee1976a2849c37a53d8a01ac10327d522a1ba93Eric Laurent status = AudioSystem::startInput(recordTrack->portId(), &silenced); 712583b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent mLock.lock(); 712683b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent // FIXME should verify that recordTrack is still in mActiveTracks 712783b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent if (status != NO_ERROR) { 712883b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent mActiveTracks.remove(recordTrack); 712983b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent recordTrack->clearSyncStartEvent(); 713083b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent ALOGV("RecordThread::start error %d", status); 713183b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent return status; 713283b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent } 7133f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov recordTrack->setSilenced(silenced); 713481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 71356dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten // Catch up with current buffer indices if thread is already running. 71366dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten // This is what makes a new client discard all buffered data. If the track's mRsmpInFront 71376dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten // was initialized to some value closer to the thread's mRsmpInFront, then the track could 71386dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten // see previously buffered data before it called start(), but with greater risk of overrun. 71396dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten 714073c02e4277b399c2ec1555d32b6ad5df23bb83dcAndy Hung recordTrack->mResamplerBufferProvider->reset(); 714197a893eb34f8687485c88eaf15917974a203f20bAndy Hung // clear any converter state as new data will be discontinuous 714297a893eb34f8687485c88eaf15917974a203f20bAndy Hung recordTrack->mRecordBufferConverter->reset(); 71436dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten recordTrack->mState = TrackBase::STARTING_2; 714481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // signal thread to start 714581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mWaitWorkCV.broadcast(); 71462b806406ac1ec680b6fe3aaa84c54bdc4e43ad8dGlenn Kasten if (mActiveTracks.indexOf(recordTrack) < 0) { 714781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent ALOGV("Record failed to start"); 714881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent status = BAD_VALUE; 714981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent goto startError; 715081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 715181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent return status; 715281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 71537c027248e1a4ccd5b22bc4deafb03e2d87ac8f38Glenn Kasten 715481784c37c61b09289654b979567a42bf73cd2b12Eric LaurentstartError: 715583b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent if (recordTrack->isExternalTrack()) { 7156fee1976a2849c37a53d8a01ac10327d522a1ba93Eric Laurent AudioSystem::stopInput(recordTrack->portId()); 715783b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent } 715825f4aa83efaa9179e65a20583a6d441de2c3ff3fGlenn Kasten recordTrack->clearSyncStartEvent(); 71596dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten // FIXME I wonder why we do not reset the state here? 716081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent return status; 716181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 716281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 716381784c37c61b09289654b979567a42bf73cd2b12Eric Laurentvoid AudioFlinger::RecordThread::syncStartEventCallback(const wp<SyncEvent>& event) 716481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 716581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent sp<SyncEvent> strongEvent = event.promote(); 716681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 716781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (strongEvent != 0) { 71688ea16e4b0a7d398d26887c18675b3899de5d779dEric Laurent sp<RefBase> ptr = strongEvent->cookie().promote(); 71698ea16e4b0a7d398d26887c18675b3899de5d779dEric Laurent if (ptr != 0) { 71708ea16e4b0a7d398d26887c18675b3899de5d779dEric Laurent RecordTrack *recordTrack = (RecordTrack *)ptr.get(); 71718ea16e4b0a7d398d26887c18675b3899de5d779dEric Laurent recordTrack->handleSyncStartEvent(strongEvent); 71728ea16e4b0a7d398d26887c18675b3899de5d779dEric Laurent } 717381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 717481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 717581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 7176a8356f663014e7d4c27869629af83d8bb3441e19Glenn Kastenbool AudioFlinger::RecordThread::stop(RecordThread::RecordTrack* recordTrack) { 717781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent ALOGV("RecordThread::stop"); 7178a8356f663014e7d4c27869629af83d8bb3441e19Glenn Kasten AutoMutex _l(mLock); 717938f86713cbd22caae9fdd4ac2f0bb76ff91df34dJean-Michel Trivi if (mActiveTracks.indexOf(recordTrack) < 0 || recordTrack->mState == TrackBase::PAUSING) { 718081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent return false; 718181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 718247c2070b2ce8aedb7300c0aad91caccf3c383841Glenn Kasten // note that threadLoop may still be processing the track at this point [without lock] 718381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent recordTrack->mState = TrackBase::PAUSING; 71845c25d5637ef3406883e0fc97a713f9d5cdca426fEric Laurent // signal thread to stop 71855c25d5637ef3406883e0fc97a713f9d5cdca426fEric Laurent mWaitWorkCV.broadcast(); 718681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // do not wait for mStartStopCond if exiting 718781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (exitPending()) { 718881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent return true; 718981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 719047c2070b2ce8aedb7300c0aad91caccf3c383841Glenn Kasten // FIXME incorrect usage of wait: no explicit predicate or loop 719181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mStartStopCond.wait(mLock); 71922b806406ac1ec680b6fe3aaa84c54bdc4e43ad8dGlenn Kasten // if we have been restarted, recordTrack is in mActiveTracks here 719338f86713cbd22caae9fdd4ac2f0bb76ff91df34dJean-Michel Trivi if (exitPending() || mActiveTracks.indexOf(recordTrack) < 0) { 719481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent ALOGV("Record stopped OK"); 719581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent return true; 719681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 719781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent return false; 719881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 719981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 72000f11b51a57bc9062c4fe8af73747319cedabc5d6Glenn Kastenbool AudioFlinger::RecordThread::isValidSyncEvent(const sp<SyncEvent>& event __unused) const 720181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 720281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent return false; 720381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 720481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 72050f11b51a57bc9062c4fe8af73747319cedabc5d6Glenn Kastenstatus_t AudioFlinger::RecordThread::setSyncEvent(const sp<SyncEvent>& event __unused) 720681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 720781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent#if 0 // This branch is currently dead code, but is preserved in case it will be needed in future 720881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (!isValidSyncEvent(event)) { 720981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent return BAD_VALUE; 721081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 721181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 7212d848eb48c121c119e8ba7583efc75415fe102570Glenn Kasten audio_session_t eventSession = event->triggerSession(); 721381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent status_t ret = NAME_NOT_FOUND; 721481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 721581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent Mutex::Autolock _l(mLock); 721681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 721781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent for (size_t i = 0; i < mTracks.size(); i++) { 721881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent sp<RecordTrack> track = mTracks[i]; 721981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (eventSession == track->sessionId()) { 722081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent (void) track->setSyncEvent(event); 722181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent ret = NO_ERROR; 722281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 722381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 722481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent return ret; 722581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent#else 722681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent return BAD_VALUE; 722781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent#endif 722881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 722981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 7230653cc0ab6d5b714d1f26adcd08f9bc3269b62fa0jiabinstatus_t AudioFlinger::RecordThread::getActiveMicrophones( 7231653cc0ab6d5b714d1f26adcd08f9bc3269b62fa0jiabin std::vector<media::MicrophoneInfo>* activeMicrophones) 7232653cc0ab6d5b714d1f26adcd08f9bc3269b62fa0jiabin{ 7233653cc0ab6d5b714d1f26adcd08f9bc3269b62fa0jiabin ALOGV("RecordThread::getActiveMicrophones"); 7234653cc0ab6d5b714d1f26adcd08f9bc3269b62fa0jiabin AutoMutex _l(mLock); 72359ff780e58ff96ff98acaae4166bb218880bf9e73jiabin status_t status = mInput->stream->getActiveMicrophones(activeMicrophones); 72369ff780e58ff96ff98acaae4166bb218880bf9e73jiabin return status; 7237653cc0ab6d5b714d1f26adcd08f9bc3269b62fa0jiabin} 7238653cc0ab6d5b714d1f26adcd08f9bc3269b62fa0jiabin 7239069c2719e753732d5af9ba51e5fcc34342b0c9f2Kevin Rocardvoid AudioFlinger::RecordThread::updateMetadata_l() 7240069c2719e753732d5af9ba51e5fcc34342b0c9f2Kevin Rocard{ 7241069c2719e753732d5af9ba51e5fcc34342b0c9f2Kevin Rocard if (mInput == nullptr || mInput->stream == nullptr || 7242069c2719e753732d5af9ba51e5fcc34342b0c9f2Kevin Rocard !mActiveTracks.readAndClearHasChanged()) { 7243069c2719e753732d5af9ba51e5fcc34342b0c9f2Kevin Rocard return; 7244069c2719e753732d5af9ba51e5fcc34342b0c9f2Kevin Rocard } 7245069c2719e753732d5af9ba51e5fcc34342b0c9f2Kevin Rocard StreamInHalInterface::SinkMetadata metadata; 7246069c2719e753732d5af9ba51e5fcc34342b0c9f2Kevin Rocard for (const sp<RecordTrack> &track : mActiveTracks) { 7247069c2719e753732d5af9ba51e5fcc34342b0c9f2Kevin Rocard // No track is invalid as this is called after prepareTrack_l in the same critical section 7248069c2719e753732d5af9ba51e5fcc34342b0c9f2Kevin Rocard metadata.tracks.push_back({ 7249069c2719e753732d5af9ba51e5fcc34342b0c9f2Kevin Rocard .source = track->attributes().source, 7250069c2719e753732d5af9ba51e5fcc34342b0c9f2Kevin Rocard .gain = 1, // capture tracks do not have volumes 7251069c2719e753732d5af9ba51e5fcc34342b0c9f2Kevin Rocard }); 7252069c2719e753732d5af9ba51e5fcc34342b0c9f2Kevin Rocard } 7253069c2719e753732d5af9ba51e5fcc34342b0c9f2Kevin Rocard mInput->stream->updateSinkMetadata(metadata); 7254069c2719e753732d5af9ba51e5fcc34342b0c9f2Kevin Rocard} 7255069c2719e753732d5af9ba51e5fcc34342b0c9f2Kevin Rocard 725681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// destroyTrack_l() must be called with ThreadBase::mLock held 725781784c37c61b09289654b979567a42bf73cd2b12Eric Laurentvoid AudioFlinger::RecordThread::destroyTrack_l(const sp<RecordTrack>& track) 725881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 7259bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent track->terminate(); 7260bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent track->mState = TrackBase::STOPPED; 726181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // active tracks are removed by threadLoop() 72622b806406ac1ec680b6fe3aaa84c54bdc4e43ad8dGlenn Kasten if (mActiveTracks.indexOf(track) < 0) { 726381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent removeTrack_l(track); 726481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 726581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 726681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 726781784c37c61b09289654b979567a42bf73cd2b12Eric Laurentvoid AudioFlinger::RecordThread::removeTrack_l(const sp<RecordTrack>& track) 726881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 72692c6c3bb76b2fa18ed3536331a1700250bd04c7ceAndy Hung String8 result; 72702c6c3bb76b2fa18ed3536331a1700250bd04c7ceAndy Hung track->appendDump(result, false /* active */); 72712c6c3bb76b2fa18ed3536331a1700250bd04c7ceAndy Hung mLocalLog.log("removeTrack_l (%p) %s", track.get(), result.string()); 72722c6c3bb76b2fa18ed3536331a1700250bd04c7ceAndy Hung 727381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mTracks.remove(track); 727481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // need anything related to effects here? 72756dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten if (track->isFastTrack()) { 72766dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten ALOG_ASSERT(!mFastTrackAvail); 72776dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten mFastTrackAvail = true; 72786dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten } 727981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 728081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 728181784c37c61b09289654b979567a42bf73cd2b12Eric Laurentvoid AudioFlinger::RecordThread::dump(int fd, const Vector<String16>& args) 728281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 728381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent dumpInternals(fd, args); 728481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent dumpTracks(fd, args); 728581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent dumpEffectChains(fd, args); 72862c6c3bb76b2fa18ed3536331a1700250bd04c7ceAndy Hung dprintf(fd, " Local log:\n"); 72872c6c3bb76b2fa18ed3536331a1700250bd04c7ceAndy Hung mLocalLog.dump(fd, " " /* prefix */, 40 /* lines */); 728881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 728981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 729081784c37c61b09289654b979567a42bf73cd2b12Eric Laurentvoid AudioFlinger::RecordThread::dumpInternals(int fd, const Vector<String16>& args) 729181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 729244182c206f7c5584ef2cf504da6be98fab665dbfGlenn Kasten dumpBase(fd, args); 729344182c206f7c5584ef2cf504da6be98fab665dbfGlenn Kasten 7294913d06c099bd689375483a839e11057ccf284d1cMikhail Naganov AudioStreamIn *input = mInput; 7295913d06c099bd689375483a839e11057ccf284d1cMikhail Naganov audio_input_flags_t flags = input != NULL ? input->flags : AUDIO_INPUT_FLAG_NONE; 7296913d06c099bd689375483a839e11057ccf284d1cMikhail Naganov dprintf(fd, " AudioStreamIn: %p flags %#x (%s)\n", 7297913d06c099bd689375483a839e11057ccf284d1cMikhail Naganov input, flags, inputFlagsToString(flags).c_str()); 729844182c206f7c5584ef2cf504da6be98fab665dbfGlenn Kasten if (mActiveTracks.size() == 0) { 729987cebadd48710e42474756fc3513df678de045ceElliott Hughes dprintf(fd, " No active record clients\n"); 730081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 7301bfa64966624c693be54cf9b9761f5124fc16fc24Andy Hung 7302bfa64966624c693be54cf9b9761f5124fc16fc24Andy Hung if (input != nullptr) { 7303bfa64966624c693be54cf9b9761f5124fc16fc24Andy Hung dprintf(fd, " Hal stream dump:\n"); 7304bfa64966624c693be54cf9b9761f5124fc16fc24Andy Hung (void)input->stream->dump(fd); 7305bfa64966624c693be54cf9b9761f5124fc16fc24Andy Hung } 7306bfa64966624c693be54cf9b9761f5124fc16fc24Andy Hung 73076e6704c06d61bc356e30c164081e5bcffb37920cGlenn Kasten dprintf(fd, " Fast capture thread: %s\n", hasFastCapture() ? "yes" : "no"); 73086dbb5e3336cfff1ad51d429fcb847307c06efd61Glenn Kasten dprintf(fd, " Fast track available: %s\n", mFastTrackAvail ? "yes" : "no"); 730917c9c998afed5ed9df7495eeed5822f3ed53ebecGlenn Kasten 73102f90c51d42efa881a9e54e4f4efadf99398304f9Glenn Kasten // Make a non-atomic copy of fast capture dump state so it won't change underneath us 73112f90c51d42efa881a9e54e4f4efadf99398304f9Glenn Kasten // while we are dumping it. It may be inconsistent, but it won't mutate! 73122f90c51d42efa881a9e54e4f4efadf99398304f9Glenn Kasten // This is a large object so we place it on the heap. 73132f90c51d42efa881a9e54e4f4efadf99398304f9Glenn Kasten // FIXME 25972958: Need an intelligent copy constructor that does not touch unused pages. 73142f90c51d42efa881a9e54e4f4efadf99398304f9Glenn Kasten const FastCaptureDumpState *copy = new FastCaptureDumpState(mFastCaptureDumpState); 73152f90c51d42efa881a9e54e4f4efadf99398304f9Glenn Kasten copy->dump(fd); 73162f90c51d42efa881a9e54e4f4efadf99398304f9Glenn Kasten delete copy; 731781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 731881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 73190f11b51a57bc9062c4fe8af73747319cedabc5d6Glenn Kastenvoid AudioFlinger::RecordThread::dumpTracks(int fd, const Vector<String16>& args __unused) 732081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 732181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent String8 result; 7322b220884bf3129253cc5bc8d030bc475411ea4911Marco Nelissen size_t numtracks = mTracks.size(); 7323b220884bf3129253cc5bc8d030bc475411ea4911Marco Nelissen size_t numactive = mActiveTracks.size(); 7324b220884bf3129253cc5bc8d030bc475411ea4911Marco Nelissen size_t numactiveseen = 0; 7325c42e9b462661673dff480ee71757a58b0f806370Glenn Kasten dprintf(fd, " %zu Tracks", numtracks); 73262c6c3bb76b2fa18ed3536331a1700250bd04c7ceAndy Hung const char *prefix = " "; 7327b220884bf3129253cc5bc8d030bc475411ea4911Marco Nelissen if (numtracks) { 7328c42e9b462661673dff480ee71757a58b0f806370Glenn Kasten dprintf(fd, " of which %zu are active\n", numactive); 73292c6c3bb76b2fa18ed3536331a1700250bd04c7ceAndy Hung result.append(prefix); 7330b220884bf3129253cc5bc8d030bc475411ea4911Marco Nelissen RecordTrack::appendDumpHeader(result); 7331b220884bf3129253cc5bc8d030bc475411ea4911Marco Nelissen for (size_t i = 0; i < numtracks ; ++i) { 7332b220884bf3129253cc5bc8d030bc475411ea4911Marco Nelissen sp<RecordTrack> track = mTracks[i]; 7333b220884bf3129253cc5bc8d030bc475411ea4911Marco Nelissen if (track != 0) { 7334b220884bf3129253cc5bc8d030bc475411ea4911Marco Nelissen bool active = mActiveTracks.indexOf(track) >= 0; 7335b220884bf3129253cc5bc8d030bc475411ea4911Marco Nelissen if (active) { 7336b220884bf3129253cc5bc8d030bc475411ea4911Marco Nelissen numactiveseen++; 7337b220884bf3129253cc5bc8d030bc475411ea4911Marco Nelissen } 73382c6c3bb76b2fa18ed3536331a1700250bd04c7ceAndy Hung result.append(prefix); 73392c6c3bb76b2fa18ed3536331a1700250bd04c7ceAndy Hung track->appendDump(result, active); 7340b220884bf3129253cc5bc8d030bc475411ea4911Marco Nelissen } 734181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 7342b220884bf3129253cc5bc8d030bc475411ea4911Marco Nelissen } else { 734387cebadd48710e42474756fc3513df678de045ceElliott Hughes dprintf(fd, "\n"); 734481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 734581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 7346b220884bf3129253cc5bc8d030bc475411ea4911Marco Nelissen if (numactiveseen != numactive) { 73472c6c3bb76b2fa18ed3536331a1700250bd04c7ceAndy Hung result.append(" The following tracks are in the active list but" 7348b220884bf3129253cc5bc8d030bc475411ea4911Marco Nelissen " not in the track list\n"); 73492c6c3bb76b2fa18ed3536331a1700250bd04c7ceAndy Hung result.append(prefix); 735081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent RecordTrack::appendDumpHeader(result); 7351b220884bf3129253cc5bc8d030bc475411ea4911Marco Nelissen for (size_t i = 0; i < numactive; ++i) { 73522b806406ac1ec680b6fe3aaa84c54bdc4e43ad8dGlenn Kasten sp<RecordTrack> track = mActiveTracks[i]; 7353b220884bf3129253cc5bc8d030bc475411ea4911Marco Nelissen if (mTracks.indexOf(track) < 0) { 73542c6c3bb76b2fa18ed3536331a1700250bd04c7ceAndy Hung result.append(prefix); 73552c6c3bb76b2fa18ed3536331a1700250bd04c7ceAndy Hung track->appendDump(result, true /* active */); 7356b220884bf3129253cc5bc8d030bc475411ea4911Marco Nelissen } 73572b806406ac1ec680b6fe3aaa84c54bdc4e43ad8dGlenn Kasten } 735881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 735981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 736081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent write(fd, result.string(), result.size()); 736181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 736281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 7363f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganovvoid AudioFlinger::RecordThread::setRecordSilenced(uid_t uid, bool silenced) 7364f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov{ 7365f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov Mutex::Autolock _l(mLock); 7366f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov for (size_t i = 0; i < mTracks.size() ; i++) { 7367f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov sp<RecordTrack> track = mTracks[i]; 7368f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov if (track != 0 && track->uid() == uid) { 7369f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov track->setSilenced(silenced); 7370f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov } 7371f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov } 7372f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov} 737373c02e4277b399c2ec1555d32b6ad5df23bb83dcAndy Hung 737473c02e4277b399c2ec1555d32b6ad5df23bb83dcAndy Hungvoid AudioFlinger::RecordThread::ResamplerBufferProvider::reset() 737573c02e4277b399c2ec1555d32b6ad5df23bb83dcAndy Hung{ 737673c02e4277b399c2ec1555d32b6ad5df23bb83dcAndy Hung sp<ThreadBase> threadBase = mRecordTrack->mThread.promote(); 737773c02e4277b399c2ec1555d32b6ad5df23bb83dcAndy Hung RecordThread *recordThread = (RecordThread *) threadBase.get(); 737873c02e4277b399c2ec1555d32b6ad5df23bb83dcAndy Hung mRsmpInFront = recordThread->mRsmpInRear; 737973c02e4277b399c2ec1555d32b6ad5df23bb83dcAndy Hung mRsmpInUnrel = 0; 738073c02e4277b399c2ec1555d32b6ad5df23bb83dcAndy Hung} 738173c02e4277b399c2ec1555d32b6ad5df23bb83dcAndy Hung 738273c02e4277b399c2ec1555d32b6ad5df23bb83dcAndy Hungvoid AudioFlinger::RecordThread::ResamplerBufferProvider::sync( 738373c02e4277b399c2ec1555d32b6ad5df23bb83dcAndy Hung size_t *framesAvailable, bool *hasOverrun) 738473c02e4277b399c2ec1555d32b6ad5df23bb83dcAndy Hung{ 738573c02e4277b399c2ec1555d32b6ad5df23bb83dcAndy Hung sp<ThreadBase> threadBase = mRecordTrack->mThread.promote(); 738673c02e4277b399c2ec1555d32b6ad5df23bb83dcAndy Hung RecordThread *recordThread = (RecordThread *) threadBase.get(); 738773c02e4277b399c2ec1555d32b6ad5df23bb83dcAndy Hung const int32_t rear = recordThread->mRsmpInRear; 738873c02e4277b399c2ec1555d32b6ad5df23bb83dcAndy Hung const int32_t front = mRsmpInFront; 738973c02e4277b399c2ec1555d32b6ad5df23bb83dcAndy Hung const ssize_t filled = rear - front; 739073c02e4277b399c2ec1555d32b6ad5df23bb83dcAndy Hung 739173c02e4277b399c2ec1555d32b6ad5df23bb83dcAndy Hung size_t framesIn; 739273c02e4277b399c2ec1555d32b6ad5df23bb83dcAndy Hung bool overrun = false; 739373c02e4277b399c2ec1555d32b6ad5df23bb83dcAndy Hung if (filled < 0) { 739473c02e4277b399c2ec1555d32b6ad5df23bb83dcAndy Hung // should not happen, but treat like a massive overrun and re-sync 739573c02e4277b399c2ec1555d32b6ad5df23bb83dcAndy Hung framesIn = 0; 739673c02e4277b399c2ec1555d32b6ad5df23bb83dcAndy Hung mRsmpInFront = rear; 739773c02e4277b399c2ec1555d32b6ad5df23bb83dcAndy Hung overrun = true; 739873c02e4277b399c2ec1555d32b6ad5df23bb83dcAndy Hung } else if ((size_t) filled <= recordThread->mRsmpInFrames) { 739973c02e4277b399c2ec1555d32b6ad5df23bb83dcAndy Hung framesIn = (size_t) filled; 740073c02e4277b399c2ec1555d32b6ad5df23bb83dcAndy Hung } else { 740173c02e4277b399c2ec1555d32b6ad5df23bb83dcAndy Hung // client is not keeping up with server, but give it latest data 740273c02e4277b399c2ec1555d32b6ad5df23bb83dcAndy Hung framesIn = recordThread->mRsmpInFrames; 740373c02e4277b399c2ec1555d32b6ad5df23bb83dcAndy Hung mRsmpInFront = /* front = */ rear - framesIn; 740473c02e4277b399c2ec1555d32b6ad5df23bb83dcAndy Hung overrun = true; 740573c02e4277b399c2ec1555d32b6ad5df23bb83dcAndy Hung } 740673c02e4277b399c2ec1555d32b6ad5df23bb83dcAndy Hung if (framesAvailable != NULL) { 740773c02e4277b399c2ec1555d32b6ad5df23bb83dcAndy Hung *framesAvailable = framesIn; 740873c02e4277b399c2ec1555d32b6ad5df23bb83dcAndy Hung } 740973c02e4277b399c2ec1555d32b6ad5df23bb83dcAndy Hung if (hasOverrun != NULL) { 741073c02e4277b399c2ec1555d32b6ad5df23bb83dcAndy Hung *hasOverrun = overrun; 741173c02e4277b399c2ec1555d32b6ad5df23bb83dcAndy Hung } 741273c02e4277b399c2ec1555d32b6ad5df23bb83dcAndy Hung} 741373c02e4277b399c2ec1555d32b6ad5df23bb83dcAndy Hung 741481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// AudioBufferProvider interface 74156dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kastenstatus_t AudioFlinger::RecordThread::ResamplerBufferProvider::getNextBuffer( 7416d79072e9dff59f767cce2cda1caab80ce5a0815bGlenn Kasten AudioBufferProvider::Buffer* buffer) 741781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 741873c02e4277b399c2ec1555d32b6ad5df23bb83dcAndy Hung sp<ThreadBase> threadBase = mRecordTrack->mThread.promote(); 74196dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten if (threadBase == 0) { 74206dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten buffer->frameCount = 0; 7421607fa3e928de696eba49f198af72d68e4591ca1bGlenn Kasten buffer->raw = NULL; 74226dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten return NOT_ENOUGH_DATA; 74236dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten } 74246dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten RecordThread *recordThread = (RecordThread *) threadBase.get(); 74256dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten int32_t rear = recordThread->mRsmpInRear; 742673c02e4277b399c2ec1555d32b6ad5df23bb83dcAndy Hung int32_t front = mRsmpInFront; 74278594843c15b4722ced39436fe9e64f3e57e7ace4Glenn Kasten ssize_t filled = rear - front; 74286dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten // FIXME should not be P2 (don't want to increase latency) 74296dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten // FIXME if client not keeping up, discard 7430607fa3e928de696eba49f198af72d68e4591ca1bGlenn Kasten LOG_ALWAYS_FATAL_IF(!(0 <= filled && (size_t) filled <= recordThread->mRsmpInFrames)); 74318594843c15b4722ced39436fe9e64f3e57e7ace4Glenn Kasten // 'filled' may be non-contiguous, so return only the first contiguous chunk 74326dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten front &= recordThread->mRsmpInFramesP2 - 1; 74336dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten size_t part1 = recordThread->mRsmpInFramesP2 - front; 74348594843c15b4722ced39436fe9e64f3e57e7ace4Glenn Kasten if (part1 > (size_t) filled) { 74358594843c15b4722ced39436fe9e64f3e57e7ace4Glenn Kasten part1 = filled; 74368594843c15b4722ced39436fe9e64f3e57e7ace4Glenn Kasten } 74378594843c15b4722ced39436fe9e64f3e57e7ace4Glenn Kasten size_t ask = buffer->frameCount; 74388594843c15b4722ced39436fe9e64f3e57e7ace4Glenn Kasten ALOG_ASSERT(ask > 0); 74398594843c15b4722ced39436fe9e64f3e57e7ace4Glenn Kasten if (part1 > ask) { 74408594843c15b4722ced39436fe9e64f3e57e7ace4Glenn Kasten part1 = ask; 74418594843c15b4722ced39436fe9e64f3e57e7ace4Glenn Kasten } 74428594843c15b4722ced39436fe9e64f3e57e7ace4Glenn Kasten if (part1 == 0) { 744373c02e4277b399c2ec1555d32b6ad5df23bb83dcAndy Hung // out of data is fine since the resampler will return a short-count. 74448594843c15b4722ced39436fe9e64f3e57e7ace4Glenn Kasten buffer->raw = NULL; 74458594843c15b4722ced39436fe9e64f3e57e7ace4Glenn Kasten buffer->frameCount = 0; 744673c02e4277b399c2ec1555d32b6ad5df23bb83dcAndy Hung mRsmpInUnrel = 0; 74478594843c15b4722ced39436fe9e64f3e57e7ace4Glenn Kasten return NOT_ENOUGH_DATA; 74488594843c15b4722ced39436fe9e64f3e57e7ace4Glenn Kasten } 74498594843c15b4722ced39436fe9e64f3e57e7ace4Glenn Kasten 74505744661e85981f8a9456bf470e2761235fc026daAndy Hung buffer->raw = (uint8_t*)recordThread->mRsmpInBuffer + front * recordThread->mFrameSize; 74518594843c15b4722ced39436fe9e64f3e57e7ace4Glenn Kasten buffer->frameCount = part1; 745273c02e4277b399c2ec1555d32b6ad5df23bb83dcAndy Hung mRsmpInUnrel = part1; 745381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent return NO_ERROR; 745481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 745581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 745681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// AudioBufferProvider interface 74576dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kastenvoid AudioFlinger::RecordThread::ResamplerBufferProvider::releaseBuffer( 74586dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten AudioBufferProvider::Buffer* buffer) 745981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 74608594843c15b4722ced39436fe9e64f3e57e7ace4Glenn Kasten size_t stepCount = buffer->frameCount; 74618594843c15b4722ced39436fe9e64f3e57e7ace4Glenn Kasten if (stepCount == 0) { 74628594843c15b4722ced39436fe9e64f3e57e7ace4Glenn Kasten return; 74638594843c15b4722ced39436fe9e64f3e57e7ace4Glenn Kasten } 746473c02e4277b399c2ec1555d32b6ad5df23bb83dcAndy Hung ALOG_ASSERT(stepCount <= mRsmpInUnrel); 746573c02e4277b399c2ec1555d32b6ad5df23bb83dcAndy Hung mRsmpInUnrel -= stepCount; 746673c02e4277b399c2ec1555d32b6ad5df23bb83dcAndy Hung mRsmpInFront += stepCount; 74678594843c15b4722ced39436fe9e64f3e57e7ace4Glenn Kasten buffer->raw = NULL; 746881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent buffer->frameCount = 0; 746981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 747081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 7471d8365c54d049aade9e02ccae722f311f846cad9aEric Laurentvoid AudioFlinger::RecordThread::checkBtNrec() 7472d8365c54d049aade9e02ccae722f311f846cad9aEric Laurent{ 7473d8365c54d049aade9e02ccae722f311f846cad9aEric Laurent Mutex::Autolock _l(mLock); 7474d8365c54d049aade9e02ccae722f311f846cad9aEric Laurent checkBtNrec_l(); 7475d8365c54d049aade9e02ccae722f311f846cad9aEric Laurent} 7476d8365c54d049aade9e02ccae722f311f846cad9aEric Laurent 7477d8365c54d049aade9e02ccae722f311f846cad9aEric Laurentvoid AudioFlinger::RecordThread::checkBtNrec_l() 7478d8365c54d049aade9e02ccae722f311f846cad9aEric Laurent{ 7479d8365c54d049aade9e02ccae722f311f846cad9aEric Laurent // disable AEC and NS if the device is a BT SCO headset supporting those 7480d8365c54d049aade9e02ccae722f311f846cad9aEric Laurent // pre processings 7481d8365c54d049aade9e02ccae722f311f846cad9aEric Laurent bool suspend = audio_is_bluetooth_sco_device(mInDevice) && 7482d8365c54d049aade9e02ccae722f311f846cad9aEric Laurent mAudioFlinger->btNrecIsOff(); 7483d8365c54d049aade9e02ccae722f311f846cad9aEric Laurent if (mBtNrecSuspended.exchange(suspend) != suspend) { 7484d8365c54d049aade9e02ccae722f311f846cad9aEric Laurent for (size_t i = 0; i < mEffectChains.size(); i++) { 7485d8365c54d049aade9e02ccae722f311f846cad9aEric Laurent setEffectSuspended_l(FX_IID_AEC, suspend, mEffectChains[i]->sessionId()); 7486d8365c54d049aade9e02ccae722f311f846cad9aEric Laurent setEffectSuspended_l(FX_IID_NS, suspend, mEffectChains[i]->sessionId()); 7487d8365c54d049aade9e02ccae722f311f846cad9aEric Laurent } 7488d8365c54d049aade9e02ccae722f311f846cad9aEric Laurent } 7489d8365c54d049aade9e02ccae722f311f846cad9aEric Laurent} 7490d8365c54d049aade9e02ccae722f311f846cad9aEric Laurent 749197a893eb34f8687485c88eaf15917974a203f20bAndy Hung 74921035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurentbool AudioFlinger::RecordThread::checkForNewParameter_l(const String8& keyValuePair, 74931035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent status_t& status) 749481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 749581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent bool reconfig = false; 749681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 74971035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent status = NO_ERROR; 74981035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent 74991035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent audio_format_t reqFormat = mFormat; 75001035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent uint32_t samplingRate = mSampleRate; 7501e1635ec096d1110c33a5aa46847af59c261fb7faGlenn Kasten // TODO this may change if we want to support capture from HDMI PCM multi channel (e.g on TVs). 75021035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent audio_channel_mask_t channelMask = audio_channel_in_mask_from_count(mChannelCount); 75031035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent 75041035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent AudioParameter param = AudioParameter(keyValuePair); 75051035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent int value; 75069ce67b524236db52eadf558e7765775acad89f1fHaynes Mathew George 75079ce67b524236db52eadf558e7765775acad89f1fHaynes Mathew George // scope for AutoPark extends to end of method 75089ce67b524236db52eadf558e7765775acad89f1fHaynes Mathew George AutoPark<FastCapture> park(mFastCapture); 75099ce67b524236db52eadf558e7765775acad89f1fHaynes Mathew George 75101035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent // TODO Investigate when this code runs. Check with audio policy when a sample rate and 75111035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent // channel count change can be requested. Do we mandate the first client defines the 75121035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent // HAL sampling rate and channel count or do we allow changes on the fly? 75131035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent if (param.getInt(String8(AudioParameter::keySamplingRate), value) == NO_ERROR) { 75141035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent samplingRate = value; 75151035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent reconfig = true; 75161035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent } 75171035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent if (param.getInt(String8(AudioParameter::keyFormat), value) == NO_ERROR) { 751897a893eb34f8687485c88eaf15917974a203f20bAndy Hung if (!audio_is_linear_pcm((audio_format_t) value)) { 75191035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent status = BAD_VALUE; 75201035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent } else { 75211035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent reqFormat = (audio_format_t) value; 752281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent reconfig = true; 752381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 75241035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent } 75251035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent if (param.getInt(String8(AudioParameter::keyChannels), value) == NO_ERROR) { 75261035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent audio_channel_mask_t mask = (audio_channel_mask_t) value; 7527d330ee46022f34da76d14d0c4d2910526ecc2321Andy Hung if (!audio_is_input_channel(mask) || 7528d330ee46022f34da76d14d0c4d2910526ecc2321Andy Hung audio_channel_count_from_in_mask(mask) > FCC_8) { 75291035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent status = BAD_VALUE; 75301035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent } else { 75311035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent channelMask = mask; 75321035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent reconfig = true; 753381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 75341035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent } 75351035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent if (param.getInt(String8(AudioParameter::keyFrameCount), value) == NO_ERROR) { 75361035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent // do not accept frame count changes if tracks are open as the track buffer 75371035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent // size depends on frame count and correct behavior would not be guaranteed 75381035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent // if frame count is changed after track creation 75391035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent if (mActiveTracks.size() > 0) { 75401035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent status = INVALID_OPERATION; 75411035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent } else { 75421035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent reconfig = true; 754381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 75441035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent } 75451035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent if (param.getInt(String8(AudioParameter::keyRouting), value) == NO_ERROR) { 75461035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent // forward device change to effects that have requested to be 75471035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent // aware of attached audio device. 75481035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent for (size_t i = 0; i < mEffectChains.size(); i++) { 75491035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent mEffectChains[i]->setDevice_l(value); 755081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 755181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 75521035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent // store input device and output device but do not forward output device to audio HAL. 75531035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent // Note that status is ignored by the caller for output device 75541035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent // (see AudioFlinger::setParameters() 75551035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent if (audio_is_output_devices(value)) { 75561035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent mOutDevice = value; 75571035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent status = BAD_VALUE; 75581035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent } else { 75591035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent mInDevice = value; 7560e8726fea8a53bf3474aa3c6deaf2f6c1f565e694Eric Laurent if (value != AUDIO_DEVICE_NONE) { 7561e8726fea8a53bf3474aa3c6deaf2f6c1f565e694Eric Laurent mPrevInDevice = value; 7562e8726fea8a53bf3474aa3c6deaf2f6c1f565e694Eric Laurent } 7563d8365c54d049aade9e02ccae722f311f846cad9aEric Laurent checkBtNrec_l(); 756481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 75651035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent } 75661035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent if (param.getInt(String8(AudioParameter::keyInputSource), value) == NO_ERROR && 75671035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent mAudioSource != (audio_source_t)value) { 75681035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent // forward device change to effects that have requested to be 75691035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent // aware of attached audio device. 75701035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent for (size_t i = 0; i < mEffectChains.size(); i++) { 75711035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent mEffectChains[i]->setAudioSource_l((audio_source_t)value); 757281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 75731035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent mAudioSource = (audio_source_t)value; 75741035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent } 7575e198c360d5e75a9b2097844c495c10902e7e8500Glenn Kasten 75761035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent if (status == NO_ERROR) { 75771dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov status = mInput->stream->setParameters(keyValuePair); 75781035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent if (status == INVALID_OPERATION) { 75791035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent inputStandBy(); 75801dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov status = mInput->stream->setParameters(keyValuePair); 75811035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent } 75821035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent if (reconfig) { 75831dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov if (status == BAD_VALUE) { 75841dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov uint32_t sRate; 75851dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov audio_channel_mask_t channelMask; 75861dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov audio_format_t format; 75871dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov if (mInput->stream->getAudioProperties(&sRate, &channelMask, &format) == OK && 75881dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov audio_is_linear_pcm(format) && audio_is_linear_pcm(reqFormat) && 75891dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov sRate <= (AUDIO_RESAMPLER_DOWN_RATIO_MAX * samplingRate) && 75901dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov audio_channel_count_from_in_mask(channelMask) <= FCC_8) { 75911dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov status = NO_ERROR; 75921dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov } 759381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 75941035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent if (status == NO_ERROR) { 75951035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent readInputParameters_l(); 759673e26b661af50be2c0a4ff6c9ac85f7347a8b235Eric Laurent sendIoConfigEvent_l(AUDIO_INPUT_CONFIG_CHANGED); 759781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 759881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 759981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 76001035194cee4fbd57e35ea15c56e66cd09b63d56eEric Laurent 760181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent return reconfig; 760281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 760381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 760481784c37c61b09289654b979567a42bf73cd2b12Eric LaurentString8 AudioFlinger::RecordThread::getParameters(const String8& keys) 760581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 760681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent Mutex::Autolock _l(mLock); 76071dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov if (initCheck() == NO_ERROR) { 76081dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov String8 out_s8; 76091dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov if (mInput->stream->getParameters(keys, &out_s8) == OK) { 76101dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov return out_s8; 76111dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov } 761281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 76131dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov return String8(); 761481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 761581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 76167c1ec5f038e63a5eb8b04434577c25bc23f5f410Eric Laurentvoid AudioFlinger::RecordThread::ioConfigChanged(audio_io_config_event event, pid_t pid) { 761773e26b661af50be2c0a4ff6c9ac85f7347a8b235Eric Laurent sp<AudioIoDescriptor> desc = new AudioIoDescriptor(); 761873e26b661af50be2c0a4ff6c9ac85f7347a8b235Eric Laurent 761973e26b661af50be2c0a4ff6c9ac85f7347a8b235Eric Laurent desc->mIoHandle = mId; 762081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 762181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent switch (event) { 762273e26b661af50be2c0a4ff6c9ac85f7347a8b235Eric Laurent case AUDIO_INPUT_OPENED: 7623ad2e7b902c0432a0db40906a4b1f5b693ce439ddEric Laurent case AUDIO_INPUT_REGISTERED: 762473e26b661af50be2c0a4ff6c9ac85f7347a8b235Eric Laurent case AUDIO_INPUT_CONFIG_CHANGED: 7625296fb13dd9b5e90d6a05cce897c3b1e7914a478aEric Laurent desc->mPatch = mPatch; 762673e26b661af50be2c0a4ff6c9ac85f7347a8b235Eric Laurent desc->mChannelMask = mChannelMask; 762773e26b661af50be2c0a4ff6c9ac85f7347a8b235Eric Laurent desc->mSamplingRate = mSampleRate; 762873e26b661af50be2c0a4ff6c9ac85f7347a8b235Eric Laurent desc->mFormat = mFormat; 762973e26b661af50be2c0a4ff6c9ac85f7347a8b235Eric Laurent desc->mFrameCount = mFrameCount; 76304a8308b11b92e608cdaf29f73f7919e75706f9a2Glenn Kasten desc->mFrameCountHAL = mFrameCount; 763173e26b661af50be2c0a4ff6c9ac85f7347a8b235Eric Laurent desc->mLatency = 0; 763281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent break; 763381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 763473e26b661af50be2c0a4ff6c9ac85f7347a8b235Eric Laurent case AUDIO_INPUT_CLOSED: 763581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent default: 763681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent break; 763781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 76387c1ec5f038e63a5eb8b04434577c25bc23f5f410Eric Laurent mAudioFlinger->ioConfigChanged(event, desc, pid); 763981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 764081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 7641deca2ae0a7cf8bc54ff3f30b7dc39bbc78b94c0dGlenn Kastenvoid AudioFlinger::RecordThread::readInputParameters_l() 764281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 76431dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov status_t result = mInput->stream->getAudioProperties(&mSampleRate, &mChannelMask, &mHALFormat); 76441dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov LOG_ALWAYS_FATAL_IF(result != OK, "Error retrieving audio properties from HAL: %d", result); 7645e541269be94f3a1072932d51537905b120ef4733Andy Hung mChannelCount = audio_channel_count_from_in_mask(mChannelMask); 76461dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov LOG_ALWAYS_FATAL_IF(mChannelCount > FCC_8, "HAL channel count %d > %d", mChannelCount, FCC_8); 7647463be250de73907965faa6a216c00312bf81e049Andy Hung mFormat = mHALFormat; 76481dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov LOG_ALWAYS_FATAL_IF(!audio_is_linear_pcm(mFormat), "HAL format %#x is not linear pcm", mFormat); 76491dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov result = mInput->stream->getFrameSize(&mFrameSize); 76501dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov LOG_ALWAYS_FATAL_IF(result != OK, "Error retrieving frame size from HAL: %d", result); 76511dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov result = mInput->stream->getBufferSize(&mBufferSize); 76521dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov LOG_ALWAYS_FATAL_IF(result != OK, "Error retrieving buffer size from HAL: %d", result); 7653548efc94813c1dec6e8cf6c085ae41ccb04827f1Glenn Kasten mFrameCount = mBufferSize / mFrameSize; 7654b3cf7e656db20c65c0d7c779640db7f5f2a52bafMikhail Naganov ALOGV("%p RecordThread params: mChannelCount=%u, mFormat=%#x, mFrameSize=%lld, " 7655b3cf7e656db20c65c0d7c779640db7f5f2a52bafMikhail Naganov "mBufferSize=%lld, mFrameCount=%lld", 7656b3cf7e656db20c65c0d7c779640db7f5f2a52bafMikhail Naganov this, mChannelCount, mFormat, (long long)mFrameSize, (long long)mBufferSize, 7657b3cf7e656db20c65c0d7c779640db7f5f2a52bafMikhail Naganov (long long)mFrameCount); 76586dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten // This is the formula for calculating the temporary buffer size. 7659e842614837e5401adf77e90485300c288b9a7876Glenn Kasten // With 7 HAL buffers, we can guarantee ability to down-sample the input by ratio of 6:1 to 76608594843c15b4722ced39436fe9e64f3e57e7ace4Glenn Kasten // 1 full output buffer, regardless of the alignment of the available input. 7661e842614837e5401adf77e90485300c288b9a7876Glenn Kasten // The value is somewhat arbitrary, and could probably be even larger. 76626dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten // A larger value should allow more old data to be read after a track calls start(), 76636dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten // without increasing latency. 766497a893eb34f8687485c88eaf15917974a203f20bAndy Hung // 766597a893eb34f8687485c88eaf15917974a203f20bAndy Hung // Note this is independent of the maximum downsampling ratio permitted for capture. 7666e842614837e5401adf77e90485300c288b9a7876Glenn Kasten mRsmpInFrames = mFrameCount * 7; 76678594843c15b4722ced39436fe9e64f3e57e7ace4Glenn Kasten mRsmpInFramesP2 = roundup(mRsmpInFrames); 76685744661e85981f8a9456bf470e2761235fc026daAndy Hung free(mRsmpInBuffer); 76690a01c2fb68e6f35905de8dfaf938d099cd48587dAndy Hung mRsmpInBuffer = NULL; 767049d00ad9164ea5ce48c85765a2b6460d9b457d38Glenn Kasten 767149d00ad9164ea5ce48c85765a2b6460d9b457d38Glenn Kasten // TODO optimize audio capture buffer sizes ... 767249d00ad9164ea5ce48c85765a2b6460d9b457d38Glenn Kasten // Here we calculate the size of the sliding buffer used as a source 767349d00ad9164ea5ce48c85765a2b6460d9b457d38Glenn Kasten // for resampling. mRsmpInFramesP2 is currently roundup(mFrameCount * 7). 767449d00ad9164ea5ce48c85765a2b6460d9b457d38Glenn Kasten // For current HAL frame counts, this is usually 2048 = 40 ms. It would 767549d00ad9164ea5ce48c85765a2b6460d9b457d38Glenn Kasten // be better to have it derived from the pipe depth in the long term. 767649d00ad9164ea5ce48c85765a2b6460d9b457d38Glenn Kasten // The current value is higher than necessary. However it should not add to latency. 767749d00ad9164ea5ce48c85765a2b6460d9b457d38Glenn Kasten 76788594843c15b4722ced39436fe9e64f3e57e7ace4Glenn Kasten // Over-allocate beyond mRsmpInFramesP2 to permit a HAL read past end of buffer 76791b291841a58ce6b2b291232dfdd56134b2185c48Glenn Kasten mRsmpInFramesOA = mRsmpInFramesP2 + mFrameCount - 1; 76801b291841a58ce6b2b291232dfdd56134b2185c48Glenn Kasten (void)posix_memalign(&mRsmpInBuffer, 32, mRsmpInFramesOA * mFrameSize); 7681d3bb645f0b7f567b033b8664499d685f8ec10628Glenn Kasten // if posix_memalign fails, will segv here. 7682d3bb645f0b7f567b033b8664499d685f8ec10628Glenn Kasten memset(mRsmpInBuffer, 0, mRsmpInFramesOA * mFrameSize); 76836dd62fb91d82dedcfa3ab38c02eb0940b4ba932aGlenn Kasten 76844cc0a6a835c806d200ef83ef31fe5bef327c355cGlenn Kasten // AudioRecord mSampleRate and mChannelCount are constant due to AudioRecord API constraints. 76854cc0a6a835c806d200ef83ef31fe5bef327c355cGlenn Kasten // But if thread's mSampleRate or mChannelCount changes, how will that affect active tracks? 768681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 768781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 76885f972c031d4061f4f037c9fda1ea4bd9b6a756cdGlenn Kastenuint32_t AudioFlinger::RecordThread::getInputFramesLost() 768981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 769081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent Mutex::Autolock _l(mLock); 76911dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov uint32_t result; 76921dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov if (initCheck() == NO_ERROR && mInput->stream->getInputFramesLost(&result) == OK) { 76931dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov return result; 769481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 76951dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov return 0; 769681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 769781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 76984c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent// hasAudioSession_l() must be called with ThreadBase::mLock held 76994c415062ad1bb53e9af8f644d8215837262b79bbEric Laurentuint32_t AudioFlinger::RecordThread::hasAudioSession_l(audio_session_t sessionId) const 770081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 770181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent uint32_t result = 0; 770281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (getEffectChain_l(sessionId) != 0) { 770381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent result = EFFECT_SESSION; 770481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 770581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 770681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent for (size_t i = 0; i < mTracks.size(); ++i) { 770781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (sessionId == mTracks[i]->sessionId()) { 770881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent result |= TRACK_SESSION; 77094c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent if (mTracks[i]->isFastTrack()) { 77104c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent result |= FAST_SESSION; 77114c415062ad1bb53e9af8f644d8215837262b79bbEric Laurent } 771281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent break; 771381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 771481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 771581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 771681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent return result; 771781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 771881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 7719d848eb48c121c119e8ba7583efc75415fe102570Glenn KastenKeyedVector<audio_session_t, bool> AudioFlinger::RecordThread::sessionIds() const 772081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 7721d848eb48c121c119e8ba7583efc75415fe102570Glenn Kasten KeyedVector<audio_session_t, bool> ids; 772281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent Mutex::Autolock _l(mLock); 772381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent for (size_t j = 0; j < mTracks.size(); ++j) { 772481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent sp<RecordThread::RecordTrack> track = mTracks[j]; 7725d848eb48c121c119e8ba7583efc75415fe102570Glenn Kasten audio_session_t sessionId = track->sessionId(); 772681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (ids.indexOfKey(sessionId) < 0) { 772781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent ids.add(sessionId, true); 772881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 772981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 773081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent return ids; 773181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 773281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 773381784c37c61b09289654b979567a42bf73cd2b12Eric LaurentAudioFlinger::AudioStreamIn* AudioFlinger::RecordThread::clearInput() 773481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 773581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent Mutex::Autolock _l(mLock); 773681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent AudioStreamIn *input = mInput; 773781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mInput = NULL; 773881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent return input; 773981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 774081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 774181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent// this method must always be called either with ThreadBase mLock held or inside the thread loop 77421dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganovsp<StreamHalInterface> AudioFlinger::RecordThread::stream() const 774381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 774481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (mInput == NULL) { 774581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent return NULL; 774681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 77471dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov return mInput->stream; 774881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 774981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 775081784c37c61b09289654b979567a42bf73cd2b12Eric Laurentstatus_t AudioFlinger::RecordThread::addEffectChain_l(const sp<EffectChain>& chain) 775181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 775281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent // only one chain per input thread 775381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (mEffectChains.size() != 0) { 7754aaa44478a373232d8416657035a9020f9c7aa7c3Eric Laurent ALOGW("addEffectChain_l() already one chain %p on thread %p", chain.get(), this); 775581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent return INVALID_OPERATION; 775681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 775781784c37c61b09289654b979567a42bf73cd2b12Eric Laurent ALOGV("addEffectChain_l() %p on thread %p", chain.get(), this); 7758aaa44478a373232d8416657035a9020f9c7aa7c3Eric Laurent chain->setThread(this); 775981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent chain->setInBuffer(NULL); 776081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent chain->setOutBuffer(NULL); 776181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 776281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent checkSuspendOnAddEffectChain_l(chain); 776381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 77641b92868010b5c1409692a86f6b27e4a265b64c1aEric Laurent // make sure enabled pre processing effects state is communicated to the HAL as we 77651b92868010b5c1409692a86f6b27e4a265b64c1aEric Laurent // just moved them to a new input stream. 77661b92868010b5c1409692a86f6b27e4a265b64c1aEric Laurent chain->syncHalEffectsState(); 77671b92868010b5c1409692a86f6b27e4a265b64c1aEric Laurent 776881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mEffectChains.add(chain); 776981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 777081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent return NO_ERROR; 777181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 777281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 777381784c37c61b09289654b979567a42bf73cd2b12Eric Laurentsize_t AudioFlinger::RecordThread::removeEffectChain_l(const sp<EffectChain>& chain) 777481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent{ 777581784c37c61b09289654b979567a42bf73cd2b12Eric Laurent ALOGV("removeEffectChain_l() %p from thread %p", chain.get(), this); 777681784c37c61b09289654b979567a42bf73cd2b12Eric Laurent ALOGW_IF(mEffectChains.size() != 1, 7777c42e9b462661673dff480ee71757a58b0f806370Glenn Kasten "removeEffectChain_l() %p invalid chain size %zu on thread %p", 777881784c37c61b09289654b979567a42bf73cd2b12Eric Laurent chain.get(), mEffectChains.size(), this); 777981784c37c61b09289654b979567a42bf73cd2b12Eric Laurent if (mEffectChains.size() == 1) { 778081784c37c61b09289654b979567a42bf73cd2b12Eric Laurent mEffectChains.removeAt(0); 778181784c37c61b09289654b979567a42bf73cd2b12Eric Laurent } 778281784c37c61b09289654b979567a42bf73cd2b12Eric Laurent return 0; 778381784c37c61b09289654b979567a42bf73cd2b12Eric Laurent} 778481784c37c61b09289654b979567a42bf73cd2b12Eric Laurent 77851c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurentstatus_t AudioFlinger::RecordThread::createAudioPatch_l(const struct audio_patch *patch, 77861c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent audio_patch_handle_t *handle) 77871c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent{ 77881c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent status_t status = NO_ERROR; 7789054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurent 7790054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurent // store new device and send to effects 7791054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurent mInDevice = patch->sources[0].ext.device.type; 7792296fb13dd9b5e90d6a05cce897c3b1e7914a478aEric Laurent mPatch = *patch; 7793054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurent for (size_t i = 0; i < mEffectChains.size(); i++) { 7794054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurent mEffectChains[i]->setDevice_l(mInDevice); 7795054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurent } 7796054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurent 7797d8365c54d049aade9e02ccae722f311f846cad9aEric Laurent checkBtNrec_l(); 77981c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent 7799054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurent // store new source and send to effects 7800054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurent if (mAudioSource != patch->sinks[0].ext.mix.usecase.source) { 7801054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurent mAudioSource = patch->sinks[0].ext.mix.usecase.source; 7802054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurent for (size_t i = 0; i < mEffectChains.size(); i++) { 7803054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurent mEffectChains[i]->setAudioSource_l(mAudioSource); 78041c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent } 7805054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurent } 78061c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent 78079ee0540d3a61bff03d561ca431a371c3d9335d2bMikhail Naganov if (mInput->audioHwDev->supportsAudioPatches()) { 7808e4f1f63a2c54ee8687ad8cca18df0f6639ad7c81Mikhail Naganov sp<DeviceHalInterface> hwDevice = mInput->audioHwDev->hwDevice(); 7809e4f1f63a2c54ee8687ad8cca18df0f6639ad7c81Mikhail Naganov status = hwDevice->createAudioPatch(patch->num_sources, 7810e4f1f63a2c54ee8687ad8cca18df0f6639ad7c81Mikhail Naganov patch->sources, 7811e4f1f63a2c54ee8687ad8cca18df0f6639ad7c81Mikhail Naganov patch->num_sinks, 7812e4f1f63a2c54ee8687ad8cca18df0f6639ad7c81Mikhail Naganov patch->sinks, 7813e4f1f63a2c54ee8687ad8cca18df0f6639ad7c81Mikhail Naganov handle); 78141c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent } else { 7815054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurent char *address; 7816054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurent if (strcmp(patch->sources[0].ext.device.address, "") != 0) { 7817054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurent address = audio_device_address_to_parameter( 7818054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurent patch->sources[0].ext.device.type, 7819054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurent patch->sources[0].ext.device.address); 7820054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurent } else { 7821054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurent address = (char *)calloc(1, 1); 7822054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurent } 7823054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurent AudioParameter param = AudioParameter(String8(address)); 7824054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurent free(address); 782500260b5e6996b0a4b12f71c5b84e44adea040534Mikhail Naganov param.addInt(String8(AudioParameter::keyRouting), 7826054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurent (int)patch->sources[0].ext.device.type); 782700260b5e6996b0a4b12f71c5b84e44adea040534Mikhail Naganov param.addInt(String8(AudioParameter::keyInputSource), 7828054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurent (int)patch->sinks[0].ext.mix.usecase.source); 78291dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov status = mInput->stream->setParameters(param.toString()); 7830054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurent *handle = AUDIO_PATCH_HANDLE_NONE; 78311c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent } 7832054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurent 7833e8726fea8a53bf3474aa3c6deaf2f6c1f565e694Eric Laurent if (mInDevice != mPrevInDevice) { 7834e8726fea8a53bf3474aa3c6deaf2f6c1f565e694Eric Laurent sendIoConfigEvent_l(AUDIO_INPUT_CONFIG_CHANGED); 7835e8726fea8a53bf3474aa3c6deaf2f6c1f565e694Eric Laurent mPrevInDevice = mInDevice; 7836e8726fea8a53bf3474aa3c6deaf2f6c1f565e694Eric Laurent } 7837296fb13dd9b5e90d6a05cce897c3b1e7914a478aEric Laurent 78381c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent return status; 78391c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent} 78401c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent 78411c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurentstatus_t AudioFlinger::RecordThread::releaseAudioPatch_l(const audio_patch_handle_t handle) 78421c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent{ 78431c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent status_t status = NO_ERROR; 7844054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurent 7845054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurent mInDevice = AUDIO_DEVICE_NONE; 7846054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurent 78479ee0540d3a61bff03d561ca431a371c3d9335d2bMikhail Naganov if (mInput->audioHwDev->supportsAudioPatches()) { 7848e4f1f63a2c54ee8687ad8cca18df0f6639ad7c81Mikhail Naganov sp<DeviceHalInterface> hwDevice = mInput->audioHwDev->hwDevice(); 7849e4f1f63a2c54ee8687ad8cca18df0f6639ad7c81Mikhail Naganov status = hwDevice->releaseAudioPatch(handle); 78501c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent } else { 7851054d9d3dea1390294650ac704acb4aa0a0731217Eric Laurent AudioParameter param; 785200260b5e6996b0a4b12f71c5b84e44adea040534Mikhail Naganov param.addInt(String8(AudioParameter::keyRouting), 0); 78531dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov status = mInput->stream->setParameters(param.toString()); 78541c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent } 78551c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent return status; 78561c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent} 78571c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent 785883b8808faad1e91690c64d7007348be8d9ebde73Eric Laurentvoid AudioFlinger::RecordThread::addPatchRecord(const sp<PatchRecord>& record) 785983b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent{ 786083b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent Mutex::Autolock _l(mLock); 786183b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent mTracks.add(record); 786283b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent} 786383b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent 786483b8808faad1e91690c64d7007348be8d9ebde73Eric Laurentvoid AudioFlinger::RecordThread::deletePatchRecord(const sp<PatchRecord>& record) 786583b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent{ 786683b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent Mutex::Autolock _l(mLock); 786783b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent destroyTrack_l(record); 786883b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent} 786983b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent 787083b8808faad1e91690c64d7007348be8d9ebde73Eric Laurentvoid AudioFlinger::RecordThread::getAudioPortConfig(struct audio_port_config *config) 787183b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent{ 787283b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent ThreadBase::getAudioPortConfig(config); 787383b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent config->role = AUDIO_PORT_ROLE_SINK; 787483b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent config->ext.mix.hw_module = mInput->audioHwDev->handle(); 787583b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent config->ext.mix.usecase.source = mAudioSource; 787683b8808faad1e91690c64d7007348be8d9ebde73Eric Laurent} 78771c333e252cbca3337c1bedbc57a005f3b7d23fdbEric Laurent 78786acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent// ---------------------------------------------------------------------------- 78796acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent// Mmap 78806acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent// ---------------------------------------------------------------------------- 78816acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 78826acd1d432f526ae9a055ddaece28bf93b474a776Eric LaurentAudioFlinger::MmapThreadHandle::MmapThreadHandle(const sp<MmapThread>& thread) 78836acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent : mThread(thread) 78846acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent{ 78859fabbf8a8ae755c3c07637f8ca7677c63a1607bbPhil Burk assert(thread != 0); // thread must start non-null and stay non-null 78866acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent} 78876acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 78886acd1d432f526ae9a055ddaece28bf93b474a776Eric LaurentAudioFlinger::MmapThreadHandle::~MmapThreadHandle() 78896acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent{ 78909fabbf8a8ae755c3c07637f8ca7677c63a1607bbPhil Burk mThread->disconnect(); 78916acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent} 78926acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 78936acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurentstatus_t AudioFlinger::MmapThreadHandle::createMmapBuffer(int32_t minSizeFrames, 78946acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent struct audio_mmap_buffer_info *info) 78956acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent{ 78966acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent return mThread->createMmapBuffer(minSizeFrames, info); 78976acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent} 78986acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 78996acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurentstatus_t AudioFlinger::MmapThreadHandle::getMmapPosition(struct audio_mmap_position *position) 79006acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent{ 79016acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent return mThread->getMmapPosition(position); 79026acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent} 79036acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 7904a54f1283fdd9adbd64ecca4e14af56aaa0e8c825Eric Laurentstatus_t AudioFlinger::MmapThreadHandle::start(const AudioClient& client, 7905d3bb645f0b7f567b033b8664499d685f8ec10628Glenn Kasten audio_port_handle_t *handle) 79066acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 79076acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent{ 79086acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent return mThread->start(client, handle); 79096acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent} 79106acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 79116acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurentstatus_t AudioFlinger::MmapThreadHandle::stop(audio_port_handle_t handle) 79126acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent{ 79136acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent return mThread->stop(handle); 79146acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent} 79156acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 791618b570146c971fe729c391bfbb869391084e623dEric Laurentstatus_t AudioFlinger::MmapThreadHandle::standby() 791718b570146c971fe729c391bfbb869391084e623dEric Laurent{ 791818b570146c971fe729c391bfbb869391084e623dEric Laurent return mThread->standby(); 791918b570146c971fe729c391bfbb869391084e623dEric Laurent} 792018b570146c971fe729c391bfbb869391084e623dEric Laurent 79216acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 79226acd1d432f526ae9a055ddaece28bf93b474a776Eric LaurentAudioFlinger::MmapThread::MmapThread( 79236acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent const sp<AudioFlinger>& audioFlinger, audio_io_handle_t id, 79246acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent AudioHwDevice *hwDev, sp<StreamHalInterface> stream, 79256acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent audio_devices_t outDevice, audio_devices_t inDevice, bool systemReady) 79266acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent : ThreadBase(audioFlinger, id, outDevice, inDevice, MMAP, systemReady), 79277aa0ccbcb6e8d35c894356015c23574619bcf648Eric Laurent mSessionId(AUDIO_SESSION_NONE), 79287aa0ccbcb6e8d35c894356015c23574619bcf648Eric Laurent mDeviceId(AUDIO_PORT_HANDLE_NONE), mPortId(AUDIO_PORT_HANDLE_NONE), 79292c6c3bb76b2fa18ed3536331a1700250bd04c7ceAndy Hung mHalStream(stream), mHalDevice(hwDev->hwDevice()), mAudioHwDev(hwDev), 793067f97291bfb7caec5152d2c93913191729db5917Eric Laurent mActiveTracks(&this->mLocalLog), 793167f97291bfb7caec5152d2c93913191729db5917Eric Laurent mHalVolFloat(-1.0f), // Initialize to illegal value so it always gets set properly later. 793267f97291bfb7caec5152d2c93913191729db5917Eric Laurent mNoCallbackWarningCount(0) 79336acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent{ 793418b570146c971fe729c391bfbb869391084e623dEric Laurent mStandby = true; 79356acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent readHalParameters_l(); 79366acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent} 79376acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 79386acd1d432f526ae9a055ddaece28bf93b474a776Eric LaurentAudioFlinger::MmapThread::~MmapThread() 79396acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent{ 794018b570146c971fe729c391bfbb869391084e623dEric Laurent releaseWakeLock_l(); 79416acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent} 79426acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 79436acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurentvoid AudioFlinger::MmapThread::onFirstRef() 79446acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent{ 79456acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent run(mThreadName, ANDROID_PRIORITY_URGENT_AUDIO); 79466acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent} 79476acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 79486acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurentvoid AudioFlinger::MmapThread::disconnect() 79496acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent{ 7950331679c8a5cd21a0e6a7a1d851e965e4721f7420Eric Laurent ActiveTracks<MmapTrack> activeTracks; 7951331679c8a5cd21a0e6a7a1d851e965e4721f7420Eric Laurent { 7952331679c8a5cd21a0e6a7a1d851e965e4721f7420Eric Laurent Mutex::Autolock _l(mLock); 7953331679c8a5cd21a0e6a7a1d851e965e4721f7420Eric Laurent for (const sp<MmapTrack> &t : mActiveTracks) { 7954331679c8a5cd21a0e6a7a1d851e965e4721f7420Eric Laurent activeTracks.add(t); 7955331679c8a5cd21a0e6a7a1d851e965e4721f7420Eric Laurent } 7956331679c8a5cd21a0e6a7a1d851e965e4721f7420Eric Laurent } 7957331679c8a5cd21a0e6a7a1d851e965e4721f7420Eric Laurent for (const sp<MmapTrack> &t : activeTracks) { 79586acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent stop(t->portId()); 79596acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } 79609fabbf8a8ae755c3c07637f8ca7677c63a1607bbPhil Burk // This will decrement references and may cause the destruction of this thread. 79616acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent if (isOutput()) { 79626acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent AudioSystem::releaseOutput(mId, streamType(), mSessionId); 79636acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } else { 7964fee1976a2849c37a53d8a01ac10327d522a1ba93Eric Laurent AudioSystem::releaseInput(mPortId); 79656acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } 79666acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent} 79676acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 79686acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 79696acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurentvoid AudioFlinger::MmapThread::configure(const audio_attributes_t *attr, 79706acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent audio_stream_type_t streamType __unused, 79716acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent audio_session_t sessionId, 79726acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent const sp<MmapStreamCallback>& callback, 79737aa0ccbcb6e8d35c894356015c23574619bcf648Eric Laurent audio_port_handle_t deviceId, 79746acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent audio_port_handle_t portId) 79756acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent{ 79766acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent mAttr = *attr; 79776acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent mSessionId = sessionId; 79786acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent mCallback = callback; 79797aa0ccbcb6e8d35c894356015c23574619bcf648Eric Laurent mDeviceId = deviceId; 79806acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent mPortId = portId; 79816acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent} 79826acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 79836acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurentstatus_t AudioFlinger::MmapThread::createMmapBuffer(int32_t minSizeFrames, 79846acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent struct audio_mmap_buffer_info *info) 79856acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent{ 79866acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent if (mHalStream == 0) { 79876acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent return NO_INIT; 79886acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } 798918b570146c971fe729c391bfbb869391084e623dEric Laurent mStandby = true; 799018b570146c971fe729c391bfbb869391084e623dEric Laurent acquireWakeLock(); 79916acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent return mHalStream->createMmapBuffer(minSizeFrames, info); 79926acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent} 79936acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 79946acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurentstatus_t AudioFlinger::MmapThread::getMmapPosition(struct audio_mmap_position *position) 79956acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent{ 79966acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent if (mHalStream == 0) { 79976acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent return NO_INIT; 79986acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } 79996acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent return mHalStream->getMmapPosition(position); 80006acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent} 80016acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 8002331679c8a5cd21a0e6a7a1d851e965e4721f7420Eric Laurentstatus_t AudioFlinger::MmapThread::exitStandby() 8003331679c8a5cd21a0e6a7a1d851e965e4721f7420Eric Laurent{ 8004331679c8a5cd21a0e6a7a1d851e965e4721f7420Eric Laurent status_t ret = mHalStream->start(); 8005331679c8a5cd21a0e6a7a1d851e965e4721f7420Eric Laurent if (ret != NO_ERROR) { 8006331679c8a5cd21a0e6a7a1d851e965e4721f7420Eric Laurent ALOGE("%s: error mHalStream->start() = %d for first track", __FUNCTION__, ret); 8007331679c8a5cd21a0e6a7a1d851e965e4721f7420Eric Laurent return ret; 8008331679c8a5cd21a0e6a7a1d851e965e4721f7420Eric Laurent } 8009331679c8a5cd21a0e6a7a1d851e965e4721f7420Eric Laurent mStandby = false; 8010331679c8a5cd21a0e6a7a1d851e965e4721f7420Eric Laurent return NO_ERROR; 8011331679c8a5cd21a0e6a7a1d851e965e4721f7420Eric Laurent} 8012331679c8a5cd21a0e6a7a1d851e965e4721f7420Eric Laurent 8013a54f1283fdd9adbd64ecca4e14af56aaa0e8c825Eric Laurentstatus_t AudioFlinger::MmapThread::start(const AudioClient& client, 80146acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent audio_port_handle_t *handle) 80156acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent{ 8016a54f1283fdd9adbd64ecca4e14af56aaa0e8c825Eric Laurent ALOGV("%s clientUid %d mStandby %d mPortId %d *handle %d", __FUNCTION__, 8017a54f1283fdd9adbd64ecca4e14af56aaa0e8c825Eric Laurent client.clientUid, mStandby, mPortId, *handle); 80186acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent if (mHalStream == 0) { 80196acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent return NO_INIT; 80206acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } 80216acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 80226acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent status_t ret; 80236acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 8024a54f1283fdd9adbd64ecca4e14af56aaa0e8c825Eric Laurent if (*handle == mPortId) { 80256acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent // for the first track, reuse portId and session allocated when the stream was opened 8026331679c8a5cd21a0e6a7a1d851e965e4721f7420Eric Laurent return exitStandby(); 8027a54f1283fdd9adbd64ecca4e14af56aaa0e8c825Eric Laurent } 8028a54f1283fdd9adbd64ecca4e14af56aaa0e8c825Eric Laurent 8029a54f1283fdd9adbd64ecca4e14af56aaa0e8c825Eric Laurent audio_port_handle_t portId = AUDIO_PORT_HANDLE_NONE; 8030a54f1283fdd9adbd64ecca4e14af56aaa0e8c825Eric Laurent 8031a54f1283fdd9adbd64ecca4e14af56aaa0e8c825Eric Laurent audio_io_handle_t io = mId; 8032a54f1283fdd9adbd64ecca4e14af56aaa0e8c825Eric Laurent if (isOutput()) { 8033a54f1283fdd9adbd64ecca4e14af56aaa0e8c825Eric Laurent audio_config_t config = AUDIO_CONFIG_INITIALIZER; 8034a54f1283fdd9adbd64ecca4e14af56aaa0e8c825Eric Laurent config.sample_rate = mSampleRate; 8035a54f1283fdd9adbd64ecca4e14af56aaa0e8c825Eric Laurent config.channel_mask = mChannelMask; 8036a54f1283fdd9adbd64ecca4e14af56aaa0e8c825Eric Laurent config.format = mFormat; 8037a54f1283fdd9adbd64ecca4e14af56aaa0e8c825Eric Laurent audio_stream_type_t stream = streamType(); 8038a54f1283fdd9adbd64ecca4e14af56aaa0e8c825Eric Laurent audio_output_flags_t flags = 8039a54f1283fdd9adbd64ecca4e14af56aaa0e8c825Eric Laurent (audio_output_flags_t)(AUDIO_OUTPUT_FLAG_MMAP_NOIRQ | AUDIO_OUTPUT_FLAG_DIRECT); 80407aa0ccbcb6e8d35c894356015c23574619bcf648Eric Laurent audio_port_handle_t deviceId = mDeviceId; 8041a54f1283fdd9adbd64ecca4e14af56aaa0e8c825Eric Laurent ret = AudioSystem::getOutputForAttr(&mAttr, &io, 8042a54f1283fdd9adbd64ecca4e14af56aaa0e8c825Eric Laurent mSessionId, 8043a54f1283fdd9adbd64ecca4e14af56aaa0e8c825Eric Laurent &stream, 8044766fb020a50b64bf9a808bd80df60c54c2ca8cc3Nadav Bar client.clientPid, 8045a54f1283fdd9adbd64ecca4e14af56aaa0e8c825Eric Laurent client.clientUid, 8046a54f1283fdd9adbd64ecca4e14af56aaa0e8c825Eric Laurent &config, 8047a54f1283fdd9adbd64ecca4e14af56aaa0e8c825Eric Laurent flags, 8048a54f1283fdd9adbd64ecca4e14af56aaa0e8c825Eric Laurent &deviceId, 8049a54f1283fdd9adbd64ecca4e14af56aaa0e8c825Eric Laurent &portId); 80506acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } else { 8051a54f1283fdd9adbd64ecca4e14af56aaa0e8c825Eric Laurent audio_config_base_t config; 8052a54f1283fdd9adbd64ecca4e14af56aaa0e8c825Eric Laurent config.sample_rate = mSampleRate; 8053a54f1283fdd9adbd64ecca4e14af56aaa0e8c825Eric Laurent config.channel_mask = mChannelMask; 8054a54f1283fdd9adbd64ecca4e14af56aaa0e8c825Eric Laurent config.format = mFormat; 80557aa0ccbcb6e8d35c894356015c23574619bcf648Eric Laurent audio_port_handle_t deviceId = mDeviceId; 8056a54f1283fdd9adbd64ecca4e14af56aaa0e8c825Eric Laurent ret = AudioSystem::getInputForAttr(&mAttr, &io, 8057a54f1283fdd9adbd64ecca4e14af56aaa0e8c825Eric Laurent mSessionId, 8058a54f1283fdd9adbd64ecca4e14af56aaa0e8c825Eric Laurent client.clientPid, 8059a54f1283fdd9adbd64ecca4e14af56aaa0e8c825Eric Laurent client.clientUid, 8060fee1976a2849c37a53d8a01ac10327d522a1ba93Eric Laurent client.packageName, 8061a54f1283fdd9adbd64ecca4e14af56aaa0e8c825Eric Laurent &config, 8062a54f1283fdd9adbd64ecca4e14af56aaa0e8c825Eric Laurent AUDIO_INPUT_FLAG_MMAP_NOIRQ, 8063a54f1283fdd9adbd64ecca4e14af56aaa0e8c825Eric Laurent &deviceId, 8064a54f1283fdd9adbd64ecca4e14af56aaa0e8c825Eric Laurent &portId); 8065a54f1283fdd9adbd64ecca4e14af56aaa0e8c825Eric Laurent } 8066a54f1283fdd9adbd64ecca4e14af56aaa0e8c825Eric Laurent // APM should not chose a different input or output stream for the same set of attributes 8067a54f1283fdd9adbd64ecca4e14af56aaa0e8c825Eric Laurent // and audo configuration 8068a54f1283fdd9adbd64ecca4e14af56aaa0e8c825Eric Laurent if (ret != NO_ERROR || io != mId) { 8069a54f1283fdd9adbd64ecca4e14af56aaa0e8c825Eric Laurent ALOGE("%s: error getting output or input from APM (error %d, io %d expected io %d)", 8070a54f1283fdd9adbd64ecca4e14af56aaa0e8c825Eric Laurent __FUNCTION__, ret, io, mId); 8071a54f1283fdd9adbd64ecca4e14af56aaa0e8c825Eric Laurent return BAD_VALUE; 80726acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } 80736acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 8074331679c8a5cd21a0e6a7a1d851e965e4721f7420Eric Laurent bool silenced = false; 80756acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent if (isOutput()) { 8076a54f1283fdd9adbd64ecca4e14af56aaa0e8c825Eric Laurent ret = AudioSystem::startOutput(mId, streamType(), mSessionId); 80776acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } else { 8078fee1976a2849c37a53d8a01ac10327d522a1ba93Eric Laurent ret = AudioSystem::startInput(portId, &silenced); 80796acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } 80806acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 8081331679c8a5cd21a0e6a7a1d851e965e4721f7420Eric Laurent Mutex::Autolock _l(mLock); 80826acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent // abort if start is rejected by audio policy manager 80836acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent if (ret != NO_ERROR) { 80847f6b40d78b1976c78d1300e8a51fda36eeb50c5dPhil Burk ALOGE("%s: error start rejected by AudioPolicyManager = %d", __FUNCTION__, ret); 80856acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent if (mActiveTracks.size() != 0) { 8086331679c8a5cd21a0e6a7a1d851e965e4721f7420Eric Laurent mLock.unlock(); 80876acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent if (isOutput()) { 8088a54f1283fdd9adbd64ecca4e14af56aaa0e8c825Eric Laurent AudioSystem::releaseOutput(mId, streamType(), mSessionId); 80896acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } else { 8090fee1976a2849c37a53d8a01ac10327d522a1ba93Eric Laurent AudioSystem::releaseInput(portId); 80916acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } 8092331679c8a5cd21a0e6a7a1d851e965e4721f7420Eric Laurent mLock.lock(); 809318b570146c971fe729c391bfbb869391084e623dEric Laurent } else { 809418b570146c971fe729c391bfbb869391084e623dEric Laurent mHalStream->stop(); 80956acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } 80966acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent return PERMISSION_DENIED; 80976acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } 80986acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 809967f97291bfb7caec5152d2c93913191729db5917Eric Laurent if (isOutput()) { 810067f97291bfb7caec5152d2c93913191729db5917Eric Laurent // force volume update when a new track is added 810167f97291bfb7caec5152d2c93913191729db5917Eric Laurent mHalVolFloat = -1.0f; 810267f97291bfb7caec5152d2c93913191729db5917Eric Laurent } else if (!silenced) { 8103331679c8a5cd21a0e6a7a1d851e965e4721f7420Eric Laurent for (const sp<MmapTrack> &track : mActiveTracks) { 8104331679c8a5cd21a0e6a7a1d851e965e4721f7420Eric Laurent if (track->isSilenced_l() && track->uid() != client.clientUid) 8105331679c8a5cd21a0e6a7a1d851e965e4721f7420Eric Laurent track->invalidate(); 8106331679c8a5cd21a0e6a7a1d851e965e4721f7420Eric Laurent } 8107331679c8a5cd21a0e6a7a1d851e965e4721f7420Eric Laurent } 8108331679c8a5cd21a0e6a7a1d851e965e4721f7420Eric Laurent 81091f564acca544826daaf7dca44e39cec6016b82fdKevin Rocard // Given that MmapThread::mAttr is mutable, should a MmapTrack have attributes ? 81101f564acca544826daaf7dca44e39cec6016b82fdKevin Rocard sp<MmapTrack> track = new MmapTrack(this, mAttr, mSampleRate, mFormat, mChannelMask, mSessionId, 8111a54f1283fdd9adbd64ecca4e14af56aaa0e8c825Eric Laurent client.clientUid, client.clientPid, portId); 81126acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 8113331679c8a5cd21a0e6a7a1d851e965e4721f7420Eric Laurent track->setSilenced_l(silenced); 81146acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent mActiveTracks.add(track); 8115a54f1283fdd9adbd64ecca4e14af56aaa0e8c825Eric Laurent sp<EffectChain> chain = getEffectChain_l(mSessionId); 81166acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent if (chain != 0) { 81176acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent chain->setStrategy(AudioSystem::getStrategyForStream(streamType())); 81186acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent chain->incTrackCnt(); 81196acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent chain->incActiveTrackCnt(); 81206acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } 81216acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 81226acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent *handle = portId; 81236acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent broadcast_l(); 81246acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 8125a54f1283fdd9adbd64ecca4e14af56aaa0e8c825Eric Laurent ALOGV("%s DONE handle %d stream %p", __FUNCTION__, *handle, mHalStream.get()); 81266acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 81276acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent return NO_ERROR; 81286acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent} 81296acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 81306acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurentstatus_t AudioFlinger::MmapThread::stop(audio_port_handle_t handle) 81316acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent{ 81326acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent ALOGV("%s handle %d", __FUNCTION__, handle); 81336acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 81346acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent if (mHalStream == 0) { 81356acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent return NO_INIT; 81366acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } 81376acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 8138a54f1283fdd9adbd64ecca4e14af56aaa0e8c825Eric Laurent if (handle == mPortId) { 8139a54f1283fdd9adbd64ecca4e14af56aaa0e8c825Eric Laurent mHalStream->stop(); 8140a54f1283fdd9adbd64ecca4e14af56aaa0e8c825Eric Laurent return NO_ERROR; 8141a54f1283fdd9adbd64ecca4e14af56aaa0e8c825Eric Laurent } 8142a54f1283fdd9adbd64ecca4e14af56aaa0e8c825Eric Laurent 8143331679c8a5cd21a0e6a7a1d851e965e4721f7420Eric Laurent Mutex::Autolock _l(mLock); 8144331679c8a5cd21a0e6a7a1d851e965e4721f7420Eric Laurent 81456acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent sp<MmapTrack> track; 81466acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent for (const sp<MmapTrack> &t : mActiveTracks) { 81476acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent if (handle == t->portId()) { 81486acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent track = t; 81496acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent break; 81506acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } 81516acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } 81526acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent if (track == 0) { 81536acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent return BAD_VALUE; 81546acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } 81556acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 81566acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent mActiveTracks.remove(track); 81576acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 8158331679c8a5cd21a0e6a7a1d851e965e4721f7420Eric Laurent mLock.unlock(); 81596acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent if (isOutput()) { 81606acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent AudioSystem::stopOutput(mId, streamType(), track->sessionId()); 8161a54f1283fdd9adbd64ecca4e14af56aaa0e8c825Eric Laurent AudioSystem::releaseOutput(mId, streamType(), track->sessionId()); 81626acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } else { 8163fee1976a2849c37a53d8a01ac10327d522a1ba93Eric Laurent AudioSystem::stopInput(track->portId()); 8164fee1976a2849c37a53d8a01ac10327d522a1ba93Eric Laurent AudioSystem::releaseInput(track->portId()); 81656acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } 8166331679c8a5cd21a0e6a7a1d851e965e4721f7420Eric Laurent mLock.lock(); 81676acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 81686acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent sp<EffectChain> chain = getEffectChain_l(track->sessionId()); 81696acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent if (chain != 0) { 81706acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent chain->decActiveTrackCnt(); 81716acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent chain->decTrackCnt(); 81726acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } 81736acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 81746acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent broadcast_l(); 81756acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 81766acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent return NO_ERROR; 81776acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent} 81786acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 817918b570146c971fe729c391bfbb869391084e623dEric Laurentstatus_t AudioFlinger::MmapThread::standby() 818018b570146c971fe729c391bfbb869391084e623dEric Laurent{ 818118b570146c971fe729c391bfbb869391084e623dEric Laurent ALOGV("%s", __FUNCTION__); 818218b570146c971fe729c391bfbb869391084e623dEric Laurent 818318b570146c971fe729c391bfbb869391084e623dEric Laurent if (mHalStream == 0) { 818418b570146c971fe729c391bfbb869391084e623dEric Laurent return NO_INIT; 818518b570146c971fe729c391bfbb869391084e623dEric Laurent } 818618b570146c971fe729c391bfbb869391084e623dEric Laurent if (mActiveTracks.size() != 0) { 818718b570146c971fe729c391bfbb869391084e623dEric Laurent return INVALID_OPERATION; 818818b570146c971fe729c391bfbb869391084e623dEric Laurent } 818918b570146c971fe729c391bfbb869391084e623dEric Laurent mHalStream->standby(); 819018b570146c971fe729c391bfbb869391084e623dEric Laurent mStandby = true; 819118b570146c971fe729c391bfbb869391084e623dEric Laurent releaseWakeLock(); 819218b570146c971fe729c391bfbb869391084e623dEric Laurent return NO_ERROR; 819318b570146c971fe729c391bfbb869391084e623dEric Laurent} 819418b570146c971fe729c391bfbb869391084e623dEric Laurent 81956acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 81966acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurentvoid AudioFlinger::MmapThread::readHalParameters_l() 81976acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent{ 81986acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent status_t result = mHalStream->getAudioProperties(&mSampleRate, &mChannelMask, &mHALFormat); 81996acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent LOG_ALWAYS_FATAL_IF(result != OK, "Error retrieving audio properties from HAL: %d", result); 82006acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent mFormat = mHALFormat; 82016acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent LOG_ALWAYS_FATAL_IF(!audio_is_linear_pcm(mFormat), "HAL format %#x is not linear pcm", mFormat); 82026acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent result = mHalStream->getFrameSize(&mFrameSize); 82036acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent LOG_ALWAYS_FATAL_IF(result != OK, "Error retrieving frame size from HAL: %d", result); 82046acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent result = mHalStream->getBufferSize(&mBufferSize); 82056acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent LOG_ALWAYS_FATAL_IF(result != OK, "Error retrieving buffer size from HAL: %d", result); 82066acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent mFrameCount = mBufferSize / mFrameSize; 82076acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent} 82086acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 82096acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurentbool AudioFlinger::MmapThread::threadLoop() 82106acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent{ 82116acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent checkSilentMode_l(); 82126acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 82136acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent const String8 myName(String8::format("thread %p type %d TID %d", this, mType, gettid())); 82146acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 82156acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent while (!exitPending()) 82166acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent { 82176acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent Mutex::Autolock _l(mLock); 82186acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent Vector< sp<EffectChain> > effectChains; 82196acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 82206acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent if (mSignalPending) { 82216acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent // A signal was raised while we were unlocked 82226acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent mSignalPending = false; 82236acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } else { 82246acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent if (mConfigEvents.isEmpty()) { 82256acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent // we're about to wait, flush the binder command buffer 82266acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent IPCThreadState::self()->flushCommands(); 82276acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 82286acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent if (exitPending()) { 82296acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent break; 82306acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } 82316acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 82326acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent // wait until we have something to do... 82336acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent ALOGV("%s going to sleep", myName.string()); 82346acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent mWaitWorkCV.wait(mLock); 82356acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent ALOGV("%s waking up", myName.string()); 82366acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 82376acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent checkSilentMode_l(); 82386acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 82396acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent continue; 82406acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } 82416acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } 82426acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 82436acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent processConfigEvents_l(); 82446acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 82456acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent processVolume_l(); 82466acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 82476acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent checkInvalidTracks_l(); 82486acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 82496acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent mActiveTracks.updatePowerState(this); 82506acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 8251069c2719e753732d5af9ba51e5fcc34342b0c9f2Kevin Rocard updateMetadata_l(); 8252069c2719e753732d5af9ba51e5fcc34342b0c9f2Kevin Rocard 82536acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent lockEffectChains_l(effectChains); 82546acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent for (size_t i = 0; i < effectChains.size(); i ++) { 82556acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent effectChains[i]->process_l(); 82566acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } 82576acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent // enable changes in effect chain 82586acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent unlockEffectChains(effectChains); 82596acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent // Effect chains will be actually deleted here if they were removed from 82606acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent // mEffectChains list during mixing or effects processing 82616acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } 82626acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 82636acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent threadLoop_exit(); 82646acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 82656acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent if (!mStandby) { 82666acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent threadLoop_standby(); 82676acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent mStandby = true; 82686acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } 82696acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 82706acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent ALOGV("Thread %p type %d exiting", this, mType); 82716acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent return false; 82726acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent} 82736acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 82746acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent// checkForNewParameter_l() must be called with ThreadBase::mLock held 82756acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurentbool AudioFlinger::MmapThread::checkForNewParameter_l(const String8& keyValuePair, 82766acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent status_t& status) 82776acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent{ 82786acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent AudioParameter param = AudioParameter(keyValuePair); 82796acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent int value; 8280e6e9a4811dc43e5c393b2c45eca64d1f1608e8d0Eric Laurent bool sendToHal = true; 82816acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent if (param.getInt(String8(AudioParameter::keyRouting), value) == NO_ERROR) { 8282e6e9a4811dc43e5c393b2c45eca64d1f1608e8d0Eric Laurent audio_devices_t device = (audio_devices_t)value; 82836acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent // forward device change to effects that have requested to be 82846acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent // aware of attached audio device. 8285e6e9a4811dc43e5c393b2c45eca64d1f1608e8d0Eric Laurent if (device != AUDIO_DEVICE_NONE) { 82866acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent for (size_t i = 0; i < mEffectChains.size(); i++) { 8287e6e9a4811dc43e5c393b2c45eca64d1f1608e8d0Eric Laurent mEffectChains[i]->setDevice_l(device); 82886acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } 82896acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } 8290e6e9a4811dc43e5c393b2c45eca64d1f1608e8d0Eric Laurent if (audio_is_output_devices(device)) { 8291e6e9a4811dc43e5c393b2c45eca64d1f1608e8d0Eric Laurent mOutDevice = device; 8292e6e9a4811dc43e5c393b2c45eca64d1f1608e8d0Eric Laurent if (!isOutput()) { 8293e6e9a4811dc43e5c393b2c45eca64d1f1608e8d0Eric Laurent sendToHal = false; 8294e6e9a4811dc43e5c393b2c45eca64d1f1608e8d0Eric Laurent } 8295e6e9a4811dc43e5c393b2c45eca64d1f1608e8d0Eric Laurent } else { 8296e6e9a4811dc43e5c393b2c45eca64d1f1608e8d0Eric Laurent mInDevice = device; 8297e6e9a4811dc43e5c393b2c45eca64d1f1608e8d0Eric Laurent if (device != AUDIO_DEVICE_NONE) { 8298e6e9a4811dc43e5c393b2c45eca64d1f1608e8d0Eric Laurent mPrevInDevice = value; 8299e6e9a4811dc43e5c393b2c45eca64d1f1608e8d0Eric Laurent } 8300e6e9a4811dc43e5c393b2c45eca64d1f1608e8d0Eric Laurent // TODO: implement and call checkBtNrec_l(); 8301e6e9a4811dc43e5c393b2c45eca64d1f1608e8d0Eric Laurent } 8302e6e9a4811dc43e5c393b2c45eca64d1f1608e8d0Eric Laurent } 8303e6e9a4811dc43e5c393b2c45eca64d1f1608e8d0Eric Laurent if (sendToHal) { 8304e6e9a4811dc43e5c393b2c45eca64d1f1608e8d0Eric Laurent status = mHalStream->setParameters(keyValuePair); 8305e6e9a4811dc43e5c393b2c45eca64d1f1608e8d0Eric Laurent } else { 8306e6e9a4811dc43e5c393b2c45eca64d1f1608e8d0Eric Laurent status = NO_ERROR; 83076acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } 83086acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 83096acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent return false; 83106acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent} 83116acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 83126acd1d432f526ae9a055ddaece28bf93b474a776Eric LaurentString8 AudioFlinger::MmapThread::getParameters(const String8& keys) 83136acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent{ 83146acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent Mutex::Autolock _l(mLock); 83156acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent String8 out_s8; 83166acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent if (initCheck() == NO_ERROR && mHalStream->getParameters(keys, &out_s8) == OK) { 83176acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent return out_s8; 83186acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } 83196acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent return String8(); 83206acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent} 83216acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 83226acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurentvoid AudioFlinger::MmapThread::ioConfigChanged(audio_io_config_event event, pid_t pid) { 83236acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent sp<AudioIoDescriptor> desc = new AudioIoDescriptor(); 83246acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 83256acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent desc->mIoHandle = mId; 83266acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 83276acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent switch (event) { 83286acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent case AUDIO_INPUT_OPENED: 8329ad2e7b902c0432a0db40906a4b1f5b693ce439ddEric Laurent case AUDIO_INPUT_REGISTERED: 83306acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent case AUDIO_INPUT_CONFIG_CHANGED: 83316acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent case AUDIO_OUTPUT_OPENED: 8332ad2e7b902c0432a0db40906a4b1f5b693ce439ddEric Laurent case AUDIO_OUTPUT_REGISTERED: 83336acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent case AUDIO_OUTPUT_CONFIG_CHANGED: 83346acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent desc->mPatch = mPatch; 83356acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent desc->mChannelMask = mChannelMask; 83366acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent desc->mSamplingRate = mSampleRate; 83376acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent desc->mFormat = mFormat; 83386acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent desc->mFrameCount = mFrameCount; 83396acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent desc->mFrameCountHAL = mFrameCount; 83406acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent desc->mLatency = 0; 83416acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent break; 83426acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 83436acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent case AUDIO_INPUT_CLOSED: 83446acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent case AUDIO_OUTPUT_CLOSED: 83456acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent default: 83466acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent break; 83476acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } 83486acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent mAudioFlinger->ioConfigChanged(event, desc, pid); 83496acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent} 83506acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 83516acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurentstatus_t AudioFlinger::MmapThread::createAudioPatch_l(const struct audio_patch *patch, 83526acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent audio_patch_handle_t *handle) 83536acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent{ 83546acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent status_t status = NO_ERROR; 83556acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 83566acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent // store new device and send to effects 83576acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent audio_devices_t type = AUDIO_DEVICE_NONE; 83586acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent audio_port_handle_t deviceId; 83596acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent if (isOutput()) { 83606acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent for (unsigned int i = 0; i < patch->num_sinks; i++) { 83616acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent type |= patch->sinks[i].ext.device.type; 83626acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } 83636acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent deviceId = patch->sinks[0].id; 83646acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } else { 83656acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent type = patch->sources[0].ext.device.type; 83666acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent deviceId = patch->sources[0].id; 83676acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } 83686acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 83696acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent for (size_t i = 0; i < mEffectChains.size(); i++) { 83706acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent mEffectChains[i]->setDevice_l(type); 83716acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } 83726acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 83736acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent if (isOutput()) { 83746acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent mOutDevice = type; 83756acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } else { 83766acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent mInDevice = type; 83776acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent // store new source and send to effects 83786acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent if (mAudioSource != patch->sinks[0].ext.mix.usecase.source) { 83796acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent mAudioSource = patch->sinks[0].ext.mix.usecase.source; 83806acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent for (size_t i = 0; i < mEffectChains.size(); i++) { 83816acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent mEffectChains[i]->setAudioSource_l(mAudioSource); 83826acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } 83836acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } 83846acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } 83856acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 83866acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent if (mAudioHwDev->supportsAudioPatches()) { 83876acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent status = mHalDevice->createAudioPatch(patch->num_sources, 83886acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent patch->sources, 83896acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent patch->num_sinks, 83906acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent patch->sinks, 83916acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent handle); 83926acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } else { 83936acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent char *address; 83946acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent if (strcmp(patch->sinks[0].ext.device.address, "") != 0) { 83956acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent //FIXME: we only support address on first sink with HAL version < 3.0 83966acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent address = audio_device_address_to_parameter( 83976acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent patch->sinks[0].ext.device.type, 83986acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent patch->sinks[0].ext.device.address); 83996acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } else { 84006acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent address = (char *)calloc(1, 1); 84016acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } 84026acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent AudioParameter param = AudioParameter(String8(address)); 84036acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent free(address); 84046acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent param.addInt(String8(AudioParameter::keyRouting), (int)type); 84056acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent if (!isOutput()) { 84066acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent param.addInt(String8(AudioParameter::keyInputSource), 84076acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent (int)patch->sinks[0].ext.mix.usecase.source); 84086acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } 84096acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent status = mHalStream->setParameters(param.toString()); 84106acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent *handle = AUDIO_PATCH_HANDLE_NONE; 84116acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } 84126acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 84136acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent if (isOutput() && mPrevOutDevice != mOutDevice) { 84146acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent mPrevOutDevice = type; 84156acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent sendIoConfigEvent_l(AUDIO_OUTPUT_CONFIG_CHANGED); 84167f6b40d78b1976c78d1300e8a51fda36eeb50c5dPhil Burk sp<MmapStreamCallback> callback = mCallback.promote(); 84177aa0ccbcb6e8d35c894356015c23574619bcf648Eric Laurent if (mDeviceId != deviceId && callback != 0) { 8418734046ead103df5ec86b1dbd29e9945034a1ecb0Eric Laurent mLock.unlock(); 84197f6b40d78b1976c78d1300e8a51fda36eeb50c5dPhil Burk callback->onRoutingChanged(deviceId); 8420734046ead103df5ec86b1dbd29e9945034a1ecb0Eric Laurent mLock.lock(); 84216acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } 84227aa0ccbcb6e8d35c894356015c23574619bcf648Eric Laurent mDeviceId = deviceId; 84236acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } 84246acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent if (!isOutput() && mPrevInDevice != mInDevice) { 84256acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent mPrevInDevice = type; 84266acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent sendIoConfigEvent_l(AUDIO_INPUT_CONFIG_CHANGED); 84277f6b40d78b1976c78d1300e8a51fda36eeb50c5dPhil Burk sp<MmapStreamCallback> callback = mCallback.promote(); 84287aa0ccbcb6e8d35c894356015c23574619bcf648Eric Laurent if (mDeviceId != deviceId && callback != 0) { 8429734046ead103df5ec86b1dbd29e9945034a1ecb0Eric Laurent mLock.unlock(); 84307f6b40d78b1976c78d1300e8a51fda36eeb50c5dPhil Burk callback->onRoutingChanged(deviceId); 8431734046ead103df5ec86b1dbd29e9945034a1ecb0Eric Laurent mLock.lock(); 84326acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } 84337aa0ccbcb6e8d35c894356015c23574619bcf648Eric Laurent mDeviceId = deviceId; 84346acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } 84356acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent return status; 84366acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent} 84376acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 84386acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurentstatus_t AudioFlinger::MmapThread::releaseAudioPatch_l(const audio_patch_handle_t handle) 84396acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent{ 84406acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent status_t status = NO_ERROR; 84416acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 84426acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent mInDevice = AUDIO_DEVICE_NONE; 84436acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 84446acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent bool supportsAudioPatches = mHalDevice->supportsAudioPatches(&supportsAudioPatches) == OK ? 84456acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent supportsAudioPatches : false; 84466acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 84476acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent if (supportsAudioPatches) { 84486acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent status = mHalDevice->releaseAudioPatch(handle); 84496acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } else { 84506acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent AudioParameter param; 84516acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent param.addInt(String8(AudioParameter::keyRouting), 0); 84526acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent status = mHalStream->setParameters(param.toString()); 84536acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } 84546acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent return status; 84556acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent} 84566acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 84576acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurentvoid AudioFlinger::MmapThread::getAudioPortConfig(struct audio_port_config *config) 84586acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent{ 84596acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent ThreadBase::getAudioPortConfig(config); 84606acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent if (isOutput()) { 84616acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent config->role = AUDIO_PORT_ROLE_SOURCE; 84626acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent config->ext.mix.hw_module = mAudioHwDev->handle(); 84636acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent config->ext.mix.usecase.stream = AUDIO_STREAM_DEFAULT; 84646acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } else { 84656acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent config->role = AUDIO_PORT_ROLE_SINK; 84666acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent config->ext.mix.hw_module = mAudioHwDev->handle(); 84676acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent config->ext.mix.usecase.source = mAudioSource; 84686acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } 84696acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent} 84706acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 84716acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurentstatus_t AudioFlinger::MmapThread::addEffectChain_l(const sp<EffectChain>& chain) 84726acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent{ 84736acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent audio_session_t session = chain->sessionId(); 84746acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 84756acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent ALOGV("addEffectChain_l() %p on thread %p for session %d", chain.get(), this, session); 84766acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent // Attach all tracks with same session ID to this chain. 84776acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent // indicate all active tracks in the chain 84786acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent for (const sp<MmapTrack> &track : mActiveTracks) { 84796acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent if (session == track->sessionId()) { 84806acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent chain->incTrackCnt(); 84816acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent chain->incActiveTrackCnt(); 84826acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } 84836acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } 84846acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 84856acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent chain->setThread(this); 84866acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent chain->setInBuffer(nullptr); 84876acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent chain->setOutBuffer(nullptr); 84886acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent chain->syncHalEffectsState(); 84896acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 84906acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent mEffectChains.add(chain); 84916acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent checkSuspendOnAddEffectChain_l(chain); 84926acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent return NO_ERROR; 84936acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent} 84946acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 84956acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurentsize_t AudioFlinger::MmapThread::removeEffectChain_l(const sp<EffectChain>& chain) 84966acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent{ 84976acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent audio_session_t session = chain->sessionId(); 84986acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 84996acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent ALOGV("removeEffectChain_l() %p from thread %p for session %d", chain.get(), this, session); 85006acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 85016acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent for (size_t i = 0; i < mEffectChains.size(); i++) { 85026acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent if (chain == mEffectChains[i]) { 85036acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent mEffectChains.removeAt(i); 85046acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent // detach all active tracks from the chain 85056acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent // detach all tracks with same session ID from this chain 85066acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent for (const sp<MmapTrack> &track : mActiveTracks) { 85076acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent if (session == track->sessionId()) { 85086acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent chain->decActiveTrackCnt(); 85096acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent chain->decTrackCnt(); 85106acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } 85116acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } 85126acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent break; 85136acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } 85146acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } 85156acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent return mEffectChains.size(); 85166acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent} 85176acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 85186acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent// hasAudioSession_l() must be called with ThreadBase::mLock held 85196acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurentuint32_t AudioFlinger::MmapThread::hasAudioSession_l(audio_session_t sessionId) const 85206acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent{ 85216acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent uint32_t result = 0; 85226acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent if (getEffectChain_l(sessionId) != 0) { 85236acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent result = EFFECT_SESSION; 85246acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } 85256acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 85266acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent for (size_t i = 0; i < mActiveTracks.size(); i++) { 85276acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent sp<MmapTrack> track = mActiveTracks[i]; 85286acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent if (sessionId == track->sessionId()) { 85296acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent result |= TRACK_SESSION; 85306acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent if (track->isFastTrack()) { 85316acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent result |= FAST_SESSION; 85326acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } 85336acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent break; 85346acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } 85356acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } 85366acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 85376acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent return result; 85386acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent} 85396acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 85406acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurentvoid AudioFlinger::MmapThread::threadLoop_standby() 85416acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent{ 85426acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent mHalStream->standby(); 85436acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent} 85446acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 85456acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurentvoid AudioFlinger::MmapThread::threadLoop_exit() 85466acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent{ 85477dce72819e3a12ef290f475c876bec3824be9312Phil Burk // Do not call callback->onTearDown() because it is redundant for thread exit 85487dce72819e3a12ef290f475c876bec3824be9312Phil Burk // and because it can cause a recursive mutex lock on stop(). 85496acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent} 85506acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 85516acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurentstatus_t AudioFlinger::MmapThread::setSyncEvent(const sp<SyncEvent>& event __unused) 85526acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent{ 85536acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent return BAD_VALUE; 85546acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent} 85556acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 85566acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurentbool AudioFlinger::MmapThread::isValidSyncEvent(const sp<SyncEvent>& event __unused) const 85576acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent{ 85586acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent return false; 85596acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent} 85606acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 85616acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurentstatus_t AudioFlinger::MmapThread::checkEffectCompatibility_l( 85626acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent const effect_descriptor_t *desc, audio_session_t sessionId) 85636acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent{ 85646acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent // No global effect sessions on mmap threads 85656acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent if (sessionId == AUDIO_SESSION_OUTPUT_MIX || sessionId == AUDIO_SESSION_OUTPUT_STAGE) { 85666acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent ALOGW("checkEffectCompatibility_l(): global effect %s on record thread %s", 85676acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent desc->name, mThreadName); 85686acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent return BAD_VALUE; 85696acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } 85706acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 85716acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent if (!isOutput() && ((desc->flags & EFFECT_FLAG_TYPE_MASK) != EFFECT_FLAG_TYPE_PRE_PROC)) { 85726acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent ALOGW("checkEffectCompatibility_l(): non pre processing effect %s on capture mmap thread", 85736acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent desc->name); 85746acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent return BAD_VALUE; 85756acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } 85766acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent if (isOutput() && ((desc->flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_PRE_PROC)) { 8577d3bb645f0b7f567b033b8664499d685f8ec10628Glenn Kasten ALOGW("checkEffectCompatibility_l(): pre processing effect %s created on playback mmap " 8578d3bb645f0b7f567b033b8664499d685f8ec10628Glenn Kasten "thread", desc->name); 85796acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent return BAD_VALUE; 85806acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } 85816acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 85826acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent // Only allow effects without processing load or latency 85836acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent if ((desc->flags & EFFECT_FLAG_NO_PROCESS_MASK) != EFFECT_FLAG_NO_PROCESS) { 85846acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent return BAD_VALUE; 85856acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } 85866acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 85876acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent return NO_ERROR; 85886acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 85896acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent} 85906acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 85916acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurentvoid AudioFlinger::MmapThread::checkInvalidTracks_l() 85926acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent{ 85936acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent for (const sp<MmapTrack> &track : mActiveTracks) { 85946acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent if (track->isInvalid()) { 85957f6b40d78b1976c78d1300e8a51fda36eeb50c5dPhil Burk sp<MmapStreamCallback> callback = mCallback.promote(); 85967f6b40d78b1976c78d1300e8a51fda36eeb50c5dPhil Burk if (callback != 0) { 8597734046ead103df5ec86b1dbd29e9945034a1ecb0Eric Laurent mLock.unlock(); 8598331679c8a5cd21a0e6a7a1d851e965e4721f7420Eric Laurent callback->onTearDown(track->portId()); 8599734046ead103df5ec86b1dbd29e9945034a1ecb0Eric Laurent mLock.lock(); 8600331679c8a5cd21a0e6a7a1d851e965e4721f7420Eric Laurent } else if (mNoCallbackWarningCount < kMaxNoCallbackWarnings) { 8601331679c8a5cd21a0e6a7a1d851e965e4721f7420Eric Laurent ALOGW("Could not notify MMAP stream tear down: no onTearDown callback!"); 8602331679c8a5cd21a0e6a7a1d851e965e4721f7420Eric Laurent mNoCallbackWarningCount++; 86036acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } 86046acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } 86056acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } 86066acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent} 86076acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 86086acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurentvoid AudioFlinger::MmapThread::dump(int fd, const Vector<String16>& args) 86096acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent{ 86106acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent dumpInternals(fd, args); 86116acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent dumpTracks(fd, args); 86126acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent dumpEffectChains(fd, args); 86132c6c3bb76b2fa18ed3536331a1700250bd04c7ceAndy Hung dprintf(fd, " Local log:\n"); 86142c6c3bb76b2fa18ed3536331a1700250bd04c7ceAndy Hung mLocalLog.dump(fd, " " /* prefix */, 40 /* lines */); 86156acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent} 86166acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 86176acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurentvoid AudioFlinger::MmapThread::dumpInternals(int fd, const Vector<String16>& args) 86186acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent{ 86196acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent dumpBase(fd, args); 86206acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 86216acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent dprintf(fd, " Attributes: content type %d usage %d source %d\n", 86226acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent mAttr.content_type, mAttr.usage, mAttr.source); 86236acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent dprintf(fd, " Session: %d port Id: %d\n", mSessionId, mPortId); 86246acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent if (mActiveTracks.size() == 0) { 86256acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent dprintf(fd, " No active clients\n"); 86266acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } 86276acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent} 86286acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 86296acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurentvoid AudioFlinger::MmapThread::dumpTracks(int fd, const Vector<String16>& args __unused) 86306acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent{ 86316acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent String8 result; 86326acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent size_t numtracks = mActiveTracks.size(); 86332c6c3bb76b2fa18ed3536331a1700250bd04c7ceAndy Hung dprintf(fd, " %zu Tracks\n", numtracks); 86342c6c3bb76b2fa18ed3536331a1700250bd04c7ceAndy Hung const char *prefix = " "; 86356acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent if (numtracks) { 86362c6c3bb76b2fa18ed3536331a1700250bd04c7ceAndy Hung result.append(prefix); 86376acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent MmapTrack::appendDumpHeader(result); 86386acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent for (size_t i = 0; i < numtracks ; ++i) { 86396acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent sp<MmapTrack> track = mActiveTracks[i]; 86402c6c3bb76b2fa18ed3536331a1700250bd04c7ceAndy Hung result.append(prefix); 86412c6c3bb76b2fa18ed3536331a1700250bd04c7ceAndy Hung track->appendDump(result, true /* active */); 86426acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } 86436acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } else { 86446acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent dprintf(fd, "\n"); 86456acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } 86466acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent write(fd, result.string(), result.size()); 86476acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent} 86486acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 86496acd1d432f526ae9a055ddaece28bf93b474a776Eric LaurentAudioFlinger::MmapPlaybackThread::MmapPlaybackThread( 86506acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent const sp<AudioFlinger>& audioFlinger, audio_io_handle_t id, 86516acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent AudioHwDevice *hwDev, AudioStreamOut *output, 86526acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent audio_devices_t outDevice, audio_devices_t inDevice, bool systemReady) 86536acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent : MmapThread(audioFlinger, id, hwDev, output->stream, outDevice, inDevice, systemReady), 86546acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent mStreamType(AUDIO_STREAM_MUSIC), 865556ecf3e3ce36d111a17d67485047836660128629Phil Burk mStreamVolume(1.0), 865656ecf3e3ce36d111a17d67485047836660128629Phil Burk mStreamMute(false), 865756ecf3e3ce36d111a17d67485047836660128629Phil Burk mOutput(output) 86586acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent{ 86596acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent snprintf(mThreadName, kThreadNameLength, "AudioMmapOut_%X", id); 86606acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent mChannelCount = audio_channel_count_from_out_mask(mChannelMask); 86616acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent mMasterVolume = audioFlinger->masterVolume_l(); 86626acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent mMasterMute = audioFlinger->masterMute_l(); 86636acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent if (mAudioHwDev) { 86646acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent if (mAudioHwDev->canSetMasterVolume()) { 86656acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent mMasterVolume = 1.0; 86666acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } 86676acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 86686acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent if (mAudioHwDev->canSetMasterMute()) { 86696acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent mMasterMute = false; 86706acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } 86716acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } 86726acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent} 86736acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 86746acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurentvoid AudioFlinger::MmapPlaybackThread::configure(const audio_attributes_t *attr, 86756acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent audio_stream_type_t streamType, 86766acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent audio_session_t sessionId, 86776acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent const sp<MmapStreamCallback>& callback, 86787aa0ccbcb6e8d35c894356015c23574619bcf648Eric Laurent audio_port_handle_t deviceId, 86796acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent audio_port_handle_t portId) 86806acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent{ 86817aa0ccbcb6e8d35c894356015c23574619bcf648Eric Laurent MmapThread::configure(attr, streamType, sessionId, callback, deviceId, portId); 86826acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent mStreamType = streamType; 86836acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent} 86846acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 86856acd1d432f526ae9a055ddaece28bf93b474a776Eric LaurentAudioStreamOut* AudioFlinger::MmapPlaybackThread::clearOutput() 86866acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent{ 86876acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent Mutex::Autolock _l(mLock); 86886acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent AudioStreamOut *output = mOutput; 86896acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent mOutput = NULL; 86906acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent return output; 86916acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent} 86926acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 86936acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurentvoid AudioFlinger::MmapPlaybackThread::setMasterVolume(float value) 86946acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent{ 86956acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent Mutex::Autolock _l(mLock); 86966acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent // Don't apply master volume in SW if our HAL can do it for us. 86976acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent if (mAudioHwDev && 86986acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent mAudioHwDev->canSetMasterVolume()) { 86996acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent mMasterVolume = 1.0; 87006acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } else { 87016acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent mMasterVolume = value; 87026acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } 87036acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent} 87046acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 87056acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurentvoid AudioFlinger::MmapPlaybackThread::setMasterMute(bool muted) 87066acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent{ 87076acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent Mutex::Autolock _l(mLock); 87086acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent // Don't apply master mute in SW if our HAL can do it for us. 87096acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent if (mAudioHwDev && mAudioHwDev->canSetMasterMute()) { 87106acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent mMasterMute = false; 87116acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } else { 87126acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent mMasterMute = muted; 87136acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } 87146acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent} 87156acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 87166acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurentvoid AudioFlinger::MmapPlaybackThread::setStreamVolume(audio_stream_type_t stream, float value) 87176acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent{ 87186acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent Mutex::Autolock _l(mLock); 87196acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent if (stream == mStreamType) { 87206acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent mStreamVolume = value; 87216acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent broadcast_l(); 87226acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } 87236acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent} 87246acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 87256acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurentfloat AudioFlinger::MmapPlaybackThread::streamVolume(audio_stream_type_t stream) const 87266acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent{ 87276acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent Mutex::Autolock _l(mLock); 87286acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent if (stream == mStreamType) { 87296acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent return mStreamVolume; 87306acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } 87316acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent return 0.0f; 87326acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent} 87336acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 87346acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurentvoid AudioFlinger::MmapPlaybackThread::setStreamMute(audio_stream_type_t stream, bool muted) 87356acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent{ 87366acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent Mutex::Autolock _l(mLock); 87376acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent if (stream == mStreamType) { 87386acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent mStreamMute= muted; 87396acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent broadcast_l(); 87406acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } 87416acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent} 87426acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 87436acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurentvoid AudioFlinger::MmapPlaybackThread::invalidateTracks(audio_stream_type_t streamType) 87446acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent{ 87456acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent Mutex::Autolock _l(mLock); 87466acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent if (streamType == mStreamType) { 87476acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent for (const sp<MmapTrack> &track : mActiveTracks) { 87486acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent track->invalidate(); 87496acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } 87506acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent broadcast_l(); 87516acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } 87526acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent} 87536acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 87546acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurentvoid AudioFlinger::MmapPlaybackThread::processVolume_l() 87556acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent{ 87566acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent float volume; 87576acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 87586acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent if (mMasterMute || mStreamMute) { 87596acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent volume = 0; 87606acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } else { 87616acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent volume = mMasterVolume * mStreamVolume; 87626acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } 87636acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 87646acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent if (volume != mHalVolFloat) { 87656acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 87666acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent // Convert volumes from float to 8.24 87676acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent uint32_t vol = (uint32_t)(volume * (1 << 24)); 87686acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 87696acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent // Delegate volume control to effect in track effect chain if needed 87706acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent // only one effect chain can be present on DirectOutputThread, so if 87716acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent // there is one, the track is connected to it 87726acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent if (!mEffectChains.isEmpty()) { 87736acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent mEffectChains[0]->setVolume_l(&vol, &vol); 87746acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent volume = (float)vol / (1 << 24); 87756acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } 8776dff774afa22569774eb2c8c25b1b3f934badea4bEric Laurent // Try to use HW volume control and fall back to SW control if not implemented 877756ecf3e3ce36d111a17d67485047836660128629Phil Burk if (mOutput->stream->setVolume(volume, volume) == NO_ERROR) { 877856ecf3e3ce36d111a17d67485047836660128629Phil Burk mHalVolFloat = volume; // HW volume control worked, so update value. 877956ecf3e3ce36d111a17d67485047836660128629Phil Burk mNoCallbackWarningCount = 0; 878056ecf3e3ce36d111a17d67485047836660128629Phil Burk } else { 8781dff774afa22569774eb2c8c25b1b3f934badea4bEric Laurent sp<MmapStreamCallback> callback = mCallback.promote(); 8782dff774afa22569774eb2c8c25b1b3f934badea4bEric Laurent if (callback != 0) { 8783dff774afa22569774eb2c8c25b1b3f934badea4bEric Laurent int channelCount; 8784dff774afa22569774eb2c8c25b1b3f934badea4bEric Laurent if (isOutput()) { 8785dff774afa22569774eb2c8c25b1b3f934badea4bEric Laurent channelCount = audio_channel_count_from_out_mask(mChannelMask); 8786dff774afa22569774eb2c8c25b1b3f934badea4bEric Laurent } else { 8787dff774afa22569774eb2c8c25b1b3f934badea4bEric Laurent channelCount = audio_channel_count_from_in_mask(mChannelMask); 8788dff774afa22569774eb2c8c25b1b3f934badea4bEric Laurent } 8789dff774afa22569774eb2c8c25b1b3f934badea4bEric Laurent Vector<float> values; 8790dff774afa22569774eb2c8c25b1b3f934badea4bEric Laurent for (int i = 0; i < channelCount; i++) { 8791dff774afa22569774eb2c8c25b1b3f934badea4bEric Laurent values.add(volume); 8792dff774afa22569774eb2c8c25b1b3f934badea4bEric Laurent } 879356ecf3e3ce36d111a17d67485047836660128629Phil Burk mHalVolFloat = volume; // SW volume control worked, so update value. 879456ecf3e3ce36d111a17d67485047836660128629Phil Burk mNoCallbackWarningCount = 0; 8795734046ead103df5ec86b1dbd29e9945034a1ecb0Eric Laurent mLock.unlock(); 8796734046ead103df5ec86b1dbd29e9945034a1ecb0Eric Laurent callback->onVolumeChanged(mChannelMask, values); 8797734046ead103df5ec86b1dbd29e9945034a1ecb0Eric Laurent mLock.lock(); 87986acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } else { 879956ecf3e3ce36d111a17d67485047836660128629Phil Burk if (mNoCallbackWarningCount < kMaxNoCallbackWarnings) { 880056ecf3e3ce36d111a17d67485047836660128629Phil Burk ALOGW("Could not set MMAP stream volume: no volume callback!"); 880156ecf3e3ce36d111a17d67485047836660128629Phil Burk mNoCallbackWarningCount++; 880256ecf3e3ce36d111a17d67485047836660128629Phil Burk } 88036acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } 88046acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } 88056acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } 88066acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent} 88076acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 8808069c2719e753732d5af9ba51e5fcc34342b0c9f2Kevin Rocardvoid AudioFlinger::MmapPlaybackThread::updateMetadata_l() 8809069c2719e753732d5af9ba51e5fcc34342b0c9f2Kevin Rocard{ 8810069c2719e753732d5af9ba51e5fcc34342b0c9f2Kevin Rocard if (mOutput == nullptr || mOutput->stream == nullptr || 8811069c2719e753732d5af9ba51e5fcc34342b0c9f2Kevin Rocard !mActiveTracks.readAndClearHasChanged()) { 8812069c2719e753732d5af9ba51e5fcc34342b0c9f2Kevin Rocard return; 8813069c2719e753732d5af9ba51e5fcc34342b0c9f2Kevin Rocard } 8814069c2719e753732d5af9ba51e5fcc34342b0c9f2Kevin Rocard StreamOutHalInterface::SourceMetadata metadata; 8815069c2719e753732d5af9ba51e5fcc34342b0c9f2Kevin Rocard for (const sp<MmapTrack> &track : mActiveTracks) { 8816069c2719e753732d5af9ba51e5fcc34342b0c9f2Kevin Rocard // No track is invalid as this is called after prepareTrack_l in the same critical section 8817069c2719e753732d5af9ba51e5fcc34342b0c9f2Kevin Rocard metadata.tracks.push_back({ 8818069c2719e753732d5af9ba51e5fcc34342b0c9f2Kevin Rocard .usage = track->attributes().usage, 8819069c2719e753732d5af9ba51e5fcc34342b0c9f2Kevin Rocard .content_type = track->attributes().content_type, 8820069c2719e753732d5af9ba51e5fcc34342b0c9f2Kevin Rocard .gain = mHalVolFloat, // TODO: propagate from aaudio pre-mix volume 8821069c2719e753732d5af9ba51e5fcc34342b0c9f2Kevin Rocard }); 8822069c2719e753732d5af9ba51e5fcc34342b0c9f2Kevin Rocard } 8823069c2719e753732d5af9ba51e5fcc34342b0c9f2Kevin Rocard mOutput->stream->updateSourceMetadata(metadata); 8824069c2719e753732d5af9ba51e5fcc34342b0c9f2Kevin Rocard} 8825069c2719e753732d5af9ba51e5fcc34342b0c9f2Kevin Rocard 88266acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurentvoid AudioFlinger::MmapPlaybackThread::checkSilentMode_l() 88276acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent{ 88286acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent if (!mMasterMute) { 88296acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent char value[PROPERTY_VALUE_MAX]; 88306acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent if (property_get("ro.audio.silent", value, "0") > 0) { 88316acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent char *endptr; 88326acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent unsigned long ul = strtoul(value, &endptr, 0); 88336acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent if (*endptr == '\0' && ul != 0) { 88346acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent ALOGD("Silence is golden"); 88356acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent // The setprop command will not allow a property to be changed after 88366acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent // the first time it is set, so we don't have to worry about un-muting. 88376acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent setMasterMute_l(true); 88386acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } 88396acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } 88406acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent } 88416acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent} 88426acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 88436acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurentvoid AudioFlinger::MmapPlaybackThread::dumpInternals(int fd, const Vector<String16>& args) 88446acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent{ 88456acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent MmapThread::dumpInternals(fd, args); 88466acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 8847d3bb645f0b7f567b033b8664499d685f8ec10628Glenn Kasten dprintf(fd, " Stream type: %d Stream volume: %f HAL volume: %f Stream mute %d\n", 8848d3bb645f0b7f567b033b8664499d685f8ec10628Glenn Kasten mStreamType, mStreamVolume, mHalVolFloat, mStreamMute); 88496acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent dprintf(fd, " Master volume: %f Master mute %d\n", mMasterVolume, mMasterMute); 88506acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent} 88516acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 88526acd1d432f526ae9a055ddaece28bf93b474a776Eric LaurentAudioFlinger::MmapCaptureThread::MmapCaptureThread( 88536acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent const sp<AudioFlinger>& audioFlinger, audio_io_handle_t id, 88546acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent AudioHwDevice *hwDev, AudioStreamIn *input, 88556acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent audio_devices_t outDevice, audio_devices_t inDevice, bool systemReady) 88566acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent : MmapThread(audioFlinger, id, hwDev, input->stream, outDevice, inDevice, systemReady), 88576acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent mInput(input) 88586acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent{ 88596acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent snprintf(mThreadName, kThreadNameLength, "AudioMmapIn_%X", id); 88606acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent mChannelCount = audio_channel_count_from_in_mask(mChannelMask); 88616acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent} 88626acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent 8863331679c8a5cd21a0e6a7a1d851e965e4721f7420Eric Laurentstatus_t AudioFlinger::MmapCaptureThread::exitStandby() 8864331679c8a5cd21a0e6a7a1d851e965e4721f7420Eric Laurent{ 8865331679c8a5cd21a0e6a7a1d851e965e4721f7420Eric Laurent mInput->stream->setGain(1.0f); 8866331679c8a5cd21a0e6a7a1d851e965e4721f7420Eric Laurent return MmapThread::exitStandby(); 8867331679c8a5cd21a0e6a7a1d851e965e4721f7420Eric Laurent} 8868331679c8a5cd21a0e6a7a1d851e965e4721f7420Eric Laurent 88696acd1d432f526ae9a055ddaece28bf93b474a776Eric LaurentAudioFlinger::AudioStreamIn* AudioFlinger::MmapCaptureThread::clearInput() 88706acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent{ 88716acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent Mutex::Autolock _l(mLock); 88726acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent AudioStreamIn *input = mInput; 88736acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent mInput = NULL; 88746acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent return input; 88756acd1d432f526ae9a055ddaece28bf93b474a776Eric Laurent} 8876069c2719e753732d5af9ba51e5fcc34342b0c9f2Kevin Rocard 8877331679c8a5cd21a0e6a7a1d851e965e4721f7420Eric Laurent 8878331679c8a5cd21a0e6a7a1d851e965e4721f7420Eric Laurentvoid AudioFlinger::MmapCaptureThread::processVolume_l() 8879331679c8a5cd21a0e6a7a1d851e965e4721f7420Eric Laurent{ 8880331679c8a5cd21a0e6a7a1d851e965e4721f7420Eric Laurent bool changed = false; 8881331679c8a5cd21a0e6a7a1d851e965e4721f7420Eric Laurent bool silenced = false; 8882331679c8a5cd21a0e6a7a1d851e965e4721f7420Eric Laurent 8883331679c8a5cd21a0e6a7a1d851e965e4721f7420Eric Laurent sp<MmapStreamCallback> callback = mCallback.promote(); 8884331679c8a5cd21a0e6a7a1d851e965e4721f7420Eric Laurent if (callback == 0) { 8885331679c8a5cd21a0e6a7a1d851e965e4721f7420Eric Laurent if (mNoCallbackWarningCount < kMaxNoCallbackWarnings) { 8886331679c8a5cd21a0e6a7a1d851e965e4721f7420Eric Laurent ALOGW("Could not set MMAP stream silenced: no onStreamSilenced callback!"); 8887331679c8a5cd21a0e6a7a1d851e965e4721f7420Eric Laurent mNoCallbackWarningCount++; 8888331679c8a5cd21a0e6a7a1d851e965e4721f7420Eric Laurent } 8889331679c8a5cd21a0e6a7a1d851e965e4721f7420Eric Laurent } 8890331679c8a5cd21a0e6a7a1d851e965e4721f7420Eric Laurent 8891331679c8a5cd21a0e6a7a1d851e965e4721f7420Eric Laurent // After a change occurred in track silenced state, mute capture in audio DSP if at least one 8892331679c8a5cd21a0e6a7a1d851e965e4721f7420Eric Laurent // track is silenced and unmute otherwise 8893331679c8a5cd21a0e6a7a1d851e965e4721f7420Eric Laurent for (size_t i = 0; i < mActiveTracks.size() && !silenced; i++) { 8894331679c8a5cd21a0e6a7a1d851e965e4721f7420Eric Laurent if (!mActiveTracks[i]->getAndSetSilencedNotified_l()) { 8895331679c8a5cd21a0e6a7a1d851e965e4721f7420Eric Laurent changed = true; 8896331679c8a5cd21a0e6a7a1d851e965e4721f7420Eric Laurent silenced = mActiveTracks[i]->isSilenced_l(); 8897331679c8a5cd21a0e6a7a1d851e965e4721f7420Eric Laurent } 8898331679c8a5cd21a0e6a7a1d851e965e4721f7420Eric Laurent } 8899331679c8a5cd21a0e6a7a1d851e965e4721f7420Eric Laurent 8900331679c8a5cd21a0e6a7a1d851e965e4721f7420Eric Laurent if (changed) { 8901331679c8a5cd21a0e6a7a1d851e965e4721f7420Eric Laurent mInput->stream->setGain(silenced ? 0.0f: 1.0f); 8902331679c8a5cd21a0e6a7a1d851e965e4721f7420Eric Laurent } 8903331679c8a5cd21a0e6a7a1d851e965e4721f7420Eric Laurent} 8904331679c8a5cd21a0e6a7a1d851e965e4721f7420Eric Laurent 8905069c2719e753732d5af9ba51e5fcc34342b0c9f2Kevin Rocardvoid AudioFlinger::MmapCaptureThread::updateMetadata_l() 8906069c2719e753732d5af9ba51e5fcc34342b0c9f2Kevin Rocard{ 8907069c2719e753732d5af9ba51e5fcc34342b0c9f2Kevin Rocard if (mInput == nullptr || mInput->stream == nullptr || 8908069c2719e753732d5af9ba51e5fcc34342b0c9f2Kevin Rocard !mActiveTracks.readAndClearHasChanged()) { 8909069c2719e753732d5af9ba51e5fcc34342b0c9f2Kevin Rocard return; 8910069c2719e753732d5af9ba51e5fcc34342b0c9f2Kevin Rocard } 8911069c2719e753732d5af9ba51e5fcc34342b0c9f2Kevin Rocard StreamInHalInterface::SinkMetadata metadata; 8912069c2719e753732d5af9ba51e5fcc34342b0c9f2Kevin Rocard for (const sp<MmapTrack> &track : mActiveTracks) { 8913069c2719e753732d5af9ba51e5fcc34342b0c9f2Kevin Rocard // No track is invalid as this is called after prepareTrack_l in the same critical section 8914069c2719e753732d5af9ba51e5fcc34342b0c9f2Kevin Rocard metadata.tracks.push_back({ 8915069c2719e753732d5af9ba51e5fcc34342b0c9f2Kevin Rocard .source = track->attributes().source, 8916069c2719e753732d5af9ba51e5fcc34342b0c9f2Kevin Rocard .gain = 1, // capture tracks do not have volumes 8917069c2719e753732d5af9ba51e5fcc34342b0c9f2Kevin Rocard }); 8918069c2719e753732d5af9ba51e5fcc34342b0c9f2Kevin Rocard } 8919069c2719e753732d5af9ba51e5fcc34342b0c9f2Kevin Rocard mInput->stream->updateSinkMetadata(metadata); 8920069c2719e753732d5af9ba51e5fcc34342b0c9f2Kevin Rocard} 8921069c2719e753732d5af9ba51e5fcc34342b0c9f2Kevin Rocard 8922331679c8a5cd21a0e6a7a1d851e965e4721f7420Eric Laurentvoid AudioFlinger::MmapCaptureThread::setRecordSilenced(uid_t uid, bool silenced) 8923331679c8a5cd21a0e6a7a1d851e965e4721f7420Eric Laurent{ 8924331679c8a5cd21a0e6a7a1d851e965e4721f7420Eric Laurent Mutex::Autolock _l(mLock); 8925331679c8a5cd21a0e6a7a1d851e965e4721f7420Eric Laurent for (size_t i = 0; i < mActiveTracks.size() ; i++) { 8926331679c8a5cd21a0e6a7a1d851e965e4721f7420Eric Laurent if (mActiveTracks[i]->uid() == uid) { 8927331679c8a5cd21a0e6a7a1d851e965e4721f7420Eric Laurent mActiveTracks[i]->setSilenced_l(silenced); 8928331679c8a5cd21a0e6a7a1d851e965e4721f7420Eric Laurent broadcast_l(); 8929331679c8a5cd21a0e6a7a1d851e965e4721f7420Eric Laurent } 8930331679c8a5cd21a0e6a7a1d851e965e4721f7420Eric Laurent } 8931331679c8a5cd21a0e6a7a1d851e965e4721f7420Eric Laurent} 8932331679c8a5cd21a0e6a7a1d851e965e4721f7420Eric Laurent 893363238efb0d674758902918e3cdaac322126484b7Glenn Kasten} // namespace android 8934