stream.cpp revision 2df788fb0c402938f827bf9c9ce2ca3ab1dcd464
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>
23e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber
24e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber#include <binder/IServiceManager.h>
25e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber#include <media/IMediaPlayerService.h>
26e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber#include <surfaceflinger/ISurfaceComposer.h>
27e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber#include <surfaceflinger/SurfaceComposerClient.h>
28e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber
29e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber#include <fcntl.h>
30e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber
31e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huberusing namespace android;
32e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber
33e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huberstruct MyStreamSource : public BnStreamSource {
34e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber    // Caller retains ownership of fd.
35e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber    MyStreamSource(int fd);
36e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber
37e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber    virtual void setListener(const sp<IStreamListener> &listener);
38e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber    virtual void setBuffers(const Vector<sp<IMemory> > &buffers);
39e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber
40e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber    virtual void onBufferAvailable(size_t index);
41e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber
42e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huberprotected:
43e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber    virtual ~MyStreamSource();
44e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber
45e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huberprivate:
46e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber    int mFd;
47f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    off64_t mFileSize;
48f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int64_t mNextSeekTimeUs;
49e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber
50e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber    sp<IStreamListener> mListener;
51e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber    Vector<sp<IMemory> > mBuffers;
52e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber
53e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(MyStreamSource);
54e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber};
55e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber
56e2b1028852120bcfded33b8f06f66b780437fe92Andreas HuberMyStreamSource::MyStreamSource(int fd)
57f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : mFd(fd),
58f933441648ef6a71dee783d733aac17b9508b452Andreas Huber      mFileSize(0),
595bc087c573c70c84c6a39946457590b42d392a33Andreas Huber      mNextSeekTimeUs(-1) {  // ALooper::GetNowUs() + 5000000ll) {
60e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber    CHECK_GE(fd, 0);
61f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
62f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mFileSize = lseek64(fd, 0, SEEK_END);
63f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    lseek64(fd, 0, SEEK_SET);
64e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber}
65e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber
66e2b1028852120bcfded33b8f06f66b780437fe92Andreas HuberMyStreamSource::~MyStreamSource() {
67e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber}
68e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber
69e2b1028852120bcfded33b8f06f66b780437fe92Andreas Hubervoid MyStreamSource::setListener(const sp<IStreamListener> &listener) {
70e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber    mListener = listener;
71e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber}
72e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber
73e2b1028852120bcfded33b8f06f66b780437fe92Andreas Hubervoid MyStreamSource::setBuffers(const Vector<sp<IMemory> > &buffers) {
74e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber    mBuffers = buffers;
75e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber}
76e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber
77e2b1028852120bcfded33b8f06f66b780437fe92Andreas Hubervoid MyStreamSource::onBufferAvailable(size_t index) {
78e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber    CHECK_LT(index, mBuffers.size());
79f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
80f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mNextSeekTimeUs >= 0 && mNextSeekTimeUs <= ALooper::GetNowUs()) {
81f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        off64_t offset = (off64_t)(((float)rand() / RAND_MAX) * mFileSize * 0.8);
82f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        offset = (offset / 188) * 188;
83f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
84f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        lseek(mFd, offset, SEEK_SET);
85f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
86f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mListener->issueCommand(
87f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                IStreamListener::DISCONTINUITY, false /* synchronous */);
88f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
89f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mNextSeekTimeUs = -1;
90f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mNextSeekTimeUs = ALooper::GetNowUs() + 5000000ll;
91f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
92f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
93e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber    sp<IMemory> mem = mBuffers.itemAt(index);
94e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber
95e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber    ssize_t n = read(mFd, mem->pointer(), mem->size());
96e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber    if (n <= 0) {
9714acc736e336cbd6026df781d4f411e908831815Andreas Huber        mListener->issueCommand(IStreamListener::EOS, false /* synchronous */);
98e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber    } else {
99e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber        mListener->queueBuffer(index, n);
100e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber    }
101e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber}
102e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber
103e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber////////////////////////////////////////////////////////////////////////////////
104e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber
105e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huberstruct MyClient : public BnMediaPlayerClient {
106e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber    MyClient()
107e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber        : mEOS(false) {
108e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber    }
109e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber
110b483c4724846c0b8d4e82afcbb7c17f671bae81cGloria Wang    virtual void notify(int msg, int ext1, int ext2, const Parcel *obj) {
111e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber        Mutex::Autolock autoLock(mLock);
112e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber
113e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber        if (msg == MEDIA_ERROR || msg == MEDIA_PLAYBACK_COMPLETE) {
114e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber            mEOS = true;
115e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber            mCondition.signal();
116e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber        }
117e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber    }
118e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber
119e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber    void waitForEOS() {
120e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber        Mutex::Autolock autoLock(mLock);
121e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber        while (!mEOS) {
122e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber            mCondition.wait(mLock);
123e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber        }
124e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber    }
125e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber
126e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huberprotected:
127e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber    virtual ~MyClient() {
128e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber    }
129e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber
130e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huberprivate:
131e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber    Mutex mLock;
132e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber    Condition mCondition;
133e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber
134e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber    bool mEOS;
135e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber
136e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(MyClient);
137e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber};
138e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber
139e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huberint main(int argc, char **argv) {
140e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber    android::ProcessState::self()->startThreadPool();
141e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber
142e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber    if (argc != 2) {
143e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber        fprintf(stderr, "Usage: %s filename\n", argv[0]);
144e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber        return 1;
145e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber    }
146e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber
147e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber    sp<SurfaceComposerClient> composerClient = new SurfaceComposerClient;
148e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber    CHECK_EQ(composerClient->initCheck(), (status_t)OK);
149e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber
150e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber    sp<SurfaceControl> control =
151e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber        composerClient->createSurface(
152e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber                String8("A Surface"),
153e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber                0,
154e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber                1280,
155e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber                800,
156e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber                PIXEL_FORMAT_RGB_565,
157e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber                0);
158e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber
159e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber    CHECK(control != NULL);
160e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber    CHECK(control->isValid());
161e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber
1622df788fb0c402938f827bf9c9ce2ca3ab1dcd464Mathias Agopian    SurfaceComposerClient::openGlobalTransaction();
163e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber    CHECK_EQ(control->setLayer(30000), (status_t)OK);
164e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber    CHECK_EQ(control->show(), (status_t)OK);
1652df788fb0c402938f827bf9c9ce2ca3ab1dcd464Mathias Agopian    SurfaceComposerClient::closeGlobalTransaction();
166e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber
167e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber    sp<Surface> surface = control->getSurface();
168e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber    CHECK(surface != NULL);
169e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber
170e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber    sp<IServiceManager> sm = defaultServiceManager();
171e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber    sp<IBinder> binder = sm->getService(String16("media.player"));
172e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber    sp<IMediaPlayerService> service = interface_cast<IMediaPlayerService>(binder);
173e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber
174e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber    CHECK(service.get() != NULL);
175e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber
176e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber    int fd = open(argv[1], O_RDONLY);
177e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber
178e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber    if (fd < 0) {
179e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber        fprintf(stderr, "Failed to open file '%s'.", argv[1]);
180e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber        return 1;
181e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber    }
182e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber
183e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber    sp<MyClient> client = new MyClient;
184e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber
185e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber    sp<IMediaPlayer> player =
186e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber        service->create(getpid(), client, new MyStreamSource(fd), 0);
187e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber
188e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber    if (player != NULL) {
189e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber        player->setVideoSurface(surface);
190e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber        player->start();
191e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber
192e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber        client->waitForEOS();
193e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber
194e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber        player->stop();
195e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber    } else {
196e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber        fprintf(stderr, "failed to instantiate player.\n");
197e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber    }
198e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber
199e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber    close(fd);
200e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber    fd = -1;
201e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber
202e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber    composerClient->dispose();
203e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber
204e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber    return 0;
205e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber}
206