Merge "IAudioFlinger::openRecord returns IMemory(s)"
diff --git a/media/libstagefright/MPEG4Extractor.cpp b/media/libstagefright/MPEG4Extractor.cpp
index 2a3fa04..e07b6aa 100644
--- a/media/libstagefright/MPEG4Extractor.cpp
+++ b/media/libstagefright/MPEG4Extractor.cpp
@@ -3540,7 +3540,7 @@
 
     off64_t offset;
     size_t size;
-    uint32_t cts;
+    uint32_t cts, stts;
     bool isSyncSample;
     bool newBuffer = false;
     if (mBuffer == NULL) {
@@ -3548,7 +3548,7 @@
 
         status_t err =
             mSampleTable->getMetaDataForSample(
-                    mCurrentSampleIndex, &offset, &size, &cts, &isSyncSample);
+                    mCurrentSampleIndex, &offset, &size, &cts, &isSyncSample, &stts);
 
         if (err != OK) {
             return err;
@@ -3579,6 +3579,8 @@
             mBuffer->meta_data()->clear();
             mBuffer->meta_data()->setInt64(
                     kKeyTime, ((int64_t)cts * 1000000) / mTimescale);
+            mBuffer->meta_data()->setInt64(
+                    kKeyDuration, ((int64_t)stts * 1000000) / mTimescale);
 
             if (targetSampleTimeUs >= 0) {
                 mBuffer->meta_data()->setInt64(
@@ -3701,6 +3703,8 @@
         mBuffer->meta_data()->clear();
         mBuffer->meta_data()->setInt64(
                 kKeyTime, ((int64_t)cts * 1000000) / mTimescale);
+        mBuffer->meta_data()->setInt64(
+                kKeyDuration, ((int64_t)stts * 1000000) / mTimescale);
 
         if (targetSampleTimeUs >= 0) {
             mBuffer->meta_data()->setInt64(
@@ -3850,6 +3854,8 @@
             mBuffer->set_range(0, size);
             mBuffer->meta_data()->setInt64(
                     kKeyTime, ((int64_t)cts * 1000000) / mTimescale);
+            mBuffer->meta_data()->setInt64(
+                    kKeyDuration, ((int64_t)smpl->duration * 1000000) / mTimescale);
 
             if (targetSampleTimeUs >= 0) {
                 mBuffer->meta_data()->setInt64(
@@ -3973,6 +3979,8 @@
 
         mBuffer->meta_data()->setInt64(
                 kKeyTime, ((int64_t)cts * 1000000) / mTimescale);
+        mBuffer->meta_data()->setInt64(
+                kKeyDuration, ((int64_t)smpl->duration * 1000000) / mTimescale);
 
         if (targetSampleTimeUs >= 0) {
             mBuffer->meta_data()->setInt64(
diff --git a/media/libstagefright/SampleIterator.cpp b/media/libstagefright/SampleIterator.cpp
index eae721b..2748349 100644
--- a/media/libstagefright/SampleIterator.cpp
+++ b/media/libstagefright/SampleIterator.cpp
@@ -133,7 +133,8 @@
     }
 
     status_t err;
-    if ((err = findSampleTime(sampleIndex, &mCurrentSampleTime)) != OK) {
+    if ((err = findSampleTimeAndDuration(
+            sampleIndex, &mCurrentSampleTime, &mCurrentSampleDuration)) != OK) {
         ALOGE("findSampleTime return error");
         return err;
     }
@@ -285,8 +286,8 @@
     return OK;
 }
 
-status_t SampleIterator::findSampleTime(
-        uint32_t sampleIndex, uint32_t *time) {
+status_t SampleIterator::findSampleTimeAndDuration(
+        uint32_t sampleIndex, uint32_t *time, uint32_t *duration) {
     if (sampleIndex >= mTable->mNumSampleSizes) {
         return ERROR_OUT_OF_RANGE;
     }
@@ -309,6 +310,8 @@
 
     *time += mTable->getCompositionTimeOffset(sampleIndex);
 
+    *duration = mTTSDuration;
+
     return OK;
 }
 
diff --git a/media/libstagefright/SampleTable.cpp b/media/libstagefright/SampleTable.cpp
index d9858d7..9a92805 100644
--- a/media/libstagefright/SampleTable.cpp
+++ b/media/libstagefright/SampleTable.cpp
@@ -778,7 +778,8 @@
         off64_t *offset,
         size_t *size,
         uint32_t *compositionTime,
-        bool *isSyncSample) {
+        bool *isSyncSample,
+        uint32_t *sampleDuration) {
     Mutex::Autolock autoLock(mLock);
 
     status_t err;
@@ -820,6 +821,10 @@
         }
     }
 
+    if (sampleDuration) {
+        *sampleDuration = mSampleIterator->getSampleDuration();
+    }
+
     return OK;
 }
 
diff --git a/media/libstagefright/httplive/PlaylistFetcher.cpp b/media/libstagefright/httplive/PlaylistFetcher.cpp
index 6160009..326d85b 100644
--- a/media/libstagefright/httplive/PlaylistFetcher.cpp
+++ b/media/libstagefright/httplive/PlaylistFetcher.cpp
@@ -69,6 +69,7 @@
       mNumRetries(0),
       mStartup(true),
       mPrepared(false),
+      mSkipToFirstIDRAfterConnect(false),
       mNextPTSTimeUs(-1ll),
       mMonitorQueueGeneration(0),
       mRefreshState(INITIAL_MINIMUM_RELOAD_DELAY),
@@ -1097,12 +1098,30 @@
             continue;
         }
 
+        if (stream == LiveSession::STREAMTYPE_VIDEO && mVideoMime.empty()) {
+            const char *mime;
+            if (source->getFormat()->findCString(kKeyMIMEType, &mime)) {
+                mVideoMime.setTo(mime);
+                if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC)) {
+                    mSkipToFirstIDRAfterConnect = true;
+                }
+            }
+        }
+
         int64_t timeUs;
         sp<ABuffer> accessUnit;
         status_t finalResult;
         while (source->hasBufferAvailable(&finalResult)
                 && source->dequeueAccessUnit(&accessUnit) == OK) {
 
+            if (stream == LiveSession::STREAMTYPE_VIDEO && mSkipToFirstIDRAfterConnect) {
+                if (!IsIDR(accessUnit)) {
+                    continue;
+                } else {
+                    mSkipToFirstIDRAfterConnect = false;
+                }
+            }
+
             CHECK(accessUnit->meta()->findInt64("timeUs", &timeUs));
             if (mMinStartTimeUs > 0) {
                 if (timeUs < mMinStartTimeUs) {
diff --git a/media/libstagefright/httplive/PlaylistFetcher.h b/media/libstagefright/httplive/PlaylistFetcher.h
index 6af82c4..e4fdbff 100644
--- a/media/libstagefright/httplive/PlaylistFetcher.h
+++ b/media/libstagefright/httplive/PlaylistFetcher.h
@@ -99,6 +99,7 @@
 
     sp<LiveSession> mSession;
     AString mURI;
+    AString mVideoMime;
 
     uint32_t mStreamTypeMask;
     int64_t mStartTimeUs;
@@ -116,6 +117,7 @@
     int32_t mNumRetries;
     bool mStartup;
     bool mPrepared;
+    bool mSkipToFirstIDRAfterConnect;
     int64_t mNextPTSTimeUs;
 
     int32_t mMonitorQueueGeneration;
diff --git a/media/libstagefright/include/SampleIterator.h b/media/libstagefright/include/SampleIterator.h
index b5a043c..60c9e7e 100644
--- a/media/libstagefright/include/SampleIterator.h
+++ b/media/libstagefright/include/SampleIterator.h
@@ -30,6 +30,7 @@
     off64_t getSampleOffset() const { return mCurrentSampleOffset; }
     size_t getSampleSize() const { return mCurrentSampleSize; }
     uint32_t getSampleTime() const { return mCurrentSampleTime; }
+    uint32_t getSampleDuration() const { return mCurrentSampleDuration; }
 
     status_t getSampleSizeDirect(
             uint32_t sampleIndex, size_t *size);
@@ -61,11 +62,12 @@
     off64_t mCurrentSampleOffset;
     size_t mCurrentSampleSize;
     uint32_t mCurrentSampleTime;
+    uint32_t mCurrentSampleDuration;
 
     void reset();
     status_t findChunkRange(uint32_t sampleIndex);
     status_t getChunkOffset(uint32_t chunk, off64_t *offset);
-    status_t findSampleTime(uint32_t sampleIndex, uint32_t *time);
+    status_t findSampleTimeAndDuration(uint32_t sampleIndex, uint32_t *time, uint32_t *duration);
 
     SampleIterator(const SampleIterator &);
     SampleIterator &operator=(const SampleIterator &);
diff --git a/media/libstagefright/include/SampleTable.h b/media/libstagefright/include/SampleTable.h
index 847dff7..fe146f2 100644
--- a/media/libstagefright/include/SampleTable.h
+++ b/media/libstagefright/include/SampleTable.h
@@ -66,7 +66,8 @@
             off64_t *offset,
             size_t *size,
             uint32_t *compositionTime,
-            bool *isSyncSample = NULL);
+            bool *isSyncSample = NULL,
+            uint32_t *sampleDuration = NULL);
 
     enum {
         kFlagBefore,