18eb69d60c09c1c4683066a94c889df28d0e9d233James Dong/* 28eb69d60c09c1c4683066a94c889df28d0e9d233James Dong * Copyright (C) 2010 The Android Open Source Project 38eb69d60c09c1c4683066a94c889df28d0e9d233James Dong * 48eb69d60c09c1c4683066a94c889df28d0e9d233James Dong * Licensed under the Apache License, Version 2.0 (the "License"); 58eb69d60c09c1c4683066a94c889df28d0e9d233James Dong * you may not use this file except in compliance with the License. 68eb69d60c09c1c4683066a94c889df28d0e9d233James Dong * You may obtain a copy of the License at 78eb69d60c09c1c4683066a94c889df28d0e9d233James Dong * 88eb69d60c09c1c4683066a94c889df28d0e9d233James Dong * http://www.apache.org/licenses/LICENSE-2.0 98eb69d60c09c1c4683066a94c889df28d0e9d233James Dong * 108eb69d60c09c1c4683066a94c889df28d0e9d233James Dong * Unless required by applicable law or agreed to in writing, software 118eb69d60c09c1c4683066a94c889df28d0e9d233James Dong * distributed under the License is distributed on an "AS IS" BASIS, 128eb69d60c09c1c4683066a94c889df28d0e9d233James Dong * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 138eb69d60c09c1c4683066a94c889df28d0e9d233James Dong * See the License for the specific language governing permissions and 148eb69d60c09c1c4683066a94c889df28d0e9d233James Dong * limitations under the License. 158eb69d60c09c1c4683066a94c889df28d0e9d233James Dong */ 168eb69d60c09c1c4683066a94c889df28d0e9d233James Dong 17f5e376fb8f2c30f82b7548241ca6b24f92ff8914Andreas Huber//#define LOG_NDEBUG 0 18f5e376fb8f2c30f82b7548241ca6b24f92ff8914Andreas Huber#define LOG_TAG "sf2" 19377b2ec9a2885f9b6405b07ba900a9e3f4349c38Kévin PETIT#include <inttypes.h> 20f5e376fb8f2c30f82b7548241ca6b24f92ff8914Andreas Huber#include <utils/Log.h> 21f5e376fb8f2c30f82b7548241ca6b24f92ff8914Andreas Huber 22a2354479716db40d865c597dc572ea83573caac2Marco Nelissen#include <signal.h> 23a2354479716db40d865c597dc572ea83573caac2Marco Nelissen 24f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <binder/ProcessState.h> 25f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 261b86fe063badb5f28c467ade39be0f4008688947Andreas Huber#include <media/IMediaHTTPService.h> 271b86fe063badb5f28c467ade39be0f4008688947Andreas Huber 28f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/foundation/hexdump.h> 29f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/foundation/ABuffer.h> 30f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/foundation/ADebug.h> 31f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/foundation/ALooper.h> 32f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/foundation/AMessage.h> 33f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 34f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/ACodec.h> 35f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/DataSource.h> 36f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/MediaBuffer.h> 37f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/MediaDefs.h> 38f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/MediaExtractor.h> 39f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/MediaSource.h> 40f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/MetaData.h> 411065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber#include <media/stagefright/NativeWindowWrapper.h> 42f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/Utils.h> 43f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 44df712ea86e6350f7005a02ab0e1c60c28a343ed0Mathias Agopian#include <gui/SurfaceComposerClient.h> 45f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 46f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include "include/ESDS.h" 47f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 48f933441648ef6a71dee783d733aac17b9508b452Andreas Huberusing namespace android; 49f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 50a2354479716db40d865c597dc572ea83573caac2Marco Nelissenvolatile static bool ctrlc = false; 51a2354479716db40d865c597dc572ea83573caac2Marco Nelissen 52a2354479716db40d865c597dc572ea83573caac2Marco Nelissenstatic sighandler_t oldhandler = NULL; 53a2354479716db40d865c597dc572ea83573caac2Marco Nelissen 54a2354479716db40d865c597dc572ea83573caac2Marco Nelissenstatic void mysighandler(int signum) { 55a2354479716db40d865c597dc572ea83573caac2Marco Nelissen if (signum == SIGINT) { 56a2354479716db40d865c597dc572ea83573caac2Marco Nelissen ctrlc = true; 57a2354479716db40d865c597dc572ea83573caac2Marco Nelissen return; 58a2354479716db40d865c597dc572ea83573caac2Marco Nelissen } 59a2354479716db40d865c597dc572ea83573caac2Marco Nelissen oldhandler(signum); 60a2354479716db40d865c597dc572ea83573caac2Marco Nelissen} 61a2354479716db40d865c597dc572ea83573caac2Marco Nelissen 62f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct Controller : public AHandler { 631065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber Controller(const char *uri, bool decodeAudio, 641065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber const sp<Surface> &surface, bool renderToSurface) 65f933441648ef6a71dee783d733aac17b9508b452Andreas Huber : mURI(uri), 66f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mDecodeAudio(decodeAudio), 67f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mSurface(surface), 681065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber mRenderToSurface(renderToSurface), 69729de186450f78c099637e1fce743fe531862c52Andreas Huber mCodec(new ACodec), 70729de186450f78c099637e1fce743fe531862c52Andreas Huber mIsVorbis(false) { 71f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(!mDecodeAudio || mSurface == NULL); 72f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 73f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 74f933441648ef6a71dee783d733aac17b9508b452Andreas Huber void startAsync() { 75f933441648ef6a71dee783d733aac17b9508b452Andreas Huber (new AMessage(kWhatStart, id()))->post(); 76f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 77f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 78f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected: 79f933441648ef6a71dee783d733aac17b9508b452Andreas Huber virtual ~Controller() { 80f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 81f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 82a2354479716db40d865c597dc572ea83573caac2Marco Nelissen virtual void printStatistics() { 83a2354479716db40d865c597dc572ea83573caac2Marco Nelissen int64_t delayUs = ALooper::GetNowUs() - mStartTimeUs; 841d6fa7af1288b550faabe4ec2cf98684236723dbNarayan Kamath 85a2354479716db40d865c597dc572ea83573caac2Marco Nelissen if (mDecodeAudio) { 861d6fa7af1288b550faabe4ec2cf98684236723dbNarayan Kamath printf("%" PRId64 " bytes received. %.2f KB/sec\n", 871d6fa7af1288b550faabe4ec2cf98684236723dbNarayan Kamath mTotalBytesReceived, 881d6fa7af1288b550faabe4ec2cf98684236723dbNarayan Kamath mTotalBytesReceived * 1E6 / 1024 / delayUs); 89a2354479716db40d865c597dc572ea83573caac2Marco Nelissen } else { 901d6fa7af1288b550faabe4ec2cf98684236723dbNarayan Kamath printf("%d frames decoded, %.2f fps. %" PRId64 " bytes " 911d6fa7af1288b550faabe4ec2cf98684236723dbNarayan Kamath "received. %.2f KB/sec\n", 921d6fa7af1288b550faabe4ec2cf98684236723dbNarayan Kamath mNumOutputBuffersReceived, 931d6fa7af1288b550faabe4ec2cf98684236723dbNarayan Kamath mNumOutputBuffersReceived * 1E6 / delayUs, 941d6fa7af1288b550faabe4ec2cf98684236723dbNarayan Kamath mTotalBytesReceived, 951d6fa7af1288b550faabe4ec2cf98684236723dbNarayan Kamath mTotalBytesReceived * 1E6 / 1024 / delayUs); 96a2354479716db40d865c597dc572ea83573caac2Marco Nelissen } 97a2354479716db40d865c597dc572ea83573caac2Marco Nelissen } 98a2354479716db40d865c597dc572ea83573caac2Marco Nelissen 99f933441648ef6a71dee783d733aac17b9508b452Andreas Huber virtual void onMessageReceived(const sp<AMessage> &msg) { 100a2354479716db40d865c597dc572ea83573caac2Marco Nelissen if (ctrlc) { 101a2354479716db40d865c597dc572ea83573caac2Marco Nelissen printf("\n"); 102a2354479716db40d865c597dc572ea83573caac2Marco Nelissen printStatistics(); 103a2354479716db40d865c597dc572ea83573caac2Marco Nelissen (new AMessage(kWhatStop, id()))->post(); 104a2354479716db40d865c597dc572ea83573caac2Marco Nelissen ctrlc = false; 105a2354479716db40d865c597dc572ea83573caac2Marco Nelissen } 106f933441648ef6a71dee783d733aac17b9508b452Andreas Huber switch (msg->what()) { 107f933441648ef6a71dee783d733aac17b9508b452Andreas Huber case kWhatStart: 108f933441648ef6a71dee783d733aac17b9508b452Andreas Huber { 109f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#if 1 110f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mDecodeLooper = looper(); 111f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#else 112f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mDecodeLooper = new ALooper; 113f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mDecodeLooper->setName("sf2 decode looper"); 114f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mDecodeLooper->start(); 115f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#endif 116f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 117f933441648ef6a71dee783d733aac17b9508b452Andreas Huber sp<DataSource> dataSource = 1181b86fe063badb5f28c467ade39be0f4008688947Andreas Huber DataSource::CreateFromURI( 1191b86fe063badb5f28c467ade39be0f4008688947Andreas Huber NULL /* httpService */, mURI.c_str()); 120f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 121f933441648ef6a71dee783d733aac17b9508b452Andreas Huber sp<MediaExtractor> extractor = 122f933441648ef6a71dee783d733aac17b9508b452Andreas Huber MediaExtractor::Create(dataSource); 123f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 124f933441648ef6a71dee783d733aac17b9508b452Andreas Huber for (size_t i = 0; i < extractor->countTracks(); ++i) { 125f933441648ef6a71dee783d733aac17b9508b452Andreas Huber sp<MetaData> meta = extractor->getTrackMetaData(i); 126f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 127f933441648ef6a71dee783d733aac17b9508b452Andreas Huber const char *mime; 128f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(meta->findCString(kKeyMIMEType, &mime)); 129f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 130f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (!strncasecmp(mDecodeAudio ? "audio/" : "video/", 131f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mime, 6)) { 132f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mSource = extractor->getTrack(i); 133729de186450f78c099637e1fce743fe531862c52Andreas Huber 134729de186450f78c099637e1fce743fe531862c52Andreas Huber if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_VORBIS)) { 135729de186450f78c099637e1fce743fe531862c52Andreas Huber mIsVorbis = true; 136729de186450f78c099637e1fce743fe531862c52Andreas Huber } else { 137729de186450f78c099637e1fce743fe531862c52Andreas Huber mIsVorbis = false; 138729de186450f78c099637e1fce743fe531862c52Andreas Huber } 139f933441648ef6a71dee783d733aac17b9508b452Andreas Huber break; 140f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 141f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 142a2354479716db40d865c597dc572ea83573caac2Marco Nelissen if (mSource == NULL) { 143a2354479716db40d865c597dc572ea83573caac2Marco Nelissen printf("no %s track found\n", mDecodeAudio ? "audio" : "video"); 144a2354479716db40d865c597dc572ea83573caac2Marco Nelissen exit (1); 145a2354479716db40d865c597dc572ea83573caac2Marco Nelissen } 146f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 147f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK_EQ(mSource->start(), (status_t)OK); 148f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 149f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mDecodeLooper->registerHandler(mCodec); 150f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 151f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mCodec->setNotificationMessage( 152f933441648ef6a71dee783d733aac17b9508b452Andreas Huber new AMessage(kWhatCodecNotify, id())); 153f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 154f933441648ef6a71dee783d733aac17b9508b452Andreas Huber sp<AMessage> format = makeFormat(mSource->getFormat()); 155f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 156f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (mSurface != NULL) { 1571065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber format->setObject( 1581065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber "native-window", new NativeWindowWrapper(mSurface)); 159f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 160f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 161f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mCodec->initiateSetup(format); 162f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 163f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mCSDIndex = 0; 164f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mStartTimeUs = ALooper::GetNowUs(); 165f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mNumOutputBuffersReceived = 0; 166f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mTotalBytesReceived = 0; 167f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mLeftOverBuffer = NULL; 168f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mFinalResult = OK; 169f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mSeekState = SEEK_NONE; 170f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 171f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // (new AMessage(kWhatSeek, id()))->post(5000000ll); 172f933441648ef6a71dee783d733aac17b9508b452Andreas Huber break; 173f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 174f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 175f933441648ef6a71dee783d733aac17b9508b452Andreas Huber case kWhatSeek: 176f933441648ef6a71dee783d733aac17b9508b452Andreas Huber { 177f933441648ef6a71dee783d733aac17b9508b452Andreas Huber printf("+"); 178f933441648ef6a71dee783d733aac17b9508b452Andreas Huber fflush(stdout); 179f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 180f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(mSeekState == SEEK_NONE 181f933441648ef6a71dee783d733aac17b9508b452Andreas Huber || mSeekState == SEEK_FLUSH_COMPLETED); 182f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 183f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (mLeftOverBuffer != NULL) { 184f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mLeftOverBuffer->release(); 185f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mLeftOverBuffer = NULL; 186f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 187f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 188f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mSeekState = SEEK_FLUSHING; 189f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mSeekTimeUs = 30000000ll; 190f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 191f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mCodec->signalFlush(); 192f933441648ef6a71dee783d733aac17b9508b452Andreas Huber break; 193f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 194f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 195f933441648ef6a71dee783d733aac17b9508b452Andreas Huber case kWhatStop: 196f933441648ef6a71dee783d733aac17b9508b452Andreas Huber { 197f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (mLeftOverBuffer != NULL) { 198f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mLeftOverBuffer->release(); 199f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mLeftOverBuffer = NULL; 200f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 201f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 202f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK_EQ(mSource->stop(), (status_t)OK); 203f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mSource.clear(); 204f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 205f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mCodec->initiateShutdown(); 206f933441648ef6a71dee783d733aac17b9508b452Andreas Huber break; 207f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 208f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 209f933441648ef6a71dee783d733aac17b9508b452Andreas Huber case kWhatCodecNotify: 210f933441648ef6a71dee783d733aac17b9508b452Andreas Huber { 211f933441648ef6a71dee783d733aac17b9508b452Andreas Huber int32_t what; 212f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(msg->findInt32("what", &what)); 213f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 214d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar if (what == CodecBase::kWhatFillThisBuffer) { 215f933441648ef6a71dee783d733aac17b9508b452Andreas Huber onFillThisBuffer(msg); 216d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar } else if (what == CodecBase::kWhatDrainThisBuffer) { 217f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if ((mNumOutputBuffersReceived++ % 16) == 0) { 218f933441648ef6a71dee783d733aac17b9508b452Andreas Huber printf("."); 219f933441648ef6a71dee783d733aac17b9508b452Andreas Huber fflush(stdout); 220f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 221f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 222f933441648ef6a71dee783d733aac17b9508b452Andreas Huber onDrainThisBuffer(msg); 223d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar } else if (what == CodecBase::kWhatEOS 224d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar || what == CodecBase::kWhatError) { 225d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar printf((what == CodecBase::kWhatEOS) ? "$\n" : "E\n"); 226f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 227a2354479716db40d865c597dc572ea83573caac2Marco Nelissen printStatistics(); 228f933441648ef6a71dee783d733aac17b9508b452Andreas Huber (new AMessage(kWhatStop, id()))->post(); 229d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar } else if (what == CodecBase::kWhatFlushCompleted) { 230f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mSeekState = SEEK_FLUSH_COMPLETED; 231f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mCodec->signalResume(); 232f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 233f933441648ef6a71dee783d733aac17b9508b452Andreas Huber (new AMessage(kWhatSeek, id()))->post(5000000ll); 234d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar } else if (what == CodecBase::kWhatOutputFormatChanged) { 235d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar } else if (what == CodecBase::kWhatShutdownCompleted) { 236f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mDecodeLooper->unregisterHandler(mCodec->id()); 237f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 238f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (mDecodeLooper != looper()) { 239f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mDecodeLooper->stop(); 240f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 241f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 242f933441648ef6a71dee783d733aac17b9508b452Andreas Huber looper()->stop(); 243f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 244f933441648ef6a71dee783d733aac17b9508b452Andreas Huber break; 245f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 246f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 247f933441648ef6a71dee783d733aac17b9508b452Andreas Huber default: 248f933441648ef6a71dee783d733aac17b9508b452Andreas Huber TRESPASS(); 249f933441648ef6a71dee783d733aac17b9508b452Andreas Huber break; 250f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 251f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 252f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 253f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate: 254f933441648ef6a71dee783d733aac17b9508b452Andreas Huber enum { 255f933441648ef6a71dee783d733aac17b9508b452Andreas Huber kWhatStart = 'strt', 256f933441648ef6a71dee783d733aac17b9508b452Andreas Huber kWhatStop = 'stop', 257f933441648ef6a71dee783d733aac17b9508b452Andreas Huber kWhatCodecNotify = 'noti', 258f933441648ef6a71dee783d733aac17b9508b452Andreas Huber kWhatSeek = 'seek', 259f933441648ef6a71dee783d733aac17b9508b452Andreas Huber }; 260f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 261f933441648ef6a71dee783d733aac17b9508b452Andreas Huber sp<ALooper> mDecodeLooper; 262f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 263f933441648ef6a71dee783d733aac17b9508b452Andreas Huber AString mURI; 264f933441648ef6a71dee783d733aac17b9508b452Andreas Huber bool mDecodeAudio; 265f933441648ef6a71dee783d733aac17b9508b452Andreas Huber sp<Surface> mSurface; 2661065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber bool mRenderToSurface; 267f933441648ef6a71dee783d733aac17b9508b452Andreas Huber sp<ACodec> mCodec; 268f933441648ef6a71dee783d733aac17b9508b452Andreas Huber sp<MediaSource> mSource; 269729de186450f78c099637e1fce743fe531862c52Andreas Huber bool mIsVorbis; 270f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 271f933441648ef6a71dee783d733aac17b9508b452Andreas Huber Vector<sp<ABuffer> > mCSD; 272f933441648ef6a71dee783d733aac17b9508b452Andreas Huber size_t mCSDIndex; 273f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 274f933441648ef6a71dee783d733aac17b9508b452Andreas Huber MediaBuffer *mLeftOverBuffer; 275f933441648ef6a71dee783d733aac17b9508b452Andreas Huber status_t mFinalResult; 276f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 277f933441648ef6a71dee783d733aac17b9508b452Andreas Huber int64_t mStartTimeUs; 278f933441648ef6a71dee783d733aac17b9508b452Andreas Huber int32_t mNumOutputBuffersReceived; 279f933441648ef6a71dee783d733aac17b9508b452Andreas Huber int64_t mTotalBytesReceived; 280f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 281f933441648ef6a71dee783d733aac17b9508b452Andreas Huber enum SeekState { 282f933441648ef6a71dee783d733aac17b9508b452Andreas Huber SEEK_NONE, 283f933441648ef6a71dee783d733aac17b9508b452Andreas Huber SEEK_FLUSHING, 284f933441648ef6a71dee783d733aac17b9508b452Andreas Huber SEEK_FLUSH_COMPLETED, 285f933441648ef6a71dee783d733aac17b9508b452Andreas Huber }; 286f933441648ef6a71dee783d733aac17b9508b452Andreas Huber SeekState mSeekState; 287f933441648ef6a71dee783d733aac17b9508b452Andreas Huber int64_t mSeekTimeUs; 288f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 289f933441648ef6a71dee783d733aac17b9508b452Andreas Huber sp<AMessage> makeFormat(const sp<MetaData> &meta) { 290f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(mCSD.isEmpty()); 291f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 292f933441648ef6a71dee783d733aac17b9508b452Andreas Huber const char *mime; 293f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(meta->findCString(kKeyMIMEType, &mime)); 294f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 295f933441648ef6a71dee783d733aac17b9508b452Andreas Huber sp<AMessage> msg = new AMessage; 296f933441648ef6a71dee783d733aac17b9508b452Andreas Huber msg->setString("mime", mime); 297f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 298f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (!strncasecmp("video/", mime, 6)) { 299f933441648ef6a71dee783d733aac17b9508b452Andreas Huber int32_t width, height; 300f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(meta->findInt32(kKeyWidth, &width)); 301f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(meta->findInt32(kKeyHeight, &height)); 302f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 303f933441648ef6a71dee783d733aac17b9508b452Andreas Huber msg->setInt32("width", width); 304f933441648ef6a71dee783d733aac17b9508b452Andreas Huber msg->setInt32("height", height); 305f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } else { 306f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(!strncasecmp("audio/", mime, 6)); 307f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 308f933441648ef6a71dee783d733aac17b9508b452Andreas Huber int32_t numChannels, sampleRate; 309f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(meta->findInt32(kKeyChannelCount, &numChannels)); 310f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(meta->findInt32(kKeySampleRate, &sampleRate)); 311f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 312f933441648ef6a71dee783d733aac17b9508b452Andreas Huber msg->setInt32("channel-count", numChannels); 313f933441648ef6a71dee783d733aac17b9508b452Andreas Huber msg->setInt32("sample-rate", sampleRate); 314ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber 315ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber int32_t isADTS; 316ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber if (meta->findInt32(kKeyIsADTS, &isADTS) && isADTS != 0) { 317ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber msg->setInt32("is-adts", true); 318ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber } 319f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 320f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 321f933441648ef6a71dee783d733aac17b9508b452Andreas Huber uint32_t type; 322f933441648ef6a71dee783d733aac17b9508b452Andreas Huber const void *data; 323f933441648ef6a71dee783d733aac17b9508b452Andreas Huber size_t size; 324f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (meta->findData(kKeyAVCC, &type, &data, &size)) { 325f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // Parse the AVCDecoderConfigurationRecord 326f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 327f933441648ef6a71dee783d733aac17b9508b452Andreas Huber const uint8_t *ptr = (const uint8_t *)data; 328f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 329f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(size >= 7); 330f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK_EQ((unsigned)ptr[0], 1u); // configurationVersion == 1 331f933441648ef6a71dee783d733aac17b9508b452Andreas Huber uint8_t profile = ptr[1]; 332f933441648ef6a71dee783d733aac17b9508b452Andreas Huber uint8_t level = ptr[3]; 333f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 334f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // There is decodable content out there that fails the following 335f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // assertion, let's be lenient for now... 336f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // CHECK((ptr[4] >> 2) == 0x3f); // reserved 337f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 338f933441648ef6a71dee783d733aac17b9508b452Andreas Huber size_t lengthSize = 1 + (ptr[4] & 3); 339f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 340f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // commented out check below as H264_QVGA_500_NO_AUDIO.3gp 341f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // violates it... 342f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // CHECK((ptr[5] >> 5) == 7); // reserved 343f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 344f933441648ef6a71dee783d733aac17b9508b452Andreas Huber size_t numSeqParameterSets = ptr[5] & 31; 345f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 346f933441648ef6a71dee783d733aac17b9508b452Andreas Huber ptr += 6; 347f933441648ef6a71dee783d733aac17b9508b452Andreas Huber size -= 6; 348f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 349f933441648ef6a71dee783d733aac17b9508b452Andreas Huber sp<ABuffer> buffer = new ABuffer(1024); 350f933441648ef6a71dee783d733aac17b9508b452Andreas Huber buffer->setRange(0, 0); 351f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 352f933441648ef6a71dee783d733aac17b9508b452Andreas Huber for (size_t i = 0; i < numSeqParameterSets; ++i) { 353f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(size >= 2); 354f933441648ef6a71dee783d733aac17b9508b452Andreas Huber size_t length = U16_AT(ptr); 355f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 356f933441648ef6a71dee783d733aac17b9508b452Andreas Huber ptr += 2; 357f933441648ef6a71dee783d733aac17b9508b452Andreas Huber size -= 2; 358f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 359f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(size >= length); 360f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 361f933441648ef6a71dee783d733aac17b9508b452Andreas Huber memcpy(buffer->data() + buffer->size(), "\x00\x00\x00\x01", 4); 362f933441648ef6a71dee783d733aac17b9508b452Andreas Huber memcpy(buffer->data() + buffer->size() + 4, ptr, length); 363f933441648ef6a71dee783d733aac17b9508b452Andreas Huber buffer->setRange(0, buffer->size() + 4 + length); 364f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 365f933441648ef6a71dee783d733aac17b9508b452Andreas Huber ptr += length; 366f933441648ef6a71dee783d733aac17b9508b452Andreas Huber size -= length; 367f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 368f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 369f933441648ef6a71dee783d733aac17b9508b452Andreas Huber buffer->meta()->setInt32("csd", true); 370f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mCSD.push(buffer); 371f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 372f933441648ef6a71dee783d733aac17b9508b452Andreas Huber buffer = new ABuffer(1024); 373f933441648ef6a71dee783d733aac17b9508b452Andreas Huber buffer->setRange(0, 0); 374f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 375f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(size >= 1); 376f933441648ef6a71dee783d733aac17b9508b452Andreas Huber size_t numPictureParameterSets = *ptr; 377f933441648ef6a71dee783d733aac17b9508b452Andreas Huber ++ptr; 378f933441648ef6a71dee783d733aac17b9508b452Andreas Huber --size; 379f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 380f933441648ef6a71dee783d733aac17b9508b452Andreas Huber for (size_t i = 0; i < numPictureParameterSets; ++i) { 381f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(size >= 2); 382f933441648ef6a71dee783d733aac17b9508b452Andreas Huber size_t length = U16_AT(ptr); 383f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 384f933441648ef6a71dee783d733aac17b9508b452Andreas Huber ptr += 2; 385f933441648ef6a71dee783d733aac17b9508b452Andreas Huber size -= 2; 386f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 387f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(size >= length); 388f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 389f933441648ef6a71dee783d733aac17b9508b452Andreas Huber memcpy(buffer->data() + buffer->size(), "\x00\x00\x00\x01", 4); 390f933441648ef6a71dee783d733aac17b9508b452Andreas Huber memcpy(buffer->data() + buffer->size() + 4, ptr, length); 391f933441648ef6a71dee783d733aac17b9508b452Andreas Huber buffer->setRange(0, buffer->size() + 4 + length); 392f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 393f933441648ef6a71dee783d733aac17b9508b452Andreas Huber ptr += length; 394f933441648ef6a71dee783d733aac17b9508b452Andreas Huber size -= length; 395f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 396f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 397f933441648ef6a71dee783d733aac17b9508b452Andreas Huber buffer->meta()->setInt32("csd", true); 398f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mCSD.push(buffer); 399f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 400bf6c85a013fb14960bac147c1ffd0a02a8d5f148Andreas Huber msg->setBuffer("csd", buffer); 401f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } else if (meta->findData(kKeyESDS, &type, &data, &size)) { 402f933441648ef6a71dee783d733aac17b9508b452Andreas Huber ESDS esds((const char *)data, size); 403f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK_EQ(esds.InitCheck(), (status_t)OK); 404f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 405f933441648ef6a71dee783d733aac17b9508b452Andreas Huber const void *codec_specific_data; 406f933441648ef6a71dee783d733aac17b9508b452Andreas Huber size_t codec_specific_data_size; 407f933441648ef6a71dee783d733aac17b9508b452Andreas Huber esds.getCodecSpecificInfo( 408f933441648ef6a71dee783d733aac17b9508b452Andreas Huber &codec_specific_data, &codec_specific_data_size); 409f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 410f933441648ef6a71dee783d733aac17b9508b452Andreas Huber sp<ABuffer> buffer = new ABuffer(codec_specific_data_size); 411f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 412f933441648ef6a71dee783d733aac17b9508b452Andreas Huber memcpy(buffer->data(), codec_specific_data, 413f933441648ef6a71dee783d733aac17b9508b452Andreas Huber codec_specific_data_size); 414f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 415f933441648ef6a71dee783d733aac17b9508b452Andreas Huber buffer->meta()->setInt32("csd", true); 416f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mCSD.push(buffer); 417729de186450f78c099637e1fce743fe531862c52Andreas Huber } else if (meta->findData(kKeyVorbisInfo, &type, &data, &size)) { 418729de186450f78c099637e1fce743fe531862c52Andreas Huber sp<ABuffer> buffer = new ABuffer(size); 419729de186450f78c099637e1fce743fe531862c52Andreas Huber memcpy(buffer->data(), data, size); 420729de186450f78c099637e1fce743fe531862c52Andreas Huber 421729de186450f78c099637e1fce743fe531862c52Andreas Huber buffer->meta()->setInt32("csd", true); 422729de186450f78c099637e1fce743fe531862c52Andreas Huber mCSD.push(buffer); 423729de186450f78c099637e1fce743fe531862c52Andreas Huber 424729de186450f78c099637e1fce743fe531862c52Andreas Huber CHECK(meta->findData(kKeyVorbisBooks, &type, &data, &size)); 425729de186450f78c099637e1fce743fe531862c52Andreas Huber 426729de186450f78c099637e1fce743fe531862c52Andreas Huber buffer = new ABuffer(size); 427729de186450f78c099637e1fce743fe531862c52Andreas Huber memcpy(buffer->data(), data, size); 428729de186450f78c099637e1fce743fe531862c52Andreas Huber 429729de186450f78c099637e1fce743fe531862c52Andreas Huber buffer->meta()->setInt32("csd", true); 430729de186450f78c099637e1fce743fe531862c52Andreas Huber mCSD.push(buffer); 431f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 432f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 433f933441648ef6a71dee783d733aac17b9508b452Andreas Huber int32_t maxInputSize; 434f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (meta->findInt32(kKeyMaxInputSize, &maxInputSize)) { 435f933441648ef6a71dee783d733aac17b9508b452Andreas Huber msg->setInt32("max-input-size", maxInputSize); 436f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 437f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 438f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return msg; 439f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 440f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 441f933441648ef6a71dee783d733aac17b9508b452Andreas Huber void onFillThisBuffer(const sp<AMessage> &msg) { 442f933441648ef6a71dee783d733aac17b9508b452Andreas Huber sp<AMessage> reply; 443f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(msg->findMessage("reply", &reply)); 444f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 445afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber if (mSource == NULL || mSeekState == SEEK_FLUSHING) { 446afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber reply->setInt32("err", ERROR_END_OF_STREAM); 447f933441648ef6a71dee783d733aac17b9508b452Andreas Huber reply->post(); 448f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return; 449f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 450f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 451bf6c85a013fb14960bac147c1ffd0a02a8d5f148Andreas Huber sp<ABuffer> outBuffer; 452bf6c85a013fb14960bac147c1ffd0a02a8d5f148Andreas Huber CHECK(msg->findBuffer("buffer", &outBuffer)); 453f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 454f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (mCSDIndex < mCSD.size()) { 455f933441648ef6a71dee783d733aac17b9508b452Andreas Huber outBuffer = mCSD.editItemAt(mCSDIndex++); 456f933441648ef6a71dee783d733aac17b9508b452Andreas Huber outBuffer->meta()->setInt64("timeUs", 0); 457f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } else { 458f933441648ef6a71dee783d733aac17b9508b452Andreas Huber size_t sizeLeft = outBuffer->capacity(); 459f933441648ef6a71dee783d733aac17b9508b452Andreas Huber outBuffer->setRange(0, 0); 460f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 461f933441648ef6a71dee783d733aac17b9508b452Andreas Huber int32_t n = 0; 462f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 463f933441648ef6a71dee783d733aac17b9508b452Andreas Huber for (;;) { 464f933441648ef6a71dee783d733aac17b9508b452Andreas Huber MediaBuffer *inBuffer; 465f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 466f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (mLeftOverBuffer != NULL) { 467f933441648ef6a71dee783d733aac17b9508b452Andreas Huber inBuffer = mLeftOverBuffer; 468f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mLeftOverBuffer = NULL; 469f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } else if (mFinalResult != OK) { 470f933441648ef6a71dee783d733aac17b9508b452Andreas Huber break; 471f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } else { 472f933441648ef6a71dee783d733aac17b9508b452Andreas Huber MediaSource::ReadOptions options; 473f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (mSeekState == SEEK_FLUSH_COMPLETED) { 474f933441648ef6a71dee783d733aac17b9508b452Andreas Huber options.setSeekTo(mSeekTimeUs); 475f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mSeekState = SEEK_NONE; 476f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 477f933441648ef6a71dee783d733aac17b9508b452Andreas Huber status_t err = mSource->read(&inBuffer, &options); 478f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 479f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (err != OK) { 480f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mFinalResult = err; 481f933441648ef6a71dee783d733aac17b9508b452Andreas Huber break; 482f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 483f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 484f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 485729de186450f78c099637e1fce743fe531862c52Andreas Huber size_t sizeNeeded = inBuffer->range_length(); 486729de186450f78c099637e1fce743fe531862c52Andreas Huber if (mIsVorbis) { 487729de186450f78c099637e1fce743fe531862c52Andreas Huber // Vorbis data is suffixed with the number of 488729de186450f78c099637e1fce743fe531862c52Andreas Huber // valid samples on the page. 489729de186450f78c099637e1fce743fe531862c52Andreas Huber sizeNeeded += sizeof(int32_t); 490729de186450f78c099637e1fce743fe531862c52Andreas Huber } 491729de186450f78c099637e1fce743fe531862c52Andreas Huber 492729de186450f78c099637e1fce743fe531862c52Andreas Huber if (sizeNeeded > sizeLeft) { 493f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (outBuffer->size() == 0) { 49429357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("Unable to fit even a single input buffer of size %d.", 495729de186450f78c099637e1fce743fe531862c52Andreas Huber sizeNeeded); 496f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 497f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK_GT(outBuffer->size(), 0u); 498f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 499f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mLeftOverBuffer = inBuffer; 500f933441648ef6a71dee783d733aac17b9508b452Andreas Huber break; 501f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 502f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 503f933441648ef6a71dee783d733aac17b9508b452Andreas Huber ++n; 504f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 505f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (outBuffer->size() == 0) { 506f933441648ef6a71dee783d733aac17b9508b452Andreas Huber int64_t timeUs; 507f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(inBuffer->meta_data()->findInt64(kKeyTime, &timeUs)); 508f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 509f933441648ef6a71dee783d733aac17b9508b452Andreas Huber outBuffer->meta()->setInt64("timeUs", timeUs); 510f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 511f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 512f933441648ef6a71dee783d733aac17b9508b452Andreas Huber memcpy(outBuffer->data() + outBuffer->size(), 513f933441648ef6a71dee783d733aac17b9508b452Andreas Huber (const uint8_t *)inBuffer->data() 514f933441648ef6a71dee783d733aac17b9508b452Andreas Huber + inBuffer->range_offset(), 515f933441648ef6a71dee783d733aac17b9508b452Andreas Huber inBuffer->range_length()); 516f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 517729de186450f78c099637e1fce743fe531862c52Andreas Huber if (mIsVorbis) { 518729de186450f78c099637e1fce743fe531862c52Andreas Huber int32_t numPageSamples; 519729de186450f78c099637e1fce743fe531862c52Andreas Huber if (!inBuffer->meta_data()->findInt32( 520729de186450f78c099637e1fce743fe531862c52Andreas Huber kKeyValidSamples, &numPageSamples)) { 521729de186450f78c099637e1fce743fe531862c52Andreas Huber numPageSamples = -1; 522729de186450f78c099637e1fce743fe531862c52Andreas Huber } 523729de186450f78c099637e1fce743fe531862c52Andreas Huber 524729de186450f78c099637e1fce743fe531862c52Andreas Huber memcpy(outBuffer->data() 525729de186450f78c099637e1fce743fe531862c52Andreas Huber + outBuffer->size() + inBuffer->range_length(), 526729de186450f78c099637e1fce743fe531862c52Andreas Huber &numPageSamples, sizeof(numPageSamples)); 527729de186450f78c099637e1fce743fe531862c52Andreas Huber } 528729de186450f78c099637e1fce743fe531862c52Andreas Huber 529f933441648ef6a71dee783d733aac17b9508b452Andreas Huber outBuffer->setRange( 530729de186450f78c099637e1fce743fe531862c52Andreas Huber 0, outBuffer->size() + sizeNeeded); 531f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 532729de186450f78c099637e1fce743fe531862c52Andreas Huber sizeLeft -= sizeNeeded; 533f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 534f933441648ef6a71dee783d733aac17b9508b452Andreas Huber inBuffer->release(); 535f933441648ef6a71dee783d733aac17b9508b452Andreas Huber inBuffer = NULL; 536f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 5371065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber break; // Don't coalesce 538f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 539f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 5403856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("coalesced %d input buffers", n); 541f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 542f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (outBuffer->size() == 0) { 543f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK_NE(mFinalResult, (status_t)OK); 544f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 545f933441648ef6a71dee783d733aac17b9508b452Andreas Huber reply->setInt32("err", mFinalResult); 546f933441648ef6a71dee783d733aac17b9508b452Andreas Huber reply->post(); 547f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return; 548f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 549f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 550f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 551bf6c85a013fb14960bac147c1ffd0a02a8d5f148Andreas Huber reply->setBuffer("buffer", outBuffer); 552f933441648ef6a71dee783d733aac17b9508b452Andreas Huber reply->post(); 553f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 554f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 555f933441648ef6a71dee783d733aac17b9508b452Andreas Huber void onDrainThisBuffer(const sp<AMessage> &msg) { 556bf6c85a013fb14960bac147c1ffd0a02a8d5f148Andreas Huber sp<ABuffer> buffer; 557bf6c85a013fb14960bac147c1ffd0a02a8d5f148Andreas Huber CHECK(msg->findBuffer("buffer", &buffer)); 558f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 559f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mTotalBytesReceived += buffer->size(); 560f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 561f933441648ef6a71dee783d733aac17b9508b452Andreas Huber sp<AMessage> reply; 562f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(msg->findMessage("reply", &reply)); 563f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 5641065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber if (mRenderToSurface) { 5651065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber reply->setInt32("render", 1); 5661065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber } 5671065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber 568f933441648ef6a71dee783d733aac17b9508b452Andreas Huber reply->post(); 569f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 570f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 571f933441648ef6a71dee783d733aac17b9508b452Andreas Huber DISALLOW_EVIL_CONSTRUCTORS(Controller); 572f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}; 573f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 574f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatic void usage(const char *me) { 575f933441648ef6a71dee783d733aac17b9508b452Andreas Huber fprintf(stderr, "usage: %s\n", me); 576f933441648ef6a71dee783d733aac17b9508b452Andreas Huber fprintf(stderr, " -h(elp)\n"); 577f933441648ef6a71dee783d733aac17b9508b452Andreas Huber fprintf(stderr, " -a(udio)\n"); 578f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 579f933441648ef6a71dee783d733aac17b9508b452Andreas Huber fprintf(stderr, 5801065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber " -S(urface) Allocate output buffers on a surface.\n" 5811065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber " -R(ender) Render surface-allocated buffers.\n"); 582f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 583f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 584f933441648ef6a71dee783d733aac17b9508b452Andreas Huberint main(int argc, char **argv) { 585f933441648ef6a71dee783d733aac17b9508b452Andreas Huber android::ProcessState::self()->startThreadPool(); 586f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 587f933441648ef6a71dee783d733aac17b9508b452Andreas Huber bool decodeAudio = false; 588f933441648ef6a71dee783d733aac17b9508b452Andreas Huber bool useSurface = false; 5891065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber bool renderToSurface = false; 590f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 591f933441648ef6a71dee783d733aac17b9508b452Andreas Huber int res; 5921065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber while ((res = getopt(argc, argv, "haSR")) >= 0) { 593f933441648ef6a71dee783d733aac17b9508b452Andreas Huber switch (res) { 594f933441648ef6a71dee783d733aac17b9508b452Andreas Huber case 'a': 595f933441648ef6a71dee783d733aac17b9508b452Andreas Huber decodeAudio = true; 596f933441648ef6a71dee783d733aac17b9508b452Andreas Huber break; 597f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 5981065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber case 'S': 599f933441648ef6a71dee783d733aac17b9508b452Andreas Huber useSurface = true; 600f933441648ef6a71dee783d733aac17b9508b452Andreas Huber break; 601f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 6021065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber case 'R': 6031065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber renderToSurface = true; 6041065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber break; 6051065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber 606f933441648ef6a71dee783d733aac17b9508b452Andreas Huber case '?': 607f933441648ef6a71dee783d733aac17b9508b452Andreas Huber case 'h': 608f933441648ef6a71dee783d733aac17b9508b452Andreas Huber default: 609f933441648ef6a71dee783d733aac17b9508b452Andreas Huber { 610f933441648ef6a71dee783d733aac17b9508b452Andreas Huber usage(argv[0]); 611f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return 1; 612f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 613f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 614f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 615f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 616f933441648ef6a71dee783d733aac17b9508b452Andreas Huber argc -= optind; 617f933441648ef6a71dee783d733aac17b9508b452Andreas Huber argv += optind; 618f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 619f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (argc != 1) { 620f933441648ef6a71dee783d733aac17b9508b452Andreas Huber usage(argv[-optind]); 621f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return 1; 622f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 623f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 624f933441648ef6a71dee783d733aac17b9508b452Andreas Huber DataSource::RegisterDefaultSniffers(); 625f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 626f933441648ef6a71dee783d733aac17b9508b452Andreas Huber sp<ALooper> looper = new ALooper; 627f933441648ef6a71dee783d733aac17b9508b452Andreas Huber looper->setName("sf2"); 628f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 629f933441648ef6a71dee783d733aac17b9508b452Andreas Huber sp<SurfaceComposerClient> composerClient; 630f933441648ef6a71dee783d733aac17b9508b452Andreas Huber sp<SurfaceControl> control; 631f933441648ef6a71dee783d733aac17b9508b452Andreas Huber sp<Surface> surface; 632f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 633f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (!decodeAudio && useSurface) { 634f933441648ef6a71dee783d733aac17b9508b452Andreas Huber composerClient = new SurfaceComposerClient; 635f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK_EQ(composerClient->initCheck(), (status_t)OK); 636f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 637f933441648ef6a71dee783d733aac17b9508b452Andreas Huber control = composerClient->createSurface( 638f933441648ef6a71dee783d733aac17b9508b452Andreas Huber String8("A Surface"), 639f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1280, 640f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 800, 641f933441648ef6a71dee783d733aac17b9508b452Andreas Huber PIXEL_FORMAT_RGB_565, 642f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 0); 643f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 644f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(control != NULL); 645f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(control->isValid()); 646f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 6472df788fb0c402938f827bf9c9ce2ca3ab1dcd464Mathias Agopian SurfaceComposerClient::openGlobalTransaction(); 64893d5ab693626fa2700375e838e4bb90e4d50e605Andreas Huber CHECK_EQ(control->setLayer(INT_MAX), (status_t)OK); 649f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK_EQ(control->show(), (status_t)OK); 6502df788fb0c402938f827bf9c9ce2ca3ab1dcd464Mathias Agopian SurfaceComposerClient::closeGlobalTransaction(); 651f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 652f933441648ef6a71dee783d733aac17b9508b452Andreas Huber surface = control->getSurface(); 653f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(surface != NULL); 65493d5ab693626fa2700375e838e4bb90e4d50e605Andreas Huber 65593d5ab693626fa2700375e838e4bb90e4d50e605Andreas Huber CHECK_EQ((status_t)OK, 65693d5ab693626fa2700375e838e4bb90e4d50e605Andreas Huber native_window_api_connect( 65793d5ab693626fa2700375e838e4bb90e4d50e605Andreas Huber surface.get(), NATIVE_WINDOW_API_MEDIA)); 658f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 659f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 6601065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber sp<Controller> controller = 6611065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber new Controller(argv[0], decodeAudio, surface, renderToSurface); 6621065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber 663f933441648ef6a71dee783d733aac17b9508b452Andreas Huber looper->registerHandler(controller); 664f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 665a2354479716db40d865c597dc572ea83573caac2Marco Nelissen signal(SIGINT, mysighandler); 666a2354479716db40d865c597dc572ea83573caac2Marco Nelissen 667f933441648ef6a71dee783d733aac17b9508b452Andreas Huber controller->startAsync(); 668f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 669f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK_EQ(looper->start(true /* runOnCallingThread */), (status_t)OK); 670f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 671f933441648ef6a71dee783d733aac17b9508b452Andreas Huber looper->unregisterHandler(controller->id()); 672f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 673f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (!decodeAudio && useSurface) { 67493d5ab693626fa2700375e838e4bb90e4d50e605Andreas Huber CHECK_EQ((status_t)OK, 67593d5ab693626fa2700375e838e4bb90e4d50e605Andreas Huber native_window_api_disconnect( 67693d5ab693626fa2700375e838e4bb90e4d50e605Andreas Huber surface.get(), NATIVE_WINDOW_API_MEDIA)); 67793d5ab693626fa2700375e838e4bb90e4d50e605Andreas Huber 678f933441648ef6a71dee783d733aac17b9508b452Andreas Huber composerClient->dispose(); 679f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 680f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 681f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return 0; 682f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 683f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 684