Merge "frameworks/av: fix errors inside ALOGV"
diff --git a/media/libmedia/AudioTrack.cpp b/media/libmedia/AudioTrack.cpp
index 0609a22..0b8fd7e 100644
--- a/media/libmedia/AudioTrack.cpp
+++ b/media/libmedia/AudioTrack.cpp
@@ -878,6 +878,12 @@
     }
     ALOGV("createTrack_l() output %d afLatency %d", output, afLatency);
 
+    if ((flags & AUDIO_OUTPUT_FLAG_FAST) && sampleRate != afSampleRate) {
+        ALOGW("AUDIO_OUTPUT_FLAG_FAST denied by client due to mismatching sample rate (%d vs %d)",
+              sampleRate, afSampleRate);
+        flags = (audio_output_flags_t) (flags & ~AUDIO_OUTPUT_FLAG_FAST);
+    }
+
     // The client's AudioTrack buffer is divided into n parts for purpose of wakeup by server, where
     //  n = 1   fast track with single buffering; nBuffering is ignored
     //  n = 2   fast track with double buffering
diff --git a/media/libstagefright/chromium_http/ChromiumHTTPDataSource.cpp b/media/libstagefright/chromium_http/ChromiumHTTPDataSource.cpp
index a862d8b..7e5c280 100644
--- a/media/libstagefright/chromium_http/ChromiumHTTPDataSource.cpp
+++ b/media/libstagefright/chromium_http/ChromiumHTTPDataSource.cpp
@@ -108,6 +108,11 @@
     return mState == CONNECTED ? OK : mIOResult;
 }
 
