stream.cpp revision 3dca4c7a5622fc6aa03397d749c4b4c1201cc4f3
15778822d86b0337407514b9372562b86edfa91cdAndreas Huber/* 25778822d86b0337407514b9372562b86edfa91cdAndreas Huber * Copyright (C) 2010 The Android Open Source Project 35778822d86b0337407514b9372562b86edfa91cdAndreas Huber * 45778822d86b0337407514b9372562b86edfa91cdAndreas Huber * Licensed under the Apache License, Version 2.0 (the "License"); 55778822d86b0337407514b9372562b86edfa91cdAndreas Huber * you may not use this file except in compliance with the License. 65778822d86b0337407514b9372562b86edfa91cdAndreas Huber * You may obtain a copy of the License at 75778822d86b0337407514b9372562b86edfa91cdAndreas Huber * 85778822d86b0337407514b9372562b86edfa91cdAndreas Huber * http://www.apache.org/licenses/LICENSE-2.0 95778822d86b0337407514b9372562b86edfa91cdAndreas Huber * 105778822d86b0337407514b9372562b86edfa91cdAndreas Huber * Unless required by applicable law or agreed to in writing, software 115778822d86b0337407514b9372562b86edfa91cdAndreas Huber * distributed under the License is distributed on an "AS IS" BASIS, 125778822d86b0337407514b9372562b86edfa91cdAndreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 135778822d86b0337407514b9372562b86edfa91cdAndreas Huber * See the License for the specific language governing permissions and 145778822d86b0337407514b9372562b86edfa91cdAndreas Huber * limitations under the License. 155778822d86b0337407514b9372562b86edfa91cdAndreas Huber */ 165778822d86b0337407514b9372562b86edfa91cdAndreas Huber 175778822d86b0337407514b9372562b86edfa91cdAndreas Huber//#define LOG_NDEBUG 0 185778822d86b0337407514b9372562b86edfa91cdAndreas Huber#define LOG_TAG "stream" 19377b2ec9a2885f9b6405b07ba900a9e3f4349c38Kévin PETIT#include "utils/Log.h" 205778822d86b0337407514b9372562b86edfa91cdAndreas Huber 215778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include <binder/ProcessState.h> 225778822d86b0337407514b9372562b86edfa91cdAndreas Huber 235778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include <media/IStreamSource.h> 241bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber#include <media/mediaplayer.h> 255778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include <media/stagefright/foundation/ADebug.h> 261bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber#include <media/stagefright/foundation/AMessage.h> 271b86fe063badb5f28c467ade39be0f4008688947Andreas Huber#include <media/stagefright/DataSource.h> 281bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber#include <media/stagefright/MPEG2TSWriter.h> 295778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include <media/stagefright/MediaExtractor.h> 305778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include <media/stagefright/MediaSource.h> 315778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include <media/stagefright/MetaData.h> 325778822d86b0337407514b9372562b86edfa91cdAndreas Huber 335b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber#include <binder/IServiceManager.h> 345778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include <media/IMediaPlayerService.h> 355778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include <gui/SurfaceComposerClient.h> 36ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber 375778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include <fcntl.h> 385778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include <ui/DisplayInfo.h> 39a6195decfe4f9021bbbd7deb050495c33371366bJeff Brown 40df712ea86e6350f7005a02ab0e1c60c28a343ed0Mathias Agopianusing namespace android; 411a2952aee048ca7b1765e2bc09ebe9aeddaeafa3Mathias Agopian 423dca4c7a5622fc6aa03397d749c4b4c1201cc4f3Mathias Agopianstruct MyStreamSource : public BnStreamSource { 435778822d86b0337407514b9372562b86edfa91cdAndreas Huber // Object assumes ownership of fd. 445778822d86b0337407514b9372562b86edfa91cdAndreas Huber MyStreamSource(int fd); 455778822d86b0337407514b9372562b86edfa91cdAndreas Huber 465778822d86b0337407514b9372562b86edfa91cdAndreas Huber virtual void setListener(const sp<IStreamListener> &listener); 47bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber virtual void setBuffers(const Vector<sp<IMemory> > &buffers); 48f69e53033f23f9f70fcdb28a3c2e650de0147459Andreas Huber 49ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber virtual void onBufferAvailable(size_t index); 505778822d86b0337407514b9372562b86edfa91cdAndreas Huber 515778822d86b0337407514b9372562b86edfa91cdAndreas Huberprotected: 525778822d86b0337407514b9372562b86edfa91cdAndreas Huber virtual ~MyStreamSource(); 535778822d86b0337407514b9372562b86edfa91cdAndreas Huber 545778822d86b0337407514b9372562b86edfa91cdAndreas Huberprivate: 555778822d86b0337407514b9372562b86edfa91cdAndreas Huber int mFd; 565778822d86b0337407514b9372562b86edfa91cdAndreas Huber off64_t mFileSize; 575778822d86b0337407514b9372562b86edfa91cdAndreas Huber uint64_t mNumPacketsSent; 585778822d86b0337407514b9372562b86edfa91cdAndreas Huber 595778822d86b0337407514b9372562b86edfa91cdAndreas Huber sp<IStreamListener> mListener; 605aaeb0d64fc98f9b019a4378eb39f0ee49ee6ec4Andreas Huber Vector<sp<IMemory> > mBuffers; 615778822d86b0337407514b9372562b86edfa91cdAndreas Huber 62bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber DISALLOW_EVIL_CONSTRUCTORS(MyStreamSource); 63bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber}; 64bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber 655778822d86b0337407514b9372562b86edfa91cdAndreas HuberMyStreamSource::MyStreamSource(int fd) 665778822d86b0337407514b9372562b86edfa91cdAndreas Huber : mFd(fd), 675778822d86b0337407514b9372562b86edfa91cdAndreas Huber mFileSize(0), 685778822d86b0337407514b9372562b86edfa91cdAndreas Huber mNumPacketsSent(0) { 695778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK_GE(fd, 0); 705778822d86b0337407514b9372562b86edfa91cdAndreas Huber 715778822d86b0337407514b9372562b86edfa91cdAndreas Huber mFileSize = lseek64(fd, 0, SEEK_END); 725778822d86b0337407514b9372562b86edfa91cdAndreas Huber lseek64(fd, 0, SEEK_SET); 73bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber} 74f69e53033f23f9f70fcdb28a3c2e650de0147459Andreas Huber 755778822d86b0337407514b9372562b86edfa91cdAndreas HuberMyStreamSource::~MyStreamSource() { 765778822d86b0337407514b9372562b86edfa91cdAndreas Huber close(mFd); 77bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber mFd = -1; 78bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber} 795778822d86b0337407514b9372562b86edfa91cdAndreas Huber 801b86fe063badb5f28c467ade39be0f4008688947Andreas Hubervoid MyStreamSource::setListener(const sp<IStreamListener> &listener) { 815778822d86b0337407514b9372562b86edfa91cdAndreas Huber mListener = listener; 825778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 835778822d86b0337407514b9372562b86edfa91cdAndreas Huber 845778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid MyStreamSource::setBuffers(const Vector<sp<IMemory> > &buffers) { 855778822d86b0337407514b9372562b86edfa91cdAndreas Huber mBuffers = buffers; 865778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 875778822d86b0337407514b9372562b86edfa91cdAndreas Huber 885778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid MyStreamSource::onBufferAvailable(size_t index) { 895778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK_LT(index, mBuffers.size()); 905778822d86b0337407514b9372562b86edfa91cdAndreas Huber 915778822d86b0337407514b9372562b86edfa91cdAndreas Huber#if 0 925778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (mNumPacketsSent >= 20000) { 935778822d86b0337407514b9372562b86edfa91cdAndreas Huber ALOGI("signalling discontinuity now"); 945778822d86b0337407514b9372562b86edfa91cdAndreas Huber 955778822d86b0337407514b9372562b86edfa91cdAndreas Huber off64_t offset = 0; 965778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK((offset % 188) == 0); 97bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber 98bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber lseek(mFd, offset, SEEK_SET); 99bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber 100bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber sp<AMessage> extra = new AMessage; 1015778822d86b0337407514b9372562b86edfa91cdAndreas Huber extra->setInt32(IStreamListener::kKeyFormatChange, 0); 102bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber 1035778822d86b0337407514b9372562b86edfa91cdAndreas Huber mListener->issueCommand( 1045778822d86b0337407514b9372562b86edfa91cdAndreas Huber IStreamListener::DISCONTINUITY, false /* synchronous */, extra); 1055778822d86b0337407514b9372562b86edfa91cdAndreas Huber 1065778822d86b0337407514b9372562b86edfa91cdAndreas Huber mNumPacketsSent = 0; 1075778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 1085778822d86b0337407514b9372562b86edfa91cdAndreas Huber#endif 1095778822d86b0337407514b9372562b86edfa91cdAndreas Huber 1105778822d86b0337407514b9372562b86edfa91cdAndreas Huber sp<IMemory> mem = mBuffers.itemAt(index); 1115778822d86b0337407514b9372562b86edfa91cdAndreas Huber 1125778822d86b0337407514b9372562b86edfa91cdAndreas Huber ssize_t n = read(mFd, mem->pointer(), mem->size()); 1135778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (n <= 0) { 1145778822d86b0337407514b9372562b86edfa91cdAndreas Huber mListener->issueCommand(IStreamListener::EOS, false /* synchronous */); 1155778822d86b0337407514b9372562b86edfa91cdAndreas Huber } else { 116bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber mListener->queueBuffer(index, n); 117bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber 118bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber mNumPacketsSent += n / 188; 119bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber } 120f69e53033f23f9f70fcdb28a3c2e650de0147459Andreas Huber} 121f69e53033f23f9f70fcdb28a3c2e650de0147459Andreas Huber//////////////////////////////////////////////////////////////////////////////// 1225778822d86b0337407514b9372562b86edfa91cdAndreas Huber 1235778822d86b0337407514b9372562b86edfa91cdAndreas Huberstruct MyConvertingStreamSource : public BnStreamSource { 1245778822d86b0337407514b9372562b86edfa91cdAndreas Huber MyConvertingStreamSource(const char *filename); 1255778822d86b0337407514b9372562b86edfa91cdAndreas Huber 126ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber virtual void setListener(const sp<IStreamListener> &listener); 127f69e53033f23f9f70fcdb28a3c2e650de0147459Andreas Huber virtual void setBuffers(const Vector<sp<IMemory> > &buffers); 1281bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber 1295778822d86b0337407514b9372562b86edfa91cdAndreas Huber virtual void onBufferAvailable(size_t index); 1305778822d86b0337407514b9372562b86edfa91cdAndreas Huber 1315778822d86b0337407514b9372562b86edfa91cdAndreas Huberprotected: 1325aaeb0d64fc98f9b019a4378eb39f0ee49ee6ec4Andreas Huber virtual ~MyConvertingStreamSource(); 1335778822d86b0337407514b9372562b86edfa91cdAndreas Huber 1345778822d86b0337407514b9372562b86edfa91cdAndreas Huberprivate: 1355778822d86b0337407514b9372562b86edfa91cdAndreas Huber Mutex mLock; 1365778822d86b0337407514b9372562b86edfa91cdAndreas Huber Condition mCondition; 1375778822d86b0337407514b9372562b86edfa91cdAndreas Huber 138bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber sp<IStreamListener> mListener; 139bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber Vector<sp<IMemory> > mBuffers; 1405778822d86b0337407514b9372562b86edfa91cdAndreas Huber 1415778822d86b0337407514b9372562b86edfa91cdAndreas Huber sp<MPEG2TSWriter> mWriter; 1425778822d86b0337407514b9372562b86edfa91cdAndreas Huber 1435778822d86b0337407514b9372562b86edfa91cdAndreas Huber ssize_t mCurrentBufferIndex; 1445778822d86b0337407514b9372562b86edfa91cdAndreas Huber size_t mCurrentBufferOffset; 1455778822d86b0337407514b9372562b86edfa91cdAndreas Huber 1465778822d86b0337407514b9372562b86edfa91cdAndreas Huber List<size_t> mBufferQueue; 1475778822d86b0337407514b9372562b86edfa91cdAndreas Huber 1485778822d86b0337407514b9372562b86edfa91cdAndreas Huber static ssize_t WriteDataWrapper(void *me, const void *data, size_t size); 1495778822d86b0337407514b9372562b86edfa91cdAndreas Huber ssize_t writeData(const void *data, size_t size); 1505778822d86b0337407514b9372562b86edfa91cdAndreas Huber 1515778822d86b0337407514b9372562b86edfa91cdAndreas Huber DISALLOW_EVIL_CONSTRUCTORS(MyConvertingStreamSource); 1525778822d86b0337407514b9372562b86edfa91cdAndreas Huber}; 1535778822d86b0337407514b9372562b86edfa91cdAndreas Huber 1545778822d86b0337407514b9372562b86edfa91cdAndreas Huber//////////////////////////////////////////////////////////////////////////////// 1555778822d86b0337407514b9372562b86edfa91cdAndreas Huber 1565778822d86b0337407514b9372562b86edfa91cdAndreas HuberMyConvertingStreamSource::MyConvertingStreamSource(const char *filename) 1575778822d86b0337407514b9372562b86edfa91cdAndreas Huber : mCurrentBufferIndex(-1), 1585778822d86b0337407514b9372562b86edfa91cdAndreas Huber mCurrentBufferOffset(0) { 1595778822d86b0337407514b9372562b86edfa91cdAndreas Huber sp<DataSource> dataSource = DataSource::CreateFromURI(filename); 1605778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(dataSource != NULL); 1615778822d86b0337407514b9372562b86edfa91cdAndreas Huber 1625aaeb0d64fc98f9b019a4378eb39f0ee49ee6ec4Andreas Huber sp<MediaExtractor> extractor = MediaExtractor::Create(dataSource); 1635778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(extractor != NULL); 1645778822d86b0337407514b9372562b86edfa91cdAndreas Huber 1655778822d86b0337407514b9372562b86edfa91cdAndreas Huber mWriter = new MPEG2TSWriter( 1665778822d86b0337407514b9372562b86edfa91cdAndreas Huber this, &MyConvertingStreamSource::WriteDataWrapper); 1675778822d86b0337407514b9372562b86edfa91cdAndreas Huber 168bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber for (size_t i = 0; i < extractor->countTracks(); ++i) { 1695778822d86b0337407514b9372562b86edfa91cdAndreas Huber const sp<MetaData> &meta = extractor->getTrackMetaData(i); 1705778822d86b0337407514b9372562b86edfa91cdAndreas Huber 1715778822d86b0337407514b9372562b86edfa91cdAndreas Huber const char *mime; 1725778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(meta->findCString(kKeyMIMEType, &mime)); 1735778822d86b0337407514b9372562b86edfa91cdAndreas Huber 1745778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (strncasecmp("video/", mime, 6) && strncasecmp("audio/", mime, 6)) { 1755778822d86b0337407514b9372562b86edfa91cdAndreas Huber continue; 1765778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 1775778822d86b0337407514b9372562b86edfa91cdAndreas Huber 1785778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK_EQ(mWriter->addSource(extractor->getTrack(i)), (status_t)OK); 1795778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 1805778822d86b0337407514b9372562b86edfa91cdAndreas Huber 1815778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK_EQ(mWriter->start(), (status_t)OK); 182ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber} 183ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber 184f69e53033f23f9f70fcdb28a3c2e650de0147459Andreas HuberMyConvertingStreamSource::~MyConvertingStreamSource() { 185f69e53033f23f9f70fcdb28a3c2e650de0147459Andreas Huber} 186f69e53033f23f9f70fcdb28a3c2e650de0147459Andreas Huber 187f69e53033f23f9f70fcdb28a3c2e650de0147459Andreas Hubervoid MyConvertingStreamSource::setListener( 188f69e53033f23f9f70fcdb28a3c2e650de0147459Andreas Huber const sp<IStreamListener> &listener) { 189f69e53033f23f9f70fcdb28a3c2e650de0147459Andreas Huber mListener = listener; 1905778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 1915778822d86b0337407514b9372562b86edfa91cdAndreas Huber 1925778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid MyConvertingStreamSource::setBuffers( 1935778822d86b0337407514b9372562b86edfa91cdAndreas Huber const Vector<sp<IMemory> > &buffers) { 1945778822d86b0337407514b9372562b86edfa91cdAndreas Huber mBuffers = buffers; 1955778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 1965778822d86b0337407514b9372562b86edfa91cdAndreas Huber 1975778822d86b0337407514b9372562b86edfa91cdAndreas Huberssize_t MyConvertingStreamSource::WriteDataWrapper( 1985aaeb0d64fc98f9b019a4378eb39f0ee49ee6ec4Andreas Huber void *me, const void *data, size_t size) { 1995aaeb0d64fc98f9b019a4378eb39f0ee49ee6ec4Andreas Huber return static_cast<MyConvertingStreamSource *>(me)->writeData(data, size); 2005aaeb0d64fc98f9b019a4378eb39f0ee49ee6ec4Andreas Huber} 2015aaeb0d64fc98f9b019a4378eb39f0ee49ee6ec4Andreas Huber 2025aaeb0d64fc98f9b019a4378eb39f0ee49ee6ec4Andreas Huberssize_t MyConvertingStreamSource::writeData(const void *data, size_t size) { 2035aaeb0d64fc98f9b019a4378eb39f0ee49ee6ec4Andreas Huber size_t totalWritten = 0; 2045aaeb0d64fc98f9b019a4378eb39f0ee49ee6ec4Andreas Huber 2055aaeb0d64fc98f9b019a4378eb39f0ee49ee6ec4Andreas Huber while (size > 0) { 2065aaeb0d64fc98f9b019a4378eb39f0ee49ee6ec4Andreas Huber Mutex::Autolock autoLock(mLock); 2075aaeb0d64fc98f9b019a4378eb39f0ee49ee6ec4Andreas Huber 2085aaeb0d64fc98f9b019a4378eb39f0ee49ee6ec4Andreas Huber if (mCurrentBufferIndex < 0) { 2095aaeb0d64fc98f9b019a4378eb39f0ee49ee6ec4Andreas Huber while (mBufferQueue.empty()) { 2105aaeb0d64fc98f9b019a4378eb39f0ee49ee6ec4Andreas Huber mCondition.wait(mLock); 2115aaeb0d64fc98f9b019a4378eb39f0ee49ee6ec4Andreas Huber } 2125aaeb0d64fc98f9b019a4378eb39f0ee49ee6ec4Andreas Huber 2135aaeb0d64fc98f9b019a4378eb39f0ee49ee6ec4Andreas Huber mCurrentBufferIndex = *mBufferQueue.begin(); 2145aaeb0d64fc98f9b019a4378eb39f0ee49ee6ec4Andreas Huber mCurrentBufferOffset = 0; 2155aaeb0d64fc98f9b019a4378eb39f0ee49ee6ec4Andreas Huber 2165aaeb0d64fc98f9b019a4378eb39f0ee49ee6ec4Andreas Huber mBufferQueue.erase(mBufferQueue.begin()); 2175aaeb0d64fc98f9b019a4378eb39f0ee49ee6ec4Andreas Huber } 2185aaeb0d64fc98f9b019a4378eb39f0ee49ee6ec4Andreas Huber 2195aaeb0d64fc98f9b019a4378eb39f0ee49ee6ec4Andreas Huber sp<IMemory> mem = mBuffers.itemAt(mCurrentBufferIndex); 2205aaeb0d64fc98f9b019a4378eb39f0ee49ee6ec4Andreas Huber 2215aaeb0d64fc98f9b019a4378eb39f0ee49ee6ec4Andreas Huber size_t copy = size; 2225aaeb0d64fc98f9b019a4378eb39f0ee49ee6ec4Andreas Huber if (copy + mCurrentBufferOffset > mem->size()) { 2235aaeb0d64fc98f9b019a4378eb39f0ee49ee6ec4Andreas Huber copy = mem->size() - mCurrentBufferOffset; 2245aaeb0d64fc98f9b019a4378eb39f0ee49ee6ec4Andreas Huber } 2255778822d86b0337407514b9372562b86edfa91cdAndreas Huber 2265778822d86b0337407514b9372562b86edfa91cdAndreas Huber memcpy((uint8_t *)mem->pointer() + mCurrentBufferOffset, data, copy); 2275778822d86b0337407514b9372562b86edfa91cdAndreas Huber mCurrentBufferOffset += copy; 2285778822d86b0337407514b9372562b86edfa91cdAndreas Huber 2295778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (mCurrentBufferOffset == mem->size()) { 2305778822d86b0337407514b9372562b86edfa91cdAndreas Huber mListener->queueBuffer(mCurrentBufferIndex, mCurrentBufferOffset); 2315778822d86b0337407514b9372562b86edfa91cdAndreas Huber mCurrentBufferIndex = -1; 2325778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 2335778822d86b0337407514b9372562b86edfa91cdAndreas Huber 2345778822d86b0337407514b9372562b86edfa91cdAndreas Huber data = (const uint8_t *)data + copy; 2355778822d86b0337407514b9372562b86edfa91cdAndreas Huber size -= copy; 2365778822d86b0337407514b9372562b86edfa91cdAndreas Huber 2375778822d86b0337407514b9372562b86edfa91cdAndreas Huber totalWritten += copy; 2385778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 2395778822d86b0337407514b9372562b86edfa91cdAndreas Huber 2405778822d86b0337407514b9372562b86edfa91cdAndreas Huber return (ssize_t)totalWritten; 2415778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 2425778822d86b0337407514b9372562b86edfa91cdAndreas Huber 2435778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid MyConvertingStreamSource::onBufferAvailable(size_t index) { 2445778822d86b0337407514b9372562b86edfa91cdAndreas Huber Mutex::Autolock autoLock(mLock); 2455778822d86b0337407514b9372562b86edfa91cdAndreas Huber 2465778822d86b0337407514b9372562b86edfa91cdAndreas Huber mBufferQueue.push_back(index); 2475778822d86b0337407514b9372562b86edfa91cdAndreas Huber mCondition.signal(); 2485778822d86b0337407514b9372562b86edfa91cdAndreas Huber 2495778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (mWriter->reachedEOS()) { 2505778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (mCurrentBufferIndex >= 0) { 2515778822d86b0337407514b9372562b86edfa91cdAndreas Huber mListener->queueBuffer(mCurrentBufferIndex, mCurrentBufferOffset); 2525778822d86b0337407514b9372562b86edfa91cdAndreas Huber mCurrentBufferIndex = -1; 2535778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 254bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber 2555778822d86b0337407514b9372562b86edfa91cdAndreas Huber mListener->issueCommand(IStreamListener::EOS, false /* synchronous */); 2565778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 2575778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 2585778822d86b0337407514b9372562b86edfa91cdAndreas Huber 2595778822d86b0337407514b9372562b86edfa91cdAndreas Huber//////////////////////////////////////////////////////////////////////////////// 260bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber 261bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huberstruct MyClient : public BnMediaPlayerClient { 262bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber MyClient() 2635778822d86b0337407514b9372562b86edfa91cdAndreas Huber : mEOS(false) { 2645778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 2655778822d86b0337407514b9372562b86edfa91cdAndreas Huber 2665778822d86b0337407514b9372562b86edfa91cdAndreas Huber virtual void notify(int msg, int ext1, int ext2, const Parcel *obj) { 2675778822d86b0337407514b9372562b86edfa91cdAndreas Huber Mutex::Autolock autoLock(mLock); 2685778822d86b0337407514b9372562b86edfa91cdAndreas Huber 2695778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (msg == MEDIA_ERROR || msg == MEDIA_PLAYBACK_COMPLETE) { 2705778822d86b0337407514b9372562b86edfa91cdAndreas Huber mEOS = true; 2715778822d86b0337407514b9372562b86edfa91cdAndreas Huber mCondition.signal(); 2725778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 2735778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 2745778822d86b0337407514b9372562b86edfa91cdAndreas Huber 2755778822d86b0337407514b9372562b86edfa91cdAndreas Huber void waitForEOS() { 2765778822d86b0337407514b9372562b86edfa91cdAndreas Huber Mutex::Autolock autoLock(mLock); 2775778822d86b0337407514b9372562b86edfa91cdAndreas Huber while (!mEOS) { 2785778822d86b0337407514b9372562b86edfa91cdAndreas Huber mCondition.wait(mLock); 2795778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 2805778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 2815778822d86b0337407514b9372562b86edfa91cdAndreas Huber 2825778822d86b0337407514b9372562b86edfa91cdAndreas Huberprotected: 2835778822d86b0337407514b9372562b86edfa91cdAndreas Huber virtual ~MyClient() { 2845778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 2855778822d86b0337407514b9372562b86edfa91cdAndreas Huber 2865778822d86b0337407514b9372562b86edfa91cdAndreas Huberprivate: 2875778822d86b0337407514b9372562b86edfa91cdAndreas Huber Mutex mLock; 288bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber Condition mCondition; 289bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber 2905778822d86b0337407514b9372562b86edfa91cdAndreas Huber bool mEOS; 2915778822d86b0337407514b9372562b86edfa91cdAndreas Huber 2925778822d86b0337407514b9372562b86edfa91cdAndreas Huber DISALLOW_EVIL_CONSTRUCTORS(MyClient); 293c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}; 294bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber 295bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huberint main(int argc, char **argv) { 296377b2ec9a2885f9b6405b07ba900a9e3f4349c38Kévin PETIT android::ProcessState::self()->startThreadPool(); 297bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber 298bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber DataSource::RegisterDefaultSniffers(); 299bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber 300bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber if (argc != 2) { 301377b2ec9a2885f9b6405b07ba900a9e3f4349c38Kévin PETIT fprintf(stderr, "Usage: %s filename\n", argv[0]); 302377b2ec9a2885f9b6405b07ba900a9e3f4349c38Kévin PETIT return 1; 303bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber } 304bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber 305bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber sp<SurfaceComposerClient> composerClient = new SurfaceComposerClient; 306bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber CHECK_EQ(composerClient->initCheck(), (status_t)OK); 307bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber 308bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber DisplayInfo info; 3095778822d86b0337407514b9372562b86edfa91cdAndreas Huber SurfaceComposerClient::getDisplayInfo(0, &info); 3105778822d86b0337407514b9372562b86edfa91cdAndreas Huber ssize_t displayWidth = info.w; 3115778822d86b0337407514b9372562b86edfa91cdAndreas Huber ssize_t displayHeight = info.h; 3125778822d86b0337407514b9372562b86edfa91cdAndreas Huber 3135778822d86b0337407514b9372562b86edfa91cdAndreas Huber ALOGV("display is %d x %d\n", displayWidth, displayHeight); 3145778822d86b0337407514b9372562b86edfa91cdAndreas Huber 3155778822d86b0337407514b9372562b86edfa91cdAndreas Huber sp<SurfaceControl> control = 3165778822d86b0337407514b9372562b86edfa91cdAndreas Huber composerClient->createSurface( 3175778822d86b0337407514b9372562b86edfa91cdAndreas Huber String8("A Surface"), 3185778822d86b0337407514b9372562b86edfa91cdAndreas Huber 0, 3195778822d86b0337407514b9372562b86edfa91cdAndreas Huber displayWidth, 3205778822d86b0337407514b9372562b86edfa91cdAndreas Huber displayHeight, 3215778822d86b0337407514b9372562b86edfa91cdAndreas Huber PIXEL_FORMAT_RGB_565, 322bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber 0); 3235778822d86b0337407514b9372562b86edfa91cdAndreas Huber 3245778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(control != NULL); 325ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber CHECK(control->isValid()); 3265778822d86b0337407514b9372562b86edfa91cdAndreas Huber 3275778822d86b0337407514b9372562b86edfa91cdAndreas Huber SurfaceComposerClient::openGlobalTransaction(); 3285778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK_EQ(control->setLayer(INT_MAX), (status_t)OK); 3295778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK_EQ(control->show(), (status_t)OK); 3305778822d86b0337407514b9372562b86edfa91cdAndreas Huber SurfaceComposerClient::closeGlobalTransaction(); 3315778822d86b0337407514b9372562b86edfa91cdAndreas Huber 3325778822d86b0337407514b9372562b86edfa91cdAndreas Huber sp<Surface> surface = control->getSurface(); 3335778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(surface != NULL); 3345778822d86b0337407514b9372562b86edfa91cdAndreas Huber 3355778822d86b0337407514b9372562b86edfa91cdAndreas Huber sp<IServiceManager> sm = defaultServiceManager(); 3365778822d86b0337407514b9372562b86edfa91cdAndreas Huber sp<IBinder> binder = sm->getService(String16("media.player")); 3375778822d86b0337407514b9372562b86edfa91cdAndreas Huber sp<IMediaPlayerService> service = interface_cast<IMediaPlayerService>(binder); 3385778822d86b0337407514b9372562b86edfa91cdAndreas Huber 3395778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(service.get() != NULL); 3405778822d86b0337407514b9372562b86edfa91cdAndreas Huber 3415778822d86b0337407514b9372562b86edfa91cdAndreas Huber sp<MyClient> client = new MyClient; 3425778822d86b0337407514b9372562b86edfa91cdAndreas Huber 3435778822d86b0337407514b9372562b86edfa91cdAndreas Huber sp<IStreamSource> source; 3445778822d86b0337407514b9372562b86edfa91cdAndreas Huber 345bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber size_t len = strlen(argv[1]); 346bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber if (len >= 3 && !strcasecmp(".ts", &argv[1][len - 3])) { 347bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber int fd = open(argv[1], O_RDONLY); 348bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber 349bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber if (fd < 0) { 350bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber fprintf(stderr, "Failed to open file '%s'.", argv[1]); 3515778822d86b0337407514b9372562b86edfa91cdAndreas Huber return 1; 3525778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 3535778822d86b0337407514b9372562b86edfa91cdAndreas Huber 3545778822d86b0337407514b9372562b86edfa91cdAndreas Huber source = new MyStreamSource(fd); 3555778822d86b0337407514b9372562b86edfa91cdAndreas Huber } else { 3565778822d86b0337407514b9372562b86edfa91cdAndreas Huber printf("Converting file to transport stream for streaming...\n"); 3575778822d86b0337407514b9372562b86edfa91cdAndreas Huber 3585778822d86b0337407514b9372562b86edfa91cdAndreas Huber source = new MyConvertingStreamSource(argv[1]); 3595778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 3605778822d86b0337407514b9372562b86edfa91cdAndreas Huber 3615778822d86b0337407514b9372562b86edfa91cdAndreas Huber sp<IMediaPlayer> player = 3625778822d86b0337407514b9372562b86edfa91cdAndreas Huber service->create(getpid(), client, 0); 3635778822d86b0337407514b9372562b86edfa91cdAndreas Huber 3645778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (player != NULL && player->setDataSource(source) == NO_ERROR) { 3655778822d86b0337407514b9372562b86edfa91cdAndreas Huber player->setVideoSurfaceTexture(surface->getSurfaceTexture()); 3665778822d86b0337407514b9372562b86edfa91cdAndreas Huber player->start(); 3675778822d86b0337407514b9372562b86edfa91cdAndreas Huber 3685778822d86b0337407514b9372562b86edfa91cdAndreas Huber client->waitForEOS(); 3695778822d86b0337407514b9372562b86edfa91cdAndreas Huber 3705778822d86b0337407514b9372562b86edfa91cdAndreas Huber player->stop(); 3715778822d86b0337407514b9372562b86edfa91cdAndreas Huber } else { 3725778822d86b0337407514b9372562b86edfa91cdAndreas Huber fprintf(stderr, "failed to instantiate player.\n"); 3735778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 3745778822d86b0337407514b9372562b86edfa91cdAndreas Huber 3755778822d86b0337407514b9372562b86edfa91cdAndreas Huber composerClient->dispose(); 3765778822d86b0337407514b9372562b86edfa91cdAndreas Huber 3775778822d86b0337407514b9372562b86edfa91cdAndreas Huber return 0; 378bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber} 379bae6f72d16a1cfc2122b4ce9b484c026ecd896b1Andreas Huber