Don't send late frames to software encoders for encoding

o Document on what frames will be rejected and what frames will be accepted

Change-Id: I5a5d489ad3d2b50dbb40a0f6e01529312ce81c54
diff --git a/media/libstagefright/codecs/avc/enc/AVCEncoder.cpp b/media/libstagefright/codecs/avc/enc/AVCEncoder.cpp
index 6e74279..0d89e02 100644
--- a/media/libstagefright/codecs/avc/enc/AVCEncoder.cpp
+++ b/media/libstagefright/codecs/avc/enc/AVCEncoder.cpp
@@ -407,6 +407,22 @@
         CHECK(mInputBuffer->meta_data()->findInt64(kKeyTime, &timeUs));
         outputBuffer->meta_data()->setInt64(kKeyTime, timeUs);
 
+        // When the timestamp of the current sample is the same as
+        // that of the previous sample, the encoding of the sample
+        // is bypassed, and the output length is set to 0.
+        if (mNumInputFrames >= 1 && mPrevTimestampUs == timeUs) {
+            // Frame arrives too late
+            mInputBuffer->release();
+            mInputBuffer = NULL;
+            outputBuffer->set_range(0, 0);
+            *out = outputBuffer;
+            return OK;
+        }
+
+        // Don't accept out-of-order samples
+        CHECK(mPrevTimestampUs < timeUs);
+        mPrevTimestampUs = timeUs;
+
         AVCFrameIO videoInput;
         memset(&videoInput, 0, sizeof(videoInput));
         videoInput.height = ((mVideoHeight  + 15) >> 4) << 4;
diff --git a/media/libstagefright/codecs/m4v_h263/enc/M4vH263Encoder.cpp b/media/libstagefright/codecs/m4v_h263/enc/M4vH263Encoder.cpp
index 1bef0e9..5ea5859 100644
--- a/media/libstagefright/codecs/m4v_h263/enc/M4vH263Encoder.cpp
+++ b/media/libstagefright/codecs/m4v_h263/enc/M4vH263Encoder.cpp
@@ -306,8 +306,13 @@
 
     int64_t timeUs;
     CHECK(mInputBuffer->meta_data()->findInt64(kKeyTime, &timeUs));
-    if (mNextModTimeUs > timeUs) {
-        LOGV("mNextModTimeUs %lld > timeUs %lld", mNextModTimeUs, timeUs);
+
+    // When the timestamp of the current sample is the same as that
+    // of the previous sample, encoding of the current sample is
+    // bypassed, and the output length of the sample is set to 0
+    if (mNumInputFrames >= 1 &&
+        (mNextModTimeUs > timeUs || mPrevTimestampUs == timeUs)) {
+        // Frame arrives too late
         outputBuffer->set_range(0, 0);
         *out = outputBuffer;
         mInputBuffer->release();
@@ -315,6 +320,10 @@
         return OK;
     }
 
+    // Don't accept out-of-order samples
+    CHECK(mPrevTimestampUs < timeUs);
+    mPrevTimestampUs = timeUs;
+
     // Color convert to OMX_COLOR_FormatYUV420Planar if necessary
     outputBuffer->meta_data()->setInt64(kKeyTime, timeUs);
     uint8_t *inPtr = (uint8_t *) mInputBuffer->data();
diff --git a/media/libstagefright/include/AVCEncoder.h b/media/libstagefright/include/AVCEncoder.h
index 4fe2e30..83e1f97 100644
--- a/media/libstagefright/include/AVCEncoder.h
+++ b/media/libstagefright/include/AVCEncoder.h
@@ -64,6 +64,7 @@
     int32_t  mVideoBitRate;
     int32_t  mVideoColorFormat;
     int64_t  mNumInputFrames;
+    int64_t  mPrevTimestampUs;
     status_t mInitCheck;
     bool     mStarted;
     bool     mSpsPpsHeaderReceived;
diff --git a/media/libstagefright/include/M4vH263Encoder.h b/media/libstagefright/include/M4vH263Encoder.h
index dd146f4..dbe9fd0 100644
--- a/media/libstagefright/include/M4vH263Encoder.h
+++ b/media/libstagefright/include/M4vH263Encoder.h
@@ -59,6 +59,7 @@
     int32_t  mVideoColorFormat;
     int64_t  mNumInputFrames;
     int64_t  mNextModTimeUs;
+    int64_t  mPrevTimestampUs;
     status_t mInitCheck;
     bool     mStarted;