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