codec.cpp revision 377b2ec9a2885f9b6405b07ba900a9e3f4349c38
1ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa/*
2ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * Copyright (C) 2012 The Android Open Source Project
3ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa *
4ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * Licensed under the Apache License, Version 2.0 (the "License");
5ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * you may not use this file except in compliance with the License.
6ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * You may obtain a copy of the License at
7ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa *
8ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa *      http://www.apache.org/licenses/LICENSE-2.0
9ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa *
10ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * Unless required by applicable law or agreed to in writing, software
11ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * distributed under the License is distributed on an "AS IS" BASIS,
12ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * See the License for the specific language governing permissions and
14ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * limitations under the License.
15ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa */
16ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa
17ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa//#define LOG_NDEBUG 0
18ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa#define LOG_TAG "codec"
19ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa#include <inttypes.h>
20ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa#include <utils/Log.h>
21ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa
226568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa#include "SimplePlayer.h"
23ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa
24ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa#include <binder/IServiceManager.h>
25ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa#include <binder/ProcessState.h>
26ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa#include <media/ICrypto.h>
27ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa#include <media/IMediaPlayerService.h>
28ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa#include <media/stagefright/foundation/ABuffer.h>
2913a60b0d41c740448ea39ca19842c7b193c61efddestradaa#include <media/stagefright/foundation/ADebug.h>
30ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa#include <media/stagefright/foundation/ALooper.h>
31ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa#include <media/stagefright/foundation/AMessage.h>
32ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa#include <media/stagefright/foundation/AString.h>
33ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa#include <media/stagefright/DataSource.h>
34ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa#include <media/stagefright/MediaCodec.h>
3513a60b0d41c740448ea39ca19842c7b193c61efddestradaa#include <media/stagefright/MediaCodecList.h>
366568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa#include <media/stagefright/MediaDefs.h>
376568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa#include <media/stagefright/NuMediaExtractor.h>
386568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa#include <gui/ISurfaceComposer.h>
396568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa#include <gui/SurfaceComposerClient.h>
406568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa#include <gui/Surface.h>
4113a60b0d41c740448ea39ca19842c7b193c61efddestradaa#include <ui/DisplayInfo.h>
426568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa
436568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaastatic void usage(const char *me) {
444b3e3931270f8e406fc806bc7fa1c2788256687ddestradaa    fprintf(stderr, "usage: %s [-a] use audio\n"
45ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa                    "\t\t[-v] use video\n"
4613a60b0d41c740448ea39ca19842c7b193c61efddestradaa                    "\t\t[-p] playback\n"
476568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa                    "\t\t[-S] allocate buffers from a surface\n",
486568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa                    me);
496568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa
506568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa    exit(1);
516568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa}
5213a60b0d41c740448ea39ca19842c7b193c61efddestradaa
5313a60b0d41c740448ea39ca19842c7b193c61efddestradaanamespace android {
546568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa
554b3e3931270f8e406fc806bc7fa1c2788256687ddestradaastruct CodecState {
566568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa    sp<MediaCodec> mCodec;
574b3e3931270f8e406fc806bc7fa1c2788256687ddestradaa    Vector<sp<ABuffer> > mInBuffers;
584b3e3931270f8e406fc806bc7fa1c2788256687ddestradaa    Vector<sp<ABuffer> > mOutBuffers;
594b3e3931270f8e406fc806bc7fa1c2788256687ddestradaa    bool mSignalledInputEOS;
60ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa    bool mSawOutputEOS;
61ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa    int64_t mNumBuffersDecoded;
62ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa    int64_t mNumBytesDecoded;
63ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa    bool mIsAudio;
64ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa};
65ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa
66ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa}  // namespace android
67ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa
68ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaastatic int decode(
69ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa        const android::sp<android::ALooper> &looper,
70ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa        const char *path,
71ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa        bool useAudio,
72ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa        bool useVideo,
736568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa        const android::sp<android::Surface> &surface) {
746568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa    using namespace android;
75ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa
76ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa    static int64_t kTimeout = 500ll;
77ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa
786568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa    sp<NuMediaExtractor> extractor = new NuMediaExtractor;
796568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa    if (extractor->setDataSource(path) != OK) {
806568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa        fprintf(stderr, "unable to instantiate extractor.\n");
816568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa        return 1;
826568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa    }
836568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa
846568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa    KeyedVector<size_t, CodecState> stateByTrack;
856568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa
866568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa    bool haveAudio = false;
876568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa    bool haveVideo = false;
886568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa    for (size_t i = 0; i < extractor->countTracks(); ++i) {
896568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa        sp<AMessage> format;
906568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa        status_t err = extractor->getTrackFormat(i, &format);
916568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa        CHECK_EQ(err, (status_t)OK);
926568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa
936568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa        AString mime;
946568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa        CHECK(format->findString("mime", &mime));
956568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa
966568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa        bool isAudio = !strncasecmp(mime.c_str(), "audio/", 6);
97ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa        bool isVideo = !strncasecmp(mime.c_str(), "video/", 6);
986568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa
99ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa        if (useAudio && !haveAudio && isAudio) {
100ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa            haveAudio = true;
101ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa        } else if (useVideo && !haveVideo && isVideo) {
102ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa            haveVideo = true;
1036568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa        } else {
104ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa            continue;
105ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa        }
106ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa
107ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa        ALOGV("selecting track %d", i);
108ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa
1096568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa        err = extractor->selectTrack(i);
1106568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa        CHECK_EQ(err, (status_t)OK);
111ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa
112ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa        CodecState *state =
113ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa            &stateByTrack.editValueAt(stateByTrack.add(i, CodecState()));
114ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa
115ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa        state->mNumBytesDecoded = 0;
116ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa        state->mNumBuffersDecoded = 0;
117ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa        state->mIsAudio = isAudio;
1186568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa
1196568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa        state->mCodec = MediaCodec::CreateByType(
1204b3e3931270f8e406fc806bc7fa1c2788256687ddestradaa                looper, mime.c_str(), false /* encoder */);
1214b3e3931270f8e406fc806bc7fa1c2788256687ddestradaa
1226568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa        CHECK(state->mCodec != NULL);
123ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa
124ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa        err = state->mCodec->configure(
125ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa                format, isVideo ? surface : NULL,
126ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa                NULL /* crypto */,
127ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa                0 /* flags */);
1286568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa
129ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa        CHECK_EQ(err, (status_t)OK);
1306568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa
131ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa        state->mSignalledInputEOS = false;
1326568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa        state->mSawOutputEOS = false;
133ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa    }
13413a60b0d41c740448ea39ca19842c7b193c61efddestradaa
1356568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa    CHECK(!stateByTrack.isEmpty());
1366568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa
1376568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa    int64_t startTimeUs = ALooper::GetNowUs();
13813a60b0d41c740448ea39ca19842c7b193c61efddestradaa
13913a60b0d41c740448ea39ca19842c7b193c61efddestradaa    for (size_t i = 0; i < stateByTrack.size(); ++i) {
14013a60b0d41c740448ea39ca19842c7b193c61efddestradaa        CodecState *state = &stateByTrack.editValueAt(i);
14113a60b0d41c740448ea39ca19842c7b193c61efddestradaa
14213a60b0d41c740448ea39ca19842c7b193c61efddestradaa        sp<MediaCodec> codec = state->mCodec;
14313a60b0d41c740448ea39ca19842c7b193c61efddestradaa
14413a60b0d41c740448ea39ca19842c7b193c61efddestradaa        CHECK_EQ((status_t)OK, codec->start());
14513a60b0d41c740448ea39ca19842c7b193c61efddestradaa
14613a60b0d41c740448ea39ca19842c7b193c61efddestradaa        CHECK_EQ((status_t)OK, codec->getInputBuffers(&state->mInBuffers));
14713a60b0d41c740448ea39ca19842c7b193c61efddestradaa        CHECK_EQ((status_t)OK, codec->getOutputBuffers(&state->mOutBuffers));
14813a60b0d41c740448ea39ca19842c7b193c61efddestradaa
14913a60b0d41c740448ea39ca19842c7b193c61efddestradaa        ALOGV("got %d input and %d output buffers",
15013a60b0d41c740448ea39ca19842c7b193c61efddestradaa              state->mInBuffers.size(), state->mOutBuffers.size());
15113a60b0d41c740448ea39ca19842c7b193c61efddestradaa    }
15213a60b0d41c740448ea39ca19842c7b193c61efddestradaa
15313a60b0d41c740448ea39ca19842c7b193c61efddestradaa    bool sawInputEOS = false;
15413a60b0d41c740448ea39ca19842c7b193c61efddestradaa
15513a60b0d41c740448ea39ca19842c7b193c61efddestradaa    for (;;) {
15613a60b0d41c740448ea39ca19842c7b193c61efddestradaa        if (!sawInputEOS) {
15713a60b0d41c740448ea39ca19842c7b193c61efddestradaa            size_t trackIndex;
15813a60b0d41c740448ea39ca19842c7b193c61efddestradaa            status_t err = extractor->getSampleTrackIndex(&trackIndex);
15913a60b0d41c740448ea39ca19842c7b193c61efddestradaa
16013a60b0d41c740448ea39ca19842c7b193c61efddestradaa            if (err != OK) {
16113a60b0d41c740448ea39ca19842c7b193c61efddestradaa                ALOGV("saw input eos");
16213a60b0d41c740448ea39ca19842c7b193c61efddestradaa                sawInputEOS = true;
16313a60b0d41c740448ea39ca19842c7b193c61efddestradaa            } else {
16413a60b0d41c740448ea39ca19842c7b193c61efddestradaa                CodecState *state = &stateByTrack.editValueFor(trackIndex);
16513a60b0d41c740448ea39ca19842c7b193c61efddestradaa
16613a60b0d41c740448ea39ca19842c7b193c61efddestradaa                size_t index;
16713a60b0d41c740448ea39ca19842c7b193c61efddestradaa                err = state->mCodec->dequeueInputBuffer(&index, kTimeout);
1686568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa
1696568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa                if (err == OK) {
1706568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa                    ALOGV("filling input buffer %d", index);
1716568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa
1726568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa                    const sp<ABuffer> &buffer = state->mInBuffers.itemAt(index);
1736568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa
1746568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa                    err = extractor->readSampleData(buffer);
1756568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa                    CHECK_EQ(err, (status_t)OK);
1766568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa
1776568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa                    int64_t timeUs;
1786568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa                    err = extractor->getSampleTime(&timeUs);
1796568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa                    CHECK_EQ(err, (status_t)OK);
1806568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa
1816568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa                    uint32_t bufferFlags = 0;
1826568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa
1836568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa                    err = state->mCodec->queueInputBuffer(
1846568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa                            index,
1856568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa                            0 /* offset */,
1866568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa                            buffer->size(),
1876568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa                            timeUs,
1886568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa                            bufferFlags);
1896568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa
1906568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa                    CHECK_EQ(err, (status_t)OK);
1916568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa
1926568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa                    extractor->advance();
193ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa                } else {
1946568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa                    CHECK_EQ(err, -EAGAIN);
1956568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa                }
196ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa            }
197ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa        } else {
19813a60b0d41c740448ea39ca19842c7b193c61efddestradaa            for (size_t i = 0; i < stateByTrack.size(); ++i) {
19913a60b0d41c740448ea39ca19842c7b193c61efddestradaa                CodecState *state = &stateByTrack.editValueAt(i);
20013a60b0d41c740448ea39ca19842c7b193c61efddestradaa
20113a60b0d41c740448ea39ca19842c7b193c61efddestradaa                if (!state->mSignalledInputEOS) {
20213a60b0d41c740448ea39ca19842c7b193c61efddestradaa                    size_t index;
20313a60b0d41c740448ea39ca19842c7b193c61efddestradaa                    status_t err =
20413a60b0d41c740448ea39ca19842c7b193c61efddestradaa                        state->mCodec->dequeueInputBuffer(&index, kTimeout);
20513a60b0d41c740448ea39ca19842c7b193c61efddestradaa
20613a60b0d41c740448ea39ca19842c7b193c61efddestradaa                    if (err == OK) {
20713a60b0d41c740448ea39ca19842c7b193c61efddestradaa                        ALOGV("signalling input EOS on track %d", i);
20813a60b0d41c740448ea39ca19842c7b193c61efddestradaa
20913a60b0d41c740448ea39ca19842c7b193c61efddestradaa                        err = state->mCodec->queueInputBuffer(
21013a60b0d41c740448ea39ca19842c7b193c61efddestradaa                                index,
21113a60b0d41c740448ea39ca19842c7b193c61efddestradaa                                0 /* offset */,
21213a60b0d41c740448ea39ca19842c7b193c61efddestradaa                                0 /* size */,
21313a60b0d41c740448ea39ca19842c7b193c61efddestradaa                                0ll /* timeUs */,
21413a60b0d41c740448ea39ca19842c7b193c61efddestradaa                                MediaCodec::BUFFER_FLAG_EOS);
21513a60b0d41c740448ea39ca19842c7b193c61efddestradaa
216ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa                        CHECK_EQ(err, (status_t)OK);
217ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa
218ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa                        state->mSignalledInputEOS = true;
219ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa                    } else {
220ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa                        CHECK_EQ(err, -EAGAIN);
221ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa                    }
222ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa                }
223ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa            }
224ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa        }
225ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa
226ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa        bool sawOutputEOSOnAllTracks = true;
227ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa        for (size_t i = 0; i < stateByTrack.size(); ++i) {
228ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa            CodecState *state = &stateByTrack.editValueAt(i);
229ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa            if (!state->mSawOutputEOS) {
2304b3e3931270f8e406fc806bc7fa1c2788256687ddestradaa                sawOutputEOSOnAllTracks = false;
231ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa                break;
232ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa            }
233ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa        }
2346568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa
2356568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa        if (sawOutputEOSOnAllTracks) {
2366568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa            break;
2376568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa        }
2386568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa
2396568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa        for (size_t i = 0; i < stateByTrack.size(); ++i) {
2406568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa            CodecState *state = &stateByTrack.editValueAt(i);
2416568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa
2426568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa            if (state->mSawOutputEOS) {
2436568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa                continue;
2446568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa            }
2456568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa
2466568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa            size_t index;
2476568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa            size_t offset;
2486568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa            size_t size;
2496568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa            int64_t presentationTimeUs;
2506568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa            uint32_t flags;
2516568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa            status_t err = state->mCodec->dequeueOutputBuffer(
2526568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa                    &index, &offset, &size, &presentationTimeUs, &flags,
253ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa                    kTimeout);
254
255            if (err == OK) {
256                ALOGV("draining output buffer %d, time = %lld us",
257                      index, presentationTimeUs);
258
259                ++state->mNumBuffersDecoded;
260                state->mNumBytesDecoded += size;
261
262                err = state->mCodec->releaseOutputBuffer(index);
263                CHECK_EQ(err, (status_t)OK);
264
265                if (flags & MediaCodec::BUFFER_FLAG_EOS) {
266                    ALOGV("reached EOS on output.");
267
268                    state->mSawOutputEOS = true;
269                }
270            } else if (err == INFO_OUTPUT_BUFFERS_CHANGED) {
271                ALOGV("INFO_OUTPUT_BUFFERS_CHANGED");
272                CHECK_EQ((status_t)OK,
273                         state->mCodec->getOutputBuffers(&state->mOutBuffers));
274
275                ALOGV("got %d output buffers", state->mOutBuffers.size());
276            } else if (err == INFO_FORMAT_CHANGED) {
277                sp<AMessage> format;
278                CHECK_EQ((status_t)OK, state->mCodec->getOutputFormat(&format));
279
280                ALOGV("INFO_FORMAT_CHANGED: %s", format->debugString().c_str());
281            } else {
282                CHECK_EQ(err, -EAGAIN);
283            }
284        }
285    }
286
287    int64_t elapsedTimeUs = ALooper::GetNowUs() - startTimeUs;
288
289    for (size_t i = 0; i < stateByTrack.size(); ++i) {
290        CodecState *state = &stateByTrack.editValueAt(i);
291
292        CHECK_EQ((status_t)OK, state->mCodec->release());
293
294        if (state->mIsAudio) {
295            printf("track %zu: %" PRId64 " bytes received. %.2f KB/sec\n",
296                   i,
297                   state->mNumBytesDecoded,
298                   state->mNumBytesDecoded * 1E6 / 1024 / elapsedTimeUs);
299        } else {
300            printf("track %zu: %" PRId64 " frames decoded, %.2f fps. %" PRId64
301                    " bytes received. %.2f KB/sec\n",
302                   i,
303                   state->mNumBuffersDecoded,
304                   state->mNumBuffersDecoded * 1E6 / elapsedTimeUs,
305                   state->mNumBytesDecoded,
306                   state->mNumBytesDecoded * 1E6 / 1024 / elapsedTimeUs);
307        }
308    }
309
310    return 0;
311}
312
313int main(int argc, char **argv) {
314    using namespace android;
315
316    const char *me = argv[0];
317
318    bool useAudio = false;
319    bool useVideo = false;
320    bool playback = false;
321    bool useSurface = false;
322
323    int res;
324    while ((res = getopt(argc, argv, "havpSD")) >= 0) {
325        switch (res) {
326            case 'a':
327            {
328                useAudio = true;
329                break;
330            }
331
332            case 'v':
333            {
334                useVideo = true;
335                break;
336            }
337
338            case 'p':
339            {
340                playback = true;
341                break;
342            }
343
344            case 'S':
345            {
346                useSurface = true;
347                break;
348            }
349
350            case '?':
351            case 'h':
352            default:
353            {
354                usage(me);
355            }
356        }
357    }
358
359    argc -= optind;
360    argv += optind;
361
362    if (argc != 1) {
363        usage(me);
364    }
365
366    if (!useAudio && !useVideo) {
367        useAudio = useVideo = true;
368    }
369
370    ProcessState::self()->startThreadPool();
371
372    DataSource::RegisterDefaultSniffers();
373
374    sp<ALooper> looper = new ALooper;
375    looper->start();
376
377    sp<SurfaceComposerClient> composerClient;
378    sp<SurfaceControl> control;
379    sp<Surface> surface;
380
381    if (playback || (useSurface && useVideo)) {
382        composerClient = new SurfaceComposerClient;
383        CHECK_EQ(composerClient->initCheck(), (status_t)OK);
384
385        sp<IBinder> display(SurfaceComposerClient::getBuiltInDisplay(
386                ISurfaceComposer::eDisplayIdMain));
387        DisplayInfo info;
388        SurfaceComposerClient::getDisplayInfo(display, &info);
389        ssize_t displayWidth = info.w;
390        ssize_t displayHeight = info.h;
391
392        ALOGV("display is %ld x %ld\n", displayWidth, displayHeight);
393
394        control = composerClient->createSurface(
395                String8("A Surface"),
396                displayWidth,
397                displayHeight,
398                PIXEL_FORMAT_RGB_565,
399                0);
400
401        CHECK(control != NULL);
402        CHECK(control->isValid());
403
404        SurfaceComposerClient::openGlobalTransaction();
405        CHECK_EQ(control->setLayer(INT_MAX), (status_t)OK);
406        CHECK_EQ(control->show(), (status_t)OK);
407        SurfaceComposerClient::closeGlobalTransaction();
408
409        surface = control->getSurface();
410        CHECK(surface != NULL);
411    }
412
413    if (playback) {
414        sp<SimplePlayer> player = new SimplePlayer;
415        looper->registerHandler(player);
416
417        player->setDataSource(argv[0]);
418        player->setSurface(surface->getIGraphicBufferProducer());
419        player->start();
420        sleep(60);
421        player->stop();
422        player->reset();
423    } else {
424        decode(looper, argv[0], useAudio, useVideo, surface);
425    }
426
427    if (playback || (useSurface && useVideo)) {
428        composerClient->dispose();
429    }
430
431    looper->stop();
432
433    return 0;
434}
435