Merge "do not use paused postition if it's not available" into lmp-mr1-dev
diff --git a/include/media/stagefright/ACodec.h b/include/media/stagefright/ACodec.h
index 4d4ce90..371e2c8 100644
--- a/include/media/stagefright/ACodec.h
+++ b/include/media/stagefright/ACodec.h
@@ -131,6 +131,7 @@
     enum {
         kFlagIsSecure                                 = 1,
         kFlagPushBlankBuffersToNativeWindowOnShutdown = 2,
+        kFlagIsGrallocUsageProtected                  = 4,
     };
 
     struct BufferInfo {
@@ -282,6 +283,8 @@
 
     status_t setupAC3Codec(bool encoder, int32_t numChannels, int32_t sampleRate);
 
+    status_t setupEAC3Codec(bool encoder, int32_t numChannels, int32_t sampleRate);
+
     status_t selectAudioPortFormat(
             OMX_U32 portIndex, OMX_AUDIO_CODINGTYPE desiredFormat);
 
diff --git a/include/media/stagefright/MediaDefs.h b/include/media/stagefright/MediaDefs.h
index e67d4d5..13695d5 100644
--- a/include/media/stagefright/MediaDefs.h
+++ b/include/media/stagefright/MediaDefs.h
@@ -47,6 +47,7 @@
 extern const char *MEDIA_MIMETYPE_AUDIO_AAC_ADTS;
 extern const char *MEDIA_MIMETYPE_AUDIO_MSGSM;
 extern const char *MEDIA_MIMETYPE_AUDIO_AC3;
+extern const char *MEDIA_MIMETYPE_AUDIO_EAC3;
 
 extern const char *MEDIA_MIMETYPE_CONTAINER_MPEG4;
 extern const char *MEDIA_MIMETYPE_CONTAINER_WAV;
diff --git a/media/libmedia/AudioRecord.cpp b/media/libmedia/AudioRecord.cpp
index d9646d9..ca3832d 100644
--- a/media/libmedia/AudioRecord.cpp
+++ b/media/libmedia/AudioRecord.cpp
@@ -167,10 +167,6 @@
         return INVALID_OPERATION;
     }
 
-    // handle default values first.
-    if (inputSource == AUDIO_SOURCE_DEFAULT) {
-        inputSource = AUDIO_SOURCE_MIC;
-    }
     if (pAttributes == NULL) {
         memset(&mAttributes, 0, sizeof(audio_attributes_t));
         mAttributes.source = inputSource;
diff --git a/media/libmediaplayerservice/MidiFile.cpp b/media/libmediaplayerservice/MidiFile.cpp
index 749ef96..60cbd3c 100644
--- a/media/libmediaplayerservice/MidiFile.cpp
+++ b/media/libmediaplayerservice/MidiFile.cpp
@@ -293,7 +293,7 @@
 {
     ALOGV("MidiFile::isPlaying, mState=%d", int(mState));
     if (!mEasHandle || mPaused) return false;
-    return (mState == EAS_STATE_PLAY);
+    return (mState == EAS_STATE_PLAY || (mState == EAS_STATE_READY && mRender));
 }
 
 status_t MidiFile::getCurrentPosition(int* position)
diff --git a/media/libmediaplayerservice/nuplayer/GenericSource.cpp b/media/libmediaplayerservice/nuplayer/GenericSource.cpp
index dd79b50..76b80bb 100644
--- a/media/libmediaplayerservice/nuplayer/GenericSource.cpp
+++ b/media/libmediaplayerservice/nuplayer/GenericSource.cpp
@@ -391,6 +391,7 @@
 
     notifyFlagsChanged(
             (mIsSecure ? FLAG_SECURE : 0)
+            | (mDecryptHandle != NULL ? FLAG_PROTECTED : 0)
             | FLAG_CAN_PAUSE
             | FLAG_CAN_SEEK_BACKWARD
             | FLAG_CAN_SEEK_FORWARD
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
index a28591e..e02a2d5 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
@@ -1190,6 +1190,10 @@
         if (mSourceFlags & Source::FLAG_SECURE) {
             format->setInt32("secure", true);
         }
+
+        if (mSourceFlags & Source::FLAG_PROTECTED) {
+            format->setInt32("protected", true);
+        }
     }
 
     if (audio) {
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
index 53dfa48..80b8493 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
@@ -39,6 +39,15 @@
 static const int64_t kOffloadPauseMaxUs = 10000000ll;
 
 // static
+const NuPlayer::Renderer::PcmInfo NuPlayer::Renderer::AUDIO_PCMINFO_INITIALIZER = {
+        AUDIO_CHANNEL_NONE,
+        AUDIO_OUTPUT_FLAG_NONE,
+        AUDIO_FORMAT_INVALID,
+        0, // mNumChannels
+        0 // mSampleRate
+};
+
+// static
 const int64_t NuPlayer::Renderer::kMinPositionUpdateDelayUs = 100000ll;
 
 NuPlayer::Renderer::Renderer(
@@ -76,6 +85,7 @@
       mAudioOffloadPauseTimeoutGeneration(0),
       mAudioOffloadTornDown(false),
       mCurrentOffloadInfo(AUDIO_INFO_INITIALIZER),
+      mCurrentPcmInfo(AUDIO_PCMINFO_INITIALIZER),
       mTotalBuffersQueued(0),
       mLastAudioBufferDrained(0) {
 }
@@ -1448,6 +1458,8 @@
                 // no change from previous configuration, everything ok.
                 return OK;
             }
+            mCurrentPcmInfo = AUDIO_PCMINFO_INITIALIZER;
+
             ALOGV("openAudioSink: try to open AudioSink in offload mode");
             uint32_t offloadFlags = flags;
             offloadFlags |= AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD;
@@ -1489,6 +1501,20 @@
         ALOGV("openAudioSink: open AudioSink in NON-offload mode");
         uint32_t pcmFlags = flags;
         pcmFlags &= ~AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD;
+
+        const PcmInfo info = {
+                (audio_channel_mask_t)channelMask,
+                (audio_output_flags_t)pcmFlags,
+                AUDIO_FORMAT_PCM_16_BIT, // TODO: change to audioFormat
+                numChannels,
+                sampleRate
+        };
+        if (memcmp(&mCurrentPcmInfo, &info, sizeof(info)) == 0) {
+            ALOGV("openAudioSink: no change in pcm mode");
+            // no change from previous configuration, everything ok.
+            return OK;
+        }
+
         audioSinkChanged = true;
         mAudioSink->close();
         mCurrentOffloadInfo = AUDIO_INFO_INITIALIZER;
@@ -1503,8 +1529,10 @@
                     (audio_output_flags_t)pcmFlags);
         if (err != OK) {
             ALOGW("openAudioSink: non offloaded open failed status: %d", err);
+            mCurrentPcmInfo = AUDIO_PCMINFO_INITIALIZER;
             return err;
         }
+        mCurrentPcmInfo = info;
         mAudioSink->start();
     }
     if (audioSinkChanged) {
@@ -1519,6 +1547,7 @@
 void NuPlayer::Renderer::onCloseAudioSink() {
     mAudioSink->close();
     mCurrentOffloadInfo = AUDIO_INFO_INITIALIZER;
+    mCurrentPcmInfo = AUDIO_PCMINFO_INITIALIZER;
 }
 
 }  // namespace android
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.h b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.h
index c6e3457..23907c8 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.h
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.h
@@ -181,6 +181,16 @@
     bool mAudioOffloadTornDown;
     audio_offload_info_t mCurrentOffloadInfo;
 
