summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cmds/stagefright/stagefright.cpp19
-rw-r--r--include/media/stagefright/OMXCodec.h23
-rw-r--r--media/libstagefright/OMXCodec.cpp149
3 files changed, 136 insertions, 55 deletions
diff --git a/cmds/stagefright/stagefright.cpp b/cmds/stagefright/stagefright.cpp
index 55bb581b..fec9e1a7 100644
--- a/cmds/stagefright/stagefright.cpp
+++ b/cmds/stagefright/stagefright.cpp
@@ -158,6 +158,7 @@ static void playSource(OMXClient *client, const sp<MediaSource> &source) {
MediaSource::ReadOptions options;
int64_t sumDecodeUs = 0;
+ int64_t totalBytes = 0;
while (numIterationsLeft-- > 0) {
long numFrames = 0;
@@ -188,6 +189,7 @@ static void playSource(OMXClient *client, const sp<MediaSource> &source) {
}
sumDecodeUs += delayDecodeUs;
+ totalBytes += buffer->range_length();
buffer->release();
buffer = NULL;
@@ -216,11 +218,20 @@ static void playSource(OMXClient *client, const sp<MediaSource> &source) {
printf("\n");
int64_t delay = getNowUs() - startTime;
- printf("avg. %.2f fps\n", n * 1E6 / delay);
- printf("avg. time to decode one buffer %.2f usecs\n",
- (double)sumDecodeUs / n);
+ if (!strncasecmp("video/", mime, 6)) {
+ printf("avg. %.2f fps\n", n * 1E6 / delay);
- 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) {
diff --git a/include/media/stagefright/OMXCodec.h b/include/media/stagefright/OMXCodec.h
index d58c7117..1d76a1ad 100644
--- a/include/media/stagefright/OMXCodec.h
+++ b/include/media/stagefright/OMXCodec.h
@@ -87,16 +87,17 @@ private:
};
enum Quirks {
- kNeedsFlushBeforeDisable = 1,
- kWantsNALFragments = 2,
- kRequiresLoadedToIdleAfterAllocation = 4,
- kRequiresAllocateBufferOnInputPorts = 8,
- kRequiresFlushCompleteEmulation = 16,
- kRequiresAllocateBufferOnOutputPorts = 32,
- kRequiresFlushBeforeShutdown = 64,
- kDefersOutputBufferAllocation = 128,
- kDecoderLiesAboutNumberOfChannels = 256,
- kInputBufferSizesAreBogus = 512,
+ kNeedsFlushBeforeDisable = 1,
+ kWantsNALFragments = 2,
+ kRequiresLoadedToIdleAfterAllocation = 4,
+ kRequiresAllocateBufferOnInputPorts = 8,
+ kRequiresFlushCompleteEmulation = 16,
+ kRequiresAllocateBufferOnOutputPorts = 32,
+ kRequiresFlushBeforeShutdown = 64,
+ kDefersOutputBufferAllocation = 128,
+ kDecoderLiesAboutNumberOfChannels = 256,
+ kInputBufferSizesAreBogus = 512,
+ kSupportsMultipleFramesPerInputBuffer = 1024,
};
struct BufferInfo {
@@ -137,6 +138,8 @@ private:
bool mOutputPortSettingsHaveChanged;
int64_t mSeekTimeUs;
+ MediaBuffer *mLeftOverBuffer;
+
Mutex mLock;
Condition mAsyncCompletion;
diff --git a/media/libstagefright/OMXCodec.cpp b/media/libstagefright/OMXCodec.cpp
index 20d95405..23466393 100644
--- a/media/libstagefright/OMXCodec.cpp
+++ b/media/libstagefright/OMXCodec.cpp
@@ -103,6 +103,7 @@ static const CodecInfo kDecoderInfo[] = {
{ MEDIA_MIMETYPE_AUDIO_MPEG, "OMX.TI.MP3.decode" },
{ MEDIA_MIMETYPE_AUDIO_MPEG, "MP3Decoder" },
// { 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, "OMX.PV.amrdec" },
{ 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")) {
quirks |= kNeedsFlushBeforeDisable;
quirks |= kRequiresFlushCompleteEmulation;
+ quirks |= kSupportsMultipleFramesPerInputBuffer;
}
if (!strncmp(componentName, "OMX.qcom.video.encoder.", 23)) {
quirks |= kRequiresLoadedToIdleAfterAllocation;
@@ -533,7 +535,28 @@ status_t OMXCodec::configureCodec(const sp<MetaData> &meta) {
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)
&& !strcmp(mComponentName, "OMX.TI.JPEG.decode")) {
OMX_COLOR_FORMATTYPE format =
@@ -1049,7 +1072,8 @@ OMXCodec::OMXCodec(
mSignalledEOS(false),
mNoMoreOutputData(false),
mOutputPortSettingsHaveChanged(false),
- mSeekTimeUs(-1) {
+ mSeekTimeUs(-1),
+ mLeftOverBuffer(NULL) {
mPortStatus[kPortIndexInput] = ENABLED;
mPortStatus[kPortIndexOutput] = ENABLED;
@@ -1938,66 +1962,104 @@ void OMXCodec::drainInputBuffer(BufferInfo *info) {
return;
}
- MediaBuffer *srcBuffer;
status_t err;
- if (mSeekTimeUs >= 0) {
- MediaSource::ReadOptions options;
- options.setSeekTo(mSeekTimeUs);
- mSeekTimeUs = -1;
- mBufferFilled.signal();
+ bool signalEOS = false;
+ int64_t timestampUs = 0;
- err = mSource->read(&srcBuffer, &options);
- } else {
- err = mSource->read(&srcBuffer);
- }
+ size_t offset = 0;
+ int32_t n = 0;
+ for (;;) {
+ MediaBuffer *srcBuffer;
+ if (mSeekTimeUs >= 0) {
+ if (mLeftOverBuffer) {
+ mLeftOverBuffer->release();
+ mLeftOverBuffer = NULL;
+ }
- OMX_U32 flags = OMX_BUFFERFLAG_ENDOFFRAME;
- OMX_TICKS timestampUs = 0;
- size_t srcLength = 0;
+ MediaSource::ReadOptions options;
+ options.setSeekTo(mSeekTimeUs);
- if (err != OK) {
- CODEC_LOGV("signalling end of input stream.");
- flags |= OMX_BUFFERFLAG_EOS;
+ mSeekTimeUs = -1;
+ mBufferFilled.signal();
- mFinalStatus = err;
- mSignalledEOS = true;
- } else {
- mNoMoreOutputData = false;
+ err = mSource->read(&srcBuffer, &options);
+ } else if (mLeftOverBuffer) {
+ srcBuffer = mLeftOverBuffer;
+ mLeftOverBuffer = NULL;
+
+ err = OK;
+ } else {
+ err = mSource->read(&srcBuffer);
+ }
- srcLength = srcBuffer->range_length();
+ if (err != OK) {
+ signalEOS = true;
+ mFinalStatus = err;
+ mSignalledEOS = true;
+ break;
+ }
- 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);
+ size_t remainingBytes = info->mSize - offset;
- srcBuffer->release();
- srcBuffer = NULL;
+ 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());
- setState(ERROR);
- return;
+ srcBuffer->release();
+ srcBuffer = NULL;
+
+ setState(ERROR);
+ return;
+ }
+
+ mLeftOverBuffer = srcBuffer;
+ break;
}
- memcpy(info->mData,
+
+ memcpy((uint8_t *)info->mData + offset,
(const uint8_t *)srcBuffer->data() + srcBuffer->range_offset(),
- srcLength);
+ srcBuffer->range_length());
- if (srcBuffer->meta_data()->findInt64(kKeyTime, &timestampUs)) {
- CODEC_LOGV("Calling emptyBuffer on buffer %p (length %d), "
- "timestamp %lld us (%.2f secs)",
- info->mBuffer, srcLength,
- timestampUs, timestampUs / 1E6);
+ if (offset == 0) {
+ CHECK(srcBuffer->meta_data()->findInt64(kKeyTime, &timestampUs));
+ CHECK(timestampUs >= 0);
}
- }
- if (srcBuffer != NULL) {
+ 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;
+
+ if (signalEOS) {
+ flags |= OMX_BUFFERFLAG_EOS;
+ } else {
+ mNoMoreOutputData = false;
+ }
+
+ CODEC_LOGV("Calling emptyBuffer on buffer %p (length %d), "
+ "timestamp %lld us (%.2f secs)",
+ info->mBuffer, offset,
+ timestampUs, timestampUs / 1E6);
+
err = mOMX->emptyBuffer(
- mNode, info->mBuffer, 0, srcLength,
+ mNode, info->mBuffer, 0, offset,
flags, timestampUs);
if (err != OK) {
@@ -2352,6 +2414,11 @@ status_t OMXCodec::stop() {
}
}
+ if (mLeftOverBuffer) {
+ mLeftOverBuffer->release();
+ mLeftOverBuffer = NULL;
+ }
+
mSource->stop();
CODEC_LOGV("stopped");