1199d1c131d29b5356f71fbd7826a592c1dd8575fJames Dong/* 2199d1c131d29b5356f71fbd7826a592c1dd8575fJames Dong * Copyright (C) 2010 The Android Open Source Project 3199d1c131d29b5356f71fbd7826a592c1dd8575fJames Dong * 4199d1c131d29b5356f71fbd7826a592c1dd8575fJames Dong * Licensed under the Apache License, Version 2.0 (the "License"); 5199d1c131d29b5356f71fbd7826a592c1dd8575fJames Dong * you may not use this file except in compliance with the License. 6199d1c131d29b5356f71fbd7826a592c1dd8575fJames Dong * You may obtain a copy of the License at 7199d1c131d29b5356f71fbd7826a592c1dd8575fJames Dong * 8199d1c131d29b5356f71fbd7826a592c1dd8575fJames Dong * http://www.apache.org/licenses/LICENSE-2.0 9199d1c131d29b5356f71fbd7826a592c1dd8575fJames Dong * 10199d1c131d29b5356f71fbd7826a592c1dd8575fJames Dong * Unless required by applicable law or agreed to in writing, software 11199d1c131d29b5356f71fbd7826a592c1dd8575fJames Dong * distributed under the License is distributed on an "AS IS" BASIS, 12199d1c131d29b5356f71fbd7826a592c1dd8575fJames Dong * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13199d1c131d29b5356f71fbd7826a592c1dd8575fJames Dong * See the License for the specific language governing permissions and 14199d1c131d29b5356f71fbd7826a592c1dd8575fJames Dong * limitations under the License. 15199d1c131d29b5356f71fbd7826a592c1dd8575fJames Dong */ 16199d1c131d29b5356f71fbd7826a592c1dd8575fJames Dong 17a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber#include <binder/ProcessState.h> 18a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber 19a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber#include <media/stagefright/foundation/hexdump.h> 20a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber#include <media/stagefright/foundation/ABuffer.h> 21a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber#include <media/stagefright/foundation/ADebug.h> 22a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber#include <media/stagefright/foundation/ALooper.h> 23a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber#include <media/stagefright/foundation/AMessage.h> 24a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber 25a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber#include <media/stagefright/ACodec.h> 26a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber#include <media/stagefright/DataSource.h> 27a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber#include <media/stagefright/MediaBuffer.h> 28a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber#include <media/stagefright/MediaDefs.h> 29a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber#include <media/stagefright/MediaExtractor.h> 30a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber#include <media/stagefright/MediaSource.h> 31a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber#include <media/stagefright/MetaData.h> 32e366f52b1520f13306d5fef1c3c8a2b2c653d935Andreas Huber#include <media/stagefright/NativeWindowWrapper.h> 33a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber#include <media/stagefright/Utils.h> 34a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber 35a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber#include <surfaceflinger/ISurfaceComposer.h> 36a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber#include <surfaceflinger/SurfaceComposerClient.h> 37a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber 38a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber#include "include/ESDS.h" 39a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber 40a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huberusing namespace android; 41a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber 42a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huberstruct Controller : public AHandler { 43e366f52b1520f13306d5fef1c3c8a2b2c653d935Andreas Huber Controller(const char *uri, bool decodeAudio, 44e366f52b1520f13306d5fef1c3c8a2b2c653d935Andreas Huber const sp<Surface> &surface, bool renderToSurface) 45a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber : mURI(uri), 46a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber mDecodeAudio(decodeAudio), 47a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber mSurface(surface), 48e366f52b1520f13306d5fef1c3c8a2b2c653d935Andreas Huber mRenderToSurface(renderToSurface), 493e408f39ef1c0513908a3b73da5ce6f4164e85d9Andreas Huber mCodec(new ACodec), 503e408f39ef1c0513908a3b73da5ce6f4164e85d9Andreas Huber mIsVorbis(false) { 51a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber CHECK(!mDecodeAudio || mSurface == NULL); 52a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber } 53a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber 54a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber void startAsync() { 55a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber (new AMessage(kWhatStart, id()))->post(); 56a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber } 57a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber 58a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huberprotected: 59a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber virtual ~Controller() { 60a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber } 61a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber 62a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber virtual void onMessageReceived(const sp<AMessage> &msg) { 63a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber switch (msg->what()) { 64a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber case kWhatStart: 65a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber { 66a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber#if 1 67a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber mDecodeLooper = looper(); 68a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber#else 69a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber mDecodeLooper = new ALooper; 70a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber mDecodeLooper->setName("sf2 decode looper"); 71a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber mDecodeLooper->start(); 72a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber#endif 73a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber 74a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber sp<DataSource> dataSource = 75a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber DataSource::CreateFromURI(mURI.c_str()); 76a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber 77a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber sp<MediaExtractor> extractor = 78a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber MediaExtractor::Create(dataSource); 79a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber 80a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber for (size_t i = 0; i < extractor->countTracks(); ++i) { 81a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber sp<MetaData> meta = extractor->getTrackMetaData(i); 82a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber 83a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber const char *mime; 84a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber CHECK(meta->findCString(kKeyMIMEType, &mime)); 85a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber 86a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber if (!strncasecmp(mDecodeAudio ? "audio/" : "video/", 87a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber mime, 6)) { 88a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber mSource = extractor->getTrack(i); 893e408f39ef1c0513908a3b73da5ce6f4164e85d9Andreas Huber 903e408f39ef1c0513908a3b73da5ce6f4164e85d9Andreas Huber if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_VORBIS)) { 913e408f39ef1c0513908a3b73da5ce6f4164e85d9Andreas Huber mIsVorbis = true; 923e408f39ef1c0513908a3b73da5ce6f4164e85d9Andreas Huber } else { 933e408f39ef1c0513908a3b73da5ce6f4164e85d9Andreas Huber mIsVorbis = false; 943e408f39ef1c0513908a3b73da5ce6f4164e85d9Andreas Huber } 95a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber break; 96a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber } 97a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber } 98a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber CHECK(mSource != NULL); 99a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber 100a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber CHECK_EQ(mSource->start(), (status_t)OK); 101a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber 102a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber mDecodeLooper->registerHandler(mCodec); 103a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber 104a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber mCodec->setNotificationMessage( 105a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber new AMessage(kWhatCodecNotify, id())); 106a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber 107a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber sp<AMessage> format = makeFormat(mSource->getFormat()); 108a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber 109a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber if (mSurface != NULL) { 110e366f52b1520f13306d5fef1c3c8a2b2c653d935Andreas Huber format->setObject( 111e366f52b1520f13306d5fef1c3c8a2b2c653d935Andreas Huber "native-window", new NativeWindowWrapper(mSurface)); 112a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber } 113a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber 114a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber mCodec->initiateSetup(format); 115a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber 116a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber mCSDIndex = 0; 117a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber mStartTimeUs = ALooper::GetNowUs(); 118a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber mNumOutputBuffersReceived = 0; 119a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber mTotalBytesReceived = 0; 120a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber mLeftOverBuffer = NULL; 121a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber mFinalResult = OK; 122a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber mSeekState = SEEK_NONE; 123a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber 124a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber // (new AMessage(kWhatSeek, id()))->post(5000000ll); 125a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber break; 126a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber } 127a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber 128a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber case kWhatSeek: 129a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber { 130a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber printf("+"); 131a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber fflush(stdout); 132a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber 133a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber CHECK(mSeekState == SEEK_NONE 134a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber || mSeekState == SEEK_FLUSH_COMPLETED); 135a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber 136a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber if (mLeftOverBuffer != NULL) { 137a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber mLeftOverBuffer->release(); 138a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber mLeftOverBuffer = NULL; 139a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber } 140a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber 141a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber mSeekState = SEEK_FLUSHING; 142a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber mSeekTimeUs = 30000000ll; 143a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber 144a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber mCodec->signalFlush(); 145a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber break; 146a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber } 147a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber 148a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber case kWhatStop: 149a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber { 150a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber if (mLeftOverBuffer != NULL) { 151a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber mLeftOverBuffer->release(); 152a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber mLeftOverBuffer = NULL; 153a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber } 154a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber 155a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber CHECK_EQ(mSource->stop(), (status_t)OK); 156a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber mSource.clear(); 157a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber 158a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber mCodec->initiateShutdown(); 159a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber break; 160a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber } 161a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber 162a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber case kWhatCodecNotify: 163a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber { 164a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber int32_t what; 165a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber CHECK(msg->findInt32("what", &what)); 166a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber 167a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber if (what == ACodec::kWhatFillThisBuffer) { 168a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber onFillThisBuffer(msg); 169a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber } else if (what == ACodec::kWhatDrainThisBuffer) { 170a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber if ((mNumOutputBuffersReceived++ % 16) == 0) { 171a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber printf("."); 172a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber fflush(stdout); 173a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber } 174a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber 175a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber onDrainThisBuffer(msg); 176a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber } else if (what == ACodec::kWhatEOS) { 177a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber printf("$\n"); 178a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber 179a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber int64_t delayUs = ALooper::GetNowUs() - mStartTimeUs; 180a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber 181a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber if (mDecodeAudio) { 182a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber printf("%lld bytes received. %.2f KB/sec\n", 183a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber mTotalBytesReceived, 184a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber mTotalBytesReceived * 1E6 / 1024 / delayUs); 185a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber } else { 186a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber printf("%d frames decoded, %.2f fps. %lld bytes " 187a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber "received. %.2f KB/sec\n", 188a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber mNumOutputBuffersReceived, 189a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber mNumOutputBuffersReceived * 1E6 / delayUs, 190a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber mTotalBytesReceived, 191a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber mTotalBytesReceived * 1E6 / 1024 / delayUs); 192a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber } 193a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber 194a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber (new AMessage(kWhatStop, id()))->post(); 195a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber } else if (what == ACodec::kWhatFlushCompleted) { 196a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber mSeekState = SEEK_FLUSH_COMPLETED; 197a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber mCodec->signalResume(); 198a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber 199a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber (new AMessage(kWhatSeek, id()))->post(5000000ll); 2005ea137203b1304d607ee37ddebf60b60598ac2d3Andreas Huber } else if (what == ACodec::kWhatOutputFormatChanged) { 201a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber } else { 202a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber CHECK_EQ(what, (int32_t)ACodec::kWhatShutdownCompleted); 203a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber 204a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber mDecodeLooper->unregisterHandler(mCodec->id()); 205a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber 206a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber if (mDecodeLooper != looper()) { 207a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber mDecodeLooper->stop(); 208a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber } 209a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber 210a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber looper()->stop(); 211a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber } 212a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber break; 213a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber } 214a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber 215a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber default: 216a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber TRESPASS(); 217a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber break; 218a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber } 219a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber } 220a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber 221a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huberprivate: 222a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber enum { 223a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber kWhatStart = 'strt', 224a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber kWhatStop = 'stop', 225a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber kWhatCodecNotify = 'noti', 226a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber kWhatSeek = 'seek', 227a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber }; 228a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber 229a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber sp<ALooper> mDecodeLooper; 230a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber 231a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber AString mURI; 232a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber bool mDecodeAudio; 233a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber sp<Surface> mSurface; 234e366f52b1520f13306d5fef1c3c8a2b2c653d935Andreas Huber bool mRenderToSurface; 235a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber sp<ACodec> mCodec; 236a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber sp<MediaSource> mSource; 2373e408f39ef1c0513908a3b73da5ce6f4164e85d9Andreas Huber bool mIsVorbis; 238a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber 239a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber Vector<sp<ABuffer> > mCSD; 240a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber size_t mCSDIndex; 241a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber 242a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber MediaBuffer *mLeftOverBuffer; 243a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber status_t mFinalResult; 244a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber 245a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber int64_t mStartTimeUs; 246a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber int32_t mNumOutputBuffersReceived; 247a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber int64_t mTotalBytesReceived; 248a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber 249a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber enum SeekState { 250a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber SEEK_NONE, 251a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber SEEK_FLUSHING, 252a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber SEEK_FLUSH_COMPLETED, 253a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber }; 254a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber SeekState mSeekState; 255a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber int64_t mSeekTimeUs; 256a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber 257a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber sp<AMessage> makeFormat(const sp<MetaData> &meta) { 258a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber CHECK(mCSD.isEmpty()); 259a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber 260a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber const char *mime; 261a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber CHECK(meta->findCString(kKeyMIMEType, &mime)); 262a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber 263a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber sp<AMessage> msg = new AMessage; 264a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber msg->setString("mime", mime); 265a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber 266a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber if (!strncasecmp("video/", mime, 6)) { 267a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber int32_t width, height; 268a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber CHECK(meta->findInt32(kKeyWidth, &width)); 269a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber CHECK(meta->findInt32(kKeyHeight, &height)); 270a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber 271a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber msg->setInt32("width", width); 272a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber msg->setInt32("height", height); 273a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber } else { 274a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber CHECK(!strncasecmp("audio/", mime, 6)); 275a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber 276a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber int32_t numChannels, sampleRate; 277a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber CHECK(meta->findInt32(kKeyChannelCount, &numChannels)); 278a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber CHECK(meta->findInt32(kKeySampleRate, &sampleRate)); 279a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber 280a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber msg->setInt32("channel-count", numChannels); 281a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber msg->setInt32("sample-rate", sampleRate); 282a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber } 283a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber 284a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber uint32_t type; 285a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber const void *data; 286a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber size_t size; 287a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber if (meta->findData(kKeyAVCC, &type, &data, &size)) { 288a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber // Parse the AVCDecoderConfigurationRecord 289a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber 290a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber const uint8_t *ptr = (const uint8_t *)data; 291a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber 292a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber CHECK(size >= 7); 293a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber CHECK_EQ((unsigned)ptr[0], 1u); // configurationVersion == 1 294a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber uint8_t profile = ptr[1]; 295a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber uint8_t level = ptr[3]; 296a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber 297a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber // There is decodable content out there that fails the following 298a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber // assertion, let's be lenient for now... 299a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber // CHECK((ptr[4] >> 2) == 0x3f); // reserved 300a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber 301a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber size_t lengthSize = 1 + (ptr[4] & 3); 302a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber 303a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber // commented out check below as H264_QVGA_500_NO_AUDIO.3gp 304a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber // violates it... 305a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber // CHECK((ptr[5] >> 5) == 7); // reserved 306a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber 307a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber size_t numSeqParameterSets = ptr[5] & 31; 308a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber 309a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber ptr += 6; 310a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber size -= 6; 311a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber 312a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber sp<ABuffer> buffer = new ABuffer(1024); 313a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber buffer->setRange(0, 0); 314a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber 315a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber for (size_t i = 0; i < numSeqParameterSets; ++i) { 316a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber CHECK(size >= 2); 317a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber size_t length = U16_AT(ptr); 318a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber 319a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber ptr += 2; 320a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber size -= 2; 321a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber 322a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber CHECK(size >= length); 323a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber 324a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber memcpy(buffer->data() + buffer->size(), "\x00\x00\x00\x01", 4); 325a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber memcpy(buffer->data() + buffer->size() + 4, ptr, length); 326a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber buffer->setRange(0, buffer->size() + 4 + length); 327a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber 328a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber ptr += length; 329a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber size -= length; 330a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber } 331a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber 332a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber buffer->meta()->setInt32("csd", true); 333a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber mCSD.push(buffer); 334a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber 335a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber buffer = new ABuffer(1024); 336a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber buffer->setRange(0, 0); 337a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber 338a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber CHECK(size >= 1); 339a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber size_t numPictureParameterSets = *ptr; 340a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber ++ptr; 341a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber --size; 342a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber 343a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber for (size_t i = 0; i < numPictureParameterSets; ++i) { 344a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber CHECK(size >= 2); 345a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber size_t length = U16_AT(ptr); 346a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber 347a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber ptr += 2; 348a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber size -= 2; 349a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber 350a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber CHECK(size >= length); 351a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber 352a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber memcpy(buffer->data() + buffer->size(), "\x00\x00\x00\x01", 4); 353a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber memcpy(buffer->data() + buffer->size() + 4, ptr, length); 354a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber buffer->setRange(0, buffer->size() + 4 + length); 355a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber 356a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber ptr += length; 357a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber size -= length; 358a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber } 359a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber 360a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber buffer->meta()->setInt32("csd", true); 361a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber mCSD.push(buffer); 362a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber 363a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber msg->setObject("csd", buffer); 364a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber } else if (meta->findData(kKeyESDS, &type, &data, &size)) { 365a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber ESDS esds((const char *)data, size); 366a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber CHECK_EQ(esds.InitCheck(), (status_t)OK); 367a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber 368a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber const void *codec_specific_data; 369a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber size_t codec_specific_data_size; 370a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber esds.getCodecSpecificInfo( 371a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber &codec_specific_data, &codec_specific_data_size); 372a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber 373a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber sp<ABuffer> buffer = new ABuffer(codec_specific_data_size); 374a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber 375a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber memcpy(buffer->data(), codec_specific_data, 376a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber codec_specific_data_size); 377a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber 378a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber buffer->meta()->setInt32("csd", true); 379a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber mCSD.push(buffer); 3803e408f39ef1c0513908a3b73da5ce6f4164e85d9Andreas Huber } else if (meta->findData(kKeyVorbisInfo, &type, &data, &size)) { 3813e408f39ef1c0513908a3b73da5ce6f4164e85d9Andreas Huber sp<ABuffer> buffer = new ABuffer(size); 3823e408f39ef1c0513908a3b73da5ce6f4164e85d9Andreas Huber memcpy(buffer->data(), data, size); 3833e408f39ef1c0513908a3b73da5ce6f4164e85d9Andreas Huber 3843e408f39ef1c0513908a3b73da5ce6f4164e85d9Andreas Huber buffer->meta()->setInt32("csd", true); 3853e408f39ef1c0513908a3b73da5ce6f4164e85d9Andreas Huber mCSD.push(buffer); 3863e408f39ef1c0513908a3b73da5ce6f4164e85d9Andreas Huber 3873e408f39ef1c0513908a3b73da5ce6f4164e85d9Andreas Huber CHECK(meta->findData(kKeyVorbisBooks, &type, &data, &size)); 3883e408f39ef1c0513908a3b73da5ce6f4164e85d9Andreas Huber 3893e408f39ef1c0513908a3b73da5ce6f4164e85d9Andreas Huber buffer = new ABuffer(size); 3903e408f39ef1c0513908a3b73da5ce6f4164e85d9Andreas Huber memcpy(buffer->data(), data, size); 3913e408f39ef1c0513908a3b73da5ce6f4164e85d9Andreas Huber 3923e408f39ef1c0513908a3b73da5ce6f4164e85d9Andreas Huber buffer->meta()->setInt32("csd", true); 3933e408f39ef1c0513908a3b73da5ce6f4164e85d9Andreas Huber mCSD.push(buffer); 394a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber } 395a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber 396a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber int32_t maxInputSize; 397a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber if (meta->findInt32(kKeyMaxInputSize, &maxInputSize)) { 398a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber msg->setInt32("max-input-size", maxInputSize); 399a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber } 400a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber 401a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber return msg; 402a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber } 403a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber 404a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber void onFillThisBuffer(const sp<AMessage> &msg) { 405a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber sp<AMessage> reply; 406a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber CHECK(msg->findMessage("reply", &reply)); 407a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber 408a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber if (mSeekState == SEEK_FLUSHING) { 409a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber reply->post(); 410a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber return; 411a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber } 412a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber 413a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber sp<RefBase> obj; 414a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber CHECK(msg->findObject("buffer", &obj)); 415a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber sp<ABuffer> outBuffer = static_cast<ABuffer *>(obj.get()); 416a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber 417a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber if (mCSDIndex < mCSD.size()) { 418a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber outBuffer = mCSD.editItemAt(mCSDIndex++); 419a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber outBuffer->meta()->setInt64("timeUs", 0); 420a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber } else { 421a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber size_t sizeLeft = outBuffer->capacity(); 422a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber outBuffer->setRange(0, 0); 423a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber 424a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber int32_t n = 0; 425a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber 426a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber for (;;) { 427a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber MediaBuffer *inBuffer; 428a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber 429a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber if (mLeftOverBuffer != NULL) { 430a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber inBuffer = mLeftOverBuffer; 431a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber mLeftOverBuffer = NULL; 432a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber } else if (mFinalResult != OK) { 433a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber break; 434a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber } else { 435a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber MediaSource::ReadOptions options; 436a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber if (mSeekState == SEEK_FLUSH_COMPLETED) { 437a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber options.setSeekTo(mSeekTimeUs); 438a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber mSeekState = SEEK_NONE; 439a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber } 440a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber status_t err = mSource->read(&inBuffer, &options); 441a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber 442a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber if (err != OK) { 443a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber mFinalResult = err; 444a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber break; 445a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber } 446a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber } 447a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber 4483e408f39ef1c0513908a3b73da5ce6f4164e85d9Andreas Huber size_t sizeNeeded = inBuffer->range_length(); 4493e408f39ef1c0513908a3b73da5ce6f4164e85d9Andreas Huber if (mIsVorbis) { 4503e408f39ef1c0513908a3b73da5ce6f4164e85d9Andreas Huber // Vorbis data is suffixed with the number of 4513e408f39ef1c0513908a3b73da5ce6f4164e85d9Andreas Huber // valid samples on the page. 4523e408f39ef1c0513908a3b73da5ce6f4164e85d9Andreas Huber sizeNeeded += sizeof(int32_t); 4533e408f39ef1c0513908a3b73da5ce6f4164e85d9Andreas Huber } 4543e408f39ef1c0513908a3b73da5ce6f4164e85d9Andreas Huber 4553e408f39ef1c0513908a3b73da5ce6f4164e85d9Andreas Huber if (sizeNeeded > sizeLeft) { 456a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber if (outBuffer->size() == 0) { 457a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber LOGE("Unable to fit even a single input buffer of size %d.", 4583e408f39ef1c0513908a3b73da5ce6f4164e85d9Andreas Huber sizeNeeded); 459a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber } 460a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber CHECK_GT(outBuffer->size(), 0u); 461a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber 462a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber mLeftOverBuffer = inBuffer; 463a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber break; 464a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber } 465a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber 466a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber ++n; 467a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber 468a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber if (outBuffer->size() == 0) { 469a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber int64_t timeUs; 470a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber CHECK(inBuffer->meta_data()->findInt64(kKeyTime, &timeUs)); 471a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber 472a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber outBuffer->meta()->setInt64("timeUs", timeUs); 473a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber } 474a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber 475a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber memcpy(outBuffer->data() + outBuffer->size(), 476a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber (const uint8_t *)inBuffer->data() 477a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber + inBuffer->range_offset(), 478a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber inBuffer->range_length()); 479a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber 4803e408f39ef1c0513908a3b73da5ce6f4164e85d9Andreas Huber if (mIsVorbis) { 4813e408f39ef1c0513908a3b73da5ce6f4164e85d9Andreas Huber int32_t numPageSamples; 4823e408f39ef1c0513908a3b73da5ce6f4164e85d9Andreas Huber if (!inBuffer->meta_data()->findInt32( 4833e408f39ef1c0513908a3b73da5ce6f4164e85d9Andreas Huber kKeyValidSamples, &numPageSamples)) { 4843e408f39ef1c0513908a3b73da5ce6f4164e85d9Andreas Huber numPageSamples = -1; 4853e408f39ef1c0513908a3b73da5ce6f4164e85d9Andreas Huber } 4863e408f39ef1c0513908a3b73da5ce6f4164e85d9Andreas Huber 4873e408f39ef1c0513908a3b73da5ce6f4164e85d9Andreas Huber memcpy(outBuffer->data() 4883e408f39ef1c0513908a3b73da5ce6f4164e85d9Andreas Huber + outBuffer->size() + inBuffer->range_length(), 4893e408f39ef1c0513908a3b73da5ce6f4164e85d9Andreas Huber &numPageSamples, sizeof(numPageSamples)); 4903e408f39ef1c0513908a3b73da5ce6f4164e85d9Andreas Huber } 4913e408f39ef1c0513908a3b73da5ce6f4164e85d9Andreas Huber 492a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber outBuffer->setRange( 4933e408f39ef1c0513908a3b73da5ce6f4164e85d9Andreas Huber 0, outBuffer->size() + sizeNeeded); 494a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber 4953e408f39ef1c0513908a3b73da5ce6f4164e85d9Andreas Huber sizeLeft -= sizeNeeded; 496a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber 497a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber inBuffer->release(); 498a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber inBuffer = NULL; 499a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber 500e366f52b1520f13306d5fef1c3c8a2b2c653d935Andreas Huber break; // Don't coalesce 501a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber } 502a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber 503a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber LOGV("coalesced %d input buffers", n); 504a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber 505a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber if (outBuffer->size() == 0) { 506a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber CHECK_NE(mFinalResult, (status_t)OK); 507a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber 508a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber reply->setInt32("err", mFinalResult); 509a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber reply->post(); 510a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber return; 511a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber } 512a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber } 513a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber 514a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber reply->setObject("buffer", outBuffer); 515a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber reply->post(); 516a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber } 517a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber 518a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber void onDrainThisBuffer(const sp<AMessage> &msg) { 519a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber sp<RefBase> obj; 520a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber CHECK(msg->findObject("buffer", &obj)); 521a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber 522a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber sp<ABuffer> buffer = static_cast<ABuffer *>(obj.get()); 523a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber mTotalBytesReceived += buffer->size(); 524a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber 525a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber sp<AMessage> reply; 526a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber CHECK(msg->findMessage("reply", &reply)); 527a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber 528e366f52b1520f13306d5fef1c3c8a2b2c653d935Andreas Huber if (mRenderToSurface) { 529e366f52b1520f13306d5fef1c3c8a2b2c653d935Andreas Huber reply->setInt32("render", 1); 530e366f52b1520f13306d5fef1c3c8a2b2c653d935Andreas Huber } 531e366f52b1520f13306d5fef1c3c8a2b2c653d935Andreas Huber 532a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber reply->post(); 533a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber } 534a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber 535a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber DISALLOW_EVIL_CONSTRUCTORS(Controller); 536a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber}; 537a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber 538a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huberstatic void usage(const char *me) { 539a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber fprintf(stderr, "usage: %s\n", me); 540a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber fprintf(stderr, " -h(elp)\n"); 541a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber fprintf(stderr, " -a(udio)\n"); 542a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber 543a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber fprintf(stderr, 544e366f52b1520f13306d5fef1c3c8a2b2c653d935Andreas Huber " -S(urface) Allocate output buffers on a surface.\n" 545e366f52b1520f13306d5fef1c3c8a2b2c653d935Andreas Huber " -R(ender) Render surface-allocated buffers.\n"); 546a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber} 547a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber 548a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huberint main(int argc, char **argv) { 549a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber android::ProcessState::self()->startThreadPool(); 550a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber 551a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber bool decodeAudio = false; 552a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber bool useSurface = false; 553e366f52b1520f13306d5fef1c3c8a2b2c653d935Andreas Huber bool renderToSurface = false; 554a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber 555a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber int res; 556e366f52b1520f13306d5fef1c3c8a2b2c653d935Andreas Huber while ((res = getopt(argc, argv, "haSR")) >= 0) { 557a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber switch (res) { 558a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber case 'a': 559a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber decodeAudio = true; 560a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber break; 561a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber 562e366f52b1520f13306d5fef1c3c8a2b2c653d935Andreas Huber case 'S': 563a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber useSurface = true; 564a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber break; 565a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber 566e366f52b1520f13306d5fef1c3c8a2b2c653d935Andreas Huber case 'R': 567e366f52b1520f13306d5fef1c3c8a2b2c653d935Andreas Huber renderToSurface = true; 568e366f52b1520f13306d5fef1c3c8a2b2c653d935Andreas Huber break; 569e366f52b1520f13306d5fef1c3c8a2b2c653d935Andreas Huber 570a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber case '?': 571a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber case 'h': 572a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber default: 573a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber { 574a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber usage(argv[0]); 575a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber return 1; 576a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber } 577a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber } 578a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber } 579a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber 580a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber argc -= optind; 581a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber argv += optind; 582a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber 583a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber if (argc != 1) { 584a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber usage(argv[-optind]); 585a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber return 1; 586a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber } 587a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber 588a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber DataSource::RegisterDefaultSniffers(); 589a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber 590a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber sp<ALooper> looper = new ALooper; 591a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber looper->setName("sf2"); 592a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber 593a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber sp<SurfaceComposerClient> composerClient; 594a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber sp<SurfaceControl> control; 595a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber sp<Surface> surface; 596a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber 597a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber if (!decodeAudio && useSurface) { 598a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber composerClient = new SurfaceComposerClient; 599a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber CHECK_EQ(composerClient->initCheck(), (status_t)OK); 600a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber 601a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber control = composerClient->createSurface( 602a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber String8("A Surface"), 603a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber 0, 604a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber 1280, 605a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber 800, 606a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber PIXEL_FORMAT_RGB_565, 607a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber 0); 608a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber 609a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber CHECK(control != NULL); 610a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber CHECK(control->isValid()); 611a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber 612439863f3b3e725b5de1cba4940a21900369961c0Mathias Agopian SurfaceComposerClient::openGlobalTransaction(); 613c5a9766dc3cb0cab0c30528ffdb7bce6dfde1848Andreas Huber CHECK_EQ(control->setLayer(INT_MAX), (status_t)OK); 614a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber CHECK_EQ(control->show(), (status_t)OK); 615439863f3b3e725b5de1cba4940a21900369961c0Mathias Agopian SurfaceComposerClient::closeGlobalTransaction(); 616a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber 617a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber surface = control->getSurface(); 618a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber CHECK(surface != NULL); 619c5a9766dc3cb0cab0c30528ffdb7bce6dfde1848Andreas Huber 620c5a9766dc3cb0cab0c30528ffdb7bce6dfde1848Andreas Huber CHECK_EQ((status_t)OK, 621c5a9766dc3cb0cab0c30528ffdb7bce6dfde1848Andreas Huber native_window_api_connect( 622c5a9766dc3cb0cab0c30528ffdb7bce6dfde1848Andreas Huber surface.get(), NATIVE_WINDOW_API_MEDIA)); 623a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber } 624a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber 625e366f52b1520f13306d5fef1c3c8a2b2c653d935Andreas Huber sp<Controller> controller = 626e366f52b1520f13306d5fef1c3c8a2b2c653d935Andreas Huber new Controller(argv[0], decodeAudio, surface, renderToSurface); 627e366f52b1520f13306d5fef1c3c8a2b2c653d935Andreas Huber 628a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber looper->registerHandler(controller); 629a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber 630a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber controller->startAsync(); 631a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber 632a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber CHECK_EQ(looper->start(true /* runOnCallingThread */), (status_t)OK); 633a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber 634a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber looper->unregisterHandler(controller->id()); 635a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber 636a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber if (!decodeAudio && useSurface) { 637c5a9766dc3cb0cab0c30528ffdb7bce6dfde1848Andreas Huber CHECK_EQ((status_t)OK, 638c5a9766dc3cb0cab0c30528ffdb7bce6dfde1848Andreas Huber native_window_api_disconnect( 639c5a9766dc3cb0cab0c30528ffdb7bce6dfde1848Andreas Huber surface.get(), NATIVE_WINDOW_API_MEDIA)); 640c5a9766dc3cb0cab0c30528ffdb7bce6dfde1848Andreas Huber 641a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber composerClient->dispose(); 642a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber } 643a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber 644a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber return 0; 645a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber} 646a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber 647