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