1199d1c131d29b5356f71fbd7826a592c1dd8575fJames Dong/*
2199d1c131d29b5356f71fbd7826a592c1dd8575fJames Dong * Copyright (C) 2010 The Android Open Source Project
3199d1c131d29b5356f71fbd7826a592c1dd8575fJames Dong *
4199d1c131d29b5356f71fbd7826a592c1dd8575fJames Dong * Licensed under the Apache License, Version 2.0 (the "License");
5199d1c131d29b5356f71fbd7826a592c1dd8575fJames Dong * you may not use this file except in compliance with the License.
6199d1c131d29b5356f71fbd7826a592c1dd8575fJames Dong * You may obtain a copy of the License at
7199d1c131d29b5356f71fbd7826a592c1dd8575fJames Dong *
8199d1c131d29b5356f71fbd7826a592c1dd8575fJames Dong *      http://www.apache.org/licenses/LICENSE-2.0
9199d1c131d29b5356f71fbd7826a592c1dd8575fJames Dong *
10199d1c131d29b5356f71fbd7826a592c1dd8575fJames Dong * Unless required by applicable law or agreed to in writing, software
11199d1c131d29b5356f71fbd7826a592c1dd8575fJames Dong * distributed under the License is distributed on an "AS IS" BASIS,
12199d1c131d29b5356f71fbd7826a592c1dd8575fJames Dong * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13199d1c131d29b5356f71fbd7826a592c1dd8575fJames Dong * See the License for the specific language governing permissions and
14199d1c131d29b5356f71fbd7826a592c1dd8575fJames Dong * limitations under the License.
15199d1c131d29b5356f71fbd7826a592c1dd8575fJames Dong */
16199d1c131d29b5356f71fbd7826a592c1dd8575fJames Dong
17ced159b1d839b24775525ccb736876e7cb7e649dAndreas Huber//#define LOG_NDEBUG 0
18ced159b1d839b24775525ccb736876e7cb7e649dAndreas Huber#define LOG_TAG "stream"
19ced159b1d839b24775525ccb736876e7cb7e649dAndreas Huber#include "utils/Log.h"
20ced159b1d839b24775525ccb736876e7cb7e649dAndreas Huber
2152b52cdfb7502d5a0fd7bba21d1daa3e36a54e42Andreas Huber#include <binder/ProcessState.h>
2252b52cdfb7502d5a0fd7bba21d1daa3e36a54e42Andreas Huber
2352b52cdfb7502d5a0fd7bba21d1daa3e36a54e42Andreas Huber#include <media/IStreamSource.h>
2452b52cdfb7502d5a0fd7bba21d1daa3e36a54e42Andreas Huber#include <media/mediaplayer.h>
2552b52cdfb7502d5a0fd7bba21d1daa3e36a54e42Andreas Huber#include <media/stagefright/foundation/ADebug.h>
26ae9d5072534de65d9ea41def2e1b4258a1731ca4Andreas Huber#include <media/stagefright/foundation/AMessage.h>
27eb9163071573e9c6133b6c23351c1274e7fc3cd8Andreas Huber#include <media/stagefright/DataSource.h>
28eb9163071573e9c6133b6c23351c1274e7fc3cd8Andreas Huber#include <media/stagefright/MPEG2TSWriter.h>
29eb9163071573e9c6133b6c23351c1274e7fc3cd8Andreas Huber#include <media/stagefright/MediaExtractor.h>
30eb9163071573e9c6133b6c23351c1274e7fc3cd8Andreas Huber#include <media/stagefright/MediaSource.h>
31eb9163071573e9c6133b6c23351c1274e7fc3cd8Andreas Huber#include <media/stagefright/MetaData.h>
3252b52cdfb7502d5a0fd7bba21d1daa3e36a54e42Andreas Huber
3352b52cdfb7502d5a0fd7bba21d1daa3e36a54e42Andreas Huber#include <binder/IServiceManager.h>
3452b52cdfb7502d5a0fd7bba21d1daa3e36a54e42Andreas Huber#include <media/IMediaPlayerService.h>
3552b52cdfb7502d5a0fd7bba21d1daa3e36a54e42Andreas Huber#include <surfaceflinger/ISurfaceComposer.h>
3652b52cdfb7502d5a0fd7bba21d1daa3e36a54e42Andreas Huber#include <surfaceflinger/SurfaceComposerClient.h>
3752b52cdfb7502d5a0fd7bba21d1daa3e36a54e42Andreas Huber
3852b52cdfb7502d5a0fd7bba21d1daa3e36a54e42Andreas Huber#include <fcntl.h>
3952b52cdfb7502d5a0fd7bba21d1daa3e36a54e42Andreas Huber
4052b52cdfb7502d5a0fd7bba21d1daa3e36a54e42Andreas Huberusing namespace android;
4152b52cdfb7502d5a0fd7bba21d1daa3e36a54e42Andreas Huber
4252b52cdfb7502d5a0fd7bba21d1daa3e36a54e42Andreas Huberstruct MyStreamSource : public BnStreamSource {
43eb9163071573e9c6133b6c23351c1274e7fc3cd8Andreas Huber    // Object assumes ownership of fd.
4452b52cdfb7502d5a0fd7bba21d1daa3e36a54e42Andreas Huber    MyStreamSource(int fd);
4552b52cdfb7502d5a0fd7bba21d1daa3e36a54e42Andreas Huber
4652b52cdfb7502d5a0fd7bba21d1daa3e36a54e42Andreas Huber    virtual void setListener(const sp<IStreamListener> &listener);
4752b52cdfb7502d5a0fd7bba21d1daa3e36a54e42Andreas Huber    virtual void setBuffers(const Vector<sp<IMemory> > &buffers);
4852b52cdfb7502d5a0fd7bba21d1daa3e36a54e42Andreas Huber
4952b52cdfb7502d5a0fd7bba21d1daa3e36a54e42Andreas Huber    virtual void onBufferAvailable(size_t index);
5052b52cdfb7502d5a0fd7bba21d1daa3e36a54e42Andreas Huber
5152b52cdfb7502d5a0fd7bba21d1daa3e36a54e42Andreas Huberprotected:
5252b52cdfb7502d5a0fd7bba21d1daa3e36a54e42Andreas Huber    virtual ~MyStreamSource();
5352b52cdfb7502d5a0fd7bba21d1daa3e36a54e42Andreas Huber
5452b52cdfb7502d5a0fd7bba21d1daa3e36a54e42Andreas Huberprivate:
5552b52cdfb7502d5a0fd7bba21d1daa3e36a54e42Andreas Huber    int mFd;
56a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber    off64_t mFileSize;
57ced159b1d839b24775525ccb736876e7cb7e649dAndreas Huber    uint64_t mNumPacketsSent;
5852b52cdfb7502d5a0fd7bba21d1daa3e36a54e42Andreas Huber
5952b52cdfb7502d5a0fd7bba21d1daa3e36a54e42Andreas Huber    sp<IStreamListener> mListener;
6052b52cdfb7502d5a0fd7bba21d1daa3e36a54e42Andreas Huber    Vector<sp<IMemory> > mBuffers;
6152b52cdfb7502d5a0fd7bba21d1daa3e36a54e42Andreas Huber
6252b52cdfb7502d5a0fd7bba21d1daa3e36a54e42Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(MyStreamSource);
6352b52cdfb7502d5a0fd7bba21d1daa3e36a54e42Andreas Huber};
6452b52cdfb7502d5a0fd7bba21d1daa3e36a54e42Andreas Huber
6552b52cdfb7502d5a0fd7bba21d1daa3e36a54e42Andreas HuberMyStreamSource::MyStreamSource(int fd)
66a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber    : mFd(fd),
67a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber      mFileSize(0),
68ced159b1d839b24775525ccb736876e7cb7e649dAndreas Huber      mNumPacketsSent(0) {
6952b52cdfb7502d5a0fd7bba21d1daa3e36a54e42Andreas Huber    CHECK_GE(fd, 0);
70a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber
71a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber    mFileSize = lseek64(fd, 0, SEEK_END);
72a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber    lseek64(fd, 0, SEEK_SET);
7352b52cdfb7502d5a0fd7bba21d1daa3e36a54e42Andreas Huber}
7452b52cdfb7502d5a0fd7bba21d1daa3e36a54e42Andreas Huber
7552b52cdfb7502d5a0fd7bba21d1daa3e36a54e42Andreas HuberMyStreamSource::~MyStreamSource() {
76eb9163071573e9c6133b6c23351c1274e7fc3cd8Andreas Huber    close(mFd);
77eb9163071573e9c6133b6c23351c1274e7fc3cd8Andreas Huber    mFd = -1;
7852b52cdfb7502d5a0fd7bba21d1daa3e36a54e42Andreas Huber}
7952b52cdfb7502d5a0fd7bba21d1daa3e36a54e42Andreas Huber
8052b52cdfb7502d5a0fd7bba21d1daa3e36a54e42Andreas Hubervoid MyStreamSource::setListener(const sp<IStreamListener> &listener) {
8152b52cdfb7502d5a0fd7bba21d1daa3e36a54e42Andreas Huber    mListener = listener;
8252b52cdfb7502d5a0fd7bba21d1daa3e36a54e42Andreas Huber}
8352b52cdfb7502d5a0fd7bba21d1daa3e36a54e42Andreas Huber
8452b52cdfb7502d5a0fd7bba21d1daa3e36a54e42Andreas Hubervoid MyStreamSource::setBuffers(const Vector<sp<IMemory> > &buffers) {
8552b52cdfb7502d5a0fd7bba21d1daa3e36a54e42Andreas Huber    mBuffers = buffers;
8652b52cdfb7502d5a0fd7bba21d1daa3e36a54e42Andreas Huber}
8752b52cdfb7502d5a0fd7bba21d1daa3e36a54e42Andreas Huber
8852b52cdfb7502d5a0fd7bba21d1daa3e36a54e42Andreas Hubervoid MyStreamSource::onBufferAvailable(size_t index) {
8952b52cdfb7502d5a0fd7bba21d1daa3e36a54e42Andreas Huber    CHECK_LT(index, mBuffers.size());
90a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber
91ced159b1d839b24775525ccb736876e7cb7e649dAndreas Huber#if 0
92ced159b1d839b24775525ccb736876e7cb7e649dAndreas Huber    if (mNumPacketsSent >= 20000) {
93ced159b1d839b24775525ccb736876e7cb7e649dAndreas Huber        LOGI("signalling discontinuity now");
94ced159b1d839b24775525ccb736876e7cb7e649dAndreas Huber
95ced159b1d839b24775525ccb736876e7cb7e649dAndreas Huber        off64_t offset = 0;
96ced159b1d839b24775525ccb736876e7cb7e649dAndreas Huber        CHECK((offset % 188) == 0);
97a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber
98a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber        lseek(mFd, offset, SEEK_SET);
99a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber
100ced159b1d839b24775525ccb736876e7cb7e649dAndreas Huber        sp<AMessage> extra = new AMessage;
101ced159b1d839b24775525ccb736876e7cb7e649dAndreas Huber        extra->setInt32(IStreamListener::kKeyFormatChange, 0);
102ced159b1d839b24775525ccb736876e7cb7e649dAndreas Huber
103a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber        mListener->issueCommand(
104ced159b1d839b24775525ccb736876e7cb7e649dAndreas Huber                IStreamListener::DISCONTINUITY, false /* synchronous */, extra);
105a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber
106ced159b1d839b24775525ccb736876e7cb7e649dAndreas Huber        mNumPacketsSent = 0;
107a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber    }
108ced159b1d839b24775525ccb736876e7cb7e649dAndreas Huber#endif
109a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber
11052b52cdfb7502d5a0fd7bba21d1daa3e36a54e42Andreas Huber    sp<IMemory> mem = mBuffers.itemAt(index);
11152b52cdfb7502d5a0fd7bba21d1daa3e36a54e42Andreas Huber
11252b52cdfb7502d5a0fd7bba21d1daa3e36a54e42Andreas Huber    ssize_t n = read(mFd, mem->pointer(), mem->size());
11352b52cdfb7502d5a0fd7bba21d1daa3e36a54e42Andreas Huber    if (n <= 0) {
114ae9d5072534de65d9ea41def2e1b4258a1731ca4Andreas Huber        mListener->issueCommand(IStreamListener::EOS, false /* synchronous */);
11552b52cdfb7502d5a0fd7bba21d1daa3e36a54e42Andreas Huber    } else {
11652b52cdfb7502d5a0fd7bba21d1daa3e36a54e42Andreas Huber        mListener->queueBuffer(index, n);
117ced159b1d839b24775525ccb736876e7cb7e649dAndreas Huber
118ced159b1d839b24775525ccb736876e7cb7e649dAndreas Huber        mNumPacketsSent += n / 188;
11952b52cdfb7502d5a0fd7bba21d1daa3e36a54e42Andreas Huber    }
12052b52cdfb7502d5a0fd7bba21d1daa3e36a54e42Andreas Huber}
121eb9163071573e9c6133b6c23351c1274e7fc3cd8Andreas Huber////////////////////////////////////////////////////////////////////////////////
122eb9163071573e9c6133b6c23351c1274e7fc3cd8Andreas Huber
123eb9163071573e9c6133b6c23351c1274e7fc3cd8Andreas Huberstruct MyConvertingStreamSource : public BnStreamSource {
124eb9163071573e9c6133b6c23351c1274e7fc3cd8Andreas Huber    MyConvertingStreamSource(const char *filename);
125eb9163071573e9c6133b6c23351c1274e7fc3cd8Andreas Huber
126eb9163071573e9c6133b6c23351c1274e7fc3cd8Andreas Huber    virtual void setListener(const sp<IStreamListener> &listener);
127eb9163071573e9c6133b6c23351c1274e7fc3cd8Andreas Huber    virtual void setBuffers(const Vector<sp<IMemory> > &buffers);
128eb9163071573e9c6133b6c23351c1274e7fc3cd8Andreas Huber
129eb9163071573e9c6133b6c23351c1274e7fc3cd8Andreas Huber    virtual void onBufferAvailable(size_t index);
130eb9163071573e9c6133b6c23351c1274e7fc3cd8Andreas Huber
131eb9163071573e9c6133b6c23351c1274e7fc3cd8Andreas Huberprotected:
132eb9163071573e9c6133b6c23351c1274e7fc3cd8Andreas Huber    virtual ~MyConvertingStreamSource();
133eb9163071573e9c6133b6c23351c1274e7fc3cd8Andreas Huber
134eb9163071573e9c6133b6c23351c1274e7fc3cd8Andreas Huberprivate:
135eb9163071573e9c6133b6c23351c1274e7fc3cd8Andreas Huber    Mutex mLock;
136eb9163071573e9c6133b6c23351c1274e7fc3cd8Andreas Huber    Condition mCondition;
137eb9163071573e9c6133b6c23351c1274e7fc3cd8Andreas Huber
138eb9163071573e9c6133b6c23351c1274e7fc3cd8Andreas Huber    sp<IStreamListener> mListener;
139eb9163071573e9c6133b6c23351c1274e7fc3cd8Andreas Huber    Vector<sp<IMemory> > mBuffers;
140eb9163071573e9c6133b6c23351c1274e7fc3cd8Andreas Huber
141eb9163071573e9c6133b6c23351c1274e7fc3cd8Andreas Huber    sp<MPEG2TSWriter> mWriter;
142eb9163071573e9c6133b6c23351c1274e7fc3cd8Andreas Huber
143eb9163071573e9c6133b6c23351c1274e7fc3cd8Andreas Huber    ssize_t mCurrentBufferIndex;
144eb9163071573e9c6133b6c23351c1274e7fc3cd8Andreas Huber    size_t mCurrentBufferOffset;
145eb9163071573e9c6133b6c23351c1274e7fc3cd8Andreas Huber
146eb9163071573e9c6133b6c23351c1274e7fc3cd8Andreas Huber    List<size_t> mBufferQueue;
147eb9163071573e9c6133b6c23351c1274e7fc3cd8Andreas Huber
148eb9163071573e9c6133b6c23351c1274e7fc3cd8Andreas Huber    static ssize_t WriteDataWrapper(void *me, const void *data, size_t size);
149eb9163071573e9c6133b6c23351c1274e7fc3cd8Andreas Huber    ssize_t writeData(const void *data, size_t size);
150eb9163071573e9c6133b6c23351c1274e7fc3cd8Andreas Huber
151eb9163071573e9c6133b6c23351c1274e7fc3cd8Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(MyConvertingStreamSource);
152eb9163071573e9c6133b6c23351c1274e7fc3cd8Andreas Huber};
153eb9163071573e9c6133b6c23351c1274e7fc3cd8Andreas Huber
154eb9163071573e9c6133b6c23351c1274e7fc3cd8Andreas Huber////////////////////////////////////////////////////////////////////////////////
155eb9163071573e9c6133b6c23351c1274e7fc3cd8Andreas Huber
156eb9163071573e9c6133b6c23351c1274e7fc3cd8Andreas HuberMyConvertingStreamSource::MyConvertingStreamSource(const char *filename)
157eb9163071573e9c6133b6c23351c1274e7fc3cd8Andreas Huber    : mCurrentBufferIndex(-1),
158eb9163071573e9c6133b6c23351c1274e7fc3cd8Andreas Huber      mCurrentBufferOffset(0) {
159eb9163071573e9c6133b6c23351c1274e7fc3cd8Andreas Huber    sp<DataSource> dataSource = DataSource::CreateFromURI(filename);
160eb9163071573e9c6133b6c23351c1274e7fc3cd8Andreas Huber    CHECK(dataSource != NULL);
161eb9163071573e9c6133b6c23351c1274e7fc3cd8Andreas Huber
162eb9163071573e9c6133b6c23351c1274e7fc3cd8Andreas Huber    sp<MediaExtractor> extractor = MediaExtractor::Create(dataSource);
163eb9163071573e9c6133b6c23351c1274e7fc3cd8Andreas Huber    CHECK(extractor != NULL);
164eb9163071573e9c6133b6c23351c1274e7fc3cd8Andreas Huber
165eb9163071573e9c6133b6c23351c1274e7fc3cd8Andreas Huber    mWriter = new MPEG2TSWriter(
166eb9163071573e9c6133b6c23351c1274e7fc3cd8Andreas Huber            this, &MyConvertingStreamSource::WriteDataWrapper);
167eb9163071573e9c6133b6c23351c1274e7fc3cd8Andreas Huber
168eb9163071573e9c6133b6c23351c1274e7fc3cd8Andreas Huber    for (size_t i = 0; i < extractor->countTracks(); ++i) {
169eb9163071573e9c6133b6c23351c1274e7fc3cd8Andreas Huber        const sp<MetaData> &meta = extractor->getTrackMetaData(i);
170eb9163071573e9c6133b6c23351c1274e7fc3cd8Andreas Huber
171eb9163071573e9c6133b6c23351c1274e7fc3cd8Andreas Huber        const char *mime;
172eb9163071573e9c6133b6c23351c1274e7fc3cd8Andreas Huber        CHECK(meta->findCString(kKeyMIMEType, &mime));
173eb9163071573e9c6133b6c23351c1274e7fc3cd8Andreas Huber
174eb9163071573e9c6133b6c23351c1274e7fc3cd8Andreas Huber        if (strncasecmp("video/", mime, 6) && strncasecmp("audio/", mime, 6)) {
175eb9163071573e9c6133b6c23351c1274e7fc3cd8Andreas Huber            continue;
176eb9163071573e9c6133b6c23351c1274e7fc3cd8Andreas Huber        }
177eb9163071573e9c6133b6c23351c1274e7fc3cd8Andreas Huber
178eb9163071573e9c6133b6c23351c1274e7fc3cd8Andreas Huber        CHECK_EQ(mWriter->addSource(extractor->getTrack(i)), (status_t)OK);
179eb9163071573e9c6133b6c23351c1274e7fc3cd8Andreas Huber    }
180eb9163071573e9c6133b6c23351c1274e7fc3cd8Andreas Huber
181eb9163071573e9c6133b6c23351c1274e7fc3cd8Andreas Huber    CHECK_EQ(mWriter->start(), (status_t)OK);
182eb9163071573e9c6133b6c23351c1274e7fc3cd8Andreas Huber}
183eb9163071573e9c6133b6c23351c1274e7fc3cd8Andreas Huber
184eb9163071573e9c6133b6c23351c1274e7fc3cd8Andreas HuberMyConvertingStreamSource::~MyConvertingStreamSource() {
185eb9163071573e9c6133b6c23351c1274e7fc3cd8Andreas Huber}
186eb9163071573e9c6133b6c23351c1274e7fc3cd8Andreas Huber
187eb9163071573e9c6133b6c23351c1274e7fc3cd8Andreas Hubervoid MyConvertingStreamSource::setListener(
188eb9163071573e9c6133b6c23351c1274e7fc3cd8Andreas Huber        const sp<IStreamListener> &listener) {
189eb9163071573e9c6133b6c23351c1274e7fc3cd8Andreas Huber    mListener = listener;
190eb9163071573e9c6133b6c23351c1274e7fc3cd8Andreas Huber}
191eb9163071573e9c6133b6c23351c1274e7fc3cd8Andreas Huber
192eb9163071573e9c6133b6c23351c1274e7fc3cd8Andreas Hubervoid MyConvertingStreamSource::setBuffers(
193eb9163071573e9c6133b6c23351c1274e7fc3cd8Andreas Huber        const Vector<sp<IMemory> > &buffers) {
194eb9163071573e9c6133b6c23351c1274e7fc3cd8Andreas Huber    mBuffers = buffers;
195eb9163071573e9c6133b6c23351c1274e7fc3cd8Andreas Huber}
196eb9163071573e9c6133b6c23351c1274e7fc3cd8Andreas Huber
197eb9163071573e9c6133b6c23351c1274e7fc3cd8Andreas Huberssize_t MyConvertingStreamSource::WriteDataWrapper(
198eb9163071573e9c6133b6c23351c1274e7fc3cd8Andreas Huber        void *me, const void *data, size_t size) {
199eb9163071573e9c6133b6c23351c1274e7fc3cd8Andreas Huber    return static_cast<MyConvertingStreamSource *>(me)->writeData(data, size);
200eb9163071573e9c6133b6c23351c1274e7fc3cd8Andreas Huber}
201eb9163071573e9c6133b6c23351c1274e7fc3cd8Andreas Huber
202eb9163071573e9c6133b6c23351c1274e7fc3cd8Andreas Huberssize_t MyConvertingStreamSource::writeData(const void *data, size_t size) {
203eb9163071573e9c6133b6c23351c1274e7fc3cd8Andreas Huber    size_t totalWritten = 0;
204eb9163071573e9c6133b6c23351c1274e7fc3cd8Andreas Huber
205eb9163071573e9c6133b6c23351c1274e7fc3cd8Andreas Huber    while (size > 0) {
206eb9163071573e9c6133b6c23351c1274e7fc3cd8Andreas Huber        Mutex::Autolock autoLock(mLock);
207eb9163071573e9c6133b6c23351c1274e7fc3cd8Andreas Huber
208eb9163071573e9c6133b6c23351c1274e7fc3cd8Andreas Huber        if (mCurrentBufferIndex < 0) {
209eb9163071573e9c6133b6c23351c1274e7fc3cd8Andreas Huber            while (mBufferQueue.empty()) {
210eb9163071573e9c6133b6c23351c1274e7fc3cd8Andreas Huber                mCondition.wait(mLock);
211eb9163071573e9c6133b6c23351c1274e7fc3cd8Andreas Huber            }
212eb9163071573e9c6133b6c23351c1274e7fc3cd8Andreas Huber
213eb9163071573e9c6133b6c23351c1274e7fc3cd8Andreas Huber            mCurrentBufferIndex = *mBufferQueue.begin();
214eb9163071573e9c6133b6c23351c1274e7fc3cd8Andreas Huber            mCurrentBufferOffset = 0;
215eb9163071573e9c6133b6c23351c1274e7fc3cd8Andreas Huber
216eb9163071573e9c6133b6c23351c1274e7fc3cd8Andreas Huber            mBufferQueue.erase(mBufferQueue.begin());
217eb9163071573e9c6133b6c23351c1274e7fc3cd8Andreas Huber        }
218eb9163071573e9c6133b6c23351c1274e7fc3cd8Andreas Huber
219eb9163071573e9c6133b6c23351c1274e7fc3cd8Andreas Huber        sp<IMemory> mem = mBuffers.itemAt(mCurrentBufferIndex);
220eb9163071573e9c6133b6c23351c1274e7fc3cd8Andreas Huber
221eb9163071573e9c6133b6c23351c1274e7fc3cd8Andreas Huber        size_t copy = size;
222eb9163071573e9c6133b6c23351c1274e7fc3cd8Andreas Huber        if (copy + mCurrentBufferOffset > mem->size()) {
223eb9163071573e9c6133b6c23351c1274e7fc3cd8Andreas Huber            copy = mem->size() - mCurrentBufferOffset;
224eb9163071573e9c6133b6c23351c1274e7fc3cd8Andreas Huber        }
225eb9163071573e9c6133b6c23351c1274e7fc3cd8Andreas Huber
226eb9163071573e9c6133b6c23351c1274e7fc3cd8Andreas Huber        memcpy((uint8_t *)mem->pointer() + mCurrentBufferOffset, data, copy);
227eb9163071573e9c6133b6c23351c1274e7fc3cd8Andreas Huber        mCurrentBufferOffset += copy;
228eb9163071573e9c6133b6c23351c1274e7fc3cd8Andreas Huber
229eb9163071573e9c6133b6c23351c1274e7fc3cd8Andreas Huber        if (mCurrentBufferOffset == mem->size()) {
230eb9163071573e9c6133b6c23351c1274e7fc3cd8Andreas Huber            mListener->queueBuffer(mCurrentBufferIndex, mCurrentBufferOffset);
231eb9163071573e9c6133b6c23351c1274e7fc3cd8Andreas Huber            mCurrentBufferIndex = -1;
232eb9163071573e9c6133b6c23351c1274e7fc3cd8Andreas Huber        }
233eb9163071573e9c6133b6c23351c1274e7fc3cd8Andreas Huber
234eb9163071573e9c6133b6c23351c1274e7fc3cd8Andreas Huber        data = (const uint8_t *)data + copy;
235eb9163071573e9c6133b6c23351c1274e7fc3cd8Andreas Huber        size -= copy;
236eb9163071573e9c6133b6c23351c1274e7fc3cd8Andreas Huber
237eb9163071573e9c6133b6c23351c1274e7fc3cd8Andreas Huber        totalWritten += copy;
238eb9163071573e9c6133b6c23351c1274e7fc3cd8Andreas Huber    }
239eb9163071573e9c6133b6c23351c1274e7fc3cd8Andreas Huber
240eb9163071573e9c6133b6c23351c1274e7fc3cd8Andreas Huber    return (ssize_t)totalWritten;
241eb9163071573e9c6133b6c23351c1274e7fc3cd8Andreas Huber}
242eb9163071573e9c6133b6c23351c1274e7fc3cd8Andreas Huber
243eb9163071573e9c6133b6c23351c1274e7fc3cd8Andreas Hubervoid MyConvertingStreamSource::onBufferAvailable(size_t index) {
244eb9163071573e9c6133b6c23351c1274e7fc3cd8Andreas Huber    Mutex::Autolock autoLock(mLock);
245eb9163071573e9c6133b6c23351c1274e7fc3cd8Andreas Huber
246eb9163071573e9c6133b6c23351c1274e7fc3cd8Andreas Huber    mBufferQueue.push_back(index);
247eb9163071573e9c6133b6c23351c1274e7fc3cd8Andreas Huber    mCondition.signal();
248eb9163071573e9c6133b6c23351c1274e7fc3cd8Andreas Huber
249eb9163071573e9c6133b6c23351c1274e7fc3cd8Andreas Huber    if (mWriter->reachedEOS()) {
250eb9163071573e9c6133b6c23351c1274e7fc3cd8Andreas Huber        if (mCurrentBufferIndex >= 0) {
251eb9163071573e9c6133b6c23351c1274e7fc3cd8Andreas Huber            mListener->queueBuffer(mCurrentBufferIndex, mCurrentBufferOffset);
252eb9163071573e9c6133b6c23351c1274e7fc3cd8Andreas Huber            mCurrentBufferIndex = -1;
253eb9163071573e9c6133b6c23351c1274e7fc3cd8Andreas Huber        }
254eb9163071573e9c6133b6c23351c1274e7fc3cd8Andreas Huber
255eb9163071573e9c6133b6c23351c1274e7fc3cd8Andreas Huber        mListener->issueCommand(IStreamListener::EOS, false /* synchronous */);
256eb9163071573e9c6133b6c23351c1274e7fc3cd8Andreas Huber    }
257eb9163071573e9c6133b6c23351c1274e7fc3cd8Andreas Huber}
25852b52cdfb7502d5a0fd7bba21d1daa3e36a54e42Andreas Huber
25952b52cdfb7502d5a0fd7bba21d1daa3e36a54e42Andreas Huber////////////////////////////////////////////////////////////////////////////////
26052b52cdfb7502d5a0fd7bba21d1daa3e36a54e42Andreas Huber
26152b52cdfb7502d5a0fd7bba21d1daa3e36a54e42Andreas Huberstruct MyClient : public BnMediaPlayerClient {
26252b52cdfb7502d5a0fd7bba21d1daa3e36a54e42Andreas Huber    MyClient()
26352b52cdfb7502d5a0fd7bba21d1daa3e36a54e42Andreas Huber        : mEOS(false) {
26452b52cdfb7502d5a0fd7bba21d1daa3e36a54e42Andreas Huber    }
26552b52cdfb7502d5a0fd7bba21d1daa3e36a54e42Andreas Huber
266162ee49e1ce8800de80697fdd0e0e42ad7e9374eGloria Wang    virtual void notify(int msg, int ext1, int ext2, const Parcel *obj) {
26752b52cdfb7502d5a0fd7bba21d1daa3e36a54e42Andreas Huber        Mutex::Autolock autoLock(mLock);
26852b52cdfb7502d5a0fd7bba21d1daa3e36a54e42Andreas Huber
26952b52cdfb7502d5a0fd7bba21d1daa3e36a54e42Andreas Huber        if (msg == MEDIA_ERROR || msg == MEDIA_PLAYBACK_COMPLETE) {
27052b52cdfb7502d5a0fd7bba21d1daa3e36a54e42Andreas Huber            mEOS = true;
27152b52cdfb7502d5a0fd7bba21d1daa3e36a54e42Andreas Huber            mCondition.signal();
27252b52cdfb7502d5a0fd7bba21d1daa3e36a54e42Andreas Huber        }
27352b52cdfb7502d5a0fd7bba21d1daa3e36a54e42Andreas Huber    }
27452b52cdfb7502d5a0fd7bba21d1daa3e36a54e42Andreas Huber
27552b52cdfb7502d5a0fd7bba21d1daa3e36a54e42Andreas Huber    void waitForEOS() {
27652b52cdfb7502d5a0fd7bba21d1daa3e36a54e42Andreas Huber        Mutex::Autolock autoLock(mLock);
27752b52cdfb7502d5a0fd7bba21d1daa3e36a54e42Andreas Huber        while (!mEOS) {
27852b52cdfb7502d5a0fd7bba21d1daa3e36a54e42Andreas Huber            mCondition.wait(mLock);
27952b52cdfb7502d5a0fd7bba21d1daa3e36a54e42Andreas Huber        }
28052b52cdfb7502d5a0fd7bba21d1daa3e36a54e42Andreas Huber    }
28152b52cdfb7502d5a0fd7bba21d1daa3e36a54e42Andreas Huber
28252b52cdfb7502d5a0fd7bba21d1daa3e36a54e42Andreas Huberprotected:
28352b52cdfb7502d5a0fd7bba21d1daa3e36a54e42Andreas Huber    virtual ~MyClient() {
28452b52cdfb7502d5a0fd7bba21d1daa3e36a54e42Andreas Huber    }
28552b52cdfb7502d5a0fd7bba21d1daa3e36a54e42Andreas Huber
28652b52cdfb7502d5a0fd7bba21d1daa3e36a54e42Andreas Huberprivate:
28752b52cdfb7502d5a0fd7bba21d1daa3e36a54e42Andreas Huber    Mutex mLock;
28852b52cdfb7502d5a0fd7bba21d1daa3e36a54e42Andreas Huber    Condition mCondition;
28952b52cdfb7502d5a0fd7bba21d1daa3e36a54e42Andreas Huber
29052b52cdfb7502d5a0fd7bba21d1daa3e36a54e42Andreas Huber    bool mEOS;
29152b52cdfb7502d5a0fd7bba21d1daa3e36a54e42Andreas Huber
29252b52cdfb7502d5a0fd7bba21d1daa3e36a54e42Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(MyClient);
29352b52cdfb7502d5a0fd7bba21d1daa3e36a54e42Andreas Huber};
29452b52cdfb7502d5a0fd7bba21d1daa3e36a54e42Andreas Huber
29552b52cdfb7502d5a0fd7bba21d1daa3e36a54e42Andreas Huberint main(int argc, char **argv) {
29652b52cdfb7502d5a0fd7bba21d1daa3e36a54e42Andreas Huber    android::ProcessState::self()->startThreadPool();
29752b52cdfb7502d5a0fd7bba21d1daa3e36a54e42Andreas Huber
298eb9163071573e9c6133b6c23351c1274e7fc3cd8Andreas Huber    DataSource::RegisterDefaultSniffers();
299eb9163071573e9c6133b6c23351c1274e7fc3cd8Andreas Huber
30052b52cdfb7502d5a0fd7bba21d1daa3e36a54e42Andreas Huber    if (argc != 2) {
30152b52cdfb7502d5a0fd7bba21d1daa3e36a54e42Andreas Huber        fprintf(stderr, "Usage: %s filename\n", argv[0]);
30252b52cdfb7502d5a0fd7bba21d1daa3e36a54e42Andreas Huber        return 1;
30352b52cdfb7502d5a0fd7bba21d1daa3e36a54e42Andreas Huber    }
30452b52cdfb7502d5a0fd7bba21d1daa3e36a54e42Andreas Huber
30552b52cdfb7502d5a0fd7bba21d1daa3e36a54e42Andreas Huber    sp<SurfaceComposerClient> composerClient = new SurfaceComposerClient;
30652b52cdfb7502d5a0fd7bba21d1daa3e36a54e42Andreas Huber    CHECK_EQ(composerClient->initCheck(), (status_t)OK);
30752b52cdfb7502d5a0fd7bba21d1daa3e36a54e42Andreas Huber
308ced159b1d839b24775525ccb736876e7cb7e649dAndreas Huber    ssize_t displayWidth = composerClient->getDisplayWidth(0);
309ced159b1d839b24775525ccb736876e7cb7e649dAndreas Huber    ssize_t displayHeight = composerClient->getDisplayHeight(0);
310ced159b1d839b24775525ccb736876e7cb7e649dAndreas Huber
311ced159b1d839b24775525ccb736876e7cb7e649dAndreas Huber    LOGV("display is %d x %d\n", displayWidth, displayHeight);
312ced159b1d839b24775525ccb736876e7cb7e649dAndreas Huber
31352b52cdfb7502d5a0fd7bba21d1daa3e36a54e42Andreas Huber    sp<SurfaceControl> control =
31452b52cdfb7502d5a0fd7bba21d1daa3e36a54e42Andreas Huber        composerClient->createSurface(
31552b52cdfb7502d5a0fd7bba21d1daa3e36a54e42Andreas Huber                String8("A Surface"),
31652b52cdfb7502d5a0fd7bba21d1daa3e36a54e42Andreas Huber                0,
317ced159b1d839b24775525ccb736876e7cb7e649dAndreas Huber                displayWidth,
318ced159b1d839b24775525ccb736876e7cb7e649dAndreas Huber                displayHeight,
31952b52cdfb7502d5a0fd7bba21d1daa3e36a54e42Andreas Huber                PIXEL_FORMAT_RGB_565,
32052b52cdfb7502d5a0fd7bba21d1daa3e36a54e42Andreas Huber                0);
32152b52cdfb7502d5a0fd7bba21d1daa3e36a54e42Andreas Huber
32252b52cdfb7502d5a0fd7bba21d1daa3e36a54e42Andreas Huber    CHECK(control != NULL);
32352b52cdfb7502d5a0fd7bba21d1daa3e36a54e42Andreas Huber    CHECK(control->isValid());
32452b52cdfb7502d5a0fd7bba21d1daa3e36a54e42Andreas Huber
325439863f3b3e725b5de1cba4940a21900369961c0Mathias Agopian    SurfaceComposerClient::openGlobalTransaction();
326c5a9766dc3cb0cab0c30528ffdb7bce6dfde1848Andreas Huber    CHECK_EQ(control->setLayer(INT_MAX), (status_t)OK);
32752b52cdfb7502d5a0fd7bba21d1daa3e36a54e42Andreas Huber    CHECK_EQ(control->show(), (status_t)OK);
328439863f3b3e725b5de1cba4940a21900369961c0Mathias Agopian    SurfaceComposerClient::closeGlobalTransaction();
32952b52cdfb7502d5a0fd7bba21d1daa3e36a54e42Andreas Huber
33052b52cdfb7502d5a0fd7bba21d1daa3e36a54e42Andreas Huber    sp<Surface> surface = control->getSurface();
33152b52cdfb7502d5a0fd7bba21d1daa3e36a54e42Andreas Huber    CHECK(surface != NULL);
33252b52cdfb7502d5a0fd7bba21d1daa3e36a54e42Andreas Huber
33352b52cdfb7502d5a0fd7bba21d1daa3e36a54e42Andreas Huber    sp<IServiceManager> sm = defaultServiceManager();
33452b52cdfb7502d5a0fd7bba21d1daa3e36a54e42Andreas Huber    sp<IBinder> binder = sm->getService(String16("media.player"));
33552b52cdfb7502d5a0fd7bba21d1daa3e36a54e42Andreas Huber    sp<IMediaPlayerService> service = interface_cast<IMediaPlayerService>(binder);
33652b52cdfb7502d5a0fd7bba21d1daa3e36a54e42Andreas Huber
33752b52cdfb7502d5a0fd7bba21d1daa3e36a54e42Andreas Huber    CHECK(service.get() != NULL);
33852b52cdfb7502d5a0fd7bba21d1daa3e36a54e42Andreas Huber
339eb9163071573e9c6133b6c23351c1274e7fc3cd8Andreas Huber    sp<MyClient> client = new MyClient;
340eb9163071573e9c6133b6c23351c1274e7fc3cd8Andreas Huber
341eb9163071573e9c6133b6c23351c1274e7fc3cd8Andreas Huber    sp<IStreamSource> source;
34252b52cdfb7502d5a0fd7bba21d1daa3e36a54e42Andreas Huber
343eb9163071573e9c6133b6c23351c1274e7fc3cd8Andreas Huber    size_t len = strlen(argv[1]);
344eb9163071573e9c6133b6c23351c1274e7fc3cd8Andreas Huber    if (len >= 3 && !strcasecmp(".ts", &argv[1][len - 3])) {
345eb9163071573e9c6133b6c23351c1274e7fc3cd8Andreas Huber        int fd = open(argv[1], O_RDONLY);
34652b52cdfb7502d5a0fd7bba21d1daa3e36a54e42Andreas Huber
347eb9163071573e9c6133b6c23351c1274e7fc3cd8Andreas Huber        if (fd < 0) {
348eb9163071573e9c6133b6c23351c1274e7fc3cd8Andreas Huber            fprintf(stderr, "Failed to open file '%s'.", argv[1]);
349eb9163071573e9c6133b6c23351c1274e7fc3cd8Andreas Huber            return 1;
350eb9163071573e9c6133b6c23351c1274e7fc3cd8Andreas Huber        }
351eb9163071573e9c6133b6c23351c1274e7fc3cd8Andreas Huber
352eb9163071573e9c6133b6c23351c1274e7fc3cd8Andreas Huber        source = new MyStreamSource(fd);
353eb9163071573e9c6133b6c23351c1274e7fc3cd8Andreas Huber    } else {
354eb9163071573e9c6133b6c23351c1274e7fc3cd8Andreas Huber        printf("Converting file to transport stream for streaming...\n");
355eb9163071573e9c6133b6c23351c1274e7fc3cd8Andreas Huber
356eb9163071573e9c6133b6c23351c1274e7fc3cd8Andreas Huber        source = new MyConvertingStreamSource(argv[1]);
357eb9163071573e9c6133b6c23351c1274e7fc3cd8Andreas Huber    }
35852b52cdfb7502d5a0fd7bba21d1daa3e36a54e42Andreas Huber
35952b52cdfb7502d5a0fd7bba21d1daa3e36a54e42Andreas Huber    sp<IMediaPlayer> player =
360fc301b0bb5c635c6bb51b48c504a8db5f9010e5cDave Burke        service->create(getpid(), client, 0);
36152b52cdfb7502d5a0fd7bba21d1daa3e36a54e42Andreas Huber
362fc301b0bb5c635c6bb51b48c504a8db5f9010e5cDave Burke    if (player != NULL && player->setDataSource(source) == NO_ERROR) {
36395be24585f46229f551c529104b5e92fa4316b38Andreas Huber        player->setVideoSurfaceTexture(surface->getSurfaceTexture());
36452b52cdfb7502d5a0fd7bba21d1daa3e36a54e42Andreas Huber        player->start();
36552b52cdfb7502d5a0fd7bba21d1daa3e36a54e42Andreas Huber
36652b52cdfb7502d5a0fd7bba21d1daa3e36a54e42Andreas Huber        client->waitForEOS();
36752b52cdfb7502d5a0fd7bba21d1daa3e36a54e42Andreas Huber
36852b52cdfb7502d5a0fd7bba21d1daa3e36a54e42Andreas Huber        player->stop();
36952b52cdfb7502d5a0fd7bba21d1daa3e36a54e42Andreas Huber    } else {
37052b52cdfb7502d5a0fd7bba21d1daa3e36a54e42Andreas Huber        fprintf(stderr, "failed to instantiate player.\n");
37152b52cdfb7502d5a0fd7bba21d1daa3e36a54e42Andreas Huber    }
37252b52cdfb7502d5a0fd7bba21d1daa3e36a54e42Andreas Huber
37352b52cdfb7502d5a0fd7bba21d1daa3e36a54e42Andreas Huber    composerClient->dispose();
37452b52cdfb7502d5a0fd7bba21d1daa3e36a54e42Andreas Huber
37552b52cdfb7502d5a0fd7bba21d1daa3e36a54e42Andreas Huber    return 0;
37652b52cdfb7502d5a0fd7bba21d1daa3e36a54e42Andreas Huber}
377