Merge "audioflinger: Pass pid of process creating track or opening record" into nyc-dev
diff --git a/include/media/stagefright/MetaData.h b/include/media/stagefright/MetaData.h
index 6493a5e..7b43f87 100644
--- a/include/media/stagefright/MetaData.h
+++ b/include/media/stagefright/MetaData.h
@@ -53,6 +53,7 @@
     kKeyFrameRate         = 'frmR',  // int32_t (video frame rate fps)
     kKeyBitRate           = 'brte',  // int32_t (bps)
     kKeyMaxBitRate        = 'mxBr',  // int32_t (bps)
+    kKeyStreamHeader      = 'stHd',  // raw data
     kKeyESDS              = 'esds',  // raw data
     kKeyAACProfile        = 'aacp',  // int32_t
     kKeyAVCC              = 'avcc',  // raw data
diff --git a/include/media/stagefright/NuMediaExtractor.h b/include/media/stagefright/NuMediaExtractor.h
index 6606c58..03e2185 100644
--- a/include/media/stagefright/NuMediaExtractor.h
+++ b/include/media/stagefright/NuMediaExtractor.h
@@ -44,6 +44,11 @@
         SAMPLE_FLAG_ENCRYPTED   = 2,
     };
 
+    // identical to IMediaExtractor::GetTrackMetaDataFlags
+    enum GetTrackFormatFlags {
+        kIncludeExtensiveMetaData = 1, // reads sample table and possibly stream headers
+    };
+
     NuMediaExtractor();
 
     status_t setDataSource(
@@ -56,7 +61,7 @@
     status_t setDataSource(const sp<DataSource> &datasource);
 
     size_t countTracks() const;
-    status_t getTrackFormat(size_t index, sp<AMessage> *format) const;
+    status_t getTrackFormat(size_t index, sp<AMessage> *format, uint32_t flags = 0) const;
 
     status_t getFileFormat(sp<AMessage> *format) const;
 
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
index 1fbb957..87d64cd 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
@@ -192,7 +192,6 @@
       mSourceStarted(false),
       mPaused(false),
       mPausedByClient(true),
-      mPendingBufferingFlag(PENDING_BUFFERING_FLAG_NONE),
       mPausedForBuffering(false) {
     clearFlushComplete();
 }
@@ -723,10 +722,6 @@
                 onStart();
             }
             mPausedByClient = false;
-            if (mPendingBufferingFlag != PENDING_BUFFERING_FLAG_NONE) {
-                notifyListener(MEDIA_INFO, mPendingBufferingFlag, 0);
-                mPendingBufferingFlag = PENDING_BUFFERING_FLAG_NONE;
-            }
             break;
         }
 
@@ -1218,8 +1213,6 @@
                 break;
             }
 
-            mPendingBufferingFlag = PENDING_BUFFERING_FLAG_NONE;
-
             mDeferredActions.push_back(
                     new FlushDecoderAction(FLUSH_CMD_FLUSH /* audio */,
                                            FLUSH_CMD_FLUSH /* video */));
@@ -1961,7 +1954,6 @@
     }
     mPreviousSeekTimeUs = seekTimeUs;
     mSource->seekTo(seekTimeUs);
-    mPendingBufferingFlag = PENDING_BUFFERING_FLAG_NONE;
     ++mTimedTextGeneration;
 
     // everything's flushed, continue playback.
@@ -2207,12 +2199,7 @@
 
         case Source::kWhatBufferingStart:
         {
-            if (mPausedByClient) {
-                mPendingBufferingFlag = PENDING_BUFFERING_FLAG_START;
-            } else {
-                notifyListener(MEDIA_INFO, MEDIA_INFO_BUFFERING_START, 0);
-                mPendingBufferingFlag = PENDING_BUFFERING_FLAG_NONE;
-            }
+            notifyListener(MEDIA_INFO, MEDIA_INFO_BUFFERING_START, 0);
             break;
         }
 
@@ -2235,7 +2222,6 @@
         case Source::kWhatBufferingEnd:
         {
             notifyListener(MEDIA_INFO, MEDIA_INFO_BUFFERING_END, 0);
-            mPendingBufferingFlag = PENDING_BUFFERING_FLAG_NONE;
             break;
         }
 
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.h b/media/libmediaplayerservice/nuplayer/NuPlayer.h
index e896ac6..7431532 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayer.h
+++ b/media/libmediaplayerservice/nuplayer/NuPlayer.h
@@ -183,12 +183,6 @@
         FLUSH_CMD_SHUTDOWN,
     };
 
-    enum PendingBufferingFlag {
-        PENDING_BUFFERING_FLAG_NONE = MEDIA_INFO_UNKNOWN,
-        PENDING_BUFFERING_FLAG_START = MEDIA_INFO_BUFFERING_START,
-        PENDING_BUFFERING_FLAG_END = MEDIA_INFO_BUFFERING_END,
-    };
-
     // Status of flush responses from the decoder and renderer.
     bool mFlushComplete[2][2];
 
