httplive: clear access units before returning from seekTo.

Bug: 12060952
Change-Id: I6a69a718c082501003ee9b78a948a2f8bbfbb14e
diff --git a/media/libstagefright/httplive/LiveSession.cpp b/media/libstagefright/httplive/LiveSession.cpp
index 687e871..c1c3e2b 100644
--- a/media/libstagefright/httplive/LiveSession.cpp
+++ b/media/libstagefright/httplive/LiveSession.cpp
@@ -67,7 +67,8 @@
       mRealTimeBaseUs(0ll),
       mReconfigurationInProgress(false),
       mSwitchInProgress(false),
-      mDisconnectReplyID(0) {
+      mDisconnectReplyID(0),
+      mSeekReplyID(0) {
     if (mUIDValid) {
         mHTTPDataSource->setUID(mUID);
     }
@@ -234,6 +235,10 @@
     sp<AMessage> response;
     status_t err = msg->postAndAwaitResponse(&response);
 
+    uint32_t replyID;
+    CHECK(response == mSeekReply && 0 != mSeekReplyID);
+    mSeekReply.clear();
+    mSeekReplyID = 0;
     return err;
 }
 
@@ -259,15 +264,12 @@
 
         case kWhatSeek:
         {
-            uint32_t replyID;
-            CHECK(msg->senderAwaitsResponse(&replyID));
+            CHECK(msg->senderAwaitsResponse(&mSeekReplyID));
 
             status_t err = onSeek(msg);
 
-            sp<AMessage> response = new AMessage;
-            response->setInt32("err", err);
-
-            response->postReply(replyID);
+            mSeekReply = new AMessage;
+            mSeekReply->setInt32("err", err);
             break;
         }
 
@@ -297,6 +299,11 @@
                         CHECK_GT(mContinuationCounter, 0);
                         if (--mContinuationCounter == 0) {
                             mContinuation->post();
+
+                            if (mSeekReplyID != 0) {
+                                CHECK(mSeekReply != NULL);
+                                mSeekReply->postReply(mSeekReplyID);
+                            }
                         }
                     }
                     break;
@@ -1035,6 +1042,11 @@
 
     if (mContinuationCounter == 0) {
         msg->post();
+
+        if (mSeekReplyID != 0) {
+            CHECK(mSeekReply != NULL);
+            mSeekReply->postReply(mSeekReplyID);
+        }
     }
 }
 
diff --git a/media/libstagefright/httplive/LiveSession.h b/media/libstagefright/httplive/LiveSession.h
index 376d451..680792d 100644
--- a/media/libstagefright/httplive/LiveSession.h
+++ b/media/libstagefright/httplive/LiveSession.h
@@ -175,6 +175,7 @@
 
     size_t mContinuationCounter;
     sp<AMessage> mContinuation;
+    sp<AMessage> mSeekReply;
 
     int64_t mLastDequeuedTimeUs;
     int64_t mRealTimeBaseUs;
@@ -182,6 +183,7 @@
     bool mReconfigurationInProgress;
     bool mSwitchInProgress;
     uint32_t mDisconnectReplyID;
+    uint32_t mSeekReplyID;
 
     sp<PlaylistFetcher> addFetcher(const char *uri);
 
diff --git a/media/libstagefright/httplive/PlaylistFetcher.cpp b/media/libstagefright/httplive/PlaylistFetcher.cpp
index 0eac8b3..012a68b 100644
--- a/media/libstagefright/httplive/PlaylistFetcher.cpp
+++ b/media/libstagefright/httplive/PlaylistFetcher.cpp
@@ -364,8 +364,10 @@
     (new AMessage(kWhatPause, id()))->post();
 }
 
-void PlaylistFetcher::stopAsync() {
-    (new AMessage(kWhatStop, id()))->post();
+void PlaylistFetcher::stopAsync(bool selfTriggered) {
+    sp<AMessage> msg = new AMessage(kWhatStop, id());
+    msg->setInt32("selfTriggered", selfTriggered);
+    msg->post();
 }
 
 void PlaylistFetcher::resumeUntilAsync(const sp<AMessage> &params) {
@@ -399,7 +401,7 @@
 
         case kWhatStop:
         {
-            onStop();
+            onStop(msg);
 
             sp<AMessage> notify = mNotify->dup();
             notify->setInt32("what", kWhatStopped);
@@ -498,9 +500,20 @@
     cancelMonitorQueue();
 }
 
-void PlaylistFetcher::onStop() {
+void PlaylistFetcher::onStop(const sp<AMessage> &msg) {
     cancelMonitorQueue();
 
+    int32_t selfTriggered;
+    CHECK(msg->findInt32("selfTriggered", &selfTriggered));
+    if (!selfTriggered) {
+        // Self triggered stops only happen during switching, in which case we do not want
+        // to clear the discontinuities queued at the end of packet sources.
+        for (size_t i = 0; i < mPacketSources.size(); i++) {
+            sp<AnotherPacketSource> packetSource = mPacketSources.valueAt(i);
+            packetSource->clear();
+        }
+    }
+
     mPacketSources.clear();
     mStreamTypeMask = 0;
 }
@@ -552,7 +565,7 @@
         for (size_t i = 0; i < mPacketSources.size(); i++) {
             mPacketSources.valueAt(i)->queueAccessUnit(mSession->createFormatChangeBuffer());
         }
-        stopAsync();
+        stopAsync(/* selfTriggered = */ true);
         return OK;
     }
 
@@ -866,7 +879,7 @@
 
     if (err == ERROR_OUT_OF_RANGE) {
         // reached stopping point
-        stopAsync();
+        stopAsync(/* selfTriggered = */ true);
         return;
     }
 
diff --git a/media/libstagefright/httplive/PlaylistFetcher.h b/media/libstagefright/httplive/PlaylistFetcher.h
index 2e0349f..8404b8d 100644
--- a/media/libstagefright/httplive/PlaylistFetcher.h
+++ b/media/libstagefright/httplive/PlaylistFetcher.h
@@ -63,7 +63,7 @@
 
     void pauseAsync();
 
-    void stopAsync();
+    void stopAsync(bool selfTriggered = false);
 
     void resumeUntilAsync(const sp<AMessage> &params);
 
@@ -162,7 +162,7 @@
 
     status_t onStart(const sp<AMessage> &msg);
     void onPause();
-    void onStop();
+    void onStop(const sp<AMessage> &msg);
     void onMonitorQueue();
     void onDownloadNext();