Merge "Progress status notification" into gingerbread
diff --git a/include/media/stagefright/MPEG4Writer.h b/include/media/stagefright/MPEG4Writer.h
index 232583a..d0c2dca 100644
--- a/include/media/stagefright/MPEG4Writer.h
+++ b/include/media/stagefright/MPEG4Writer.h
@@ -97,6 +97,7 @@
     inline size_t write(const void *ptr, size_t size, size_t nmemb, FILE* stream);
     bool exceedsFileSizeLimit();
     bool exceedsFileDurationLimit();
+    void trackProgressStatus(const Track* track, int64_t timeUs, status_t err = OK);
 
     MPEG4Writer(const MPEG4Writer &);
     MPEG4Writer &operator=(const MPEG4Writer &);
diff --git a/media/libmediaplayerservice/StagefrightRecorder.cpp b/media/libmediaplayerservice/StagefrightRecorder.cpp
index 4840391..b56f997 100644
--- a/media/libmediaplayerservice/StagefrightRecorder.cpp
+++ b/media/libmediaplayerservice/StagefrightRecorder.cpp
@@ -406,16 +406,6 @@
     return OK;
 }
 
-status_t StagefrightRecorder::setParamTrackFrameStatus(int32_t nFrames) {
-    LOGV("setParamTrackFrameStatus: %d", nFrames);
-    if (nFrames <= 0) {
-        LOGE("Invalid number of frames to track: %d", nFrames);
-        return BAD_VALUE;
-    }
-    mTrackEveryNumberOfFrames = nFrames;
-    return OK;
-}
-
 status_t StagefrightRecorder::setParamTrackTimeStatus(int64_t timeDurationUs) {
     LOGV("setParamTrackTimeStatus: %lld", timeDurationUs);
     if (timeDurationUs < 20000) {  // Infeasible if shorter than 20 ms?
@@ -510,11 +500,6 @@
         if (safe_strtoi32(value.string(), &use64BitOffset)) {
             return setParam64BitFileOffset(use64BitOffset != 0);
         }
-    } else if (key == "param-track-frame-status") {
-        int32_t nFrames;
-        if (safe_strtoi32(value.string(), &nFrames)) {
-            return setParamTrackFrameStatus(nFrames);
-        }
     } else if (key == "param-track-time-status") {
         int64_t timeDurationUs;
         if (safe_strtoi64(value.string(), &timeDurationUs)) {
@@ -1011,9 +996,6 @@
     meta->setInt32(kKeyBitRate, totalBitRate);
     meta->setInt32(kKey64BitFileOffset, mUse64BitFileOffset);
     meta->setInt32(kKeyTimeScale, mMovieTimeScale);
-    if (mTrackEveryNumberOfFrames > 0) {
-        meta->setInt32(kKeyTrackFrameStatus, mTrackEveryNumberOfFrames);
-    }
     if (mTrackEveryTimeDurationUs > 0) {
         meta->setInt64(kKeyTrackTimeStatus, mTrackEveryTimeDurationUs);
     }
@@ -1092,7 +1074,6 @@
     mVideoEncoderLevel   = -1;
     mMaxFileDurationUs = 0;
     mMaxFileSizeBytes = 0;
-    mTrackEveryNumberOfFrames = 0;
     mTrackEveryTimeDurationUs = 0;
     mEncoderProfiles = MediaProfiles::getInstance();
 
@@ -1136,8 +1117,6 @@
     result.append(buffer);
     snprintf(buffer, SIZE, "     Interleave duration (us): %d\n", mInterleaveDurationUs);
     result.append(buffer);
-    snprintf(buffer, SIZE, "     Progress notification: %d frames\n", mTrackEveryNumberOfFrames);
-    result.append(buffer);
     snprintf(buffer, SIZE, "     Progress notification: %lld us\n", mTrackEveryTimeDurationUs);
     result.append(buffer);
     snprintf(buffer, SIZE, "   Audio\n");
diff --git a/media/libmediaplayerservice/StagefrightRecorder.h b/media/libmediaplayerservice/StagefrightRecorder.h
index 9ab02cd..b4c5900 100644
--- a/media/libmediaplayerservice/StagefrightRecorder.h
+++ b/media/libmediaplayerservice/StagefrightRecorder.h
@@ -90,7 +90,6 @@
     int32_t mAudioTimeScale;
     int64_t mMaxFileSizeBytes;
     int64_t mMaxFileDurationUs;
-    int32_t mTrackEveryNumberOfFrames;
     int64_t mTrackEveryTimeDurationUs;
 
     String8 mParams;
@@ -120,7 +119,6 @@
     status_t setParamVideoCameraId(int32_t cameraId);
     status_t setParamVideoTimeScale(int32_t timeScale);
     status_t setParamTrackTimeStatus(int64_t timeDurationUs);
-    status_t setParamTrackFrameStatus(int32_t nFrames);
     status_t setParamInterleaveDuration(int32_t durationUs);
     status_t setParam64BitFileOffset(bool use64BitFileOffset);
     status_t setParamMaxFileDurationUs(int64_t timeUs);
diff --git a/media/libstagefright/MPEG4Writer.cpp b/media/libstagefright/MPEG4Writer.cpp
index b7388bb..c4a25bc 100644
--- a/media/libstagefright/MPEG4Writer.cpp
+++ b/media/libstagefright/MPEG4Writer.cpp
@@ -111,7 +111,6 @@
     int64_t mStartTimestampUs;
     int64_t mPreviousTrackTimeUs;
     int64_t mTrackEveryTimeDurationUs;
-    int32_t mTrackEveryNumberOfFrames;
 
     static void *ThreadWrapper(void *me);
     void threadEntry();
@@ -121,7 +120,7 @@
     void writeOneChunk(bool isAvc);
 
     // Track authoring progress status
-    void trackProgressStatus(int32_t nFrames, int64_t timeUs);
+    void trackProgressStatus(int64_t timeUs, status_t err = OK);
     void initTrackingProgressStatus(MetaData *params);
 
     // Utilities for collecting statistical data
@@ -742,7 +741,6 @@
     mPreviousTrackTimeUs = -1;
     mTrackingProgressStatus = false;
     mTrackEveryTimeDurationUs = 0;
-    mTrackEveryNumberOfFrames = 0;
     {
         int64_t timeUs;
         if (params && params->findInt64(kKeyTrackTimeStatus, &timeUs)) {
@@ -751,14 +749,6 @@
             mTrackingProgressStatus = true;
         }
     }
-    {
-        int32_t nFrames;
-        if (params && params->findInt32(kKeyTrackFrameStatus, &nFrames)) {
-            LOGV("Receive request to track progress status for every %d frames", nFrames);
-            mTrackEveryNumberOfFrames = nFrames;
-            mTrackingProgressStatus = true;
-        }
-    }
 }
 
 status_t MPEG4Writer::Track::start(MetaData *params) {
@@ -1164,7 +1154,7 @@
             if (mPreviousTrackTimeUs <= 0) {
                 mPreviousTrackTimeUs = mStartTimestampUs;
             }
-            trackProgressStatus(mSampleInfos.size(), timestampUs);
+            trackProgressStatus(timestampUs);
         }
         if (mOwner->numTracks() == 1) {
             off_t offset = is_avc? mOwner->addLengthPrefixedSample_l(copy)
@@ -1207,7 +1197,7 @@
     if (mSampleInfos.empty()) {
         err = UNKNOWN_ERROR;
     }
-    mOwner->notify(MEDIA_RECORDER_EVENT_INFO, MEDIA_RECORDER_INFO_COMPLETION_STATUS, err);
+    mOwner->trackProgressStatus(this, -1, err);
 
     // Last chunk
     if (mOwner->numTracks() == 1) {
@@ -1237,26 +1227,61 @@
     logStatisticalData(is_audio);
 }
 
-void MPEG4Writer::Track::trackProgressStatus(int32_t nFrames, int64_t timeUs) {
-    LOGV("trackProgressStatus: %d frames and %lld us", nFrames, timeUs);
-    if (mTrackEveryNumberOfFrames > 0 &&
-        nFrames % mTrackEveryNumberOfFrames == 0) {
-        LOGV("Fire frame tracking progress status at frame %d", nFrames);
-        mOwner->notify(MEDIA_RECORDER_EVENT_INFO,
-                       MEDIA_RECORDER_INFO_PROGRESS_FRAME_STATUS,
-                       nFrames);
-    }
-
+void MPEG4Writer::Track::trackProgressStatus(int64_t timeUs, status_t err) {
+    LOGV("trackProgressStatus: %lld us", timeUs);
     if (mTrackEveryTimeDurationUs > 0 &&
         timeUs - mPreviousTrackTimeUs >= mTrackEveryTimeDurationUs) {
         LOGV("Fire time tracking progress status at %lld us", timeUs);
-        mOwner->notify(MEDIA_RECORDER_EVENT_INFO,
-                       MEDIA_RECORDER_INFO_PROGRESS_TIME_STATUS,
-                       timeUs / 1000);
+        mOwner->trackProgressStatus(this, timeUs - mPreviousTrackTimeUs, err);
         mPreviousTrackTimeUs = timeUs;
     }
 }
 
+void MPEG4Writer::trackProgressStatus(
+        const MPEG4Writer::Track* track, int64_t timeUs, status_t err) {
+    Mutex::Autolock lock(mLock);
+    int32_t nTracks = mTracks.size();
+    CHECK(nTracks >= 1);
+    CHECK(nTracks < 64);  // Arbitrary number
+
+    int32_t trackNum = 0;
+#if 0
+    // In the worst case, we can put the trackNum
+    // along with MEDIA_RECORDER_INFO_COMPLETION_STATUS
+    // to report the progress.
+    for (List<Track *>::iterator it = mTracks.begin();
+         it != mTracks.end(); ++it, ++trackNum) {
+        if (track == (*it)) {
+            break;
+        }
+    }
+#endif
+    CHECK(trackNum < nTracks);
+    trackNum <<= 16;
+
+    // Error notification
+    // Do not consider ERROR_END_OF_STREAM an error
+    if (err != OK && err != ERROR_END_OF_STREAM) {
+        notify(MEDIA_RECORDER_EVENT_ERROR,
+               trackNum | MEDIA_RECORDER_ERROR_UNKNOWN,
+               err);
+        return;
+    }
+
+    if (timeUs == -1) {
+        // Send completion notification
+        notify(MEDIA_RECORDER_EVENT_INFO,
+               trackNum | MEDIA_RECORDER_INFO_COMPLETION_STATUS,
+               err);
+        return;
+    } else {
+        // Send progress status
+        notify(MEDIA_RECORDER_EVENT_INFO,
+               trackNum | MEDIA_RECORDER_INFO_PROGRESS_TIME_STATUS,
+               timeUs / 1000);
+    }
+}
+
 void MPEG4Writer::Track::findMinAvgMaxSampleDurationMs(
         int32_t *min, int32_t *avg, int32_t *max) {
     CHECK(!mSampleInfos.empty());
diff --git a/media/libstagefright/codecs/m4v_h263/enc/M4vH263Encoder.cpp b/media/libstagefright/codecs/m4v_h263/enc/M4vH263Encoder.cpp
index e375250..5002442e 100644
--- a/media/libstagefright/codecs/m4v_h263/enc/M4vH263Encoder.cpp
+++ b/media/libstagefright/codecs/m4v_h263/enc/M4vH263Encoder.cpp
@@ -267,7 +267,6 @@
 status_t M4vH263Encoder::read(
         MediaBuffer **out, const ReadOptions *options) {
 
-    CHECK(!options);
     *out = NULL;
 
     MediaBuffer *outputBuffer;