sf2.cpp revision f933441648ef6a71dee783d733aac17b9508b452
1f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <binder/ProcessState.h>
2f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/foundation/hexdump.h>
4f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/foundation/ABuffer.h>
5f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/foundation/ADebug.h>
6f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/foundation/ALooper.h>
7f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/foundation/AMessage.h>
8f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
9f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/ACodec.h>
10f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/DataSource.h>
11f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/MediaBuffer.h>
12f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/MediaDefs.h>
13f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/MediaExtractor.h>
14f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/MediaSource.h>
15f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/MetaData.h>
16f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/Utils.h>
17f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
18f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <surfaceflinger/ISurfaceComposer.h>
19f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <surfaceflinger/SurfaceComposerClient.h>
20f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
21f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include "include/ESDS.h"
22f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
23f933441648ef6a71dee783d733aac17b9508b452Andreas Huberusing namespace android;
24f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
25f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct Controller : public AHandler {
26f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    Controller(const char *uri, bool decodeAudio, const sp<Surface> &surface)
27f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        : mURI(uri),
28f933441648ef6a71dee783d733aac17b9508b452Andreas Huber          mDecodeAudio(decodeAudio),
29f933441648ef6a71dee783d733aac17b9508b452Andreas Huber          mSurface(surface),
30f933441648ef6a71dee783d733aac17b9508b452Andreas Huber          mCodec(new ACodec) {
31f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK(!mDecodeAudio || mSurface == NULL);
32f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
33f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
34f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void startAsync() {
35f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        (new AMessage(kWhatStart, id()))->post();
36f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
37f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
38f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
39f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual ~Controller() {
40f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
41f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
42f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onMessageReceived(const sp<AMessage> &msg) {
43f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        switch (msg->what()) {
44f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            case kWhatStart:
45f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            {
46f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#if 1
47f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mDecodeLooper = looper();
48f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#else
49f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mDecodeLooper = new ALooper;
50f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mDecodeLooper->setName("sf2 decode looper");
51f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mDecodeLooper->start();
52f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#endif
53f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
54f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                sp<DataSource> dataSource =
55f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    DataSource::CreateFromURI(mURI.c_str());
56f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
57f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                sp<MediaExtractor> extractor =
58f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    MediaExtractor::Create(dataSource);
59f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
60f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                for (size_t i = 0; i < extractor->countTracks(); ++i) {
61f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    sp<MetaData> meta = extractor->getTrackMetaData(i);
62f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
63f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    const char *mime;
64f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    CHECK(meta->findCString(kKeyMIMEType, &mime));
65f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
66f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    if (!strncasecmp(mDecodeAudio ? "audio/" : "video/",
67f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                                     mime, 6)) {
68f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mSource = extractor->getTrack(i);
69f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        break;
70f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    }
71f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
72f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(mSource != NULL);
73f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
74f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mSource->start(), (status_t)OK);
75f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
76f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mDecodeLooper->registerHandler(mCodec);
77f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
78f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->setNotificationMessage(
79f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        new AMessage(kWhatCodecNotify, id()));
80f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
81f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                sp<AMessage> format = makeFormat(mSource->getFormat());
82f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
83f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (mSurface != NULL) {
84f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    format->setObject("surface", mSurface);
85f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
86f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
87f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->initiateSetup(format);
88f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
89f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCSDIndex = 0;
90f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mStartTimeUs = ALooper::GetNowUs();
91f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mNumOutputBuffersReceived = 0;
92f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mTotalBytesReceived = 0;
93f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mLeftOverBuffer = NULL;
94f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mFinalResult = OK;
95f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mSeekState = SEEK_NONE;
96f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
97f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // (new AMessage(kWhatSeek, id()))->post(5000000ll);
98f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
99f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
100f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
101f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            case kWhatSeek:
102f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            {
103f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                printf("+");
104f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                fflush(stdout);
105f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
106f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(mSeekState == SEEK_NONE
107f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        || mSeekState == SEEK_FLUSH_COMPLETED);
108f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
109f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (mLeftOverBuffer != NULL) {
110f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mLeftOverBuffer->release();
111f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mLeftOverBuffer = NULL;
112f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
113f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
114f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mSeekState = SEEK_FLUSHING;
115f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mSeekTimeUs = 30000000ll;
116f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
117f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->signalFlush();
118f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
119f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
120f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
121f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            case kWhatStop:
122f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            {
123f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (mLeftOverBuffer != NULL) {
124f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mLeftOverBuffer->release();
125f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mLeftOverBuffer = NULL;
126f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
127f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
128f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mSource->stop(), (status_t)OK);
129f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mSource.clear();
130f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
131f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->initiateShutdown();
132f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
133f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
134f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
135f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            case kWhatCodecNotify:
136f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            {
137f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                int32_t what;
138f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(msg->findInt32("what", &what));
139f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
140f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (what == ACodec::kWhatFillThisBuffer) {
141f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    onFillThisBuffer(msg);
142f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                } else if (what == ACodec::kWhatDrainThisBuffer) {
143f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    if ((mNumOutputBuffersReceived++ % 16) == 0) {
144f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        printf(".");
145f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        fflush(stdout);
146f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    }
147f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
148f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    onDrainThisBuffer(msg);
149f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                } else if (what == ACodec::kWhatEOS) {
150f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    printf("$\n");
151f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
152f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    int64_t delayUs = ALooper::GetNowUs() - mStartTimeUs;
153f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
154f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    if (mDecodeAudio) {
155f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        printf("%lld bytes received. %.2f KB/sec\n",
156f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                               mTotalBytesReceived,
157f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                               mTotalBytesReceived * 1E6 / 1024 / delayUs);
158f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    } else {
159f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        printf("%d frames decoded, %.2f fps. %lld bytes "
160f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                               "received. %.2f KB/sec\n",
161f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                               mNumOutputBuffersReceived,
162f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                               mNumOutputBuffersReceived * 1E6 / delayUs,
163f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                               mTotalBytesReceived,
164f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                               mTotalBytesReceived * 1E6 / 1024 / delayUs);
165f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    }
166f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
167f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    (new AMessage(kWhatStop, id()))->post();
168f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                } else if (what == ACodec::kWhatFlushCompleted) {
169f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mSeekState = SEEK_FLUSH_COMPLETED;
170f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mCodec->signalResume();
171f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
172f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    (new AMessage(kWhatSeek, id()))->post(5000000ll);
173f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                } else {
174f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    CHECK_EQ(what, (int32_t)ACodec::kWhatShutdownCompleted);
175f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
176f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mDecodeLooper->unregisterHandler(mCodec->id());
177f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
178f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    if (mDecodeLooper != looper()) {
179f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mDecodeLooper->stop();
180f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    }
181f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
182f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    looper()->stop();
183f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
184f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
185f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
186f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
187f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            default:
188f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                TRESPASS();
189f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
190f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
191f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
192f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
193f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
194f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    enum {
195f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        kWhatStart             = 'strt',
196f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        kWhatStop              = 'stop',
197f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        kWhatCodecNotify       = 'noti',
198f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        kWhatSeek              = 'seek',
199f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    };
200f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
201f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<ALooper> mDecodeLooper;
202f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
203f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    AString mURI;
204f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool mDecodeAudio;
205f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<Surface> mSurface;
206f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<ACodec> mCodec;
207f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<MediaSource> mSource;
208f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
209f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    Vector<sp<ABuffer> > mCSD;
210f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    size_t mCSDIndex;
211f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
212f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    MediaBuffer *mLeftOverBuffer;
213f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t mFinalResult;
214f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
215f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int64_t mStartTimeUs;
216f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t mNumOutputBuffersReceived;
217f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int64_t mTotalBytesReceived;
218f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
219f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    enum SeekState {
220f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        SEEK_NONE,
221f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        SEEK_FLUSHING,
222f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        SEEK_FLUSH_COMPLETED,
223f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    };
224f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    SeekState mSeekState;
225f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int64_t mSeekTimeUs;
226f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
227f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<AMessage> makeFormat(const sp<MetaData> &meta) {
228f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK(mCSD.isEmpty());
229f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
230f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *mime;
231f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK(meta->findCString(kKeyMIMEType, &mime));
232f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
233f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sp<AMessage> msg = new AMessage;
234f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        msg->setString("mime", mime);
235f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
236f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (!strncasecmp("video/", mime, 6)) {
237f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int32_t width, height;
238f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(meta->findInt32(kKeyWidth, &width));
239f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(meta->findInt32(kKeyHeight, &height));
240f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
241f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            msg->setInt32("width", width);
242f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            msg->setInt32("height", height);
243f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        } else {
244f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(!strncasecmp("audio/", mime, 6));
245f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
246f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int32_t numChannels, sampleRate;
247f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(meta->findInt32(kKeyChannelCount, &numChannels));
248f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(meta->findInt32(kKeySampleRate, &sampleRate));
249f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
250f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            msg->setInt32("channel-count", numChannels);
251f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            msg->setInt32("sample-rate", sampleRate);
252f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
253f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
254f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        uint32_t type;
255f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const void *data;
256f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        size_t size;
257f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (meta->findData(kKeyAVCC, &type, &data, &size)) {
258f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // Parse the AVCDecoderConfigurationRecord
259f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
260f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            const uint8_t *ptr = (const uint8_t *)data;
261f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
262f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(size >= 7);
263f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((unsigned)ptr[0], 1u);  // configurationVersion == 1
264f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            uint8_t profile = ptr[1];
265f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            uint8_t level = ptr[3];
266f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
267f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // There is decodable content out there that fails the following
268f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // assertion, let's be lenient for now...
269f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // CHECK((ptr[4] >> 2) == 0x3f);  // reserved
270f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
271f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            size_t lengthSize = 1 + (ptr[4] & 3);
272f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
273f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // commented out check below as H264_QVGA_500_NO_AUDIO.3gp
274f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // violates it...
275f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // CHECK((ptr[5] >> 5) == 7);  // reserved
276f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
277f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            size_t numSeqParameterSets = ptr[5] & 31;
278f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
279f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            ptr += 6;
280f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            size -= 6;
281f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
282f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            sp<ABuffer> buffer = new ABuffer(1024);
283f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            buffer->setRange(0, 0);
284f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
285f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            for (size_t i = 0; i < numSeqParameterSets; ++i) {
286f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(size >= 2);
287f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                size_t length = U16_AT(ptr);
288f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
289f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                ptr += 2;
290f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                size -= 2;
291f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
292f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(size >= length);
293f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
294f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                memcpy(buffer->data() + buffer->size(), "\x00\x00\x00\x01", 4);
295f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                memcpy(buffer->data() + buffer->size() + 4, ptr, length);
296f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                buffer->setRange(0, buffer->size() + 4 + length);
297f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
298f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                ptr += length;
299f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                size -= length;
300f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
301f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
302f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            buffer->meta()->setInt32("csd", true);
303f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCSD.push(buffer);
304f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
305f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            buffer = new ABuffer(1024);
306f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            buffer->setRange(0, 0);
307f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
308f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(size >= 1);
309f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            size_t numPictureParameterSets = *ptr;
310f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            ++ptr;
311f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            --size;
312f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
313f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            for (size_t i = 0; i < numPictureParameterSets; ++i) {
314f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(size >= 2);
315f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                size_t length = U16_AT(ptr);
316f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
317f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                ptr += 2;
318f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                size -= 2;
319f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
320f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(size >= length);
321f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
322f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                memcpy(buffer->data() + buffer->size(), "\x00\x00\x00\x01", 4);
323f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                memcpy(buffer->data() + buffer->size() + 4, ptr, length);
324f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                buffer->setRange(0, buffer->size() + 4 + length);
325f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
326f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                ptr += length;
327f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                size -= length;
328f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
329f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
330f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            buffer->meta()->setInt32("csd", true);
331f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCSD.push(buffer);
332f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
333f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            msg->setObject("csd", buffer);
334f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        } else if (meta->findData(kKeyESDS, &type, &data, &size)) {
335f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            ESDS esds((const char *)data, size);
336f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(esds.InitCheck(), (status_t)OK);
337f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
338f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            const void *codec_specific_data;
339f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            size_t codec_specific_data_size;
340f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            esds.getCodecSpecificInfo(
341f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    &codec_specific_data, &codec_specific_data_size);
342f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
343f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            sp<ABuffer> buffer = new ABuffer(codec_specific_data_size);
344f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
345f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            memcpy(buffer->data(), codec_specific_data,
346f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                   codec_specific_data_size);
347f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
348f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            buffer->meta()->setInt32("csd", true);
349f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCSD.push(buffer);
350f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
351f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
352f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        int32_t maxInputSize;
353f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (meta->findInt32(kKeyMaxInputSize, &maxInputSize)) {
354f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            msg->setInt32("max-input-size", maxInputSize);
355f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
356f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
357f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return msg;
358f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
359f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
360f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void onFillThisBuffer(const sp<AMessage> &msg) {
361f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sp<AMessage> reply;
362f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK(msg->findMessage("reply", &reply));
363f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
364f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (mSeekState == SEEK_FLUSHING) {
365f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            reply->post();
366f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return;
367f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
368f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
369f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sp<RefBase> obj;
370f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK(msg->findObject("buffer", &obj));
371f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sp<ABuffer> outBuffer = static_cast<ABuffer *>(obj.get());
372f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
373f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (mCSDIndex < mCSD.size()) {
374f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            outBuffer = mCSD.editItemAt(mCSDIndex++);
375f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            outBuffer->meta()->setInt64("timeUs", 0);
376f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        } else {
377f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            size_t sizeLeft = outBuffer->capacity();
378f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            outBuffer->setRange(0, 0);
379f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
380f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int32_t n = 0;
381f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
382f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            for (;;) {
383f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                MediaBuffer *inBuffer;
384f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
385f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (mLeftOverBuffer != NULL) {
386f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    inBuffer = mLeftOverBuffer;
387f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mLeftOverBuffer = NULL;
388f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                } else if (mFinalResult != OK) {
389f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    break;
390f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                } else {
391f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    MediaSource::ReadOptions options;
392f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    if (mSeekState == SEEK_FLUSH_COMPLETED) {
393f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        options.setSeekTo(mSeekTimeUs);
394f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mSeekState = SEEK_NONE;
395f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    }
396f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    status_t err = mSource->read(&inBuffer, &options);
397f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
398f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    if (err != OK) {
399f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mFinalResult = err;
400f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        break;
401f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    }
402f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
403f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
404f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (inBuffer->range_length() > sizeLeft) {
405f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    if (outBuffer->size() == 0) {
406f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        LOGE("Unable to fit even a single input buffer of size %d.",
407f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                             inBuffer->range_length());
408f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    }
409f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    CHECK_GT(outBuffer->size(), 0u);
410f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
411f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mLeftOverBuffer = inBuffer;
412f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    break;
413f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
414f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
415f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                ++n;
416f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
417f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (outBuffer->size() == 0) {
418f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    int64_t timeUs;
419f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    CHECK(inBuffer->meta_data()->findInt64(kKeyTime, &timeUs));
420f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
421f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    outBuffer->meta()->setInt64("timeUs", timeUs);
422f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
423f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
424f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                memcpy(outBuffer->data() + outBuffer->size(),
425f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                       (const uint8_t *)inBuffer->data()
426f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        + inBuffer->range_offset(),
427f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                       inBuffer->range_length());
428f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
429f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                outBuffer->setRange(
430f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        0, outBuffer->size() + inBuffer->range_length());
431f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
432f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                sizeLeft -= inBuffer->range_length();
433f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
434f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                inBuffer->release();
435f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                inBuffer = NULL;
436f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
437f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // break;  // Don't coalesce
438f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
439f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
440f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            LOGV("coalesced %d input buffers", n);
441f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
442f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (outBuffer->size() == 0) {
443f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_NE(mFinalResult, (status_t)OK);
444f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
445f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                reply->setInt32("err", mFinalResult);
446f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                reply->post();
447f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                return;
448f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
449f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
450f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
451f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        reply->setObject("buffer", outBuffer);
452f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        reply->post();
453f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
454f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
455f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void onDrainThisBuffer(const sp<AMessage> &msg) {
456f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sp<RefBase> obj;
457f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK(msg->findObject("buffer", &obj));
458f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
459f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sp<ABuffer> buffer = static_cast<ABuffer *>(obj.get());
460f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mTotalBytesReceived += buffer->size();
461f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
462f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sp<AMessage> reply;
463f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK(msg->findMessage("reply", &reply));
464f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
465f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        reply->post();
466f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
467f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
468f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(Controller);
469f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
470f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
471f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatic void usage(const char *me) {
472f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    fprintf(stderr, "usage: %s\n", me);
473f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    fprintf(stderr, "       -h(elp)\n");
474f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    fprintf(stderr, "       -a(udio)\n");
475f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
476f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    fprintf(stderr,
477f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "       -s(surface) Allocate output buffers on a surface.\n");
478f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
479f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
480f933441648ef6a71dee783d733aac17b9508b452Andreas Huberint main(int argc, char **argv) {
481f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    android::ProcessState::self()->startThreadPool();
482f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
483f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool decodeAudio = false;
484f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool useSurface = false;
485f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
486f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int res;
487f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    while ((res = getopt(argc, argv, "has")) >= 0) {
488f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        switch (res) {
489f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            case 'a':
490f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                decodeAudio = true;
491f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
492f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
493f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            case 's':
494f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                useSurface = true;
495f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
496f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
497f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            case '?':
498f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            case 'h':
499f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            default:
500f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            {
501f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                usage(argv[0]);
502f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                return 1;
503f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
504f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
505f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
506f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
507f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    argc -= optind;
508f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    argv += optind;
509f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
510f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (argc != 1) {
511f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        usage(argv[-optind]);
512f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return 1;
513f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
514f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
515f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DataSource::RegisterDefaultSniffers();
516f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
517f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<ALooper> looper = new ALooper;
518f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    looper->setName("sf2");
519f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
520f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<SurfaceComposerClient> composerClient;
521f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<SurfaceControl> control;
522f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<Surface> surface;
523f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
524f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (!decodeAudio && useSurface) {
525f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        composerClient = new SurfaceComposerClient;
526f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ(composerClient->initCheck(), (status_t)OK);
527f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
528f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        control = composerClient->createSurface(
529f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                getpid(),
530f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                String8("A Surface"),
531f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                0,
532f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                1280,
533f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                800,
534f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                PIXEL_FORMAT_RGB_565,
535f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                0);
536f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
537f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK(control != NULL);
538f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK(control->isValid());
539f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
540f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ(composerClient->openTransaction(), (status_t)OK);
541f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ(control->setLayer(30000), (status_t)OK);
542f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ(control->show(), (status_t)OK);
543f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ(composerClient->closeTransaction(), (status_t)OK);
544f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
545f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        surface = control->getSurface();
546f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK(surface != NULL);
547f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
548f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
549f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<Controller> controller = new Controller(argv[0], decodeAudio, surface);
550f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    looper->registerHandler(controller);
551f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
552f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    controller->startAsync();
553f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
554f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(looper->start(true /* runOnCallingThread */), (status_t)OK);
555f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
556f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    looper->unregisterHandler(controller->id());
557f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
558f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (!decodeAudio && useSurface) {
559f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        composerClient->dispose();
560f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
561f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
562f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return 0;
563f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
564f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
565