@@ -215,9 +209,6 @@
     // still become true, when we pause internally due to buffering.
     bool mPausedByClient;
 
-    // Pending buffering flag which is not sent to client due to being paused.
-    PendingBufferingFlag mPendingBufferingFlag;
-
     // Pause state as requested by source (internally) due to buffering
     bool mPausedForBuffering;
 
diff --git a/media/libstagefright/MPEG4Extractor.cpp b/media/libstagefright/MPEG4Extractor.cpp
index 718dbb6..f29ec11 100644
--- a/media/libstagefright/MPEG4Extractor.cpp
+++ b/media/libstagefright/MPEG4Extractor.cpp
@@ -51,6 +51,11 @@
 
 namespace android {
 
+enum {
+    // max track header chunk to return
+    kMaxTrackHeaderSize = 32,
+};
+
 class MPEG4Source : public MediaSource {
 public:
     // Caller retains ownership of both "dataSource" and "sampleTable".
@@ -476,6 +481,22 @@
                             ((int64_t)sampleTime * 1000000) / track->timescale);
                 }
             }
+
+            // MPEG2 tracks do not provide CSD, so read the stream header
+            if (!strcmp(mime, MEDIA_MIMETYPE_VIDEO_MPEG2)) {
+                off64_t offset;
+                size_t size;
+                if (track->sampleTable->getMetaDataForSample(
+                            0 /* sampleIndex */, &offset, &size, NULL /* sampleTime */) == OK) {
+                    if (size > kMaxTrackHeaderSize) {
+                        size = kMaxTrackHeaderSize;
+                    }
+                    uint8_t header[kMaxTrackHeaderSize];
+                    if (mDataSource->readAt(offset, &header, size) == (ssize_t)size) {
+                        track->meta->setData(kKeyStreamHeader, 'mdat', header, size);
+                    }
+                }
+            }
         }
     }
 
diff --git a/media/libstagefright/NuMediaExtractor.cpp b/media/libstagefright/NuMediaExtractor.cpp
index 271c69b..a669dca 100644
--- a/media/libstagefright/NuMediaExtractor.cpp
+++ b/media/libstagefright/NuMediaExtractor.cpp
@@ -232,7 +232,7 @@
 }
 
 status_t NuMediaExtractor::getTrackFormat(
-        size_t index, sp<AMessage> *format) const {
+        size_t index, sp<AMessage> *format, uint32_t flags) const {
     Mutex::Autolock autoLock(mLock);
 
     *format = NULL;
@@ -245,7 +245,7 @@
         return -ERANGE;
     }
 
-    sp<MetaData> meta = mImpl->getTrackMetaData(index);
+    sp<MetaData> meta = mImpl->getTrackMetaData(index, flags);
     // Extractors either support trackID-s or not, so either all tracks have trackIDs or none.
     // Generate trackID if missing.
     int32_t trackID;
diff --git a/services/camera/libcameraservice/device3/Camera3Device.cpp b/services/camera/libcameraservice/device3/Camera3Device.cpp
index 0e4e244..c0de95a 100644
--- a/services/camera/libcameraservice/device3/Camera3Device.cpp
+++ b/services/camera/libcameraservice/device3/Camera3Device.cpp
@@ -2967,19 +2967,28 @@
 }
 
 void Camera3Device::RequestThread::checkAndStopRepeatingRequest() {
-    Mutex::Autolock l(mRequestLock);
-    // Check all streams needed by repeating requests are still valid. Otherwise, stop
-    // repeating requests.
-    for (const auto& request : mRepeatingRequests) {
-        for (const auto& s : request->mOutputStreams) {
-            if (s->isAbandoned()) {
-                int64_t lastFrameNumber = 0;
-                clearRepeatingRequestsLocked(&lastFrameNumber);
-                mListener->notifyRepeatingRequestError(lastFrameNumber);
-                return;
+    bool surfaceAbandoned = false;
+    int64_t lastFrameNumber = 0;
+    {
+        Mutex::Autolock l(mRequestLock);
+        // Check all streams needed by repeating requests are still valid. Otherwise, stop
+        // repeating requests.
+        for (const auto& request : mRepeatingRequests) {
+            for (const auto& s : request->mOutputStreams) {
+                if (s->isAbandoned()) {
+                    surfaceAbandoned = true;
+                    clearRepeatingRequestsLocked(&lastFrameNumber);
+                    break;
+                }
+            }
+            if (surfaceAbandoned) {
+                break;
             }
         }
     }
+    if (surfaceAbandoned) {
+        mListener->notifyRepeatingRequestError(lastFrameNumber);
+    }
 }
 
 bool Camera3Device::RequestThread::threadLoop() {