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