Merge "Second part of speeding up video recording frame rate" into kraken

This commit is contained in:
James Dong
2010-06-08 10:14:26 -07:00
committed by Android (Google) Code Review
3 changed files with 52 additions and 33 deletions

View File

@@ -98,6 +98,7 @@ private:
kDecoderLiesAboutNumberOfChannels = 256, kDecoderLiesAboutNumberOfChannels = 256,
kInputBufferSizesAreBogus = 512, kInputBufferSizesAreBogus = 512,
kSupportsMultipleFramesPerInputBuffer = 1024, kSupportsMultipleFramesPerInputBuffer = 1024,
kAvoidMemcopyInputRecordingFrames = 2048,
}; };
struct BufferInfo { struct BufferInfo {
@@ -165,7 +166,8 @@ private:
OMX_COLOR_FORMATTYPE colorFormat); OMX_COLOR_FORMATTYPE colorFormat);
void setVideoInputFormat( 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 setupMPEG4EncoderParameters();
status_t setupAVCEncoderParameters(); status_t setupAVCEncoderParameters();

View File

@@ -705,6 +705,7 @@ void MPEG4Writer::Track::threadEntry() {
int64_t lastDuration = 0; // Time spacing between the previous two samples int64_t lastDuration = 0; // Time spacing between the previous two samples
int32_t sampleCount = 1; // Sample count in the current stts table entry int32_t sampleCount = 1; // Sample count in the current stts table entry
uint32_t previousSampleSize = 0; // Size of the previous sample uint32_t previousSampleSize = 0; // Size of the previous sample
sp<MetaData> meta_data;
MediaBuffer *buffer; MediaBuffer *buffer;
while (!mDone && mSource->read(&buffer) == OK) { while (!mDone && mSource->read(&buffer) == OK) {
@@ -825,35 +826,46 @@ void MPEG4Writer::Track::threadEntry() {
continue; 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; SampleInfo info;
info.size = is_avc info.size = is_avc
#if USE_NALLEN_FOUR #if USE_NALLEN_FOUR
? buffer->range_length() + 4 ? copy->range_length() + 4
#else #else
? buffer->range_length() + 2 ? copy->range_length() + 2
#endif #endif
: buffer->range_length(); : copy->range_length();
// Max file size or duration handling // Max file size or duration handling
mEstimatedTrackSizeBytes += info.size; mEstimatedTrackSizeBytes += info.size;
if (mOwner->exceedsFileSizeLimit()) { if (mOwner->exceedsFileSizeLimit()) {
buffer->release();
buffer = NULL;
mOwner->notify(MEDIA_RECORDER_EVENT_INFO, MEDIA_RECORDER_INFO_MAX_FILESIZE_REACHED, 0); mOwner->notify(MEDIA_RECORDER_EVENT_INFO, MEDIA_RECORDER_INFO_MAX_FILESIZE_REACHED, 0);
break; break;
} }
if (mOwner->exceedsFileDurationLimit()) { if (mOwner->exceedsFileDurationLimit()) {
buffer->release();
buffer = NULL;
mOwner->notify(MEDIA_RECORDER_EVENT_INFO, MEDIA_RECORDER_INFO_MAX_DURATION_REACHED, 0); mOwner->notify(MEDIA_RECORDER_EVENT_INFO, MEDIA_RECORDER_INFO_MAX_DURATION_REACHED, 0);
break; break;
} }
int32_t isSync = false;
meta_data->findInt32(kKeyIsSyncFrame, &isSync);
int64_t timestampUs; int64_t timestampUs;
CHECK(buffer->meta_data()->findInt64(kKeyTime, &timestampUs)); CHECK(meta_data->findInt64(kKeyTime, &timestampUs));
////////////////////////////////////////////////////////////////////////////////
if (mSampleInfos.empty()) { if (mSampleInfos.empty()) {
mOwner->setStartTimestamp(timestampUs); mOwner->setStartTimestamp(timestampUs);
mStartTimestampUs = (timestampUs - mOwner->getStartTimestamp()); mStartTimestampUs = (timestampUs - mOwner->getStartTimestamp());
@@ -884,12 +896,10 @@ void MPEG4Writer::Track::threadEntry() {
lastDuration = info.timestamp - lastTimestamp; lastDuration = info.timestamp - lastTimestamp;
lastTimestamp = info.timestamp; lastTimestamp = info.timestamp;
//////////////////////////////////////////////////////////////////////////////// if (isSync != 0) {
// Make a deep copy of the MediaBuffer less Metadata mStssTableEntries.push_back(mSampleInfos.size());
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());
mChunkSamples.push_back(copy); mChunkSamples.push_back(copy);
if (interleaveDurationUs == 0) { 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()) { if (mSampleInfos.empty()) {

View File

@@ -347,6 +347,9 @@ uint32_t OMXCodec::getComponentQuirks(const char *componentName) {
quirks |= kRequiresAllocateBufferOnInputPorts; quirks |= kRequiresAllocateBufferOnInputPorts;
quirks |= kRequiresAllocateBufferOnOutputPorts; quirks |= kRequiresAllocateBufferOnOutputPorts;
if (!strncmp(componentName, "OMX.TI.video.encoder", 20)) {
quirks |= kAvoidMemcopyInputRecordingFrames;
}
} }
if (!strcmp(componentName, "OMX.TI.Video.Decoder")) { if (!strcmp(componentName, "OMX.TI.Video.Decoder")) {
@@ -574,7 +577,10 @@ status_t OMXCodec::configureCodec(const sp<MetaData> &meta) {
CHECK(success); CHECK(success);
if (mIsEncoder) { 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 { } else {
status_t err = setVideoOutputFormat( status_t err = setVideoOutputFormat(
mMIME, width, height); mMIME, width, height);
@@ -739,7 +745,8 @@ static size_t getFrameSize(
} }
void OMXCodec::setVideoInputFormat( 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); CODEC_LOGV("setVideoInputFormat width=%ld, height=%ld", width, height);
OMX_VIDEO_CODINGTYPE compressionFormat = OMX_VIDEO_CodingUnused; OMX_VIDEO_CODINGTYPE compressionFormat = OMX_VIDEO_CodingUnused;
@@ -769,6 +776,7 @@ void OMXCodec::setVideoInputFormat(
CHECK_EQ(setVideoPortFormatType( CHECK_EQ(setVideoPortFormatType(
kPortIndexInput, OMX_VIDEO_CodingUnused, kPortIndexInput, OMX_VIDEO_CodingUnused,
colorFormat), OK); colorFormat), OK);
InitOMXParams(&def); InitOMXParams(&def);
def.nPortIndex = kPortIndexInput; def.nPortIndex = kPortIndexInput;
@@ -782,11 +790,10 @@ void OMXCodec::setVideoInputFormat(
video_def->nFrameWidth = width; video_def->nFrameWidth = width;
video_def->nFrameHeight = height; video_def->nFrameHeight = height;
video_def->xFramerate = (frameRate << 16); // Q16 format
video_def->eCompressionFormat = OMX_VIDEO_CodingUnused; video_def->eCompressionFormat = OMX_VIDEO_CodingUnused;
video_def->eColorFormat = colorFormat; video_def->eColorFormat = colorFormat;
video_def->xFramerate = (24 << 16); // Q16 format
err = mOMX->setParameter( err = mOMX->setParameter(
mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
CHECK_EQ(err, OK); CHECK_EQ(err, OK);
@@ -806,7 +813,8 @@ void OMXCodec::setVideoInputFormat(
video_def->nFrameWidth = width; video_def->nFrameWidth = width;
video_def->nFrameHeight = height; video_def->nFrameHeight = height;
video_def->xFramerate = (frameRate << 16); // Q16 format
video_def->nBitrate = bitRate; // Q16 format
video_def->eCompressionFormat = compressionFormat; video_def->eCompressionFormat = compressionFormat;
video_def->eColorFormat = OMX_COLOR_FormatUnused; video_def->eColorFormat = OMX_COLOR_FormatUnused;
@@ -928,6 +936,7 @@ status_t OMXCodec::setupAVCEncoderParameters() {
h264type.nSliceHeaderSpacing = 0; h264type.nSliceHeaderSpacing = 0;
h264type.nBFrames = 0; h264type.nBFrames = 0;
h264type.nPFrames = 24; // XXX
h264type.bUseHadamard = OMX_TRUE; h264type.bUseHadamard = OMX_TRUE;
h264type.nRefFrames = 1; h264type.nRefFrames = 1;
h264type.nRefIdx10ActiveMinus1 = 0; h264type.nRefIdx10ActiveMinus1 = 0;
@@ -960,7 +969,7 @@ status_t OMXCodec::setupAVCEncoderParameters() {
CHECK_EQ(err, OK); CHECK_EQ(err, OK);
bitrateType.eControlRate = OMX_Video_ControlRateVariable; bitrateType.eControlRate = OMX_Video_ControlRateVariable;
bitrateType.nTargetBitrate = 3000000; bitrateType.nTargetBitrate = 3000000; // XXX
err = mOMX->setParameter( err = mOMX->setParameter(
mNode, OMX_IndexParamVideoBitrate, mNode, OMX_IndexParamVideoBitrate,
@@ -2049,9 +2058,15 @@ void OMXCodec::drainInputBuffer(BufferInfo *info) {
break; break;
} }
memcpy((uint8_t *)info->mData + offset, if (mIsEncoder && (mQuirks & kAvoidMemcopyInputRecordingFrames)) {
(const uint8_t *)srcBuffer->data() + srcBuffer->range_offset(), CHECK(mOMXLivesLocally && offset == 0);
srcBuffer->range_length()); 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; int64_t lastBufferTimeUs;
CHECK(srcBuffer->meta_data()->findInt64(kKeyTime, &lastBufferTimeUs)); CHECK(srcBuffer->meta_data()->findInt64(kKeyTime, &lastBufferTimeUs));