codec2.cpp revision 52bffe176c343075c196c072aa7924de3abdd1b5
152bffe176c343075c196c072aa7924de3abdd1b5Johny Lin// Copyright 2017 The Chromium Authors. All rights reserved. 252bffe176c343075c196c072aa7924de3abdd1b5Johny Lin// Use of this source code is governed by a BSD-style license that can be 352bffe176c343075c196c072aa7924de3abdd1b5Johny Lin// found in the LICENSE file. 452bffe176c343075c196c072aa7924de3abdd1b5Johny Lin 552bffe176c343075c196c072aa7924de3abdd1b5Johny Lin//#define LOG_NDEBUG 0 652bffe176c343075c196c072aa7924de3abdd1b5Johny Lin#define LOG_TAG "codec2" 752bffe176c343075c196c072aa7924de3abdd1b5Johny Lin 852bffe176c343075c196c072aa7924de3abdd1b5Johny Lin#include <inttypes.h> 952bffe176c343075c196c072aa7924de3abdd1b5Johny Lin#include <fcntl.h> 1052bffe176c343075c196c072aa7924de3abdd1b5Johny Lin#include <stdlib.h> 1152bffe176c343075c196c072aa7924de3abdd1b5Johny Lin#include <string.h> 1252bffe176c343075c196c072aa7924de3abdd1b5Johny Lin#include <sys/time.h> 1352bffe176c343075c196c072aa7924de3abdd1b5Johny Lin#include <sys/types.h> 1452bffe176c343075c196c072aa7924de3abdd1b5Johny Lin#include <sys/stat.h> 1552bffe176c343075c196c072aa7924de3abdd1b5Johny Lin 1652bffe176c343075c196c072aa7924de3abdd1b5Johny Lin#include <thread> 1752bffe176c343075c196c072aa7924de3abdd1b5Johny Lin 1852bffe176c343075c196c072aa7924de3abdd1b5Johny Lin#include "C2VDAComponent.h" 1952bffe176c343075c196c072aa7924de3abdd1b5Johny Lin 2052bffe176c343075c196c072aa7924de3abdd1b5Johny Lin#include <C2AllocatorCrosGralloc.h> 2152bffe176c343075c196c072aa7924de3abdd1b5Johny Lin#include <C2AllocatorMemDealer.h> 2252bffe176c343075c196c072aa7924de3abdd1b5Johny Lin#include <C2Buffer.h> 2352bffe176c343075c196c072aa7924de3abdd1b5Johny Lin#include <C2BufferPriv.h> 2452bffe176c343075c196c072aa7924de3abdd1b5Johny Lin#include <C2Component.h> 2552bffe176c343075c196c072aa7924de3abdd1b5Johny Lin#include <C2VDASupport.h> 2652bffe176c343075c196c072aa7924de3abdd1b5Johny Lin#include <C2Work.h> 2752bffe176c343075c196c072aa7924de3abdd1b5Johny Lin 2852bffe176c343075c196c072aa7924de3abdd1b5Johny Lin#include <binder/IServiceManager.h> 2952bffe176c343075c196c072aa7924de3abdd1b5Johny Lin#include <binder/ProcessState.h> 3052bffe176c343075c196c072aa7924de3abdd1b5Johny Lin#include <media/ICrypto.h> 3152bffe176c343075c196c072aa7924de3abdd1b5Johny Lin#include <media/IMediaHTTPService.h> 3252bffe176c343075c196c072aa7924de3abdd1b5Johny Lin#include <media/stagefright/foundation/ABuffer.h> 3352bffe176c343075c196c072aa7924de3abdd1b5Johny Lin#include <media/stagefright/foundation/ALooper.h> 3452bffe176c343075c196c072aa7924de3abdd1b5Johny Lin#include <media/stagefright/foundation/AMessage.h> 3552bffe176c343075c196c072aa7924de3abdd1b5Johny Lin#include <media/stagefright/foundation/AUtils.h> 3652bffe176c343075c196c072aa7924de3abdd1b5Johny Lin#include <media/stagefright/DataSource.h> 3752bffe176c343075c196c072aa7924de3abdd1b5Johny Lin#include <media/stagefright/MediaDefs.h> 3852bffe176c343075c196c072aa7924de3abdd1b5Johny Lin#include <media/stagefright/MediaErrors.h> 3952bffe176c343075c196c072aa7924de3abdd1b5Johny Lin#include <media/stagefright/MediaExtractor.h> 4052bffe176c343075c196c072aa7924de3abdd1b5Johny Lin#include <media/stagefright/MediaSource.h> 4152bffe176c343075c196c072aa7924de3abdd1b5Johny Lin#include <media/stagefright/MetaData.h> 4252bffe176c343075c196c072aa7924de3abdd1b5Johny Lin#include <media/stagefright/Utils.h> 4352bffe176c343075c196c072aa7924de3abdd1b5Johny Lin 4452bffe176c343075c196c072aa7924de3abdd1b5Johny Lin#include <gui/GLConsumer.h> 4552bffe176c343075c196c072aa7924de3abdd1b5Johny Lin#include <gui/IProducerListener.h> 4652bffe176c343075c196c072aa7924de3abdd1b5Johny Lin#include <gui/Surface.h> 4752bffe176c343075c196c072aa7924de3abdd1b5Johny Lin#include <gui/SurfaceComposerClient.h> 4852bffe176c343075c196c072aa7924de3abdd1b5Johny Lin 4952bffe176c343075c196c072aa7924de3abdd1b5Johny Linusing namespace android; 5052bffe176c343075c196c072aa7924de3abdd1b5Johny Linusing namespace std::chrono_literals; 5152bffe176c343075c196c072aa7924de3abdd1b5Johny Lin 5252bffe176c343075c196c072aa7924de3abdd1b5Johny Linnamespace { 5352bffe176c343075c196c072aa7924de3abdd1b5Johny Lin 5452bffe176c343075c196c072aa7924de3abdd1b5Johny Linconst int kWidth = 416; 5552bffe176c343075c196c072aa7924de3abdd1b5Johny Linconst int kHeight = 240; // BigBuckBunny.mp4 5652bffe176c343075c196c072aa7924de3abdd1b5Johny Lin//const int kWidth = 560; 5752bffe176c343075c196c072aa7924de3abdd1b5Johny Lin//const int kHeight = 320; // small.mp4 5852bffe176c343075c196c072aa7924de3abdd1b5Johny Lin 5952bffe176c343075c196c072aa7924de3abdd1b5Johny Linclass C2VDALinearBuffer : public C2Buffer { 6052bffe176c343075c196c072aa7924de3abdd1b5Johny Linpublic: 6152bffe176c343075c196c072aa7924de3abdd1b5Johny Lin explicit C2VDALinearBuffer(const std::shared_ptr<C2LinearBlock>& block) 6252bffe176c343075c196c072aa7924de3abdd1b5Johny Lin : C2Buffer({ block->share(block->offset(), block->size(), ::android::C2Fence()) }) {} 6352bffe176c343075c196c072aa7924de3abdd1b5Johny Lin}; 6452bffe176c343075c196c072aa7924de3abdd1b5Johny Lin 6552bffe176c343075c196c072aa7924de3abdd1b5Johny Linclass Listener; 6652bffe176c343075c196c072aa7924de3abdd1b5Johny Lin 6752bffe176c343075c196c072aa7924de3abdd1b5Johny Linclass SimplePlayer { 6852bffe176c343075c196c072aa7924de3abdd1b5Johny Linpublic: 6952bffe176c343075c196c072aa7924de3abdd1b5Johny Lin SimplePlayer(); 7052bffe176c343075c196c072aa7924de3abdd1b5Johny Lin ~SimplePlayer(); 7152bffe176c343075c196c072aa7924de3abdd1b5Johny Lin 7252bffe176c343075c196c072aa7924de3abdd1b5Johny Lin void onWorkDone(std::weak_ptr<C2Component> component, 7352bffe176c343075c196c072aa7924de3abdd1b5Johny Lin std::vector<std::unique_ptr<C2Work>> workItems); 7452bffe176c343075c196c072aa7924de3abdd1b5Johny Lin void onTripped(std::weak_ptr<C2Component> component, 7552bffe176c343075c196c072aa7924de3abdd1b5Johny Lin std::vector<std::shared_ptr<C2SettingResult>> settingResult); 7652bffe176c343075c196c072aa7924de3abdd1b5Johny Lin void onError(std::weak_ptr<C2Component> component, uint32_t errorCode); 7752bffe176c343075c196c072aa7924de3abdd1b5Johny Lin 7852bffe176c343075c196c072aa7924de3abdd1b5Johny Lin status_t play(const sp<IMediaSource> &source); 7952bffe176c343075c196c072aa7924de3abdd1b5Johny Lin 8052bffe176c343075c196c072aa7924de3abdd1b5Johny Linprivate: 8152bffe176c343075c196c072aa7924de3abdd1b5Johny Lin typedef std::unique_lock<std::mutex> ULock; 8252bffe176c343075c196c072aa7924de3abdd1b5Johny Lin 8352bffe176c343075c196c072aa7924de3abdd1b5Johny Lin enum { 8452bffe176c343075c196c072aa7924de3abdd1b5Johny Lin kInputBufferCount = 8, 8552bffe176c343075c196c072aa7924de3abdd1b5Johny Lin kDefaultInputBufferSize = 1024 * 1024, 8652bffe176c343075c196c072aa7924de3abdd1b5Johny Lin }; 8752bffe176c343075c196c072aa7924de3abdd1b5Johny Lin 8852bffe176c343075c196c072aa7924de3abdd1b5Johny Lin std::shared_ptr<Listener> mListener; 8952bffe176c343075c196c072aa7924de3abdd1b5Johny Lin 9052bffe176c343075c196c072aa7924de3abdd1b5Johny Lin sp<IProducerListener> mProducerListener; 9152bffe176c343075c196c072aa7924de3abdd1b5Johny Lin 9252bffe176c343075c196c072aa7924de3abdd1b5Johny Lin // Allocators 9352bffe176c343075c196c072aa7924de3abdd1b5Johny Lin std::shared_ptr<C2Allocator> mLinearAlloc; 9452bffe176c343075c196c072aa7924de3abdd1b5Johny Lin std::shared_ptr<C2BlockPool> mLinearBlockPool; 9552bffe176c343075c196c072aa7924de3abdd1b5Johny Lin 9652bffe176c343075c196c072aa7924de3abdd1b5Johny Lin std::mutex mQueueLock; 9752bffe176c343075c196c072aa7924de3abdd1b5Johny Lin std::condition_variable mQueueCondition; 9852bffe176c343075c196c072aa7924de3abdd1b5Johny Lin std::list<std::unique_ptr<C2Work>> mWorkQueue; 9952bffe176c343075c196c072aa7924de3abdd1b5Johny Lin 10052bffe176c343075c196c072aa7924de3abdd1b5Johny Lin std::mutex mProcessedLock; 10152bffe176c343075c196c072aa7924de3abdd1b5Johny Lin std::condition_variable mProcessedCondition; 10252bffe176c343075c196c072aa7924de3abdd1b5Johny Lin std::list<std::unique_ptr<C2Work>> mProcessedWork; 10352bffe176c343075c196c072aa7924de3abdd1b5Johny Lin 10452bffe176c343075c196c072aa7924de3abdd1b5Johny Lin sp<Surface> mSurface; 10552bffe176c343075c196c072aa7924de3abdd1b5Johny Lin sp<SurfaceComposerClient> mComposerClient; 10652bffe176c343075c196c072aa7924de3abdd1b5Johny Lin sp<SurfaceControl> mControl; 10752bffe176c343075c196c072aa7924de3abdd1b5Johny Lin}; 10852bffe176c343075c196c072aa7924de3abdd1b5Johny Lin 10952bffe176c343075c196c072aa7924de3abdd1b5Johny Linclass Listener : public C2Component::Listener { 11052bffe176c343075c196c072aa7924de3abdd1b5Johny Linpublic: 11152bffe176c343075c196c072aa7924de3abdd1b5Johny Lin explicit Listener(SimplePlayer *thiz) : mThis(thiz) {} 11252bffe176c343075c196c072aa7924de3abdd1b5Johny Lin virtual ~Listener() = default; 11352bffe176c343075c196c072aa7924de3abdd1b5Johny Lin 11452bffe176c343075c196c072aa7924de3abdd1b5Johny Lin virtual void onWorkDone_nb(std::weak_ptr<C2Component> component, 11552bffe176c343075c196c072aa7924de3abdd1b5Johny Lin std::vector<std::unique_ptr<C2Work>> workItems) override { 11652bffe176c343075c196c072aa7924de3abdd1b5Johny Lin mThis->onWorkDone(component, std::move(workItems)); 11752bffe176c343075c196c072aa7924de3abdd1b5Johny Lin } 11852bffe176c343075c196c072aa7924de3abdd1b5Johny Lin 11952bffe176c343075c196c072aa7924de3abdd1b5Johny Lin virtual void onTripped_nb( 12052bffe176c343075c196c072aa7924de3abdd1b5Johny Lin std::weak_ptr<C2Component> component, 12152bffe176c343075c196c072aa7924de3abdd1b5Johny Lin std::vector<std::shared_ptr<C2SettingResult>> settingResult) override { 12252bffe176c343075c196c072aa7924de3abdd1b5Johny Lin mThis->onTripped(component, settingResult); 12352bffe176c343075c196c072aa7924de3abdd1b5Johny Lin } 12452bffe176c343075c196c072aa7924de3abdd1b5Johny Lin 12552bffe176c343075c196c072aa7924de3abdd1b5Johny Lin virtual void onError_nb(std::weak_ptr<C2Component> component, 12652bffe176c343075c196c072aa7924de3abdd1b5Johny Lin uint32_t errorCode) override { 12752bffe176c343075c196c072aa7924de3abdd1b5Johny Lin mThis->onError(component, errorCode); 12852bffe176c343075c196c072aa7924de3abdd1b5Johny Lin } 12952bffe176c343075c196c072aa7924de3abdd1b5Johny Lin 13052bffe176c343075c196c072aa7924de3abdd1b5Johny Linprivate: 13152bffe176c343075c196c072aa7924de3abdd1b5Johny Lin SimplePlayer * const mThis; 13252bffe176c343075c196c072aa7924de3abdd1b5Johny Lin}; 13352bffe176c343075c196c072aa7924de3abdd1b5Johny Lin 13452bffe176c343075c196c072aa7924de3abdd1b5Johny LinSimplePlayer::SimplePlayer() 13552bffe176c343075c196c072aa7924de3abdd1b5Johny Lin : mListener(new Listener(this)), 13652bffe176c343075c196c072aa7924de3abdd1b5Johny Lin mProducerListener(new DummyProducerListener), 13752bffe176c343075c196c072aa7924de3abdd1b5Johny Lin mComposerClient(new SurfaceComposerClient) { 13852bffe176c343075c196c072aa7924de3abdd1b5Johny Lin CHECK_EQ(mComposerClient->initCheck(), OK); 13952bffe176c343075c196c072aa7924de3abdd1b5Johny Lin 14052bffe176c343075c196c072aa7924de3abdd1b5Johny Lin std::shared_ptr<C2AllocatorStore> store = getCodec2VDAAllocatorStore(); 14152bffe176c343075c196c072aa7924de3abdd1b5Johny Lin CHECK_EQ(store->fetchAllocator(C2AllocatorStore::DEFAULT_LINEAR, &mLinearAlloc), C2_OK); 14252bffe176c343075c196c072aa7924de3abdd1b5Johny Lin 14352bffe176c343075c196c072aa7924de3abdd1b5Johny Lin mLinearBlockPool = std::make_shared<C2BasicLinearBlockPool>(mLinearAlloc); 14452bffe176c343075c196c072aa7924de3abdd1b5Johny Lin 14552bffe176c343075c196c072aa7924de3abdd1b5Johny Lin mControl = mComposerClient->createSurface(String8("A Surface"), 14652bffe176c343075c196c072aa7924de3abdd1b5Johny Lin kWidth, kHeight, HAL_PIXEL_FORMAT_YV12); 14752bffe176c343075c196c072aa7924de3abdd1b5Johny Lin 14852bffe176c343075c196c072aa7924de3abdd1b5Johny Lin CHECK(mControl != nullptr); 14952bffe176c343075c196c072aa7924de3abdd1b5Johny Lin CHECK(mControl->isValid()); 15052bffe176c343075c196c072aa7924de3abdd1b5Johny Lin 15152bffe176c343075c196c072aa7924de3abdd1b5Johny Lin SurfaceComposerClient::openGlobalTransaction(); 15252bffe176c343075c196c072aa7924de3abdd1b5Johny Lin CHECK_EQ(mControl->setLayer(INT_MAX), OK); 15352bffe176c343075c196c072aa7924de3abdd1b5Johny Lin CHECK_EQ(mControl->show(), OK); 15452bffe176c343075c196c072aa7924de3abdd1b5Johny Lin SurfaceComposerClient::closeGlobalTransaction(); 15552bffe176c343075c196c072aa7924de3abdd1b5Johny Lin 15652bffe176c343075c196c072aa7924de3abdd1b5Johny Lin mSurface = mControl->getSurface(); 15752bffe176c343075c196c072aa7924de3abdd1b5Johny Lin CHECK(mSurface != nullptr); 15852bffe176c343075c196c072aa7924de3abdd1b5Johny Lin mSurface->connect(NATIVE_WINDOW_API_CPU, mProducerListener); 15952bffe176c343075c196c072aa7924de3abdd1b5Johny Lin} 16052bffe176c343075c196c072aa7924de3abdd1b5Johny Lin 16152bffe176c343075c196c072aa7924de3abdd1b5Johny LinSimplePlayer::~SimplePlayer() { 16252bffe176c343075c196c072aa7924de3abdd1b5Johny Lin mComposerClient->dispose(); 16352bffe176c343075c196c072aa7924de3abdd1b5Johny Lin} 16452bffe176c343075c196c072aa7924de3abdd1b5Johny Lin 16552bffe176c343075c196c072aa7924de3abdd1b5Johny Linvoid SimplePlayer::onWorkDone( 16652bffe176c343075c196c072aa7924de3abdd1b5Johny Lin std::weak_ptr<C2Component> component, std::vector<std::unique_ptr<C2Work>> workItems) { 16752bffe176c343075c196c072aa7924de3abdd1b5Johny Lin (void) component; 16852bffe176c343075c196c072aa7924de3abdd1b5Johny Lin ULock l(mProcessedLock); 16952bffe176c343075c196c072aa7924de3abdd1b5Johny Lin for (auto & item : workItems) { 17052bffe176c343075c196c072aa7924de3abdd1b5Johny Lin mProcessedWork.emplace_back(std::move(item)); 17152bffe176c343075c196c072aa7924de3abdd1b5Johny Lin } 17252bffe176c343075c196c072aa7924de3abdd1b5Johny Lin mProcessedCondition.notify_all(); 17352bffe176c343075c196c072aa7924de3abdd1b5Johny Lin} 17452bffe176c343075c196c072aa7924de3abdd1b5Johny Lin 17552bffe176c343075c196c072aa7924de3abdd1b5Johny Linvoid SimplePlayer::onTripped( 17652bffe176c343075c196c072aa7924de3abdd1b5Johny Lin std::weak_ptr<C2Component> component, 17752bffe176c343075c196c072aa7924de3abdd1b5Johny Lin std::vector<std::shared_ptr<C2SettingResult>> settingResult) { 17852bffe176c343075c196c072aa7924de3abdd1b5Johny Lin (void) component; 17952bffe176c343075c196c072aa7924de3abdd1b5Johny Lin (void) settingResult; 18052bffe176c343075c196c072aa7924de3abdd1b5Johny Lin // TODO 18152bffe176c343075c196c072aa7924de3abdd1b5Johny Lin} 18252bffe176c343075c196c072aa7924de3abdd1b5Johny Lin 18352bffe176c343075c196c072aa7924de3abdd1b5Johny Linvoid SimplePlayer::onError(std::weak_ptr<C2Component> component, uint32_t errorCode) { 18452bffe176c343075c196c072aa7924de3abdd1b5Johny Lin (void) component; 18552bffe176c343075c196c072aa7924de3abdd1b5Johny Lin (void) errorCode; 18652bffe176c343075c196c072aa7924de3abdd1b5Johny Lin // TODO 18752bffe176c343075c196c072aa7924de3abdd1b5Johny Lin} 18852bffe176c343075c196c072aa7924de3abdd1b5Johny Lin 18952bffe176c343075c196c072aa7924de3abdd1b5Johny Lin// TODO(johnylin): remove this when we move the development env to P 19052bffe176c343075c196c072aa7924de3abdd1b5Johny Lin// from master: system/core/libcutils/native_handle.c 19152bffe176c343075c196c072aa7924de3abdd1b5Johny Linnative_handle_t* native_handle_clone(const native_handle_t* handle) { 19252bffe176c343075c196c072aa7924de3abdd1b5Johny Lin native_handle_t* clone = native_handle_create(handle->numFds, handle->numInts); 19352bffe176c343075c196c072aa7924de3abdd1b5Johny Lin if (clone == nullptr) return nullptr; 19452bffe176c343075c196c072aa7924de3abdd1b5Johny Lin for (int i = 0; i < handle->numFds; i++) { 19552bffe176c343075c196c072aa7924de3abdd1b5Johny Lin clone->data[i] = dup(handle->data[i]); 19652bffe176c343075c196c072aa7924de3abdd1b5Johny Lin ALOGV("clone handle fd: %d", clone->data[i]); 19752bffe176c343075c196c072aa7924de3abdd1b5Johny Lin if (clone->data[i] == -1) { 19852bffe176c343075c196c072aa7924de3abdd1b5Johny Lin clone->numFds = i; 19952bffe176c343075c196c072aa7924de3abdd1b5Johny Lin native_handle_close(clone); 20052bffe176c343075c196c072aa7924de3abdd1b5Johny Lin native_handle_delete(clone); 20152bffe176c343075c196c072aa7924de3abdd1b5Johny Lin return nullptr; 20252bffe176c343075c196c072aa7924de3abdd1b5Johny Lin } 20352bffe176c343075c196c072aa7924de3abdd1b5Johny Lin } 20452bffe176c343075c196c072aa7924de3abdd1b5Johny Lin memcpy(&clone->data[handle->numFds], &handle->data[handle->numFds], 20552bffe176c343075c196c072aa7924de3abdd1b5Johny Lin sizeof(int) * handle->numInts); 20652bffe176c343075c196c072aa7924de3abdd1b5Johny Lin return clone; 20752bffe176c343075c196c072aa7924de3abdd1b5Johny Lin} 20852bffe176c343075c196c072aa7924de3abdd1b5Johny Lin 20952bffe176c343075c196c072aa7924de3abdd1b5Johny Linstatus_t SimplePlayer::play(const sp<IMediaSource> &source) { 21052bffe176c343075c196c072aa7924de3abdd1b5Johny Lin sp<AMessage> format; 21152bffe176c343075c196c072aa7924de3abdd1b5Johny Lin (void) convertMetaDataToMessage(source->getFormat(), &format); 21252bffe176c343075c196c072aa7924de3abdd1b5Johny Lin 21352bffe176c343075c196c072aa7924de3abdd1b5Johny Lin std::deque<sp<ABuffer>> csds(2); 21452bffe176c343075c196c072aa7924de3abdd1b5Johny Lin format->findBuffer("csd-0", &csds[0]); 21552bffe176c343075c196c072aa7924de3abdd1b5Johny Lin format->findBuffer("csd-1", &csds[1]); 21652bffe176c343075c196c072aa7924de3abdd1b5Johny Lin 21752bffe176c343075c196c072aa7924de3abdd1b5Johny Lin status_t err = source->start(); 21852bffe176c343075c196c072aa7924de3abdd1b5Johny Lin 21952bffe176c343075c196c072aa7924de3abdd1b5Johny Lin if (err != OK) { 22052bffe176c343075c196c072aa7924de3abdd1b5Johny Lin ALOGE("source returned error %d (0x%08x)", err, err); 22152bffe176c343075c196c072aa7924de3abdd1b5Johny Lin fprintf(stderr, "source returned error %d (0x%08x)\n", err, err); 22252bffe176c343075c196c072aa7924de3abdd1b5Johny Lin return err; 22352bffe176c343075c196c072aa7924de3abdd1b5Johny Lin } 22452bffe176c343075c196c072aa7924de3abdd1b5Johny Lin 22552bffe176c343075c196c072aa7924de3abdd1b5Johny Lin std::shared_ptr<C2Component> component(std::make_shared<C2VDAComponent>("avc", 0)); 22652bffe176c343075c196c072aa7924de3abdd1b5Johny Lin component->setListener_sm(mListener); 22752bffe176c343075c196c072aa7924de3abdd1b5Johny Lin std::unique_ptr<C2PortBlockPoolsTuning::output> pools = 22852bffe176c343075c196c072aa7924de3abdd1b5Johny Lin C2PortBlockPoolsTuning::output::alloc_unique( 22952bffe176c343075c196c072aa7924de3abdd1b5Johny Lin { static_cast<uint64_t>(C2BlockPool::BASIC_GRAPHIC) }); 23052bffe176c343075c196c072aa7924de3abdd1b5Johny Lin std::vector<std::unique_ptr<C2SettingResult>> result; 23152bffe176c343075c196c072aa7924de3abdd1b5Johny Lin (void)component->intf()->config_nb({pools.get()}, &result); 23252bffe176c343075c196c072aa7924de3abdd1b5Johny Lin component->start(); 23352bffe176c343075c196c072aa7924de3abdd1b5Johny Lin 23452bffe176c343075c196c072aa7924de3abdd1b5Johny Lin mProcessedWork.clear(); 23552bffe176c343075c196c072aa7924de3abdd1b5Johny Lin for (int i = 0; i < kInputBufferCount; ++i) { 23652bffe176c343075c196c072aa7924de3abdd1b5Johny Lin mWorkQueue.emplace_back(new C2Work); 23752bffe176c343075c196c072aa7924de3abdd1b5Johny Lin } 23852bffe176c343075c196c072aa7924de3abdd1b5Johny Lin 23952bffe176c343075c196c072aa7924de3abdd1b5Johny Lin std::atomic_bool running(true); 24052bffe176c343075c196c072aa7924de3abdd1b5Johny Lin std::thread surfaceThread([this, &running]() { 24152bffe176c343075c196c072aa7924de3abdd1b5Johny Lin const sp<IGraphicBufferProducer> &igbp = mSurface->getIGraphicBufferProducer(); 24252bffe176c343075c196c072aa7924de3abdd1b5Johny Lin std::vector<std::shared_ptr<C2Buffer>> pendingDisplayBuffers; 24352bffe176c343075c196c072aa7924de3abdd1b5Johny Lin pendingDisplayBuffers.resize(BufferQueue::NUM_BUFFER_SLOTS); 24452bffe176c343075c196c072aa7924de3abdd1b5Johny Lin while (running) { 24552bffe176c343075c196c072aa7924de3abdd1b5Johny Lin std::unique_ptr<C2Work> work; 24652bffe176c343075c196c072aa7924de3abdd1b5Johny Lin { 24752bffe176c343075c196c072aa7924de3abdd1b5Johny Lin ULock l(mProcessedLock); 24852bffe176c343075c196c072aa7924de3abdd1b5Johny Lin if (mProcessedWork.empty()) { 24952bffe176c343075c196c072aa7924de3abdd1b5Johny Lin mProcessedCondition.wait_for(l, 100ms); 25052bffe176c343075c196c072aa7924de3abdd1b5Johny Lin if (mProcessedWork.empty()) { 25152bffe176c343075c196c072aa7924de3abdd1b5Johny Lin continue; 25252bffe176c343075c196c072aa7924de3abdd1b5Johny Lin } 25352bffe176c343075c196c072aa7924de3abdd1b5Johny Lin } 25452bffe176c343075c196c072aa7924de3abdd1b5Johny Lin work = std::move(mProcessedWork.front()); 25552bffe176c343075c196c072aa7924de3abdd1b5Johny Lin mProcessedWork.pop_front(); 25652bffe176c343075c196c072aa7924de3abdd1b5Johny Lin } 25752bffe176c343075c196c072aa7924de3abdd1b5Johny Lin 25852bffe176c343075c196c072aa7924de3abdd1b5Johny Lin if (work->worklets_processed > 0) { 25952bffe176c343075c196c072aa7924de3abdd1b5Johny Lin int slot; 26052bffe176c343075c196c072aa7924de3abdd1b5Johny Lin sp<Fence> fence; 26152bffe176c343075c196c072aa7924de3abdd1b5Johny Lin std::shared_ptr<C2Buffer> output = work->worklets.front()->output.buffers[0]; 26252bffe176c343075c196c072aa7924de3abdd1b5Johny Lin C2ConstGraphicBlock graphic_block = output->data().graphicBlocks().front(); 26352bffe176c343075c196c072aa7924de3abdd1b5Johny Lin 26452bffe176c343075c196c072aa7924de3abdd1b5Johny Lin // Create GraphicBuffer from cloning native_handle 26552bffe176c343075c196c072aa7924de3abdd1b5Johny Lin native_handle_t* cloneHandle = native_handle_clone(graphic_block.handle()); 26652bffe176c343075c196c072aa7924de3abdd1b5Johny Lin sp<GraphicBuffer> buffer = new GraphicBuffer( 26752bffe176c343075c196c072aa7924de3abdd1b5Johny Lin graphic_block.width(), 26852bffe176c343075c196c072aa7924de3abdd1b5Johny Lin graphic_block.height(), 26952bffe176c343075c196c072aa7924de3abdd1b5Johny Lin HAL_PIXEL_FORMAT_YCbCr_420_888, 27052bffe176c343075c196c072aa7924de3abdd1b5Johny Lin GRALLOC_USAGE_SW_READ_OFTEN, 27152bffe176c343075c196c072aa7924de3abdd1b5Johny Lin graphic_block.width(), 27252bffe176c343075c196c072aa7924de3abdd1b5Johny Lin cloneHandle, 27352bffe176c343075c196c072aa7924de3abdd1b5Johny Lin false); 27452bffe176c343075c196c072aa7924de3abdd1b5Johny Lin 27552bffe176c343075c196c072aa7924de3abdd1b5Johny Lin CHECK_EQ(igbp->attachBuffer(&slot, buffer), OK); 27652bffe176c343075c196c072aa7924de3abdd1b5Johny Lin ALOGV("attachBuffer slot=%d ts=%lld", slot, 27752bffe176c343075c196c072aa7924de3abdd1b5Johny Lin work->worklets.front()->output.ordinal.timestamp * 1000ll); 27852bffe176c343075c196c072aa7924de3abdd1b5Johny Lin 27952bffe176c343075c196c072aa7924de3abdd1b5Johny Lin IGraphicBufferProducer::QueueBufferInput qbi( 28052bffe176c343075c196c072aa7924de3abdd1b5Johny Lin work->worklets.front()->output.ordinal.timestamp * 1000ll, 28152bffe176c343075c196c072aa7924de3abdd1b5Johny Lin false, 28252bffe176c343075c196c072aa7924de3abdd1b5Johny Lin HAL_DATASPACE_UNKNOWN, 28352bffe176c343075c196c072aa7924de3abdd1b5Johny Lin Rect(graphic_block.width(), graphic_block.height()), 28452bffe176c343075c196c072aa7924de3abdd1b5Johny Lin NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW, 28552bffe176c343075c196c072aa7924de3abdd1b5Johny Lin 0, 28652bffe176c343075c196c072aa7924de3abdd1b5Johny Lin Fence::NO_FENCE, 28752bffe176c343075c196c072aa7924de3abdd1b5Johny Lin 0); 28852bffe176c343075c196c072aa7924de3abdd1b5Johny Lin IGraphicBufferProducer::QueueBufferOutput qbo; 28952bffe176c343075c196c072aa7924de3abdd1b5Johny Lin CHECK_EQ(igbp->queueBuffer(slot, qbi, &qbo), OK); 29052bffe176c343075c196c072aa7924de3abdd1b5Johny Lin 29152bffe176c343075c196c072aa7924de3abdd1b5Johny Lin // If the slot is reused then we can make sure the previous graphic buffer is 29252bffe176c343075c196c072aa7924de3abdd1b5Johny Lin // displayed (consumed), so we could returned the graphic buffer. 29352bffe176c343075c196c072aa7924de3abdd1b5Johny Lin pendingDisplayBuffers[slot].swap(output); 29452bffe176c343075c196c072aa7924de3abdd1b5Johny Lin 29552bffe176c343075c196c072aa7924de3abdd1b5Johny Lin // Remember to close the cloned handle. 29652bffe176c343075c196c072aa7924de3abdd1b5Johny Lin native_handle_close(cloneHandle); 29752bffe176c343075c196c072aa7924de3abdd1b5Johny Lin native_handle_delete(cloneHandle); 29852bffe176c343075c196c072aa7924de3abdd1b5Johny Lin } 29952bffe176c343075c196c072aa7924de3abdd1b5Johny Lin 30052bffe176c343075c196c072aa7924de3abdd1b5Johny Lin // input buffers should be cleared in component side. 30152bffe176c343075c196c072aa7924de3abdd1b5Johny Lin CHECK(work->input.buffers.empty()); 30252bffe176c343075c196c072aa7924de3abdd1b5Johny Lin work->worklets.clear(); 30352bffe176c343075c196c072aa7924de3abdd1b5Johny Lin work->worklets_processed = 0; 30452bffe176c343075c196c072aa7924de3abdd1b5Johny Lin 30552bffe176c343075c196c072aa7924de3abdd1b5Johny Lin if (work->input.flags & C2BufferPack::FLAG_END_OF_STREAM) { 30652bffe176c343075c196c072aa7924de3abdd1b5Johny Lin running.store(false); // stop the thread 30752bffe176c343075c196c072aa7924de3abdd1b5Johny Lin } 30852bffe176c343075c196c072aa7924de3abdd1b5Johny Lin 30952bffe176c343075c196c072aa7924de3abdd1b5Johny Lin ULock l(mQueueLock); 31052bffe176c343075c196c072aa7924de3abdd1b5Johny Lin mWorkQueue.emplace_back(std::move(work)); 31152bffe176c343075c196c072aa7924de3abdd1b5Johny Lin mQueueCondition.notify_all(); 31252bffe176c343075c196c072aa7924de3abdd1b5Johny Lin } 31352bffe176c343075c196c072aa7924de3abdd1b5Johny Lin }); 31452bffe176c343075c196c072aa7924de3abdd1b5Johny Lin 31552bffe176c343075c196c072aa7924de3abdd1b5Johny Lin long numFrames = 0; 31652bffe176c343075c196c072aa7924de3abdd1b5Johny Lin 31752bffe176c343075c196c072aa7924de3abdd1b5Johny Lin for (;;) { 31852bffe176c343075c196c072aa7924de3abdd1b5Johny Lin size_t size = 0u; 31952bffe176c343075c196c072aa7924de3abdd1b5Johny Lin void *data = nullptr; 32052bffe176c343075c196c072aa7924de3abdd1b5Johny Lin int64_t timestamp = 0u; 32152bffe176c343075c196c072aa7924de3abdd1b5Johny Lin MediaBuffer* buffer = nullptr; 32252bffe176c343075c196c072aa7924de3abdd1b5Johny Lin sp<ABuffer> csd; 32352bffe176c343075c196c072aa7924de3abdd1b5Johny Lin if (!csds.empty()) { 32452bffe176c343075c196c072aa7924de3abdd1b5Johny Lin csd = std::move(csds.front()); 32552bffe176c343075c196c072aa7924de3abdd1b5Johny Lin csds.pop_front(); 32652bffe176c343075c196c072aa7924de3abdd1b5Johny Lin size = csd->size(); 32752bffe176c343075c196c072aa7924de3abdd1b5Johny Lin data = csd->data(); 32852bffe176c343075c196c072aa7924de3abdd1b5Johny Lin } else { 32952bffe176c343075c196c072aa7924de3abdd1b5Johny Lin status_t err = source->read(&buffer); 33052bffe176c343075c196c072aa7924de3abdd1b5Johny Lin if (err != OK) { 33152bffe176c343075c196c072aa7924de3abdd1b5Johny Lin CHECK(buffer == nullptr); 33252bffe176c343075c196c072aa7924de3abdd1b5Johny Lin 33352bffe176c343075c196c072aa7924de3abdd1b5Johny Lin if (err == INFO_FORMAT_CHANGED) { 33452bffe176c343075c196c072aa7924de3abdd1b5Johny Lin continue; 33552bffe176c343075c196c072aa7924de3abdd1b5Johny Lin } 33652bffe176c343075c196c072aa7924de3abdd1b5Johny Lin 33752bffe176c343075c196c072aa7924de3abdd1b5Johny Lin break; 33852bffe176c343075c196c072aa7924de3abdd1b5Johny Lin } 33952bffe176c343075c196c072aa7924de3abdd1b5Johny Lin sp<MetaData> meta = buffer->meta_data(); 34052bffe176c343075c196c072aa7924de3abdd1b5Johny Lin CHECK(meta->findInt64(kKeyTime, ×tamp)); 34152bffe176c343075c196c072aa7924de3abdd1b5Johny Lin 34252bffe176c343075c196c072aa7924de3abdd1b5Johny Lin size = buffer->size(); 34352bffe176c343075c196c072aa7924de3abdd1b5Johny Lin data = buffer->data(); 34452bffe176c343075c196c072aa7924de3abdd1b5Johny Lin } 34552bffe176c343075c196c072aa7924de3abdd1b5Johny Lin 34652bffe176c343075c196c072aa7924de3abdd1b5Johny Lin // Prepare C2Work 34752bffe176c343075c196c072aa7924de3abdd1b5Johny Lin 34852bffe176c343075c196c072aa7924de3abdd1b5Johny Lin std::unique_ptr<C2Work> work; 34952bffe176c343075c196c072aa7924de3abdd1b5Johny Lin while (!work) { 35052bffe176c343075c196c072aa7924de3abdd1b5Johny Lin ULock l(mQueueLock); 35152bffe176c343075c196c072aa7924de3abdd1b5Johny Lin if (!mWorkQueue.empty()) { 35252bffe176c343075c196c072aa7924de3abdd1b5Johny Lin work = std::move(mWorkQueue.front()); 35352bffe176c343075c196c072aa7924de3abdd1b5Johny Lin mWorkQueue.pop_front(); 35452bffe176c343075c196c072aa7924de3abdd1b5Johny Lin } else { 35552bffe176c343075c196c072aa7924de3abdd1b5Johny Lin mQueueCondition.wait_for(l, 100ms); 35652bffe176c343075c196c072aa7924de3abdd1b5Johny Lin } 35752bffe176c343075c196c072aa7924de3abdd1b5Johny Lin } 35852bffe176c343075c196c072aa7924de3abdd1b5Johny Lin work->input.flags = static_cast<C2BufferPack::flags_t>(0); 35952bffe176c343075c196c072aa7924de3abdd1b5Johny Lin work->input.ordinal.timestamp = timestamp; 36052bffe176c343075c196c072aa7924de3abdd1b5Johny Lin work->input.ordinal.frame_index = numFrames; 36152bffe176c343075c196c072aa7924de3abdd1b5Johny Lin 36252bffe176c343075c196c072aa7924de3abdd1b5Johny Lin // Allocate input buffer. 36352bffe176c343075c196c072aa7924de3abdd1b5Johny Lin std::shared_ptr<C2LinearBlock> block; 36452bffe176c343075c196c072aa7924de3abdd1b5Johny Lin mLinearBlockPool->fetchLinearBlock( 36552bffe176c343075c196c072aa7924de3abdd1b5Johny Lin size, { C2MemoryUsage::kSoftwareRead, C2MemoryUsage::kSoftwareWrite }, &block); 36652bffe176c343075c196c072aa7924de3abdd1b5Johny Lin C2WriteView view = block->map().get(); 36752bffe176c343075c196c072aa7924de3abdd1b5Johny Lin if (view.error() != C2_OK) { 36852bffe176c343075c196c072aa7924de3abdd1b5Johny Lin fprintf(stderr, "C2LinearBlock::map() failed : %d\n", view.error()); 36952bffe176c343075c196c072aa7924de3abdd1b5Johny Lin break; 37052bffe176c343075c196c072aa7924de3abdd1b5Johny Lin } 37152bffe176c343075c196c072aa7924de3abdd1b5Johny Lin memcpy(view.base(), data, size); 37252bffe176c343075c196c072aa7924de3abdd1b5Johny Lin 37352bffe176c343075c196c072aa7924de3abdd1b5Johny Lin work->input.buffers.clear(); 37452bffe176c343075c196c072aa7924de3abdd1b5Johny Lin work->input.buffers.emplace_back(new C2VDALinearBuffer(std::move(block))); 37552bffe176c343075c196c072aa7924de3abdd1b5Johny Lin work->worklets.clear(); 37652bffe176c343075c196c072aa7924de3abdd1b5Johny Lin work->worklets.emplace_back(new C2Worklet); 37752bffe176c343075c196c072aa7924de3abdd1b5Johny Lin 37852bffe176c343075c196c072aa7924de3abdd1b5Johny Lin std::list<std::unique_ptr<C2Work>> items; 37952bffe176c343075c196c072aa7924de3abdd1b5Johny Lin items.push_back(std::move(work)); 38052bffe176c343075c196c072aa7924de3abdd1b5Johny Lin 38152bffe176c343075c196c072aa7924de3abdd1b5Johny Lin // DO THE DECODING 38252bffe176c343075c196c072aa7924de3abdd1b5Johny Lin component->queue_nb(&items); 38352bffe176c343075c196c072aa7924de3abdd1b5Johny Lin 38452bffe176c343075c196c072aa7924de3abdd1b5Johny Lin if (buffer) { 38552bffe176c343075c196c072aa7924de3abdd1b5Johny Lin buffer->release(); 38652bffe176c343075c196c072aa7924de3abdd1b5Johny Lin } 38752bffe176c343075c196c072aa7924de3abdd1b5Johny Lin ++numFrames; 38852bffe176c343075c196c072aa7924de3abdd1b5Johny Lin } 38952bffe176c343075c196c072aa7924de3abdd1b5Johny Lin component->drain_nb(C2Component::DRAIN_COMPONENT); 39052bffe176c343075c196c072aa7924de3abdd1b5Johny Lin 39152bffe176c343075c196c072aa7924de3abdd1b5Johny Lin surfaceThread.join(); 39252bffe176c343075c196c072aa7924de3abdd1b5Johny Lin 39352bffe176c343075c196c072aa7924de3abdd1b5Johny Lin source->stop(); 39452bffe176c343075c196c072aa7924de3abdd1b5Johny Lin component->stop(); 39552bffe176c343075c196c072aa7924de3abdd1b5Johny Lin printf("finished...\n"); 39652bffe176c343075c196c072aa7924de3abdd1b5Johny Lin return OK; 39752bffe176c343075c196c072aa7924de3abdd1b5Johny Lin} 39852bffe176c343075c196c072aa7924de3abdd1b5Johny Lin 39952bffe176c343075c196c072aa7924de3abdd1b5Johny Lin} // namespace 40052bffe176c343075c196c072aa7924de3abdd1b5Johny Lin 40152bffe176c343075c196c072aa7924de3abdd1b5Johny Linstatic bool getMediaSourceFromFile(const char* filename, sp<IMediaSource>* source) { 40252bffe176c343075c196c072aa7924de3abdd1b5Johny Lin source->clear(); 40352bffe176c343075c196c072aa7924de3abdd1b5Johny Lin 40452bffe176c343075c196c072aa7924de3abdd1b5Johny Lin sp<DataSource> dataSource = 40552bffe176c343075c196c072aa7924de3abdd1b5Johny Lin DataSource::CreateFromURI(nullptr /* httpService */, filename); 40652bffe176c343075c196c072aa7924de3abdd1b5Johny Lin 40752bffe176c343075c196c072aa7924de3abdd1b5Johny Lin if (dataSource == nullptr) { 40852bffe176c343075c196c072aa7924de3abdd1b5Johny Lin fprintf(stderr, "Unable to create data source.\n"); 40952bffe176c343075c196c072aa7924de3abdd1b5Johny Lin return false; 41052bffe176c343075c196c072aa7924de3abdd1b5Johny Lin } 41152bffe176c343075c196c072aa7924de3abdd1b5Johny Lin 41252bffe176c343075c196c072aa7924de3abdd1b5Johny Lin sp<IMediaExtractor> extractor = MediaExtractor::Create(dataSource); 41352bffe176c343075c196c072aa7924de3abdd1b5Johny Lin if (extractor == nullptr) { 41452bffe176c343075c196c072aa7924de3abdd1b5Johny Lin fprintf(stderr, "could not create extractor.\n"); 41552bffe176c343075c196c072aa7924de3abdd1b5Johny Lin return false; 41652bffe176c343075c196c072aa7924de3abdd1b5Johny Lin } 41752bffe176c343075c196c072aa7924de3abdd1b5Johny Lin 41852bffe176c343075c196c072aa7924de3abdd1b5Johny Lin for (size_t i = 0, numTracks = extractor->countTracks(); i < numTracks; ++i) { 41952bffe176c343075c196c072aa7924de3abdd1b5Johny Lin sp<MetaData> meta = 42052bffe176c343075c196c072aa7924de3abdd1b5Johny Lin extractor->getTrackMetaData(i, MediaExtractor::kIncludeExtensiveMetaData); 42152bffe176c343075c196c072aa7924de3abdd1b5Johny Lin if (meta == nullptr) { 42252bffe176c343075c196c072aa7924de3abdd1b5Johny Lin continue; 42352bffe176c343075c196c072aa7924de3abdd1b5Johny Lin } 42452bffe176c343075c196c072aa7924de3abdd1b5Johny Lin const char *mime; 42552bffe176c343075c196c072aa7924de3abdd1b5Johny Lin meta->findCString(kKeyMIMEType, &mime); 42652bffe176c343075c196c072aa7924de3abdd1b5Johny Lin // TODO: only h264 is working now, adapt other codec (vp8/9) stream in the future. 42752bffe176c343075c196c072aa7924de3abdd1b5Johny Lin if (!strncasecmp(mime, "video/avc", 9)) { 42852bffe176c343075c196c072aa7924de3abdd1b5Johny Lin *source = extractor->getTrack(i); 42952bffe176c343075c196c072aa7924de3abdd1b5Johny Lin if (*source == nullptr) { 43052bffe176c343075c196c072aa7924de3abdd1b5Johny Lin fprintf(stderr, "It's nullptr track for track %zu.\n", i); 43152bffe176c343075c196c072aa7924de3abdd1b5Johny Lin return false; 43252bffe176c343075c196c072aa7924de3abdd1b5Johny Lin } 43352bffe176c343075c196c072aa7924de3abdd1b5Johny Lin return true; 43452bffe176c343075c196c072aa7924de3abdd1b5Johny Lin } 43552bffe176c343075c196c072aa7924de3abdd1b5Johny Lin } 43652bffe176c343075c196c072aa7924de3abdd1b5Johny Lin fprintf(stderr, "No AVC track found.\n"); 43752bffe176c343075c196c072aa7924de3abdd1b5Johny Lin return false; 43852bffe176c343075c196c072aa7924de3abdd1b5Johny Lin} 43952bffe176c343075c196c072aa7924de3abdd1b5Johny Lin 44052bffe176c343075c196c072aa7924de3abdd1b5Johny Linstatic void usage(const char *me) { 44152bffe176c343075c196c072aa7924de3abdd1b5Johny Lin fprintf(stderr, "usage: %s [options] [input_filename]...\n", me); 44252bffe176c343075c196c072aa7924de3abdd1b5Johny Lin fprintf(stderr, " -h(elp)\n"); 44352bffe176c343075c196c072aa7924de3abdd1b5Johny Lin} 44452bffe176c343075c196c072aa7924de3abdd1b5Johny Lin 44552bffe176c343075c196c072aa7924de3abdd1b5Johny Linint main(int argc, char **argv) { 44652bffe176c343075c196c072aa7924de3abdd1b5Johny Lin android::ProcessState::self()->startThreadPool(); 44752bffe176c343075c196c072aa7924de3abdd1b5Johny Lin 44852bffe176c343075c196c072aa7924de3abdd1b5Johny Lin int res; 44952bffe176c343075c196c072aa7924de3abdd1b5Johny Lin while ((res = getopt(argc, argv, "h")) >= 0) { 45052bffe176c343075c196c072aa7924de3abdd1b5Johny Lin switch (res) { 45152bffe176c343075c196c072aa7924de3abdd1b5Johny Lin case 'h': 45252bffe176c343075c196c072aa7924de3abdd1b5Johny Lin default: 45352bffe176c343075c196c072aa7924de3abdd1b5Johny Lin { 45452bffe176c343075c196c072aa7924de3abdd1b5Johny Lin usage(argv[0]); 45552bffe176c343075c196c072aa7924de3abdd1b5Johny Lin exit(1); 45652bffe176c343075c196c072aa7924de3abdd1b5Johny Lin break; 45752bffe176c343075c196c072aa7924de3abdd1b5Johny Lin } 45852bffe176c343075c196c072aa7924de3abdd1b5Johny Lin } 45952bffe176c343075c196c072aa7924de3abdd1b5Johny Lin } 46052bffe176c343075c196c072aa7924de3abdd1b5Johny Lin 46152bffe176c343075c196c072aa7924de3abdd1b5Johny Lin argc -= optind; 46252bffe176c343075c196c072aa7924de3abdd1b5Johny Lin argv += optind; 46352bffe176c343075c196c072aa7924de3abdd1b5Johny Lin 46452bffe176c343075c196c072aa7924de3abdd1b5Johny Lin if (argc < 1) { 46552bffe176c343075c196c072aa7924de3abdd1b5Johny Lin fprintf(stderr, "No input file specified\n"); 46652bffe176c343075c196c072aa7924de3abdd1b5Johny Lin return 1; 46752bffe176c343075c196c072aa7924de3abdd1b5Johny Lin } 46852bffe176c343075c196c072aa7924de3abdd1b5Johny Lin 46952bffe176c343075c196c072aa7924de3abdd1b5Johny Lin SimplePlayer player; 47052bffe176c343075c196c072aa7924de3abdd1b5Johny Lin 47152bffe176c343075c196c072aa7924de3abdd1b5Johny Lin for (int k = 0; k < argc; ++k) { 47252bffe176c343075c196c072aa7924de3abdd1b5Johny Lin sp<IMediaSource> mediaSource; 47352bffe176c343075c196c072aa7924de3abdd1b5Johny Lin if (!getMediaSourceFromFile(argv[k], &mediaSource)) { 47452bffe176c343075c196c072aa7924de3abdd1b5Johny Lin fprintf(stderr, "Unable to get media source from file: %s\n", argv[k]); 47552bffe176c343075c196c072aa7924de3abdd1b5Johny Lin return -1; 47652bffe176c343075c196c072aa7924de3abdd1b5Johny Lin } 47752bffe176c343075c196c072aa7924de3abdd1b5Johny Lin if (player.play(mediaSource) != OK) { 47852bffe176c343075c196c072aa7924de3abdd1b5Johny Lin fprintf(stderr, "Player failed to play media source: %s\n", argv[k]); 47952bffe176c343075c196c072aa7924de3abdd1b5Johny Lin return -1; 48052bffe176c343075c196c072aa7924de3abdd1b5Johny Lin } 48152bffe176c343075c196c072aa7924de3abdd1b5Johny Lin } 48252bffe176c343075c196c072aa7924de3abdd1b5Johny Lin 48352bffe176c343075c196c072aa7924de3abdd1b5Johny Lin return 0; 48452bffe176c343075c196c072aa7924de3abdd1b5Johny Lin} 485