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 8c6d0b6f730a74e2d10a414ba5b368fb7cd87f78dJohny Lin#include <C2VDAComponent.h> 98a2118e656587a22ebf4c1a4c23874fea45062b4Johny Lin 1052bffe176c343075c196c072aa7924de3abdd1b5Johny Lin#include <C2Buffer.h> 1152bffe176c343075c196c072aa7924de3abdd1b5Johny Lin#include <C2BufferPriv.h> 1252bffe176c343075c196c072aa7924de3abdd1b5Johny Lin#include <C2Component.h> 1385e1ec6ac0790a8f527ffc310a9f1a9be6589241Pin-chih Lin#include <C2PlatformSupport.h> 1452bffe176c343075c196c072aa7924de3abdd1b5Johny Lin#include <C2Work.h> 1547d00e960809f081a3410d4937ffb2725571bf62Lev Rumyantsev#include <SimpleC2Interface.h> 1652bffe176c343075c196c072aa7924de3abdd1b5Johny Lin 1752bffe176c343075c196c072aa7924de3abdd1b5Johny Lin#include <binder/IServiceManager.h> 1852bffe176c343075c196c072aa7924de3abdd1b5Johny Lin#include <binder/ProcessState.h> 19c6d0b6f730a74e2d10a414ba5b368fb7cd87f78dJohny Lin#include <gui/GLConsumer.h> 20c6d0b6f730a74e2d10a414ba5b368fb7cd87f78dJohny Lin#include <gui/IProducerListener.h> 21c6d0b6f730a74e2d10a414ba5b368fb7cd87f78dJohny Lin#include <gui/Surface.h> 22c6d0b6f730a74e2d10a414ba5b368fb7cd87f78dJohny Lin#include <gui/SurfaceComposerClient.h> 231ca0d0b761fd3074c538f3d31487f1b524e096daPin-chih Lin#include <media/DataSource.h> 2452bffe176c343075c196c072aa7924de3abdd1b5Johny Lin#include <media/ICrypto.h> 2552bffe176c343075c196c072aa7924de3abdd1b5Johny Lin#include <media/IMediaHTTPService.h> 261ca0d0b761fd3074c538f3d31487f1b524e096daPin-chih Lin#include <media/MediaExtractor.h> 271ca0d0b761fd3074c538f3d31487f1b524e096daPin-chih Lin#include <media/MediaSource.h> 281ca0d0b761fd3074c538f3d31487f1b524e096daPin-chih Lin#include <media/stagefright/DataSourceFactory.h> 2952bffe176c343075c196c072aa7924de3abdd1b5Johny Lin#include <media/stagefright/MediaDefs.h> 3052bffe176c343075c196c072aa7924de3abdd1b5Johny Lin#include <media/stagefright/MediaErrors.h> 311ca0d0b761fd3074c538f3d31487f1b524e096daPin-chih Lin#include <media/stagefright/MediaExtractorFactory.h> 3252bffe176c343075c196c072aa7924de3abdd1b5Johny Lin#include <media/stagefright/MetaData.h> 3352bffe176c343075c196c072aa7924de3abdd1b5Johny Lin#include <media/stagefright/Utils.h> 34a891f0ea984eb1175467ebe1c0ec086977464a07Johny Lin#include <media/stagefright/foundation/ABuffer.h> 35a891f0ea984eb1175467ebe1c0ec086977464a07Johny Lin#include <media/stagefright/foundation/ALooper.h> 36a891f0ea984eb1175467ebe1c0ec086977464a07Johny Lin#include <media/stagefright/foundation/AMessage.h> 37a891f0ea984eb1175467ebe1c0ec086977464a07Johny Lin#include <media/stagefright/foundation/AUtils.h> 3852bffe176c343075c196c072aa7924de3abdd1b5Johny Lin 39c6d0b6f730a74e2d10a414ba5b368fb7cd87f78dJohny Lin#include <fcntl.h> 40c6d0b6f730a74e2d10a414ba5b368fb7cd87f78dJohny Lin#include <inttypes.h> 41c6d0b6f730a74e2d10a414ba5b368fb7cd87f78dJohny Lin#include <stdlib.h> 42c6d0b6f730a74e2d10a414ba5b368fb7cd87f78dJohny Lin#include <string.h> 43c6d0b6f730a74e2d10a414ba5b368fb7cd87f78dJohny Lin#include <sys/stat.h> 44c6d0b6f730a74e2d10a414ba5b368fb7cd87f78dJohny Lin#include <sys/time.h> 45c6d0b6f730a74e2d10a414ba5b368fb7cd87f78dJohny Lin#include <sys/types.h> 46c6d0b6f730a74e2d10a414ba5b368fb7cd87f78dJohny Lin#include <thread> 4752bffe176c343075c196c072aa7924de3abdd1b5Johny Lin 4852bffe176c343075c196c072aa7924de3abdd1b5Johny Linusing namespace android; 4952bffe176c343075c196c072aa7924de3abdd1b5Johny Linusing namespace std::chrono_literals; 5052bffe176c343075c196c072aa7924de3abdd1b5Johny Lin 5152bffe176c343075c196c072aa7924de3abdd1b5Johny Linnamespace { 5252bffe176c343075c196c072aa7924de3abdd1b5Johny Lin 53226ec4605d573878f8062524e271daf2732a650aPin-chih Linconst std::string kH264DecoderName = "c2.vda.avc.decoder"; 54226ec4605d573878f8062524e271daf2732a650aPin-chih Linconst std::string kVP8DecoderName = "c2.vda.vp8.decoder"; 55226ec4605d573878f8062524e271daf2732a650aPin-chih Linconst std::string kVP9DecoderName = "c2.vda.vp9.decoder"; 569be5270780fda8f9e7e4aff26e10d94a1d47517bJohny Lin 5752bffe176c343075c196c072aa7924de3abdd1b5Johny Linconst int kWidth = 416; 5852bffe176c343075c196c072aa7924de3abdd1b5Johny Linconst int kHeight = 240; // BigBuckBunny.mp4 5952bffe176c343075c196c072aa7924de3abdd1b5Johny Lin//const int kWidth = 560; 6052bffe176c343075c196c072aa7924de3abdd1b5Johny Lin//const int kHeight = 320; // small.mp4 619be5270780fda8f9e7e4aff26e10d94a1d47517bJohny Linconst std::string kComponentName = kH264DecoderName; 6252bffe176c343075c196c072aa7924de3abdd1b5Johny Lin 6352bffe176c343075c196c072aa7924de3abdd1b5Johny Linclass C2VDALinearBuffer : public C2Buffer { 6452bffe176c343075c196c072aa7924de3abdd1b5Johny Linpublic: 6552bffe176c343075c196c072aa7924de3abdd1b5Johny Lin explicit C2VDALinearBuffer(const std::shared_ptr<C2LinearBlock>& block) 6693e4f225df19e43300fb3b29e6f95b4e63daa4c7Lajos Molnar : C2Buffer({block->share(block->offset(), block->size(), ::C2Fence())}) {} 6752bffe176c343075c196c072aa7924de3abdd1b5Johny Lin}; 6852bffe176c343075c196c072aa7924de3abdd1b5Johny Lin 6952bffe176c343075c196c072aa7924de3abdd1b5Johny Linclass Listener; 7052bffe176c343075c196c072aa7924de3abdd1b5Johny Lin 7152bffe176c343075c196c072aa7924de3abdd1b5Johny Linclass SimplePlayer { 7252bffe176c343075c196c072aa7924de3abdd1b5Johny Linpublic: 7352bffe176c343075c196c072aa7924de3abdd1b5Johny Lin SimplePlayer(); 7452bffe176c343075c196c072aa7924de3abdd1b5Johny Lin ~SimplePlayer(); 7552bffe176c343075c196c072aa7924de3abdd1b5Johny Lin 7652bffe176c343075c196c072aa7924de3abdd1b5Johny Lin void onWorkDone(std::weak_ptr<C2Component> component, 77fa7abe5b3914c3041874b360f511b132e6bf1116Lajos Molnar std::list<std::unique_ptr<C2Work>> workItems); 7852bffe176c343075c196c072aa7924de3abdd1b5Johny Lin void onTripped(std::weak_ptr<C2Component> component, 7952bffe176c343075c196c072aa7924de3abdd1b5Johny Lin std::vector<std::shared_ptr<C2SettingResult>> settingResult); 8052bffe176c343075c196c072aa7924de3abdd1b5Johny Lin void onError(std::weak_ptr<C2Component> component, uint32_t errorCode); 8152bffe176c343075c196c072aa7924de3abdd1b5Johny Lin 82a891f0ea984eb1175467ebe1c0ec086977464a07Johny Lin status_t play(const sp<IMediaSource>& source); 8352bffe176c343075c196c072aa7924de3abdd1b5Johny Lin 8452bffe176c343075c196c072aa7924de3abdd1b5Johny Linprivate: 8552bffe176c343075c196c072aa7924de3abdd1b5Johny Lin typedef std::unique_lock<std::mutex> ULock; 8652bffe176c343075c196c072aa7924de3abdd1b5Johny Lin 8752bffe176c343075c196c072aa7924de3abdd1b5Johny Lin enum { 8852bffe176c343075c196c072aa7924de3abdd1b5Johny Lin kInputBufferCount = 8, 8952bffe176c343075c196c072aa7924de3abdd1b5Johny Lin kDefaultInputBufferSize = 1024 * 1024, 9052bffe176c343075c196c072aa7924de3abdd1b5Johny Lin }; 9152bffe176c343075c196c072aa7924de3abdd1b5Johny Lin 9252bffe176c343075c196c072aa7924de3abdd1b5Johny Lin std::shared_ptr<Listener> mListener; 9352bffe176c343075c196c072aa7924de3abdd1b5Johny Lin 9452bffe176c343075c196c072aa7924de3abdd1b5Johny Lin sp<IProducerListener> mProducerListener; 9552bffe176c343075c196c072aa7924de3abdd1b5Johny Lin 9652bffe176c343075c196c072aa7924de3abdd1b5Johny Lin // Allocators 9752bffe176c343075c196c072aa7924de3abdd1b5Johny Lin std::shared_ptr<C2Allocator> mLinearAlloc; 9852bffe176c343075c196c072aa7924de3abdd1b5Johny Lin std::shared_ptr<C2BlockPool> mLinearBlockPool; 9952bffe176c343075c196c072aa7924de3abdd1b5Johny Lin 10052bffe176c343075c196c072aa7924de3abdd1b5Johny Lin std::mutex mQueueLock; 10152bffe176c343075c196c072aa7924de3abdd1b5Johny Lin std::condition_variable mQueueCondition; 10252bffe176c343075c196c072aa7924de3abdd1b5Johny Lin std::list<std::unique_ptr<C2Work>> mWorkQueue; 10352bffe176c343075c196c072aa7924de3abdd1b5Johny Lin 10452bffe176c343075c196c072aa7924de3abdd1b5Johny Lin std::mutex mProcessedLock; 10552bffe176c343075c196c072aa7924de3abdd1b5Johny Lin std::condition_variable mProcessedCondition; 10652bffe176c343075c196c072aa7924de3abdd1b5Johny Lin std::list<std::unique_ptr<C2Work>> mProcessedWork; 10752bffe176c343075c196c072aa7924de3abdd1b5Johny Lin 10852bffe176c343075c196c072aa7924de3abdd1b5Johny Lin sp<Surface> mSurface; 10952bffe176c343075c196c072aa7924de3abdd1b5Johny Lin sp<SurfaceComposerClient> mComposerClient; 11052bffe176c343075c196c072aa7924de3abdd1b5Johny Lin sp<SurfaceControl> mControl; 11152bffe176c343075c196c072aa7924de3abdd1b5Johny Lin}; 11252bffe176c343075c196c072aa7924de3abdd1b5Johny Lin 11352bffe176c343075c196c072aa7924de3abdd1b5Johny Linclass Listener : public C2Component::Listener { 11452bffe176c343075c196c072aa7924de3abdd1b5Johny Linpublic: 115a891f0ea984eb1175467ebe1c0ec086977464a07Johny Lin explicit Listener(SimplePlayer* thiz) : mThis(thiz) {} 11652bffe176c343075c196c072aa7924de3abdd1b5Johny Lin virtual ~Listener() = default; 11752bffe176c343075c196c072aa7924de3abdd1b5Johny Lin 11852bffe176c343075c196c072aa7924de3abdd1b5Johny Lin virtual void onWorkDone_nb(std::weak_ptr<C2Component> component, 119fa7abe5b3914c3041874b360f511b132e6bf1116Lajos Molnar std::list<std::unique_ptr<C2Work>> workItems) override { 12052bffe176c343075c196c072aa7924de3abdd1b5Johny Lin mThis->onWorkDone(component, std::move(workItems)); 12152bffe176c343075c196c072aa7924de3abdd1b5Johny Lin } 12252bffe176c343075c196c072aa7924de3abdd1b5Johny Lin 12352bffe176c343075c196c072aa7924de3abdd1b5Johny Lin virtual void onTripped_nb( 12452bffe176c343075c196c072aa7924de3abdd1b5Johny Lin std::weak_ptr<C2Component> component, 12552bffe176c343075c196c072aa7924de3abdd1b5Johny Lin std::vector<std::shared_ptr<C2SettingResult>> settingResult) override { 12652bffe176c343075c196c072aa7924de3abdd1b5Johny Lin mThis->onTripped(component, settingResult); 12752bffe176c343075c196c072aa7924de3abdd1b5Johny Lin } 12852bffe176c343075c196c072aa7924de3abdd1b5Johny Lin 129a891f0ea984eb1175467ebe1c0ec086977464a07Johny Lin virtual void onError_nb(std::weak_ptr<C2Component> component, uint32_t errorCode) override { 13052bffe176c343075c196c072aa7924de3abdd1b5Johny Lin mThis->onError(component, errorCode); 13152bffe176c343075c196c072aa7924de3abdd1b5Johny Lin } 13252bffe176c343075c196c072aa7924de3abdd1b5Johny Lin 13352bffe176c343075c196c072aa7924de3abdd1b5Johny Linprivate: 134a891f0ea984eb1175467ebe1c0ec086977464a07Johny Lin SimplePlayer* const mThis; 13552bffe176c343075c196c072aa7924de3abdd1b5Johny Lin}; 13652bffe176c343075c196c072aa7924de3abdd1b5Johny Lin 13752bffe176c343075c196c072aa7924de3abdd1b5Johny LinSimplePlayer::SimplePlayer() 138a891f0ea984eb1175467ebe1c0ec086977464a07Johny Lin : mListener(new Listener(this)), 139a891f0ea984eb1175467ebe1c0ec086977464a07Johny Lin mProducerListener(new DummyProducerListener), 140a891f0ea984eb1175467ebe1c0ec086977464a07Johny Lin mComposerClient(new SurfaceComposerClient) { 14152bffe176c343075c196c072aa7924de3abdd1b5Johny Lin CHECK_EQ(mComposerClient->initCheck(), OK); 14252bffe176c343075c196c072aa7924de3abdd1b5Johny Lin 1438a2118e656587a22ebf4c1a4c23874fea45062b4Johny Lin std::shared_ptr<C2AllocatorStore> store = GetCodec2PlatformAllocatorStore(); 14452bffe176c343075c196c072aa7924de3abdd1b5Johny Lin CHECK_EQ(store->fetchAllocator(C2AllocatorStore::DEFAULT_LINEAR, &mLinearAlloc), C2_OK); 14552bffe176c343075c196c072aa7924de3abdd1b5Johny Lin 14652bffe176c343075c196c072aa7924de3abdd1b5Johny Lin mLinearBlockPool = std::make_shared<C2BasicLinearBlockPool>(mLinearAlloc); 14752bffe176c343075c196c072aa7924de3abdd1b5Johny Lin 148a891f0ea984eb1175467ebe1c0ec086977464a07Johny Lin mControl = mComposerClient->createSurface(String8("A Surface"), kWidth, kHeight, 149a891f0ea984eb1175467ebe1c0ec086977464a07Johny Lin HAL_PIXEL_FORMAT_YV12); 15052bffe176c343075c196c072aa7924de3abdd1b5Johny Lin 15152bffe176c343075c196c072aa7924de3abdd1b5Johny Lin CHECK(mControl != nullptr); 15252bffe176c343075c196c072aa7924de3abdd1b5Johny Lin CHECK(mControl->isValid()); 15352bffe176c343075c196c072aa7924de3abdd1b5Johny Lin 1540deb659ab57ad7d9bac1c025cb5dd182946bc9f8Johny Lin SurfaceComposerClient::Transaction{}.setLayer(mControl, INT_MAX).show(mControl).apply(); 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 165a891f0ea984eb1175467ebe1c0ec086977464a07Johny Linvoid SimplePlayer::onWorkDone(std::weak_ptr<C2Component> component, 166fa7abe5b3914c3041874b360f511b132e6bf1116Lajos Molnar std::list<std::unique_ptr<C2Work>> workItems) { 167a891f0ea984eb1175467ebe1c0ec086977464a07Johny Lin (void)component; 16852bffe176c343075c196c072aa7924de3abdd1b5Johny Lin ULock l(mProcessedLock); 169a891f0ea984eb1175467ebe1c0ec086977464a07Johny Lin for (auto& item : workItems) { 17052bffe176c343075c196c072aa7924de3abdd1b5Johny Lin mProcessedWork.emplace_back(std::move(item)); 17152bffe176c343075c196c072aa7924de3abdd1b5Johny Lin } 17252bffe176c343075c196c072aa7924de3abdd1b5Johny Lin mProcessedCondition.notify_all(); 17352bffe176c343075c196c072aa7924de3abdd1b5Johny Lin} 17452bffe176c343075c196c072aa7924de3abdd1b5Johny Lin 175a891f0ea984eb1175467ebe1c0ec086977464a07Johny Linvoid SimplePlayer::onTripped(std::weak_ptr<C2Component> component, 176a891f0ea984eb1175467ebe1c0ec086977464a07Johny Lin std::vector<std::shared_ptr<C2SettingResult>> settingResult) { 177a891f0ea984eb1175467ebe1c0ec086977464a07Johny Lin (void)component; 178a891f0ea984eb1175467ebe1c0ec086977464a07Johny Lin (void)settingResult; 17952bffe176c343075c196c072aa7924de3abdd1b5Johny Lin // TODO 18052bffe176c343075c196c072aa7924de3abdd1b5Johny Lin} 18152bffe176c343075c196c072aa7924de3abdd1b5Johny Lin 18252bffe176c343075c196c072aa7924de3abdd1b5Johny Linvoid SimplePlayer::onError(std::weak_ptr<C2Component> component, uint32_t errorCode) { 183a891f0ea984eb1175467ebe1c0ec086977464a07Johny Lin (void)component; 184a891f0ea984eb1175467ebe1c0ec086977464a07Johny Lin (void)errorCode; 18552bffe176c343075c196c072aa7924de3abdd1b5Johny Lin // TODO 18652bffe176c343075c196c072aa7924de3abdd1b5Johny Lin} 18752bffe176c343075c196c072aa7924de3abdd1b5Johny Lin 188a891f0ea984eb1175467ebe1c0ec086977464a07Johny Linstatus_t SimplePlayer::play(const sp<IMediaSource>& source) { 1899be5270780fda8f9e7e4aff26e10d94a1d47517bJohny Lin std::deque<sp<ABuffer>> csds; 1909be5270780fda8f9e7e4aff26e10d94a1d47517bJohny Lin if (kComponentName == kH264DecoderName) { 1919be5270780fda8f9e7e4aff26e10d94a1d47517bJohny Lin sp<AMessage> format; 192a891f0ea984eb1175467ebe1c0ec086977464a07Johny Lin (void)convertMetaDataToMessage(source->getFormat(), &format); 1939be5270780fda8f9e7e4aff26e10d94a1d47517bJohny Lin 1949be5270780fda8f9e7e4aff26e10d94a1d47517bJohny Lin csds.resize(2); 1959be5270780fda8f9e7e4aff26e10d94a1d47517bJohny Lin format->findBuffer("csd-0", &csds[0]); 1969be5270780fda8f9e7e4aff26e10d94a1d47517bJohny Lin format->findBuffer("csd-1", &csds[1]); 1979be5270780fda8f9e7e4aff26e10d94a1d47517bJohny Lin } 19852bffe176c343075c196c072aa7924de3abdd1b5Johny Lin 19952bffe176c343075c196c072aa7924de3abdd1b5Johny Lin status_t err = source->start(); 20052bffe176c343075c196c072aa7924de3abdd1b5Johny Lin 20152bffe176c343075c196c072aa7924de3abdd1b5Johny Lin if (err != OK) { 20252bffe176c343075c196c072aa7924de3abdd1b5Johny Lin ALOGE("source returned error %d (0x%08x)", err, err); 20352bffe176c343075c196c072aa7924de3abdd1b5Johny Lin fprintf(stderr, "source returned error %d (0x%08x)\n", err, err); 20452bffe176c343075c196c072aa7924de3abdd1b5Johny Lin return err; 20552bffe176c343075c196c072aa7924de3abdd1b5Johny Lin } 20652bffe176c343075c196c072aa7924de3abdd1b5Johny Lin 2071ca0d0b761fd3074c538f3d31487f1b524e096daPin-chih Lin std::shared_ptr<C2Component> component(std::make_shared<C2VDAComponent>( 2081ca0d0b761fd3074c538f3d31487f1b524e096daPin-chih Lin kComponentName, 0, std::make_shared<C2ReflectorHelper>())); 2091ca0d0b761fd3074c538f3d31487f1b524e096daPin-chih Lin 210a891f0ea984eb1175467ebe1c0ec086977464a07Johny Lin component->setListener_vb(mListener, C2_DONT_BLOCK); 21152bffe176c343075c196c072aa7924de3abdd1b5Johny Lin std::unique_ptr<C2PortBlockPoolsTuning::output> pools = 21293e4f225df19e43300fb3b29e6f95b4e63daa4c7Lajos Molnar C2PortBlockPoolsTuning::output::AllocUnique( 213a891f0ea984eb1175467ebe1c0ec086977464a07Johny Lin {static_cast<uint64_t>(C2BlockPool::BASIC_GRAPHIC)}); 21452bffe176c343075c196c072aa7924de3abdd1b5Johny Lin std::vector<std::unique_ptr<C2SettingResult>> result; 2152737fb61ca7ecd786b160ec5d79e3eaa48135606Lajos Molnar (void)component->intf()->config_vb({pools.get()}, C2_DONT_BLOCK, &result); 21652bffe176c343075c196c072aa7924de3abdd1b5Johny Lin component->start(); 21752bffe176c343075c196c072aa7924de3abdd1b5Johny Lin 21852bffe176c343075c196c072aa7924de3abdd1b5Johny Lin mProcessedWork.clear(); 21952bffe176c343075c196c072aa7924de3abdd1b5Johny Lin for (int i = 0; i < kInputBufferCount; ++i) { 22052bffe176c343075c196c072aa7924de3abdd1b5Johny Lin mWorkQueue.emplace_back(new C2Work); 22152bffe176c343075c196c072aa7924de3abdd1b5Johny Lin } 22252bffe176c343075c196c072aa7924de3abdd1b5Johny Lin 22352bffe176c343075c196c072aa7924de3abdd1b5Johny Lin std::atomic_bool running(true); 22452bffe176c343075c196c072aa7924de3abdd1b5Johny Lin std::thread surfaceThread([this, &running]() { 225a891f0ea984eb1175467ebe1c0ec086977464a07Johny Lin const sp<IGraphicBufferProducer>& igbp = mSurface->getIGraphicBufferProducer(); 22652bffe176c343075c196c072aa7924de3abdd1b5Johny Lin std::vector<std::shared_ptr<C2Buffer>> pendingDisplayBuffers; 22752bffe176c343075c196c072aa7924de3abdd1b5Johny Lin pendingDisplayBuffers.resize(BufferQueue::NUM_BUFFER_SLOTS); 22852bffe176c343075c196c072aa7924de3abdd1b5Johny Lin while (running) { 22952bffe176c343075c196c072aa7924de3abdd1b5Johny Lin std::unique_ptr<C2Work> work; 23052bffe176c343075c196c072aa7924de3abdd1b5Johny Lin { 23152bffe176c343075c196c072aa7924de3abdd1b5Johny Lin ULock l(mProcessedLock); 23252bffe176c343075c196c072aa7924de3abdd1b5Johny Lin if (mProcessedWork.empty()) { 23352bffe176c343075c196c072aa7924de3abdd1b5Johny Lin mProcessedCondition.wait_for(l, 100ms); 23452bffe176c343075c196c072aa7924de3abdd1b5Johny Lin if (mProcessedWork.empty()) { 23552bffe176c343075c196c072aa7924de3abdd1b5Johny Lin continue; 23652bffe176c343075c196c072aa7924de3abdd1b5Johny Lin } 23752bffe176c343075c196c072aa7924de3abdd1b5Johny Lin } 23852bffe176c343075c196c072aa7924de3abdd1b5Johny Lin work = std::move(mProcessedWork.front()); 23952bffe176c343075c196c072aa7924de3abdd1b5Johny Lin mProcessedWork.pop_front(); 24052bffe176c343075c196c072aa7924de3abdd1b5Johny Lin } 24152bffe176c343075c196c072aa7924de3abdd1b5Johny Lin 2423760d5fdd7e60b68ed599d7322e2599efe7a13c9Johny Lin CHECK_EQ(work->worklets.size(), 1u); 2433760d5fdd7e60b68ed599d7322e2599efe7a13c9Johny Lin if (work->worklets.front()->output.buffers.size() == 1u) { 24452bffe176c343075c196c072aa7924de3abdd1b5Johny Lin int slot; 24552bffe176c343075c196c072aa7924de3abdd1b5Johny Lin sp<Fence> fence; 24652bffe176c343075c196c072aa7924de3abdd1b5Johny Lin std::shared_ptr<C2Buffer> output = work->worklets.front()->output.buffers[0]; 24752bffe176c343075c196c072aa7924de3abdd1b5Johny Lin C2ConstGraphicBlock graphic_block = output->data().graphicBlocks().front(); 24852bffe176c343075c196c072aa7924de3abdd1b5Johny Lin 2490deb659ab57ad7d9bac1c025cb5dd182946bc9f8Johny Lin sp<GraphicBuffer> buffer(new GraphicBuffer( 2500deb659ab57ad7d9bac1c025cb5dd182946bc9f8Johny Lin graphic_block.handle(), GraphicBuffer::CLONE_HANDLE, graphic_block.width(), 2510deb659ab57ad7d9bac1c025cb5dd182946bc9f8Johny Lin graphic_block.height(), HAL_PIXEL_FORMAT_YCbCr_420_888, 1 /* layerCount */, 2520deb659ab57ad7d9bac1c025cb5dd182946bc9f8Johny Lin GRALLOC_USAGE_SW_READ_OFTEN, graphic_block.width())); 25352bffe176c343075c196c072aa7924de3abdd1b5Johny Lin 25452bffe176c343075c196c072aa7924de3abdd1b5Johny Lin CHECK_EQ(igbp->attachBuffer(&slot, buffer), OK); 25552bffe176c343075c196c072aa7924de3abdd1b5Johny Lin ALOGV("attachBuffer slot=%d ts=%lld", slot, 2562a2b90179d72e158c74982599752c92aac9029deLajos Molnar (work->worklets.front()->output.ordinal.timestamp * 1000ll).peekll()); 25752bffe176c343075c196c072aa7924de3abdd1b5Johny Lin 25852bffe176c343075c196c072aa7924de3abdd1b5Johny Lin IGraphicBufferProducer::QueueBufferInput qbi( 2592a2b90179d72e158c74982599752c92aac9029deLajos Molnar (work->worklets.front()->output.ordinal.timestamp * 1000ll).peekll(), false, 260a891f0ea984eb1175467ebe1c0ec086977464a07Johny Lin HAL_DATASPACE_UNKNOWN, Rect(graphic_block.width(), graphic_block.height()), 261a891f0ea984eb1175467ebe1c0ec086977464a07Johny Lin NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW, 0, Fence::NO_FENCE, 0); 26252bffe176c343075c196c072aa7924de3abdd1b5Johny Lin IGraphicBufferProducer::QueueBufferOutput qbo; 26352bffe176c343075c196c072aa7924de3abdd1b5Johny Lin CHECK_EQ(igbp->queueBuffer(slot, qbi, &qbo), OK); 26452bffe176c343075c196c072aa7924de3abdd1b5Johny Lin 26552bffe176c343075c196c072aa7924de3abdd1b5Johny Lin // If the slot is reused then we can make sure the previous graphic buffer is 26652bffe176c343075c196c072aa7924de3abdd1b5Johny Lin // displayed (consumed), so we could returned the graphic buffer. 26752bffe176c343075c196c072aa7924de3abdd1b5Johny Lin pendingDisplayBuffers[slot].swap(output); 26852bffe176c343075c196c072aa7924de3abdd1b5Johny Lin } 26952bffe176c343075c196c072aa7924de3abdd1b5Johny Lin 2703760d5fdd7e60b68ed599d7322e2599efe7a13c9Johny Lin bool eos = work->worklets.front()->output.flags & C2FrameData::FLAG_END_OF_STREAM; 271cd56fe7ad767762950d20582daf9d646d916f10bPin-chih Lin // input buffer should be reset in component side. 272cd56fe7ad767762950d20582daf9d646d916f10bPin-chih Lin CHECK_EQ(work->input.buffers.size(), 1u); 273cd56fe7ad767762950d20582daf9d646d916f10bPin-chih Lin CHECK(work->input.buffers.front() == nullptr); 27452bffe176c343075c196c072aa7924de3abdd1b5Johny Lin work->worklets.clear(); 2752a2b90179d72e158c74982599752c92aac9029deLajos Molnar work->workletsProcessed = 0; 27652bffe176c343075c196c072aa7924de3abdd1b5Johny Lin 2773760d5fdd7e60b68ed599d7322e2599efe7a13c9Johny Lin if (eos) { 27852bffe176c343075c196c072aa7924de3abdd1b5Johny Lin running.store(false); // stop the thread 27952bffe176c343075c196c072aa7924de3abdd1b5Johny Lin } 28052bffe176c343075c196c072aa7924de3abdd1b5Johny Lin 28152bffe176c343075c196c072aa7924de3abdd1b5Johny Lin ULock l(mQueueLock); 28252bffe176c343075c196c072aa7924de3abdd1b5Johny Lin mWorkQueue.emplace_back(std::move(work)); 28352bffe176c343075c196c072aa7924de3abdd1b5Johny Lin mQueueCondition.notify_all(); 28452bffe176c343075c196c072aa7924de3abdd1b5Johny Lin } 28552bffe176c343075c196c072aa7924de3abdd1b5Johny Lin }); 28652bffe176c343075c196c072aa7924de3abdd1b5Johny Lin 28752bffe176c343075c196c072aa7924de3abdd1b5Johny Lin long numFrames = 0; 28852bffe176c343075c196c072aa7924de3abdd1b5Johny Lin 28952bffe176c343075c196c072aa7924de3abdd1b5Johny Lin for (;;) { 29052bffe176c343075c196c072aa7924de3abdd1b5Johny Lin size_t size = 0u; 291a891f0ea984eb1175467ebe1c0ec086977464a07Johny Lin void* data = nullptr; 29252bffe176c343075c196c072aa7924de3abdd1b5Johny Lin int64_t timestamp = 0u; 2937291a48a6117a6c67c6e4b776fe660e4ed9ef02bDongwon Kang MediaBufferBase* buffer = nullptr; 29452bffe176c343075c196c072aa7924de3abdd1b5Johny Lin sp<ABuffer> csd; 29552bffe176c343075c196c072aa7924de3abdd1b5Johny Lin if (!csds.empty()) { 29652bffe176c343075c196c072aa7924de3abdd1b5Johny Lin csd = std::move(csds.front()); 29752bffe176c343075c196c072aa7924de3abdd1b5Johny Lin csds.pop_front(); 29852bffe176c343075c196c072aa7924de3abdd1b5Johny Lin size = csd->size(); 29952bffe176c343075c196c072aa7924de3abdd1b5Johny Lin data = csd->data(); 30052bffe176c343075c196c072aa7924de3abdd1b5Johny Lin } else { 30152bffe176c343075c196c072aa7924de3abdd1b5Johny Lin status_t err = source->read(&buffer); 30252bffe176c343075c196c072aa7924de3abdd1b5Johny Lin if (err != OK) { 30352bffe176c343075c196c072aa7924de3abdd1b5Johny Lin CHECK(buffer == nullptr); 30452bffe176c343075c196c072aa7924de3abdd1b5Johny Lin 30552bffe176c343075c196c072aa7924de3abdd1b5Johny Lin if (err == INFO_FORMAT_CHANGED) { 30652bffe176c343075c196c072aa7924de3abdd1b5Johny Lin continue; 30752bffe176c343075c196c072aa7924de3abdd1b5Johny Lin } 30852bffe176c343075c196c072aa7924de3abdd1b5Johny Lin 30952bffe176c343075c196c072aa7924de3abdd1b5Johny Lin break; 31052bffe176c343075c196c072aa7924de3abdd1b5Johny Lin } 3111ca0d0b761fd3074c538f3d31487f1b524e096daPin-chih Lin MetaDataBase& meta = buffer->meta_data(); 312ac29bf870c419dc38903896c50844b736fa8540eMarco Nelissen CHECK(meta.findInt64(kKeyTime, ×tamp)); 31352bffe176c343075c196c072aa7924de3abdd1b5Johny Lin 31452bffe176c343075c196c072aa7924de3abdd1b5Johny Lin size = buffer->size(); 31552bffe176c343075c196c072aa7924de3abdd1b5Johny Lin data = buffer->data(); 31652bffe176c343075c196c072aa7924de3abdd1b5Johny Lin } 31752bffe176c343075c196c072aa7924de3abdd1b5Johny Lin 31852bffe176c343075c196c072aa7924de3abdd1b5Johny Lin // Prepare C2Work 31952bffe176c343075c196c072aa7924de3abdd1b5Johny Lin 32052bffe176c343075c196c072aa7924de3abdd1b5Johny Lin std::unique_ptr<C2Work> work; 32152bffe176c343075c196c072aa7924de3abdd1b5Johny Lin while (!work) { 32252bffe176c343075c196c072aa7924de3abdd1b5Johny Lin ULock l(mQueueLock); 32352bffe176c343075c196c072aa7924de3abdd1b5Johny Lin if (!mWorkQueue.empty()) { 32452bffe176c343075c196c072aa7924de3abdd1b5Johny Lin work = std::move(mWorkQueue.front()); 32552bffe176c343075c196c072aa7924de3abdd1b5Johny Lin mWorkQueue.pop_front(); 32652bffe176c343075c196c072aa7924de3abdd1b5Johny Lin } else { 32752bffe176c343075c196c072aa7924de3abdd1b5Johny Lin mQueueCondition.wait_for(l, 100ms); 32852bffe176c343075c196c072aa7924de3abdd1b5Johny Lin } 32952bffe176c343075c196c072aa7924de3abdd1b5Johny Lin } 3302a2b90179d72e158c74982599752c92aac9029deLajos Molnar work->input.flags = static_cast<C2FrameData::flags_t>(0); 33152bffe176c343075c196c072aa7924de3abdd1b5Johny Lin work->input.ordinal.timestamp = timestamp; 3322a2b90179d72e158c74982599752c92aac9029deLajos Molnar work->input.ordinal.frameIndex = numFrames; 33352bffe176c343075c196c072aa7924de3abdd1b5Johny Lin 33452bffe176c343075c196c072aa7924de3abdd1b5Johny Lin // Allocate input buffer. 33552bffe176c343075c196c072aa7924de3abdd1b5Johny Lin std::shared_ptr<C2LinearBlock> block; 33652bffe176c343075c196c072aa7924de3abdd1b5Johny Lin mLinearBlockPool->fetchLinearBlock( 33720d1a263e74399f3a93e01bbe24db5b0066af653Johny Lin size, {C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE}, &block); 33852bffe176c343075c196c072aa7924de3abdd1b5Johny Lin C2WriteView view = block->map().get(); 33952bffe176c343075c196c072aa7924de3abdd1b5Johny Lin if (view.error() != C2_OK) { 34052bffe176c343075c196c072aa7924de3abdd1b5Johny Lin fprintf(stderr, "C2LinearBlock::map() failed : %d\n", view.error()); 34152bffe176c343075c196c072aa7924de3abdd1b5Johny Lin break; 34252bffe176c343075c196c072aa7924de3abdd1b5Johny Lin } 34352bffe176c343075c196c072aa7924de3abdd1b5Johny Lin memcpy(view.base(), data, size); 34452bffe176c343075c196c072aa7924de3abdd1b5Johny Lin 34552bffe176c343075c196c072aa7924de3abdd1b5Johny Lin work->input.buffers.clear(); 34652bffe176c343075c196c072aa7924de3abdd1b5Johny Lin work->input.buffers.emplace_back(new C2VDALinearBuffer(std::move(block))); 34752bffe176c343075c196c072aa7924de3abdd1b5Johny Lin work->worklets.clear(); 34852bffe176c343075c196c072aa7924de3abdd1b5Johny Lin work->worklets.emplace_back(new C2Worklet); 34952bffe176c343075c196c072aa7924de3abdd1b5Johny Lin 35052bffe176c343075c196c072aa7924de3abdd1b5Johny Lin std::list<std::unique_ptr<C2Work>> items; 35152bffe176c343075c196c072aa7924de3abdd1b5Johny Lin items.push_back(std::move(work)); 35252bffe176c343075c196c072aa7924de3abdd1b5Johny Lin 35352bffe176c343075c196c072aa7924de3abdd1b5Johny Lin // DO THE DECODING 35452bffe176c343075c196c072aa7924de3abdd1b5Johny Lin component->queue_nb(&items); 35552bffe176c343075c196c072aa7924de3abdd1b5Johny Lin 35652bffe176c343075c196c072aa7924de3abdd1b5Johny Lin if (buffer) { 35752bffe176c343075c196c072aa7924de3abdd1b5Johny Lin buffer->release(); 35852bffe176c343075c196c072aa7924de3abdd1b5Johny Lin } 35952bffe176c343075c196c072aa7924de3abdd1b5Johny Lin ++numFrames; 36052bffe176c343075c196c072aa7924de3abdd1b5Johny Lin } 361a891f0ea984eb1175467ebe1c0ec086977464a07Johny Lin component->drain_nb(C2Component::DRAIN_COMPONENT_WITH_EOS); 36252bffe176c343075c196c072aa7924de3abdd1b5Johny Lin 36352bffe176c343075c196c072aa7924de3abdd1b5Johny Lin surfaceThread.join(); 36452bffe176c343075c196c072aa7924de3abdd1b5Johny Lin 36552bffe176c343075c196c072aa7924de3abdd1b5Johny Lin source->stop(); 36652bffe176c343075c196c072aa7924de3abdd1b5Johny Lin component->stop(); 36752bffe176c343075c196c072aa7924de3abdd1b5Johny Lin printf("finished...\n"); 36852bffe176c343075c196c072aa7924de3abdd1b5Johny Lin return OK; 36952bffe176c343075c196c072aa7924de3abdd1b5Johny Lin} 37052bffe176c343075c196c072aa7924de3abdd1b5Johny Lin 37152bffe176c343075c196c072aa7924de3abdd1b5Johny Lin} // namespace 37252bffe176c343075c196c072aa7924de3abdd1b5Johny Lin 37352bffe176c343075c196c072aa7924de3abdd1b5Johny Linstatic bool getMediaSourceFromFile(const char* filename, sp<IMediaSource>* source) { 37452bffe176c343075c196c072aa7924de3abdd1b5Johny Lin source->clear(); 37552bffe176c343075c196c072aa7924de3abdd1b5Johny Lin 3760deb659ab57ad7d9bac1c025cb5dd182946bc9f8Johny Lin sp<DataSource> dataSource = 3770deb659ab57ad7d9bac1c025cb5dd182946bc9f8Johny Lin DataSourceFactory::CreateFromURI(nullptr /* httpService */, filename); 37852bffe176c343075c196c072aa7924de3abdd1b5Johny Lin 37952bffe176c343075c196c072aa7924de3abdd1b5Johny Lin if (dataSource == nullptr) { 38052bffe176c343075c196c072aa7924de3abdd1b5Johny Lin fprintf(stderr, "Unable to create data source.\n"); 38152bffe176c343075c196c072aa7924de3abdd1b5Johny Lin return false; 38252bffe176c343075c196c072aa7924de3abdd1b5Johny Lin } 38352bffe176c343075c196c072aa7924de3abdd1b5Johny Lin 3840deb659ab57ad7d9bac1c025cb5dd182946bc9f8Johny Lin sp<IMediaExtractor> extractor = MediaExtractorFactory::Create(dataSource); 38552bffe176c343075c196c072aa7924de3abdd1b5Johny Lin if (extractor == nullptr) { 38652bffe176c343075c196c072aa7924de3abdd1b5Johny Lin fprintf(stderr, "could not create extractor.\n"); 38752bffe176c343075c196c072aa7924de3abdd1b5Johny Lin return false; 38852bffe176c343075c196c072aa7924de3abdd1b5Johny Lin } 38952bffe176c343075c196c072aa7924de3abdd1b5Johny Lin 3909be5270780fda8f9e7e4aff26e10d94a1d47517bJohny Lin std::string expectedMime; 3919be5270780fda8f9e7e4aff26e10d94a1d47517bJohny Lin if (kComponentName == kH264DecoderName) { 3929be5270780fda8f9e7e4aff26e10d94a1d47517bJohny Lin expectedMime = "video/avc"; 3939be5270780fda8f9e7e4aff26e10d94a1d47517bJohny Lin } else if (kComponentName == kVP8DecoderName) { 3949be5270780fda8f9e7e4aff26e10d94a1d47517bJohny Lin expectedMime = "video/x-vnd.on2.vp8"; 39595d0e47610746d8c8444051e42413f6c0d454817Johny Lin } else if (kComponentName == kVP9DecoderName) { 39695d0e47610746d8c8444051e42413f6c0d454817Johny Lin expectedMime = "video/x-vnd.on2.vp9"; 3979be5270780fda8f9e7e4aff26e10d94a1d47517bJohny Lin } else { 3989be5270780fda8f9e7e4aff26e10d94a1d47517bJohny Lin fprintf(stderr, "unrecognized component name: %s\n", kComponentName.c_str()); 3999be5270780fda8f9e7e4aff26e10d94a1d47517bJohny Lin return false; 4009be5270780fda8f9e7e4aff26e10d94a1d47517bJohny Lin } 4019be5270780fda8f9e7e4aff26e10d94a1d47517bJohny Lin 40252bffe176c343075c196c072aa7924de3abdd1b5Johny Lin for (size_t i = 0, numTracks = extractor->countTracks(); i < numTracks; ++i) { 40352bffe176c343075c196c072aa7924de3abdd1b5Johny Lin sp<MetaData> meta = 40452bffe176c343075c196c072aa7924de3abdd1b5Johny Lin extractor->getTrackMetaData(i, MediaExtractor::kIncludeExtensiveMetaData); 40552bffe176c343075c196c072aa7924de3abdd1b5Johny Lin if (meta == nullptr) { 40652bffe176c343075c196c072aa7924de3abdd1b5Johny Lin continue; 40752bffe176c343075c196c072aa7924de3abdd1b5Johny Lin } 408a891f0ea984eb1175467ebe1c0ec086977464a07Johny Lin const char* mime; 40952bffe176c343075c196c072aa7924de3abdd1b5Johny Lin meta->findCString(kKeyMIMEType, &mime); 4109be5270780fda8f9e7e4aff26e10d94a1d47517bJohny Lin if (!strcasecmp(mime, expectedMime.c_str())) { 41152bffe176c343075c196c072aa7924de3abdd1b5Johny Lin *source = extractor->getTrack(i); 41252bffe176c343075c196c072aa7924de3abdd1b5Johny Lin if (*source == nullptr) { 41352bffe176c343075c196c072aa7924de3abdd1b5Johny Lin fprintf(stderr, "It's nullptr track for track %zu.\n", i); 41452bffe176c343075c196c072aa7924de3abdd1b5Johny Lin return false; 41552bffe176c343075c196c072aa7924de3abdd1b5Johny Lin } 41652bffe176c343075c196c072aa7924de3abdd1b5Johny Lin return true; 41752bffe176c343075c196c072aa7924de3abdd1b5Johny Lin } 41852bffe176c343075c196c072aa7924de3abdd1b5Johny Lin } 4199be5270780fda8f9e7e4aff26e10d94a1d47517bJohny Lin fprintf(stderr, "No track found.\n"); 42052bffe176c343075c196c072aa7924de3abdd1b5Johny Lin return false; 42152bffe176c343075c196c072aa7924de3abdd1b5Johny Lin} 42252bffe176c343075c196c072aa7924de3abdd1b5Johny Lin 423a891f0ea984eb1175467ebe1c0ec086977464a07Johny Linstatic void usage(const char* me) { 42452bffe176c343075c196c072aa7924de3abdd1b5Johny Lin fprintf(stderr, "usage: %s [options] [input_filename]...\n", me); 42552bffe176c343075c196c072aa7924de3abdd1b5Johny Lin fprintf(stderr, " -h(elp)\n"); 42652bffe176c343075c196c072aa7924de3abdd1b5Johny Lin} 42752bffe176c343075c196c072aa7924de3abdd1b5Johny Lin 428a891f0ea984eb1175467ebe1c0ec086977464a07Johny Linint main(int argc, char** argv) { 42952bffe176c343075c196c072aa7924de3abdd1b5Johny Lin android::ProcessState::self()->startThreadPool(); 43052bffe176c343075c196c072aa7924de3abdd1b5Johny Lin 43152bffe176c343075c196c072aa7924de3abdd1b5Johny Lin int res; 43252bffe176c343075c196c072aa7924de3abdd1b5Johny Lin while ((res = getopt(argc, argv, "h")) >= 0) { 43352bffe176c343075c196c072aa7924de3abdd1b5Johny Lin switch (res) { 434a891f0ea984eb1175467ebe1c0ec086977464a07Johny Lin case 'h': 435a891f0ea984eb1175467ebe1c0ec086977464a07Johny Lin default: { 436a891f0ea984eb1175467ebe1c0ec086977464a07Johny Lin usage(argv[0]); 437a891f0ea984eb1175467ebe1c0ec086977464a07Johny Lin exit(1); 438a891f0ea984eb1175467ebe1c0ec086977464a07Johny Lin break; 439a891f0ea984eb1175467ebe1c0ec086977464a07Johny Lin } 44052bffe176c343075c196c072aa7924de3abdd1b5Johny Lin } 44152bffe176c343075c196c072aa7924de3abdd1b5Johny Lin } 44252bffe176c343075c196c072aa7924de3abdd1b5Johny Lin 44352bffe176c343075c196c072aa7924de3abdd1b5Johny Lin argc -= optind; 44452bffe176c343075c196c072aa7924de3abdd1b5Johny Lin argv += optind; 44552bffe176c343075c196c072aa7924de3abdd1b5Johny Lin 44652bffe176c343075c196c072aa7924de3abdd1b5Johny Lin if (argc < 1) { 44752bffe176c343075c196c072aa7924de3abdd1b5Johny Lin fprintf(stderr, "No input file specified\n"); 44852bffe176c343075c196c072aa7924de3abdd1b5Johny Lin return 1; 44952bffe176c343075c196c072aa7924de3abdd1b5Johny Lin } 45052bffe176c343075c196c072aa7924de3abdd1b5Johny Lin 45152bffe176c343075c196c072aa7924de3abdd1b5Johny Lin SimplePlayer player; 45252bffe176c343075c196c072aa7924de3abdd1b5Johny Lin 45352bffe176c343075c196c072aa7924de3abdd1b5Johny Lin for (int k = 0; k < argc; ++k) { 45452bffe176c343075c196c072aa7924de3abdd1b5Johny Lin sp<IMediaSource> mediaSource; 45552bffe176c343075c196c072aa7924de3abdd1b5Johny Lin if (!getMediaSourceFromFile(argv[k], &mediaSource)) { 45652bffe176c343075c196c072aa7924de3abdd1b5Johny Lin fprintf(stderr, "Unable to get media source from file: %s\n", argv[k]); 45752bffe176c343075c196c072aa7924de3abdd1b5Johny Lin return -1; 45852bffe176c343075c196c072aa7924de3abdd1b5Johny Lin } 45952bffe176c343075c196c072aa7924de3abdd1b5Johny Lin if (player.play(mediaSource) != OK) { 46052bffe176c343075c196c072aa7924de3abdd1b5Johny Lin fprintf(stderr, "Player failed to play media source: %s\n", argv[k]); 46152bffe176c343075c196c072aa7924de3abdd1b5Johny Lin return -1; 46252bffe176c343075c196c072aa7924de3abdd1b5Johny Lin } 46352bffe176c343075c196c072aa7924de3abdd1b5Johny Lin } 46452bffe176c343075c196c072aa7924de3abdd1b5Johny Lin 46552bffe176c343075c196c072aa7924de3abdd1b5Johny Lin return 0; 46652bffe176c343075c196c072aa7924de3abdd1b5Johny Lin} 467