stream.cpp revision 8eb69d60c09c1c4683066a94c889df28d0e9d233
1/* 2 * Copyright (C) 2010 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#include <binder/ProcessState.h> 18 19#include <media/IStreamSource.h> 20#include <media/mediaplayer.h> 21#include <media/stagefright/foundation/ADebug.h> 22#include <media/stagefright/foundation/AMessage.h> 23 24#include <binder/IServiceManager.h> 25#include <media/IMediaPlayerService.h> 26#include <surfaceflinger/ISurfaceComposer.h> 27#include <surfaceflinger/SurfaceComposerClient.h> 28 29#include <fcntl.h> 30 31using namespace android; 32 33struct MyStreamSource : public BnStreamSource { 34 // Caller retains ownership of fd. 35 MyStreamSource(int fd); 36 37 virtual void setListener(const sp<IStreamListener> &listener); 38 virtual void setBuffers(const Vector<sp<IMemory> > &buffers); 39 40 virtual void onBufferAvailable(size_t index); 41 42protected: 43 virtual ~MyStreamSource(); 44 45private: 46 int mFd; 47 off64_t mFileSize; 48 int64_t mNextSeekTimeUs; 49 50 sp<IStreamListener> mListener; 51 Vector<sp<IMemory> > mBuffers; 52 53 DISALLOW_EVIL_CONSTRUCTORS(MyStreamSource); 54}; 55 56MyStreamSource::MyStreamSource(int fd) 57 : mFd(fd), 58 mFileSize(0), 59 mNextSeekTimeUs(-1) { // ALooper::GetNowUs() + 5000000ll) { 60 CHECK_GE(fd, 0); 61 62 mFileSize = lseek64(fd, 0, SEEK_END); 63 lseek64(fd, 0, SEEK_SET); 64} 65 66MyStreamSource::~MyStreamSource() { 67} 68 69void MyStreamSource::setListener(const sp<IStreamListener> &listener) { 70 mListener = listener; 71} 72 73void MyStreamSource::setBuffers(const Vector<sp<IMemory> > &buffers) { 74 mBuffers = buffers; 75} 76 77void MyStreamSource::onBufferAvailable(size_t index) { 78 CHECK_LT(index, mBuffers.size()); 79 80 if (mNextSeekTimeUs >= 0 && mNextSeekTimeUs <= ALooper::GetNowUs()) { 81 off64_t offset = (off64_t)(((float)rand() / RAND_MAX) * mFileSize * 0.8); 82 offset = (offset / 188) * 188; 83 84 lseek(mFd, offset, SEEK_SET); 85 86 mListener->issueCommand( 87 IStreamListener::DISCONTINUITY, false /* synchronous */); 88 89 mNextSeekTimeUs = -1; 90 mNextSeekTimeUs = ALooper::GetNowUs() + 5000000ll; 91 } 92 93 sp<IMemory> mem = mBuffers.itemAt(index); 94 95 ssize_t n = read(mFd, mem->pointer(), mem->size()); 96 if (n <= 0) { 97 mListener->issueCommand(IStreamListener::EOS, false /* synchronous */); 98 } else { 99 mListener->queueBuffer(index, n); 100 } 101} 102 103//////////////////////////////////////////////////////////////////////////////// 104 105struct MyClient : public BnMediaPlayerClient { 106 MyClient() 107 : mEOS(false) { 108 } 109 110 virtual void notify(int msg, int ext1, int ext2) { 111 Mutex::Autolock autoLock(mLock); 112 113 if (msg == MEDIA_ERROR || msg == MEDIA_PLAYBACK_COMPLETE) { 114 mEOS = true; 115 mCondition.signal(); 116 } 117 } 118 119 void waitForEOS() { 120 Mutex::Autolock autoLock(mLock); 121 while (!mEOS) { 122 mCondition.wait(mLock); 123 } 124 } 125 126protected: 127 virtual ~MyClient() { 128 } 129 130private: 131 Mutex mLock; 132 Condition mCondition; 133 134 bool mEOS; 135 136 DISALLOW_EVIL_CONSTRUCTORS(MyClient); 137}; 138 139int main(int argc, char **argv) { 140 android::ProcessState::self()->startThreadPool(); 141 142 if (argc != 2) { 143 fprintf(stderr, "Usage: %s filename\n", argv[0]); 144 return 1; 145 } 146 147 sp<SurfaceComposerClient> composerClient = new SurfaceComposerClient; 148 CHECK_EQ(composerClient->initCheck(), (status_t)OK); 149 150 sp<SurfaceControl> control = 151 composerClient->createSurface( 152 getpid(), 153 String8("A Surface"), 154 0, 155 1280, 156 800, 157 PIXEL_FORMAT_RGB_565, 158 0); 159 160 CHECK(control != NULL); 161 CHECK(control->isValid()); 162 163 CHECK_EQ(composerClient->openTransaction(), (status_t)OK); 164 CHECK_EQ(control->setLayer(30000), (status_t)OK); 165 CHECK_EQ(control->show(), (status_t)OK); 166 CHECK_EQ(composerClient->closeTransaction(), (status_t)OK); 167 168 sp<Surface> surface = control->getSurface(); 169 CHECK(surface != NULL); 170 171 sp<IServiceManager> sm = defaultServiceManager(); 172 sp<IBinder> binder = sm->getService(String16("media.player")); 173 sp<IMediaPlayerService> service = interface_cast<IMediaPlayerService>(binder); 174 175 CHECK(service.get() != NULL); 176 177 int fd = open(argv[1], O_RDONLY); 178 179 if (fd < 0) { 180 fprintf(stderr, "Failed to open file '%s'.", argv[1]); 181 return 1; 182 } 183 184 sp<MyClient> client = new MyClient; 185 186 sp<IMediaPlayer> player = 187 service->create(getpid(), client, new MyStreamSource(fd), 0); 188 189 if (player != NULL) { 190 player->setVideoSurface(surface); 191 player->start(); 192 193 client->waitForEOS(); 194 195 player->stop(); 196 } else { 197 fprintf(stderr, "failed to instantiate player.\n"); 198 } 199 200 close(fd); 201 fd = -1; 202 203 composerClient->dispose(); 204 205 return 0; 206} 207