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> 41f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/Utils.h> 42f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 43df712ea86e6350f7005a02ab0e1c60c28a343ed0Mathias Agopian#include <gui/SurfaceComposerClient.h> 441de1e25cba872bd4c077c2e394f8ca9c70b65856Lajos Molnar#include <gui/Surface.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() { 751d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar (new AMessage(kWhatStart, this))->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(); 1031d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar (new AMessage(kWhatStop, this))->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( 1521d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar new AMessage(kWhatCodecNotify, this)); 153f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 154f933441648ef6a71dee783d733aac17b9508b452Andreas Huber sp<AMessage> format = makeFormat(mSource->getFormat()); 155f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 156f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (mSurface != NULL) { 1571de1e25cba872bd4c077c2e394f8ca9c70b65856Lajos Molnar format->setObject("surface", mSurface); 158f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 159f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 160f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mCodec->initiateSetup(format); 161f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 162f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mCSDIndex = 0; 163f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mStartTimeUs = ALooper::GetNowUs(); 164f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mNumOutputBuffersReceived = 0; 165f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mTotalBytesReceived = 0; 166f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mLeftOverBuffer = NULL; 167f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mFinalResult = OK; 168f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mSeekState = SEEK_NONE; 169f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1701d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar // (new AMessage(kWhatSeek, this))->post(5000000ll); 171f933441648ef6a71dee783d733aac17b9508b452Andreas Huber break; 172f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 173f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 174f933441648ef6a71dee783d733aac17b9508b452Andreas Huber case kWhatSeek: 175f933441648ef6a71dee783d733aac17b9508b452Andreas Huber { 176f933441648ef6a71dee783d733aac17b9508b452Andreas Huber printf("+"); 177f933441648ef6a71dee783d733aac17b9508b452Andreas Huber fflush(stdout); 178f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 179f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(mSeekState == SEEK_NONE 180f933441648ef6a71dee783d733aac17b9508b452Andreas Huber || mSeekState == SEEK_FLUSH_COMPLETED); 181f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 182f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (mLeftOverBuffer != NULL) { 183f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mLeftOverBuffer->release(); 184f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mLeftOverBuffer = NULL; 185f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 186f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 187f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mSeekState = SEEK_FLUSHING; 188f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mSeekTimeUs = 30000000ll; 189f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 190f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mCodec->signalFlush(); 191f933441648ef6a71dee783d733aac17b9508b452Andreas Huber break; 192f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 193f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 194f933441648ef6a71dee783d733aac17b9508b452Andreas Huber case kWhatStop: 195f933441648ef6a71dee783d733aac17b9508b452Andreas Huber { 196f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (mLeftOverBuffer != NULL) { 197f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mLeftOverBuffer->release(); 198f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mLeftOverBuffer = NULL; 199f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 200f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 201f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK_EQ(mSource->stop(), (status_t)OK); 202f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mSource.clear(); 203f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 204f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mCodec->initiateShutdown(); 205f933441648ef6a71dee783d733aac17b9508b452Andreas Huber break; 206f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 207f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 208f933441648ef6a71dee783d733aac17b9508b452Andreas Huber case kWhatCodecNotify: 209f933441648ef6a71dee783d733aac17b9508b452Andreas Huber { 210f933441648ef6a71dee783d733aac17b9508b452Andreas Huber int32_t what; 211f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(msg->findInt32("what", &what)); 212f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 213d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar if (what == CodecBase::kWhatFillThisBuffer) { 214f933441648ef6a71dee783d733aac17b9508b452Andreas Huber onFillThisBuffer(msg); 215d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar } else if (what == CodecBase::kWhatDrainThisBuffer) { 216f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if ((mNumOutputBuffersReceived++ % 16) == 0) { 217f933441648ef6a71dee783d733aac17b9508b452Andreas Huber printf("."); 218f933441648ef6a71dee783d733aac17b9508b452Andreas Huber fflush(stdout); 219f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 220f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 221f933441648ef6a71dee783d733aac17b9508b452Andreas Huber onDrainThisBuffer(msg); 222d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar } else if (what == CodecBase::kWhatEOS 223d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar || what == CodecBase::kWhatError) { 224d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar printf((what == CodecBase::kWhatEOS) ? "$\n" : "E\n"); 225f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 226a2354479716db40d865c597dc572ea83573caac2Marco Nelissen printStatistics(); 2271d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar (new AMessage(kWhatStop, this))->post(); 228d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar } else if (what == CodecBase::kWhatFlushCompleted) { 229f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mSeekState = SEEK_FLUSH_COMPLETED; 230f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mCodec->signalResume(); 231f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 2321d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar (new AMessage(kWhatSeek, this))->post(5000000ll); 233d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar } else if (what == CodecBase::kWhatOutputFormatChanged) { 234d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar } else if (what == CodecBase::kWhatShutdownCompleted) { 235f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mDecodeLooper->unregisterHandler(mCodec->id()); 236f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 237f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (mDecodeLooper != looper()) { 238f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mDecodeLooper->stop(); 239f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 240f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 241f933441648ef6a71dee783d733aac17b9508b452Andreas Huber looper()->stop(); 242f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 243f933441648ef6a71dee783d733aac17b9508b452Andreas Huber break; 244f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 245f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 246f933441648ef6a71dee783d733aac17b9508b452Andreas Huber default: 247f933441648ef6a71dee783d733aac17b9508b452Andreas Huber TRESPASS(); 248f933441648ef6a71dee783d733aac17b9508b452Andreas Huber break; 249f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 250f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 251f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 252f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate: 253f933441648ef6a71dee783d733aac17b9508b452Andreas Huber enum { 254f933441648ef6a71dee783d733aac17b9508b452Andreas Huber kWhatStart = 'strt', 255f933441648ef6a71dee783d733aac17b9508b452Andreas Huber kWhatStop = 'stop', 256f933441648ef6a71dee783d733aac17b9508b452Andreas Huber kWhatCodecNotify = 'noti', 257f933441648ef6a71dee783d733aac17b9508b452Andreas Huber kWhatSeek = 'seek', 258f933441648ef6a71dee783d733aac17b9508b452Andreas Huber }; 259f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 260f933441648ef6a71dee783d733aac17b9508b452Andreas Huber sp<ALooper> mDecodeLooper; 261f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 262f933441648ef6a71dee783d733aac17b9508b452Andreas Huber AString mURI; 263f933441648ef6a71dee783d733aac17b9508b452Andreas Huber bool mDecodeAudio; 264f933441648ef6a71dee783d733aac17b9508b452Andreas Huber sp<Surface> mSurface; 2651065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber bool mRenderToSurface; 266f933441648ef6a71dee783d733aac17b9508b452Andreas Huber sp<ACodec> mCodec; 267f933441648ef6a71dee783d733aac17b9508b452Andreas Huber sp<MediaSource> mSource; 268729de186450f78c099637e1fce743fe531862c52Andreas Huber bool mIsVorbis; 269f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 270f933441648ef6a71dee783d733aac17b9508b452Andreas Huber Vector<sp<ABuffer> > mCSD; 271f933441648ef6a71dee783d733aac17b9508b452Andreas Huber size_t mCSDIndex; 272f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 273f933441648ef6a71dee783d733aac17b9508b452Andreas Huber MediaBuffer *mLeftOverBuffer; 274f933441648ef6a71dee783d733aac17b9508b452Andreas Huber status_t mFinalResult; 275f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 276f933441648ef6a71dee783d733aac17b9508b452Andreas Huber int64_t mStartTimeUs; 277f933441648ef6a71dee783d733aac17b9508b452Andreas Huber int32_t mNumOutputBuffersReceived; 278f933441648ef6a71dee783d733aac17b9508b452Andreas Huber int64_t mTotalBytesReceived; 279f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 280f933441648ef6a71dee783d733aac17b9508b452Andreas Huber enum SeekState { 281f933441648ef6a71dee783d733aac17b9508b452Andreas Huber SEEK_NONE, 282f933441648ef6a71dee783d733aac17b9508b452Andreas Huber SEEK_FLUSHING, 283f933441648ef6a71dee783d733aac17b9508b452Andreas Huber SEEK_FLUSH_COMPLETED, 284f933441648ef6a71dee783d733aac17b9508b452Andreas Huber }; 285f933441648ef6a71dee783d733aac17b9508b452Andreas Huber SeekState mSeekState; 286f933441648ef6a71dee783d733aac17b9508b452Andreas Huber int64_t mSeekTimeUs; 287f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 288f933441648ef6a71dee783d733aac17b9508b452Andreas Huber sp<AMessage> makeFormat(const sp<MetaData> &meta) { 289f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(mCSD.isEmpty()); 290f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 291f933441648ef6a71dee783d733aac17b9508b452Andreas Huber const char *mime; 292f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(meta->findCString(kKeyMIMEType, &mime)); 293f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 294f933441648ef6a71dee783d733aac17b9508b452Andreas Huber sp<AMessage> msg = new AMessage; 295f933441648ef6a71dee783d733aac17b9508b452Andreas Huber msg->setString("mime", mime); 296f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 297f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (!strncasecmp("video/", mime, 6)) { 298f933441648ef6a71dee783d733aac17b9508b452Andreas Huber int32_t width, height; 299f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(meta->findInt32(kKeyWidth, &width)); 300f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(meta->findInt32(kKeyHeight, &height)); 301f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 302f933441648ef6a71dee783d733aac17b9508b452Andreas Huber msg->setInt32("width", width); 303f933441648ef6a71dee783d733aac17b9508b452Andreas Huber msg->setInt32("height", height); 304f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } else { 305f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(!strncasecmp("audio/", mime, 6)); 306f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 307f933441648ef6a71dee783d733aac17b9508b452Andreas Huber int32_t numChannels, sampleRate; 308f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(meta->findInt32(kKeyChannelCount, &numChannels)); 309f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(meta->findInt32(kKeySampleRate, &sampleRate)); 310f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 311f933441648ef6a71dee783d733aac17b9508b452Andreas Huber msg->setInt32("channel-count", numChannels); 312f933441648ef6a71dee783d733aac17b9508b452Andreas Huber msg->setInt32("sample-rate", sampleRate); 313ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber 314ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber int32_t isADTS; 315ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber if (meta->findInt32(kKeyIsADTS, &isADTS) && isADTS != 0) { 316ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber msg->setInt32("is-adts", true); 317ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber } 318f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 319f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 320f933441648ef6a71dee783d733aac17b9508b452Andreas Huber uint32_t type; 321f933441648ef6a71dee783d733aac17b9508b452Andreas Huber const void *data; 322f933441648ef6a71dee783d733aac17b9508b452Andreas Huber size_t size; 323f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (meta->findData(kKeyAVCC, &type, &data, &size)) { 324f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // Parse the AVCDecoderConfigurationRecord 325f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 326f933441648ef6a71dee783d733aac17b9508b452Andreas Huber const uint8_t *ptr = (const uint8_t *)data; 327f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 328f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(size >= 7); 329f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK_EQ((unsigned)ptr[0], 1u); // configurationVersion == 1 33031de88566257d5546cf4eee9064d96926a4b0c24Lajos Molnar uint8_t profile __unused = ptr[1]; 33131de88566257d5546cf4eee9064d96926a4b0c24Lajos Molnar uint8_t level __unused = ptr[3]; 332f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 333f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // There is decodable content out there that fails the following 334f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // assertion, let's be lenient for now... 335f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // CHECK((ptr[4] >> 2) == 0x3f); // reserved 336f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 33731de88566257d5546cf4eee9064d96926a4b0c24Lajos Molnar size_t lengthSize __unused = 1 + (ptr[4] & 3); 338f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 339f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // commented out check below as H264_QVGA_500_NO_AUDIO.3gp 340f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // violates it... 341f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // CHECK((ptr[5] >> 5) == 7); // reserved 342f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 343f933441648ef6a71dee783d733aac17b9508b452Andreas Huber size_t numSeqParameterSets = ptr[5] & 31; 344f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 345f933441648ef6a71dee783d733aac17b9508b452Andreas Huber ptr += 6; 346f933441648ef6a71dee783d733aac17b9508b452Andreas Huber size -= 6; 347f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 348f933441648ef6a71dee783d733aac17b9508b452Andreas Huber sp<ABuffer> buffer = new ABuffer(1024); 349f933441648ef6a71dee783d733aac17b9508b452Andreas Huber buffer->setRange(0, 0); 350f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 351f933441648ef6a71dee783d733aac17b9508b452Andreas Huber for (size_t i = 0; i < numSeqParameterSets; ++i) { 352f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(size >= 2); 353f933441648ef6a71dee783d733aac17b9508b452Andreas Huber size_t length = U16_AT(ptr); 354f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 355f933441648ef6a71dee783d733aac17b9508b452Andreas Huber ptr += 2; 356f933441648ef6a71dee783d733aac17b9508b452Andreas Huber size -= 2; 357f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 358f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(size >= length); 359f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 360f933441648ef6a71dee783d733aac17b9508b452Andreas Huber memcpy(buffer->data() + buffer->size(), "\x00\x00\x00\x01", 4); 361f933441648ef6a71dee783d733aac17b9508b452Andreas Huber memcpy(buffer->data() + buffer->size() + 4, ptr, length); 362f933441648ef6a71dee783d733aac17b9508b452Andreas Huber buffer->setRange(0, buffer->size() + 4 + length); 363f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 364f933441648ef6a71dee783d733aac17b9508b452Andreas Huber ptr += length; 365f933441648ef6a71dee783d733aac17b9508b452Andreas Huber size -= length; 366f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 367f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 368f933441648ef6a71dee783d733aac17b9508b452Andreas Huber buffer->meta()->setInt32("csd", true); 369f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mCSD.push(buffer); 370f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 371f933441648ef6a71dee783d733aac17b9508b452Andreas Huber buffer = new ABuffer(1024); 372f933441648ef6a71dee783d733aac17b9508b452Andreas Huber buffer->setRange(0, 0); 373f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 374f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(size >= 1); 375f933441648ef6a71dee783d733aac17b9508b452Andreas Huber size_t numPictureParameterSets = *ptr; 376f933441648ef6a71dee783d733aac17b9508b452Andreas Huber ++ptr; 377f933441648ef6a71dee783d733aac17b9508b452Andreas Huber --size; 378f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 379f933441648ef6a71dee783d733aac17b9508b452Andreas Huber for (size_t i = 0; i < numPictureParameterSets; ++i) { 380f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(size >= 2); 381f933441648ef6a71dee783d733aac17b9508b452Andreas Huber size_t length = U16_AT(ptr); 382f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 383f933441648ef6a71dee783d733aac17b9508b452Andreas Huber ptr += 2; 384f933441648ef6a71dee783d733aac17b9508b452Andreas Huber size -= 2; 385f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 386f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(size >= length); 387f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 388f933441648ef6a71dee783d733aac17b9508b452Andreas Huber memcpy(buffer->data() + buffer->size(), "\x00\x00\x00\x01", 4); 389f933441648ef6a71dee783d733aac17b9508b452Andreas Huber memcpy(buffer->data() + buffer->size() + 4, ptr, length); 390f933441648ef6a71dee783d733aac17b9508b452Andreas Huber buffer->setRange(0, buffer->size() + 4 + length); 391f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 392f933441648ef6a71dee783d733aac17b9508b452Andreas Huber ptr += length; 393f933441648ef6a71dee783d733aac17b9508b452Andreas Huber size -= length; 394f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 395f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 396f933441648ef6a71dee783d733aac17b9508b452Andreas Huber buffer->meta()->setInt32("csd", true); 397f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mCSD.push(buffer); 398f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 399bf6c85a013fb14960bac147c1ffd0a02a8d5f148Andreas Huber msg->setBuffer("csd", buffer); 400f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } else if (meta->findData(kKeyESDS, &type, &data, &size)) { 401f933441648ef6a71dee783d733aac17b9508b452Andreas Huber ESDS esds((const char *)data, size); 402f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK_EQ(esds.InitCheck(), (status_t)OK); 403f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 404f933441648ef6a71dee783d733aac17b9508b452Andreas Huber const void *codec_specific_data; 405f933441648ef6a71dee783d733aac17b9508b452Andreas Huber size_t codec_specific_data_size; 406f933441648ef6a71dee783d733aac17b9508b452Andreas Huber esds.getCodecSpecificInfo( 407f933441648ef6a71dee783d733aac17b9508b452Andreas Huber &codec_specific_data, &codec_specific_data_size); 408f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 409f933441648ef6a71dee783d733aac17b9508b452Andreas Huber sp<ABuffer> buffer = new ABuffer(codec_specific_data_size); 410f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 411f933441648ef6a71dee783d733aac17b9508b452Andreas Huber memcpy(buffer->data(), codec_specific_data, 412f933441648ef6a71dee783d733aac17b9508b452Andreas Huber codec_specific_data_size); 413f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 414f933441648ef6a71dee783d733aac17b9508b452Andreas Huber buffer->meta()->setInt32("csd", true); 415f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mCSD.push(buffer); 416729de186450f78c099637e1fce743fe531862c52Andreas Huber } else if (meta->findData(kKeyVorbisInfo, &type, &data, &size)) { 417729de186450f78c099637e1fce743fe531862c52Andreas Huber sp<ABuffer> buffer = new ABuffer(size); 418729de186450f78c099637e1fce743fe531862c52Andreas Huber memcpy(buffer->data(), data, size); 419729de186450f78c099637e1fce743fe531862c52Andreas Huber 420729de186450f78c099637e1fce743fe531862c52Andreas Huber buffer->meta()->setInt32("csd", true); 421729de186450f78c099637e1fce743fe531862c52Andreas Huber mCSD.push(buffer); 422729de186450f78c099637e1fce743fe531862c52Andreas Huber 423729de186450f78c099637e1fce743fe531862c52Andreas Huber CHECK(meta->findData(kKeyVorbisBooks, &type, &data, &size)); 424729de186450f78c099637e1fce743fe531862c52Andreas Huber 425729de186450f78c099637e1fce743fe531862c52Andreas Huber buffer = new ABuffer(size); 426729de186450f78c099637e1fce743fe531862c52Andreas Huber memcpy(buffer->data(), data, size); 427729de186450f78c099637e1fce743fe531862c52Andreas Huber 428729de186450f78c099637e1fce743fe531862c52Andreas Huber buffer->meta()->setInt32("csd", true); 429729de186450f78c099637e1fce743fe531862c52Andreas Huber mCSD.push(buffer); 430f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 431f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 432f933441648ef6a71dee783d733aac17b9508b452Andreas Huber int32_t maxInputSize; 433f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (meta->findInt32(kKeyMaxInputSize, &maxInputSize)) { 434f933441648ef6a71dee783d733aac17b9508b452Andreas Huber msg->setInt32("max-input-size", maxInputSize); 435f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 436f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 437f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return msg; 438f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 439f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 440f933441648ef6a71dee783d733aac17b9508b452Andreas Huber void onFillThisBuffer(const sp<AMessage> &msg) { 441f933441648ef6a71dee783d733aac17b9508b452Andreas Huber sp<AMessage> reply; 442f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(msg->findMessage("reply", &reply)); 443f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 444afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber if (mSource == NULL || mSeekState == SEEK_FLUSHING) { 445afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber reply->setInt32("err", ERROR_END_OF_STREAM); 446f933441648ef6a71dee783d733aac17b9508b452Andreas Huber reply->post(); 447f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return; 448f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 449f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 450bf6c85a013fb14960bac147c1ffd0a02a8d5f148Andreas Huber sp<ABuffer> outBuffer; 451bf6c85a013fb14960bac147c1ffd0a02a8d5f148Andreas Huber CHECK(msg->findBuffer("buffer", &outBuffer)); 452f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 453f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (mCSDIndex < mCSD.size()) { 454f933441648ef6a71dee783d733aac17b9508b452Andreas Huber outBuffer = mCSD.editItemAt(mCSDIndex++); 455f933441648ef6a71dee783d733aac17b9508b452Andreas Huber outBuffer->meta()->setInt64("timeUs", 0); 456f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } else { 457f933441648ef6a71dee783d733aac17b9508b452Andreas Huber size_t sizeLeft = outBuffer->capacity(); 458f933441648ef6a71dee783d733aac17b9508b452Andreas Huber outBuffer->setRange(0, 0); 459f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 460f933441648ef6a71dee783d733aac17b9508b452Andreas Huber int32_t n = 0; 461f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 462f933441648ef6a71dee783d733aac17b9508b452Andreas Huber for (;;) { 463f933441648ef6a71dee783d733aac17b9508b452Andreas Huber MediaBuffer *inBuffer; 464f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 465f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (mLeftOverBuffer != NULL) { 466f933441648ef6a71dee783d733aac17b9508b452Andreas Huber inBuffer = mLeftOverBuffer; 467f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mLeftOverBuffer = NULL; 468f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } else if (mFinalResult != OK) { 469f933441648ef6a71dee783d733aac17b9508b452Andreas Huber break; 470f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } else { 471f933441648ef6a71dee783d733aac17b9508b452Andreas Huber MediaSource::ReadOptions options; 472f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (mSeekState == SEEK_FLUSH_COMPLETED) { 473f933441648ef6a71dee783d733aac17b9508b452Andreas Huber options.setSeekTo(mSeekTimeUs); 474f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mSeekState = SEEK_NONE; 475f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 476f933441648ef6a71dee783d733aac17b9508b452Andreas Huber status_t err = mSource->read(&inBuffer, &options); 477f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 478f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (err != OK) { 479f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mFinalResult = err; 480f933441648ef6a71dee783d733aac17b9508b452Andreas Huber break; 481f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 482f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 483f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 484729de186450f78c099637e1fce743fe531862c52Andreas Huber size_t sizeNeeded = inBuffer->range_length(); 485729de186450f78c099637e1fce743fe531862c52Andreas Huber if (mIsVorbis) { 486729de186450f78c099637e1fce743fe531862c52Andreas Huber // Vorbis data is suffixed with the number of 487729de186450f78c099637e1fce743fe531862c52Andreas Huber // valid samples on the page. 488729de186450f78c099637e1fce743fe531862c52Andreas Huber sizeNeeded += sizeof(int32_t); 489729de186450f78c099637e1fce743fe531862c52Andreas Huber } 490729de186450f78c099637e1fce743fe531862c52Andreas Huber 491729de186450f78c099637e1fce743fe531862c52Andreas Huber if (sizeNeeded > sizeLeft) { 492f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (outBuffer->size() == 0) { 49331de88566257d5546cf4eee9064d96926a4b0c24Lajos Molnar ALOGE("Unable to fit even a single input buffer of size %zu.", 494729de186450f78c099637e1fce743fe531862c52Andreas Huber sizeNeeded); 495f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 496f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK_GT(outBuffer->size(), 0u); 497f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 498f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mLeftOverBuffer = inBuffer; 499f933441648ef6a71dee783d733aac17b9508b452Andreas Huber break; 500f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 501f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 502f933441648ef6a71dee783d733aac17b9508b452Andreas Huber ++n; 503f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 504f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (outBuffer->size() == 0) { 505f933441648ef6a71dee783d733aac17b9508b452Andreas Huber int64_t timeUs; 506f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(inBuffer->meta_data()->findInt64(kKeyTime, &timeUs)); 507f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 508f933441648ef6a71dee783d733aac17b9508b452Andreas Huber outBuffer->meta()->setInt64("timeUs", timeUs); 509f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 510f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 511f933441648ef6a71dee783d733aac17b9508b452Andreas Huber memcpy(outBuffer->data() + outBuffer->size(), 512f933441648ef6a71dee783d733aac17b9508b452Andreas Huber (const uint8_t *)inBuffer->data() 513f933441648ef6a71dee783d733aac17b9508b452Andreas Huber + inBuffer->range_offset(), 514f933441648ef6a71dee783d733aac17b9508b452Andreas Huber inBuffer->range_length()); 515f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 516729de186450f78c099637e1fce743fe531862c52Andreas Huber if (mIsVorbis) { 517729de186450f78c099637e1fce743fe531862c52Andreas Huber int32_t numPageSamples; 518729de186450f78c099637e1fce743fe531862c52Andreas Huber if (!inBuffer->meta_data()->findInt32( 519729de186450f78c099637e1fce743fe531862c52Andreas Huber kKeyValidSamples, &numPageSamples)) { 520729de186450f78c099637e1fce743fe531862c52Andreas Huber numPageSamples = -1; 521729de186450f78c099637e1fce743fe531862c52Andreas Huber } 522729de186450f78c099637e1fce743fe531862c52Andreas Huber 523729de186450f78c099637e1fce743fe531862c52Andreas Huber memcpy(outBuffer->data() 524729de186450f78c099637e1fce743fe531862c52Andreas Huber + outBuffer->size() + inBuffer->range_length(), 525729de186450f78c099637e1fce743fe531862c52Andreas Huber &numPageSamples, sizeof(numPageSamples)); 526729de186450f78c099637e1fce743fe531862c52Andreas Huber } 527729de186450f78c099637e1fce743fe531862c52Andreas Huber 528f933441648ef6a71dee783d733aac17b9508b452Andreas Huber outBuffer->setRange( 529729de186450f78c099637e1fce743fe531862c52Andreas Huber 0, outBuffer->size() + sizeNeeded); 530f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 531729de186450f78c099637e1fce743fe531862c52Andreas Huber sizeLeft -= sizeNeeded; 532f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 533f933441648ef6a71dee783d733aac17b9508b452Andreas Huber inBuffer->release(); 534f933441648ef6a71dee783d733aac17b9508b452Andreas Huber inBuffer = NULL; 535f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 5361065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber break; // Don't coalesce 537f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 538f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 5393856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("coalesced %d input buffers", n); 540f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 541f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (outBuffer->size() == 0) { 542f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK_NE(mFinalResult, (status_t)OK); 543f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 544f933441648ef6a71dee783d733aac17b9508b452Andreas Huber reply->setInt32("err", mFinalResult); 545f933441648ef6a71dee783d733aac17b9508b452Andreas Huber reply->post(); 546f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return; 547f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 548f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 549f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 550bf6c85a013fb14960bac147c1ffd0a02a8d5f148Andreas Huber reply->setBuffer("buffer", outBuffer); 551f933441648ef6a71dee783d733aac17b9508b452Andreas Huber reply->post(); 552f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 553f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 554f933441648ef6a71dee783d733aac17b9508b452Andreas Huber void onDrainThisBuffer(const sp<AMessage> &msg) { 555bf6c85a013fb14960bac147c1ffd0a02a8d5f148Andreas Huber sp<ABuffer> buffer; 556bf6c85a013fb14960bac147c1ffd0a02a8d5f148Andreas Huber CHECK(msg->findBuffer("buffer", &buffer)); 557f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 558f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mTotalBytesReceived += buffer->size(); 559f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 560f933441648ef6a71dee783d733aac17b9508b452Andreas Huber sp<AMessage> reply; 561f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(msg->findMessage("reply", &reply)); 562f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 5631065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber if (mRenderToSurface) { 5641065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber reply->setInt32("render", 1); 5651065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber } 5661065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber 567f933441648ef6a71dee783d733aac17b9508b452Andreas Huber reply->post(); 568f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 569f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 570f933441648ef6a71dee783d733aac17b9508b452Andreas Huber DISALLOW_EVIL_CONSTRUCTORS(Controller); 571f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}; 572f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 573f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatic void usage(const char *me) { 574f933441648ef6a71dee783d733aac17b9508b452Andreas Huber fprintf(stderr, "usage: %s\n", me); 575f933441648ef6a71dee783d733aac17b9508b452Andreas Huber fprintf(stderr, " -h(elp)\n"); 576f933441648ef6a71dee783d733aac17b9508b452Andreas Huber fprintf(stderr, " -a(udio)\n"); 577f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 578f933441648ef6a71dee783d733aac17b9508b452Andreas Huber fprintf(stderr, 5791065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber " -S(urface) Allocate output buffers on a surface.\n" 5801065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber " -R(ender) Render surface-allocated buffers.\n"); 581f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 582f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 583f933441648ef6a71dee783d733aac17b9508b452Andreas Huberint main(int argc, char **argv) { 584f933441648ef6a71dee783d733aac17b9508b452Andreas Huber android::ProcessState::self()->startThreadPool(); 585f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 586f933441648ef6a71dee783d733aac17b9508b452Andreas Huber bool decodeAudio = false; 587f933441648ef6a71dee783d733aac17b9508b452Andreas Huber bool useSurface = false; 5881065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber bool renderToSurface = false; 589f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 590f933441648ef6a71dee783d733aac17b9508b452Andreas Huber int res; 5911065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber while ((res = getopt(argc, argv, "haSR")) >= 0) { 592f933441648ef6a71dee783d733aac17b9508b452Andreas Huber switch (res) { 593f933441648ef6a71dee783d733aac17b9508b452Andreas Huber case 'a': 594f933441648ef6a71dee783d733aac17b9508b452Andreas Huber decodeAudio = true; 595f933441648ef6a71dee783d733aac17b9508b452Andreas Huber break; 596f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 5971065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber case 'S': 598f933441648ef6a71dee783d733aac17b9508b452Andreas Huber useSurface = true; 599f933441648ef6a71dee783d733aac17b9508b452Andreas Huber break; 600f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 6011065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber case 'R': 6021065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber renderToSurface = true; 6031065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber break; 6041065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber 605f933441648ef6a71dee783d733aac17b9508b452Andreas Huber case '?': 606f933441648ef6a71dee783d733aac17b9508b452Andreas Huber case 'h': 607f933441648ef6a71dee783d733aac17b9508b452Andreas Huber default: 608f933441648ef6a71dee783d733aac17b9508b452Andreas Huber { 609f933441648ef6a71dee783d733aac17b9508b452Andreas Huber usage(argv[0]); 610f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return 1; 611f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 612f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 613f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 614f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 615f933441648ef6a71dee783d733aac17b9508b452Andreas Huber argc -= optind; 616f933441648ef6a71dee783d733aac17b9508b452Andreas Huber argv += optind; 617f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 618f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (argc != 1) { 619f933441648ef6a71dee783d733aac17b9508b452Andreas Huber usage(argv[-optind]); 620f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return 1; 621f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 622f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 623f933441648ef6a71dee783d733aac17b9508b452Andreas Huber DataSource::RegisterDefaultSniffers(); 624f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 625f933441648ef6a71dee783d733aac17b9508b452Andreas Huber sp<ALooper> looper = new ALooper; 626f933441648ef6a71dee783d733aac17b9508b452Andreas Huber looper->setName("sf2"); 627f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 628f933441648ef6a71dee783d733aac17b9508b452Andreas Huber sp<SurfaceComposerClient> composerClient; 629f933441648ef6a71dee783d733aac17b9508b452Andreas Huber sp<SurfaceControl> control; 630f933441648ef6a71dee783d733aac17b9508b452Andreas Huber sp<Surface> surface; 631f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 632f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (!decodeAudio && useSurface) { 633f933441648ef6a71dee783d733aac17b9508b452Andreas Huber composerClient = new SurfaceComposerClient; 634f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK_EQ(composerClient->initCheck(), (status_t)OK); 635f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 636f933441648ef6a71dee783d733aac17b9508b452Andreas Huber control = composerClient->createSurface( 637f933441648ef6a71dee783d733aac17b9508b452Andreas Huber String8("A Surface"), 638f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1280, 639f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 800, 640f933441648ef6a71dee783d733aac17b9508b452Andreas Huber PIXEL_FORMAT_RGB_565, 641f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 0); 642f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 643f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(control != NULL); 644f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(control->isValid()); 645f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 6462df788fb0c402938f827bf9c9ce2ca3ab1dcd464Mathias Agopian SurfaceComposerClient::openGlobalTransaction(); 64793d5ab693626fa2700375e838e4bb90e4d50e605Andreas Huber CHECK_EQ(control->setLayer(INT_MAX), (status_t)OK); 648f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK_EQ(control->show(), (status_t)OK); 6492df788fb0c402938f827bf9c9ce2ca3ab1dcd464Mathias Agopian SurfaceComposerClient::closeGlobalTransaction(); 650f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 651f933441648ef6a71dee783d733aac17b9508b452Andreas Huber surface = control->getSurface(); 652f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(surface != NULL); 65393d5ab693626fa2700375e838e4bb90e4d50e605Andreas Huber 65493d5ab693626fa2700375e838e4bb90e4d50e605Andreas Huber CHECK_EQ((status_t)OK, 65593d5ab693626fa2700375e838e4bb90e4d50e605Andreas Huber native_window_api_connect( 65693d5ab693626fa2700375e838e4bb90e4d50e605Andreas Huber surface.get(), NATIVE_WINDOW_API_MEDIA)); 657f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 658f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 6591065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber sp<Controller> controller = 6601065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber new Controller(argv[0], decodeAudio, surface, renderToSurface); 6611065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber 662f933441648ef6a71dee783d733aac17b9508b452Andreas Huber looper->registerHandler(controller); 663f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 664a2354479716db40d865c597dc572ea83573caac2Marco Nelissen signal(SIGINT, mysighandler); 665a2354479716db40d865c597dc572ea83573caac2Marco Nelissen 666f933441648ef6a71dee783d733aac17b9508b452Andreas Huber controller->startAsync(); 667f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 668f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK_EQ(looper->start(true /* runOnCallingThread */), (status_t)OK); 669f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 670f933441648ef6a71dee783d733aac17b9508b452Andreas Huber looper->unregisterHandler(controller->id()); 671f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 672f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (!decodeAudio && useSurface) { 67393d5ab693626fa2700375e838e4bb90e4d50e605Andreas Huber CHECK_EQ((status_t)OK, 67493d5ab693626fa2700375e838e4bb90e4d50e605Andreas Huber native_window_api_disconnect( 67593d5ab693626fa2700375e838e4bb90e4d50e605Andreas Huber surface.get(), NATIVE_WINDOW_API_MEDIA)); 67693d5ab693626fa2700375e838e4bb90e4d50e605Andreas Huber 677f933441648ef6a71dee783d733aac17b9508b452Andreas Huber composerClient->dispose(); 678f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 679f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 680f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return 0; 681f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 682f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 683