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" 19f5e376fb8f2c30f82b7548241ca6b24f92ff8914Andreas Huber#include <utils/Log.h> 20f5e376fb8f2c30f82b7548241ca6b24f92ff8914Andreas Huber 21f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <binder/ProcessState.h> 22f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 23f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/foundation/hexdump.h> 24f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/foundation/ABuffer.h> 25f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/foundation/ADebug.h> 26f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/foundation/ALooper.h> 27f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/foundation/AMessage.h> 28f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 29f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/ACodec.h> 30f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/DataSource.h> 31f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/MediaBuffer.h> 32f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/MediaDefs.h> 33f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/MediaExtractor.h> 34f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/MediaSource.h> 35f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/MetaData.h> 361065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber#include <media/stagefright/NativeWindowWrapper.h> 37f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/Utils.h> 38f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 39df712ea86e6350f7005a02ab0e1c60c28a343ed0Mathias Agopian#include <gui/SurfaceComposerClient.h> 40f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 41f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include "include/ESDS.h" 42f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 43f933441648ef6a71dee783d733aac17b9508b452Andreas Huberusing namespace android; 44f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 45f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct Controller : public AHandler { 461065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber Controller(const char *uri, bool decodeAudio, 471065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber const sp<Surface> &surface, bool renderToSurface) 48f933441648ef6a71dee783d733aac17b9508b452Andreas Huber : mURI(uri), 49f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mDecodeAudio(decodeAudio), 50f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mSurface(surface), 511065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber mRenderToSurface(renderToSurface), 52729de186450f78c099637e1fce743fe531862c52Andreas Huber mCodec(new ACodec), 53729de186450f78c099637e1fce743fe531862c52Andreas Huber mIsVorbis(false) { 54f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(!mDecodeAudio || mSurface == NULL); 55f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 56f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 57f933441648ef6a71dee783d733aac17b9508b452Andreas Huber void startAsync() { 58f933441648ef6a71dee783d733aac17b9508b452Andreas Huber (new AMessage(kWhatStart, id()))->post(); 59f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 60f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 61f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected: 62f933441648ef6a71dee783d733aac17b9508b452Andreas Huber virtual ~Controller() { 63f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 64f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 65f933441648ef6a71dee783d733aac17b9508b452Andreas Huber virtual void onMessageReceived(const sp<AMessage> &msg) { 66f933441648ef6a71dee783d733aac17b9508b452Andreas Huber switch (msg->what()) { 67f933441648ef6a71dee783d733aac17b9508b452Andreas Huber case kWhatStart: 68f933441648ef6a71dee783d733aac17b9508b452Andreas Huber { 69f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#if 1 70f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mDecodeLooper = looper(); 71f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#else 72f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mDecodeLooper = new ALooper; 73f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mDecodeLooper->setName("sf2 decode looper"); 74f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mDecodeLooper->start(); 75f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#endif 76f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 77f933441648ef6a71dee783d733aac17b9508b452Andreas Huber sp<DataSource> dataSource = 78f933441648ef6a71dee783d733aac17b9508b452Andreas Huber DataSource::CreateFromURI(mURI.c_str()); 79f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 80f933441648ef6a71dee783d733aac17b9508b452Andreas Huber sp<MediaExtractor> extractor = 81f933441648ef6a71dee783d733aac17b9508b452Andreas Huber MediaExtractor::Create(dataSource); 82f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 83f933441648ef6a71dee783d733aac17b9508b452Andreas Huber for (size_t i = 0; i < extractor->countTracks(); ++i) { 84f933441648ef6a71dee783d733aac17b9508b452Andreas Huber sp<MetaData> meta = extractor->getTrackMetaData(i); 85f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 86f933441648ef6a71dee783d733aac17b9508b452Andreas Huber const char *mime; 87f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(meta->findCString(kKeyMIMEType, &mime)); 88f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 89f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (!strncasecmp(mDecodeAudio ? "audio/" : "video/", 90f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mime, 6)) { 91f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mSource = extractor->getTrack(i); 92729de186450f78c099637e1fce743fe531862c52Andreas Huber 93729de186450f78c099637e1fce743fe531862c52Andreas Huber if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_VORBIS)) { 94729de186450f78c099637e1fce743fe531862c52Andreas Huber mIsVorbis = true; 95729de186450f78c099637e1fce743fe531862c52Andreas Huber } else { 96729de186450f78c099637e1fce743fe531862c52Andreas Huber mIsVorbis = false; 97729de186450f78c099637e1fce743fe531862c52Andreas Huber } 98f933441648ef6a71dee783d733aac17b9508b452Andreas Huber break; 99f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 100f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 101f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(mSource != NULL); 102f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 103f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK_EQ(mSource->start(), (status_t)OK); 104f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 105f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mDecodeLooper->registerHandler(mCodec); 106f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 107f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mCodec->setNotificationMessage( 108f933441648ef6a71dee783d733aac17b9508b452Andreas Huber new AMessage(kWhatCodecNotify, id())); 109f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 110f933441648ef6a71dee783d733aac17b9508b452Andreas Huber sp<AMessage> format = makeFormat(mSource->getFormat()); 111f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 112f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (mSurface != NULL) { 1131065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber format->setObject( 1141065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber "native-window", new NativeWindowWrapper(mSurface)); 115f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 116f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 117f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mCodec->initiateSetup(format); 118f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 119f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mCSDIndex = 0; 120f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mStartTimeUs = ALooper::GetNowUs(); 121f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mNumOutputBuffersReceived = 0; 122f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mTotalBytesReceived = 0; 123f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mLeftOverBuffer = NULL; 124f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mFinalResult = OK; 125f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mSeekState = SEEK_NONE; 126f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 127f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // (new AMessage(kWhatSeek, id()))->post(5000000ll); 128f933441648ef6a71dee783d733aac17b9508b452Andreas Huber break; 129f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 130f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 131f933441648ef6a71dee783d733aac17b9508b452Andreas Huber case kWhatSeek: 132f933441648ef6a71dee783d733aac17b9508b452Andreas Huber { 133f933441648ef6a71dee783d733aac17b9508b452Andreas Huber printf("+"); 134f933441648ef6a71dee783d733aac17b9508b452Andreas Huber fflush(stdout); 135f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 136f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(mSeekState == SEEK_NONE 137f933441648ef6a71dee783d733aac17b9508b452Andreas Huber || mSeekState == SEEK_FLUSH_COMPLETED); 138f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 139f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (mLeftOverBuffer != NULL) { 140f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mLeftOverBuffer->release(); 141f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mLeftOverBuffer = NULL; 142f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 143f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 144f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mSeekState = SEEK_FLUSHING; 145f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mSeekTimeUs = 30000000ll; 146f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 147f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mCodec->signalFlush(); 148f933441648ef6a71dee783d733aac17b9508b452Andreas Huber break; 149f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 150f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 151f933441648ef6a71dee783d733aac17b9508b452Andreas Huber case kWhatStop: 152f933441648ef6a71dee783d733aac17b9508b452Andreas Huber { 153f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (mLeftOverBuffer != NULL) { 154f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mLeftOverBuffer->release(); 155f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mLeftOverBuffer = NULL; 156f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 157f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 158f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK_EQ(mSource->stop(), (status_t)OK); 159f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mSource.clear(); 160f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 161f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mCodec->initiateShutdown(); 162f933441648ef6a71dee783d733aac17b9508b452Andreas Huber break; 163f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 164f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 165f933441648ef6a71dee783d733aac17b9508b452Andreas Huber case kWhatCodecNotify: 166f933441648ef6a71dee783d733aac17b9508b452Andreas Huber { 167f933441648ef6a71dee783d733aac17b9508b452Andreas Huber int32_t what; 168f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(msg->findInt32("what", &what)); 169f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 170f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (what == ACodec::kWhatFillThisBuffer) { 171f933441648ef6a71dee783d733aac17b9508b452Andreas Huber onFillThisBuffer(msg); 172f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } else if (what == ACodec::kWhatDrainThisBuffer) { 173f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if ((mNumOutputBuffersReceived++ % 16) == 0) { 174f933441648ef6a71dee783d733aac17b9508b452Andreas Huber printf("."); 175f933441648ef6a71dee783d733aac17b9508b452Andreas Huber fflush(stdout); 176f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 177f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 178f933441648ef6a71dee783d733aac17b9508b452Andreas Huber onDrainThisBuffer(msg); 179afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber } else if (what == ACodec::kWhatEOS 180afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber || what == ACodec::kWhatError) { 181afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber printf((what == ACodec::kWhatEOS) ? "$\n" : "E\n"); 182f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 183f933441648ef6a71dee783d733aac17b9508b452Andreas Huber int64_t delayUs = ALooper::GetNowUs() - mStartTimeUs; 184f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 185f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (mDecodeAudio) { 186f933441648ef6a71dee783d733aac17b9508b452Andreas Huber printf("%lld bytes received. %.2f KB/sec\n", 187f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mTotalBytesReceived, 188f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mTotalBytesReceived * 1E6 / 1024 / delayUs); 189f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } else { 190f933441648ef6a71dee783d733aac17b9508b452Andreas Huber printf("%d frames decoded, %.2f fps. %lld bytes " 191f933441648ef6a71dee783d733aac17b9508b452Andreas Huber "received. %.2f KB/sec\n", 192f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mNumOutputBuffersReceived, 193f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mNumOutputBuffersReceived * 1E6 / delayUs, 194f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mTotalBytesReceived, 195f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mTotalBytesReceived * 1E6 / 1024 / delayUs); 196f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 197f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 198f933441648ef6a71dee783d733aac17b9508b452Andreas Huber (new AMessage(kWhatStop, id()))->post(); 199f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } else if (what == ACodec::kWhatFlushCompleted) { 200f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mSeekState = SEEK_FLUSH_COMPLETED; 201f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mCodec->signalResume(); 202f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 203f933441648ef6a71dee783d733aac17b9508b452Andreas Huber (new AMessage(kWhatSeek, id()))->post(5000000ll); 204777833cde11bfe8bae9c99aba8eeec33755ab264Andreas Huber } else if (what == ACodec::kWhatOutputFormatChanged) { 2055778822d86b0337407514b9372562b86edfa91cdAndreas Huber } else if (what == ACodec::kWhatShutdownCompleted) { 206f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mDecodeLooper->unregisterHandler(mCodec->id()); 207f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 208f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (mDecodeLooper != looper()) { 209f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mDecodeLooper->stop(); 210f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 211f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 212f933441648ef6a71dee783d733aac17b9508b452Andreas Huber looper()->stop(); 213f5e376fb8f2c30f82b7548241ca6b24f92ff8914Andreas Huber } else if (what == ACodec::kWhatError) { 214f5e376fb8f2c30f82b7548241ca6b24f92ff8914Andreas Huber ALOGE("something went wrong, codec reported an error."); 215f5e376fb8f2c30f82b7548241ca6b24f92ff8914Andreas Huber 216f5e376fb8f2c30f82b7548241ca6b24f92ff8914Andreas Huber printf("E\n"); 217f5e376fb8f2c30f82b7548241ca6b24f92ff8914Andreas Huber 218f5e376fb8f2c30f82b7548241ca6b24f92ff8914Andreas Huber (new AMessage(kWhatStop, id()))->post(); 219f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 220f933441648ef6a71dee783d733aac17b9508b452Andreas Huber break; 221f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 222f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 223f933441648ef6a71dee783d733aac17b9508b452Andreas Huber default: 224f933441648ef6a71dee783d733aac17b9508b452Andreas Huber TRESPASS(); 225f933441648ef6a71dee783d733aac17b9508b452Andreas Huber break; 226f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 227f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 228f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 229f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate: 230f933441648ef6a71dee783d733aac17b9508b452Andreas Huber enum { 231f933441648ef6a71dee783d733aac17b9508b452Andreas Huber kWhatStart = 'strt', 232f933441648ef6a71dee783d733aac17b9508b452Andreas Huber kWhatStop = 'stop', 233f933441648ef6a71dee783d733aac17b9508b452Andreas Huber kWhatCodecNotify = 'noti', 234f933441648ef6a71dee783d733aac17b9508b452Andreas Huber kWhatSeek = 'seek', 235f933441648ef6a71dee783d733aac17b9508b452Andreas Huber }; 236f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 237f933441648ef6a71dee783d733aac17b9508b452Andreas Huber sp<ALooper> mDecodeLooper; 238f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 239f933441648ef6a71dee783d733aac17b9508b452Andreas Huber AString mURI; 240f933441648ef6a71dee783d733aac17b9508b452Andreas Huber bool mDecodeAudio; 241f933441648ef6a71dee783d733aac17b9508b452Andreas Huber sp<Surface> mSurface; 2421065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber bool mRenderToSurface; 243f933441648ef6a71dee783d733aac17b9508b452Andreas Huber sp<ACodec> mCodec; 244f933441648ef6a71dee783d733aac17b9508b452Andreas Huber sp<MediaSource> mSource; 245729de186450f78c099637e1fce743fe531862c52Andreas Huber bool mIsVorbis; 246f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 247f933441648ef6a71dee783d733aac17b9508b452Andreas Huber Vector<sp<ABuffer> > mCSD; 248f933441648ef6a71dee783d733aac17b9508b452Andreas Huber size_t mCSDIndex; 249f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 250f933441648ef6a71dee783d733aac17b9508b452Andreas Huber MediaBuffer *mLeftOverBuffer; 251f933441648ef6a71dee783d733aac17b9508b452Andreas Huber status_t mFinalResult; 252f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 253f933441648ef6a71dee783d733aac17b9508b452Andreas Huber int64_t mStartTimeUs; 254f933441648ef6a71dee783d733aac17b9508b452Andreas Huber int32_t mNumOutputBuffersReceived; 255f933441648ef6a71dee783d733aac17b9508b452Andreas Huber int64_t mTotalBytesReceived; 256f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 257f933441648ef6a71dee783d733aac17b9508b452Andreas Huber enum SeekState { 258f933441648ef6a71dee783d733aac17b9508b452Andreas Huber SEEK_NONE, 259f933441648ef6a71dee783d733aac17b9508b452Andreas Huber SEEK_FLUSHING, 260f933441648ef6a71dee783d733aac17b9508b452Andreas Huber SEEK_FLUSH_COMPLETED, 261f933441648ef6a71dee783d733aac17b9508b452Andreas Huber }; 262f933441648ef6a71dee783d733aac17b9508b452Andreas Huber SeekState mSeekState; 263f933441648ef6a71dee783d733aac17b9508b452Andreas Huber int64_t mSeekTimeUs; 264f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 265f933441648ef6a71dee783d733aac17b9508b452Andreas Huber sp<AMessage> makeFormat(const sp<MetaData> &meta) { 266f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(mCSD.isEmpty()); 267f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 268f933441648ef6a71dee783d733aac17b9508b452Andreas Huber const char *mime; 269f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(meta->findCString(kKeyMIMEType, &mime)); 270f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 271f933441648ef6a71dee783d733aac17b9508b452Andreas Huber sp<AMessage> msg = new AMessage; 272f933441648ef6a71dee783d733aac17b9508b452Andreas Huber msg->setString("mime", mime); 273f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 274f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (!strncasecmp("video/", mime, 6)) { 275f933441648ef6a71dee783d733aac17b9508b452Andreas Huber int32_t width, height; 276f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(meta->findInt32(kKeyWidth, &width)); 277f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(meta->findInt32(kKeyHeight, &height)); 278f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 279f933441648ef6a71dee783d733aac17b9508b452Andreas Huber msg->setInt32("width", width); 280f933441648ef6a71dee783d733aac17b9508b452Andreas Huber msg->setInt32("height", height); 281f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } else { 282f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(!strncasecmp("audio/", mime, 6)); 283f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 284f933441648ef6a71dee783d733aac17b9508b452Andreas Huber int32_t numChannels, sampleRate; 285f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(meta->findInt32(kKeyChannelCount, &numChannels)); 286f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(meta->findInt32(kKeySampleRate, &sampleRate)); 287f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 288f933441648ef6a71dee783d733aac17b9508b452Andreas Huber msg->setInt32("channel-count", numChannels); 289f933441648ef6a71dee783d733aac17b9508b452Andreas Huber msg->setInt32("sample-rate", sampleRate); 290ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber 291ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber int32_t isADTS; 292ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber if (meta->findInt32(kKeyIsADTS, &isADTS) && isADTS != 0) { 293ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber msg->setInt32("is-adts", true); 294ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber } 295f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 296f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 297f933441648ef6a71dee783d733aac17b9508b452Andreas Huber uint32_t type; 298f933441648ef6a71dee783d733aac17b9508b452Andreas Huber const void *data; 299f933441648ef6a71dee783d733aac17b9508b452Andreas Huber size_t size; 300f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (meta->findData(kKeyAVCC, &type, &data, &size)) { 301f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // Parse the AVCDecoderConfigurationRecord 302f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 303f933441648ef6a71dee783d733aac17b9508b452Andreas Huber const uint8_t *ptr = (const uint8_t *)data; 304f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 305f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(size >= 7); 306f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK_EQ((unsigned)ptr[0], 1u); // configurationVersion == 1 307f933441648ef6a71dee783d733aac17b9508b452Andreas Huber uint8_t profile = ptr[1]; 308f933441648ef6a71dee783d733aac17b9508b452Andreas Huber uint8_t level = ptr[3]; 309f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 310f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // There is decodable content out there that fails the following 311f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // assertion, let's be lenient for now... 312f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // CHECK((ptr[4] >> 2) == 0x3f); // reserved 313f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 314f933441648ef6a71dee783d733aac17b9508b452Andreas Huber size_t lengthSize = 1 + (ptr[4] & 3); 315f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 316f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // commented out check below as H264_QVGA_500_NO_AUDIO.3gp 317f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // violates it... 318f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // CHECK((ptr[5] >> 5) == 7); // reserved 319f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 320f933441648ef6a71dee783d733aac17b9508b452Andreas Huber size_t numSeqParameterSets = ptr[5] & 31; 321f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 322f933441648ef6a71dee783d733aac17b9508b452Andreas Huber ptr += 6; 323f933441648ef6a71dee783d733aac17b9508b452Andreas Huber size -= 6; 324f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 325f933441648ef6a71dee783d733aac17b9508b452Andreas Huber sp<ABuffer> buffer = new ABuffer(1024); 326f933441648ef6a71dee783d733aac17b9508b452Andreas Huber buffer->setRange(0, 0); 327f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 328f933441648ef6a71dee783d733aac17b9508b452Andreas Huber for (size_t i = 0; i < numSeqParameterSets; ++i) { 329f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(size >= 2); 330f933441648ef6a71dee783d733aac17b9508b452Andreas Huber size_t length = U16_AT(ptr); 331f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 332f933441648ef6a71dee783d733aac17b9508b452Andreas Huber ptr += 2; 333f933441648ef6a71dee783d733aac17b9508b452Andreas Huber size -= 2; 334f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 335f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(size >= length); 336f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 337f933441648ef6a71dee783d733aac17b9508b452Andreas Huber memcpy(buffer->data() + buffer->size(), "\x00\x00\x00\x01", 4); 338f933441648ef6a71dee783d733aac17b9508b452Andreas Huber memcpy(buffer->data() + buffer->size() + 4, ptr, length); 339f933441648ef6a71dee783d733aac17b9508b452Andreas Huber buffer->setRange(0, buffer->size() + 4 + length); 340f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 341f933441648ef6a71dee783d733aac17b9508b452Andreas Huber ptr += length; 342f933441648ef6a71dee783d733aac17b9508b452Andreas Huber size -= length; 343f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 344f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 345f933441648ef6a71dee783d733aac17b9508b452Andreas Huber buffer->meta()->setInt32("csd", true); 346f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mCSD.push(buffer); 347f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 348f933441648ef6a71dee783d733aac17b9508b452Andreas Huber buffer = new ABuffer(1024); 349f933441648ef6a71dee783d733aac17b9508b452Andreas Huber buffer->setRange(0, 0); 350f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 351f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(size >= 1); 352f933441648ef6a71dee783d733aac17b9508b452Andreas Huber size_t numPictureParameterSets = *ptr; 353f933441648ef6a71dee783d733aac17b9508b452Andreas Huber ++ptr; 354f933441648ef6a71dee783d733aac17b9508b452Andreas Huber --size; 355f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 356f933441648ef6a71dee783d733aac17b9508b452Andreas Huber for (size_t i = 0; i < numPictureParameterSets; ++i) { 357f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(size >= 2); 358f933441648ef6a71dee783d733aac17b9508b452Andreas Huber size_t length = U16_AT(ptr); 359f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 360f933441648ef6a71dee783d733aac17b9508b452Andreas Huber ptr += 2; 361f933441648ef6a71dee783d733aac17b9508b452Andreas Huber size -= 2; 362f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 363f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(size >= length); 364f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 365f933441648ef6a71dee783d733aac17b9508b452Andreas Huber memcpy(buffer->data() + buffer->size(), "\x00\x00\x00\x01", 4); 366f933441648ef6a71dee783d733aac17b9508b452Andreas Huber memcpy(buffer->data() + buffer->size() + 4, ptr, length); 367f933441648ef6a71dee783d733aac17b9508b452Andreas Huber buffer->setRange(0, buffer->size() + 4 + length); 368f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 369f933441648ef6a71dee783d733aac17b9508b452Andreas Huber ptr += length; 370f933441648ef6a71dee783d733aac17b9508b452Andreas Huber size -= length; 371f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 372f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 373f933441648ef6a71dee783d733aac17b9508b452Andreas Huber buffer->meta()->setInt32("csd", true); 374f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mCSD.push(buffer); 375f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 376bf6c85a013fb14960bac147c1ffd0a02a8d5f148Andreas Huber msg->setBuffer("csd", buffer); 377f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } else if (meta->findData(kKeyESDS, &type, &data, &size)) { 378f933441648ef6a71dee783d733aac17b9508b452Andreas Huber ESDS esds((const char *)data, size); 379f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK_EQ(esds.InitCheck(), (status_t)OK); 380f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 381f933441648ef6a71dee783d733aac17b9508b452Andreas Huber const void *codec_specific_data; 382f933441648ef6a71dee783d733aac17b9508b452Andreas Huber size_t codec_specific_data_size; 383f933441648ef6a71dee783d733aac17b9508b452Andreas Huber esds.getCodecSpecificInfo( 384f933441648ef6a71dee783d733aac17b9508b452Andreas Huber &codec_specific_data, &codec_specific_data_size); 385f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 386f933441648ef6a71dee783d733aac17b9508b452Andreas Huber sp<ABuffer> buffer = new ABuffer(codec_specific_data_size); 387f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 388f933441648ef6a71dee783d733aac17b9508b452Andreas Huber memcpy(buffer->data(), codec_specific_data, 389f933441648ef6a71dee783d733aac17b9508b452Andreas Huber codec_specific_data_size); 390f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 391f933441648ef6a71dee783d733aac17b9508b452Andreas Huber buffer->meta()->setInt32("csd", true); 392f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mCSD.push(buffer); 393729de186450f78c099637e1fce743fe531862c52Andreas Huber } else if (meta->findData(kKeyVorbisInfo, &type, &data, &size)) { 394729de186450f78c099637e1fce743fe531862c52Andreas Huber sp<ABuffer> buffer = new ABuffer(size); 395729de186450f78c099637e1fce743fe531862c52Andreas Huber memcpy(buffer->data(), data, size); 396729de186450f78c099637e1fce743fe531862c52Andreas Huber 397729de186450f78c099637e1fce743fe531862c52Andreas Huber buffer->meta()->setInt32("csd", true); 398729de186450f78c099637e1fce743fe531862c52Andreas Huber mCSD.push(buffer); 399729de186450f78c099637e1fce743fe531862c52Andreas Huber 400729de186450f78c099637e1fce743fe531862c52Andreas Huber CHECK(meta->findData(kKeyVorbisBooks, &type, &data, &size)); 401729de186450f78c099637e1fce743fe531862c52Andreas Huber 402729de186450f78c099637e1fce743fe531862c52Andreas Huber buffer = new ABuffer(size); 403729de186450f78c099637e1fce743fe531862c52Andreas Huber memcpy(buffer->data(), data, size); 404729de186450f78c099637e1fce743fe531862c52Andreas Huber 405729de186450f78c099637e1fce743fe531862c52Andreas Huber buffer->meta()->setInt32("csd", true); 406729de186450f78c099637e1fce743fe531862c52Andreas Huber mCSD.push(buffer); 407f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 408f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 409f933441648ef6a71dee783d733aac17b9508b452Andreas Huber int32_t maxInputSize; 410f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (meta->findInt32(kKeyMaxInputSize, &maxInputSize)) { 411f933441648ef6a71dee783d733aac17b9508b452Andreas Huber msg->setInt32("max-input-size", maxInputSize); 412f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 413f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 414f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return msg; 415f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 416f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 417f933441648ef6a71dee783d733aac17b9508b452Andreas Huber void onFillThisBuffer(const sp<AMessage> &msg) { 418f933441648ef6a71dee783d733aac17b9508b452Andreas Huber sp<AMessage> reply; 419f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(msg->findMessage("reply", &reply)); 420f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 421afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber if (mSource == NULL || mSeekState == SEEK_FLUSHING) { 422afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber reply->setInt32("err", ERROR_END_OF_STREAM); 423f933441648ef6a71dee783d733aac17b9508b452Andreas Huber reply->post(); 424f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return; 425f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 426f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 427bf6c85a013fb14960bac147c1ffd0a02a8d5f148Andreas Huber sp<ABuffer> outBuffer; 428bf6c85a013fb14960bac147c1ffd0a02a8d5f148Andreas Huber CHECK(msg->findBuffer("buffer", &outBuffer)); 429f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 430f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (mCSDIndex < mCSD.size()) { 431f933441648ef6a71dee783d733aac17b9508b452Andreas Huber outBuffer = mCSD.editItemAt(mCSDIndex++); 432f933441648ef6a71dee783d733aac17b9508b452Andreas Huber outBuffer->meta()->setInt64("timeUs", 0); 433f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } else { 434f933441648ef6a71dee783d733aac17b9508b452Andreas Huber size_t sizeLeft = outBuffer->capacity(); 435f933441648ef6a71dee783d733aac17b9508b452Andreas Huber outBuffer->setRange(0, 0); 436f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 437f933441648ef6a71dee783d733aac17b9508b452Andreas Huber int32_t n = 0; 438f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 439f933441648ef6a71dee783d733aac17b9508b452Andreas Huber for (;;) { 440f933441648ef6a71dee783d733aac17b9508b452Andreas Huber MediaBuffer *inBuffer; 441f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 442f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (mLeftOverBuffer != NULL) { 443f933441648ef6a71dee783d733aac17b9508b452Andreas Huber inBuffer = mLeftOverBuffer; 444f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mLeftOverBuffer = NULL; 445f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } else if (mFinalResult != OK) { 446f933441648ef6a71dee783d733aac17b9508b452Andreas Huber break; 447f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } else { 448f933441648ef6a71dee783d733aac17b9508b452Andreas Huber MediaSource::ReadOptions options; 449f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (mSeekState == SEEK_FLUSH_COMPLETED) { 450f933441648ef6a71dee783d733aac17b9508b452Andreas Huber options.setSeekTo(mSeekTimeUs); 451f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mSeekState = SEEK_NONE; 452f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 453f933441648ef6a71dee783d733aac17b9508b452Andreas Huber status_t err = mSource->read(&inBuffer, &options); 454f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 455f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (err != OK) { 456f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mFinalResult = err; 457f933441648ef6a71dee783d733aac17b9508b452Andreas Huber break; 458f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 459f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 460f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 461729de186450f78c099637e1fce743fe531862c52Andreas Huber size_t sizeNeeded = inBuffer->range_length(); 462729de186450f78c099637e1fce743fe531862c52Andreas Huber if (mIsVorbis) { 463729de186450f78c099637e1fce743fe531862c52Andreas Huber // Vorbis data is suffixed with the number of 464729de186450f78c099637e1fce743fe531862c52Andreas Huber // valid samples on the page. 465729de186450f78c099637e1fce743fe531862c52Andreas Huber sizeNeeded += sizeof(int32_t); 466729de186450f78c099637e1fce743fe531862c52Andreas Huber } 467729de186450f78c099637e1fce743fe531862c52Andreas Huber 468729de186450f78c099637e1fce743fe531862c52Andreas Huber if (sizeNeeded > sizeLeft) { 469f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (outBuffer->size() == 0) { 47029357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("Unable to fit even a single input buffer of size %d.", 471729de186450f78c099637e1fce743fe531862c52Andreas Huber sizeNeeded); 472f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 473f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK_GT(outBuffer->size(), 0u); 474f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 475f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mLeftOverBuffer = inBuffer; 476f933441648ef6a71dee783d733aac17b9508b452Andreas Huber break; 477f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 478f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 479f933441648ef6a71dee783d733aac17b9508b452Andreas Huber ++n; 480f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 481f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (outBuffer->size() == 0) { 482f933441648ef6a71dee783d733aac17b9508b452Andreas Huber int64_t timeUs; 483f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(inBuffer->meta_data()->findInt64(kKeyTime, &timeUs)); 484f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 485f933441648ef6a71dee783d733aac17b9508b452Andreas Huber outBuffer->meta()->setInt64("timeUs", timeUs); 486f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 487f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 488f933441648ef6a71dee783d733aac17b9508b452Andreas Huber memcpy(outBuffer->data() + outBuffer->size(), 489f933441648ef6a71dee783d733aac17b9508b452Andreas Huber (const uint8_t *)inBuffer->data() 490f933441648ef6a71dee783d733aac17b9508b452Andreas Huber + inBuffer->range_offset(), 491f933441648ef6a71dee783d733aac17b9508b452Andreas Huber inBuffer->range_length()); 492f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 493729de186450f78c099637e1fce743fe531862c52Andreas Huber if (mIsVorbis) { 494729de186450f78c099637e1fce743fe531862c52Andreas Huber int32_t numPageSamples; 495729de186450f78c099637e1fce743fe531862c52Andreas Huber if (!inBuffer->meta_data()->findInt32( 496729de186450f78c099637e1fce743fe531862c52Andreas Huber kKeyValidSamples, &numPageSamples)) { 497729de186450f78c099637e1fce743fe531862c52Andreas Huber numPageSamples = -1; 498729de186450f78c099637e1fce743fe531862c52Andreas Huber } 499729de186450f78c099637e1fce743fe531862c52Andreas Huber 500729de186450f78c099637e1fce743fe531862c52Andreas Huber memcpy(outBuffer->data() 501729de186450f78c099637e1fce743fe531862c52Andreas Huber + outBuffer->size() + inBuffer->range_length(), 502729de186450f78c099637e1fce743fe531862c52Andreas Huber &numPageSamples, sizeof(numPageSamples)); 503729de186450f78c099637e1fce743fe531862c52Andreas Huber } 504729de186450f78c099637e1fce743fe531862c52Andreas Huber 505f933441648ef6a71dee783d733aac17b9508b452Andreas Huber outBuffer->setRange( 506729de186450f78c099637e1fce743fe531862c52Andreas Huber 0, outBuffer->size() + sizeNeeded); 507f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 508729de186450f78c099637e1fce743fe531862c52Andreas Huber sizeLeft -= sizeNeeded; 509f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 510f933441648ef6a71dee783d733aac17b9508b452Andreas Huber inBuffer->release(); 511f933441648ef6a71dee783d733aac17b9508b452Andreas Huber inBuffer = NULL; 512f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 5131065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber break; // Don't coalesce 514f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 515f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 5163856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("coalesced %d input buffers", n); 517f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 518f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (outBuffer->size() == 0) { 519f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK_NE(mFinalResult, (status_t)OK); 520f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 521f933441648ef6a71dee783d733aac17b9508b452Andreas Huber reply->setInt32("err", mFinalResult); 522f933441648ef6a71dee783d733aac17b9508b452Andreas Huber reply->post(); 523f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return; 524f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 525f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 526f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 527bf6c85a013fb14960bac147c1ffd0a02a8d5f148Andreas Huber reply->setBuffer("buffer", outBuffer); 528f933441648ef6a71dee783d733aac17b9508b452Andreas Huber reply->post(); 529f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 530f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 531f933441648ef6a71dee783d733aac17b9508b452Andreas Huber void onDrainThisBuffer(const sp<AMessage> &msg) { 532bf6c85a013fb14960bac147c1ffd0a02a8d5f148Andreas Huber sp<ABuffer> buffer; 533bf6c85a013fb14960bac147c1ffd0a02a8d5f148Andreas Huber CHECK(msg->findBuffer("buffer", &buffer)); 534f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 535f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mTotalBytesReceived += buffer->size(); 536f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 537f933441648ef6a71dee783d733aac17b9508b452Andreas Huber sp<AMessage> reply; 538f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(msg->findMessage("reply", &reply)); 539f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 5401065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber if (mRenderToSurface) { 5411065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber reply->setInt32("render", 1); 5421065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber } 5431065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber 544f933441648ef6a71dee783d733aac17b9508b452Andreas Huber reply->post(); 545f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 546f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 547f933441648ef6a71dee783d733aac17b9508b452Andreas Huber DISALLOW_EVIL_CONSTRUCTORS(Controller); 548f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}; 549f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 550f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatic void usage(const char *me) { 551f933441648ef6a71dee783d733aac17b9508b452Andreas Huber fprintf(stderr, "usage: %s\n", me); 552f933441648ef6a71dee783d733aac17b9508b452Andreas Huber fprintf(stderr, " -h(elp)\n"); 553f933441648ef6a71dee783d733aac17b9508b452Andreas Huber fprintf(stderr, " -a(udio)\n"); 554f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 555f933441648ef6a71dee783d733aac17b9508b452Andreas Huber fprintf(stderr, 5561065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber " -S(urface) Allocate output buffers on a surface.\n" 5571065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber " -R(ender) Render surface-allocated buffers.\n"); 558f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 559f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 560f933441648ef6a71dee783d733aac17b9508b452Andreas Huberint main(int argc, char **argv) { 561f933441648ef6a71dee783d733aac17b9508b452Andreas Huber android::ProcessState::self()->startThreadPool(); 562f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 563f933441648ef6a71dee783d733aac17b9508b452Andreas Huber bool decodeAudio = false; 564f933441648ef6a71dee783d733aac17b9508b452Andreas Huber bool useSurface = false; 5651065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber bool renderToSurface = false; 566f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 567f933441648ef6a71dee783d733aac17b9508b452Andreas Huber int res; 5681065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber while ((res = getopt(argc, argv, "haSR")) >= 0) { 569f933441648ef6a71dee783d733aac17b9508b452Andreas Huber switch (res) { 570f933441648ef6a71dee783d733aac17b9508b452Andreas Huber case 'a': 571f933441648ef6a71dee783d733aac17b9508b452Andreas Huber decodeAudio = true; 572f933441648ef6a71dee783d733aac17b9508b452Andreas Huber break; 573f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 5741065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber case 'S': 575f933441648ef6a71dee783d733aac17b9508b452Andreas Huber useSurface = true; 576f933441648ef6a71dee783d733aac17b9508b452Andreas Huber break; 577f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 5781065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber case 'R': 5791065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber renderToSurface = true; 5801065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber break; 5811065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber 582f933441648ef6a71dee783d733aac17b9508b452Andreas Huber case '?': 583f933441648ef6a71dee783d733aac17b9508b452Andreas Huber case 'h': 584f933441648ef6a71dee783d733aac17b9508b452Andreas Huber default: 585f933441648ef6a71dee783d733aac17b9508b452Andreas Huber { 586f933441648ef6a71dee783d733aac17b9508b452Andreas Huber usage(argv[0]); 587f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return 1; 588f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 589f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 590f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 591f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 592f933441648ef6a71dee783d733aac17b9508b452Andreas Huber argc -= optind; 593f933441648ef6a71dee783d733aac17b9508b452Andreas Huber argv += optind; 594f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 595f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (argc != 1) { 596f933441648ef6a71dee783d733aac17b9508b452Andreas Huber usage(argv[-optind]); 597f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return 1; 598f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 599f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 600f933441648ef6a71dee783d733aac17b9508b452Andreas Huber DataSource::RegisterDefaultSniffers(); 601f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 602f933441648ef6a71dee783d733aac17b9508b452Andreas Huber sp<ALooper> looper = new ALooper; 603f933441648ef6a71dee783d733aac17b9508b452Andreas Huber looper->setName("sf2"); 604f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 605f933441648ef6a71dee783d733aac17b9508b452Andreas Huber sp<SurfaceComposerClient> composerClient; 606f933441648ef6a71dee783d733aac17b9508b452Andreas Huber sp<SurfaceControl> control; 607f933441648ef6a71dee783d733aac17b9508b452Andreas Huber sp<Surface> surface; 608f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 609f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (!decodeAudio && useSurface) { 610f933441648ef6a71dee783d733aac17b9508b452Andreas Huber composerClient = new SurfaceComposerClient; 611f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK_EQ(composerClient->initCheck(), (status_t)OK); 612f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 613f933441648ef6a71dee783d733aac17b9508b452Andreas Huber control = composerClient->createSurface( 614f933441648ef6a71dee783d733aac17b9508b452Andreas Huber String8("A Surface"), 615f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1280, 616f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 800, 617f933441648ef6a71dee783d733aac17b9508b452Andreas Huber PIXEL_FORMAT_RGB_565, 618f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 0); 619f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 620f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(control != NULL); 621f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(control->isValid()); 622f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 6232df788fb0c402938f827bf9c9ce2ca3ab1dcd464Mathias Agopian SurfaceComposerClient::openGlobalTransaction(); 62493d5ab693626fa2700375e838e4bb90e4d50e605Andreas Huber CHECK_EQ(control->setLayer(INT_MAX), (status_t)OK); 625f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK_EQ(control->show(), (status_t)OK); 6262df788fb0c402938f827bf9c9ce2ca3ab1dcd464Mathias Agopian SurfaceComposerClient::closeGlobalTransaction(); 627f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 628f933441648ef6a71dee783d733aac17b9508b452Andreas Huber surface = control->getSurface(); 629f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK(surface != NULL); 63093d5ab693626fa2700375e838e4bb90e4d50e605Andreas Huber 63193d5ab693626fa2700375e838e4bb90e4d50e605Andreas Huber CHECK_EQ((status_t)OK, 63293d5ab693626fa2700375e838e4bb90e4d50e605Andreas Huber native_window_api_connect( 63393d5ab693626fa2700375e838e4bb90e4d50e605Andreas Huber surface.get(), NATIVE_WINDOW_API_MEDIA)); 634f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 635f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 6361065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber sp<Controller> controller = 6371065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber new Controller(argv[0], decodeAudio, surface, renderToSurface); 6381065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber 639f933441648ef6a71dee783d733aac17b9508b452Andreas Huber looper->registerHandler(controller); 640f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 641f933441648ef6a71dee783d733aac17b9508b452Andreas Huber controller->startAsync(); 642f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 643f933441648ef6a71dee783d733aac17b9508b452Andreas Huber CHECK_EQ(looper->start(true /* runOnCallingThread */), (status_t)OK); 644f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 645f933441648ef6a71dee783d733aac17b9508b452Andreas Huber looper->unregisterHandler(controller->id()); 646f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 647f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (!decodeAudio && useSurface) { 64893d5ab693626fa2700375e838e4bb90e4d50e605Andreas Huber CHECK_EQ((status_t)OK, 64993d5ab693626fa2700375e838e4bb90e4d50e605Andreas Huber native_window_api_disconnect( 65093d5ab693626fa2700375e838e4bb90e4d50e605Andreas Huber surface.get(), NATIVE_WINDOW_API_MEDIA)); 65193d5ab693626fa2700375e838e4bb90e4d50e605Andreas Huber 652f933441648ef6a71dee783d733aac17b9508b452Andreas Huber composerClient->dispose(); 653f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 654f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 655f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return 0; 656f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 657f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 658