+    struct PcmInfo {
+        audio_channel_mask_t mChannelMask;
+        audio_output_flags_t mFlags;
+        audio_format_t mFormat;
+        int32_t mNumChannels;
+        int32_t mSampleRate;
+    };
+    PcmInfo mCurrentPcmInfo;
+    static const PcmInfo AUDIO_PCMINFO_INITIALIZER;
+
     int32_t mTotalBuffersQueued;
     int32_t mLastAudioBufferDrained;
 
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerSource.h b/media/libmediaplayerservice/nuplayer/NuPlayerSource.h
index 2b0ac47..5bf9187 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerSource.h
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerSource.h
@@ -39,6 +39,7 @@
         FLAG_CAN_SEEK           = 8,  // the "seek bar"
         FLAG_DYNAMIC_DURATION   = 16,
         FLAG_SECURE             = 32,
+        FLAG_PROTECTED          = 64,
     };
 
     enum {
diff --git a/media/libstagefright/ACodec.cpp b/media/libstagefright/ACodec.cpp
index e1b3b4d..87606a5 100644
--- a/media/libstagefright/ACodec.cpp
+++ b/media/libstagefright/ACodec.cpp
@@ -670,7 +670,7 @@
         usage = 0;
     }
 
-    if (mFlags & kFlagIsSecure) {
+    if (mFlags & kFlagIsGrallocUsageProtected) {
         usage |= GRALLOC_USAGE_PROTECTED;
     }
 
@@ -1106,6 +1106,8 @@
             "video_decoder.mpeg2", "video_encoder.mpeg2" },
         { MEDIA_MIMETYPE_AUDIO_AC3,
             "audio_decoder.ac3", "audio_encoder.ac3" },
+        { MEDIA_MIMETYPE_AUDIO_EAC3,
+            "audio_decoder.eac3", "audio_encoder.eac3" },
     };
 
     static const size_t kNumMimeToRole =
@@ -1262,6 +1264,16 @@
     mStoreMetaDataInOutputBuffers = false;
     if (video && !encoder) {
         inputFormat->setInt32("adaptive-playback", false);
+
+        int32_t usageProtected;
+        if (msg->findInt32("protected", &usageProtected) && usageProtected) {
+            if (!haveNativeWindow) {
+                ALOGE("protected output buffers must be sent to an ANativeWindow");
+                return PERMISSION_DENIED;
+            }
+            mFlags |= kFlagIsGrallocUsageProtected;
+            mFlags |= kFlagPushBlankBuffersToNativeWindowOnShutdown;
+        }
     }
     if (!encoder && video && haveNativeWindow) {
         sp<NativeWindowWrapper> windowWrapper(
@@ -1530,6 +1542,15 @@
         } else {
             err = setupAC3Codec(encoder, numChannels, sampleRate);
         }
+    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_EAC3)) {
+        int32_t numChannels;
+        int32_t sampleRate;
+        if (!msg->findInt32("channel-count", &numChannels)
+                || !msg->findInt32("sample-rate", &sampleRate)) {
+            err = INVALID_OPERATION;
+        } else {
+            err = setupEAC3Codec(encoder, numChannels, sampleRate);
+        }
     }
 
     if (err != OK) {
@@ -1815,6 +1836,44 @@
             sizeof(def));
 }
 
