Loading cmds/stagefright/stagefright.cpp +15 −4 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -188,6 +189,7 @@ static void playSource(OMXClient *client, const sp<MediaSource> &source) { } sumDecodeUs += delayDecodeUs; totalBytes += buffer->range_length(); buffer->release(); buffer = NULL; Loading Loading @@ -216,11 +218,20 @@ static void playSource(OMXClient *client, const sp<MediaSource> &source) { printf("\n"); int64_t delay = getNowUs() - startTime; if (!strncasecmp("video/", mime, 6)) { printf("avg. %.2f fps\n", n * 1E6 / delay); 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) { Loading include/media/stagefright/OMXCodec.h +13 −10 Original line number Diff line number Diff line Loading @@ -97,6 +97,7 @@ private: kDefersOutputBufferAllocation = 128, kDecoderLiesAboutNumberOfChannels = 256, kInputBufferSizesAreBogus = 512, kSupportsMultipleFramesPerInputBuffer = 1024, }; struct BufferInfo { Loading Loading @@ -137,6 +138,8 @@ private: bool mOutputPortSettingsHaveChanged; int64_t mSeekTimeUs; MediaBuffer *mLeftOverBuffer; Mutex mLock; Condition mAsyncCompletion; Loading media/libstagefright/OMXCodec.cpp +108 −41 Original line number Diff line number Diff line Loading @@ -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" }, Loading Loading @@ -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; Loading Loading @@ -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 = Loading Loading @@ -1049,7 +1072,8 @@ OMXCodec::OMXCodec( mSignalledEOS(false), mNoMoreOutputData(false), mOutputPortSettingsHaveChanged(false), mSeekTimeUs(-1) { mSeekTimeUs(-1), mLeftOverBuffer(NULL) { mPortStatus[kPortIndexInput] = ENABLED; mPortStatus[kPortIndexOutput] = ENABLED; Loading Loading @@ -1938,9 +1962,21 @@ void OMXCodec::drainInputBuffer(BufferInfo *info) { return; } MediaBuffer *srcBuffer; status_t err; bool signalEOS = false; int64_t timestampUs = 0; size_t offset = 0; int32_t n = 0; for (;;) { MediaBuffer *srcBuffer; if (mSeekTimeUs >= 0) { if (mLeftOverBuffer) { mLeftOverBuffer->release(); mLeftOverBuffer = NULL; } MediaSource::ReadOptions options; options.setSeekTo(mSeekTimeUs); Loading @@ -1948,30 +1984,30 @@ void OMXCodec::drainInputBuffer(BufferInfo *info) { mBufferFilled.signal(); err = mSource->read(&srcBuffer, &options); } else if (mLeftOverBuffer) { srcBuffer = mLeftOverBuffer; mLeftOverBuffer = NULL; err = OK; } else { err = mSource->read(&srcBuffer); } OMX_U32 flags = OMX_BUFFERFLAG_ENDOFFRAME; OMX_TICKS timestampUs = 0; size_t srcLength = 0; if (err != OK) { CODEC_LOGV("signalling end of input stream."); flags |= OMX_BUFFERFLAG_EOS; signalEOS = true; mFinalStatus = err; mSignalledEOS = true; } else { mNoMoreOutputData = false; break; } srcLength = srcBuffer->range_length(); size_t remainingBytes = info->mSize - offset; if (info->mSize < srcLength) { 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, srcLength); info->mSize, srcBuffer->range_length()); srcBuffer->release(); srcBuffer = NULL; Loading @@ -1979,25 +2015,51 @@ void OMXCodec::drainInputBuffer(BufferInfo *info) { 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); 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); } 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) { Loading Loading @@ -2352,6 +2414,11 @@ status_t OMXCodec::stop() { } } if (mLeftOverBuffer) { mLeftOverBuffer->release(); mLeftOverBuffer = NULL; } mSource->stop(); CODEC_LOGV("stopped"); Loading Loading
cmds/stagefright/stagefright.cpp +15 −4 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -188,6 +189,7 @@ static void playSource(OMXClient *client, const sp<MediaSource> &source) { } sumDecodeUs += delayDecodeUs; totalBytes += buffer->range_length(); buffer->release(); buffer = NULL; Loading Loading @@ -216,11 +218,20 @@ static void playSource(OMXClient *client, const sp<MediaSource> &source) { printf("\n"); int64_t delay = getNowUs() - startTime; if (!strncasecmp("video/", mime, 6)) { printf("avg. %.2f fps\n", n * 1E6 / delay); 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) { Loading
include/media/stagefright/OMXCodec.h +13 −10 Original line number Diff line number Diff line Loading @@ -97,6 +97,7 @@ private: kDefersOutputBufferAllocation = 128, kDecoderLiesAboutNumberOfChannels = 256, kInputBufferSizesAreBogus = 512, kSupportsMultipleFramesPerInputBuffer = 1024, }; struct BufferInfo { Loading Loading @@ -137,6 +138,8 @@ private: bool mOutputPortSettingsHaveChanged; int64_t mSeekTimeUs; MediaBuffer *mLeftOverBuffer; Mutex mLock; Condition mAsyncCompletion; Loading
media/libstagefright/OMXCodec.cpp +108 −41 Original line number Diff line number Diff line Loading @@ -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" }, Loading Loading @@ -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; Loading Loading @@ -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 = Loading Loading @@ -1049,7 +1072,8 @@ OMXCodec::OMXCodec( mSignalledEOS(false), mNoMoreOutputData(false), mOutputPortSettingsHaveChanged(false), mSeekTimeUs(-1) { mSeekTimeUs(-1), mLeftOverBuffer(NULL) { mPortStatus[kPortIndexInput] = ENABLED; mPortStatus[kPortIndexOutput] = ENABLED; Loading Loading @@ -1938,9 +1962,21 @@ void OMXCodec::drainInputBuffer(BufferInfo *info) { return; } MediaBuffer *srcBuffer; status_t err; bool signalEOS = false; int64_t timestampUs = 0; size_t offset = 0; int32_t n = 0; for (;;) { MediaBuffer *srcBuffer; if (mSeekTimeUs >= 0) { if (mLeftOverBuffer) { mLeftOverBuffer->release(); mLeftOverBuffer = NULL; } MediaSource::ReadOptions options; options.setSeekTo(mSeekTimeUs); Loading @@ -1948,30 +1984,30 @@ void OMXCodec::drainInputBuffer(BufferInfo *info) { mBufferFilled.signal(); err = mSource->read(&srcBuffer, &options); } else if (mLeftOverBuffer) { srcBuffer = mLeftOverBuffer; mLeftOverBuffer = NULL; err = OK; } else { err = mSource->read(&srcBuffer); } OMX_U32 flags = OMX_BUFFERFLAG_ENDOFFRAME; OMX_TICKS timestampUs = 0; size_t srcLength = 0; if (err != OK) { CODEC_LOGV("signalling end of input stream."); flags |= OMX_BUFFERFLAG_EOS; signalEOS = true; mFinalStatus = err; mSignalledEOS = true; } else { mNoMoreOutputData = false; break; } srcLength = srcBuffer->range_length(); size_t remainingBytes = info->mSize - offset; if (info->mSize < srcLength) { 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, srcLength); info->mSize, srcBuffer->range_length()); srcBuffer->release(); srcBuffer = NULL; Loading @@ -1979,25 +2015,51 @@ void OMXCodec::drainInputBuffer(BufferInfo *info) { 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); 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); } 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) { Loading Loading @@ -2352,6 +2414,11 @@ status_t OMXCodec::stop() { } } if (mLeftOverBuffer) { mLeftOverBuffer->release(); mLeftOverBuffer = NULL; } mSource->stop(); CODEC_LOGV("stopped"); Loading