Merge "Using requested video scaling mode in NuPlayer" into nyc-mr1-dev
diff --git a/include/media/IMediaSource.h b/include/media/IMediaSource.h
index 709f425..524e7aa 100644
--- a/include/media/IMediaSource.h
+++ b/include/media/IMediaSource.h
@@ -114,6 +114,9 @@
     virtual status_t readMultiple(
             Vector<MediaBuffer *> *buffers, uint32_t maxNumBuffers = 1) = 0;
 
+    // Returns true if |readMultiple| is supported, otherwise false.
+    virtual bool supportReadMultiple() = 0;
+
     // Causes this source to suspend pulling data from its upstream source
     // until a subsequent read-with-seek. Currently only supported by
     // OMXCodec.
@@ -148,6 +151,10 @@
             Vector<MediaBuffer *> * /* buffers */, uint32_t /* maxNumBuffers = 1 */) {
         return ERROR_UNSUPPORTED;
     }
+
+    virtual bool supportReadMultiple() {
+        return false;
+    }
 protected:
     virtual ~BnMediaSource();
 
diff --git a/media/libmedia/IMediaSource.cpp b/media/libmedia/IMediaSource.cpp
index 7e40e4f..d2b4291 100644
--- a/media/libmedia/IMediaSource.cpp
+++ b/media/libmedia/IMediaSource.cpp
@@ -221,6 +221,10 @@
         return ret;
     }
 
+    bool supportReadMultiple() {
+        return true;
+    }
+
     virtual status_t pause() {
         ALOGV("pause");
         Parcel data, reply;
diff --git a/media/libmediaplayerservice/nuplayer/GenericSource.cpp b/media/libmediaplayerservice/nuplayer/GenericSource.cpp
index 56042d4..3d836c8 100644
--- a/media/libmediaplayerservice/nuplayer/GenericSource.cpp
+++ b/media/libmediaplayerservice/nuplayer/GenericSource.cpp
@@ -1420,7 +1420,9 @@
         options.setNonBlocking();
     }
 
-    bool couldReadMultiple = (!mIsWidevine && trackType == MEDIA_TRACK_TYPE_AUDIO);
+    bool couldReadMultiple =
+        (!mIsWidevine && trackType == MEDIA_TRACK_TYPE_AUDIO
+                && track->mSource->supportReadMultiple());
     for (size_t numBuffers = 0; numBuffers < maxBuffers; ) {
         Vector<MediaBuffer *> mediaBuffers;
         status_t err = NO_ERROR;
diff --git a/media/libstagefright/MediaCodecSource.cpp b/media/libstagefright/MediaCodecSource.cpp
index 0aafa6b..5039922 100644
--- a/media/libstagefright/MediaCodecSource.cpp
+++ b/media/libstagefright/MediaCodecSource.cpp
@@ -648,6 +648,15 @@
             CHECK(mbuf->meta_data()->findInt64(kKeyTime, &timeUs));
             timeUs += mInputBufferTimeOffsetUs;
 
+            // Due to the extra delay adjustment at the beginning of start/resume,
+            // the adjusted timeUs may be negative if MediaCodecSource goes into pause
+            // state before feeding any buffers to the encoder. Drop the buffer in this
+            // case.
+            if (timeUs < 0) {
+                mbuf->release();
+                return OK;
+            }
+
             // push decoding time for video, or drift time for audio
             if (mIsVideo) {
                 mDecodingTimeQueue.push_back(timeUs);
@@ -832,9 +841,16 @@
                         // Time offset is not applied at
                         // feedEncoderInputBuffer() in surface input case.
                         timeUs += mInputBufferTimeOffsetUs;
-                        // GraphicBufferSource is supposed to discard samples
-                        // queued before start, and offset timeUs by start time
-                        CHECK_GE(timeUs, 0ll);
+
+                        // Due to the extra delay adjustment at the beginning of
+                        // start/resume, the adjusted timeUs may be negative if
+                        // MediaCodecSource goes into pause state before feeding
+                        // any buffers to the encoder. Drop the buffer in this case.
+                        if (timeUs < 0) {
+                            mEncoder->releaseOutputBuffer(index);
+                            break;
+                        }
+
                         // TODO:
                         // Decoding time for surface source is unavailable,
                         // use presentation time for now. May need to move
diff --git a/media/libstagefright/SurfaceUtils.cpp b/media/libstagefright/SurfaceUtils.cpp
index f64bb3e..9940822 100644
--- a/media/libstagefright/SurfaceUtils.cpp
+++ b/media/libstagefright/SurfaceUtils.cpp
@@ -168,10 +168,6 @@
             break;
         }
 
-        if (img == NULL) {
-            ALOGE("error pushing blank frames: lock returned NULL buffer");
-            break;
-        }
         *img = 0;
 
         err = buf->unlock();
diff --git a/media/libstagefright/httplive/M3UParser.cpp b/media/libstagefright/httplive/M3UParser.cpp
index 935f1dc..c04549a 100644
--- a/media/libstagefright/httplive/M3UParser.cpp
+++ b/media/libstagefright/httplive/M3UParser.cpp
@@ -701,6 +701,22 @@
         mLastSeqNumber = mFirstSeqNumber + mItems.size() - 1;
     }
 
+    for (size_t i = 0; i < mItems.size(); ++i) {
+        sp<AMessage> meta = mItems.itemAt(i).mMeta;
+        const char *keys[] = {"audio", "video", "subtitles"};
+        for (size_t j = 0; j < sizeof(keys) / sizeof(const char *); ++j) {
+            AString groupID;
+            if (meta->findString(keys[j], &groupID)) {
+                ssize_t groupIndex = mMediaGroups.indexOfKey(groupID);
+                if (groupIndex < 0) {
+                    ALOGE("Undefined media group '%s' referenced in stream info.",
+                          groupID.c_str());
+                    return ERROR_MALFORMED;
+                }
+            }
+        }
+    }
+
     return OK;
 }
 
@@ -873,15 +889,6 @@
             }
 
             const AString &groupID = unquoteString(val);
-            ssize_t groupIndex = mMediaGroups.indexOfKey(groupID);
-
-            if (groupIndex < 0) {
-                ALOGE("Undefined media group '%s' referenced in stream info.",
-                      groupID.c_str());
-
-                return ERROR_MALFORMED;
-            }
-
             key.tolower();
             if (meta->get() == NULL) {
                 *meta = new AMessage;