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