am eb6e3edc
: Merge "Coalesce multiple encoded AAC frames into a single input buffer on this particular OMX codec to increase throughput significantly." into froyo
Merge commit 'eb6e3edc0f21c5c8a574f8086f9622c44c0ff866' into froyo-plus-aosp * commit 'eb6e3edc0f21c5c8a574f8086f9622c44c0ff866': Coalesce multiple encoded AAC frames into a single input buffer on this particular OMX codec to increase throughput significantly.
This commit is contained in:
@ -158,6 +158,7 @@ static void playSource(OMXClient *client, const sp<MediaSource> &source) {
|
|||||||
MediaSource::ReadOptions options;
|
MediaSource::ReadOptions options;
|
||||||
|
|
||||||
int64_t sumDecodeUs = 0;
|
int64_t sumDecodeUs = 0;
|
||||||
|
int64_t totalBytes = 0;
|
||||||
|
|
||||||
while (numIterationsLeft-- > 0) {
|
while (numIterationsLeft-- > 0) {
|
||||||
long numFrames = 0;
|
long numFrames = 0;
|
||||||
@ -188,6 +189,7 @@ static void playSource(OMXClient *client, const sp<MediaSource> &source) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
sumDecodeUs += delayDecodeUs;
|
sumDecodeUs += delayDecodeUs;
|
||||||
|
totalBytes += buffer->range_length();
|
||||||
|
|
||||||
buffer->release();
|
buffer->release();
|
||||||
buffer = NULL;
|
buffer = NULL;
|
||||||
@ -216,11 +218,20 @@ static void playSource(OMXClient *client, const sp<MediaSource> &source) {
|
|||||||
printf("\n");
|
printf("\n");
|
||||||
|
|
||||||
int64_t delay = getNowUs() - startTime;
|
int64_t delay = getNowUs() - startTime;
|
||||||
printf("avg. %.2f fps\n", n * 1E6 / delay);
|
if (!strncasecmp("video/", mime, 6)) {
|
||||||
printf("avg. time to decode one buffer %.2f usecs\n",
|
printf("avg. %.2f fps\n", n * 1E6 / delay);
|
||||||
(double)sumDecodeUs / n);
|
|
||||||
|
|
||||||
printf("decoded a total of %d frame(s).\n", n);
|
printf("avg. time to decode one buffer %.2f usecs\n",
|
||||||
|
(double)sumDecodeUs / n);
|
||||||
|
|
||||||
|
printf("decoded a total of %d frame(s).\n", n);
|
||||||
|
} else if (!strncasecmp("audio/", mime, 6)) {
|
||||||
|
// Frame count makes less sense for audio, as the output buffer
|
||||||
|
// sizes may be different across decoders.
|
||||||
|
printf("avg. %.2f KB/sec\n", totalBytes / 1024 * 1E6 / delay);
|
||||||
|
|
||||||
|
printf("decoded a total of %lld bytes\n", totalBytes);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void usage(const char *me) {
|
static void usage(const char *me) {
|
||||||
|
@ -87,16 +87,17 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
enum Quirks {
|
enum Quirks {
|
||||||
kNeedsFlushBeforeDisable = 1,
|
kNeedsFlushBeforeDisable = 1,
|
||||||
kWantsNALFragments = 2,
|
kWantsNALFragments = 2,
|
||||||
kRequiresLoadedToIdleAfterAllocation = 4,
|
kRequiresLoadedToIdleAfterAllocation = 4,
|
||||||
kRequiresAllocateBufferOnInputPorts = 8,
|
kRequiresAllocateBufferOnInputPorts = 8,
|
||||||
kRequiresFlushCompleteEmulation = 16,
|
kRequiresFlushCompleteEmulation = 16,
|
||||||
kRequiresAllocateBufferOnOutputPorts = 32,
|
kRequiresAllocateBufferOnOutputPorts = 32,
|
||||||
kRequiresFlushBeforeShutdown = 64,
|
kRequiresFlushBeforeShutdown = 64,
|
||||||
kDefersOutputBufferAllocation = 128,
|
kDefersOutputBufferAllocation = 128,
|
||||||
kDecoderLiesAboutNumberOfChannels = 256,
|
kDecoderLiesAboutNumberOfChannels = 256,
|
||||||
kInputBufferSizesAreBogus = 512,
|
kInputBufferSizesAreBogus = 512,
|
||||||
|
kSupportsMultipleFramesPerInputBuffer = 1024,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct BufferInfo {
|
struct BufferInfo {
|
||||||
@ -137,6 +138,8 @@ private:
|
|||||||
bool mOutputPortSettingsHaveChanged;
|
bool mOutputPortSettingsHaveChanged;
|
||||||
int64_t mSeekTimeUs;
|
int64_t mSeekTimeUs;
|
||||||
|
|
||||||
|
MediaBuffer *mLeftOverBuffer;
|
||||||
|
|
||||||
Mutex mLock;
|
Mutex mLock;
|
||||||
Condition mAsyncCompletion;
|
Condition mAsyncCompletion;
|
||||||
|
|
||||||
|
@ -103,6 +103,7 @@ static const CodecInfo kDecoderInfo[] = {
|
|||||||
{ MEDIA_MIMETYPE_AUDIO_MPEG, "OMX.TI.MP3.decode" },
|
{ MEDIA_MIMETYPE_AUDIO_MPEG, "OMX.TI.MP3.decode" },
|
||||||
{ MEDIA_MIMETYPE_AUDIO_MPEG, "MP3Decoder" },
|
{ MEDIA_MIMETYPE_AUDIO_MPEG, "MP3Decoder" },
|
||||||
// { MEDIA_MIMETYPE_AUDIO_MPEG, "OMX.PV.mp3dec" },
|
// { MEDIA_MIMETYPE_AUDIO_MPEG, "OMX.PV.mp3dec" },
|
||||||
|
// { MEDIA_MIMETYPE_AUDIO_AMR_NB, "OMX.TI.AMR.decode" },
|
||||||
{ MEDIA_MIMETYPE_AUDIO_AMR_NB, "AMRNBDecoder" },
|
{ MEDIA_MIMETYPE_AUDIO_AMR_NB, "AMRNBDecoder" },
|
||||||
// { MEDIA_MIMETYPE_AUDIO_AMR_NB, "OMX.PV.amrdec" },
|
// { MEDIA_MIMETYPE_AUDIO_AMR_NB, "OMX.PV.amrdec" },
|
||||||
{ MEDIA_MIMETYPE_AUDIO_AMR_WB, "OMX.TI.WBAMR.decode" },
|
{ MEDIA_MIMETYPE_AUDIO_AMR_WB, "OMX.TI.WBAMR.decode" },
|
||||||
@ -284,6 +285,7 @@ uint32_t OMXCodec::getComponentQuirks(const char *componentName) {
|
|||||||
if (!strcmp(componentName, "OMX.TI.AAC.decode")) {
|
if (!strcmp(componentName, "OMX.TI.AAC.decode")) {
|
||||||
quirks |= kNeedsFlushBeforeDisable;
|
quirks |= kNeedsFlushBeforeDisable;
|
||||||
quirks |= kRequiresFlushCompleteEmulation;
|
quirks |= kRequiresFlushCompleteEmulation;
|
||||||
|
quirks |= kSupportsMultipleFramesPerInputBuffer;
|
||||||
}
|
}
|
||||||
if (!strncmp(componentName, "OMX.qcom.video.encoder.", 23)) {
|
if (!strncmp(componentName, "OMX.qcom.video.encoder.", 23)) {
|
||||||
quirks |= kRequiresLoadedToIdleAfterAllocation;
|
quirks |= kRequiresLoadedToIdleAfterAllocation;
|
||||||
@ -533,7 +535,28 @@ status_t OMXCodec::configureCodec(const sp<MetaData> &meta) {
|
|||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else if (!strncasecmp(mMIME, "audio/", 6)) {
|
||||||
|
if ((mQuirks & kSupportsMultipleFramesPerInputBuffer)
|
||||||
|
&& !strcmp(mComponentName, "OMX.TI.AAC.decode")) {
|
||||||
|
OMX_PARAM_PORTDEFINITIONTYPE def;
|
||||||
|
InitOMXParams(&def);
|
||||||
|
def.nPortIndex = kPortIndexInput;
|
||||||
|
|
||||||
|
status_t err = mOMX->getParameter(
|
||||||
|
mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
|
||||||
|
CHECK_EQ(err, OK);
|
||||||
|
|
||||||
|
const size_t kMinBufferSize = 100 * 1024;
|
||||||
|
if (def.nBufferSize < kMinBufferSize) {
|
||||||
|
def.nBufferSize = kMinBufferSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
err = mOMX->setParameter(
|
||||||
|
mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
|
||||||
|
CHECK_EQ(err, OK);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!strcasecmp(mMIME, MEDIA_MIMETYPE_IMAGE_JPEG)
|
if (!strcasecmp(mMIME, MEDIA_MIMETYPE_IMAGE_JPEG)
|
||||||
&& !strcmp(mComponentName, "OMX.TI.JPEG.decode")) {
|
&& !strcmp(mComponentName, "OMX.TI.JPEG.decode")) {
|
||||||
OMX_COLOR_FORMATTYPE format =
|
OMX_COLOR_FORMATTYPE format =
|
||||||
@ -1049,7 +1072,8 @@ OMXCodec::OMXCodec(
|
|||||||
mSignalledEOS(false),
|
mSignalledEOS(false),
|
||||||
mNoMoreOutputData(false),
|
mNoMoreOutputData(false),
|
||||||
mOutputPortSettingsHaveChanged(false),
|
mOutputPortSettingsHaveChanged(false),
|
||||||
mSeekTimeUs(-1) {
|
mSeekTimeUs(-1),
|
||||||
|
mLeftOverBuffer(NULL) {
|
||||||
mPortStatus[kPortIndexInput] = ENABLED;
|
mPortStatus[kPortIndexInput] = ENABLED;
|
||||||
mPortStatus[kPortIndexOutput] = ENABLED;
|
mPortStatus[kPortIndexOutput] = ENABLED;
|
||||||
|
|
||||||
@ -1938,66 +1962,104 @@ void OMXCodec::drainInputBuffer(BufferInfo *info) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
MediaBuffer *srcBuffer;
|
|
||||||
status_t err;
|
status_t err;
|
||||||
if (mSeekTimeUs >= 0) {
|
|
||||||
MediaSource::ReadOptions options;
|
|
||||||
options.setSeekTo(mSeekTimeUs);
|
|
||||||
|
|
||||||
mSeekTimeUs = -1;
|
bool signalEOS = false;
|
||||||
mBufferFilled.signal();
|
int64_t timestampUs = 0;
|
||||||
|
|
||||||
err = mSource->read(&srcBuffer, &options);
|
size_t offset = 0;
|
||||||
} else {
|
int32_t n = 0;
|
||||||
err = mSource->read(&srcBuffer);
|
for (;;) {
|
||||||
|
MediaBuffer *srcBuffer;
|
||||||
|
if (mSeekTimeUs >= 0) {
|
||||||
|
if (mLeftOverBuffer) {
|
||||||
|
mLeftOverBuffer->release();
|
||||||
|
mLeftOverBuffer = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
MediaSource::ReadOptions options;
|
||||||
|
options.setSeekTo(mSeekTimeUs);
|
||||||
|
|
||||||
|
mSeekTimeUs = -1;
|
||||||
|
mBufferFilled.signal();
|
||||||
|
|
||||||
|
err = mSource->read(&srcBuffer, &options);
|
||||||
|
} else if (mLeftOverBuffer) {
|
||||||
|
srcBuffer = mLeftOverBuffer;
|
||||||
|
mLeftOverBuffer = NULL;
|
||||||
|
|
||||||
|
err = OK;
|
||||||
|
} else {
|
||||||
|
err = mSource->read(&srcBuffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (err != OK) {
|
||||||
|
signalEOS = true;
|
||||||
|
mFinalStatus = err;
|
||||||
|
mSignalledEOS = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t remainingBytes = info->mSize - offset;
|
||||||
|
|
||||||
|
if (srcBuffer->range_length() > remainingBytes) {
|
||||||
|
if (offset == 0) {
|
||||||
|
CODEC_LOGE(
|
||||||
|
"Codec's input buffers are too small to accomodate "
|
||||||
|
"buffer read from source (info->mSize = %d, srcLength = %d)",
|
||||||
|
info->mSize, srcBuffer->range_length());
|
||||||
|
|
||||||
|
srcBuffer->release();
|
||||||
|
srcBuffer = NULL;
|
||||||
|
|
||||||
|
setState(ERROR);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
mLeftOverBuffer = srcBuffer;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy((uint8_t *)info->mData + offset,
|
||||||
|
(const uint8_t *)srcBuffer->data() + srcBuffer->range_offset(),
|
||||||
|
srcBuffer->range_length());
|
||||||
|
|
||||||
|
if (offset == 0) {
|
||||||
|
CHECK(srcBuffer->meta_data()->findInt64(kKeyTime, ×tampUs));
|
||||||
|
CHECK(timestampUs >= 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
offset += srcBuffer->range_length();
|
||||||
|
|
||||||
|
srcBuffer->release();
|
||||||
|
srcBuffer = NULL;
|
||||||
|
|
||||||
|
++n;
|
||||||
|
|
||||||
|
if (!(mQuirks & kSupportsMultipleFramesPerInputBuffer)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (n > 1) {
|
||||||
|
LOGV("coalesced %d frames into one input buffer", n);
|
||||||
}
|
}
|
||||||
|
|
||||||
OMX_U32 flags = OMX_BUFFERFLAG_ENDOFFRAME;
|
OMX_U32 flags = OMX_BUFFERFLAG_ENDOFFRAME;
|
||||||
OMX_TICKS timestampUs = 0;
|
|
||||||
size_t srcLength = 0;
|
|
||||||
|
|
||||||
if (err != OK) {
|
if (signalEOS) {
|
||||||
CODEC_LOGV("signalling end of input stream.");
|
|
||||||
flags |= OMX_BUFFERFLAG_EOS;
|
flags |= OMX_BUFFERFLAG_EOS;
|
||||||
|
|
||||||
mFinalStatus = err;
|
|
||||||
mSignalledEOS = true;
|
|
||||||
} else {
|
} else {
|
||||||
mNoMoreOutputData = false;
|
mNoMoreOutputData = false;
|
||||||
|
|
||||||
srcLength = srcBuffer->range_length();
|
|
||||||
|
|
||||||
if (info->mSize < srcLength) {
|
|
||||||
CODEC_LOGE(
|
|
||||||
"Codec's input buffers are too small to accomodate "
|
|
||||||
"buffer read from source (info->mSize = %d, srcLength = %d)",
|
|
||||||
info->mSize, srcLength);
|
|
||||||
|
|
||||||
srcBuffer->release();
|
|
||||||
srcBuffer = NULL;
|
|
||||||
|
|
||||||
setState(ERROR);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
memcpy(info->mData,
|
|
||||||
(const uint8_t *)srcBuffer->data() + srcBuffer->range_offset(),
|
|
||||||
srcLength);
|
|
||||||
|
|
||||||
if (srcBuffer->meta_data()->findInt64(kKeyTime, ×tampUs)) {
|
|
||||||
CODEC_LOGV("Calling emptyBuffer on buffer %p (length %d), "
|
|
||||||
"timestamp %lld us (%.2f secs)",
|
|
||||||
info->mBuffer, srcLength,
|
|
||||||
timestampUs, timestampUs / 1E6);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (srcBuffer != NULL) {
|
CODEC_LOGV("Calling emptyBuffer on buffer %p (length %d), "
|
||||||
srcBuffer->release();
|
"timestamp %lld us (%.2f secs)",
|
||||||
srcBuffer = NULL;
|
info->mBuffer, offset,
|
||||||
}
|
timestampUs, timestampUs / 1E6);
|
||||||
|
|
||||||
err = mOMX->emptyBuffer(
|
err = mOMX->emptyBuffer(
|
||||||
mNode, info->mBuffer, 0, srcLength,
|
mNode, info->mBuffer, 0, offset,
|
||||||
flags, timestampUs);
|
flags, timestampUs);
|
||||||
|
|
||||||
if (err != OK) {
|
if (err != OK) {
|
||||||
@ -2352,6 +2414,11 @@ status_t OMXCodec::stop() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (mLeftOverBuffer) {
|
||||||
|
mLeftOverBuffer->release();
|
||||||
|
mLeftOverBuffer = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
mSource->stop();
|
mSource->stop();
|
||||||
|
|
||||||
CODEC_LOGV("stopped");
|
CODEC_LOGV("stopped");
|
||||||
|
Reference in New Issue
Block a user