stream.cpp revision 3dca4c7a5622fc6aa03397d749c4b4c1201cc4f3
15778822d86b0337407514b9372562b86edfa91cdAndreas Huber/*
25778822d86b0337407514b9372562b86edfa91cdAndreas Huber * Copyright (C) 2010 The Android Open Source Project
35778822d86b0337407514b9372562b86edfa91cdAndreas Huber *
45778822d86b0337407514b9372562b86edfa91cdAndreas Huber * Licensed under the Apache License, Version 2.0 (the "License");
55778822d86b0337407514b9372562b86edfa91cdAndreas Huber * you may not use this file except in compliance with the License.
65778822d86b0337407514b9372562b86edfa91cdAndreas Huber * You may obtain a copy of the License at
75778822d86b0337407514b9372562b86edfa91cdAndreas Huber *
85778822d86b0337407514b9372562b86edfa91cdAndreas Huber *      http://www.apache.org/licenses/LICENSE-2.0
95778822d86b0337407514b9372562b86edfa91cdAndreas Huber *
105778822d86b0337407514b9372562b86edfa91cdAndreas Huber * Unless required by applicable law or agreed to in writing, software
115778822d86b0337407514b9372562b86edfa91cdAndreas Huber * distributed under the License is distributed on an "AS IS" BASIS,
125778822d86b0337407514b9372562b86edfa91cdAndreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
135778822d86b0337407514b9372562b86edfa91cdAndreas Huber * See the License for the specific language governing permissions and
145778822d86b0337407514b9372562b86edfa91cdAndreas Huber * limitations under the License.
155778822d86b0337407514b9372562b86edfa91cdAndreas Huber */
165778822d86b0337407514b9372562b86edfa91cdAndreas Huber
175778822d86b0337407514b9372562b86edfa91cdAndreas Huber//#define LOG_NDEBUG 0
185778822d86b0337407514b9372562b86edfa91cdAndreas Huber#define LOG_TAG "stream"
19377b2ec9a2885f9b6405b07ba900a9e3f4349c38Kévin PETIT#include "utils/Log.h"
205778822d86b0337407514b9372562b86edfa91cdAndreas Huber
215778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include <binder/ProcessState.h>
225778822d86b0337407514b9372562b86edfa91cdAndreas Huber
235778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include <media/IStreamSource.h>
241bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber#include <media/mediaplayer.h>
255778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include <media/stagefright/foundation/ADebug.h>
261bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber#include <media/stagefright/foundation/AMessage.h>
271b86fe063badb5f28c467ade39be0f4008688947Andreas Huber#include <media/stagefright/DataSource.h>
281bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber#include <media/stagefright/MPEG2TSWriter.h>
295778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include <media/stagefright/MediaExtractor.h>
305778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include <media/stagefright/MediaSource.h>
315778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include <media/stagefright/MetaData.h>
325778822d86b0337407514b9372562b86edfa91cdAndreas Huber
335b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber#include <binder/IServiceManager.h>
345778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include <media/IMediaPlayerService.h>
355778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include <gui/SurfaceComposerClient.h>
36ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
375778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include <fcntl.h>
385778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include <ui/DisplayInfo.h>
39a6195decfe4f9021bbbd7deb050495c33371366bJeff Brown
40df712ea86e6350f7005a02ab0e1c60c28a343ed0Mathias Agopianusing namespace android;
411a2952aee048ca7b1765e2bc09ebe9aeddaeafa3Mathias Agopian
423dca4c7a5622fc6aa03397d749c4b4c1201cc4f3Mathias Agopianstruct MyStreamSource : public BnStreamSource {
435778822d86b0337407514b9372562b86edfa91cdAndreas Huber    // Object assumes ownership of fd.
445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    MyStreamSource(int fd);
455778822d86b0337407514b9372562b86edfa91cdAndreas Huber
465778822d86b0337407514b9372562b86edfa91cdAndreas Huber    virtual void setListener(const sp<IStreamListener> &listener);
47bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber    virtual void setBuffers(const Vector<sp<IMemory> > &buffers);
48f69e53033f23f9f70fcdb28a3c2e650de0147459Andreas Huber
49ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    virtual void onBufferAvailable(size_t index);
505778822d86b0337407514b9372562b86edfa91cdAndreas Huber
515778822d86b0337407514b9372562b86edfa91cdAndreas Huberprotected:
525778822d86b0337407514b9372562b86edfa91cdAndreas Huber    virtual ~MyStreamSource();
535778822d86b0337407514b9372562b86edfa91cdAndreas Huber
545778822d86b0337407514b9372562b86edfa91cdAndreas Huberprivate:
555778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int mFd;
565778822d86b0337407514b9372562b86edfa91cdAndreas Huber    off64_t mFileSize;
575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    uint64_t mNumPacketsSent;
585778822d86b0337407514b9372562b86edfa91cdAndreas Huber
595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<IStreamListener> mListener;
605aaeb0d64fc98f9b019a4378eb39f0ee49ee6ec4Andreas Huber    Vector<sp<IMemory> > mBuffers;
615778822d86b0337407514b9372562b86edfa91cdAndreas Huber
62bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(MyStreamSource);
63bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber};
64bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber
655778822d86b0337407514b9372562b86edfa91cdAndreas HuberMyStreamSource::MyStreamSource(int fd)
665778822d86b0337407514b9372562b86edfa91cdAndreas Huber    : mFd(fd),
675778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mFileSize(0),
685778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mNumPacketsSent(0) {
695778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK_GE(fd, 0);
705778822d86b0337407514b9372562b86edfa91cdAndreas Huber
715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mFileSize = lseek64(fd, 0, SEEK_END);
725778822d86b0337407514b9372562b86edfa91cdAndreas Huber    lseek64(fd, 0, SEEK_SET);
73bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber}
74f69e53033f23f9f70fcdb28a3c2e650de0147459Andreas Huber
755778822d86b0337407514b9372562b86edfa91cdAndreas HuberMyStreamSource::~MyStreamSource() {
765778822d86b0337407514b9372562b86edfa91cdAndreas Huber    close(mFd);
77bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber    mFd = -1;
78bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber}
795778822d86b0337407514b9372562b86edfa91cdAndreas Huber
801b86fe063badb5f28c467ade39be0f4008688947Andreas Hubervoid MyStreamSource::setListener(const sp<IStreamListener> &listener) {
815778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mListener = listener;
825778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
835778822d86b0337407514b9372562b86edfa91cdAndreas Huber
845778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid MyStreamSource::setBuffers(const Vector<sp<IMemory> > &buffers) {
855778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mBuffers = buffers;
865778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
875778822d86b0337407514b9372562b86edfa91cdAndreas Huber
885778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid MyStreamSource::onBufferAvailable(size_t index) {
895778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK_LT(index, mBuffers.size());
905778822d86b0337407514b9372562b86edfa91cdAndreas Huber
915778822d86b0337407514b9372562b86edfa91cdAndreas Huber#if 0
925778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mNumPacketsSent >= 20000) {
935778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGI("signalling discontinuity now");
945778822d86b0337407514b9372562b86edfa91cdAndreas Huber
955778822d86b0337407514b9372562b86edfa91cdAndreas Huber        off64_t offset = 0;
965778822d86b0337407514b9372562b86edfa91cdAndreas Huber        CHECK((offset % 188) == 0);
97bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber
98bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber        lseek(mFd, offset, SEEK_SET);
99bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber
100bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber        sp<AMessage> extra = new AMessage;
1015778822d86b0337407514b9372562b86edfa91cdAndreas Huber        extra->setInt32(IStreamListener::kKeyFormatChange, 0);
102bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber
1035778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mListener->issueCommand(
1045778822d86b0337407514b9372562b86edfa91cdAndreas Huber                IStreamListener::DISCONTINUITY, false /* synchronous */, extra);
1055778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1065778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mNumPacketsSent = 0;
1075778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1085778822d86b0337407514b9372562b86edfa91cdAndreas Huber#endif
1095778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1105778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<IMemory> mem = mBuffers.itemAt(index);
1115778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1125778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ssize_t n = read(mFd, mem->pointer(), mem->size());
1135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (n <= 0) {
1145778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mListener->issueCommand(IStreamListener::EOS, false /* synchronous */);
1155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {
116bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber        mListener->queueBuffer(index, n);
117bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber
118bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber        mNumPacketsSent += n / 188;
119bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber    }
120f69e53033f23f9f70fcdb28a3c2e650de0147459Andreas Huber}
121f69e53033f23f9f70fcdb28a3c2e650de0147459Andreas Huber////////////////////////////////////////////////////////////////////////////////
1225778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1235778822d86b0337407514b9372562b86edfa91cdAndreas Huberstruct MyConvertingStreamSource : public BnStreamSource {
1245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    MyConvertingStreamSource(const char *filename);
1255778822d86b0337407514b9372562b86edfa91cdAndreas Huber
126ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    virtual void setListener(const sp<IStreamListener> &listener);
127f69e53033f23f9f70fcdb28a3c2e650de0147459Andreas Huber    virtual void setBuffers(const Vector<sp<IMemory> > &buffers);
1281bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber
1295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    virtual void onBufferAvailable(size_t index);
1305778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1315778822d86b0337407514b9372562b86edfa91cdAndreas Huberprotected:
1325aaeb0d64fc98f9b019a4378eb39f0ee49ee6ec4Andreas Huber    virtual ~MyConvertingStreamSource();
1335778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1345778822d86b0337407514b9372562b86edfa91cdAndreas Huberprivate:
1355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    Mutex mLock;
1365778822d86b0337407514b9372562b86edfa91cdAndreas Huber    Condition mCondition;
1375778822d86b0337407514b9372562b86edfa91cdAndreas Huber
138bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber    sp<IStreamListener> mListener;
139bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber    Vector<sp<IMemory> > mBuffers;
1405778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1415778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<MPEG2TSWriter> mWriter;
1425778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1435778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ssize_t mCurrentBufferIndex;
1445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    size_t mCurrentBufferOffset;
1455778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1465778822d86b0337407514b9372562b86edfa91cdAndreas Huber    List<size_t> mBufferQueue;
1475778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1485778822d86b0337407514b9372562b86edfa91cdAndreas Huber    static ssize_t WriteDataWrapper(void *me, const void *data, size_t size);
1495778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ssize_t writeData(const void *data, size_t size);
1505778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1515778822d86b0337407514b9372562b86edfa91cdAndreas Huber    DISALLOW_EVIL_CONSTRUCTORS(MyConvertingStreamSource);
1525778822d86b0337407514b9372562b86edfa91cdAndreas Huber};
1535778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1545778822d86b0337407514b9372562b86edfa91cdAndreas Huber////////////////////////////////////////////////////////////////////////////////
1555778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1565778822d86b0337407514b9372562b86edfa91cdAndreas HuberMyConvertingStreamSource::MyConvertingStreamSource(const char *filename)
1575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    : mCurrentBufferIndex(-1),
1585778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mCurrentBufferOffset(0) {
1595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<DataSource> dataSource = DataSource::CreateFromURI(filename);
1605778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(dataSource != NULL);
1615778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1625aaeb0d64fc98f9b019a4378eb39f0ee49ee6ec4Andreas Huber    sp<MediaExtractor> extractor = MediaExtractor::Create(dataSource);
1635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(extractor != NULL);
1645778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mWriter = new MPEG2TSWriter(
1665778822d86b0337407514b9372562b86edfa91cdAndreas Huber            this, &MyConvertingStreamSource::WriteDataWrapper);
1675778822d86b0337407514b9372562b86edfa91cdAndreas Huber
168bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber    for (size_t i = 0; i < extractor->countTracks(); ++i) {
1695778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const sp<MetaData> &meta = extractor->getTrackMetaData(i);
1705778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1715778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const char *mime;
1725778822d86b0337407514b9372562b86edfa91cdAndreas Huber        CHECK(meta->findCString(kKeyMIMEType, &mime));
1735778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1745778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (strncasecmp("video/", mime, 6) && strncasecmp("audio/", mime, 6)) {
1755778822d86b0337407514b9372562b86edfa91cdAndreas Huber            continue;
1765778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
1775778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1785778822d86b0337407514b9372562b86edfa91cdAndreas Huber        CHECK_EQ(mWriter->addSource(extractor->getTrack(i)), (status_t)OK);
1795778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1805778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1815778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK_EQ(mWriter->start(), (status_t)OK);
182ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber}
183ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
184f69e53033f23f9f70fcdb28a3c2e650de0147459Andreas HuberMyConvertingStreamSource::~MyConvertingStreamSource() {
185f69e53033f23f9f70fcdb28a3c2e650de0147459Andreas Huber}
186f69e53033f23f9f70fcdb28a3c2e650de0147459Andreas Huber
187f69e53033f23f9f70fcdb28a3c2e650de0147459Andreas Hubervoid MyConvertingStreamSource::setListener(
188f69e53033f23f9f70fcdb28a3c2e650de0147459Andreas Huber        const sp<IStreamListener> &listener) {
189f69e53033f23f9f70fcdb28a3c2e650de0147459Andreas Huber    mListener = listener;
1905778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
1915778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1925778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid MyConvertingStreamSource::setBuffers(
1935778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const Vector<sp<IMemory> > &buffers) {
1945778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mBuffers = buffers;
1955778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
1965778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1975778822d86b0337407514b9372562b86edfa91cdAndreas Huberssize_t MyConvertingStreamSource::WriteDataWrapper(
1985aaeb0d64fc98f9b019a4378eb39f0ee49ee6ec4Andreas Huber        void *me, const void *data, size_t size) {
1995aaeb0d64fc98f9b019a4378eb39f0ee49ee6ec4Andreas Huber    return static_cast<MyConvertingStreamSource *>(me)->writeData(data, size);
2005aaeb0d64fc98f9b019a4378eb39f0ee49ee6ec4Andreas Huber}
2015aaeb0d64fc98f9b019a4378eb39f0ee49ee6ec4Andreas Huber
2025aaeb0d64fc98f9b019a4378eb39f0ee49ee6ec4Andreas Huberssize_t MyConvertingStreamSource::writeData(const void *data, size_t size) {
2035aaeb0d64fc98f9b019a4378eb39f0ee49ee6ec4Andreas Huber    size_t totalWritten = 0;
2045aaeb0d64fc98f9b019a4378eb39f0ee49ee6ec4Andreas Huber
2055aaeb0d64fc98f9b019a4378eb39f0ee49ee6ec4Andreas Huber    while (size > 0) {
2065aaeb0d64fc98f9b019a4378eb39f0ee49ee6ec4Andreas Huber        Mutex::Autolock autoLock(mLock);
2075aaeb0d64fc98f9b019a4378eb39f0ee49ee6ec4Andreas Huber
2085aaeb0d64fc98f9b019a4378eb39f0ee49ee6ec4Andreas Huber        if (mCurrentBufferIndex < 0) {
2095aaeb0d64fc98f9b019a4378eb39f0ee49ee6ec4Andreas Huber            while (mBufferQueue.empty()) {
2105aaeb0d64fc98f9b019a4378eb39f0ee49ee6ec4Andreas Huber                mCondition.wait(mLock);
2115aaeb0d64fc98f9b019a4378eb39f0ee49ee6ec4Andreas Huber            }
2125aaeb0d64fc98f9b019a4378eb39f0ee49ee6ec4Andreas Huber
2135aaeb0d64fc98f9b019a4378eb39f0ee49ee6ec4Andreas Huber            mCurrentBufferIndex = *mBufferQueue.begin();
2145aaeb0d64fc98f9b019a4378eb39f0ee49ee6ec4Andreas Huber            mCurrentBufferOffset = 0;
2155aaeb0d64fc98f9b019a4378eb39f0ee49ee6ec4Andreas Huber
2165aaeb0d64fc98f9b019a4378eb39f0ee49ee6ec4Andreas Huber            mBufferQueue.erase(mBufferQueue.begin());
2175aaeb0d64fc98f9b019a4378eb39f0ee49ee6ec4Andreas Huber        }
2185aaeb0d64fc98f9b019a4378eb39f0ee49ee6ec4Andreas Huber
2195aaeb0d64fc98f9b019a4378eb39f0ee49ee6ec4Andreas Huber        sp<IMemory> mem = mBuffers.itemAt(mCurrentBufferIndex);
2205aaeb0d64fc98f9b019a4378eb39f0ee49ee6ec4Andreas Huber
2215aaeb0d64fc98f9b019a4378eb39f0ee49ee6ec4Andreas Huber        size_t copy = size;
2225aaeb0d64fc98f9b019a4378eb39f0ee49ee6ec4Andreas Huber        if (copy + mCurrentBufferOffset > mem->size()) {
2235aaeb0d64fc98f9b019a4378eb39f0ee49ee6ec4Andreas Huber            copy = mem->size() - mCurrentBufferOffset;
2245aaeb0d64fc98f9b019a4378eb39f0ee49ee6ec4Andreas Huber        }
2255778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2265778822d86b0337407514b9372562b86edfa91cdAndreas Huber        memcpy((uint8_t *)mem->pointer() + mCurrentBufferOffset, data, copy);
2275778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mCurrentBufferOffset += copy;
2285778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2295778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (mCurrentBufferOffset == mem->size()) {
2305778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mListener->queueBuffer(mCurrentBufferIndex, mCurrentBufferOffset);
2315778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mCurrentBufferIndex = -1;
2325778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
2335778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2345778822d86b0337407514b9372562b86edfa91cdAndreas Huber        data = (const uint8_t *)data + copy;
2355778822d86b0337407514b9372562b86edfa91cdAndreas Huber        size -= copy;
2365778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2375778822d86b0337407514b9372562b86edfa91cdAndreas Huber        totalWritten += copy;
2385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
2395778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return (ssize_t)totalWritten;
2415778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
2425778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2435778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid MyConvertingStreamSource::onBufferAvailable(size_t index) {
2445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    Mutex::Autolock autoLock(mLock);
2455778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2465778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mBufferQueue.push_back(index);
2475778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mCondition.signal();
2485778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2495778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mWriter->reachedEOS()) {
2505778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (mCurrentBufferIndex >= 0) {
2515778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mListener->queueBuffer(mCurrentBufferIndex, mCurrentBufferOffset);
2525778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mCurrentBufferIndex = -1;
2535778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
254bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber
2555778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mListener->issueCommand(IStreamListener::EOS, false /* synchronous */);
2565778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
2575778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
2585778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2595778822d86b0337407514b9372562b86edfa91cdAndreas Huber////////////////////////////////////////////////////////////////////////////////
260bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber
261bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huberstruct MyClient : public BnMediaPlayerClient {
262bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber    MyClient()
2635778822d86b0337407514b9372562b86edfa91cdAndreas Huber        : mEOS(false) {
2645778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
2655778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2665778822d86b0337407514b9372562b86edfa91cdAndreas Huber    virtual void notify(int msg, int ext1, int ext2, const Parcel *obj) {
2675778822d86b0337407514b9372562b86edfa91cdAndreas Huber        Mutex::Autolock autoLock(mLock);
2685778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2695778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (msg == MEDIA_ERROR || msg == MEDIA_PLAYBACK_COMPLETE) {
2705778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mEOS = true;
2715778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mCondition.signal();
2725778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
2735778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
2745778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2755778822d86b0337407514b9372562b86edfa91cdAndreas Huber    void waitForEOS() {
2765778822d86b0337407514b9372562b86edfa91cdAndreas Huber        Mutex::Autolock autoLock(mLock);
2775778822d86b0337407514b9372562b86edfa91cdAndreas Huber        while (!mEOS) {
2785778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mCondition.wait(mLock);
2795778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
2805778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
2815778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2825778822d86b0337407514b9372562b86edfa91cdAndreas Huberprotected:
2835778822d86b0337407514b9372562b86edfa91cdAndreas Huber    virtual ~MyClient() {
2845778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
2855778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2865778822d86b0337407514b9372562b86edfa91cdAndreas Huberprivate:
2875778822d86b0337407514b9372562b86edfa91cdAndreas Huber    Mutex mLock;
288bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber    Condition mCondition;
289bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber
2905778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bool mEOS;
2915778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2925778822d86b0337407514b9372562b86edfa91cdAndreas Huber    DISALLOW_EVIL_CONSTRUCTORS(MyClient);
293c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber};
294bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber
295bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huberint main(int argc, char **argv) {
296377b2ec9a2885f9b6405b07ba900a9e3f4349c38Kévin PETIT    android::ProcessState::self()->startThreadPool();
297bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber
298bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber    DataSource::RegisterDefaultSniffers();
299bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber
300bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber    if (argc != 2) {
301377b2ec9a2885f9b6405b07ba900a9e3f4349c38Kévin PETIT        fprintf(stderr, "Usage: %s filename\n", argv[0]);
302377b2ec9a2885f9b6405b07ba900a9e3f4349c38Kévin PETIT        return 1;
303bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber    }
304bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber
305bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber    sp<SurfaceComposerClient> composerClient = new SurfaceComposerClient;
306bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber    CHECK_EQ(composerClient->initCheck(), (status_t)OK);
307bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber
308bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber    DisplayInfo info;
3095778822d86b0337407514b9372562b86edfa91cdAndreas Huber    SurfaceComposerClient::getDisplayInfo(0, &info);
3105778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ssize_t displayWidth = info.w;
3115778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ssize_t displayHeight = info.h;
3125778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("display is %d x %d\n", displayWidth, displayHeight);
3145778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<SurfaceControl> control =
3165778822d86b0337407514b9372562b86edfa91cdAndreas Huber        composerClient->createSurface(
3175778822d86b0337407514b9372562b86edfa91cdAndreas Huber                String8("A Surface"),
3185778822d86b0337407514b9372562b86edfa91cdAndreas Huber                0,
3195778822d86b0337407514b9372562b86edfa91cdAndreas Huber                displayWidth,
3205778822d86b0337407514b9372562b86edfa91cdAndreas Huber                displayHeight,
3215778822d86b0337407514b9372562b86edfa91cdAndreas Huber                PIXEL_FORMAT_RGB_565,
322bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber                0);
3235778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(control != NULL);
325ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    CHECK(control->isValid());
3265778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    SurfaceComposerClient::openGlobalTransaction();
3285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK_EQ(control->setLayer(INT_MAX), (status_t)OK);
3295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK_EQ(control->show(), (status_t)OK);
3305778822d86b0337407514b9372562b86edfa91cdAndreas Huber    SurfaceComposerClient::closeGlobalTransaction();
3315778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<Surface> surface = control->getSurface();
3335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(surface != NULL);
3345778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<IServiceManager> sm = defaultServiceManager();
3365778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<IBinder> binder = sm->getService(String16("media.player"));
3375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<IMediaPlayerService> service = interface_cast<IMediaPlayerService>(binder);
3385778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3395778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(service.get() != NULL);
3405778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3415778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<MyClient> client = new MyClient;
3425778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3435778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<IStreamSource> source;
3445778822d86b0337407514b9372562b86edfa91cdAndreas Huber
345bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber    size_t len = strlen(argv[1]);
346bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber    if (len >= 3 && !strcasecmp(".ts", &argv[1][len - 3])) {
347bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber        int fd = open(argv[1], O_RDONLY);
348bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber
349bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber        if (fd < 0) {
350bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber            fprintf(stderr, "Failed to open file '%s'.", argv[1]);
3515778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return 1;
3525778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
3535778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3545778822d86b0337407514b9372562b86edfa91cdAndreas Huber        source = new MyStreamSource(fd);
3555778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {
3565778822d86b0337407514b9372562b86edfa91cdAndreas Huber        printf("Converting file to transport stream for streaming...\n");
3575778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3585778822d86b0337407514b9372562b86edfa91cdAndreas Huber        source = new MyConvertingStreamSource(argv[1]);
3595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
3605778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<IMediaPlayer> player =
3625778822d86b0337407514b9372562b86edfa91cdAndreas Huber        service->create(getpid(), client, 0);
3635778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3645778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (player != NULL && player->setDataSource(source) == NO_ERROR) {
3655778822d86b0337407514b9372562b86edfa91cdAndreas Huber        player->setVideoSurfaceTexture(surface->getSurfaceTexture());
3665778822d86b0337407514b9372562b86edfa91cdAndreas Huber        player->start();
3675778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3685778822d86b0337407514b9372562b86edfa91cdAndreas Huber        client->waitForEOS();
3695778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3705778822d86b0337407514b9372562b86edfa91cdAndreas Huber        player->stop();
3715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {
3725778822d86b0337407514b9372562b86edfa91cdAndreas Huber        fprintf(stderr, "failed to instantiate player.\n");
3735778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
3745778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3755778822d86b0337407514b9372562b86edfa91cdAndreas Huber    composerClient->dispose();
3765778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3775778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return 0;
378bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber}
379bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber