Merge "Fix the h.263 assembler to properly subset a buffer's range if it already has a range applied." into gingerbread
diff --git a/include/media/stagefright/AudioSource.h b/include/media/stagefright/AudioSource.h
index f1d45d2..2597e9e 100644
--- a/include/media/stagefright/AudioSource.h
+++ b/include/media/stagefright/AudioSource.h
@@ -60,7 +60,8 @@
int64_t mStartTimeUs;
int16_t mMaxAmplitude;
int64_t mPrevSampleTimeUs;
- int64_t mNumLostFrames;
+ int64_t mTotalLostFrames;
+ int64_t mPrevLostBytes;
MediaBufferGroup *mGroup;
diff --git a/media/libmedia/IMediaRecorder.cpp b/media/libmedia/IMediaRecorder.cpp
index 4eb63e8..947ff34 100644
--- a/media/libmedia/IMediaRecorder.cpp
+++ b/media/libmedia/IMediaRecorder.cpp
@@ -23,6 +23,7 @@
#include <camera/ICamera.h>
#include <media/IMediaRecorderClient.h>
#include <media/IMediaRecorder.h>
+#include <unistd.h>
namespace android {
@@ -373,6 +374,7 @@
int64_t offset = data.readInt64();
int64_t length = data.readInt64();
reply->writeInt32(setOutputFile(fd, offset, length));
+ ::close(fd);
return NO_ERROR;
} break;
case SET_VIDEO_SIZE: {
diff --git a/media/libmediaplayerservice/StagefrightRecorder.cpp b/media/libmediaplayerservice/StagefrightRecorder.cpp
index f6f89c7..8481d493 100644
--- a/media/libmediaplayerservice/StagefrightRecorder.cpp
+++ b/media/libmediaplayerservice/StagefrightRecorder.cpp
@@ -55,11 +55,6 @@
StagefrightRecorder::~StagefrightRecorder() {
LOGV("Destructor");
stop();
-
- if (mOutputFd >= 0) {
- ::close(mOutputFd);
- mOutputFd = -1;
- }
}
status_t StagefrightRecorder::init() {
@@ -1084,6 +1079,11 @@
mFlags = 0;
}
+ if (mOutputFd >= 0) {
+ ::close(mOutputFd);
+ mOutputFd = -1;
+ }
+
return OK;
}
diff --git a/media/libstagefright/AudioSource.cpp b/media/libstagefright/AudioSource.cpp
index 99978e8..c8dfede 100644
--- a/media/libstagefright/AudioSource.cpp
+++ b/media/libstagefright/AudioSource.cpp
@@ -35,7 +35,8 @@
: mStarted(false),
mCollectStats(false),
mPrevSampleTimeUs(0),
- mNumLostFrames(0),
+ mTotalLostFrames(0),
+ mPrevLostBytes(0),
mGroup(NULL) {
LOGV("sampleRate: %d, channels: %d", sampleRate, channels);
@@ -108,7 +109,8 @@
mStarted = false;
if (mCollectStats) {
- LOGI("Total lost audio frames: %lld", mNumLostFrames);
+ LOGI("Total lost audio frames: %lld",
+ mTotalLostFrames + (mPrevLostBytes >> 1));
}
return OK;
@@ -186,10 +188,11 @@
// Insert null frames when lost frames are detected.
int64_t timestampUs = mPrevSampleTimeUs;
uint32_t numLostBytes = mRecord->getInputFramesLost() << 1;
+ numLostBytes += mPrevLostBytes;
#if 0
// Simulate lost frames
- numLostBytes = ((rand() * 1.0 / RAND_MAX)) * kMaxBufferSize;
- numLostBytes &= 0xFFFFFFFE; // Alignment request
+ numLostBytes = ((rand() * 1.0 / RAND_MAX)) * 2 * kMaxBufferSize;
+ numLostBytes &= 0xFFFFFFFE; // Alignment requirement
// Reduce the chance to lose
if (rand() * 1.0 / RAND_MAX >= 0.05) {
@@ -197,13 +200,18 @@
}
#endif
if (numLostBytes > 0) {
- // Not expect too many lost frames!
- CHECK(numLostBytes <= kMaxBufferSize);
+ if (numLostBytes > kMaxBufferSize) {
+ mPrevLostBytes = numLostBytes - kMaxBufferSize;
+ numLostBytes = kMaxBufferSize;
+ }
- timestampUs += (1000000LL * numLostBytes >> 1) / sampleRate;
+ CHECK_EQ(numLostBytes & 1, 0);
+ timestampUs += ((1000000LL * (numLostBytes >> 1)) +
+ (sampleRate >> 1)) / sampleRate;
+
CHECK(timestampUs > mPrevSampleTimeUs);
if (mCollectStats) {
- mNumLostFrames += (numLostBytes >> 1);
+ mTotalLostFrames += (numLostBytes >> 1);
}
if ((err = skipFrame(timestampUs, options)) == -1) {
buffer->release();
@@ -240,7 +248,7 @@
buffer->meta_data()->setInt64(kKeyTime, mPrevSampleTimeUs);
CHECK(timestampUs > mPrevSampleTimeUs);
- if (mNumLostFrames == 0) {
+ if (mTotalLostFrames == 0) {
CHECK_EQ(mPrevSampleTimeUs,
mStartTimeUs + (1000000LL * numFramesRecorded) / sampleRate);
}
diff --git a/media/libstagefright/MPEG4Writer.cpp b/media/libstagefright/MPEG4Writer.cpp
index c860c5c..1460f37 100644
--- a/media/libstagefright/MPEG4Writer.cpp
+++ b/media/libstagefright/MPEG4Writer.cpp
@@ -1956,11 +1956,11 @@
mOwner->writeInt16(0x18); // depth
mOwner->writeInt16(-1); // predefined
- CHECK(mCodecSpecificData);
- CHECK(mCodecSpecificDataSize > 0);
CHECK(23 + mCodecSpecificDataSize < 128);
if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_MPEG4, mime)) {
+ CHECK(mCodecSpecificData);
+ CHECK(mCodecSpecificDataSize > 0);
mOwner->beginBox("esds");
mOwner->writeInt32(0); // version=0, flags=0
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;