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