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
179a442c1b9a051edc6d4ceb0daad2d0a8433e7b0bAndreas Huber//#define LOG_NDEBUG 0
189a442c1b9a051edc6d4ceb0daad2d0a8433e7b0bAndreas Huber#define LOG_TAG "stream"
199a442c1b9a051edc6d4ceb0daad2d0a8433e7b0bAndreas Huber#include "utils/Log.h"
209a442c1b9a051edc6d4ceb0daad2d0a8433e7b0bAndreas Huber
21e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber#include <binder/ProcessState.h>
22840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber#include <cutils/properties.h> // for property_get
23e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber
241b86fe063badb5f28c467ade39be0f4008688947Andreas Huber#include <media/IMediaHTTPService.h>
25e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber#include <media/IStreamSource.h>
26e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber#include <media/mediaplayer.h>
27e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber#include <media/stagefright/foundation/ADebug.h>
2814acc736e336cbd6026df781d4f411e908831815Andreas Huber#include <media/stagefright/foundation/AMessage.h>
29b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber#include <media/stagefright/DataSource.h>
30b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber#include <media/stagefright/MPEG2TSWriter.h>
31b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber#include <media/stagefright/MediaExtractor.h>
32b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber#include <media/stagefright/MediaSource.h>
33b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber#include <media/stagefright/MetaData.h>
34e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber
35e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber#include <binder/IServiceManager.h>
36e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber#include <media/IMediaPlayerService.h>
37a6195decfe4f9021bbbd7deb050495c33371366bJeff Brown#include <gui/ISurfaceComposer.h>
38df712ea86e6350f7005a02ab0e1c60c28a343ed0Mathias Agopian#include <gui/SurfaceComposerClient.h>
391a2952aee048ca7b1765e2bc09ebe9aeddaeafa3Mathias Agopian#include <gui/Surface.h>
40e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber
41e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber#include <fcntl.h>
423dca4c7a5622fc6aa03397d749c4b4c1201cc4f3Mathias Agopian#include <ui/DisplayInfo.h>
43e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber
44e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huberusing namespace android;
45e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber
46e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huberstruct MyStreamSource : public BnStreamSource {
47b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber    // Object assumes ownership of fd.
48090ef604f81447eab4aa0a5b45d6307482573560Chih-Hung Hsieh    explicit MyStreamSource(int fd);
49e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber
50e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber    virtual void setListener(const sp<IStreamListener> &listener);
51e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber    virtual void setBuffers(const Vector<sp<IMemory> > &buffers);
52e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber
53e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber    virtual void onBufferAvailable(size_t index);
54e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber
55e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huberprotected:
56e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber    virtual ~MyStreamSource();
57e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber
58e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huberprivate:
59e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber    int mFd;
60f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    off64_t mFileSize;
619a442c1b9a051edc6d4ceb0daad2d0a8433e7b0bAndreas Huber    uint64_t mNumPacketsSent;
62e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber
63e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber    sp<IStreamListener> mListener;
64e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber    Vector<sp<IMemory> > mBuffers;
65e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber
66e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(MyStreamSource);
67e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber};
68e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber
69e2b1028852120bcfded33b8f06f66b780437fe92Andreas HuberMyStreamSource::MyStreamSource(int fd)
70f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : mFd(fd),
71f933441648ef6a71dee783d733aac17b9508b452Andreas Huber      mFileSize(0),
729a442c1b9a051edc6d4ceb0daad2d0a8433e7b0bAndreas Huber      mNumPacketsSent(0) {
73e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber    CHECK_GE(fd, 0);
74f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
75f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mFileSize = lseek64(fd, 0, SEEK_END);
76f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    lseek64(fd, 0, SEEK_SET);
77e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber}
78e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber
79e2b1028852120bcfded33b8f06f66b780437fe92Andreas HuberMyStreamSource::~MyStreamSource() {
80b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber    close(mFd);
81b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber    mFd = -1;
82e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber}
83e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber
84e2b1028852120bcfded33b8f06f66b780437fe92Andreas Hubervoid MyStreamSource::setListener(const sp<IStreamListener> &listener) {
85e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber    mListener = listener;
86e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber}
87e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber
88e2b1028852120bcfded33b8f06f66b780437fe92Andreas Hubervoid MyStreamSource::setBuffers(const Vector<sp<IMemory> > &buffers) {
89e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber    mBuffers = buffers;
90e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber}
91e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber
92e2b1028852120bcfded33b8f06f66b780437fe92Andreas Hubervoid MyStreamSource::onBufferAvailable(size_t index) {
93e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber    CHECK_LT(index, mBuffers.size());
94f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
959a442c1b9a051edc6d4ceb0daad2d0a8433e7b0bAndreas Huber#if 0
969a442c1b9a051edc6d4ceb0daad2d0a8433e7b0bAndreas Huber    if (mNumPacketsSent >= 20000) {
97df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block        ALOGI("signalling discontinuity now");
989a442c1b9a051edc6d4ceb0daad2d0a8433e7b0bAndreas Huber
999a442c1b9a051edc6d4ceb0daad2d0a8433e7b0bAndreas Huber        off64_t offset = 0;
1009a442c1b9a051edc6d4ceb0daad2d0a8433e7b0bAndreas Huber        CHECK((offset % 188) == 0);
101f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
102f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        lseek(mFd, offset, SEEK_SET);
103f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1049a442c1b9a051edc6d4ceb0daad2d0a8433e7b0bAndreas Huber        sp<AMessage> extra = new AMessage;
1059a442c1b9a051edc6d4ceb0daad2d0a8433e7b0bAndreas Huber        extra->setInt32(IStreamListener::kKeyFormatChange, 0);
1069a442c1b9a051edc6d4ceb0daad2d0a8433e7b0bAndreas Huber
107f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mListener->issueCommand(
1089a442c1b9a051edc6d4ceb0daad2d0a8433e7b0bAndreas Huber                IStreamListener::DISCONTINUITY, false /* synchronous */, extra);
109f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1109a442c1b9a051edc6d4ceb0daad2d0a8433e7b0bAndreas Huber        mNumPacketsSent = 0;
111f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1129a442c1b9a051edc6d4ceb0daad2d0a8433e7b0bAndreas Huber#endif
113f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
114e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber    sp<IMemory> mem = mBuffers.itemAt(index);
115e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber
116e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber    ssize_t n = read(mFd, mem->pointer(), mem->size());
117e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber    if (n <= 0) {
11814acc736e336cbd6026df781d4f411e908831815Andreas Huber        mListener->issueCommand(IStreamListener::EOS, false /* synchronous */);
119e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber    } else {
120e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber        mListener->queueBuffer(index, n);
1219a442c1b9a051edc6d4ceb0daad2d0a8433e7b0bAndreas Huber
1229a442c1b9a051edc6d4ceb0daad2d0a8433e7b0bAndreas Huber        mNumPacketsSent += n / 188;
123e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber    }
124e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber}
125b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber////////////////////////////////////////////////////////////////////////////////
126b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber
127b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huberstruct MyConvertingStreamSource : public BnStreamSource {
128090ef604f81447eab4aa0a5b45d6307482573560Chih-Hung Hsieh    explicit MyConvertingStreamSource(const char *filename);
129b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber
130b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber    virtual void setListener(const sp<IStreamListener> &listener);
131b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber    virtual void setBuffers(const Vector<sp<IMemory> > &buffers);
132b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber
133b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber    virtual void onBufferAvailable(size_t index);
134b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber
135b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huberprotected:
136b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber    virtual ~MyConvertingStreamSource();
137b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber
138b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huberprivate:
139b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber    Mutex mLock;
140b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber    Condition mCondition;
141b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber
142b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber    sp<IStreamListener> mListener;
143b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber    Vector<sp<IMemory> > mBuffers;
144b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber
145b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber    sp<MPEG2TSWriter> mWriter;
146b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber
147b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber    ssize_t mCurrentBufferIndex;
148b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber    size_t mCurrentBufferOffset;
149b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber
150b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber    List<size_t> mBufferQueue;
151b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber
152b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber    static ssize_t WriteDataWrapper(void *me, const void *data, size_t size);
153b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber    ssize_t writeData(const void *data, size_t size);
154b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber
155b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber    DISALLOW_EVIL_CONSTRUCTORS(MyConvertingStreamSource);
156b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber};
157b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber
158b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber////////////////////////////////////////////////////////////////////////////////
159b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber
160b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas HuberMyConvertingStreamSource::MyConvertingStreamSource(const char *filename)
161b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber    : mCurrentBufferIndex(-1),
162b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber      mCurrentBufferOffset(0) {
1631b86fe063badb5f28c467ade39be0f4008688947Andreas Huber    sp<DataSource> dataSource =
1641b86fe063badb5f28c467ade39be0f4008688947Andreas Huber        DataSource::CreateFromURI(NULL /* httpService */, filename);
1651b86fe063badb5f28c467ade39be0f4008688947Andreas Huber
166b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber    CHECK(dataSource != NULL);
167b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber
168b2487f03f12dcafdb801fc0007c8df8412397f44Marco Nelissen    sp<IMediaExtractor> extractor = MediaExtractor::Create(dataSource);
169b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber    CHECK(extractor != NULL);
170b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber
171b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber    mWriter = new MPEG2TSWriter(
172b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber            this, &MyConvertingStreamSource::WriteDataWrapper);
173b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber
174322db26b76f7511c6d73f34a92a4e54840fcb876Wei Jia    size_t numTracks = extractor->countTracks();
175322db26b76f7511c6d73f34a92a4e54840fcb876Wei Jia    for (size_t i = 0; i < numTracks; ++i) {
176b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber        const sp<MetaData> &meta = extractor->getTrackMetaData(i);
177b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber
178b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber        const char *mime;
179b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber        CHECK(meta->findCString(kKeyMIMEType, &mime));
180b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber
181b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber        if (strncasecmp("video/", mime, 6) && strncasecmp("audio/", mime, 6)) {
182b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber            continue;
183b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber        }
184b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber
185322db26b76f7511c6d73f34a92a4e54840fcb876Wei Jia        sp<IMediaSource> track = extractor->getTrack(i);
186322db26b76f7511c6d73f34a92a4e54840fcb876Wei Jia        if (track == nullptr) {
187322db26b76f7511c6d73f34a92a4e54840fcb876Wei Jia            fprintf(stderr, "skip NULL track %zu, total tracks %zu\n", i, numTracks);
188322db26b76f7511c6d73f34a92a4e54840fcb876Wei Jia            continue;
189322db26b76f7511c6d73f34a92a4e54840fcb876Wei Jia        }
190322db26b76f7511c6d73f34a92a4e54840fcb876Wei Jia        CHECK_EQ(mWriter->addSource(track), (status_t)OK);
191b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber    }
192b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber
193b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber    CHECK_EQ(mWriter->start(), (status_t)OK);
194b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber}
195b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber
196b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas HuberMyConvertingStreamSource::~MyConvertingStreamSource() {
197b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber}
198b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber
199b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Hubervoid MyConvertingStreamSource::setListener(
200b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber        const sp<IStreamListener> &listener) {
201b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber    mListener = listener;
202b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber}
203b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber
204b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Hubervoid MyConvertingStreamSource::setBuffers(
205b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber        const Vector<sp<IMemory> > &buffers) {
206b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber    mBuffers = buffers;
207b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber}
208b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber
209b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huberssize_t MyConvertingStreamSource::WriteDataWrapper(
210b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber        void *me, const void *data, size_t size) {
211b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber    return static_cast<MyConvertingStreamSource *>(me)->writeData(data, size);
212b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber}
213b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber
214b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huberssize_t MyConvertingStreamSource::writeData(const void *data, size_t size) {
215b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber    size_t totalWritten = 0;
216b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber
217b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber    while (size > 0) {
218b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber        Mutex::Autolock autoLock(mLock);
219b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber
220b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber        if (mCurrentBufferIndex < 0) {
221b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber            while (mBufferQueue.empty()) {
222b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber                mCondition.wait(mLock);
223b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber            }
224b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber
225b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber            mCurrentBufferIndex = *mBufferQueue.begin();
226b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber            mCurrentBufferOffset = 0;
227b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber
228b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber            mBufferQueue.erase(mBufferQueue.begin());
229b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber        }
230b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber
231b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber        sp<IMemory> mem = mBuffers.itemAt(mCurrentBufferIndex);
232b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber
233b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber        size_t copy = size;
234b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber        if (copy + mCurrentBufferOffset > mem->size()) {
235b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber            copy = mem->size() - mCurrentBufferOffset;
236b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber        }
237b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber
238b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber        memcpy((uint8_t *)mem->pointer() + mCurrentBufferOffset, data, copy);
239b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber        mCurrentBufferOffset += copy;
240b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber
241b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber        if (mCurrentBufferOffset == mem->size()) {
242b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber            mListener->queueBuffer(mCurrentBufferIndex, mCurrentBufferOffset);
243b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber            mCurrentBufferIndex = -1;
244b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber        }
245b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber
246b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber        data = (const uint8_t *)data + copy;
247b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber        size -= copy;
248b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber
249b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber        totalWritten += copy;
250b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber    }
251b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber
252b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber    return (ssize_t)totalWritten;
253b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber}
254b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber
255b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Hubervoid MyConvertingStreamSource::onBufferAvailable(size_t index) {
256b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber    Mutex::Autolock autoLock(mLock);
257b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber
258b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber    mBufferQueue.push_back(index);
259b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber    mCondition.signal();
260b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber
261b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber    if (mWriter->reachedEOS()) {
262b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber        if (mCurrentBufferIndex >= 0) {
263b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber            mListener->queueBuffer(mCurrentBufferIndex, mCurrentBufferOffset);
264b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber            mCurrentBufferIndex = -1;
265b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber        }
266b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber
267b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber        mListener->issueCommand(IStreamListener::EOS, false /* synchronous */);
268b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber    }
269b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber}
270e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber
271e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber////////////////////////////////////////////////////////////////////////////////
272e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber
273e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huberstruct MyClient : public BnMediaPlayerClient {
274e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber    MyClient()
275e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber        : mEOS(false) {
276e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber    }
277e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber
27831de88566257d5546cf4eee9064d96926a4b0c24Lajos Molnar    virtual void notify(int msg, int ext1 __unused, int ext2 __unused, const Parcel *obj __unused) {
279e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber        Mutex::Autolock autoLock(mLock);
280e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber
281e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber        if (msg == MEDIA_ERROR || msg == MEDIA_PLAYBACK_COMPLETE) {
282e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber            mEOS = true;
283e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber            mCondition.signal();
284e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber        }
285e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber    }
286e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber
287e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber    void waitForEOS() {
288e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber        Mutex::Autolock autoLock(mLock);
289e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber        while (!mEOS) {
290e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber            mCondition.wait(mLock);
291e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber        }
292e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber    }
293e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber
294e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huberprotected:
295e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber    virtual ~MyClient() {
296e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber    }
297e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber
298e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huberprivate:
299e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber    Mutex mLock;
300e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber    Condition mCondition;
301e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber
302e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber    bool mEOS;
303e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber
304e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(MyClient);
305e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber};
306e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber
307e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huberint main(int argc, char **argv) {
308e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber    android::ProcessState::self()->startThreadPool();
309e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber
310e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber    if (argc != 2) {
311e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber        fprintf(stderr, "Usage: %s filename\n", argv[0]);
312e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber        return 1;
313e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber    }
314e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber
315e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber    sp<SurfaceComposerClient> composerClient = new SurfaceComposerClient;
316e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber    CHECK_EQ(composerClient->initCheck(), (status_t)OK);
317e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber
318a6195decfe4f9021bbbd7deb050495c33371366bJeff Brown    sp<IBinder> display(SurfaceComposerClient::getBuiltInDisplay(
319a6195decfe4f9021bbbd7deb050495c33371366bJeff Brown            ISurfaceComposer::eDisplayIdMain));
3203dca4c7a5622fc6aa03397d749c4b4c1201cc4f3Mathias Agopian    DisplayInfo info;
321a6195decfe4f9021bbbd7deb050495c33371366bJeff Brown    SurfaceComposerClient::getDisplayInfo(display, &info);
3223dca4c7a5622fc6aa03397d749c4b4c1201cc4f3Mathias Agopian    ssize_t displayWidth = info.w;
3233dca4c7a5622fc6aa03397d749c4b4c1201cc4f3Mathias Agopian    ssize_t displayHeight = info.h;
3249a442c1b9a051edc6d4ceb0daad2d0a8433e7b0bAndreas Huber
32531de88566257d5546cf4eee9064d96926a4b0c24Lajos Molnar    ALOGV("display is %zd x %zd\n", displayWidth, displayHeight);
3269a442c1b9a051edc6d4ceb0daad2d0a8433e7b0bAndreas Huber
327e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber    sp<SurfaceControl> control =
328e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber        composerClient->createSurface(
329e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber                String8("A Surface"),
3309a442c1b9a051edc6d4ceb0daad2d0a8433e7b0bAndreas Huber                displayWidth,
3319a442c1b9a051edc6d4ceb0daad2d0a8433e7b0bAndreas Huber                displayHeight,
332e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber                PIXEL_FORMAT_RGB_565,
333e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber                0);
334e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber
335e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber    CHECK(control != NULL);
336e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber    CHECK(control->isValid());
337e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber
3382df788fb0c402938f827bf9c9ce2ca3ab1dcd464Mathias Agopian    SurfaceComposerClient::openGlobalTransaction();
33993d5ab693626fa2700375e838e4bb90e4d50e605Andreas Huber    CHECK_EQ(control->setLayer(INT_MAX), (status_t)OK);
340e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber    CHECK_EQ(control->show(), (status_t)OK);
3412df788fb0c402938f827bf9c9ce2ca3ab1dcd464Mathias Agopian    SurfaceComposerClient::closeGlobalTransaction();
342e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber
343e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber    sp<Surface> surface = control->getSurface();
344e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber    CHECK(surface != NULL);
345e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber
346e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber    sp<IServiceManager> sm = defaultServiceManager();
347e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber    sp<IBinder> binder = sm->getService(String16("media.player"));
348e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber    sp<IMediaPlayerService> service = interface_cast<IMediaPlayerService>(binder);
349e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber
350e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber    CHECK(service.get() != NULL);
351e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber
352b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber    sp<MyClient> client = new MyClient;
353b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber
354b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber    sp<IStreamSource> source;
355e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber
35696626b7f9a4e5c9e1e04f7f710383631d1470364Marco Nelissen    bool usemp4 = property_get_bool("media.stagefright.use-mp4source", false);
357840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber
358b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber    size_t len = strlen(argv[1]);
359840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber    if ((!usemp4 && len >= 3 && !strcasecmp(".ts", &argv[1][len - 3])) ||
360b9787142c5f5f8f47e7e35409f4f2ef7112ab72eAndreas Huber        (usemp4 && len >= 4 &&
361b9787142c5f5f8f47e7e35409f4f2ef7112ab72eAndreas Huber         (!strcasecmp(".mp4", &argv[1][len - 4])
362b9787142c5f5f8f47e7e35409f4f2ef7112ab72eAndreas Huber            || !strcasecmp(".3gp", &argv[1][len- 4])
363b9787142c5f5f8f47e7e35409f4f2ef7112ab72eAndreas Huber            || !strcasecmp(".3g2", &argv[1][len- 4])))) {
364b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber        int fd = open(argv[1], O_RDONLY);
365e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber
366b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber        if (fd < 0) {
367b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber            fprintf(stderr, "Failed to open file '%s'.", argv[1]);
368b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber            return 1;
369b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber        }
370b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber
371b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber        source = new MyStreamSource(fd);
372b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber    } else {
373b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber        printf("Converting file to transport stream for streaming...\n");
374b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber
375b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber        source = new MyConvertingStreamSource(argv[1]);
376b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber    }
377e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber
378e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber    sp<IMediaPlayer> player =
37966e4635cb09fadcaccf912f37c387396c428378aGlenn Kasten        service->create(client, AUDIO_SESSION_ALLOCATE);
380e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber
381d681bbb1767bed09415e050ba78975df214bcd68Dave Burke    if (player != NULL && player->setDataSource(source) == NO_ERROR) {
3829e1cdea45d40fa8cf95dd080943053856009054fMathias Agopian        player->setVideoSurfaceTexture(surface->getIGraphicBufferProducer());
383e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber        player->start();
384e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber
385e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber        client->waitForEOS();
386e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber
387e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber        player->stop();
388e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber    } else {
389e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber        fprintf(stderr, "failed to instantiate player.\n");
390e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber    }
391e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber
392e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber    composerClient->dispose();
393e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber
394e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber    return 0;
395e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber}
396