stream.cpp revision b26a1176517579bd4d23f2a2cc91eca2e59b245c
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
17e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber#include <binder/ProcessState.h>
18e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber
19e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber#include <media/IStreamSource.h>
20e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber#include <media/mediaplayer.h>
21e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber#include <media/stagefright/foundation/ADebug.h>
2214acc736e336cbd6026df781d4f411e908831815Andreas Huber#include <media/stagefright/foundation/AMessage.h>
23b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber#include <media/stagefright/DataSource.h>
24b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber#include <media/stagefright/MPEG2TSWriter.h>
25b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber#include <media/stagefright/MediaExtractor.h>
26b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber#include <media/stagefright/MediaSource.h>
27b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber#include <media/stagefright/MetaData.h>
28e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber
29e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber#include <binder/IServiceManager.h>
30e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber#include <media/IMediaPlayerService.h>
31e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber#include <surfaceflinger/ISurfaceComposer.h>
32e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber#include <surfaceflinger/SurfaceComposerClient.h>
33e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber
34e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber#include <fcntl.h>
35e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber
36e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huberusing namespace android;
37e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber
38e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huberstruct MyStreamSource : public BnStreamSource {
39b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber    // Object assumes ownership of fd.
40e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber    MyStreamSource(int fd);
41e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber
42e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber    virtual void setListener(const sp<IStreamListener> &listener);
43e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber    virtual void setBuffers(const Vector<sp<IMemory> > &buffers);
44e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber
45e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber    virtual void onBufferAvailable(size_t index);
46e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber
47e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huberprotected:
48e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber    virtual ~MyStreamSource();
49e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber
50e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huberprivate:
51e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber    int mFd;
52f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    off64_t mFileSize;
53f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int64_t mNextSeekTimeUs;
54e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber
55e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber    sp<IStreamListener> mListener;
56e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber    Vector<sp<IMemory> > mBuffers;
57e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber
58e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(MyStreamSource);
59e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber};
60e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber
61e2b1028852120bcfded33b8f06f66b780437fe92Andreas HuberMyStreamSource::MyStreamSource(int fd)
62f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : mFd(fd),
63f933441648ef6a71dee783d733aac17b9508b452Andreas Huber      mFileSize(0),
645bc087c573c70c84c6a39946457590b42d392a33Andreas Huber      mNextSeekTimeUs(-1) {  // ALooper::GetNowUs() + 5000000ll) {
65e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber    CHECK_GE(fd, 0);
66f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
67f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mFileSize = lseek64(fd, 0, SEEK_END);
68f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    lseek64(fd, 0, SEEK_SET);
69e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber}
70e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber
71e2b1028852120bcfded33b8f06f66b780437fe92Andreas HuberMyStreamSource::~MyStreamSource() {
72b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber    close(mFd);
73b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber    mFd = -1;
74e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber}
75e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber
76e2b1028852120bcfded33b8f06f66b780437fe92Andreas Hubervoid MyStreamSource::setListener(const sp<IStreamListener> &listener) {
77e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber    mListener = listener;
78e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber}
79e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber
80e2b1028852120bcfded33b8f06f66b780437fe92Andreas Hubervoid MyStreamSource::setBuffers(const Vector<sp<IMemory> > &buffers) {
81e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber    mBuffers = buffers;
82e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber}
83e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber
84e2b1028852120bcfded33b8f06f66b780437fe92Andreas Hubervoid MyStreamSource::onBufferAvailable(size_t index) {
85e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber    CHECK_LT(index, mBuffers.size());
86f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
87f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mNextSeekTimeUs >= 0 && mNextSeekTimeUs <= ALooper::GetNowUs()) {
88f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        off64_t offset = (off64_t)(((float)rand() / RAND_MAX) * mFileSize * 0.8);
89f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        offset = (offset / 188) * 188;
90f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
91f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        lseek(mFd, offset, SEEK_SET);
92f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
93f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mListener->issueCommand(
94f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                IStreamListener::DISCONTINUITY, false /* synchronous */);
95f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
96f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mNextSeekTimeUs = -1;
97f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mNextSeekTimeUs = ALooper::GetNowUs() + 5000000ll;
98f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
99f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
100e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber    sp<IMemory> mem = mBuffers.itemAt(index);
101e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber
102e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber    ssize_t n = read(mFd, mem->pointer(), mem->size());
103e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber    if (n <= 0) {
10414acc736e336cbd6026df781d4f411e908831815Andreas Huber        mListener->issueCommand(IStreamListener::EOS, false /* synchronous */);
105e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber    } else {
106e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber        mListener->queueBuffer(index, n);
107e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber    }
108e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber}
109b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber////////////////////////////////////////////////////////////////////////////////
110b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber
111b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huberstruct MyConvertingStreamSource : public BnStreamSource {
112b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber    MyConvertingStreamSource(const char *filename);
113b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber
114b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber    virtual void setListener(const sp<IStreamListener> &listener);
115b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber    virtual void setBuffers(const Vector<sp<IMemory> > &buffers);
116b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber
117b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber    virtual void onBufferAvailable(size_t index);
118b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber
119b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huberprotected:
120b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber    virtual ~MyConvertingStreamSource();
121b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber
122b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huberprivate:
123b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber    Mutex mLock;
124b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber    Condition mCondition;
125b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber
126b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber    sp<IStreamListener> mListener;
127b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber    Vector<sp<IMemory> > mBuffers;
128b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber
129b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber    sp<MPEG2TSWriter> mWriter;
130b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber
131b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber    ssize_t mCurrentBufferIndex;
132b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber    size_t mCurrentBufferOffset;
133b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber
134b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber    List<size_t> mBufferQueue;
135b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber
136b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber    static ssize_t WriteDataWrapper(void *me, const void *data, size_t size);
137b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber    ssize_t writeData(const void *data, size_t size);
138b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber
139b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber    DISALLOW_EVIL_CONSTRUCTORS(MyConvertingStreamSource);
140b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber};
141b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber
142b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber////////////////////////////////////////////////////////////////////////////////
143b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber
144b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas HuberMyConvertingStreamSource::MyConvertingStreamSource(const char *filename)
145b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber    : mCurrentBufferIndex(-1),
146b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber      mCurrentBufferOffset(0) {
147b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber    sp<DataSource> dataSource = DataSource::CreateFromURI(filename);
148b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber    CHECK(dataSource != NULL);
149b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber
150b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber    sp<MediaExtractor> extractor = MediaExtractor::Create(dataSource);
151b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber    CHECK(extractor != NULL);
152b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber
153b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber    mWriter = new MPEG2TSWriter(
154b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber            this, &MyConvertingStreamSource::WriteDataWrapper);
155b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber
156b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber    for (size_t i = 0; i < extractor->countTracks(); ++i) {
157b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber        const sp<MetaData> &meta = extractor->getTrackMetaData(i);
158b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber
159b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber        const char *mime;
160b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber        CHECK(meta->findCString(kKeyMIMEType, &mime));
161b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber
162b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber        if (strncasecmp("video/", mime, 6) && strncasecmp("audio/", mime, 6)) {
163b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber            continue;
164b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber        }
165b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber
166b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber        CHECK_EQ(mWriter->addSource(extractor->getTrack(i)), (status_t)OK);
167b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber    }
168b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber
169b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber    CHECK_EQ(mWriter->start(), (status_t)OK);
170b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber}
171b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber
172b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas HuberMyConvertingStreamSource::~MyConvertingStreamSource() {
173b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber}
174b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber
175b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Hubervoid MyConvertingStreamSource::setListener(
176b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber        const sp<IStreamListener> &listener) {
177b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber    mListener = listener;
178b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber}
179b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber
180b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Hubervoid MyConvertingStreamSource::setBuffers(
181b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber        const Vector<sp<IMemory> > &buffers) {
182b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber    mBuffers = buffers;
183b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber}
184b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber
185b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huberssize_t MyConvertingStreamSource::WriteDataWrapper(
186b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber        void *me, const void *data, size_t size) {
187b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber    return static_cast<MyConvertingStreamSource *>(me)->writeData(data, size);
188b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber}
189b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber
190b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huberssize_t MyConvertingStreamSource::writeData(const void *data, size_t size) {
191b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber    size_t totalWritten = 0;
192b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber
193b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber    while (size > 0) {
194b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber        Mutex::Autolock autoLock(mLock);
195b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber
196b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber        if (mCurrentBufferIndex < 0) {
197b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber            while (mBufferQueue.empty()) {
198b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber                mCondition.wait(mLock);
199b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber            }
200b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber
201b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber            mCurrentBufferIndex = *mBufferQueue.begin();
202b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber            mCurrentBufferOffset = 0;
203b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber
204b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber            mBufferQueue.erase(mBufferQueue.begin());
205b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber        }
206b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber
207b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber        sp<IMemory> mem = mBuffers.itemAt(mCurrentBufferIndex);
208b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber
209b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber        size_t copy = size;
210b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber        if (copy + mCurrentBufferOffset > mem->size()) {
211b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber            copy = mem->size() - mCurrentBufferOffset;
212b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber        }
213b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber
214b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber        memcpy((uint8_t *)mem->pointer() + mCurrentBufferOffset, data, copy);
215b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber        mCurrentBufferOffset += copy;
216b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber
217b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber        if (mCurrentBufferOffset == mem->size()) {
218b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber            mListener->queueBuffer(mCurrentBufferIndex, mCurrentBufferOffset);
219b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber            mCurrentBufferIndex = -1;
220b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber        }
221b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber
222b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber        data = (const uint8_t *)data + copy;
223b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber        size -= copy;
224b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber
225b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber        totalWritten += copy;
226b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber    }
227b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber
228b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber    return (ssize_t)totalWritten;
229b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber}
230b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber
231b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Hubervoid MyConvertingStreamSource::onBufferAvailable(size_t index) {
232b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber    Mutex::Autolock autoLock(mLock);
233b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber
234b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber    mBufferQueue.push_back(index);
235b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber    mCondition.signal();
236b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber
237b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber    if (mWriter->reachedEOS()) {
238b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber        if (mCurrentBufferIndex >= 0) {
239b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber            mListener->queueBuffer(mCurrentBufferIndex, mCurrentBufferOffset);
240b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber            mCurrentBufferIndex = -1;
241b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber        }
242b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber
243b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber        mListener->issueCommand(IStreamListener::EOS, false /* synchronous */);
244b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber    }
245b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber}
246e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber
247e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber////////////////////////////////////////////////////////////////////////////////
248e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber
249e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huberstruct MyClient : public BnMediaPlayerClient {
250e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber    MyClient()
251e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber        : mEOS(false) {
252e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber    }
253e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber
254b483c4724846c0b8d4e82afcbb7c17f671bae81cGloria Wang    virtual void notify(int msg, int ext1, int ext2, const Parcel *obj) {
255e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber        Mutex::Autolock autoLock(mLock);
256e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber
257e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber        if (msg == MEDIA_ERROR || msg == MEDIA_PLAYBACK_COMPLETE) {
258e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber            mEOS = true;
259e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber            mCondition.signal();
260e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber        }
261e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber    }
262e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber
263e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber    void waitForEOS() {
264e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber        Mutex::Autolock autoLock(mLock);
265e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber        while (!mEOS) {
266e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber            mCondition.wait(mLock);
267e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber        }
268e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber    }
269e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber
270e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huberprotected:
271e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber    virtual ~MyClient() {
272e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber    }
273e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber
274e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huberprivate:
275e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber    Mutex mLock;
276e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber    Condition mCondition;
277e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber
278e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber    bool mEOS;
279e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber
280e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(MyClient);
281e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber};
282e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber
283e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huberint main(int argc, char **argv) {
284e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber    android::ProcessState::self()->startThreadPool();
285e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber
286b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber    DataSource::RegisterDefaultSniffers();
287b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber
288e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber    if (argc != 2) {
289e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber        fprintf(stderr, "Usage: %s filename\n", argv[0]);
290e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber        return 1;
291e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber    }
292e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber
293e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber    sp<SurfaceComposerClient> composerClient = new SurfaceComposerClient;
294e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber    CHECK_EQ(composerClient->initCheck(), (status_t)OK);
295e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber
296e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber    sp<SurfaceControl> control =
297e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber        composerClient->createSurface(
298e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber                String8("A Surface"),
299e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber                0,
300e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber                1280,
301e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber                800,
302e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber                PIXEL_FORMAT_RGB_565,
303e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber                0);
304e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber
305e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber    CHECK(control != NULL);
306e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber    CHECK(control->isValid());
307e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber
308e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber    CHECK_EQ(composerClient->openTransaction(), (status_t)OK);
309e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber    CHECK_EQ(control->setLayer(30000), (status_t)OK);
310e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber    CHECK_EQ(control->show(), (status_t)OK);
311e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber    CHECK_EQ(composerClient->closeTransaction(), (status_t)OK);
312e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber
313e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber    sp<Surface> surface = control->getSurface();
314e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber    CHECK(surface != NULL);
315e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber
316e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber    sp<IServiceManager> sm = defaultServiceManager();
317e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber    sp<IBinder> binder = sm->getService(String16("media.player"));
318e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber    sp<IMediaPlayerService> service = interface_cast<IMediaPlayerService>(binder);
319e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber
320e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber    CHECK(service.get() != NULL);
321e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber
322b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber    sp<MyClient> client = new MyClient;
323b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber
324b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber    sp<IStreamSource> source;
325e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber
326b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber    size_t len = strlen(argv[1]);
327b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber    if (len >= 3 && !strcasecmp(".ts", &argv[1][len - 3])) {
328b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber        int fd = open(argv[1], O_RDONLY);
329e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber
330b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber        if (fd < 0) {
331b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber            fprintf(stderr, "Failed to open file '%s'.", argv[1]);
332b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber            return 1;
333b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber        }
334b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber
335b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber        source = new MyStreamSource(fd);
336b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber    } else {
337b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber        printf("Converting file to transport stream for streaming...\n");
338b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber
339b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber        source = new MyConvertingStreamSource(argv[1]);
340b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber    }
341e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber
342e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber    sp<IMediaPlayer> player =
343b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber        service->create(getpid(), client, source, 0);
344e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber
345e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber    if (player != NULL) {
346e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber        player->setVideoSurface(surface);
347e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber        player->start();
348e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber
349e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber        client->waitForEOS();
350e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber
351e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber        player->stop();
352e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber    } else {
353e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber        fprintf(stderr, "failed to instantiate player.\n");
354e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber    }
355e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber
356e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber    composerClient->dispose();
357e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber
358e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber    return 0;
359e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber}
360