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