+void ChromiumHTTPDataSource::onRedirect(const char *url) {
+    Mutex::Autolock autoLock(mLock);
+    mURI = url;
+}
+
 void ChromiumHTTPDataSource::onConnectionEstablished(
         int64_t contentSize, const char *contentType) {
     Mutex::Autolock autoLock(mLock);
diff --git a/media/libstagefright/chromium_http/support.cpp b/media/libstagefright/chromium_http/support.cpp
index 0a8e3e3..3b33212 100644
--- a/media/libstagefright/chromium_http/support.cpp
+++ b/media/libstagefright/chromium_http/support.cpp
@@ -269,6 +269,7 @@
 void SfDelegate::OnReceivedRedirect(
             net::URLRequest *request, const GURL &new_url, bool *defer_redirect) {
     MY_LOGV("OnReceivedRedirect");
+    mOwner->onRedirect(new_url.spec().c_str());
 }
 
 void SfDelegate::OnAuthRequired(
diff --git a/media/libstagefright/codecs/avc/enc/SoftAVCEncoder.cpp b/media/libstagefright/codecs/avc/enc/SoftAVCEncoder.cpp
index 4a21a3e..1d398fb 100644
--- a/media/libstagefright/codecs/avc/enc/SoftAVCEncoder.cpp
+++ b/media/libstagefright/codecs/avc/enc/SoftAVCEncoder.cpp
@@ -593,6 +593,17 @@
                 mVideoHeight = def->format.video.nFrameHeight;
                 mVideoFrameRate = def->format.video.xFramerate >> 16;
                 mVideoColorFormat = def->format.video.eColorFormat;
+
+                OMX_PARAM_PORTDEFINITIONTYPE *portDef =
+                    &editPortInfo(0)->mDef;
+                portDef->format.video.nFrameWidth = mVideoWidth;
+                portDef->format.video.nFrameHeight = mVideoHeight;
+                portDef->format.video.xFramerate = def->format.video.xFramerate;
+                portDef->format.video.eColorFormat =
+                    (OMX_COLOR_FORMATTYPE) mVideoColorFormat;
+                portDef = &editPortInfo(1)->mDef;
+                portDef->format.video.nFrameWidth = mVideoWidth;
+                portDef->format.video.nFrameHeight = mVideoHeight;
             } else {
                 mVideoBitRate = def->format.video.nBitrate;
             }
diff --git a/media/libstagefright/codecs/on2/enc/SoftVPXEncoder.cpp b/media/libstagefright/codecs/on2/enc/SoftVPXEncoder.cpp
index 8375cac..5efe022 100644
--- a/media/libstagefright/codecs/on2/enc/SoftVPXEncoder.cpp
+++ b/media/libstagefright/codecs/on2/enc/SoftVPXEncoder.cpp
@@ -677,6 +677,9 @@
         def->format.video.nFrameHeight = mHeight;
         def->format.video.xFramerate = port->format.video.xFramerate;
         def->format.video.eColorFormat = mColorFormat;
+        def = &editPortInfo(kOutputPortIndex)->mDef;
+        def->format.video.nFrameWidth = mWidth;
+        def->format.video.nFrameHeight = mHeight;
 
         return OMX_ErrorNone;
     } else if (port->nPortIndex == kOutputPortIndex) {
diff --git a/media/libstagefright/httplive/M3UParser.cpp b/media/libstagefright/httplive/M3UParser.cpp
index dd248cb..5ef7c0f 100644
--- a/media/libstagefright/httplive/M3UParser.cpp
+++ b/media/libstagefright/httplive/M3UParser.cpp
@@ -416,22 +416,32 @@
     } else {
         // URL is a relative path
 
-        size_t n = strlen(baseURL);
-        if (baseURL[n - 1] == '/') {
-            out->setTo(baseURL);
-            out->append(url);
+        // Check for a possible query string
+        const char *qsPos = strchr(baseURL, '?');
+        size_t end;
+        if (qsPos != NULL) {
+            end = qsPos - baseURL;
         } else {
-            const char *slashPos = strrchr(baseURL, '/');
-
-            if (slashPos > &baseURL[6]) {
-                out->setTo(baseURL, slashPos - baseURL);
-            } else {
-                out->setTo(baseURL);
-            }
-
-            out->append("/");
-            out->append(url);
+            end = strlen(baseURL);
         }
+        // Check for the last slash before a potential query string
+        for (ssize_t pos = end - 1; pos >= 0; pos--) {
+            if (baseURL[pos] == '/') {
+                end = pos;
+                break;
+            }
+        }
+
+        // Check whether the found slash actually is part of the path
+        // and not part of the "http://".
+        if (end > 6) {
+            out->setTo(baseURL, end);
+        } else {
+            out->setTo(baseURL);
+        }
+
+        out->append("/");
+        out->append(url);
     }
 
     ALOGV("base:'%s', url:'%s' => '%s'", baseURL, url, out->c_str());
diff --git a/media/libstagefright/include/ChromiumHTTPDataSource.h b/media/libstagefright/include/ChromiumHTTPDataSource.h
index 785f939..da188dd 100644
--- a/media/libstagefright/include/ChromiumHTTPDataSource.h
+++ b/media/libstagefright/include/ChromiumHTTPDataSource.h
@@ -113,6 +113,7 @@
     void onConnectionFailed(status_t err);
     void onReadCompleted(ssize_t size);
     void onDisconnectComplete();
+    void onRedirect(const char *url);
 
     void clearDRMState_l();
 
diff --git a/services/audioflinger/Configuration.h b/services/audioflinger/Configuration.h
index bc2038a..0754d9d 100644
--- a/services/audioflinger/Configuration.h
+++ b/services/audioflinger/Configuration.h
@@ -32,9 +32,6 @@
 // uncomment to enable fast mixer to take performance samples for later statistical analysis
 #define FAST_MIXER_STATISTICS
 
-// uncomment to allow fast tracks at non-native sample rate
-//#define FAST_TRACKS_AT_NON_NATIVE_SAMPLE_RATE
-
 // uncomment for debugging timing problems related to StateQueue::push()
 //#define STATE_QUEUE_DUMP
 
diff --git a/services/audioflinger/FastMixer.cpp b/services/audioflinger/FastMixer.cpp
index f27ea17..3054619 100644
--- a/services/audioflinger/FastMixer.cpp
+++ b/services/audioflinger/FastMixer.cpp
@@ -236,7 +236,6 @@
                     sampleRate = Format_sampleRate(format);
                     ALOG_ASSERT(Format_channelCount(format) == FCC_2);
                 }
-                dumpState->mSampleRate = sampleRate;
             }
 
             if ((format != previousFormat) || (frameCount != previous->mFrameCount)) {
@@ -321,10 +320,6 @@
                         mixer->setParameter(name, AudioMixer::TRACK, AudioMixer::MAIN_BUFFER,
                                 (void *) mixBuffer);
                         // newly allocated track names default to full scale volume
-                        if (fastTrack->mSampleRate != 0 && fastTrack->mSampleRate != sampleRate) {
-                            mixer->setParameter(name, AudioMixer::RESAMPLE,
-                                    AudioMixer::SAMPLE_RATE, (void*) fastTrack->mSampleRate);
-                        }
                         mixer->setParameter(name, AudioMixer::TRACK, AudioMixer::CHANNEL_MASK,
                                 (void *) fastTrack->mChannelMask);
                         mixer->enable(name);
@@ -353,14 +348,8 @@
                                 mixer->setParameter(name, AudioMixer::VOLUME, AudioMixer::VOLUME1,
                                         (void *)0x1000);
                             }
