summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author James Dong <jdong@google.com> 2010-06-07 14:41:41 -0700
committer James Dong <jdong@google.com> 2010-06-08 10:01:47 -0700
commit4f501f0f2b71b69cadbdb96c71e83a06751e7f0e (patch)
tree6bec0a78ccd9c1f2fbc6b1537324aef8ffc24121
parent526f2ff1a5f648a2ae3c872acc085b2a16a6a34c (diff)
Second part of speeding up video recording frame rate
1. Avoid copying the input recording frames to the encoder via OMX interface for TI video encoder This is a missing change for part one which help reduces the CPU load. 2. Release output buffers as early as possible. This is a little bit helpful, but not critical. TODO: We should save the underlying pointers allocated by the OMX component before we replace them and restore them before we call OMX_FreeBuffer()! Change-Id: Ib3a88978f4c3b1153808872eaa7ac4c265a811ff
-rw-r--r--include/media/stagefright/OMXCodec.h4
-rw-r--r--media/libstagefright/MPEG4Writer.cpp48
-rw-r--r--media/libstagefright/OMXCodec.cpp33
3 files changed, 52 insertions, 33 deletions
diff --git a/include/media/stagefright/OMXCodec.h b/include/media/stagefright/OMXCodec.h
index f836c55929d3..aceeab8bc4c8 100644
--- a/include/media/stagefright/OMXCodec.h
+++ b/include/media/stagefright/OMXCodec.h
@@ -98,6 +98,7 @@ private:
kDecoderLiesAboutNumberOfChannels = 256,
kInputBufferSizesAreBogus = 512,
kSupportsMultipleFramesPerInputBuffer = 1024,
+ kAvoidMemcopyInputRecordingFrames = 2048,
};
struct BufferInfo {
@@ -165,7 +166,8 @@ private:
OMX_COLOR_FORMATTYPE colorFormat);
void setVideoInputFormat(
- const char *mime, OMX_U32 width, OMX_U32 height);
+ const char *mime, OMX_U32 width, OMX_U32 height,
+ OMX_U32 frameRate, OMX_U32 bitRate);
status_t setupMPEG4EncoderParameters();
status_t setupAVCEncoderParameters();
diff --git a/media/libstagefright/MPEG4Writer.cpp b/media/libstagefright/MPEG4Writer.cpp
index e0f8f9e87bc9..6fa11e062c11 100644
--- a/media/libstagefright/MPEG4Writer.cpp
+++ b/media/libstagefright/MPEG4Writer.cpp
@@ -705,6 +705,7 @@ void MPEG4Writer::Track::threadEntry() {
int64_t lastDuration = 0; // Time spacing between the previous two samples
int32_t sampleCount = 1; // Sample count in the current stts table entry
uint32_t previousSampleSize = 0; // Size of the previous sample
+ sp<MetaData> meta_data;
MediaBuffer *buffer;
while (!mDone && mSource->read(&buffer) == OK) {
@@ -825,35 +826,46 @@ void MPEG4Writer::Track::threadEntry() {
continue;
}
- if (is_avc) StripStartcode(buffer);
+ // Make a deep copy of the MediaBuffer and Metadata and release
+ // the original as soon as we can
+ MediaBuffer *copy = new MediaBuffer(buffer->range_length());
+ memcpy(copy->data(), (uint8_t *)buffer->data() + buffer->range_offset(),
+ buffer->range_length());
+ copy->set_range(0, buffer->range_length());
+ meta_data = new MetaData(*buffer->meta_data().get());
+ buffer->release();
+ buffer = NULL;
+
+ if (is_avc) StripStartcode(copy);
SampleInfo info;
info.size = is_avc
#if USE_NALLEN_FOUR
- ? buffer->range_length() + 4
+ ? copy->range_length() + 4
#else
- ? buffer->range_length() + 2
+ ? copy->range_length() + 2
#endif
- : buffer->range_length();
+ : copy->range_length();
// Max file size or duration handling
mEstimatedTrackSizeBytes += info.size;
if (mOwner->exceedsFileSizeLimit()) {
- buffer->release();
- buffer = NULL;
mOwner->notify(MEDIA_RECORDER_EVENT_INFO, MEDIA_RECORDER_INFO_MAX_FILESIZE_REACHED, 0);
break;
}
if (mOwner->exceedsFileDurationLimit()) {
- buffer->release();
- buffer = NULL;
mOwner->notify(MEDIA_RECORDER_EVENT_INFO, MEDIA_RECORDER_INFO_MAX_DURATION_REACHED, 0);
break;
}
+ int32_t isSync = false;
+ meta_data->findInt32(kKeyIsSyncFrame, &isSync);
+
int64_t timestampUs;
- CHECK(buffer->meta_data()->findInt64(kKeyTime, &timestampUs));
+ CHECK(meta_data->findInt64(kKeyTime, &timestampUs));
+
+////////////////////////////////////////////////////////////////////////////////
if (mSampleInfos.empty()) {
mOwner->setStartTimestamp(timestampUs);
mStartTimestampUs = (timestampUs - mOwner->getStartTimestamp());
@@ -884,12 +896,10 @@ void MPEG4Writer::Track::threadEntry() {
lastDuration = info.timestamp - lastTimestamp;
lastTimestamp = info.timestamp;
-////////////////////////////////////////////////////////////////////////////////
- // Make a deep copy of the MediaBuffer less Metadata
- MediaBuffer *copy = new MediaBuffer(buffer->range_length());
- memcpy(copy->data(), (uint8_t *)buffer->data() + buffer->range_offset(),
- buffer->range_length());
- copy->set_range(0, buffer->range_length());
+ if (isSync != 0) {
+ mStssTableEntries.push_back(mSampleInfos.size());
+ }
+
mChunkSamples.push_back(copy);
if (interleaveDurationUs == 0) {
@@ -915,14 +925,6 @@ void MPEG4Writer::Track::threadEntry() {
}
}
- int32_t isSync = false;
- if (buffer->meta_data()->findInt32(kKeyIsSyncFrame, &isSync) &&
- isSync != 0) {
- mStssTableEntries.push_back(mSampleInfos.size());
- }
-
- buffer->release();
- buffer = NULL;
}
if (mSampleInfos.empty()) {
diff --git a/media/libstagefright/OMXCodec.cpp b/media/libstagefright/OMXCodec.cpp
index 66011ca92d4d..7c3df3105777 100644
--- a/media/libstagefright/OMXCodec.cpp
+++ b/media/libstagefright/OMXCodec.cpp
@@ -347,6 +347,9 @@ uint32_t OMXCodec::getComponentQuirks(const char *componentName) {
quirks |= kRequiresAllocateBufferOnInputPorts;
quirks |= kRequiresAllocateBufferOnOutputPorts;
+ if (!strncmp(componentName, "OMX.TI.video.encoder", 20)) {
+ quirks |= kAvoidMemcopyInputRecordingFrames;
+ }
}
if (!strcmp(componentName, "OMX.TI.Video.Decoder")) {
@@ -574,7 +577,10 @@ status_t OMXCodec::configureCodec(const sp<MetaData> &meta) {
CHECK(success);
if (mIsEncoder) {
- setVideoInputFormat(mMIME, width, height);
+ int32_t frameRate = 25; // XXX
+ int32_t bitRate = 3000000; // bit rate
+ //success = success && meta->findInt32(kKeySampleRate, &frameRate);
+ setVideoInputFormat(mMIME, width, height, frameRate, bitRate);
} else {
status_t err = setVideoOutputFormat(
mMIME, width, height);
@@ -739,7 +745,8 @@ static size_t getFrameSize(
}
void OMXCodec::setVideoInputFormat(
- const char *mime, OMX_U32 width, OMX_U32 height) {
+ const char *mime, OMX_U32 width, OMX_U32 height,
+ OMX_U32 frameRate, OMX_U32 bitRate) {
CODEC_LOGV("setVideoInputFormat width=%ld, height=%ld", width, height);
OMX_VIDEO_CODINGTYPE compressionFormat = OMX_VIDEO_CodingUnused;
@@ -769,6 +776,7 @@ void OMXCodec::setVideoInputFormat(
CHECK_EQ(setVideoPortFormatType(
kPortIndexInput, OMX_VIDEO_CodingUnused,
colorFormat), OK);
+
InitOMXParams(&def);
def.nPortIndex = kPortIndexInput;
@@ -782,11 +790,10 @@ void OMXCodec::setVideoInputFormat(
video_def->nFrameWidth = width;
video_def->nFrameHeight = height;
+ video_def->xFramerate = (frameRate << 16); // Q16 format
video_def->eCompressionFormat = OMX_VIDEO_CodingUnused;
video_def->eColorFormat = colorFormat;
- video_def->xFramerate = (24 << 16); // Q16 format
-
err = mOMX->setParameter(
mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
CHECK_EQ(err, OK);
@@ -806,7 +813,8 @@ void OMXCodec::setVideoInputFormat(
video_def->nFrameWidth = width;
video_def->nFrameHeight = height;
-
+ video_def->xFramerate = (frameRate << 16); // Q16 format
+ video_def->nBitrate = bitRate; // Q16 format
video_def->eCompressionFormat = compressionFormat;
video_def->eColorFormat = OMX_COLOR_FormatUnused;
@@ -928,6 +936,7 @@ status_t OMXCodec::setupAVCEncoderParameters() {
h264type.nSliceHeaderSpacing = 0;
h264type.nBFrames = 0;
+ h264type.nPFrames = 24; // XXX
h264type.bUseHadamard = OMX_TRUE;
h264type.nRefFrames = 1;
h264type.nRefIdx10ActiveMinus1 = 0;
@@ -960,7 +969,7 @@ status_t OMXCodec::setupAVCEncoderParameters() {
CHECK_EQ(err, OK);
bitrateType.eControlRate = OMX_Video_ControlRateVariable;
- bitrateType.nTargetBitrate = 3000000;
+ bitrateType.nTargetBitrate = 3000000; // XXX
err = mOMX->setParameter(
mNode, OMX_IndexParamVideoBitrate,
@@ -2049,9 +2058,15 @@ void OMXCodec::drainInputBuffer(BufferInfo *info) {
break;
}
- memcpy((uint8_t *)info->mData + offset,
- (const uint8_t *)srcBuffer->data() + srcBuffer->range_offset(),
- srcBuffer->range_length());
+ if (mIsEncoder && (mQuirks & kAvoidMemcopyInputRecordingFrames)) {
+ CHECK(mOMXLivesLocally && offset == 0);
+ OMX_BUFFERHEADERTYPE *header = (OMX_BUFFERHEADERTYPE *) info->mBuffer;
+ header->pBuffer = (OMX_U8 *) srcBuffer->data() + srcBuffer->range_offset();
+ } else {
+ memcpy((uint8_t *)info->mData + offset,
+ (const uint8_t *)srcBuffer->data() + srcBuffer->range_offset(),
+ srcBuffer->range_length());
+ }
int64_t lastBufferTimeUs;
CHECK(srcBuffer->meta_data()->findInt64(kKeyTime, &lastBufferTimeUs));