Merge "Support widevine:// URLs in NuMediaExtractor / java MediaExtractor."
diff --git a/media/libmedia/IAudioRecord.cpp b/media/libmedia/IAudioRecord.cpp
index cb5c7f3..58c6d38 100644
--- a/media/libmedia/IAudioRecord.cpp
+++ b/media/libmedia/IAudioRecord.cpp
@@ -93,7 +93,10 @@
         } break;
         case START: {
             CHECK_INTERFACE(IAudioRecord, data, reply);
-            reply->writeInt32(start(data.readInt32(), data.readInt32(), data.readInt32()));
+            pid_t tid = (pid_t) data.readInt32();
+            int event = data.readInt32();
+            int triggerSession = data.readInt32();
+            reply->writeInt32(start(tid, event, triggerSession));
             return NO_ERROR;
         } break;
         case STOP: {
diff --git a/media/libmedia/ToneGenerator.cpp b/media/libmedia/ToneGenerator.cpp
index 717d316..c93b6fd 100644
--- a/media/libmedia/ToneGenerator.cpp
+++ b/media/libmedia/ToneGenerator.cpp
@@ -1020,15 +1020,15 @@
     ALOGV("Create Track: %p", mpAudioTrack);
 
     mpAudioTrack->set(mStreamType,
-                      0,
+                      0,    // sampleRate
                       AUDIO_FORMAT_PCM_16_BIT,
                       AUDIO_CHANNEL_OUT_MONO,
-                      0,
-                      AUDIO_POLICY_OUTPUT_FLAG_NONE,
+                      0,    // frameCount
+                      AUDIO_POLICY_OUTPUT_FLAG_FAST,
                       audioCallback,
-                      this,
-                      0,
-                      0,
+                      this, // user
+                      0,    // notificationFrames
+                      0,    // sharedBuffer
                       mThreadCanCallJava);
 
     if (mpAudioTrack->initCheck() != NO_ERROR) {
diff --git a/services/audioflinger/AudioMixer.cpp b/services/audioflinger/AudioMixer.cpp
index 399d987..100f289 100644
--- a/services/audioflinger/AudioMixer.cpp
+++ b/services/audioflinger/AudioMixer.cpp
@@ -119,6 +119,7 @@
     for (unsigned i=0 ; i < MAX_NUM_TRACKS ; i++) {
         // FIXME redundant per track
         t->localTimeFreq = lc.getLocalFreq();
+        t->resampler = NULL;
         t++;
     }
 
@@ -326,15 +327,9 @@
         track.enabled = false;
         invalidateState(1<<name);
     }
-    if (track.resampler != NULL) {
-        // delete the resampler
-        delete track.resampler;
-        track.resampler = NULL;
-        track.sampleRate = mSampleRate;
-        invalidateState(1<<name);
-    }
-    track.volumeInc[0] = 0;
-    track.volumeInc[1] = 0;
+    // delete the resampler
+    delete track.resampler;
+    track.resampler = NULL;
     mTrackNames &= ~(1<<name);
 }
 
@@ -438,6 +433,12 @@
             track.resetResampler();
             invalidateState(1 << name);
             break;
+        case REMOVE:
+            delete track.resampler;
+            track.resampler = NULL;
+            track.sampleRate = mSampleRate;
+            invalidateState(1 << name);
+            break;
         default:
             LOG_FATAL("bad param");
         }
@@ -498,7 +499,7 @@
 
 bool AudioMixer::track_t::setResampler(uint32_t value, uint32_t devSampleRate)
 {
-    if (value!=devSampleRate || resampler) {
+    if (value != devSampleRate || resampler != NULL) {
         if (sampleRate != value) {
             sampleRate = value;
             if (resampler == NULL) {
diff --git a/services/audioflinger/AudioMixer.h b/services/audioflinger/AudioMixer.h
index a04fe95..9698d0c 100644
--- a/services/audioflinger/AudioMixer.h
+++ b/services/audioflinger/AudioMixer.h
@@ -70,8 +70,17 @@
         AUX_BUFFER      = 0x4003,
         DOWNMIX_TYPE    = 0X4004,
         // for target RESAMPLE
-        SAMPLE_RATE     = 0x4100,
-        RESET           = 0x4101,
+        SAMPLE_RATE     = 0x4100, // Configure sample rate conversion on this track name;
+                                  // parameter 'value' is the new sample rate in Hz.
+                                  // Only creates a sample rate converter the first time that
+                                  // the track sample rate is different from the mix sample rate.
+                                  // If the new sample rate is the same as the mix sample rate,
+                                  // and a sample rate converter already exists,
+                                  // then the sample rate converter remains present but is a no-op.
+        RESET           = 0x4101, // Reset sample rate converter without changing sample rate.
+                                  // This clears out the resampler's input buffer.
+        REMOVE          = 0x4102, // Remove the sample rate converter on this track name;
+                                  // the track is restored to the mix sample rate.
         // for target RAMP_VOLUME and VOLUME (8 channels max)
         VOLUME0         = 0x4200,
         VOLUME1         = 0x4201,
@@ -237,7 +246,10 @@
     // indicates whether a downmix effect has been found and is usable by this mixer
     static bool                isMultichannelCapable;
 
+    // Call after changing either the enabled status of a track, or parameters of an enabled track.
+    // OK to call more often than that, but unnecessary.
     void invalidateState(uint32_t mask);
+
     static status_t prepareTrackForDownmix(track_t* pTrack, int trackNum);
 
     static void track__genericResample(track_t* t, int32_t* out, size_t numFrames, int32_t* temp, int32_t* aux);