-                            if (fastTrack->mSampleRate != 0 &&
-                                    fastTrack->mSampleRate != sampleRate) {
-                                mixer->setParameter(name, AudioMixer::RESAMPLE,
-                                        AudioMixer::SAMPLE_RATE, (void*) fastTrack->mSampleRate);
-                            } else {
-                                mixer->setParameter(name, AudioMixer::RESAMPLE,
-                                        AudioMixer::REMOVE, NULL);
-                            }
+                            mixer->setParameter(name, AudioMixer::RESAMPLE,
+                                    AudioMixer::REMOVE, NULL);
                             mixer->setParameter(name, AudioMixer::TRACK, AudioMixer::CHANNEL_MASK,
                                     (void *) fastTrack->mChannelMask);
                             // already enabled
@@ -392,16 +381,8 @@
 
                 // Refresh the per-track timestamp
                 if (timestampStatus == NO_ERROR) {
-                    uint32_t trackFramesWrittenButNotPresented;
-                    uint32_t trackSampleRate = fastTrack->mSampleRate;
-                    // There is currently no sample rate conversion for fast tracks currently
-                    if (trackSampleRate != 0 && trackSampleRate != sampleRate) {
-                        trackFramesWrittenButNotPresented =
-                                ((int64_t) nativeFramesWrittenButNotPresented * trackSampleRate) /
-                                sampleRate;
-                    } else {
-                        trackFramesWrittenButNotPresented = nativeFramesWrittenButNotPresented;
-                    }
+                    uint32_t trackFramesWrittenButNotPresented =
+                        nativeFramesWrittenButNotPresented;
                     uint32_t trackFramesWritten = fastTrack->mBufferProvider->framesReleased();
                     // Can't provide an AudioTimestamp before first frame presented,
                     // or during the brief 32-bit wraparound window
diff --git a/services/audioflinger/FastMixerState.cpp b/services/audioflinger/FastMixerState.cpp
index 737de97..43ff233 100644
--- a/services/audioflinger/FastMixerState.cpp
+++ b/services/audioflinger/FastMixerState.cpp
@@ -20,7 +20,7 @@
 namespace android {
 
 FastTrack::FastTrack() :
-    mBufferProvider(NULL), mVolumeProvider(NULL), mSampleRate(0),
+    mBufferProvider(NULL), mVolumeProvider(NULL),
     mChannelMask(AUDIO_CHANNEL_OUT_STEREO), mGeneration(0)
 {
 }
diff --git a/services/audioflinger/FastMixerState.h b/services/audioflinger/FastMixerState.h
index f6e7903..9739fe9 100644
--- a/services/audioflinger/FastMixerState.h
+++ b/services/audioflinger/FastMixerState.h
@@ -43,7 +43,6 @@
 
     ExtendedAudioBufferProvider* mBufferProvider; // must be NULL if inactive, or non-NULL if active
     VolumeProvider*         mVolumeProvider; // optional; if NULL then full-scale
-    unsigned                mSampleRate;     // optional; if zero then use mixer sample rate
     audio_channel_mask_t    mChannelMask;    // AUDIO_CHANNEL_OUT_MONO or AUDIO_CHANNEL_OUT_STEREO
     int                     mGeneration;     // increment when any field is assigned
 };
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index 73429ec..f7f3a31 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -1218,10 +1218,8 @@
             // mono or stereo
             ( (channelMask == AUDIO_CHANNEL_OUT_MONO) ||
               (channelMask == AUDIO_CHANNEL_OUT_STEREO) ) &&
-#ifndef FAST_TRACKS_AT_NON_NATIVE_SAMPLE_RATE
             // hardware sample rate
             (sampleRate == mSampleRate) &&
-#endif
             // normal mixer has an associated fast mixer
             hasFastMixer() &&
             // there are sufficient fast track slots available
@@ -2973,7 +2971,6 @@
                     VolumeProvider *vp = track;
                     fastTrack->mBufferProvider = eabp;
                     fastTrack->mVolumeProvider = vp;
-                    fastTrack->mSampleRate = track->mSampleRate;
                     fastTrack->mChannelMask = track->mChannelMask;
                     fastTrack->mGeneration++;
                     state->mTrackMask |= 1 << j;