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