Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a4357add authored by Andreas Huber's avatar Andreas Huber
Browse files

Coalesce multiple encoded AAC frames into a single input buffer on this...

Coalesce multiple encoded AAC frames into a single input buffer on this particular OMX codec to increase throughput significantly.

Change-Id: I90c7db6656a53339c5d454336548c4f00d0d9064
related-to-bug: 2548426
parent d9c16c37
Loading
Loading
Loading
Loading
+15 −4
Original line number Diff line number Diff line
@@ -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;
    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) {
+13 −10
Original line number Diff line number Diff line
@@ -97,6 +97,7 @@ private:
        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;

+108 −41
Original line number Diff line number Diff line
@@ -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,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);

@@ -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;
@@ -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, &timestampUs)) {
            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, &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");