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