codec.cpp revision 1bd139a2a68690e80398b70b27ca59550fea0e65
15778822d86b0337407514b9372562b86edfa91cdAndreas Huber/*
25778822d86b0337407514b9372562b86edfa91cdAndreas Huber * Copyright (C) 2012 The Android Open Source Project
35778822d86b0337407514b9372562b86edfa91cdAndreas Huber *
45778822d86b0337407514b9372562b86edfa91cdAndreas Huber * Licensed under the Apache License, Version 2.0 (the "License");
55778822d86b0337407514b9372562b86edfa91cdAndreas Huber * you may not use this file except in compliance with the License.
65778822d86b0337407514b9372562b86edfa91cdAndreas Huber * You may obtain a copy of the License at
75778822d86b0337407514b9372562b86edfa91cdAndreas Huber *
85778822d86b0337407514b9372562b86edfa91cdAndreas Huber *      http://www.apache.org/licenses/LICENSE-2.0
95778822d86b0337407514b9372562b86edfa91cdAndreas Huber *
105778822d86b0337407514b9372562b86edfa91cdAndreas Huber * Unless required by applicable law or agreed to in writing, software
115778822d86b0337407514b9372562b86edfa91cdAndreas Huber * distributed under the License is distributed on an "AS IS" BASIS,
125778822d86b0337407514b9372562b86edfa91cdAndreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
135778822d86b0337407514b9372562b86edfa91cdAndreas Huber * See the License for the specific language governing permissions and
145778822d86b0337407514b9372562b86edfa91cdAndreas Huber * limitations under the License.
155778822d86b0337407514b9372562b86edfa91cdAndreas Huber */
165778822d86b0337407514b9372562b86edfa91cdAndreas Huber
175778822d86b0337407514b9372562b86edfa91cdAndreas Huber//#define LOG_NDEBUG 0
185778822d86b0337407514b9372562b86edfa91cdAndreas Huber#define LOG_TAG "codec"
195778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include <utils/Log.h>
205778822d86b0337407514b9372562b86edfa91cdAndreas Huber
215778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include "SimplePlayer.h"
225778822d86b0337407514b9372562b86edfa91cdAndreas Huber
231bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber#include <binder/IServiceManager.h>
245778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include <binder/ProcessState.h>
251bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber#include <media/ICrypto.h>
261bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber#include <media/IMediaPlayerService.h>
275778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include <media/stagefright/foundation/ABuffer.h>
285778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include <media/stagefright/foundation/ADebug.h>
295778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include <media/stagefright/foundation/ALooper.h>
305778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include <media/stagefright/foundation/AMessage.h>
315778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include <media/stagefright/DataSource.h>
325778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include <media/stagefright/MediaCodec.h>
33ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber#include <media/stagefright/MediaCodecList.h>
345778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include <media/stagefright/MediaDefs.h>
355778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include <media/stagefright/NuMediaExtractor.h>
36df712ea86e6350f7005a02ab0e1c60c28a343ed0Mathias Agopian#include <gui/SurfaceComposerClient.h>
375778822d86b0337407514b9372562b86edfa91cdAndreas Huber
385778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatic void usage(const char *me) {
395778822d86b0337407514b9372562b86edfa91cdAndreas Huber    fprintf(stderr, "usage: %s [-a] use audio\n"
405778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    "\t\t[-v] use video\n"
41bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber                    "\t\t[-p] playback\n"
42ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    "\t\t[-S] allocate buffers from a surface\n"
43ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    "\t\t[-D] decrypt input buffers\n",
44ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    me);
455778822d86b0337407514b9372562b86edfa91cdAndreas Huber
465778822d86b0337407514b9372562b86edfa91cdAndreas Huber    exit(1);
475778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
485778822d86b0337407514b9372562b86edfa91cdAndreas Huber
495778822d86b0337407514b9372562b86edfa91cdAndreas Hubernamespace android {
505778822d86b0337407514b9372562b86edfa91cdAndreas Huber
515778822d86b0337407514b9372562b86edfa91cdAndreas Huberstruct CodecState {
525778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<MediaCodec> mCodec;
535778822d86b0337407514b9372562b86edfa91cdAndreas Huber    Vector<sp<ABuffer> > mCSD;
545778822d86b0337407514b9372562b86edfa91cdAndreas Huber    size_t mCSDIndex;
555778822d86b0337407514b9372562b86edfa91cdAndreas Huber    Vector<sp<ABuffer> > mInBuffers;
565778822d86b0337407514b9372562b86edfa91cdAndreas Huber    Vector<sp<ABuffer> > mOutBuffers;
575aaeb0d64fc98f9b019a4378eb39f0ee49ee6ec4Andreas Huber    bool mSignalledInputEOS;
585778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bool mSawOutputEOS;
59bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber    int64_t mNumBuffersDecoded;
60bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber    int64_t mNumBytesDecoded;
61bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber    bool mIsAudio;
625778822d86b0337407514b9372562b86edfa91cdAndreas Huber};
635778822d86b0337407514b9372562b86edfa91cdAndreas Huber
641bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huberstatic sp<ICrypto> makeCrypto(
651bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        const uint8_t uuid[16], const void *data, size_t size) {
661bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber    sp<IServiceManager> sm = defaultServiceManager();
671bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber
681bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber    sp<IBinder> binder =
691bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        sm->getService(String16("media.player"));
701bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber
711bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber    sp<IMediaPlayerService> service =
721bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        interface_cast<IMediaPlayerService>(binder);
731bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber
741bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber    CHECK(service != NULL);
751bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber
761bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber    sp<ICrypto> crypto = service->makeCrypto();
771bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber
781bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber    if (crypto == NULL || crypto->initCheck() != OK) {
791bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        return NULL;
801bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber    }
811bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber
821bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber    status_t err = crypto->createPlugin(uuid, data, size);
831bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber
841bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber    if (err != OK) {
851bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        return NULL;
861bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber    }
871bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber
881bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber    return crypto;
891bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber}
901bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber
915778822d86b0337407514b9372562b86edfa91cdAndreas Huber}  // namespace android
925778822d86b0337407514b9372562b86edfa91cdAndreas Huber
935778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatic int decode(
945778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const android::sp<android::ALooper> &looper,
955778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const char *path,
965778822d86b0337407514b9372562b86edfa91cdAndreas Huber        bool useAudio,
97bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber        bool useVideo,
98ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        const android::sp<android::Surface> &surface,
99ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        bool decryptInputBuffers) {
1005778822d86b0337407514b9372562b86edfa91cdAndreas Huber    using namespace android;
1015778822d86b0337407514b9372562b86edfa91cdAndreas Huber
102bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber    static int64_t kTimeout = 500ll;
103bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber
1045778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<NuMediaExtractor> extractor = new NuMediaExtractor;
1055778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (extractor->setDataSource(path) != OK) {
1065778822d86b0337407514b9372562b86edfa91cdAndreas Huber        fprintf(stderr, "unable to instantiate extractor.\n");
1075778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return 1;
1085778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1095778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1101bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber    sp<ICrypto> crypto;
1111bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber
1125778822d86b0337407514b9372562b86edfa91cdAndreas Huber    KeyedVector<size_t, CodecState> stateByTrack;
1135778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1145778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bool haveAudio = false;
1155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bool haveVideo = false;
1165778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (size_t i = 0; i < extractor->countTracks(); ++i) {
1175778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sp<AMessage> format;
1185778822d86b0337407514b9372562b86edfa91cdAndreas Huber        status_t err = extractor->getTrackFormat(i, &format);
1195778822d86b0337407514b9372562b86edfa91cdAndreas Huber        CHECK_EQ(err, (status_t)OK);
1205778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1215778822d86b0337407514b9372562b86edfa91cdAndreas Huber        AString mime;
1225778822d86b0337407514b9372562b86edfa91cdAndreas Huber        CHECK(format->findString("mime", &mime));
1235778822d86b0337407514b9372562b86edfa91cdAndreas Huber
124bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber        bool isAudio = !strncasecmp(mime.c_str(), "audio/", 6);
125bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber        bool isVideo = !strncasecmp(mime.c_str(), "video/", 6);
126bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber
127bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber        if (useAudio && !haveAudio && isAudio) {
1285778822d86b0337407514b9372562b86edfa91cdAndreas Huber            haveAudio = true;
129bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber        } else if (useVideo && !haveVideo && isVideo) {
1305778822d86b0337407514b9372562b86edfa91cdAndreas Huber            haveVideo = true;
1315778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
1325778822d86b0337407514b9372562b86edfa91cdAndreas Huber            continue;
1335778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
1345778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1355778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGV("selecting track %d", i);
1365778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1375778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = extractor->selectTrack(i);
1385778822d86b0337407514b9372562b86edfa91cdAndreas Huber        CHECK_EQ(err, (status_t)OK);
1395778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1405778822d86b0337407514b9372562b86edfa91cdAndreas Huber        CodecState *state =
1415778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &stateByTrack.editValueAt(stateByTrack.add(i, CodecState()));
1425778822d86b0337407514b9372562b86edfa91cdAndreas Huber
143bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber        state->mNumBytesDecoded = 0;
144bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber        state->mNumBuffersDecoded = 0;
145bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber        state->mIsAudio = isAudio;
146bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber
1471bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        if (decryptInputBuffers && crypto == NULL) {
1481bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            sp<ABuffer> emm;
1491bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            CHECK(format->findBuffer("emm", &emm));
1501bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber
1511bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            sp<ABuffer> ecm;
1521bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            CHECK(format->findBuffer("ecm", &ecm));
1531bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber
1541bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            struct WVOpaqueInitData {
1551bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                uint8_t mEMM[16];
1561bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                uint8_t mECM[32];
1571bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber
1581bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            } opaque;
1591bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber
1601bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            CHECK_EQ(emm->size(), sizeof(opaque.mEMM));
1611bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            memcpy(opaque.mEMM, emm->data(), emm->size());
1621bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber
1631bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            CHECK_EQ(ecm->size(), 80u);
1641bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            // bytes 16..47 of the original ecm stream data.
1651bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            memcpy(opaque.mECM, ecm->data() + 16, 32);
1661bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber
1671bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            static const uint8_t kUUIDWidevine[16] = {
1681bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1691bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
1701bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            };
1711bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber
1721bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            crypto = makeCrypto(kUUIDWidevine, &opaque, sizeof(opaque));
1731bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            CHECK(crypto != NULL);
1741bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            CHECK_EQ(crypto->initCheck(), (status_t)OK);
1751bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        }
1761bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber
1771bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        if (decryptInputBuffers
1781bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                && crypto->requiresSecureDecoderComponent(mime.c_str())) {
179ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            static const MediaCodecList *list = MediaCodecList::getInstance();
180ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
181ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            ssize_t index =
182ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                list->findCodecByType(mime.c_str(), false /* encoder */);
183ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
184ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            CHECK_GE(index, 0);
185ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
186ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            const char *componentName = list->getCodecName(index);
187ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
188ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            AString fullName = componentName;
189ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            fullName.append(".secure");
190ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
191ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            state->mCodec = MediaCodec::CreateByComponentName(
192ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    looper, fullName.c_str());
193ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        } else {
194ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            state->mCodec = MediaCodec::CreateByType(
195ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    looper, mime.c_str(), false /* encoder */);
196ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        }
1975778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1985778822d86b0337407514b9372562b86edfa91cdAndreas Huber        CHECK(state->mCodec != NULL);
1995778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2005778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = state->mCodec->configure(
201ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                format, isVideo ? surface : NULL,
2021bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                crypto,
2031bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                0 /* flags */);
2045778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2055778822d86b0337407514b9372562b86edfa91cdAndreas Huber        CHECK_EQ(err, (status_t)OK);
2065778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2075778822d86b0337407514b9372562b86edfa91cdAndreas Huber        size_t j = 0;
208bf6c85a013fb14960bac147c1ffd0a02a8d5f148Andreas Huber        sp<ABuffer> buffer;
209bf6c85a013fb14960bac147c1ffd0a02a8d5f148Andreas Huber        while (format->findBuffer(StringPrintf("csd-%d", j).c_str(), &buffer)) {
2105778822d86b0337407514b9372562b86edfa91cdAndreas Huber            state->mCSD.push_back(buffer);
2115778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2125778822d86b0337407514b9372562b86edfa91cdAndreas Huber            ++j;
2135778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
2145778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2155778822d86b0337407514b9372562b86edfa91cdAndreas Huber        state->mCSDIndex = 0;
2165aaeb0d64fc98f9b019a4378eb39f0ee49ee6ec4Andreas Huber        state->mSignalledInputEOS = false;
2175778822d86b0337407514b9372562b86edfa91cdAndreas Huber        state->mSawOutputEOS = false;
2185778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2195778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGV("got %d pieces of codec specific data.", state->mCSD.size());
2205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
2215778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(!stateByTrack.isEmpty());
2235778822d86b0337407514b9372562b86edfa91cdAndreas Huber
224bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber    int64_t startTimeUs = ALooper::GetNowUs();
225bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber
2265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (size_t i = 0; i < stateByTrack.size(); ++i) {
2275778822d86b0337407514b9372562b86edfa91cdAndreas Huber        CodecState *state = &stateByTrack.editValueAt(i);
2285778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2295778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sp<MediaCodec> codec = state->mCodec;
2305778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2315778822d86b0337407514b9372562b86edfa91cdAndreas Huber        CHECK_EQ((status_t)OK, codec->start());
2325778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2335778822d86b0337407514b9372562b86edfa91cdAndreas Huber        CHECK_EQ((status_t)OK, codec->getInputBuffers(&state->mInBuffers));
2345778822d86b0337407514b9372562b86edfa91cdAndreas Huber        CHECK_EQ((status_t)OK, codec->getOutputBuffers(&state->mOutBuffers));
2355778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2365778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGV("got %d input and %d output buffers",
2375778822d86b0337407514b9372562b86edfa91cdAndreas Huber              state->mInBuffers.size(), state->mOutBuffers.size());
2385778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2395778822d86b0337407514b9372562b86edfa91cdAndreas Huber        while (state->mCSDIndex < state->mCSD.size()) {
2405778822d86b0337407514b9372562b86edfa91cdAndreas Huber            size_t index;
241bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber            status_t err = codec->dequeueInputBuffer(&index, -1ll);
2425778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK_EQ(err, (status_t)OK);
2435778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2445778822d86b0337407514b9372562b86edfa91cdAndreas Huber            const sp<ABuffer> &srcBuffer =
2455778822d86b0337407514b9372562b86edfa91cdAndreas Huber                state->mCSD.itemAt(state->mCSDIndex++);
2465778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2475778822d86b0337407514b9372562b86edfa91cdAndreas Huber            const sp<ABuffer> &buffer = state->mInBuffers.itemAt(index);
2485778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2495778822d86b0337407514b9372562b86edfa91cdAndreas Huber            memcpy(buffer->data(), srcBuffer->data(), srcBuffer->size());
2505778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2515778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = codec->queueInputBuffer(
2525778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    index,
2535778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    0 /* offset */,
2545778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    srcBuffer->size(),
2555778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    0ll /* timeUs */,
2565778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    MediaCodec::BUFFER_FLAG_CODECCONFIG);
2575778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2585778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK_EQ(err, (status_t)OK);
2595778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
2605778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
2615778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2625778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bool sawInputEOS = false;
2635778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2645778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (;;) {
2655778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!sawInputEOS) {
2665778822d86b0337407514b9372562b86edfa91cdAndreas Huber            size_t trackIndex;
2675778822d86b0337407514b9372562b86edfa91cdAndreas Huber            status_t err = extractor->getSampleTrackIndex(&trackIndex);
2685778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2695778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (err != OK) {
2705aaeb0d64fc98f9b019a4378eb39f0ee49ee6ec4Andreas Huber                ALOGV("saw input eos");
2715778822d86b0337407514b9372562b86edfa91cdAndreas Huber                sawInputEOS = true;
2725778822d86b0337407514b9372562b86edfa91cdAndreas Huber            } else {
2735778822d86b0337407514b9372562b86edfa91cdAndreas Huber                CodecState *state = &stateByTrack.editValueFor(trackIndex);
2745778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2755778822d86b0337407514b9372562b86edfa91cdAndreas Huber                size_t index;
276bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber                err = state->mCodec->dequeueInputBuffer(&index, kTimeout);
2775778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2785778822d86b0337407514b9372562b86edfa91cdAndreas Huber                if (err == OK) {
2795778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    ALOGV("filling input buffer %d", index);
2805778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2815778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    const sp<ABuffer> &buffer = state->mInBuffers.itemAt(index);
2825778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2835778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    err = extractor->readSampleData(buffer);
2845778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    CHECK_EQ(err, (status_t)OK);
2855778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2865778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    int64_t timeUs;
2875778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    err = extractor->getSampleTime(&timeUs);
2885778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    CHECK_EQ(err, (status_t)OK);
2895778822d86b0337407514b9372562b86edfa91cdAndreas Huber
290ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    uint32_t bufferFlags = 0;
291ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
292ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    uint32_t sampleFlags;
293ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    err = extractor->getSampleFlags(&sampleFlags);
294ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    CHECK_EQ(err, (status_t)OK);
295ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
296ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    if (sampleFlags & NuMediaExtractor::SAMPLE_FLAG_ENCRYPTED) {
297ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                        CHECK(decryptInputBuffers);
298ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
299ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                        bufferFlags |= MediaCodec::BUFFER_FLAG_ENCRYPTED;
300ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    }
301ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
3025778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    err = state->mCodec->queueInputBuffer(
3035778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            index,
3045778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            0 /* offset */,
3055778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            buffer->size(),
3065778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            timeUs,
307ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                            bufferFlags);
3085778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3095778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    CHECK_EQ(err, (status_t)OK);
3105778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3115778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    extractor->advance();
3125778822d86b0337407514b9372562b86edfa91cdAndreas Huber                } else {
3135778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    CHECK_EQ(err, -EAGAIN);
3145778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
3155778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
3165aaeb0d64fc98f9b019a4378eb39f0ee49ee6ec4Andreas Huber        } else {
3175aaeb0d64fc98f9b019a4378eb39f0ee49ee6ec4Andreas Huber            for (size_t i = 0; i < stateByTrack.size(); ++i) {
3185aaeb0d64fc98f9b019a4378eb39f0ee49ee6ec4Andreas Huber                CodecState *state = &stateByTrack.editValueAt(i);
3195aaeb0d64fc98f9b019a4378eb39f0ee49ee6ec4Andreas Huber
3205aaeb0d64fc98f9b019a4378eb39f0ee49ee6ec4Andreas Huber                if (!state->mSignalledInputEOS) {
3215aaeb0d64fc98f9b019a4378eb39f0ee49ee6ec4Andreas Huber                    size_t index;
3225aaeb0d64fc98f9b019a4378eb39f0ee49ee6ec4Andreas Huber                    status_t err =
3235aaeb0d64fc98f9b019a4378eb39f0ee49ee6ec4Andreas Huber                        state->mCodec->dequeueInputBuffer(&index, kTimeout);
3245aaeb0d64fc98f9b019a4378eb39f0ee49ee6ec4Andreas Huber
3255aaeb0d64fc98f9b019a4378eb39f0ee49ee6ec4Andreas Huber                    if (err == OK) {
3265aaeb0d64fc98f9b019a4378eb39f0ee49ee6ec4Andreas Huber                        ALOGV("signalling input EOS on track %d", i);
3275aaeb0d64fc98f9b019a4378eb39f0ee49ee6ec4Andreas Huber
3285aaeb0d64fc98f9b019a4378eb39f0ee49ee6ec4Andreas Huber                        err = state->mCodec->queueInputBuffer(
3295aaeb0d64fc98f9b019a4378eb39f0ee49ee6ec4Andreas Huber                                index,
3305aaeb0d64fc98f9b019a4378eb39f0ee49ee6ec4Andreas Huber                                0 /* offset */,
3315aaeb0d64fc98f9b019a4378eb39f0ee49ee6ec4Andreas Huber                                0 /* size */,
3325aaeb0d64fc98f9b019a4378eb39f0ee49ee6ec4Andreas Huber                                0ll /* timeUs */,
3335aaeb0d64fc98f9b019a4378eb39f0ee49ee6ec4Andreas Huber                                MediaCodec::BUFFER_FLAG_EOS);
3345aaeb0d64fc98f9b019a4378eb39f0ee49ee6ec4Andreas Huber
3355aaeb0d64fc98f9b019a4378eb39f0ee49ee6ec4Andreas Huber                        CHECK_EQ(err, (status_t)OK);
3365aaeb0d64fc98f9b019a4378eb39f0ee49ee6ec4Andreas Huber
3375aaeb0d64fc98f9b019a4378eb39f0ee49ee6ec4Andreas Huber                        state->mSignalledInputEOS = true;
3385aaeb0d64fc98f9b019a4378eb39f0ee49ee6ec4Andreas Huber                    } else {
3395aaeb0d64fc98f9b019a4378eb39f0ee49ee6ec4Andreas Huber                        CHECK_EQ(err, -EAGAIN);
3405aaeb0d64fc98f9b019a4378eb39f0ee49ee6ec4Andreas Huber                    }
3415aaeb0d64fc98f9b019a4378eb39f0ee49ee6ec4Andreas Huber                }
3425aaeb0d64fc98f9b019a4378eb39f0ee49ee6ec4Andreas Huber            }
3435778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
3445778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3455778822d86b0337407514b9372562b86edfa91cdAndreas Huber        bool sawOutputEOSOnAllTracks = true;
3465778822d86b0337407514b9372562b86edfa91cdAndreas Huber        for (size_t i = 0; i < stateByTrack.size(); ++i) {
3475778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CodecState *state = &stateByTrack.editValueAt(i);
3485778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (!state->mSawOutputEOS) {
3495778822d86b0337407514b9372562b86edfa91cdAndreas Huber                sawOutputEOSOnAllTracks = false;
3505778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
3515778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
3525778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
3535778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3545778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (sawOutputEOSOnAllTracks) {
3555778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
3565778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
3575778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3585778822d86b0337407514b9372562b86edfa91cdAndreas Huber        for (size_t i = 0; i < stateByTrack.size(); ++i) {
3595778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CodecState *state = &stateByTrack.editValueAt(i);
3605778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3615778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (state->mSawOutputEOS) {
3625778822d86b0337407514b9372562b86edfa91cdAndreas Huber                continue;
3635778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
3645778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3655778822d86b0337407514b9372562b86edfa91cdAndreas Huber            size_t index;
3665778822d86b0337407514b9372562b86edfa91cdAndreas Huber            size_t offset;
3675778822d86b0337407514b9372562b86edfa91cdAndreas Huber            size_t size;
3685778822d86b0337407514b9372562b86edfa91cdAndreas Huber            int64_t presentationTimeUs;
3695778822d86b0337407514b9372562b86edfa91cdAndreas Huber            uint32_t flags;
3705778822d86b0337407514b9372562b86edfa91cdAndreas Huber            status_t err = state->mCodec->dequeueOutputBuffer(
3715778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    &index, &offset, &size, &presentationTimeUs, &flags,
372bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber                    kTimeout);
3735778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3745778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (err == OK) {
3755778822d86b0337407514b9372562b86edfa91cdAndreas Huber                ALOGV("draining output buffer %d, time = %lld us",
3765778822d86b0337407514b9372562b86edfa91cdAndreas Huber                      index, presentationTimeUs);
3775778822d86b0337407514b9372562b86edfa91cdAndreas Huber
378bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber                ++state->mNumBuffersDecoded;
379bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber                state->mNumBytesDecoded += size;
380bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber
3815778822d86b0337407514b9372562b86edfa91cdAndreas Huber                err = state->mCodec->releaseOutputBuffer(index);
3825778822d86b0337407514b9372562b86edfa91cdAndreas Huber                CHECK_EQ(err, (status_t)OK);
3835778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3845778822d86b0337407514b9372562b86edfa91cdAndreas Huber                if (flags & MediaCodec::BUFFER_FLAG_EOS) {
3855778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    ALOGV("reached EOS on output.");
3865778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3875778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    state->mSawOutputEOS = true;
3885778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
3895778822d86b0337407514b9372562b86edfa91cdAndreas Huber            } else if (err == INFO_OUTPUT_BUFFERS_CHANGED) {
3905778822d86b0337407514b9372562b86edfa91cdAndreas Huber                ALOGV("INFO_OUTPUT_BUFFERS_CHANGED");
3915778822d86b0337407514b9372562b86edfa91cdAndreas Huber                CHECK_EQ((status_t)OK,
3925778822d86b0337407514b9372562b86edfa91cdAndreas Huber                         state->mCodec->getOutputBuffers(&state->mOutBuffers));
3935778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3945778822d86b0337407514b9372562b86edfa91cdAndreas Huber                ALOGV("got %d output buffers", state->mOutBuffers.size());
3955778822d86b0337407514b9372562b86edfa91cdAndreas Huber            } else if (err == INFO_FORMAT_CHANGED) {
3965778822d86b0337407514b9372562b86edfa91cdAndreas Huber                sp<AMessage> format;
3975778822d86b0337407514b9372562b86edfa91cdAndreas Huber                CHECK_EQ((status_t)OK, state->mCodec->getOutputFormat(&format));
3985778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3995778822d86b0337407514b9372562b86edfa91cdAndreas Huber                ALOGV("INFO_FORMAT_CHANGED: %s", format->debugString().c_str());
4005778822d86b0337407514b9372562b86edfa91cdAndreas Huber            } else {
4015778822d86b0337407514b9372562b86edfa91cdAndreas Huber                CHECK_EQ(err, -EAGAIN);
4025778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
4035778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
4045778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
4055778822d86b0337407514b9372562b86edfa91cdAndreas Huber
406bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber    int64_t elapsedTimeUs = ALooper::GetNowUs() - startTimeUs;
407bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber
4085778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (size_t i = 0; i < stateByTrack.size(); ++i) {
4095778822d86b0337407514b9372562b86edfa91cdAndreas Huber        CodecState *state = &stateByTrack.editValueAt(i);
4105778822d86b0337407514b9372562b86edfa91cdAndreas Huber
411c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        CHECK_EQ((status_t)OK, state->mCodec->release());
412bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber
413bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber        if (state->mIsAudio) {
414bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber            printf("track %d: %lld bytes received. %.2f KB/sec\n",
415bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber                   i,
416bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber                   state->mNumBytesDecoded,
417bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber                   state->mNumBytesDecoded * 1E6 / 1024 / elapsedTimeUs);
418bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber        } else {
419bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber            printf("track %d: %lld frames decoded, %.2f fps. %lld bytes "
420bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber                   "received. %.2f KB/sec\n",
421bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber                   i,
422bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber                   state->mNumBuffersDecoded,
423bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber                   state->mNumBuffersDecoded * 1E6 / elapsedTimeUs,
424bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber                   state->mNumBytesDecoded,
425bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber                   state->mNumBytesDecoded * 1E6 / 1024 / elapsedTimeUs);
426bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber        }
4275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
4285778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return 0;
4305778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
4315778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4325778822d86b0337407514b9372562b86edfa91cdAndreas Huberint main(int argc, char **argv) {
4335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    using namespace android;
4345778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    const char *me = argv[0];
4365778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bool useAudio = false;
4385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bool useVideo = false;
4395778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bool playback = false;
440bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber    bool useSurface = false;
441ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    bool decryptInputBuffers = false;
4425778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4435778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int res;
444ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    while ((res = getopt(argc, argv, "havpSD")) >= 0) {
4455778822d86b0337407514b9372562b86edfa91cdAndreas Huber        switch (res) {
4465778822d86b0337407514b9372562b86edfa91cdAndreas Huber            case 'a':
4475778822d86b0337407514b9372562b86edfa91cdAndreas Huber            {
4485778822d86b0337407514b9372562b86edfa91cdAndreas Huber                useAudio = true;
4495778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
4505778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
4515778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4525778822d86b0337407514b9372562b86edfa91cdAndreas Huber            case 'v':
4535778822d86b0337407514b9372562b86edfa91cdAndreas Huber            {
4545778822d86b0337407514b9372562b86edfa91cdAndreas Huber                useVideo = true;
4555778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
4565778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
4575778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4585778822d86b0337407514b9372562b86edfa91cdAndreas Huber            case 'p':
4595778822d86b0337407514b9372562b86edfa91cdAndreas Huber            {
4605778822d86b0337407514b9372562b86edfa91cdAndreas Huber                playback = true;
4615778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
4625778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
4635778822d86b0337407514b9372562b86edfa91cdAndreas Huber
464bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber            case 'S':
465bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber            {
466bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber                useSurface = true;
467bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber                break;
468bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber            }
469bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber
470ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            case 'D':
471ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            {
472ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                decryptInputBuffers = true;
473ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                break;
474ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            }
475ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
4765778822d86b0337407514b9372562b86edfa91cdAndreas Huber            case '?':
4775778822d86b0337407514b9372562b86edfa91cdAndreas Huber            case 'h':
4785778822d86b0337407514b9372562b86edfa91cdAndreas Huber            default:
4795778822d86b0337407514b9372562b86edfa91cdAndreas Huber            {
4805778822d86b0337407514b9372562b86edfa91cdAndreas Huber                usage(me);
4815778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
4825778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
4835778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
4845778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4855778822d86b0337407514b9372562b86edfa91cdAndreas Huber    argc -= optind;
4865778822d86b0337407514b9372562b86edfa91cdAndreas Huber    argv += optind;
4875778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4885778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (argc != 1) {
4895778822d86b0337407514b9372562b86edfa91cdAndreas Huber        usage(me);
4905778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
4915778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4925778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!useAudio && !useVideo) {
4935778822d86b0337407514b9372562b86edfa91cdAndreas Huber        useAudio = useVideo = true;
4945778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
4955778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ProcessState::self()->startThreadPool();
4975778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4985778822d86b0337407514b9372562b86edfa91cdAndreas Huber    DataSource::RegisterDefaultSniffers();
4995778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5005778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<ALooper> looper = new ALooper;
5015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    looper->start();
5025778822d86b0337407514b9372562b86edfa91cdAndreas Huber
503bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber    sp<SurfaceComposerClient> composerClient;
504bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber    sp<SurfaceControl> control;
505bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber    sp<Surface> surface;
506bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber
507bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber    if (playback || (useSurface && useVideo)) {
508bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber        composerClient = new SurfaceComposerClient;
5095778822d86b0337407514b9372562b86edfa91cdAndreas Huber        CHECK_EQ(composerClient->initCheck(), (status_t)OK);
5105778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5115778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ssize_t displayWidth = composerClient->getDisplayWidth(0);
5125778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ssize_t displayHeight = composerClient->getDisplayHeight(0);
5135778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5145778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGV("display is %ld x %ld\n", displayWidth, displayHeight);
5155778822d86b0337407514b9372562b86edfa91cdAndreas Huber
516bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber        control = composerClient->createSurface(
517bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber                String8("A Surface"),
518bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber                0,
519bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber                displayWidth,
520bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber                displayHeight,
521bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber                PIXEL_FORMAT_RGB_565,
522bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber                0);
5235778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5245778822d86b0337407514b9372562b86edfa91cdAndreas Huber        CHECK(control != NULL);
5255778822d86b0337407514b9372562b86edfa91cdAndreas Huber        CHECK(control->isValid());
5265778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5275778822d86b0337407514b9372562b86edfa91cdAndreas Huber        SurfaceComposerClient::openGlobalTransaction();
5285778822d86b0337407514b9372562b86edfa91cdAndreas Huber        CHECK_EQ(control->setLayer(INT_MAX), (status_t)OK);
5295778822d86b0337407514b9372562b86edfa91cdAndreas Huber        CHECK_EQ(control->show(), (status_t)OK);
5305778822d86b0337407514b9372562b86edfa91cdAndreas Huber        SurfaceComposerClient::closeGlobalTransaction();
5315778822d86b0337407514b9372562b86edfa91cdAndreas Huber
532bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber        surface = control->getSurface();
5335778822d86b0337407514b9372562b86edfa91cdAndreas Huber        CHECK(surface != NULL);
534bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber    }
5355778822d86b0337407514b9372562b86edfa91cdAndreas Huber
536bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber    if (playback) {
5375778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sp<SimplePlayer> player = new SimplePlayer;
5385778822d86b0337407514b9372562b86edfa91cdAndreas Huber        looper->registerHandler(player);
5395778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5405778822d86b0337407514b9372562b86edfa91cdAndreas Huber        player->setDataSource(argv[0]);
5415778822d86b0337407514b9372562b86edfa91cdAndreas Huber        player->setSurface(surface->getSurfaceTexture());
5425778822d86b0337407514b9372562b86edfa91cdAndreas Huber        player->start();
543e98f8c04faf27df3b1829d336299ad51dad569cfAndreas Huber        sleep(60);
5445778822d86b0337407514b9372562b86edfa91cdAndreas Huber        player->stop();
5455778822d86b0337407514b9372562b86edfa91cdAndreas Huber        player->reset();
546bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber    } else {
547ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        decode(looper, argv[0],
548ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber               useAudio, useVideo, surface, decryptInputBuffers);
549bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber    }
5505778822d86b0337407514b9372562b86edfa91cdAndreas Huber
551bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber    if (playback || (useSurface && useVideo)) {
5525778822d86b0337407514b9372562b86edfa91cdAndreas Huber        composerClient->dispose();
5535778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
5545778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5555778822d86b0337407514b9372562b86edfa91cdAndreas Huber    looper->stop();
5565778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return 0;
5585778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
559