Merge "Second part of speeding up video recording frame rate" into kraken
This commit is contained in:
@@ -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();
|
||||||
|
|||||||
@@ -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, ×tampUs));
|
CHECK(meta_data->findInt64(kKeyTime, ×tampUs));
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
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()) {
|
||||||
|
|||||||
@@ -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));
|
||||||
|
|||||||
Reference in New Issue
Block a user