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