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

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

Added better codec statistics to evaluate performance.

Change-Id: I9a1e4a803502329e0342ddde07b6df6b3761afd8
parent 761415bd
Loading
Loading
Loading
Loading
+73 −31
Original line number Diff line number Diff line
@@ -35,7 +35,8 @@
static void usage(const char *me) {
    fprintf(stderr, "usage: %s [-a] use audio\n"
                    "\t\t[-v] use video\n"
                    "\t\t[-p] playback\n", me);
                    "\t\t[-p] playback\n"
                    "\t\t[-S] allocate buffers from a surface\n", me);

    exit(1);
}
@@ -49,6 +50,9 @@ struct CodecState {
    Vector<sp<ABuffer> > mInBuffers;
    Vector<sp<ABuffer> > mOutBuffers;
    bool mSawOutputEOS;
    int64_t mNumBuffersDecoded;
    int64_t mNumBytesDecoded;
    bool mIsAudio;
};

}  // namespace android
@@ -57,9 +61,12 @@ static int decode(
        const android::sp<android::ALooper> &looper,
        const char *path,
        bool useAudio,
        bool useVideo) {
        bool useVideo,
        const android::sp<android::Surface> &surface) {
    using namespace android;

    static int64_t kTimeout = 500ll;

    sp<NuMediaExtractor> extractor = new NuMediaExtractor;
    if (extractor->setDataSource(path) != OK) {
        fprintf(stderr, "unable to instantiate extractor.\n");
@@ -78,11 +85,12 @@ static int decode(
        AString mime;
        CHECK(format->findString("mime", &mime));

        if (useAudio && !haveAudio
                && !strncasecmp(mime.c_str(), "audio/", 6)) {
        bool isAudio = !strncasecmp(mime.c_str(), "audio/", 6);
        bool isVideo = !strncasecmp(mime.c_str(), "video/", 6);

        if (useAudio && !haveAudio && isAudio) {
            haveAudio = true;
        } else if (useVideo && !haveVideo
                && !strncasecmp(mime.c_str(), "video/", 6)) {
        } else if (useVideo && !haveVideo && isVideo) {
            haveVideo = true;
        } else {
            continue;
@@ -96,13 +104,17 @@ static int decode(
        CodecState *state =
            &stateByTrack.editValueAt(stateByTrack.add(i, CodecState()));

        state->mNumBytesDecoded = 0;
        state->mNumBuffersDecoded = 0;
        state->mIsAudio = isAudio;

        state->mCodec = MediaCodec::CreateByType(
                looper, mime.c_str(), false /* encoder */);

        CHECK(state->mCodec != NULL);

        err = state->mCodec->configure(
                format, NULL /* surfaceTexture */, 0 /* flags */);
                format, isVideo ? surface : NULL, 0 /* flags */);

        CHECK_EQ(err, (status_t)OK);

@@ -122,6 +134,8 @@ static int decode(

    CHECK(!stateByTrack.isEmpty());

    int64_t startTimeUs = ALooper::GetNowUs();

    for (size_t i = 0; i < stateByTrack.size(); ++i) {
        CodecState *state = &stateByTrack.editValueAt(i);

@@ -137,13 +151,7 @@ static int decode(

        while (state->mCSDIndex < state->mCSD.size()) {
            size_t index;
            status_t err = codec->dequeueInputBuffer(&index);

            if (err == -EAGAIN) {
                usleep(10000);
                continue;
            }

            status_t err = codec->dequeueInputBuffer(&index, -1ll);
            CHECK_EQ(err, (status_t)OK);

            const sp<ABuffer> &srcBuffer =
@@ -179,7 +187,7 @@ static int decode(

                    for (;;) {
                        size_t index;
                        err = state->mCodec->dequeueInputBuffer(&index);
                        err = state->mCodec->dequeueInputBuffer(&index, kTimeout);

                        if (err == -EAGAIN) {
                            continue;
@@ -204,7 +212,7 @@ static int decode(
                CodecState *state = &stateByTrack.editValueFor(trackIndex);

                size_t index;
                err = state->mCodec->dequeueInputBuffer(&index);
                err = state->mCodec->dequeueInputBuffer(&index, kTimeout);

                if (err == OK) {
                    ALOGV("filling input buffer %d", index);
@@ -261,12 +269,15 @@ static int decode(
            uint32_t flags;
            status_t err = state->mCodec->dequeueOutputBuffer(
                    &index, &offset, &size, &presentationTimeUs, &flags,
                    10000ll);
                    kTimeout);

            if (err == OK) {
                ALOGV("draining output buffer %d, time = %lld us",
                      index, presentationTimeUs);

                ++state->mNumBuffersDecoded;
                state->mNumBytesDecoded += size;

                err = state->mCodec->releaseOutputBuffer(index);
                CHECK_EQ(err, (status_t)OK);

@@ -292,10 +303,27 @@ static int decode(
        }
    }

    int64_t elapsedTimeUs = ALooper::GetNowUs() - startTimeUs;

    for (size_t i = 0; i < stateByTrack.size(); ++i) {
        CodecState *state = &stateByTrack.editValueAt(i);

        CHECK_EQ((status_t)OK, state->mCodec->release());

        if (state->mIsAudio) {
            printf("track %d: %lld bytes received. %.2f KB/sec\n",
                   i,
                   state->mNumBytesDecoded,
                   state->mNumBytesDecoded * 1E6 / 1024 / elapsedTimeUs);
        } else {
            printf("track %d: %lld frames decoded, %.2f fps. %lld bytes "
                   "received. %.2f KB/sec\n",
                   i,
                   state->mNumBuffersDecoded,
                   state->mNumBuffersDecoded * 1E6 / elapsedTimeUs,
                   state->mNumBytesDecoded,
                   state->mNumBytesDecoded * 1E6 / 1024 / elapsedTimeUs);
        }
    }

    return 0;
@@ -309,9 +337,10 @@ int main(int argc, char **argv) {
    bool useAudio = false;
    bool useVideo = false;
    bool playback = false;
    bool useSurface = false;

    int res;
    while ((res = getopt(argc, argv, "havp")) >= 0) {
    while ((res = getopt(argc, argv, "havpS")) >= 0) {
        switch (res) {
            case 'a':
            {
@@ -331,6 +360,12 @@ int main(int argc, char **argv) {
                break;
            }

            case 'S':
            {
                useSurface = true;
                break;
            }

            case '?':
            case 'h':
            default:
@@ -358,8 +393,12 @@ int main(int argc, char **argv) {
    sp<ALooper> looper = new ALooper;
    looper->start();

    if (playback) {
        sp<SurfaceComposerClient> composerClient = new SurfaceComposerClient;
    sp<SurfaceComposerClient> composerClient;
    sp<SurfaceControl> control;
    sp<Surface> surface;

    if (playback || (useSurface && useVideo)) {
        composerClient = new SurfaceComposerClient;
        CHECK_EQ(composerClient->initCheck(), (status_t)OK);

        ssize_t displayWidth = composerClient->getDisplayWidth(0);
@@ -367,8 +406,7 @@ int main(int argc, char **argv) {

        ALOGV("display is %ld x %ld\n", displayWidth, displayHeight);

        sp<SurfaceControl> control =
            composerClient->createSurface(
        control = composerClient->createSurface(
                String8("A Surface"),
                0,
                displayWidth,
@@ -384,9 +422,11 @@ int main(int argc, char **argv) {
        CHECK_EQ(control->show(), (status_t)OK);
        SurfaceComposerClient::closeGlobalTransaction();

        sp<Surface> surface = control->getSurface();
        surface = control->getSurface();
        CHECK(surface != NULL);
    }

    if (playback) {
        sp<SimplePlayer> player = new SimplePlayer;
        looper->registerHandler(player);

@@ -396,10 +436,12 @@ int main(int argc, char **argv) {
        sleep(60);
        player->stop();
        player->reset();
    } else {
        decode(looper, argv[0], useAudio, useVideo, surface);
    }

    if (playback || (useSurface && useVideo)) {
        composerClient->dispose();
    } else {
        decode(looper, argv[0], useAudio, useVideo);
    }

    looper->stop();