OSDN Git Service

AudioFlinger: Make StandbyTime configurable.
authorJohn Grossman <johngro@google.com>
Mon, 5 Dec 2011 22:35:26 +0000 (14:35 -0800)
committerJohn Grossman <johngro@google.com>
Tue, 6 Dec 2011 18:02:29 +0000 (10:02 -0800)
Make the standby time for AudioFlinger configurable using a system
property.  Default AudioFlinger behavior is to go into standby
(allowing the audio outputs to underflow) after there has been nothing
to mix and AudioFlinger has just been pumping out silence for the
configured standby time (which defaulted to 3 seconds).

Now, by setting the "ro.audio.flinger_standbytime_ms" property in
their platform init.rc, platforms can override this default and
control the standby time.  If the property is missing or malformed,
the old default value of 3 seconds will be used instead.

Change-Id: Ic9fa8b5f5bccee493bc72c65e408d3fd8ddd1059
Signed-off-by: John Grossman <johngro@google.com>
services/audioflinger/AudioFlinger.cpp
services/audioflinger/AudioFlinger.h

index 18e7a62..e520b10 100644 (file)
@@ -69,7 +69,6 @@ namespace android {
 static const char* kDeadlockedString = "AudioFlinger may be deadlocked\n";
 static const char* kHardwareLockedString = "Hardware lock is taken\n";
 
-//static const nsecs_t kStandbyTimeInNsecs = seconds(3);
 static const float MAX_GAIN = 4096.0f;
 static const float MAX_GAIN_INT = 0x1000;
 
@@ -97,6 +96,9 @@ static const uint32_t kMinThreadSleepTimeUs = 5000;
 // maximum divider applied to the active sleep time in the mixer thread loop
 static const uint32_t kMaxThreadSleepTimeShift = 2;
 
+nsecs_t AudioFlinger::mStandbyTimeInNsecs = kDefaultStandbyTimeInNsecs;
+bool    AudioFlinger::mStaticInitDone = false;
+Mutex   AudioFlinger::mStaticInitLock;
 
 // ----------------------------------------------------------------------------
 
@@ -167,6 +169,31 @@ AudioFlinger::AudioFlinger()
 {
 }
 
+bool AudioFlinger::doStaticInit() {
+    if (!mStaticInitDone) {
+        Mutex::Autolock _l(mStaticInitLock);
+
+        if (mStaticInitDone)
+            return true;
+
+        char val_str[PROPERTY_VALUE_MAX] = { 0 };
+        if (property_get("ro.audio.flinger_standbytime_ms", val_str, NULL) >= 0) {
+            uint32_t int_val;
+            if (1 == sscanf(val_str, "%u", &int_val)) {
+                mStandbyTimeInNsecs = milliseconds(int_val);
+                LOGI("Using %u mSec as standby time.", int_val);
+            } else {
+                mStandbyTimeInNsecs = kDefaultStandbyTimeInNsecs;
+                LOGI("Using default %u mSec as standby time.",
+                        (uint32_t)(mStandbyTimeInNsecs / 1000000));
+            }
+        }
+
+        mStaticInitDone = true;
+    }
+
+    return mStaticInitDone;
+}
 void AudioFlinger::onFirstRef()
 {
     int rc = 0;
@@ -176,6 +203,10 @@ void AudioFlinger::onFirstRef()
     /* TODO: move all this work into an Init() function */
     mHardwareStatus = AUDIO_HW_IDLE;
 
+    // Make sure all static variables are set up.  Right now, this is limited to
+    // the standby time parameter.
+    doStaticInit();
+
     for (size_t i = 0; i < ARRAY_SIZE(audio_interfaces); i++) {
         const hw_module_t *mod;
         audio_hw_device_t *dev;
@@ -334,7 +365,10 @@ status_t AudioFlinger::dumpInternals(int fd, const Vector<String16>& args)
     String8 result;
     int hardwareStatus = mHardwareStatus;
 
-    snprintf(buffer, SIZE, "Hardware status: %d\n", hardwareStatus);
+    snprintf(buffer, SIZE, "Hardware status: %d\n"
+                           "Standby Time mSec: %u\n",
+                            hardwareStatus,
+                            (uint32_t)(mStandbyTimeInNsecs / 1000000));
     result.append(buffer);
     write(fd, result.string(), result.size());
     return NO_ERROR;
@@ -2023,7 +2057,7 @@ bool AudioFlinger::MixerThread::threadLoop()
                         }
                     }
 
-                    standbyTime = systemTime() + kStandbyTimeInNsecs;
+                    standbyTime = systemTime() + mStandbyTimeInNsecs;
                     sleepTime = idleSleepTime;
                     sleepTimeShift = 0;
                     continue;
@@ -2059,7 +2093,7 @@ bool AudioFlinger::MixerThread::threadLoop()
             if (sleepTimeShift > 0) {
                 sleepTimeShift--;
             }
-            standbyTime = systemTime() + kStandbyTimeInNsecs;
+            standbyTime = systemTime() + mStandbyTimeInNsecs;
             //TODO: delay standby when effects have a tail
         } else {
             // If no tracks are ready, sleep once for the duration of an output
@@ -3105,7 +3139,7 @@ bool AudioFlinger::DuplicatingThread::threadLoop()
                         }
                     }
 
-                    standbyTime = systemTime() + kStandbyTimeInNsecs;
+                    standbyTime = systemTime() + mStandbyTimeInNsecs;
                     sleepTime = idleSleepTime;
                     continue;
                 }
@@ -3159,7 +3193,7 @@ bool AudioFlinger::DuplicatingThread::threadLoop()
             // enable changes in effect chain
             unlockEffectChains(effectChains);
 
-            standbyTime = systemTime() + kStandbyTimeInNsecs;
+            standbyTime = systemTime() + mStandbyTimeInNsecs;
             for (size_t i = 0; i < outputTracks.size(); i++) {
                 outputTracks[i]->write(mMixBuffer, writeFrames);
             }
index 4ed86c7..bf41c42 100644 (file)
@@ -61,7 +61,7 @@ class AudioResampler;
 
 // ----------------------------------------------------------------------------
 
-static const nsecs_t kStandbyTimeInNsecs = seconds(3);
+static const nsecs_t kDefaultStandbyTimeInNsecs = seconds(3);
 
 class AudioFlinger :
     public BinderService<AudioFlinger>,
@@ -224,6 +224,11 @@ private:
     audio_hw_device_t*      findSuitableHwDev_l(uint32_t devices);
     void                    purgeStaleEffects_l();
 
+    static Mutex            mStaticInitLock;
+    static bool             mStaticInitDone;
+    static bool             doStaticInit();
+    static nsecs_t          mStandbyTimeInNsecs;
+
     // Internal dump utilites.
     status_t dumpPermissionDenial(int fd, const Vector<String16>& args);
     status_t dumpClients(int fd, const Vector<String16>& args);