Merge "GenericSource: timed text support" into lmp-dev
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
index adc5f33..58d0138 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
@@ -1230,14 +1230,15 @@
                 mTimeDiscontinuityPending =
                     mTimeDiscontinuityPending || timeChange;
 
+                if (mFlushingAudio == NONE && mFlushingVideo == NONE) {
+                    // And we'll resume scanning sources once we're done
+                    // flushing.
+                    mDeferredActions.push_front(
+                            new SimpleAction(
+                                &NuPlayer::performScanSources));
+                }
+
                 if (formatChange || timeChange) {
-                    if (mFlushingAudio == NONE && mFlushingVideo == NONE) {
-                        // And we'll resume scanning sources once we're done
-                        // flushing.
-                        mDeferredActions.push_front(
-                                new SimpleAction(
-                                    &NuPlayer::performScanSources));
-                    }
 
                     sp<AMessage> newFormat = mSource->getFormat(audio);
                     sp<Decoder> &decoder = audio ? mAudioDecoder : mVideoDecoder;
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp
index 280b5af..4748546 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp
@@ -42,6 +42,7 @@
       mLooper(new ALooper),
       mPlayerFlags(0),
       mAtEOS(false),
+      mLooping(false),
       mStartupSeekTimeUs(-1) {
     mLooper->setName("NuPlayerDriver Looper");
 
@@ -76,6 +77,7 @@
         const KeyedVector<String8, String8> *headers) {
     Mutex::Autolock autoLock(mLock);
 
+    ALOGV("setDataSource: url=%s", url);
     if (mState != STATE_IDLE) {
         return INVALID_OPERATION;
     }
@@ -94,6 +96,7 @@
 status_t NuPlayerDriver::setDataSource(int fd, int64_t offset, int64_t length) {
     Mutex::Autolock autoLock(mLock);
 
+    ALOGV("setDataSource: fd=%d", fd);
     if (mState != STATE_IDLE) {
         return INVALID_OPERATION;
     }
@@ -112,6 +115,7 @@
 status_t NuPlayerDriver::setDataSource(const sp<IStreamSource> &source) {
     Mutex::Autolock autoLock(mLock);
 
+    ALOGV("setDataSource: stream source");
     if (mState != STATE_IDLE) {
         return INVALID_OPERATION;
     }
@@ -367,12 +371,14 @@
     mDurationUs = -1;
     mPositionUs = -1;
     mStartupSeekTimeUs = -1;
+    mLooping = false;
 
     return OK;
 }
 
-status_t NuPlayerDriver::setLooping(int /* loop */) {
-    return INVALID_OPERATION;
+status_t NuPlayerDriver::setLooping(int loop) {
+    mLooping = loop != 0;
+    return OK;
 }
 
 player_type NuPlayerDriver::playerType() {
@@ -523,8 +529,24 @@
 
 void NuPlayerDriver::notifyListener(
         int msg, int ext1, int ext2, const Parcel *in) {
-    if (msg == MEDIA_PLAYBACK_COMPLETE || msg == MEDIA_ERROR) {
-        mAtEOS = true;
+    switch (msg) {
+        case MEDIA_PLAYBACK_COMPLETE:
+        {
+            if (mLooping) {
+                mPlayer->seekToAsync(0);
+                break;
+            }
+            // fall through
+        }
+
+        case MEDIA_ERROR:
+        {
+            mAtEOS = true;
+            break;
+        }
+
+        default:
+            break;
     }
 
     sendEvent(msg, ext1, ext2, in);
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDriver.h b/media/libmediaplayerservice/nuplayer/NuPlayerDriver.h
index 0148fb1..9424aae 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerDriver.h
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerDriver.h
@@ -111,6 +111,7 @@
     uint32_t mPlayerFlags;
 
     bool mAtEOS;
+    bool mLooping;
 
     int64_t mStartupSeekTimeUs;
 
diff --git a/media/libstagefright/MPEG4Extractor.cpp b/media/libstagefright/MPEG4Extractor.cpp
index 19da6ee..0064293 100644
--- a/media/libstagefright/MPEG4Extractor.cpp
+++ b/media/libstagefright/MPEG4Extractor.cpp
@@ -489,7 +489,9 @@
         off64_t orig_offset = offset;
         err = parseChunk(&offset, 0);
 
-        if (offset <= orig_offset) {
+        if (err != OK && err != UNKNOWN_ERROR) {
+            break;
+        } else if (offset <= orig_offset) {
             // only continue parsing if the offset was advanced,
             // otherwise we might end up in an infinite loop
             ALOGE("did not advance: 0x%lld->0x%lld", orig_offset, offset);
@@ -497,9 +499,8 @@
             break;
         } else if (err == OK) {
             continue;
-        } else if (err != UNKNOWN_ERROR) {
-            break;
         }
+
         uint32_t hdr[2];
         if (mDataSource->readAt(offset, hdr, 8) < 8) {
             break;