+status_t ACodec::setupEAC3Codec(
+        bool encoder, int32_t numChannels, int32_t sampleRate) {
+    status_t err = setupRawAudioFormat(
+            encoder ? kPortIndexInput : kPortIndexOutput, sampleRate, numChannels);
+
+    if (err != OK) {
+        return err;
+    }
+
+    if (encoder) {
+        ALOGW("EAC3 encoding is not supported.");
+        return INVALID_OPERATION;
+    }
+
+    OMX_AUDIO_PARAM_ANDROID_EAC3TYPE def;
+    InitOMXParams(&def);
+    def.nPortIndex = kPortIndexInput;
+
+    err = mOMX->getParameter(
+            mNode,
+            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidEac3,
+            &def,
+            sizeof(def));
+
+    if (err != OK) {
+        return err;
+    }
+
+    def.nChannels = numChannels;
+    def.nSampleRate = sampleRate;
+
+    return mOMX->setParameter(
+            mNode,
+            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidEac3,
+            &def,
+            sizeof(def));
+}
+
 static OMX_AUDIO_AMRBANDMODETYPE pickModeFromBitRate(
         bool isAMRWB, int32_t bps) {
     if (isAMRWB) {
@@ -3490,6 +3549,24 @@
                     break;
                 }
 
+                case OMX_AUDIO_CodingAndroidEAC3:
+                {
+                    OMX_AUDIO_PARAM_ANDROID_EAC3TYPE params;
+                    InitOMXParams(&params);
+                    params.nPortIndex = portIndex;
+
+                    CHECK_EQ((status_t)OK, mOMX->getParameter(
+                            mNode,
+                            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidEac3,
+                            &params,
+                            sizeof(params)));
+
+                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_EAC3);
+                    notify->setInt32("channel-count", params.nChannels);
+                    notify->setInt32("sample-rate", params.nSampleRate);
+                    break;
+                }
+
                 case OMX_AUDIO_CodingAndroidOPUS:
                 {
                     OMX_AUDIO_PARAM_ANDROID_OPUSTYPE params;
@@ -4627,6 +4704,7 @@
 
     if (componentName.endsWith(".secure")) {
         mCodec->mFlags |= kFlagIsSecure;
+        mCodec->mFlags |= kFlagIsGrallocUsageProtected;
         mCodec->mFlags |= kFlagPushBlankBuffersToNativeWindowOnShutdown;
     }
 
diff --git a/media/libstagefright/HTTPBase.cpp b/media/libstagefright/HTTPBase.cpp
index 32291c8..0c2ff15 100644
--- a/media/libstagefright/HTTPBase.cpp
+++ b/media/libstagefright/HTTPBase.cpp
@@ -36,7 +36,8 @@
       mTotalTransferBytes(0),
       mPrevBandwidthMeasureTimeUs(0),
       mPrevEstimatedBandWidthKbps(0),
-      mBandWidthCollectFreqMs(5000) {
+      mBandWidthCollectFreqMs(5000),
+      mMaxBandwidthHistoryItems(100) {
 }
 
 void HTTPBase::addBandwidthMeasurement(
@@ -50,7 +51,7 @@
     mTotalTransferBytes += numBytes;
 
     mBandwidthHistory.push_back(entry);
-    if (++mNumBandwidthHistoryItems > 100) {
+    if (++mNumBandwidthHistoryItems > mMaxBandwidthHistoryItems) {
         BandwidthEntry *entry = &*mBandwidthHistory.begin();
         mTotalTransferTimeUs -= entry->mDelayUs;
         mTotalTransferBytes -= entry->mNumBytes;
@@ -104,6 +105,10 @@
     return OK;
 }
 
+void HTTPBase::setBandwidthHistorySize(size_t numHistoryItems) {
+    mMaxBandwidthHistoryItems = numHistoryItems;
+}
+
 // static
 void HTTPBase::RegisterSocketUserTag(int sockfd, uid_t uid, uint32_t kTag) {
     int res = qtaguid_tagSocket(sockfd, kTag, uid);
diff --git a/media/libstagefright/MediaCodec.cpp b/media/libstagefright/MediaCodec.cpp
index e1c8a41..c2381b4 100644
--- a/media/libstagefright/MediaCodec.cpp
+++ b/media/libstagefright/MediaCodec.cpp
@@ -1014,11 +1014,13 @@
 
                     // Notify mCrypto of video resolution changes
                     if (mCrypto != NULL) {
-                      int32_t height, width;
-                      if (mOutputFormat->findInt32("height", &height) &&
-                          mOutputFormat->findInt32("width", &width)) {
-                        mCrypto->notifyResolution(width, height);
-                      }
+                        int32_t left, top, right, bottom, width, height;
+                        if (mOutputFormat->findRect("crop", &left, &top, &right, &bottom)) {
+                            mCrypto->notifyResolution(right - left + 1, bottom - top + 1);
+                        } else if (mOutputFormat->findInt32("width", &width)
+                                && mOutputFormat->findInt32("height", &height)) {
+                            mCrypto->notifyResolution(width, height);
+                        }
                     }
 
                     break;
diff --git a/media/libstagefright/MediaDefs.cpp b/media/libstagefright/MediaDefs.cpp
index d48dd84..c5a6939 100644
--- a/media/libstagefright/MediaDefs.cpp
+++ b/media/libstagefright/MediaDefs.cpp
@@ -45,6 +45,7 @@
 const char *MEDIA_MIMETYPE_AUDIO_AAC_ADTS = "audio/aac-adts";
 const char *MEDIA_MIMETYPE_AUDIO_MSGSM = "audio/gsm";
 const char *MEDIA_MIMETYPE_AUDIO_AC3 = "audio/ac3";
+const char *MEDIA_MIMETYPE_AUDIO_EAC3 = "audio/eac3";
 
 const char *MEDIA_MIMETYPE_CONTAINER_MPEG4 = "video/mp4";
 const char *MEDIA_MIMETYPE_CONTAINER_WAV = "audio/x-wav";
diff --git a/media/libstagefright/codecs/m4v_h263/dec/src/pvdec_api.cpp b/media/libstagefright/codecs/m4v_h263/dec/src/pvdec_api.cpp
index 844bd14..b783222 100644
--- a/media/libstagefright/codecs/m4v_h263/dec/src/pvdec_api.cpp
+++ b/media/libstagefright/codecs/m4v_h263/dec/src/pvdec_api.cpp
@@ -247,10 +247,13 @@
                         video->vol[idx]->useReverseVLC = 0;
                         video->intra_acdcPredDisable = 1;
                         video->vol[idx]->scalability = 0;
-                        video->size = (int32)width * height;
 
-                        video->displayWidth = video->width = width;
-                        video->displayHeight = video->height = height;
+                        video->displayWidth = width;
+                        video->displayHeight = height;
+                        video->width = (width + 15) & -16;
+                        video->height = (height + 15) & -16;
+                        video->size = (int32)video->width * video->height;
+
 #ifdef PV_ANNEX_IJKT_SUPPORT
                         video->modified_quant = 0;
                         video->advanced_INTRA = 0;
diff --git a/media/libstagefright/httplive/LiveSession.cpp b/media/libstagefright/httplive/LiveSession.cpp
index 0b18666..9daab3b 100644
--- a/media/libstagefright/httplive/LiveSession.cpp
+++ b/media/libstagefright/httplive/LiveSession.cpp
@@ -49,6 +49,9 @@
 
 namespace android {
 
+// Number of recently-read bytes to use for bandwidth estimation
+const size_t LiveSession::kBandwidthHistoryBytes = 200 * 1024;
+
 LiveSession::LiveSession(
         const sp<AMessage> &notify, uint32_t flags,
         const sp<IMediaHTTPService> &httpService)
@@ -84,6 +87,13 @@
         mPacketSources2.add(indexToType(i), new AnotherPacketSource(NULL /* meta */));
         mBuffering[i] = false;
     }
+
+    size_t numHistoryItems = kBandwidthHistoryBytes /
+            PlaylistFetcher::kDownloadBlockSize + 1;
+    if (numHistoryItems < 5) {
+        numHistoryItems = 5;
+    }
+    mHTTPDataSource->setBandwidthHistorySize(numHistoryItems);
 }
 
 LiveSession::~LiveSession() {
@@ -145,10 +155,24 @@
         }
     }
 
+    int32_t targetDuration = 0;
+    sp<AMessage> meta = packetSource->getLatestEnqueuedMeta();
+    if (meta != NULL) {
+        meta->findInt32("targetDuration", &targetDuration);
+    }
+
+    int64_t targetDurationUs = targetDuration * 1000000ll;
+    if (targetDurationUs == 0 ||
+            targetDurationUs > PlaylistFetcher::kMinBufferedDurationUs) {
+        // Fetchers limit buffering to
+        // min(3 * targetDuration, kMinBufferedDurationUs)
+        targetDurationUs = PlaylistFetcher::kMinBufferedDurationUs;
+    }
+
     if (mBuffering[idx]) {
         if (mSwitchInProgress
                 || packetSource->isFinished(0)
-                || packetSource->getEstimatedDurationUs() > 10000000ll) {
+                || packetSource->getEstimatedDurationUs() > targetDurationUs) {
             mBuffering[idx] = false;
         }
     }
@@ -859,7 +883,11 @@
         // Only resize when we don't know the size.
         size_t bufferRemaining = buffer->capacity() - buffer->size();
         if (bufferRemaining == 0 && getSizeErr != OK) {
-            bufferRemaining = 32768;
+            size_t bufferIncrement = buffer->size() / 2;
+            if (bufferIncrement < 32768) {
+                bufferIncrement = 32768;
+            }
+            bufferRemaining = bufferIncrement;
 
             ALOGV("increasing download buffer to %zu bytes",
                  buffer->size() + bufferRemaining);
diff --git a/media/libstagefright/httplive/LiveSession.h b/media/libstagefright/httplive/LiveSession.h
index 896a8fc..dfb5e59 100644
--- a/media/libstagefright/httplive/LiveSession.h
+++ b/media/libstagefright/httplive/LiveSession.h
@@ -114,6 +114,8 @@
         kWhatSwitchDown                 = 'sDwn',
     };
 
+    static const size_t kBandwidthHistoryBytes;
+
     struct BandwidthItem {
         size_t mPlaylistIndex;
         unsigned long mBandwidth;
diff --git a/media/libstagefright/httplive/PlaylistFetcher.cpp b/media/libstagefright/httplive/PlaylistFetcher.cpp
index d8eed5b..4a97803 100644
--- a/media/libstagefright/httplive/PlaylistFetcher.cpp
+++ b/media/libstagefright/httplive/PlaylistFetcher.cpp
@@ -49,8 +49,9 @@
 // static
 const int64_t PlaylistFetcher::kMinBufferedDurationUs = 10000000ll;
 const int64_t PlaylistFetcher::kMaxMonitorDelayUs = 3000000ll;
-const int32_t PlaylistFetcher::kDownloadBlockSize = 2048;
-const int32_t PlaylistFetcher::kNumSkipFrames = 10;
+// LCM of 188 (size of a TS packet) & 1k works well
+const int32_t PlaylistFetcher::kDownloadBlockSize = 47 * 1024;
+const int32_t PlaylistFetcher::kNumSkipFrames = 5;
 
 PlaylistFetcher::PlaylistFetcher(
         const sp<AMessage> &notify,
@@ -561,7 +562,7 @@
         // Don't resume if we would stop within a resume threshold.
         int32_t discontinuitySeq;
         int64_t latestTimeUs = 0, stopTimeUs = 0;
-        sp<AMessage> latestMeta = packetSource->getLatestDequeuedMeta();
+        sp<AMessage> latestMeta = packetSource->getLatestEnqueuedMeta();
         if (latestMeta != NULL
                 && latestMeta->findInt32("discontinuitySeq", &discontinuitySeq)
                 && discontinuitySeq == mDiscontinuitySeq
@@ -610,7 +611,12 @@
     int32_t targetDurationSecs;
     int64_t targetDurationUs = kMinBufferedDurationUs;
     if (mPlaylist != NULL) {
-        CHECK(mPlaylist->meta()->findInt32("target-duration", &targetDurationSecs));
+        if (mPlaylist->meta() == NULL || !mPlaylist->meta()->findInt32(
+                "target-duration", &targetDurationSecs)) {
+            ALOGE("Playlist is missing required EXT-X-TARGETDURATION tag");
+            notifyError(ERROR_MALFORMED);
+            return;
+        }
         targetDurationUs = targetDurationSecs * 1000000ll;
     }
 
@@ -1159,6 +1165,11 @@
         accessUnit->meta()->setInt32("discard", discard);
     }
 
+    int32_t targetDurationSecs;
+    if (mPlaylist->meta()->findInt32("target-duration", &targetDurationSecs)) {
+        accessUnit->meta()->setInt32("targetDuration", targetDurationSecs);
+    }
+
     accessUnit->meta()->setInt32("discontinuitySeq", mDiscontinuitySeq);
     accessUnit->meta()->setInt64("segmentStartTimeUs", getSegmentStartTimeUs(mSeqNumber));
     return accessUnit;
@@ -1668,7 +1679,7 @@
 
 int64_t PlaylistFetcher::resumeThreshold(const sp<AMessage> &msg) {
     int64_t durationUs, threshold;
-    if (msg->findInt64("durationUs", &durationUs)) {
+    if (msg->findInt64("durationUs", &durationUs) && durationUs > 0) {
         return kNumSkipFrames * durationUs;
     }
 
diff --git a/media/libstagefright/httplive/PlaylistFetcher.h b/media/libstagefright/httplive/PlaylistFetcher.h
index 78c358f..67161a9 100644
--- a/media/libstagefright/httplive/PlaylistFetcher.h
+++ b/media/libstagefright/httplive/PlaylistFetcher.h
@@ -34,6 +34,9 @@
 struct String8;
 
 struct PlaylistFetcher : public AHandler {
+    static const int64_t kMinBufferedDurationUs;
+    static const int32_t kDownloadBlockSize;
+
     enum {
         kWhatStarted,
         kWhatPaused,
@@ -92,9 +95,7 @@
         kWhatDownloadNext   = 'dlnx',
     };
 
-    static const int64_t kMinBufferedDurationUs;
     static const int64_t kMaxMonitorDelayUs;
-    static const int32_t kDownloadBlockSize;
     static const int32_t kNumSkipFrames;
 
     static bool bufferStartsWithTsSyncByte(const sp<ABuffer>& buffer);
diff --git a/media/libstagefright/include/HTTPBase.h b/media/libstagefright/include/HTTPBase.h
index 1c3cd5e..0c66e27 100644
--- a/media/libstagefright/include/HTTPBase.h
+++ b/media/libstagefright/include/HTTPBase.h
@@ -48,6 +48,8 @@
 
     virtual status_t setBandwidthStatCollectFreq(int32_t freqMs);
 
+    virtual void setBandwidthHistorySize(size_t numHistoryItems);
+
     static void RegisterSocketUserTag(int sockfd, uid_t uid, uint32_t kTag);
     static void UnRegisterSocketUserTag(int sockfd);
 
@@ -55,7 +57,7 @@
     static void UnRegisterSocketUserMark(int sockfd);
 
 protected:
-    void addBandwidthMeasurement(size_t numBytes, int64_t delayUs);
+    virtual void addBandwidthMeasurement(size_t numBytes, int64_t delayUs);
 
 private:
     struct BandwidthEntry {
@@ -69,6 +71,7 @@
     size_t mNumBandwidthHistoryItems;
     int64_t mTotalTransferTimeUs;
     size_t mTotalTransferBytes;
+    size_t mMaxBandwidthHistoryItems;
 
     enum {
         kMinBandwidthCollectFreqMs = 1000,   // 1 second
diff --git a/media/libstagefright/mpeg2ts/AnotherPacketSource.cpp b/media/libstagefright/mpeg2ts/AnotherPacketSource.cpp
index c579d4c..f266fe7 100644
--- a/media/libstagefright/mpeg2ts/AnotherPacketSource.cpp
+++ b/media/libstagefright/mpeg2ts/AnotherPacketSource.cpp
@@ -218,12 +218,19 @@
     }
 
     if (mLatestEnqueuedMeta == NULL) {
-        mLatestEnqueuedMeta = buffer->meta();
+        mLatestEnqueuedMeta = buffer->meta()->dup();
     } else {
         int64_t latestTimeUs = 0;
+        int64_t frameDeltaUs = 0;
         CHECK(mLatestEnqueuedMeta->findInt64("timeUs", &latestTimeUs));
         if (lastQueuedTimeUs > latestTimeUs) {
-            mLatestEnqueuedMeta = buffer->meta();
+            mLatestEnqueuedMeta = buffer->meta()->dup();
+            frameDeltaUs = lastQueuedTimeUs - latestTimeUs;
+            mLatestEnqueuedMeta->setInt64("durationUs", frameDeltaUs);
+        } else if (!mLatestEnqueuedMeta->findInt64("durationUs", &frameDeltaUs)) {
+            // For B frames
+            frameDeltaUs = latestTimeUs - lastQueuedTimeUs;
+            mLatestEnqueuedMeta->setInt64("durationUs", frameDeltaUs);
         }
     }
 }
diff --git a/media/libstagefright/omx/SoftVideoDecoderOMXComponent.cpp b/media/libstagefright/omx/SoftVideoDecoderOMXComponent.cpp
index 532cf2f..4ce165b 100644
--- a/media/libstagefright/omx/SoftVideoDecoderOMXComponent.cpp
+++ b/media/libstagefright/omx/SoftVideoDecoderOMXComponent.cpp
@@ -149,7 +149,9 @@
 
     // when output format changes, input buffer size does not actually change
     if (updateInputSize) {
-        inDef->nBufferSize = max(outDef->nBufferSize / mMinCompressionRatio, mMinInputBufferSize);
+        inDef->nBufferSize = max(
+                outDef->nBufferSize / mMinCompressionRatio,
+                max(mMinInputBufferSize, inDef->nBufferSize));
     }
 
     if (updateCrop) {
@@ -388,30 +390,21 @@
             uint32_t newHeight = video_def->nFrameHeight;
             if (newWidth != oldWidth || newHeight != oldHeight) {
                 bool outputPort = (newParams->nPortIndex == kOutputPortIndex);
-                def->format.video.nFrameWidth =
-                    (mIsAdaptive && outputPort) ? mAdaptiveMaxWidth : newWidth;
-                def->format.video.nFrameHeight =
-                    (mIsAdaptive && outputPort) ? mAdaptiveMaxHeight : newHeight;
                 if (outputPort) {
-                    def->format.video.nStride = def->format.video.nFrameWidth;
-                    def->format.video.nSliceHeight = def->format.video.nFrameHeight;
-                    def->nBufferSize =
-                        def->format.video.nStride * def->format.video.nSliceHeight * 3 / 2;
-
-
-                    OMX_PARAM_PORTDEFINITIONTYPE *inDef = &editPortInfo(kInputPortIndex)->mDef;
-                    // increase input buffer size if required
-                    inDef->nBufferSize =
-                        max(def->nBufferSize / mMinCompressionRatio, inDef->nBufferSize);
-
+                    // only update (essentially crop) if size changes
                     mWidth = newWidth;
                     mHeight = newHeight;
-                    mCropLeft = 0;
-                    mCropTop = 0;
-                    mCropWidth = newWidth;
-                    mCropHeight = newHeight;
+
+                    updatePortDefinitions(true /* updateCrop */, true /* updateInputSize */);
+                    // reset buffer size based on frame size
+                    newParams->nBufferSize = def->nBufferSize;
+                } else {
+                    // For input port, we only set nFrameWidth and nFrameHeight. Buffer size
+                    // is updated when configuring the output port using the max-frame-size,
+                    // though client can still request a larger size.
+                    def->format.video.nFrameWidth = newWidth;
+                    def->format.video.nFrameHeight = newHeight;
                 }
-                newParams->nBufferSize = def->nBufferSize;
             }
             return SimpleSoftOMXComponent::internalSetParameter(index, params);
         }
diff --git a/services/audioflinger/Android.mk b/services/audioflinger/Android.mk
index 697fb37..f0196c6 100644
--- a/services/audioflinger/Android.mk
+++ b/services/audioflinger/Android.mk
@@ -19,7 +19,13 @@
 # FIXME Move this library to frameworks/native
 LOCAL_MODULE := libserviceutility
 
-include $(BUILD_STATIC_LIBRARY)
+LOCAL_SHARED_LIBRARIES := \
+    libcutils \
+    libutils \
+    liblog \
+    libbinder
+
+include $(BUILD_SHARED_LIBRARY)
 
 include $(CLEAR_VARS)
 
@@ -51,13 +57,13 @@
     libhardware \
     libhardware_legacy \
     libeffects \
-    libpowermanager
+    libpowermanager \
+    libserviceutility
 
 LOCAL_STATIC_LIBRARIES := \
     libscheduling_policy \
     libcpustats \
-    libmedia_helper \
-    libserviceutility
+    libmedia_helper
 
 LOCAL_MODULE:= libaudioflinger
 LOCAL_32_BIT_ONLY := true
diff --git a/services/audioflinger/PatchPanel.cpp b/services/audioflinger/PatchPanel.cpp
index 7544052..4f0c6b1 100644
--- a/services/audioflinger/PatchPanel.cpp
+++ b/services/audioflinger/PatchPanel.cpp
@@ -166,7 +166,9 @@
             if (*handle == mPatches[index]->mHandle) {
                 ALOGV("createAudioPatch() removing patch handle %d", *handle);
                 halHandle = mPatches[index]->mHalHandle;
+                Patch *removedPatch = mPatches[index];
                 mPatches.removeAt(index);
+                delete removedPatch;
                 break;
             }
         }
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index dacb12c..9fccda1 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -4083,6 +4083,10 @@
                 track->mRetryCount = kMaxTrackRetriesDirect;
                 mActiveTrack = t;
                 mixerStatus = MIXER_TRACKS_READY;
+                if (usesHwAvSync() && mHwPaused) {
+                    doHwResume = true;
+                    mHwPaused = false;
+                }
             }
         } else {
             // clear effect chain input buffer if the last active track started underruns
@@ -4111,9 +4115,6 @@
                         track->mState = TrackBase::STOPPED;
                     }
                     if (track->isStopped()) {
-                        if (track->mState == TrackBase::FLUSHED) {
-                            flushHw_l();
-                        }
                         track->reset();
                     }
                     tracksToRemove->add(track);
@@ -4130,6 +4131,10 @@
                     android_atomic_or(CBLK_DISABLED, &cblk->mFlags);
                 } else if (last) {
                     mixerStatus = MIXER_TRACKS_ENABLED;
+                    if (usesHwAvSync() && !mHwPaused && !mStandby) {
+                        doHwPause = true;
+                        mHwPaused = true;
+                    }
                 }
             }
         }
@@ -4192,7 +4197,7 @@
 void AudioFlinger::DirectOutputThread::threadLoop_sleepTime()
 {
     // do not write to HAL when paused
-    if (mHwPaused) {
+    if (mHwPaused || (usesHwAvSync() && mStandby)) {
         sleepTime = idleSleepTime;
         return;
     }
@@ -4237,7 +4242,7 @@
         trackPaused = mTracks[mTracks.size() - 1]->isPaused();
     }
 
-    return !mStandby && !trackPaused;
+    return !mStandby && !(trackPaused || (usesHwAvSync() && mHwPaused));
 }
 
 // getTrackName_l() must be called with ThreadBase::mLock held
diff --git a/services/audioflinger/Threads.h b/services/audioflinger/Threads.h
index f5d0e27..1088843 100644
--- a/services/audioflinger/Threads.h
+++ b/services/audioflinger/Threads.h
@@ -710,6 +710,9 @@
                                    audio_patch_handle_t *handle);
     virtual     status_t    releaseAudioPatch_l(const audio_patch_handle_t handle);
 
+                bool        usesHwAvSync() const { return (mType == DIRECT) && (mOutput != NULL) &&
+                                                (mOutput->flags & AUDIO_OUTPUT_FLAG_HW_AV_SYNC); }
+
 private:
 
     friend class AudioFlinger;      // for numerous
diff --git a/services/audiopolicy/Android.mk b/services/audiopolicy/Android.mk
index 6512c38..188fc89 100644
--- a/services/audiopolicy/Android.mk
+++ b/services/audiopolicy/Android.mk
@@ -30,7 +30,8 @@
     libbinder \
     libmedia \
     libhardware \
-    libhardware_legacy
+    libhardware_legacy \
+    libserviceutility
 
 ifneq ($(USE_LEGACY_AUDIO_POLICY), 1)
 LOCAL_SHARED_LIBRARIES += \
@@ -38,8 +39,7 @@
 endif
 
 LOCAL_STATIC_LIBRARIES := \
-    libmedia_helper \
-    libserviceutility
+    libmedia_helper
 
 LOCAL_MODULE:= libaudiopolicyservice
 
diff --git a/services/audiopolicy/AudioPolicyEffects.cpp b/services/audiopolicy/AudioPolicyEffects.cpp
index 4fbe042..e6ace20 100644
--- a/services/audiopolicy/AudioPolicyEffects.cpp
+++ b/services/audiopolicy/AudioPolicyEffects.cpp
@@ -658,6 +658,10 @@
     loadInputEffectConfigurations(root, effects);
     loadStreamEffectConfigurations(root, effects);
 
+    for (size_t i = 0; i < effects.size(); i++) {
+        delete effects[i];
+    }
+
     config_free(root);
     free(root);
     free(data);
diff --git a/services/audiopolicy/AudioPolicyInterfaceImplLegacy.cpp b/services/audiopolicy/AudioPolicyInterfaceImplLegacy.cpp
index 4bc3c7f..b8846c6 100644
--- a/services/audiopolicy/AudioPolicyInterfaceImplLegacy.cpp
+++ b/services/audiopolicy/AudioPolicyInterfaceImplLegacy.cpp
@@ -241,14 +241,21 @@
     if (mpAudioPolicy == NULL) {
         return NO_INIT;
     }
+
+    audio_source_t inputSource = attr->source;
+
     // already checked by client, but double-check in case the client wrapper is bypassed
-    if (attr->source >= AUDIO_SOURCE_CNT && attr->source != AUDIO_SOURCE_HOTWORD &&
-        attr->source != AUDIO_SOURCE_FM_TUNER) {
+    if (inputSource >= AUDIO_SOURCE_CNT && inputSource != AUDIO_SOURCE_HOTWORD &&
+        inputSource != AUDIO_SOURCE_FM_TUNER) {
         return BAD_VALUE;
     }
 
-    if (((attr->source == AUDIO_SOURCE_HOTWORD) && !captureHotwordAllowed()) ||
-        ((attr->source == AUDIO_SOURCE_FM_TUNER) && !captureFmTunerAllowed())) {
+    if (inputSource == AUDIO_SOURCE_DEFAULT) {
+        inputSource = AUDIO_SOURCE_MIC;
+    }
+
+    if (((inputSource == AUDIO_SOURCE_HOTWORD) && !captureHotwordAllowed()) ||
+        ((inputSource == AUDIO_SOURCE_FM_TUNER) && !captureFmTunerAllowed())) {
         return BAD_VALUE;
     }
 
@@ -256,7 +263,7 @@
     {
         Mutex::Autolock _l(mLock);
         // the audio_in_acoustics_t parameter is ignored by get_input()
-        *input = mpAudioPolicy->get_input(mpAudioPolicy, attr->source, samplingRate,
+        *input = mpAudioPolicy->get_input(mpAudioPolicy, inputSource, samplingRate,
                                              format, channelMask, (audio_in_acoustics_t) 0);
         audioPolicyEffects = mAudioPolicyEffects;
     }
@@ -266,7 +273,7 @@
 
     if (audioPolicyEffects != 0) {
         // create audio pre processors according to input source
-        status_t status = audioPolicyEffects->addInputEffects(*input, attr->source, session);
+        status_t status = audioPolicyEffects->addInputEffects(*input, inputSource, session);
         if (status != NO_ERROR && status != ALREADY_EXISTS) {
             ALOGW("Failed to add effects on input %d", input);
         }
diff --git a/services/audiopolicy/AudioPolicyManager.cpp b/services/audiopolicy/AudioPolicyManager.cpp
index a3389e0..0349327 100644
--- a/services/audiopolicy/AudioPolicyManager.cpp
+++ b/services/audiopolicy/AudioPolicyManager.cpp
@@ -596,6 +596,9 @@
             }
             handleIncallSonification((audio_stream_type_t)stream, false, true);
         }
+
+        // force reevaluating accessibility routing when call starts
+        mpClientInterface->invalidateStream(AUDIO_STREAM_ACCESSIBILITY);
     }
 
     // store previous phone state for management of sonification strategy below
@@ -1290,6 +1293,11 @@
                         outputDesc->mPolicyMix->mRegistrationId);
         }
 
