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