stream.cpp revision 31de88566257d5546cf4eee9064d96926a4b0c24
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 179a442c1b9a051edc6d4ceb0daad2d0a8433e7b0bAndreas Huber//#define LOG_NDEBUG 0 189a442c1b9a051edc6d4ceb0daad2d0a8433e7b0bAndreas Huber#define LOG_TAG "stream" 199a442c1b9a051edc6d4ceb0daad2d0a8433e7b0bAndreas Huber#include "utils/Log.h" 209a442c1b9a051edc6d4ceb0daad2d0a8433e7b0bAndreas Huber 21e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber#include <binder/ProcessState.h> 22840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber#include <cutils/properties.h> // for property_get 23e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber 241b86fe063badb5f28c467ade39be0f4008688947Andreas Huber#include <media/IMediaHTTPService.h> 25e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber#include <media/IStreamSource.h> 26e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber#include <media/mediaplayer.h> 27e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber#include <media/stagefright/foundation/ADebug.h> 2814acc736e336cbd6026df781d4f411e908831815Andreas Huber#include <media/stagefright/foundation/AMessage.h> 29b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber#include <media/stagefright/DataSource.h> 30b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber#include <media/stagefright/MPEG2TSWriter.h> 31b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber#include <media/stagefright/MediaExtractor.h> 32b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber#include <media/stagefright/MediaSource.h> 33b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber#include <media/stagefright/MetaData.h> 34e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber 35e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber#include <binder/IServiceManager.h> 36e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber#include <media/IMediaPlayerService.h> 37a6195decfe4f9021bbbd7deb050495c33371366bJeff Brown#include <gui/ISurfaceComposer.h> 38df712ea86e6350f7005a02ab0e1c60c28a343ed0Mathias Agopian#include <gui/SurfaceComposerClient.h> 391a2952aee048ca7b1765e2bc09ebe9aeddaeafa3Mathias Agopian#include <gui/Surface.h> 40e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber 41e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber#include <fcntl.h> 423dca4c7a5622fc6aa03397d749c4b4c1201cc4f3Mathias Agopian#include <ui/DisplayInfo.h> 43e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber 44e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huberusing namespace android; 45e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber 46e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huberstruct MyStreamSource : public BnStreamSource { 47b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber // Object assumes ownership of fd. 48e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber MyStreamSource(int fd); 49e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber 50e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber virtual void setListener(const sp<IStreamListener> &listener); 51e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber virtual void setBuffers(const Vector<sp<IMemory> > &buffers); 52e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber 53e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber virtual void onBufferAvailable(size_t index); 54e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber 55e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huberprotected: 56e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber virtual ~MyStreamSource(); 57e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber 58e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huberprivate: 59e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber int mFd; 60f933441648ef6a71dee783d733aac17b9508b452Andreas Huber off64_t mFileSize; 619a442c1b9a051edc6d4ceb0daad2d0a8433e7b0bAndreas Huber uint64_t mNumPacketsSent; 62e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber 63e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber sp<IStreamListener> mListener; 64e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber Vector<sp<IMemory> > mBuffers; 65e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber 66e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber DISALLOW_EVIL_CONSTRUCTORS(MyStreamSource); 67e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber}; 68e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber 69e2b1028852120bcfded33b8f06f66b780437fe92Andreas HuberMyStreamSource::MyStreamSource(int fd) 70f933441648ef6a71dee783d733aac17b9508b452Andreas Huber : mFd(fd), 71f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mFileSize(0), 729a442c1b9a051edc6d4ceb0daad2d0a8433e7b0bAndreas Huber mNumPacketsSent(0) { 73e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber CHECK_GE(fd, 0); 74f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 75f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mFileSize = lseek64(fd, 0, SEEK_END); 76f933441648ef6a71dee783d733aac17b9508b452Andreas Huber lseek64(fd, 0, SEEK_SET); 77e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber} 78e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber 79e2b1028852120bcfded33b8f06f66b780437fe92Andreas HuberMyStreamSource::~MyStreamSource() { 80b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber close(mFd); 81b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber mFd = -1; 82e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber} 83e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber 84e2b1028852120bcfded33b8f06f66b780437fe92Andreas Hubervoid MyStreamSource::setListener(const sp<IStreamListener> &listener) { 85e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber mListener = listener; 86e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber} 87e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber 88e2b1028852120bcfded33b8f06f66b780437fe92Andreas Hubervoid MyStreamSource::setBuffers(const Vector<sp<IMemory> > &buffers) { 89e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber mBuffers = buffers; 90e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber} 91e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber 92e2b1028852120bcfded33b8f06f66b780437fe92Andreas Hubervoid MyStreamSource::onBufferAvailable(size_t index) { 93e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber CHECK_LT(index, mBuffers.size()); 94f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 959a442c1b9a051edc6d4ceb0daad2d0a8433e7b0bAndreas Huber#if 0 969a442c1b9a051edc6d4ceb0daad2d0a8433e7b0bAndreas Huber if (mNumPacketsSent >= 20000) { 97df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block ALOGI("signalling discontinuity now"); 989a442c1b9a051edc6d4ceb0daad2d0a8433e7b0bAndreas Huber 999a442c1b9a051edc6d4ceb0daad2d0a8433e7b0bAndreas Huber off64_t offset = 0; 1009a442c1b9a051edc6d4ceb0daad2d0a8433e7b0bAndreas Huber CHECK((offset % 188) == 0); 101f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 102f933441648ef6a71dee783d733aac17b9508b452Andreas Huber lseek(mFd, offset, SEEK_SET); 103f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1049a442c1b9a051edc6d4ceb0daad2d0a8433e7b0bAndreas Huber sp<AMessage> extra = new AMessage; 1059a442c1b9a051edc6d4ceb0daad2d0a8433e7b0bAndreas Huber extra->setInt32(IStreamListener::kKeyFormatChange, 0); 1069a442c1b9a051edc6d4ceb0daad2d0a8433e7b0bAndreas Huber 107f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mListener->issueCommand( 1089a442c1b9a051edc6d4ceb0daad2d0a8433e7b0bAndreas Huber IStreamListener::DISCONTINUITY, false /* synchronous */, extra); 109f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1109a442c1b9a051edc6d4ceb0daad2d0a8433e7b0bAndreas Huber mNumPacketsSent = 0; 111f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 1129a442c1b9a051edc6d4ceb0daad2d0a8433e7b0bAndreas Huber#endif 113f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 114e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber sp<IMemory> mem = mBuffers.itemAt(index); 115e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber 116e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber ssize_t n = read(mFd, mem->pointer(), mem->size()); 117e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber if (n <= 0) { 11814acc736e336cbd6026df781d4f411e908831815Andreas Huber mListener->issueCommand(IStreamListener::EOS, false /* synchronous */); 119e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber } else { 120e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber mListener->queueBuffer(index, n); 1219a442c1b9a051edc6d4ceb0daad2d0a8433e7b0bAndreas Huber 1229a442c1b9a051edc6d4ceb0daad2d0a8433e7b0bAndreas Huber mNumPacketsSent += n / 188; 123e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber } 124e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber} 125b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber//////////////////////////////////////////////////////////////////////////////// 126b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber 127b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huberstruct MyConvertingStreamSource : public BnStreamSource { 128b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber MyConvertingStreamSource(const char *filename); 129b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber 130b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber virtual void setListener(const sp<IStreamListener> &listener); 131b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber virtual void setBuffers(const Vector<sp<IMemory> > &buffers); 132b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber 133b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber virtual void onBufferAvailable(size_t index); 134b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber 135b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huberprotected: 136b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber virtual ~MyConvertingStreamSource(); 137b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber 138b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huberprivate: 139b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber Mutex mLock; 140b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber Condition mCondition; 141b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber 142b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber sp<IStreamListener> mListener; 143b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber Vector<sp<IMemory> > mBuffers; 144b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber 145b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber sp<MPEG2TSWriter> mWriter; 146b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber 147b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber ssize_t mCurrentBufferIndex; 148b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber size_t mCurrentBufferOffset; 149b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber 150b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber List<size_t> mBufferQueue; 151b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber 152b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber static ssize_t WriteDataWrapper(void *me, const void *data, size_t size); 153b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber ssize_t writeData(const void *data, size_t size); 154b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber 155b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber DISALLOW_EVIL_CONSTRUCTORS(MyConvertingStreamSource); 156b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber}; 157b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber 158b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber//////////////////////////////////////////////////////////////////////////////// 159b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber 160b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas HuberMyConvertingStreamSource::MyConvertingStreamSource(const char *filename) 161b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber : mCurrentBufferIndex(-1), 162b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber mCurrentBufferOffset(0) { 1631b86fe063badb5f28c467ade39be0f4008688947Andreas Huber sp<DataSource> dataSource = 1641b86fe063badb5f28c467ade39be0f4008688947Andreas Huber DataSource::CreateFromURI(NULL /* httpService */, filename); 1651b86fe063badb5f28c467ade39be0f4008688947Andreas Huber 166b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber CHECK(dataSource != NULL); 167b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber 168b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber sp<MediaExtractor> extractor = MediaExtractor::Create(dataSource); 169b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber CHECK(extractor != NULL); 170b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber 171b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber mWriter = new MPEG2TSWriter( 172b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber this, &MyConvertingStreamSource::WriteDataWrapper); 173b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber 174b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber for (size_t i = 0; i < extractor->countTracks(); ++i) { 175b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber const sp<MetaData> &meta = extractor->getTrackMetaData(i); 176b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber 177b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber const char *mime; 178b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber CHECK(meta->findCString(kKeyMIMEType, &mime)); 179b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber 180b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber if (strncasecmp("video/", mime, 6) && strncasecmp("audio/", mime, 6)) { 181b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber continue; 182b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber } 183b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber 184b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber CHECK_EQ(mWriter->addSource(extractor->getTrack(i)), (status_t)OK); 185b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber } 186b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber 187b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber CHECK_EQ(mWriter->start(), (status_t)OK); 188b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber} 189b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber 190b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas HuberMyConvertingStreamSource::~MyConvertingStreamSource() { 191b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber} 192b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber 193b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Hubervoid MyConvertingStreamSource::setListener( 194b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber const sp<IStreamListener> &listener) { 195b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber mListener = listener; 196b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber} 197b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber 198b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Hubervoid MyConvertingStreamSource::setBuffers( 199b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber const Vector<sp<IMemory> > &buffers) { 200b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber mBuffers = buffers; 201b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber} 202b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber 203b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huberssize_t MyConvertingStreamSource::WriteDataWrapper( 204b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber void *me, const void *data, size_t size) { 205b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber return static_cast<MyConvertingStreamSource *>(me)->writeData(data, size); 206b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber} 207b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber 208b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huberssize_t MyConvertingStreamSource::writeData(const void *data, size_t size) { 209b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber size_t totalWritten = 0; 210b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber 211b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber while (size > 0) { 212b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber Mutex::Autolock autoLock(mLock); 213b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber 214b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber if (mCurrentBufferIndex < 0) { 215b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber while (mBufferQueue.empty()) { 216b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber mCondition.wait(mLock); 217b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber } 218b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber 219b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber mCurrentBufferIndex = *mBufferQueue.begin(); 220b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber mCurrentBufferOffset = 0; 221b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber 222b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber mBufferQueue.erase(mBufferQueue.begin()); 223b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber } 224b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber 225b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber sp<IMemory> mem = mBuffers.itemAt(mCurrentBufferIndex); 226b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber 227b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber size_t copy = size; 228b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber if (copy + mCurrentBufferOffset > mem->size()) { 229b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber copy = mem->size() - mCurrentBufferOffset; 230b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber } 231b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber 232b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber memcpy((uint8_t *)mem->pointer() + mCurrentBufferOffset, data, copy); 233b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber mCurrentBufferOffset += copy; 234b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber 235b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber if (mCurrentBufferOffset == mem->size()) { 236b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber mListener->queueBuffer(mCurrentBufferIndex, mCurrentBufferOffset); 237b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber mCurrentBufferIndex = -1; 238b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber } 239b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber 240b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber data = (const uint8_t *)data + copy; 241b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber size -= copy; 242b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber 243b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber totalWritten += copy; 244b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber } 245b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber 246b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber return (ssize_t)totalWritten; 247b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber} 248b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber 249b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Hubervoid MyConvertingStreamSource::onBufferAvailable(size_t index) { 250b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber Mutex::Autolock autoLock(mLock); 251b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber 252b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber mBufferQueue.push_back(index); 253b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber mCondition.signal(); 254b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber 255b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber if (mWriter->reachedEOS()) { 256b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber if (mCurrentBufferIndex >= 0) { 257b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber mListener->queueBuffer(mCurrentBufferIndex, mCurrentBufferOffset); 258b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber mCurrentBufferIndex = -1; 259b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber } 260b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber 261b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber mListener->issueCommand(IStreamListener::EOS, false /* synchronous */); 262b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber } 263b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber} 264e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber 265e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber//////////////////////////////////////////////////////////////////////////////// 266e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber 267e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huberstruct MyClient : public BnMediaPlayerClient { 268e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber MyClient() 269e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber : mEOS(false) { 270e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber } 271e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber 27231de88566257d5546cf4eee9064d96926a4b0c24Lajos Molnar virtual void notify(int msg, int ext1 __unused, int ext2 __unused, const Parcel *obj __unused) { 273e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber Mutex::Autolock autoLock(mLock); 274e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber 275e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber if (msg == MEDIA_ERROR || msg == MEDIA_PLAYBACK_COMPLETE) { 276e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber mEOS = true; 277e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber mCondition.signal(); 278e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber } 279e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber } 280e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber 281e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber void waitForEOS() { 282e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber Mutex::Autolock autoLock(mLock); 283e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber while (!mEOS) { 284e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber mCondition.wait(mLock); 285e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber } 286e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber } 287e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber 288e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huberprotected: 289e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber virtual ~MyClient() { 290e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber } 291e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber 292e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huberprivate: 293e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber Mutex mLock; 294e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber Condition mCondition; 295e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber 296e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber bool mEOS; 297e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber 298e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber DISALLOW_EVIL_CONSTRUCTORS(MyClient); 299e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber}; 300e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber 301e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huberint main(int argc, char **argv) { 302e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber android::ProcessState::self()->startThreadPool(); 303e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber 304b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber DataSource::RegisterDefaultSniffers(); 305b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber 306e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber if (argc != 2) { 307e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber fprintf(stderr, "Usage: %s filename\n", argv[0]); 308e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber return 1; 309e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber } 310e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber 311e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber sp<SurfaceComposerClient> composerClient = new SurfaceComposerClient; 312e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber CHECK_EQ(composerClient->initCheck(), (status_t)OK); 313e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber 314a6195decfe4f9021bbbd7deb050495c33371366bJeff Brown sp<IBinder> display(SurfaceComposerClient::getBuiltInDisplay( 315a6195decfe4f9021bbbd7deb050495c33371366bJeff Brown ISurfaceComposer::eDisplayIdMain)); 3163dca4c7a5622fc6aa03397d749c4b4c1201cc4f3Mathias Agopian DisplayInfo info; 317a6195decfe4f9021bbbd7deb050495c33371366bJeff Brown SurfaceComposerClient::getDisplayInfo(display, &info); 3183dca4c7a5622fc6aa03397d749c4b4c1201cc4f3Mathias Agopian ssize_t displayWidth = info.w; 3193dca4c7a5622fc6aa03397d749c4b4c1201cc4f3Mathias Agopian ssize_t displayHeight = info.h; 3209a442c1b9a051edc6d4ceb0daad2d0a8433e7b0bAndreas Huber 32131de88566257d5546cf4eee9064d96926a4b0c24Lajos Molnar ALOGV("display is %zd x %zd\n", displayWidth, displayHeight); 3229a442c1b9a051edc6d4ceb0daad2d0a8433e7b0bAndreas Huber 323e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber sp<SurfaceControl> control = 324e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber composerClient->createSurface( 325e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber String8("A Surface"), 3269a442c1b9a051edc6d4ceb0daad2d0a8433e7b0bAndreas Huber displayWidth, 3279a442c1b9a051edc6d4ceb0daad2d0a8433e7b0bAndreas Huber displayHeight, 328e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber PIXEL_FORMAT_RGB_565, 329e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber 0); 330e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber 331e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber CHECK(control != NULL); 332e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber CHECK(control->isValid()); 333e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber 3342df788fb0c402938f827bf9c9ce2ca3ab1dcd464Mathias Agopian SurfaceComposerClient::openGlobalTransaction(); 33593d5ab693626fa2700375e838e4bb90e4d50e605Andreas Huber CHECK_EQ(control->setLayer(INT_MAX), (status_t)OK); 336e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber CHECK_EQ(control->show(), (status_t)OK); 3372df788fb0c402938f827bf9c9ce2ca3ab1dcd464Mathias Agopian SurfaceComposerClient::closeGlobalTransaction(); 338e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber 339e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber sp<Surface> surface = control->getSurface(); 340e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber CHECK(surface != NULL); 341e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber 342e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber sp<IServiceManager> sm = defaultServiceManager(); 343e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber sp<IBinder> binder = sm->getService(String16("media.player")); 344e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber sp<IMediaPlayerService> service = interface_cast<IMediaPlayerService>(binder); 345e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber 346e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber CHECK(service.get() != NULL); 347e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber 348b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber sp<MyClient> client = new MyClient; 349b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber 350b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber sp<IStreamSource> source; 351e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber 352840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber char prop[PROPERTY_VALUE_MAX]; 353840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber bool usemp4 = property_get("media.stagefright.use-mp4source", prop, NULL) && 354840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber (!strcmp(prop, "1") || !strcasecmp(prop, "true")); 355840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber 356b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber size_t len = strlen(argv[1]); 357840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber if ((!usemp4 && len >= 3 && !strcasecmp(".ts", &argv[1][len - 3])) || 358b9787142c5f5f8f47e7e35409f4f2ef7112ab72eAndreas Huber (usemp4 && len >= 4 && 359b9787142c5f5f8f47e7e35409f4f2ef7112ab72eAndreas Huber (!strcasecmp(".mp4", &argv[1][len - 4]) 360b9787142c5f5f8f47e7e35409f4f2ef7112ab72eAndreas Huber || !strcasecmp(".3gp", &argv[1][len- 4]) 361b9787142c5f5f8f47e7e35409f4f2ef7112ab72eAndreas Huber || !strcasecmp(".3g2", &argv[1][len- 4])))) { 362b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber int fd = open(argv[1], O_RDONLY); 363e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber 364b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber if (fd < 0) { 365b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber fprintf(stderr, "Failed to open file '%s'.", argv[1]); 366b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber return 1; 367b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber } 368b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber 369b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber source = new MyStreamSource(fd); 370b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber } else { 371b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber printf("Converting file to transport stream for streaming...\n"); 372b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber 373b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber source = new MyConvertingStreamSource(argv[1]); 374b26a1176517579bd4d23f2a2cc91eca2e59b245cAndreas Huber } 375e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber 376e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber sp<IMediaPlayer> player = 37766e4635cb09fadcaccf912f37c387396c428378aGlenn Kasten service->create(client, AUDIO_SESSION_ALLOCATE); 378e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber 379d681bbb1767bed09415e050ba78975df214bcd68Dave Burke if (player != NULL && player->setDataSource(source) == NO_ERROR) { 3809e1cdea45d40fa8cf95dd080943053856009054fMathias Agopian player->setVideoSurfaceTexture(surface->getIGraphicBufferProducer()); 381e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber player->start(); 382e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber 383e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber client->waitForEOS(); 384e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber 385e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber player->stop(); 386e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber } else { 387e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber fprintf(stderr, "failed to instantiate player.\n"); 388e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber } 389e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber 390e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber composerClient->dispose(); 391e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber 392e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber return 0; 393e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber} 394