stream.cpp revision 14acc736e336cbd6026df781d4f411e908831815
1#include <binder/ProcessState.h>
2
3#include <media/IStreamSource.h>
4#include <media/mediaplayer.h>
5#include <media/stagefright/foundation/ADebug.h>
6#include <media/stagefright/foundation/AMessage.h>
7
8#include <binder/IServiceManager.h>
9#include <media/IMediaPlayerService.h>
10#include <surfaceflinger/ISurfaceComposer.h>
11#include <surfaceflinger/SurfaceComposerClient.h>
12
13#include <fcntl.h>
14
15using namespace android;
16
17struct MyStreamSource : public BnStreamSource {
18    // Caller retains ownership of fd.
19    MyStreamSource(int fd);
20
21    virtual void setListener(const sp<IStreamListener> &listener);
22    virtual void setBuffers(const Vector<sp<IMemory> > &buffers);
23
24    virtual void onBufferAvailable(size_t index);
25
26protected:
27    virtual ~MyStreamSource();
28
29private:
30    int mFd;
31
32    sp<IStreamListener> mListener;
33    Vector<sp<IMemory> > mBuffers;
34
35    DISALLOW_EVIL_CONSTRUCTORS(MyStreamSource);
36};
37
38MyStreamSource::MyStreamSource(int fd)
39    : mFd(fd) {
40    CHECK_GE(fd, 0);
41}
42
43MyStreamSource::~MyStreamSource() {
44}
45
46void MyStreamSource::setListener(const sp<IStreamListener> &listener) {
47    mListener = listener;
48}
49
50void MyStreamSource::setBuffers(const Vector<sp<IMemory> > &buffers) {
51    mBuffers = buffers;
52}
53
54void MyStreamSource::onBufferAvailable(size_t index) {
55    CHECK_LT(index, mBuffers.size());
56    sp<IMemory> mem = mBuffers.itemAt(index);
57
58    ssize_t n = read(mFd, mem->pointer(), mem->size());
59    if (n <= 0) {
60        mListener->issueCommand(IStreamListener::EOS, false /* synchronous */);
61    } else {
62        mListener->queueBuffer(index, n);
63    }
64}
65
66////////////////////////////////////////////////////////////////////////////////
67
68struct MyClient : public BnMediaPlayerClient {
69    MyClient()
70        : mEOS(false) {
71    }
72
73    virtual void notify(int msg, int ext1, int ext2) {
74        Mutex::Autolock autoLock(mLock);
75
76        if (msg == MEDIA_ERROR || msg == MEDIA_PLAYBACK_COMPLETE) {
77            mEOS = true;
78            mCondition.signal();
79        }
80    }
81
82    void waitForEOS() {
83        Mutex::Autolock autoLock(mLock);
84        while (!mEOS) {
85            mCondition.wait(mLock);
86        }
87    }
88
89protected:
90    virtual ~MyClient() {
91    }
92
93private:
94    Mutex mLock;
95    Condition mCondition;
96
97    bool mEOS;
98
99    DISALLOW_EVIL_CONSTRUCTORS(MyClient);
100};
101
102int main(int argc, char **argv) {
103    android::ProcessState::self()->startThreadPool();
104
105    if (argc != 2) {
106        fprintf(stderr, "Usage: %s filename\n", argv[0]);
107        return 1;
108    }
109
110    sp<SurfaceComposerClient> composerClient = new SurfaceComposerClient;
111    CHECK_EQ(composerClient->initCheck(), (status_t)OK);
112
113    sp<SurfaceControl> control =
114        composerClient->createSurface(
115                getpid(),
116                String8("A Surface"),
117                0,
118                1280,
119                800,
120                PIXEL_FORMAT_RGB_565,
121                0);
122
123    CHECK(control != NULL);
124    CHECK(control->isValid());
125
126    CHECK_EQ(composerClient->openTransaction(), (status_t)OK);
127    CHECK_EQ(control->setLayer(30000), (status_t)OK);
128    CHECK_EQ(control->show(), (status_t)OK);
129    CHECK_EQ(composerClient->closeTransaction(), (status_t)OK);
130
131    sp<Surface> surface = control->getSurface();
132    CHECK(surface != NULL);
133
134    sp<IServiceManager> sm = defaultServiceManager();
135    sp<IBinder> binder = sm->getService(String16("media.player"));
136    sp<IMediaPlayerService> service = interface_cast<IMediaPlayerService>(binder);
137
138    CHECK(service.get() != NULL);
139
140    int fd = open(argv[1], O_RDONLY);
141
142    if (fd < 0) {
143        fprintf(stderr, "Failed to open file '%s'.", argv[1]);
144        return 1;
145    }
146
147    sp<MyClient> client = new MyClient;
148
149    sp<IMediaPlayer> player =
150        service->create(getpid(), client, new MyStreamSource(fd), 0);
151
152    if (player != NULL) {
153        player->setVideoSurface(surface);
154        player->start();
155
156        client->waitForEOS();
157
158        player->stop();
159    } else {
160        fprintf(stderr, "failed to instantiate player.\n");
161    }
162
163    close(fd);
164    fd = -1;
165
166    composerClient->dispose();
167
168    return 0;
169}
170