mpeg2ts: revise duration estimation logic

Estimate duration based on GOP duration and size to yield more
accurate result. For a fully buffered stream, just use the buffered
duration.

Bug: 21391417
Change-Id: I116ae8f596007a0b9fca427a4875c10820ddfea2
diff --git a/media/libstagefright/mpeg2ts/MPEG2TSExtractor.cpp b/media/libstagefright/mpeg2ts/MPEG2TSExtractor.cpp
index e0ee87b..aae3e9f 100644
--- a/media/libstagefright/mpeg2ts/MPEG2TSExtractor.cpp
+++ b/media/libstagefright/mpeg2ts/MPEG2TSExtractor.cpp
@@ -194,18 +194,19 @@
                         ATSParser::VIDEO).get()
                 : (AnotherPacketSource *)mParser->getSource(
                         ATSParser::AUDIO).get();
-        int64_t prevBufferedDurationUs = 0;
+        size_t prevSyncSize = 1;
         int64_t durationUs = -1;
         List<int64_t> durations;
         // Estimate duration --- stabilize until you get <500ms deviation.
-        while (feedMore() == OK && ALooper::GetNowUs() - startTime <= 2000000ll) {
-            status_t err;
-            int64_t bufferedDurationUs = impl->getBufferedDurationUs(&err);
-            if (err != OK) {
-                break;
-            }
-            if (bufferedDurationUs != prevBufferedDurationUs) {
-                durationUs = size * bufferedDurationUs / mOffset;
+        while (feedMore() == OK
+                && ALooper::GetNowUs() - startTime <= 2000000ll) {
+            if (mSeekSyncPoints->size() > prevSyncSize) {
+                prevSyncSize = mSeekSyncPoints->size();
+                int64_t diffUs = mSeekSyncPoints->keyAt(prevSyncSize - 1)
+                        - mSeekSyncPoints->keyAt(0);
+                off64_t diffOffset = mSeekSyncPoints->valueAt(prevSyncSize - 1)
+                        - mSeekSyncPoints->valueAt(0);
+                durationUs = size * diffUs / diffOffset;
                 durations.push_back(durationUs);
                 if (durations.size() > 5) {
                     durations.erase(durations.begin());
@@ -225,9 +226,14 @@
                         break;
                     }
                 }
-                prevBufferedDurationUs = bufferedDurationUs;
             }
         }
+        status_t err;
+        int64_t bufferedDurationUs;
+        bufferedDurationUs = impl->getBufferedDurationUs(&err);
+        if (err == ERROR_END_OF_STREAM) {
+            durationUs = bufferedDurationUs;
+        }
         if (durationUs > 0) {
             const sp<MetaData> meta = impl->getFormat();
             meta->setInt64(kKeyDuration, durationUs);