codec.cpp revision fab8f4679795b86c7aaaf63f6be6b019cf7ea0cd
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" 19377b2ec9a2885f9b6405b07ba900a9e3f4349c38Kévin PETIT#include <inttypes.h> 205778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include <utils/Log.h> 215778822d86b0337407514b9372562b86edfa91cdAndreas Huber 225778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include "SimplePlayer.h" 235778822d86b0337407514b9372562b86edfa91cdAndreas Huber 241bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber#include <binder/IServiceManager.h> 255778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include <binder/ProcessState.h> 261bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber#include <media/ICrypto.h> 271b86fe063badb5f28c467ade39be0f4008688947Andreas Huber#include <media/IMediaHTTPService.h> 281bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber#include <media/IMediaPlayerService.h> 295778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include <media/stagefright/foundation/ABuffer.h> 305778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include <media/stagefright/foundation/ADebug.h> 315778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include <media/stagefright/foundation/ALooper.h> 325778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include <media/stagefright/foundation/AMessage.h> 335b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber#include <media/stagefright/foundation/AString.h> 345778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include <media/stagefright/DataSource.h> 355778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include <media/stagefright/MediaCodec.h> 36ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber#include <media/stagefright/MediaCodecList.h> 375778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include <media/stagefright/MediaDefs.h> 385778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include <media/stagefright/NuMediaExtractor.h> 39a6195decfe4f9021bbbd7deb050495c33371366bJeff Brown#include <gui/ISurfaceComposer.h> 40df712ea86e6350f7005a02ab0e1c60c28a343ed0Mathias Agopian#include <gui/SurfaceComposerClient.h> 411a2952aee048ca7b1765e2bc09ebe9aeddaeafa3Mathias Agopian#include <gui/Surface.h> 423dca4c7a5622fc6aa03397d749c4b4c1201cc4f3Mathias Agopian#include <ui/DisplayInfo.h> 435778822d86b0337407514b9372562b86edfa91cdAndreas Huber 445778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatic void usage(const char *me) { 455778822d86b0337407514b9372562b86edfa91cdAndreas Huber fprintf(stderr, "usage: %s [-a] use audio\n" 465778822d86b0337407514b9372562b86edfa91cdAndreas Huber "\t\t[-v] use video\n" 47bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber "\t\t[-p] playback\n" 48fab8f4679795b86c7aaaf63f6be6b019cf7ea0cdDavid Smith "\t\t[-S] allocate buffers from a surface\n" 49fab8f4679795b86c7aaaf63f6be6b019cf7ea0cdDavid Smith "\t\t[-R] render output to surface (enables -S)\n" 50fab8f4679795b86c7aaaf63f6be6b019cf7ea0cdDavid Smith "\t\t[-T] use render timestamps (enables -R)\n", 51ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber me); 525778822d86b0337407514b9372562b86edfa91cdAndreas Huber exit(1); 535778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 545778822d86b0337407514b9372562b86edfa91cdAndreas Huber 555778822d86b0337407514b9372562b86edfa91cdAndreas Hubernamespace android { 565778822d86b0337407514b9372562b86edfa91cdAndreas Huber 575778822d86b0337407514b9372562b86edfa91cdAndreas Huberstruct CodecState { 585778822d86b0337407514b9372562b86edfa91cdAndreas Huber sp<MediaCodec> mCodec; 595778822d86b0337407514b9372562b86edfa91cdAndreas Huber Vector<sp<ABuffer> > mInBuffers; 605778822d86b0337407514b9372562b86edfa91cdAndreas Huber Vector<sp<ABuffer> > mOutBuffers; 615aaeb0d64fc98f9b019a4378eb39f0ee49ee6ec4Andreas Huber bool mSignalledInputEOS; 625778822d86b0337407514b9372562b86edfa91cdAndreas Huber bool mSawOutputEOS; 63bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber int64_t mNumBuffersDecoded; 64bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber int64_t mNumBytesDecoded; 65bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber bool mIsAudio; 665778822d86b0337407514b9372562b86edfa91cdAndreas Huber}; 675778822d86b0337407514b9372562b86edfa91cdAndreas Huber 685778822d86b0337407514b9372562b86edfa91cdAndreas Huber} // namespace android 695778822d86b0337407514b9372562b86edfa91cdAndreas Huber 705778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatic int decode( 715778822d86b0337407514b9372562b86edfa91cdAndreas Huber const android::sp<android::ALooper> &looper, 725778822d86b0337407514b9372562b86edfa91cdAndreas Huber const char *path, 735778822d86b0337407514b9372562b86edfa91cdAndreas Huber bool useAudio, 74bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber bool useVideo, 75fab8f4679795b86c7aaaf63f6be6b019cf7ea0cdDavid Smith const android::sp<android::Surface> &surface, 76fab8f4679795b86c7aaaf63f6be6b019cf7ea0cdDavid Smith bool renderSurface, 77fab8f4679795b86c7aaaf63f6be6b019cf7ea0cdDavid Smith bool useTimestamp) { 785778822d86b0337407514b9372562b86edfa91cdAndreas Huber using namespace android; 795778822d86b0337407514b9372562b86edfa91cdAndreas Huber 80bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber static int64_t kTimeout = 500ll; 81bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber 825778822d86b0337407514b9372562b86edfa91cdAndreas Huber sp<NuMediaExtractor> extractor = new NuMediaExtractor; 831b86fe063badb5f28c467ade39be0f4008688947Andreas Huber if (extractor->setDataSource(NULL /* httpService */, path) != OK) { 845778822d86b0337407514b9372562b86edfa91cdAndreas Huber fprintf(stderr, "unable to instantiate extractor.\n"); 855778822d86b0337407514b9372562b86edfa91cdAndreas Huber return 1; 865778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 875778822d86b0337407514b9372562b86edfa91cdAndreas Huber 885778822d86b0337407514b9372562b86edfa91cdAndreas Huber KeyedVector<size_t, CodecState> stateByTrack; 895778822d86b0337407514b9372562b86edfa91cdAndreas Huber 905778822d86b0337407514b9372562b86edfa91cdAndreas Huber bool haveAudio = false; 915778822d86b0337407514b9372562b86edfa91cdAndreas Huber bool haveVideo = false; 925778822d86b0337407514b9372562b86edfa91cdAndreas Huber for (size_t i = 0; i < extractor->countTracks(); ++i) { 935778822d86b0337407514b9372562b86edfa91cdAndreas Huber sp<AMessage> format; 945778822d86b0337407514b9372562b86edfa91cdAndreas Huber status_t err = extractor->getTrackFormat(i, &format); 955778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK_EQ(err, (status_t)OK); 965778822d86b0337407514b9372562b86edfa91cdAndreas Huber 975778822d86b0337407514b9372562b86edfa91cdAndreas Huber AString mime; 985778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(format->findString("mime", &mime)); 995778822d86b0337407514b9372562b86edfa91cdAndreas Huber 100bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber bool isAudio = !strncasecmp(mime.c_str(), "audio/", 6); 101bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber bool isVideo = !strncasecmp(mime.c_str(), "video/", 6); 102bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber 103bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber if (useAudio && !haveAudio && isAudio) { 1045778822d86b0337407514b9372562b86edfa91cdAndreas Huber haveAudio = true; 105bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber } else if (useVideo && !haveVideo && isVideo) { 1065778822d86b0337407514b9372562b86edfa91cdAndreas Huber haveVideo = true; 1075778822d86b0337407514b9372562b86edfa91cdAndreas Huber } else { 1085778822d86b0337407514b9372562b86edfa91cdAndreas Huber continue; 1095778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 1105778822d86b0337407514b9372562b86edfa91cdAndreas Huber 1115778822d86b0337407514b9372562b86edfa91cdAndreas Huber ALOGV("selecting track %d", i); 1125778822d86b0337407514b9372562b86edfa91cdAndreas Huber 1135778822d86b0337407514b9372562b86edfa91cdAndreas Huber err = extractor->selectTrack(i); 1145778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK_EQ(err, (status_t)OK); 1155778822d86b0337407514b9372562b86edfa91cdAndreas Huber 1165778822d86b0337407514b9372562b86edfa91cdAndreas Huber CodecState *state = 1175778822d86b0337407514b9372562b86edfa91cdAndreas Huber &stateByTrack.editValueAt(stateByTrack.add(i, CodecState())); 1185778822d86b0337407514b9372562b86edfa91cdAndreas Huber 119bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber state->mNumBytesDecoded = 0; 120bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber state->mNumBuffersDecoded = 0; 121bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber state->mIsAudio = isAudio; 122bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber 123f69e53033f23f9f70fcdb28a3c2e650de0147459Andreas Huber state->mCodec = MediaCodec::CreateByType( 124f69e53033f23f9f70fcdb28a3c2e650de0147459Andreas Huber looper, mime.c_str(), false /* encoder */); 1255778822d86b0337407514b9372562b86edfa91cdAndreas Huber 1265778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(state->mCodec != NULL); 1275778822d86b0337407514b9372562b86edfa91cdAndreas Huber 1285778822d86b0337407514b9372562b86edfa91cdAndreas Huber err = state->mCodec->configure( 129ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber format, isVideo ? surface : NULL, 130f69e53033f23f9f70fcdb28a3c2e650de0147459Andreas Huber NULL /* crypto */, 1311bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber 0 /* flags */); 1325778822d86b0337407514b9372562b86edfa91cdAndreas Huber 1335778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK_EQ(err, (status_t)OK); 1345778822d86b0337407514b9372562b86edfa91cdAndreas Huber 1355aaeb0d64fc98f9b019a4378eb39f0ee49ee6ec4Andreas Huber state->mSignalledInputEOS = false; 1365778822d86b0337407514b9372562b86edfa91cdAndreas Huber state->mSawOutputEOS = false; 1375778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 1385778822d86b0337407514b9372562b86edfa91cdAndreas Huber 1395778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(!stateByTrack.isEmpty()); 1405778822d86b0337407514b9372562b86edfa91cdAndreas Huber 141bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber int64_t startTimeUs = ALooper::GetNowUs(); 142fab8f4679795b86c7aaaf63f6be6b019cf7ea0cdDavid Smith int64_t startTimeRender = -1; 143bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber 1445778822d86b0337407514b9372562b86edfa91cdAndreas Huber for (size_t i = 0; i < stateByTrack.size(); ++i) { 1455778822d86b0337407514b9372562b86edfa91cdAndreas Huber CodecState *state = &stateByTrack.editValueAt(i); 1465778822d86b0337407514b9372562b86edfa91cdAndreas Huber 1475778822d86b0337407514b9372562b86edfa91cdAndreas Huber sp<MediaCodec> codec = state->mCodec; 1485778822d86b0337407514b9372562b86edfa91cdAndreas Huber 1495778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK_EQ((status_t)OK, codec->start()); 1505778822d86b0337407514b9372562b86edfa91cdAndreas Huber 1515778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK_EQ((status_t)OK, codec->getInputBuffers(&state->mInBuffers)); 1525778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK_EQ((status_t)OK, codec->getOutputBuffers(&state->mOutBuffers)); 1535778822d86b0337407514b9372562b86edfa91cdAndreas Huber 1545778822d86b0337407514b9372562b86edfa91cdAndreas Huber ALOGV("got %d input and %d output buffers", 1555778822d86b0337407514b9372562b86edfa91cdAndreas Huber state->mInBuffers.size(), state->mOutBuffers.size()); 1565778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 1575778822d86b0337407514b9372562b86edfa91cdAndreas Huber 1585778822d86b0337407514b9372562b86edfa91cdAndreas Huber bool sawInputEOS = false; 1595778822d86b0337407514b9372562b86edfa91cdAndreas Huber 1605778822d86b0337407514b9372562b86edfa91cdAndreas Huber for (;;) { 1615778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (!sawInputEOS) { 1625778822d86b0337407514b9372562b86edfa91cdAndreas Huber size_t trackIndex; 1635778822d86b0337407514b9372562b86edfa91cdAndreas Huber status_t err = extractor->getSampleTrackIndex(&trackIndex); 1645778822d86b0337407514b9372562b86edfa91cdAndreas Huber 1655778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (err != OK) { 1665aaeb0d64fc98f9b019a4378eb39f0ee49ee6ec4Andreas Huber ALOGV("saw input eos"); 1675778822d86b0337407514b9372562b86edfa91cdAndreas Huber sawInputEOS = true; 1685778822d86b0337407514b9372562b86edfa91cdAndreas Huber } else { 1695778822d86b0337407514b9372562b86edfa91cdAndreas Huber CodecState *state = &stateByTrack.editValueFor(trackIndex); 1705778822d86b0337407514b9372562b86edfa91cdAndreas Huber 1715778822d86b0337407514b9372562b86edfa91cdAndreas Huber size_t index; 172bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber err = state->mCodec->dequeueInputBuffer(&index, kTimeout); 1735778822d86b0337407514b9372562b86edfa91cdAndreas Huber 1745778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (err == OK) { 1755778822d86b0337407514b9372562b86edfa91cdAndreas Huber ALOGV("filling input buffer %d", index); 1765778822d86b0337407514b9372562b86edfa91cdAndreas Huber 1775778822d86b0337407514b9372562b86edfa91cdAndreas Huber const sp<ABuffer> &buffer = state->mInBuffers.itemAt(index); 1785778822d86b0337407514b9372562b86edfa91cdAndreas Huber 1795778822d86b0337407514b9372562b86edfa91cdAndreas Huber err = extractor->readSampleData(buffer); 1805778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK_EQ(err, (status_t)OK); 1815778822d86b0337407514b9372562b86edfa91cdAndreas Huber 1825778822d86b0337407514b9372562b86edfa91cdAndreas Huber int64_t timeUs; 1835778822d86b0337407514b9372562b86edfa91cdAndreas Huber err = extractor->getSampleTime(&timeUs); 1845778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK_EQ(err, (status_t)OK); 1855778822d86b0337407514b9372562b86edfa91cdAndreas Huber 186ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber uint32_t bufferFlags = 0; 187ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber 188f69e53033f23f9f70fcdb28a3c2e650de0147459Andreas Huber err = state->mCodec->queueInputBuffer( 189f69e53033f23f9f70fcdb28a3c2e650de0147459Andreas Huber index, 190f69e53033f23f9f70fcdb28a3c2e650de0147459Andreas Huber 0 /* offset */, 191f69e53033f23f9f70fcdb28a3c2e650de0147459Andreas Huber buffer->size(), 192f69e53033f23f9f70fcdb28a3c2e650de0147459Andreas Huber timeUs, 193f69e53033f23f9f70fcdb28a3c2e650de0147459Andreas Huber bufferFlags); 1945778822d86b0337407514b9372562b86edfa91cdAndreas Huber 1955778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK_EQ(err, (status_t)OK); 1965778822d86b0337407514b9372562b86edfa91cdAndreas Huber 1975778822d86b0337407514b9372562b86edfa91cdAndreas Huber extractor->advance(); 1985778822d86b0337407514b9372562b86edfa91cdAndreas Huber } else { 1995778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK_EQ(err, -EAGAIN); 2005778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 2015778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 2025aaeb0d64fc98f9b019a4378eb39f0ee49ee6ec4Andreas Huber } else { 2035aaeb0d64fc98f9b019a4378eb39f0ee49ee6ec4Andreas Huber for (size_t i = 0; i < stateByTrack.size(); ++i) { 2045aaeb0d64fc98f9b019a4378eb39f0ee49ee6ec4Andreas Huber CodecState *state = &stateByTrack.editValueAt(i); 2055aaeb0d64fc98f9b019a4378eb39f0ee49ee6ec4Andreas Huber 2065aaeb0d64fc98f9b019a4378eb39f0ee49ee6ec4Andreas Huber if (!state->mSignalledInputEOS) { 2075aaeb0d64fc98f9b019a4378eb39f0ee49ee6ec4Andreas Huber size_t index; 2085aaeb0d64fc98f9b019a4378eb39f0ee49ee6ec4Andreas Huber status_t err = 2095aaeb0d64fc98f9b019a4378eb39f0ee49ee6ec4Andreas Huber state->mCodec->dequeueInputBuffer(&index, kTimeout); 2105aaeb0d64fc98f9b019a4378eb39f0ee49ee6ec4Andreas Huber 2115aaeb0d64fc98f9b019a4378eb39f0ee49ee6ec4Andreas Huber if (err == OK) { 2125aaeb0d64fc98f9b019a4378eb39f0ee49ee6ec4Andreas Huber ALOGV("signalling input EOS on track %d", i); 2135aaeb0d64fc98f9b019a4378eb39f0ee49ee6ec4Andreas Huber 2145aaeb0d64fc98f9b019a4378eb39f0ee49ee6ec4Andreas Huber err = state->mCodec->queueInputBuffer( 2155aaeb0d64fc98f9b019a4378eb39f0ee49ee6ec4Andreas Huber index, 2165aaeb0d64fc98f9b019a4378eb39f0ee49ee6ec4Andreas Huber 0 /* offset */, 2175aaeb0d64fc98f9b019a4378eb39f0ee49ee6ec4Andreas Huber 0 /* size */, 2185aaeb0d64fc98f9b019a4378eb39f0ee49ee6ec4Andreas Huber 0ll /* timeUs */, 2195aaeb0d64fc98f9b019a4378eb39f0ee49ee6ec4Andreas Huber MediaCodec::BUFFER_FLAG_EOS); 2205aaeb0d64fc98f9b019a4378eb39f0ee49ee6ec4Andreas Huber 2215aaeb0d64fc98f9b019a4378eb39f0ee49ee6ec4Andreas Huber CHECK_EQ(err, (status_t)OK); 2225aaeb0d64fc98f9b019a4378eb39f0ee49ee6ec4Andreas Huber 2235aaeb0d64fc98f9b019a4378eb39f0ee49ee6ec4Andreas Huber state->mSignalledInputEOS = true; 2245aaeb0d64fc98f9b019a4378eb39f0ee49ee6ec4Andreas Huber } else { 2255aaeb0d64fc98f9b019a4378eb39f0ee49ee6ec4Andreas Huber CHECK_EQ(err, -EAGAIN); 2265aaeb0d64fc98f9b019a4378eb39f0ee49ee6ec4Andreas Huber } 2275aaeb0d64fc98f9b019a4378eb39f0ee49ee6ec4Andreas Huber } 2285aaeb0d64fc98f9b019a4378eb39f0ee49ee6ec4Andreas Huber } 2295778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 2305778822d86b0337407514b9372562b86edfa91cdAndreas Huber 2315778822d86b0337407514b9372562b86edfa91cdAndreas Huber bool sawOutputEOSOnAllTracks = true; 2325778822d86b0337407514b9372562b86edfa91cdAndreas Huber for (size_t i = 0; i < stateByTrack.size(); ++i) { 2335778822d86b0337407514b9372562b86edfa91cdAndreas Huber CodecState *state = &stateByTrack.editValueAt(i); 2345778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (!state->mSawOutputEOS) { 2355778822d86b0337407514b9372562b86edfa91cdAndreas Huber sawOutputEOSOnAllTracks = false; 2365778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 2375778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 2385778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 2395778822d86b0337407514b9372562b86edfa91cdAndreas Huber 2405778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (sawOutputEOSOnAllTracks) { 2415778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 2425778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 2435778822d86b0337407514b9372562b86edfa91cdAndreas Huber 2445778822d86b0337407514b9372562b86edfa91cdAndreas Huber for (size_t i = 0; i < stateByTrack.size(); ++i) { 2455778822d86b0337407514b9372562b86edfa91cdAndreas Huber CodecState *state = &stateByTrack.editValueAt(i); 2465778822d86b0337407514b9372562b86edfa91cdAndreas Huber 2475778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (state->mSawOutputEOS) { 2485778822d86b0337407514b9372562b86edfa91cdAndreas Huber continue; 2495778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 2505778822d86b0337407514b9372562b86edfa91cdAndreas Huber 2515778822d86b0337407514b9372562b86edfa91cdAndreas Huber size_t index; 2525778822d86b0337407514b9372562b86edfa91cdAndreas Huber size_t offset; 2535778822d86b0337407514b9372562b86edfa91cdAndreas Huber size_t size; 2545778822d86b0337407514b9372562b86edfa91cdAndreas Huber int64_t presentationTimeUs; 2555778822d86b0337407514b9372562b86edfa91cdAndreas Huber uint32_t flags; 2565778822d86b0337407514b9372562b86edfa91cdAndreas Huber status_t err = state->mCodec->dequeueOutputBuffer( 2575778822d86b0337407514b9372562b86edfa91cdAndreas Huber &index, &offset, &size, &presentationTimeUs, &flags, 258bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber kTimeout); 2595778822d86b0337407514b9372562b86edfa91cdAndreas Huber 2605778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (err == OK) { 2615778822d86b0337407514b9372562b86edfa91cdAndreas Huber ALOGV("draining output buffer %d, time = %lld us", 2625778822d86b0337407514b9372562b86edfa91cdAndreas Huber index, presentationTimeUs); 2635778822d86b0337407514b9372562b86edfa91cdAndreas Huber 264bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber ++state->mNumBuffersDecoded; 265bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber state->mNumBytesDecoded += size; 266bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber 267fab8f4679795b86c7aaaf63f6be6b019cf7ea0cdDavid Smith if (surface == NULL || !renderSurface) { 268fab8f4679795b86c7aaaf63f6be6b019cf7ea0cdDavid Smith err = state->mCodec->releaseOutputBuffer(index); 269fab8f4679795b86c7aaaf63f6be6b019cf7ea0cdDavid Smith } else if (useTimestamp) { 270fab8f4679795b86c7aaaf63f6be6b019cf7ea0cdDavid Smith if (startTimeRender == -1) { 271fab8f4679795b86c7aaaf63f6be6b019cf7ea0cdDavid Smith // begin rendering 2 vsyncs (~33ms) after first decode 272fab8f4679795b86c7aaaf63f6be6b019cf7ea0cdDavid Smith startTimeRender = 273fab8f4679795b86c7aaaf63f6be6b019cf7ea0cdDavid Smith systemTime(SYSTEM_TIME_MONOTONIC) + 33000000 274fab8f4679795b86c7aaaf63f6be6b019cf7ea0cdDavid Smith - (presentationTimeUs * 1000); 275fab8f4679795b86c7aaaf63f6be6b019cf7ea0cdDavid Smith } 276fab8f4679795b86c7aaaf63f6be6b019cf7ea0cdDavid Smith presentationTimeUs = 277fab8f4679795b86c7aaaf63f6be6b019cf7ea0cdDavid Smith (presentationTimeUs * 1000) + startTimeRender; 278fab8f4679795b86c7aaaf63f6be6b019cf7ea0cdDavid Smith err = state->mCodec->renderOutputBufferAndRelease( 279fab8f4679795b86c7aaaf63f6be6b019cf7ea0cdDavid Smith index, presentationTimeUs); 280fab8f4679795b86c7aaaf63f6be6b019cf7ea0cdDavid Smith } else { 281fab8f4679795b86c7aaaf63f6be6b019cf7ea0cdDavid Smith err = state->mCodec->renderOutputBufferAndRelease(index); 282fab8f4679795b86c7aaaf63f6be6b019cf7ea0cdDavid Smith } 283fab8f4679795b86c7aaaf63f6be6b019cf7ea0cdDavid Smith 2845778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK_EQ(err, (status_t)OK); 2855778822d86b0337407514b9372562b86edfa91cdAndreas Huber 2865778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (flags & MediaCodec::BUFFER_FLAG_EOS) { 2875778822d86b0337407514b9372562b86edfa91cdAndreas Huber ALOGV("reached EOS on output."); 2885778822d86b0337407514b9372562b86edfa91cdAndreas Huber 2895778822d86b0337407514b9372562b86edfa91cdAndreas Huber state->mSawOutputEOS = true; 2905778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 2915778822d86b0337407514b9372562b86edfa91cdAndreas Huber } else if (err == INFO_OUTPUT_BUFFERS_CHANGED) { 2925778822d86b0337407514b9372562b86edfa91cdAndreas Huber ALOGV("INFO_OUTPUT_BUFFERS_CHANGED"); 2935778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK_EQ((status_t)OK, 2945778822d86b0337407514b9372562b86edfa91cdAndreas Huber state->mCodec->getOutputBuffers(&state->mOutBuffers)); 2955778822d86b0337407514b9372562b86edfa91cdAndreas Huber 2965778822d86b0337407514b9372562b86edfa91cdAndreas Huber ALOGV("got %d output buffers", state->mOutBuffers.size()); 2975778822d86b0337407514b9372562b86edfa91cdAndreas Huber } else if (err == INFO_FORMAT_CHANGED) { 2985778822d86b0337407514b9372562b86edfa91cdAndreas Huber sp<AMessage> format; 2995778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK_EQ((status_t)OK, state->mCodec->getOutputFormat(&format)); 3005778822d86b0337407514b9372562b86edfa91cdAndreas Huber 3015778822d86b0337407514b9372562b86edfa91cdAndreas Huber ALOGV("INFO_FORMAT_CHANGED: %s", format->debugString().c_str()); 3025778822d86b0337407514b9372562b86edfa91cdAndreas Huber } else { 3035778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK_EQ(err, -EAGAIN); 3045778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 3055778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 3065778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 3075778822d86b0337407514b9372562b86edfa91cdAndreas Huber 308bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber int64_t elapsedTimeUs = ALooper::GetNowUs() - startTimeUs; 309bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber 3105778822d86b0337407514b9372562b86edfa91cdAndreas Huber for (size_t i = 0; i < stateByTrack.size(); ++i) { 3115778822d86b0337407514b9372562b86edfa91cdAndreas Huber CodecState *state = &stateByTrack.editValueAt(i); 3125778822d86b0337407514b9372562b86edfa91cdAndreas Huber 313c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber CHECK_EQ((status_t)OK, state->mCodec->release()); 314bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber 315bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber if (state->mIsAudio) { 316377b2ec9a2885f9b6405b07ba900a9e3f4349c38Kévin PETIT printf("track %zu: %" PRId64 " bytes received. %.2f KB/sec\n", 317bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber i, 318bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber state->mNumBytesDecoded, 319bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber state->mNumBytesDecoded * 1E6 / 1024 / elapsedTimeUs); 320bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber } else { 321377b2ec9a2885f9b6405b07ba900a9e3f4349c38Kévin PETIT printf("track %zu: %" PRId64 " frames decoded, %.2f fps. %" PRId64 322377b2ec9a2885f9b6405b07ba900a9e3f4349c38Kévin PETIT " bytes received. %.2f KB/sec\n", 323bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber i, 324bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber state->mNumBuffersDecoded, 325bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber state->mNumBuffersDecoded * 1E6 / elapsedTimeUs, 326bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber state->mNumBytesDecoded, 327bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber state->mNumBytesDecoded * 1E6 / 1024 / elapsedTimeUs); 328bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber } 3295778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 3305778822d86b0337407514b9372562b86edfa91cdAndreas Huber 3315778822d86b0337407514b9372562b86edfa91cdAndreas Huber return 0; 3325778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 3335778822d86b0337407514b9372562b86edfa91cdAndreas Huber 3345778822d86b0337407514b9372562b86edfa91cdAndreas Huberint main(int argc, char **argv) { 3355778822d86b0337407514b9372562b86edfa91cdAndreas Huber using namespace android; 3365778822d86b0337407514b9372562b86edfa91cdAndreas Huber 3375778822d86b0337407514b9372562b86edfa91cdAndreas Huber const char *me = argv[0]; 3385778822d86b0337407514b9372562b86edfa91cdAndreas Huber 3395778822d86b0337407514b9372562b86edfa91cdAndreas Huber bool useAudio = false; 3405778822d86b0337407514b9372562b86edfa91cdAndreas Huber bool useVideo = false; 3415778822d86b0337407514b9372562b86edfa91cdAndreas Huber bool playback = false; 342bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber bool useSurface = false; 343fab8f4679795b86c7aaaf63f6be6b019cf7ea0cdDavid Smith bool renderSurface = false; 344fab8f4679795b86c7aaaf63f6be6b019cf7ea0cdDavid Smith bool useTimestamp = false; 3455778822d86b0337407514b9372562b86edfa91cdAndreas Huber 3465778822d86b0337407514b9372562b86edfa91cdAndreas Huber int res; 347fab8f4679795b86c7aaaf63f6be6b019cf7ea0cdDavid Smith while ((res = getopt(argc, argv, "havpSDRT")) >= 0) { 3485778822d86b0337407514b9372562b86edfa91cdAndreas Huber switch (res) { 3495778822d86b0337407514b9372562b86edfa91cdAndreas Huber case 'a': 3505778822d86b0337407514b9372562b86edfa91cdAndreas Huber { 3515778822d86b0337407514b9372562b86edfa91cdAndreas Huber useAudio = true; 3525778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 3535778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 3545778822d86b0337407514b9372562b86edfa91cdAndreas Huber case 'v': 3555778822d86b0337407514b9372562b86edfa91cdAndreas Huber { 3565778822d86b0337407514b9372562b86edfa91cdAndreas Huber useVideo = true; 3575778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 3585778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 3595778822d86b0337407514b9372562b86edfa91cdAndreas Huber case 'p': 3605778822d86b0337407514b9372562b86edfa91cdAndreas Huber { 3615778822d86b0337407514b9372562b86edfa91cdAndreas Huber playback = true; 3625778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 3635778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 364fab8f4679795b86c7aaaf63f6be6b019cf7ea0cdDavid Smith case 'T': 365fab8f4679795b86c7aaaf63f6be6b019cf7ea0cdDavid Smith { 366fab8f4679795b86c7aaaf63f6be6b019cf7ea0cdDavid Smith useTimestamp = true; 367fab8f4679795b86c7aaaf63f6be6b019cf7ea0cdDavid Smith } 368fab8f4679795b86c7aaaf63f6be6b019cf7ea0cdDavid Smith // fall through 369fab8f4679795b86c7aaaf63f6be6b019cf7ea0cdDavid Smith case 'R': 370fab8f4679795b86c7aaaf63f6be6b019cf7ea0cdDavid Smith { 371fab8f4679795b86c7aaaf63f6be6b019cf7ea0cdDavid Smith renderSurface = true; 372fab8f4679795b86c7aaaf63f6be6b019cf7ea0cdDavid Smith } 373fab8f4679795b86c7aaaf63f6be6b019cf7ea0cdDavid Smith // fall through 374bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber case 'S': 375bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber { 376bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber useSurface = true; 377bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber break; 378bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber } 3795778822d86b0337407514b9372562b86edfa91cdAndreas Huber case '?': 3805778822d86b0337407514b9372562b86edfa91cdAndreas Huber case 'h': 3815778822d86b0337407514b9372562b86edfa91cdAndreas Huber default: 3825778822d86b0337407514b9372562b86edfa91cdAndreas Huber { 3835778822d86b0337407514b9372562b86edfa91cdAndreas Huber usage(me); 3845778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 3855778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 3865778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 3875778822d86b0337407514b9372562b86edfa91cdAndreas Huber 3885778822d86b0337407514b9372562b86edfa91cdAndreas Huber argc -= optind; 3895778822d86b0337407514b9372562b86edfa91cdAndreas Huber argv += optind; 3905778822d86b0337407514b9372562b86edfa91cdAndreas Huber 3915778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (argc != 1) { 3925778822d86b0337407514b9372562b86edfa91cdAndreas Huber usage(me); 3935778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 3945778822d86b0337407514b9372562b86edfa91cdAndreas Huber 3955778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (!useAudio && !useVideo) { 3965778822d86b0337407514b9372562b86edfa91cdAndreas Huber useAudio = useVideo = true; 3975778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 3985778822d86b0337407514b9372562b86edfa91cdAndreas Huber 3995778822d86b0337407514b9372562b86edfa91cdAndreas Huber ProcessState::self()->startThreadPool(); 4005778822d86b0337407514b9372562b86edfa91cdAndreas Huber 4015778822d86b0337407514b9372562b86edfa91cdAndreas Huber DataSource::RegisterDefaultSniffers(); 4025778822d86b0337407514b9372562b86edfa91cdAndreas Huber 4035778822d86b0337407514b9372562b86edfa91cdAndreas Huber sp<ALooper> looper = new ALooper; 4045778822d86b0337407514b9372562b86edfa91cdAndreas Huber looper->start(); 4055778822d86b0337407514b9372562b86edfa91cdAndreas Huber 406bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber sp<SurfaceComposerClient> composerClient; 407bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber sp<SurfaceControl> control; 408bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber sp<Surface> surface; 409bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber 410bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber if (playback || (useSurface && useVideo)) { 411bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber composerClient = new SurfaceComposerClient; 4125778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK_EQ(composerClient->initCheck(), (status_t)OK); 4135778822d86b0337407514b9372562b86edfa91cdAndreas Huber 414a6195decfe4f9021bbbd7deb050495c33371366bJeff Brown sp<IBinder> display(SurfaceComposerClient::getBuiltInDisplay( 415a6195decfe4f9021bbbd7deb050495c33371366bJeff Brown ISurfaceComposer::eDisplayIdMain)); 4163dca4c7a5622fc6aa03397d749c4b4c1201cc4f3Mathias Agopian DisplayInfo info; 417a6195decfe4f9021bbbd7deb050495c33371366bJeff Brown SurfaceComposerClient::getDisplayInfo(display, &info); 4183dca4c7a5622fc6aa03397d749c4b4c1201cc4f3Mathias Agopian ssize_t displayWidth = info.w; 4193dca4c7a5622fc6aa03397d749c4b4c1201cc4f3Mathias Agopian ssize_t displayHeight = info.h; 4205778822d86b0337407514b9372562b86edfa91cdAndreas Huber 4215778822d86b0337407514b9372562b86edfa91cdAndreas Huber ALOGV("display is %ld x %ld\n", displayWidth, displayHeight); 4225778822d86b0337407514b9372562b86edfa91cdAndreas Huber 423bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber control = composerClient->createSurface( 424bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber String8("A Surface"), 425bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber displayWidth, 426bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber displayHeight, 427bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber PIXEL_FORMAT_RGB_565, 428bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber 0); 4295778822d86b0337407514b9372562b86edfa91cdAndreas Huber 4305778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(control != NULL); 4315778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(control->isValid()); 4325778822d86b0337407514b9372562b86edfa91cdAndreas Huber 4335778822d86b0337407514b9372562b86edfa91cdAndreas Huber SurfaceComposerClient::openGlobalTransaction(); 4345778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK_EQ(control->setLayer(INT_MAX), (status_t)OK); 4355778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK_EQ(control->show(), (status_t)OK); 4365778822d86b0337407514b9372562b86edfa91cdAndreas Huber SurfaceComposerClient::closeGlobalTransaction(); 4375778822d86b0337407514b9372562b86edfa91cdAndreas Huber 438bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber surface = control->getSurface(); 4395778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(surface != NULL); 440bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber } 4415778822d86b0337407514b9372562b86edfa91cdAndreas Huber 442bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber if (playback) { 4435778822d86b0337407514b9372562b86edfa91cdAndreas Huber sp<SimplePlayer> player = new SimplePlayer; 4445778822d86b0337407514b9372562b86edfa91cdAndreas Huber looper->registerHandler(player); 4455778822d86b0337407514b9372562b86edfa91cdAndreas Huber 4465778822d86b0337407514b9372562b86edfa91cdAndreas Huber player->setDataSource(argv[0]); 4471a2952aee048ca7b1765e2bc09ebe9aeddaeafa3Mathias Agopian player->setSurface(surface->getIGraphicBufferProducer()); 4485778822d86b0337407514b9372562b86edfa91cdAndreas Huber player->start(); 449e98f8c04faf27df3b1829d336299ad51dad569cfAndreas Huber sleep(60); 4505778822d86b0337407514b9372562b86edfa91cdAndreas Huber player->stop(); 4515778822d86b0337407514b9372562b86edfa91cdAndreas Huber player->reset(); 452bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber } else { 453fab8f4679795b86c7aaaf63f6be6b019cf7ea0cdDavid Smith decode(looper, argv[0], useAudio, useVideo, surface, renderSurface, 454fab8f4679795b86c7aaaf63f6be6b019cf7ea0cdDavid Smith useTimestamp); 455bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber } 4565778822d86b0337407514b9372562b86edfa91cdAndreas Huber 457bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber if (playback || (useSurface && useVideo)) { 4585778822d86b0337407514b9372562b86edfa91cdAndreas Huber composerClient->dispose(); 4595778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 4605778822d86b0337407514b9372562b86edfa91cdAndreas Huber 4615778822d86b0337407514b9372562b86edfa91cdAndreas Huber looper->stop(); 4625778822d86b0337407514b9372562b86edfa91cdAndreas Huber 4635778822d86b0337407514b9372562b86edfa91cdAndreas Huber return 0; 4645778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 465