+        // force reevaluating accessibility routing when ringtone or alarm starts
+        if (strategy == STRATEGY_SONIFICATION) {
+            mpClientInterface->invalidateStream(AUDIO_STREAM_ACCESSIBILITY);
+        }
+
         if (waitMs > muteWaitMs) {
             usleep((waitMs - muteWaitMs) * 2 * 1000);
         }
@@ -1432,10 +1440,16 @@
     // handle legacy remote submix case where the address was not always specified
     String8 address = String8("");
     bool isSoundTrigger = false;
-    audio_source_t halInputSource = attr->source;
+    audio_source_t inputSource = attr->source;
+    audio_source_t halInputSource;
     AudioMix *policyMix = NULL;
 
-    if (attr->source == AUDIO_SOURCE_REMOTE_SUBMIX &&
+    if (inputSource == AUDIO_SOURCE_DEFAULT) {
+        inputSource = AUDIO_SOURCE_MIC;
+    }
+    halInputSource = inputSource;
+
+    if (inputSource == AUDIO_SOURCE_REMOTE_SUBMIX &&
             strncmp(attr->tags, "addr=", strlen("addr=")) == 0) {
         device = AUDIO_DEVICE_IN_REMOTE_SUBMIX;
         address = String8(attr->tags + strlen("addr="));
@@ -1451,9 +1465,9 @@
         policyMix = &mPolicyMixes[index]->mMix;
         *inputType = API_INPUT_MIX_EXT_POLICY_REROUTE;
     } else {
-        device = getDeviceAndMixForInputSource(attr->source, &policyMix);
+        device = getDeviceAndMixForInputSource(inputSource, &policyMix);
         if (device == AUDIO_DEVICE_NONE) {
-            ALOGW("getInputForAttr() could not find device for source %d", attr->source);
+            ALOGW("getInputForAttr() could not find device for source %d", inputSource);
             return BAD_VALUE;
         }
         if (policyMix != NULL) {
@@ -1475,7 +1489,7 @@
             *inputType = API_INPUT_LEGACY;
         }
         // adapt channel selection to input source
-        switch (attr->source) {
+        switch (inputSource) {
         case AUDIO_SOURCE_VOICE_UPLINK:
             channelMask = AUDIO_CHANNEL_IN_VOICE_UPLINK;
             break;
@@ -1488,7 +1502,7 @@
         default:
             break;
         }
-        if (attr->source == AUDIO_SOURCE_HOTWORD) {
+        if (inputSource == AUDIO_SOURCE_HOTWORD) {
             ssize_t index = mSoundTriggerSessions.indexOfKey(session);
             if (index >= 0) {
                 *input = mSoundTriggerSessions.valueFor(session);
@@ -1551,7 +1565,7 @@
     }
 
     sp<AudioInputDescriptor> inputDesc = new AudioInputDescriptor(profile);
-    inputDesc->mInputSource = attr->source;
+    inputDesc->mInputSource = inputSource;
     inputDesc->mRefCount = 0;
     inputDesc->mOpenRefCount = 1;
     inputDesc->mSamplingRate = samplingRate;
@@ -2047,12 +2061,23 @@
 {
     for (size_t i = 0; i < mInputs.size(); i++) {
         const sp<AudioInputDescriptor>  inputDescriptor = mInputs.valueAt(i);
-        if ((inputDescriptor->mInputSource == (int)source ||
-                (source == AUDIO_SOURCE_VOICE_RECOGNITION &&
-                 inputDescriptor->mInputSource == AUDIO_SOURCE_HOTWORD))
-             && (inputDescriptor->mRefCount > 0)) {
+        if (inputDescriptor->mRefCount == 0) {
+            continue;
+        }
+        if (inputDescriptor->mInputSource == (int)source) {
             return true;
         }
+        // AUDIO_SOURCE_HOTWORD is equivalent to AUDIO_SOURCE_VOICE_RECOGNITION only if it
+        // corresponds to an active capture triggered by a hardware hotword recognition
+        if ((source == AUDIO_SOURCE_VOICE_RECOGNITION) &&
+                 (inputDescriptor->mInputSource == AUDIO_SOURCE_HOTWORD)) {
+            // FIXME: we should not assume that the first session is the active one and keep
+            // activity count per session. Same in startInput().
+            ssize_t index = mSoundTriggerSessions.indexOfKey(inputDescriptor->mSessions.itemAt(0));
+            if (index >= 0) {
+                return true;
+            }
+        }
     }
     return false;
 }
@@ -3423,29 +3448,15 @@
 }
 
 void AudioPolicyManager::findIoHandlesByAddress(sp<AudioOutputDescriptor> desc /*in*/,
+        const audio_devices_t device /*in*/,
         const String8 address /*in*/,
         SortedVector<audio_io_handle_t>& outputs /*out*/) {
-    // look for a match on the given address on the addresses of the outputs:
-    // find the address by finding the patch that maps to this output
-    ssize_t patchIdx = mAudioPatches.indexOfKey(desc->mPatchHandle);
-    //ALOGV("    inspecting output %d (patch %d) for supported device=0x%x",
-    //        outputIdx, patchIdx,  desc->mProfile->mSupportedDevices.types());
-    if (patchIdx >= 0) {
-        const sp<AudioPatch> patchDesc = mAudioPatches.valueAt(patchIdx);
-        const int numSinks = patchDesc->mPatch.num_sinks;
-        for (ssize_t j=0; j < numSinks; j++) {
-            if (patchDesc->mPatch.sinks[j].type == AUDIO_PORT_TYPE_DEVICE) {
-                const char* patchAddr =
-                        patchDesc->mPatch.sinks[j].ext.device.address;
-                if (strncmp(patchAddr,
-                        address.string(), AUDIO_DEVICE_MAX_ADDRESS_LEN) == 0) {
-                    ALOGV("findIoHandlesByAddress(): adding opened output %d on same address %s",
-                            desc->mIoHandle,  patchDesc->mPatch.sinks[j].ext.device.address);
-                    outputs.add(desc->mIoHandle);
-                    break;
-                }
-            }
-        }
+    sp<DeviceDescriptor> devDesc =
+        desc->mProfile->mSupportedDevices.getDevice(device, address);
+    if (devDesc != 0) {
+        ALOGV("findIoHandlesByAddress(): adding opened output %d on same address %s",
+              desc->mIoHandle, address.string());
+        outputs.add(desc->mIoHandle);
     }
 }
 
@@ -3469,7 +3480,7 @@
                     outputs.add(mOutputs.keyAt(i));
                 } else {
                     ALOGV("  checking address match due to device 0x%x", device);
-                    findIoHandlesByAddress(desc, address, outputs);
+                    findIoHandlesByAddress(desc, device, address, outputs);
                 }
             }
         }
@@ -3697,7 +3708,7 @@
                 // exact match on device
                 if (deviceDistinguishesOnAddress(device) &&
                         (desc->mProfile->mSupportedDevices.types() == device)) {
-                    findIoHandlesByAddress(desc, address, outputs);
+                    findIoHandlesByAddress(desc, device, address, outputs);
                 } else if (!(desc->mProfile->mSupportedDevices.types()
                         & mAvailableOutputDevices.types())) {
                     ALOGV("checkOutputsForDevice(): disconnecting adding output %d",
@@ -5288,7 +5299,7 @@
     for (size_t i = 0; i < mInputs.size(); i++) {
         const sp<AudioInputDescriptor>  desc = mInputs.valueAt(i);
         if (desc->mRefCount > 0) {
-            return count++;
+            count++;
         }
     }
     return count;
diff --git a/services/audiopolicy/AudioPolicyManager.h b/services/audiopolicy/AudioPolicyManager.h
index 2059f58..0fa182b 100644
--- a/services/audiopolicy/AudioPolicyManager.h
+++ b/services/audiopolicy/AudioPolicyManager.h
@@ -594,7 +594,7 @@
 
         // change the route of the specified output. Returns the number of ms we have slept to
         // allow new routing to take effect in certain cases.
-        uint32_t setOutputDevice(audio_io_handle_t output,
+        virtual uint32_t setOutputDevice(audio_io_handle_t output,
                              audio_devices_t device,
                              bool force = false,
                              int delayMs = 0,
@@ -877,11 +877,13 @@
 #endif //AUDIO_POLICY_TEST
         static float volIndexToAmpl(audio_devices_t device, const StreamDescriptor& streamDesc,
                 int indexInUi);
+        static bool isVirtualInputDevice(audio_devices_t device);
+        uint32_t nextUniqueId();
+        uint32_t nextAudioPortGeneration();
 private:
         // updates device caching and output for streams that can influence the
         //    routing of notifications
         void handleNotificationRoutingForStream(audio_stream_type_t stream);
-        static bool isVirtualInputDevice(audio_devices_t device);
         static bool deviceDistinguishesOnAddress(audio_devices_t device);
         // find the outputs on a given output descriptor that have the given address.
         // to be called on an AudioOutputDescriptor whose supported devices (as defined
@@ -889,10 +891,9 @@
         // see deviceDistinguishesOnAddress(audio_devices_t) for whether the device type is one
         //   where addresses are used to distinguish between one connected device and another.
         void findIoHandlesByAddress(sp<AudioOutputDescriptor> desc /*in*/,
+                const audio_devices_t device /*in*/,
                 const String8 address /*in*/,
                 SortedVector<audio_io_handle_t>& outputs /*out*/);
-        uint32_t nextUniqueId();
-        uint32_t nextAudioPortGeneration();
         uint32_t curAudioPortGeneration() const { return mAudioPortGeneration; }
         // internal method to return the output handle for the given device and format
         audio_io_handle_t getOutputForDevice(
diff --git a/services/soundtrigger/Android.mk b/services/soundtrigger/Android.mk
index 572ae56..ecc49ae 100644
--- a/services/soundtrigger/Android.mk
+++ b/services/soundtrigger/Android.mk
@@ -32,9 +32,7 @@
     libcutils \
     libhardware \
     libsoundtrigger \
-    libmedia
-
-LOCAL_STATIC_LIBRARIES := \
+    libmedia \
     libserviceutility
 
 LOCAL_C_INCLUDES += \