codec2.cpp revision cd56fe7ad767762950d20582daf9d646d916f10b
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
108a2118e656587a22ebf4c1a4c23874fea45062b4Johny Lin#ifdef ANDROID_VERSION_NYC
118a2118e656587a22ebf4c1a4c23874fea45062b4Johny Lin// Get allocators from NYC-specific implementation
12c6d0b6f730a74e2d10a414ba5b368fb7cd87f78dJohny Lin#include <C2VDASupport.h>
138a2118e656587a22ebf4c1a4c23874fea45062b4Johny Lin#else
148a2118e656587a22ebf4c1a4c23874fea45062b4Johny Lin// Get allocators from framework
158a2118e656587a22ebf4c1a4c23874fea45062b4Johny Lin#include <C2PlatformSupport.h>
168a2118e656587a22ebf4c1a4c23874fea45062b4Johny Lin#endif
17c6d0b6f730a74e2d10a414ba5b368fb7cd87f78dJohny Lin
1852bffe176c343075c196c072aa7924de3abdd1b5Johny Lin#include <C2Buffer.h>
1952bffe176c343075c196c072aa7924de3abdd1b5Johny Lin#include <C2BufferPriv.h>
2052bffe176c343075c196c072aa7924de3abdd1b5Johny Lin#include <C2Component.h>
2152bffe176c343075c196c072aa7924de3abdd1b5Johny Lin#include <C2Work.h>
2252bffe176c343075c196c072aa7924de3abdd1b5Johny Lin
2352bffe176c343075c196c072aa7924de3abdd1b5Johny Lin#include <binder/IServiceManager.h>
2452bffe176c343075c196c072aa7924de3abdd1b5Johny Lin#include <binder/ProcessState.h>
25c6d0b6f730a74e2d10a414ba5b368fb7cd87f78dJohny Lin#include <gui/GLConsumer.h>
26c6d0b6f730a74e2d10a414ba5b368fb7cd87f78dJohny Lin#include <gui/IProducerListener.h>
27c6d0b6f730a74e2d10a414ba5b368fb7cd87f78dJohny Lin#include <gui/Surface.h>
28c6d0b6f730a74e2d10a414ba5b368fb7cd87f78dJohny Lin#include <gui/SurfaceComposerClient.h>
2952bffe176c343075c196c072aa7924de3abdd1b5Johny Lin#include <media/ICrypto.h>
3052bffe176c343075c196c072aa7924de3abdd1b5Johny Lin#include <media/IMediaHTTPService.h>
3152bffe176c343075c196c072aa7924de3abdd1b5Johny Lin#include <media/stagefright/MediaDefs.h>
3252bffe176c343075c196c072aa7924de3abdd1b5Johny Lin#include <media/stagefright/MediaErrors.h>
3352bffe176c343075c196c072aa7924de3abdd1b5Johny Lin#include <media/stagefright/MetaData.h>
3452bffe176c343075c196c072aa7924de3abdd1b5Johny Lin#include <media/stagefright/Utils.h>
35a891f0ea984eb1175467ebe1c0ec086977464a07Johny Lin#include <media/stagefright/foundation/ABuffer.h>
36a891f0ea984eb1175467ebe1c0ec086977464a07Johny Lin#include <media/stagefright/foundation/ALooper.h>
37a891f0ea984eb1175467ebe1c0ec086977464a07Johny Lin#include <media/stagefright/foundation/AMessage.h>
38a891f0ea984eb1175467ebe1c0ec086977464a07Johny Lin#include <media/stagefright/foundation/AUtils.h>
390deb659ab57ad7d9bac1c025cb5dd182946bc9f8Johny Lin#ifdef ANDROID_VERSION_NYC
400deb659ab57ad7d9bac1c025cb5dd182946bc9f8Johny Lin#include <media/stagefright/DataSource.h>
410deb659ab57ad7d9bac1c025cb5dd182946bc9f8Johny Lin#include <media/stagefright/MediaExtractor.h>
420deb659ab57ad7d9bac1c025cb5dd182946bc9f8Johny Lin#include <media/stagefright/MediaSource.h>
430deb659ab57ad7d9bac1c025cb5dd182946bc9f8Johny Lin#else
440deb659ab57ad7d9bac1c025cb5dd182946bc9f8Johny Lin#include <media/DataSource.h>
450deb659ab57ad7d9bac1c025cb5dd182946bc9f8Johny Lin#include <media/MediaExtractor.h>
460deb659ab57ad7d9bac1c025cb5dd182946bc9f8Johny Lin#include <media/MediaSource.h>
470deb659ab57ad7d9bac1c025cb5dd182946bc9f8Johny Lin#include <media/stagefright/DataSourceFactory.h>
480deb659ab57ad7d9bac1c025cb5dd182946bc9f8Johny Lin#include <media/stagefright/MediaExtractorFactory.h>
490deb659ab57ad7d9bac1c025cb5dd182946bc9f8Johny Lin#endif
5052bffe176c343075c196c072aa7924de3abdd1b5Johny Lin
51c6d0b6f730a74e2d10a414ba5b368fb7cd87f78dJohny Lin#include <fcntl.h>
52c6d0b6f730a74e2d10a414ba5b368fb7cd87f78dJohny Lin#include <inttypes.h>
53c6d0b6f730a74e2d10a414ba5b368fb7cd87f78dJohny Lin#include <stdlib.h>
54c6d0b6f730a74e2d10a414ba5b368fb7cd87f78dJohny Lin#include <string.h>
55c6d0b6f730a74e2d10a414ba5b368fb7cd87f78dJohny Lin#include <sys/stat.h>
56c6d0b6f730a74e2d10a414ba5b368fb7cd87f78dJohny Lin#include <sys/time.h>
57c6d0b6f730a74e2d10a414ba5b368fb7cd87f78dJohny Lin#include <sys/types.h>
58c6d0b6f730a74e2d10a414ba5b368fb7cd87f78dJohny Lin#include <thread>
5952bffe176c343075c196c072aa7924de3abdd1b5Johny Lin
6052bffe176c343075c196c072aa7924de3abdd1b5Johny Linusing namespace android;
6152bffe176c343075c196c072aa7924de3abdd1b5Johny Linusing namespace std::chrono_literals;
6252bffe176c343075c196c072aa7924de3abdd1b5Johny Lin
6352bffe176c343075c196c072aa7924de3abdd1b5Johny Linnamespace {
6452bffe176c343075c196c072aa7924de3abdd1b5Johny Lin
65226ec4605d573878f8062524e271daf2732a650aPin-chih Linconst std::string kH264DecoderName = "c2.vda.avc.decoder";
66226ec4605d573878f8062524e271daf2732a650aPin-chih Linconst std::string kVP8DecoderName = "c2.vda.vp8.decoder";
67226ec4605d573878f8062524e271daf2732a650aPin-chih Linconst std::string kVP9DecoderName = "c2.vda.vp9.decoder";
689be5270780fda8f9e7e4aff26e10d94a1d47517bJohny Lin
6952bffe176c343075c196c072aa7924de3abdd1b5Johny Linconst int kWidth = 416;
7052bffe176c343075c196c072aa7924de3abdd1b5Johny Linconst int kHeight = 240;  // BigBuckBunny.mp4
7152bffe176c343075c196c072aa7924de3abdd1b5Johny Lin//const int kWidth = 560;
7252bffe176c343075c196c072aa7924de3abdd1b5Johny Lin//const int kHeight = 320;  // small.mp4
739be5270780fda8f9e7e4aff26e10d94a1d47517bJohny Linconst std::string kComponentName = kH264DecoderName;
7452bffe176c343075c196c072aa7924de3abdd1b5Johny Lin
7552bffe176c343075c196c072aa7924de3abdd1b5Johny Linclass C2VDALinearBuffer : public C2Buffer {
7652bffe176c343075c196c072aa7924de3abdd1b5Johny Linpublic:
7752bffe176c343075c196c072aa7924de3abdd1b5Johny Lin    explicit C2VDALinearBuffer(const std::shared_ptr<C2LinearBlock>& block)
7893e4f225df19e43300fb3b29e6f95b4e63daa4c7Lajos Molnar          : C2Buffer({block->share(block->offset(), block->size(), ::C2Fence())}) {}
7952bffe176c343075c196c072aa7924de3abdd1b5Johny Lin};
8052bffe176c343075c196c072aa7924de3abdd1b5Johny Lin
8152bffe176c343075c196c072aa7924de3abdd1b5Johny Linclass Listener;
8252bffe176c343075c196c072aa7924de3abdd1b5Johny Lin
8352bffe176c343075c196c072aa7924de3abdd1b5Johny Linclass SimplePlayer {
8452bffe176c343075c196c072aa7924de3abdd1b5Johny Linpublic:
8552bffe176c343075c196c072aa7924de3abdd1b5Johny Lin    SimplePlayer();
8652bffe176c343075c196c072aa7924de3abdd1b5Johny Lin    ~SimplePlayer();
8752bffe176c343075c196c072aa7924de3abdd1b5Johny Lin
8852bffe176c343075c196c072aa7924de3abdd1b5Johny Lin    void onWorkDone(std::weak_ptr<C2Component> component,
89fa7abe5b3914c3041874b360f511b132e6bf1116Lajos Molnar                    std::list<std::unique_ptr<C2Work>> workItems);
9052bffe176c343075c196c072aa7924de3abdd1b5Johny Lin    void onTripped(std::weak_ptr<C2Component> component,
9152bffe176c343075c196c072aa7924de3abdd1b5Johny Lin                   std::vector<std::shared_ptr<C2SettingResult>> settingResult);
9252bffe176c343075c196c072aa7924de3abdd1b5Johny Lin    void onError(std::weak_ptr<C2Component> component, uint32_t errorCode);
9352bffe176c343075c196c072aa7924de3abdd1b5Johny Lin
94a891f0ea984eb1175467ebe1c0ec086977464a07Johny Lin    status_t play(const sp<IMediaSource>& source);
9552bffe176c343075c196c072aa7924de3abdd1b5Johny Lin
9652bffe176c343075c196c072aa7924de3abdd1b5Johny Linprivate:
9752bffe176c343075c196c072aa7924de3abdd1b5Johny Lin    typedef std::unique_lock<std::mutex> ULock;
9852bffe176c343075c196c072aa7924de3abdd1b5Johny Lin
9952bffe176c343075c196c072aa7924de3abdd1b5Johny Lin    enum {
10052bffe176c343075c196c072aa7924de3abdd1b5Johny Lin        kInputBufferCount = 8,
10152bffe176c343075c196c072aa7924de3abdd1b5Johny Lin        kDefaultInputBufferSize = 1024 * 1024,
10252bffe176c343075c196c072aa7924de3abdd1b5Johny Lin    };
10352bffe176c343075c196c072aa7924de3abdd1b5Johny Lin
10452bffe176c343075c196c072aa7924de3abdd1b5Johny Lin    std::shared_ptr<Listener> mListener;
10552bffe176c343075c196c072aa7924de3abdd1b5Johny Lin
10652bffe176c343075c196c072aa7924de3abdd1b5Johny Lin    sp<IProducerListener> mProducerListener;
10752bffe176c343075c196c072aa7924de3abdd1b5Johny Lin
10852bffe176c343075c196c072aa7924de3abdd1b5Johny Lin    // Allocators
10952bffe176c343075c196c072aa7924de3abdd1b5Johny Lin    std::shared_ptr<C2Allocator> mLinearAlloc;
11052bffe176c343075c196c072aa7924de3abdd1b5Johny Lin    std::shared_ptr<C2BlockPool> mLinearBlockPool;
11152bffe176c343075c196c072aa7924de3abdd1b5Johny Lin
11252bffe176c343075c196c072aa7924de3abdd1b5Johny Lin    std::mutex mQueueLock;
11352bffe176c343075c196c072aa7924de3abdd1b5Johny Lin    std::condition_variable mQueueCondition;
11452bffe176c343075c196c072aa7924de3abdd1b5Johny Lin    std::list<std::unique_ptr<C2Work>> mWorkQueue;
11552bffe176c343075c196c072aa7924de3abdd1b5Johny Lin
11652bffe176c343075c196c072aa7924de3abdd1b5Johny Lin    std::mutex mProcessedLock;
11752bffe176c343075c196c072aa7924de3abdd1b5Johny Lin    std::condition_variable mProcessedCondition;
11852bffe176c343075c196c072aa7924de3abdd1b5Johny Lin    std::list<std::unique_ptr<C2Work>> mProcessedWork;
11952bffe176c343075c196c072aa7924de3abdd1b5Johny Lin
12052bffe176c343075c196c072aa7924de3abdd1b5Johny Lin    sp<Surface> mSurface;
12152bffe176c343075c196c072aa7924de3abdd1b5Johny Lin    sp<SurfaceComposerClient> mComposerClient;
12252bffe176c343075c196c072aa7924de3abdd1b5Johny Lin    sp<SurfaceControl> mControl;
12352bffe176c343075c196c072aa7924de3abdd1b5Johny Lin};
12452bffe176c343075c196c072aa7924de3abdd1b5Johny Lin
12552bffe176c343075c196c072aa7924de3abdd1b5Johny Linclass Listener : public C2Component::Listener {
12652bffe176c343075c196c072aa7924de3abdd1b5Johny Linpublic:
127a891f0ea984eb1175467ebe1c0ec086977464a07Johny Lin    explicit Listener(SimplePlayer* thiz) : mThis(thiz) {}
12852bffe176c343075c196c072aa7924de3abdd1b5Johny Lin    virtual ~Listener() = default;
12952bffe176c343075c196c072aa7924de3abdd1b5Johny Lin
13052bffe176c343075c196c072aa7924de3abdd1b5Johny Lin    virtual void onWorkDone_nb(std::weak_ptr<C2Component> component,
131fa7abe5b3914c3041874b360f511b132e6bf1116Lajos Molnar                               std::list<std::unique_ptr<C2Work>> workItems) override {
13252bffe176c343075c196c072aa7924de3abdd1b5Johny Lin        mThis->onWorkDone(component, std::move(workItems));
13352bffe176c343075c196c072aa7924de3abdd1b5Johny Lin    }
13452bffe176c343075c196c072aa7924de3abdd1b5Johny Lin
13552bffe176c343075c196c072aa7924de3abdd1b5Johny Lin    virtual void onTripped_nb(
13652bffe176c343075c196c072aa7924de3abdd1b5Johny Lin            std::weak_ptr<C2Component> component,
13752bffe176c343075c196c072aa7924de3abdd1b5Johny Lin            std::vector<std::shared_ptr<C2SettingResult>> settingResult) override {
13852bffe176c343075c196c072aa7924de3abdd1b5Johny Lin        mThis->onTripped(component, settingResult);
13952bffe176c343075c196c072aa7924de3abdd1b5Johny Lin    }
14052bffe176c343075c196c072aa7924de3abdd1b5Johny Lin
141a891f0ea984eb1175467ebe1c0ec086977464a07Johny Lin    virtual void onError_nb(std::weak_ptr<C2Component> component, uint32_t errorCode) override {
14252bffe176c343075c196c072aa7924de3abdd1b5Johny Lin        mThis->onError(component, errorCode);
14352bffe176c343075c196c072aa7924de3abdd1b5Johny Lin    }
14452bffe176c343075c196c072aa7924de3abdd1b5Johny Lin
14552bffe176c343075c196c072aa7924de3abdd1b5Johny Linprivate:
146a891f0ea984eb1175467ebe1c0ec086977464a07Johny Lin    SimplePlayer* const mThis;
14752bffe176c343075c196c072aa7924de3abdd1b5Johny Lin};
14852bffe176c343075c196c072aa7924de3abdd1b5Johny Lin
14952bffe176c343075c196c072aa7924de3abdd1b5Johny LinSimplePlayer::SimplePlayer()
150a891f0ea984eb1175467ebe1c0ec086977464a07Johny Lin      : mListener(new Listener(this)),
151a891f0ea984eb1175467ebe1c0ec086977464a07Johny Lin        mProducerListener(new DummyProducerListener),
152a891f0ea984eb1175467ebe1c0ec086977464a07Johny Lin        mComposerClient(new SurfaceComposerClient) {
15352bffe176c343075c196c072aa7924de3abdd1b5Johny Lin    CHECK_EQ(mComposerClient->initCheck(), OK);
15452bffe176c343075c196c072aa7924de3abdd1b5Johny Lin
1558a2118e656587a22ebf4c1a4c23874fea45062b4Johny Lin#ifdef ANDROID_VERSION_NYC
1568a2118e656587a22ebf4c1a4c23874fea45062b4Johny Lin    std::shared_ptr<C2AllocatorStore> store = GetCodec2VDAAllocatorStore();
1578a2118e656587a22ebf4c1a4c23874fea45062b4Johny Lin#else
1588a2118e656587a22ebf4c1a4c23874fea45062b4Johny Lin    std::shared_ptr<C2AllocatorStore> store = GetCodec2PlatformAllocatorStore();
1598a2118e656587a22ebf4c1a4c23874fea45062b4Johny Lin#endif
16052bffe176c343075c196c072aa7924de3abdd1b5Johny Lin    CHECK_EQ(store->fetchAllocator(C2AllocatorStore::DEFAULT_LINEAR, &mLinearAlloc), C2_OK);
16152bffe176c343075c196c072aa7924de3abdd1b5Johny Lin
16252bffe176c343075c196c072aa7924de3abdd1b5Johny Lin    mLinearBlockPool = std::make_shared<C2BasicLinearBlockPool>(mLinearAlloc);
16352bffe176c343075c196c072aa7924de3abdd1b5Johny Lin
164a891f0ea984eb1175467ebe1c0ec086977464a07Johny Lin    mControl = mComposerClient->createSurface(String8("A Surface"), kWidth, kHeight,
165a891f0ea984eb1175467ebe1c0ec086977464a07Johny Lin                                              HAL_PIXEL_FORMAT_YV12);
16652bffe176c343075c196c072aa7924de3abdd1b5Johny Lin
16752bffe176c343075c196c072aa7924de3abdd1b5Johny Lin    CHECK(mControl != nullptr);
16852bffe176c343075c196c072aa7924de3abdd1b5Johny Lin    CHECK(mControl->isValid());
16952bffe176c343075c196c072aa7924de3abdd1b5Johny Lin
1700deb659ab57ad7d9bac1c025cb5dd182946bc9f8Johny Lin#ifdef ANDROID_VERSION_NYC
17152bffe176c343075c196c072aa7924de3abdd1b5Johny Lin    SurfaceComposerClient::openGlobalTransaction();
17252bffe176c343075c196c072aa7924de3abdd1b5Johny Lin    CHECK_EQ(mControl->setLayer(INT_MAX), OK);
17352bffe176c343075c196c072aa7924de3abdd1b5Johny Lin    CHECK_EQ(mControl->show(), OK);
17452bffe176c343075c196c072aa7924de3abdd1b5Johny Lin    SurfaceComposerClient::closeGlobalTransaction();
1750deb659ab57ad7d9bac1c025cb5dd182946bc9f8Johny Lin#else
1760deb659ab57ad7d9bac1c025cb5dd182946bc9f8Johny Lin    SurfaceComposerClient::Transaction{}.setLayer(mControl, INT_MAX).show(mControl).apply();
1770deb659ab57ad7d9bac1c025cb5dd182946bc9f8Johny Lin#endif
17852bffe176c343075c196c072aa7924de3abdd1b5Johny Lin
17952bffe176c343075c196c072aa7924de3abdd1b5Johny Lin    mSurface = mControl->getSurface();
18052bffe176c343075c196c072aa7924de3abdd1b5Johny Lin    CHECK(mSurface != nullptr);
18152bffe176c343075c196c072aa7924de3abdd1b5Johny Lin    mSurface->connect(NATIVE_WINDOW_API_CPU, mProducerListener);
18252bffe176c343075c196c072aa7924de3abdd1b5Johny Lin}
18352bffe176c343075c196c072aa7924de3abdd1b5Johny Lin
18452bffe176c343075c196c072aa7924de3abdd1b5Johny LinSimplePlayer::~SimplePlayer() {
18552bffe176c343075c196c072aa7924de3abdd1b5Johny Lin    mComposerClient->dispose();
18652bffe176c343075c196c072aa7924de3abdd1b5Johny Lin}
18752bffe176c343075c196c072aa7924de3abdd1b5Johny Lin
188a891f0ea984eb1175467ebe1c0ec086977464a07Johny Linvoid SimplePlayer::onWorkDone(std::weak_ptr<C2Component> component,
189fa7abe5b3914c3041874b360f511b132e6bf1116Lajos Molnar                              std::list<std::unique_ptr<C2Work>> workItems) {
190a891f0ea984eb1175467ebe1c0ec086977464a07Johny Lin    (void)component;
19152bffe176c343075c196c072aa7924de3abdd1b5Johny Lin    ULock l(mProcessedLock);
192a891f0ea984eb1175467ebe1c0ec086977464a07Johny Lin    for (auto& item : workItems) {
19352bffe176c343075c196c072aa7924de3abdd1b5Johny Lin        mProcessedWork.emplace_back(std::move(item));
19452bffe176c343075c196c072aa7924de3abdd1b5Johny Lin    }
19552bffe176c343075c196c072aa7924de3abdd1b5Johny Lin    mProcessedCondition.notify_all();
19652bffe176c343075c196c072aa7924de3abdd1b5Johny Lin}
19752bffe176c343075c196c072aa7924de3abdd1b5Johny Lin
198a891f0ea984eb1175467ebe1c0ec086977464a07Johny Linvoid SimplePlayer::onTripped(std::weak_ptr<C2Component> component,
199a891f0ea984eb1175467ebe1c0ec086977464a07Johny Lin                             std::vector<std::shared_ptr<C2SettingResult>> settingResult) {
200a891f0ea984eb1175467ebe1c0ec086977464a07Johny Lin    (void)component;
201a891f0ea984eb1175467ebe1c0ec086977464a07Johny Lin    (void)settingResult;
20252bffe176c343075c196c072aa7924de3abdd1b5Johny Lin    // TODO
20352bffe176c343075c196c072aa7924de3abdd1b5Johny Lin}
20452bffe176c343075c196c072aa7924de3abdd1b5Johny Lin
20552bffe176c343075c196c072aa7924de3abdd1b5Johny Linvoid SimplePlayer::onError(std::weak_ptr<C2Component> component, uint32_t errorCode) {
206a891f0ea984eb1175467ebe1c0ec086977464a07Johny Lin    (void)component;
207a891f0ea984eb1175467ebe1c0ec086977464a07Johny Lin    (void)errorCode;
20852bffe176c343075c196c072aa7924de3abdd1b5Johny Lin    // TODO
20952bffe176c343075c196c072aa7924de3abdd1b5Johny Lin}
21052bffe176c343075c196c072aa7924de3abdd1b5Johny Lin
2110deb659ab57ad7d9bac1c025cb5dd182946bc9f8Johny Lin#ifdef ANDROID_VERSION_NYC
21252bffe176c343075c196c072aa7924de3abdd1b5Johny Lin// TODO(johnylin): remove this when we move the development env to P
21352bffe176c343075c196c072aa7924de3abdd1b5Johny Lin// from master: system/core/libcutils/native_handle.c
21452bffe176c343075c196c072aa7924de3abdd1b5Johny Linnative_handle_t* native_handle_clone(const native_handle_t* handle) {
21552bffe176c343075c196c072aa7924de3abdd1b5Johny Lin    native_handle_t* clone = native_handle_create(handle->numFds, handle->numInts);
21652bffe176c343075c196c072aa7924de3abdd1b5Johny Lin    if (clone == nullptr) return nullptr;
21752bffe176c343075c196c072aa7924de3abdd1b5Johny Lin    for (int i = 0; i < handle->numFds; i++) {
21852bffe176c343075c196c072aa7924de3abdd1b5Johny Lin        clone->data[i] = dup(handle->data[i]);
21952bffe176c343075c196c072aa7924de3abdd1b5Johny Lin        ALOGV("clone handle fd: %d", clone->data[i]);
22052bffe176c343075c196c072aa7924de3abdd1b5Johny Lin        if (clone->data[i] == -1) {
22152bffe176c343075c196c072aa7924de3abdd1b5Johny Lin            clone->numFds = i;
22252bffe176c343075c196c072aa7924de3abdd1b5Johny Lin            native_handle_close(clone);
22352bffe176c343075c196c072aa7924de3abdd1b5Johny Lin            native_handle_delete(clone);
22452bffe176c343075c196c072aa7924de3abdd1b5Johny Lin            return nullptr;
22552bffe176c343075c196c072aa7924de3abdd1b5Johny Lin        }
22652bffe176c343075c196c072aa7924de3abdd1b5Johny Lin    }
22752bffe176c343075c196c072aa7924de3abdd1b5Johny Lin    memcpy(&clone->data[handle->numFds], &handle->data[handle->numFds],
22852bffe176c343075c196c072aa7924de3abdd1b5Johny Lin           sizeof(int) * handle->numInts);
22952bffe176c343075c196c072aa7924de3abdd1b5Johny Lin    return clone;
23052bffe176c343075c196c072aa7924de3abdd1b5Johny Lin}
2310deb659ab57ad7d9bac1c025cb5dd182946bc9f8Johny Lin#endif
23252bffe176c343075c196c072aa7924de3abdd1b5Johny Lin
233a891f0ea984eb1175467ebe1c0ec086977464a07Johny Linstatus_t SimplePlayer::play(const sp<IMediaSource>& source) {
2349be5270780fda8f9e7e4aff26e10d94a1d47517bJohny Lin    std::deque<sp<ABuffer>> csds;
2359be5270780fda8f9e7e4aff26e10d94a1d47517bJohny Lin    if (kComponentName == kH264DecoderName) {
2369be5270780fda8f9e7e4aff26e10d94a1d47517bJohny Lin        sp<AMessage> format;
237a891f0ea984eb1175467ebe1c0ec086977464a07Johny Lin        (void)convertMetaDataToMessage(source->getFormat(), &format);
2389be5270780fda8f9e7e4aff26e10d94a1d47517bJohny Lin
2399be5270780fda8f9e7e4aff26e10d94a1d47517bJohny Lin        csds.resize(2);
2409be5270780fda8f9e7e4aff26e10d94a1d47517bJohny Lin        format->findBuffer("csd-0", &csds[0]);
2419be5270780fda8f9e7e4aff26e10d94a1d47517bJohny Lin        format->findBuffer("csd-1", &csds[1]);
2429be5270780fda8f9e7e4aff26e10d94a1d47517bJohny Lin    }
24352bffe176c343075c196c072aa7924de3abdd1b5Johny Lin
24452bffe176c343075c196c072aa7924de3abdd1b5Johny Lin    status_t err = source->start();
24552bffe176c343075c196c072aa7924de3abdd1b5Johny Lin
24652bffe176c343075c196c072aa7924de3abdd1b5Johny Lin    if (err != OK) {
24752bffe176c343075c196c072aa7924de3abdd1b5Johny Lin        ALOGE("source returned error %d (0x%08x)", err, err);
24852bffe176c343075c196c072aa7924de3abdd1b5Johny Lin        fprintf(stderr, "source returned error %d (0x%08x)\n", err, err);
24952bffe176c343075c196c072aa7924de3abdd1b5Johny Lin        return err;
25052bffe176c343075c196c072aa7924de3abdd1b5Johny Lin    }
25152bffe176c343075c196c072aa7924de3abdd1b5Johny Lin
2529be5270780fda8f9e7e4aff26e10d94a1d47517bJohny Lin    std::shared_ptr<C2Component> component(std::make_shared<C2VDAComponent>(kComponentName, 0));
253a891f0ea984eb1175467ebe1c0ec086977464a07Johny Lin    component->setListener_vb(mListener, C2_DONT_BLOCK);
25452bffe176c343075c196c072aa7924de3abdd1b5Johny Lin    std::unique_ptr<C2PortBlockPoolsTuning::output> pools =
25593e4f225df19e43300fb3b29e6f95b4e63daa4c7Lajos Molnar            C2PortBlockPoolsTuning::output::AllocUnique(
256a891f0ea984eb1175467ebe1c0ec086977464a07Johny Lin                    {static_cast<uint64_t>(C2BlockPool::BASIC_GRAPHIC)});
25752bffe176c343075c196c072aa7924de3abdd1b5Johny Lin    std::vector<std::unique_ptr<C2SettingResult>> result;
2582737fb61ca7ecd786b160ec5d79e3eaa48135606Lajos Molnar    (void)component->intf()->config_vb({pools.get()}, C2_DONT_BLOCK, &result);
25952bffe176c343075c196c072aa7924de3abdd1b5Johny Lin    component->start();
26052bffe176c343075c196c072aa7924de3abdd1b5Johny Lin
26152bffe176c343075c196c072aa7924de3abdd1b5Johny Lin    mProcessedWork.clear();
26252bffe176c343075c196c072aa7924de3abdd1b5Johny Lin    for (int i = 0; i < kInputBufferCount; ++i) {
26352bffe176c343075c196c072aa7924de3abdd1b5Johny Lin        mWorkQueue.emplace_back(new C2Work);
26452bffe176c343075c196c072aa7924de3abdd1b5Johny Lin    }
26552bffe176c343075c196c072aa7924de3abdd1b5Johny Lin
26652bffe176c343075c196c072aa7924de3abdd1b5Johny Lin    std::atomic_bool running(true);
26752bffe176c343075c196c072aa7924de3abdd1b5Johny Lin    std::thread surfaceThread([this, &running]() {
268a891f0ea984eb1175467ebe1c0ec086977464a07Johny Lin        const sp<IGraphicBufferProducer>& igbp = mSurface->getIGraphicBufferProducer();
26952bffe176c343075c196c072aa7924de3abdd1b5Johny Lin        std::vector<std::shared_ptr<C2Buffer>> pendingDisplayBuffers;
27052bffe176c343075c196c072aa7924de3abdd1b5Johny Lin        pendingDisplayBuffers.resize(BufferQueue::NUM_BUFFER_SLOTS);
27152bffe176c343075c196c072aa7924de3abdd1b5Johny Lin        while (running) {
27252bffe176c343075c196c072aa7924de3abdd1b5Johny Lin            std::unique_ptr<C2Work> work;
27352bffe176c343075c196c072aa7924de3abdd1b5Johny Lin            {
27452bffe176c343075c196c072aa7924de3abdd1b5Johny Lin                ULock l(mProcessedLock);
27552bffe176c343075c196c072aa7924de3abdd1b5Johny Lin                if (mProcessedWork.empty()) {
27652bffe176c343075c196c072aa7924de3abdd1b5Johny Lin                    mProcessedCondition.wait_for(l, 100ms);
27752bffe176c343075c196c072aa7924de3abdd1b5Johny Lin                    if (mProcessedWork.empty()) {
27852bffe176c343075c196c072aa7924de3abdd1b5Johny Lin                        continue;
27952bffe176c343075c196c072aa7924de3abdd1b5Johny Lin                    }
28052bffe176c343075c196c072aa7924de3abdd1b5Johny Lin                }
28152bffe176c343075c196c072aa7924de3abdd1b5Johny Lin                work = std::move(mProcessedWork.front());
28252bffe176c343075c196c072aa7924de3abdd1b5Johny Lin                mProcessedWork.pop_front();
28352bffe176c343075c196c072aa7924de3abdd1b5Johny Lin            }
28452bffe176c343075c196c072aa7924de3abdd1b5Johny Lin
2853760d5fdd7e60b68ed599d7322e2599efe7a13c9Johny Lin            CHECK_EQ(work->worklets.size(), 1u);
2863760d5fdd7e60b68ed599d7322e2599efe7a13c9Johny Lin            if (work->worklets.front()->output.buffers.size() == 1u) {
28752bffe176c343075c196c072aa7924de3abdd1b5Johny Lin                int slot;
28852bffe176c343075c196c072aa7924de3abdd1b5Johny Lin                sp<Fence> fence;
28952bffe176c343075c196c072aa7924de3abdd1b5Johny Lin                std::shared_ptr<C2Buffer> output = work->worklets.front()->output.buffers[0];
29052bffe176c343075c196c072aa7924de3abdd1b5Johny Lin                C2ConstGraphicBlock graphic_block = output->data().graphicBlocks().front();
29152bffe176c343075c196c072aa7924de3abdd1b5Johny Lin
2920deb659ab57ad7d9bac1c025cb5dd182946bc9f8Johny Lin#ifdef ANDROID_VERSION_NYC
29352bffe176c343075c196c072aa7924de3abdd1b5Johny Lin                // Create GraphicBuffer from cloning native_handle
29452bffe176c343075c196c072aa7924de3abdd1b5Johny Lin                native_handle_t* cloneHandle = native_handle_clone(graphic_block.handle());
29552bffe176c343075c196c072aa7924de3abdd1b5Johny Lin                sp<GraphicBuffer> buffer = new GraphicBuffer(
296a891f0ea984eb1175467ebe1c0ec086977464a07Johny Lin                        graphic_block.width(), graphic_block.height(),
297a891f0ea984eb1175467ebe1c0ec086977464a07Johny Lin                        HAL_PIXEL_FORMAT_YCbCr_420_888, GRALLOC_USAGE_SW_READ_OFTEN,
298a891f0ea984eb1175467ebe1c0ec086977464a07Johny Lin                        graphic_block.width(), cloneHandle, false);
2990deb659ab57ad7d9bac1c025cb5dd182946bc9f8Johny Lin#else
3000deb659ab57ad7d9bac1c025cb5dd182946bc9f8Johny Lin                sp<GraphicBuffer> buffer(new GraphicBuffer(
3010deb659ab57ad7d9bac1c025cb5dd182946bc9f8Johny Lin                        graphic_block.handle(), GraphicBuffer::CLONE_HANDLE, graphic_block.width(),
3020deb659ab57ad7d9bac1c025cb5dd182946bc9f8Johny Lin                        graphic_block.height(), HAL_PIXEL_FORMAT_YCbCr_420_888, 1 /* layerCount */,
3030deb659ab57ad7d9bac1c025cb5dd182946bc9f8Johny Lin                        GRALLOC_USAGE_SW_READ_OFTEN, graphic_block.width()));
3040deb659ab57ad7d9bac1c025cb5dd182946bc9f8Johny Lin#endif
30552bffe176c343075c196c072aa7924de3abdd1b5Johny Lin
30652bffe176c343075c196c072aa7924de3abdd1b5Johny Lin                CHECK_EQ(igbp->attachBuffer(&slot, buffer), OK);
30752bffe176c343075c196c072aa7924de3abdd1b5Johny Lin                ALOGV("attachBuffer slot=%d ts=%lld", slot,
3082a2b90179d72e158c74982599752c92aac9029deLajos Molnar                      (work->worklets.front()->output.ordinal.timestamp * 1000ll).peekll());
30952bffe176c343075c196c072aa7924de3abdd1b5Johny Lin
31052bffe176c343075c196c072aa7924de3abdd1b5Johny Lin                IGraphicBufferProducer::QueueBufferInput qbi(
3112a2b90179d72e158c74982599752c92aac9029deLajos Molnar                        (work->worklets.front()->output.ordinal.timestamp * 1000ll).peekll(), false,
312a891f0ea984eb1175467ebe1c0ec086977464a07Johny Lin                        HAL_DATASPACE_UNKNOWN, Rect(graphic_block.width(), graphic_block.height()),
313a891f0ea984eb1175467ebe1c0ec086977464a07Johny Lin                        NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW, 0, Fence::NO_FENCE, 0);
31452bffe176c343075c196c072aa7924de3abdd1b5Johny Lin                IGraphicBufferProducer::QueueBufferOutput qbo;
31552bffe176c343075c196c072aa7924de3abdd1b5Johny Lin                CHECK_EQ(igbp->queueBuffer(slot, qbi, &qbo), OK);
31652bffe176c343075c196c072aa7924de3abdd1b5Johny Lin
31752bffe176c343075c196c072aa7924de3abdd1b5Johny Lin                // If the slot is reused then we can make sure the previous graphic buffer is
31852bffe176c343075c196c072aa7924de3abdd1b5Johny Lin                // displayed (consumed), so we could returned the graphic buffer.
31952bffe176c343075c196c072aa7924de3abdd1b5Johny Lin                pendingDisplayBuffers[slot].swap(output);
32052bffe176c343075c196c072aa7924de3abdd1b5Johny Lin
3210deb659ab57ad7d9bac1c025cb5dd182946bc9f8Johny Lin#ifdef ANDROID_VERSION_NYC
32252bffe176c343075c196c072aa7924de3abdd1b5Johny Lin                // Remember to close the cloned handle.
32352bffe176c343075c196c072aa7924de3abdd1b5Johny Lin                native_handle_close(cloneHandle);
32452bffe176c343075c196c072aa7924de3abdd1b5Johny Lin                native_handle_delete(cloneHandle);
3250deb659ab57ad7d9bac1c025cb5dd182946bc9f8Johny Lin#endif
32652bffe176c343075c196c072aa7924de3abdd1b5Johny Lin            }
32752bffe176c343075c196c072aa7924de3abdd1b5Johny Lin
3283760d5fdd7e60b68ed599d7322e2599efe7a13c9Johny Lin            bool eos = work->worklets.front()->output.flags & C2FrameData::FLAG_END_OF_STREAM;
329cd56fe7ad767762950d20582daf9d646d916f10bPin-chih Lin            // input buffer should be reset in component side.
330cd56fe7ad767762950d20582daf9d646d916f10bPin-chih Lin            CHECK_EQ(work->input.buffers.size(), 1u);
331cd56fe7ad767762950d20582daf9d646d916f10bPin-chih Lin            CHECK(work->input.buffers.front() == nullptr);
33252bffe176c343075c196c072aa7924de3abdd1b5Johny Lin            work->worklets.clear();
3332a2b90179d72e158c74982599752c92aac9029deLajos Molnar            work->workletsProcessed = 0;
33452bffe176c343075c196c072aa7924de3abdd1b5Johny Lin
3353760d5fdd7e60b68ed599d7322e2599efe7a13c9Johny Lin            if (eos) {
33652bffe176c343075c196c072aa7924de3abdd1b5Johny Lin                running.store(false);  // stop the thread
33752bffe176c343075c196c072aa7924de3abdd1b5Johny Lin            }
33852bffe176c343075c196c072aa7924de3abdd1b5Johny Lin
33952bffe176c343075c196c072aa7924de3abdd1b5Johny Lin            ULock l(mQueueLock);
34052bffe176c343075c196c072aa7924de3abdd1b5Johny Lin            mWorkQueue.emplace_back(std::move(work));
34152bffe176c343075c196c072aa7924de3abdd1b5Johny Lin            mQueueCondition.notify_all();
34252bffe176c343075c196c072aa7924de3abdd1b5Johny Lin        }
34352bffe176c343075c196c072aa7924de3abdd1b5Johny Lin    });
34452bffe176c343075c196c072aa7924de3abdd1b5Johny Lin
34552bffe176c343075c196c072aa7924de3abdd1b5Johny Lin    long numFrames = 0;
34652bffe176c343075c196c072aa7924de3abdd1b5Johny Lin
34752bffe176c343075c196c072aa7924de3abdd1b5Johny Lin    for (;;) {
34852bffe176c343075c196c072aa7924de3abdd1b5Johny Lin        size_t size = 0u;
349a891f0ea984eb1175467ebe1c0ec086977464a07Johny Lin        void* data = nullptr;
35052bffe176c343075c196c072aa7924de3abdd1b5Johny Lin        int64_t timestamp = 0u;
351fcbd8a30bab48f4e9a1cb3d25e75fbba33afb06ePin-chih Lin#ifdef ANDROID_VERSION_NYC
352fcbd8a30bab48f4e9a1cb3d25e75fbba33afb06ePin-chih Lin        MediaBuffer* buffer = nullptr;
353fcbd8a30bab48f4e9a1cb3d25e75fbba33afb06ePin-chih Lin#else
3547291a48a6117a6c67c6e4b776fe660e4ed9ef02bDongwon Kang        MediaBufferBase* buffer = nullptr;
355fcbd8a30bab48f4e9a1cb3d25e75fbba33afb06ePin-chih Lin#endif
35652bffe176c343075c196c072aa7924de3abdd1b5Johny Lin        sp<ABuffer> csd;
35752bffe176c343075c196c072aa7924de3abdd1b5Johny Lin        if (!csds.empty()) {
35852bffe176c343075c196c072aa7924de3abdd1b5Johny Lin            csd = std::move(csds.front());
35952bffe176c343075c196c072aa7924de3abdd1b5Johny Lin            csds.pop_front();
36052bffe176c343075c196c072aa7924de3abdd1b5Johny Lin            size = csd->size();
36152bffe176c343075c196c072aa7924de3abdd1b5Johny Lin            data = csd->data();
36252bffe176c343075c196c072aa7924de3abdd1b5Johny Lin        } else {
36352bffe176c343075c196c072aa7924de3abdd1b5Johny Lin            status_t err = source->read(&buffer);
36452bffe176c343075c196c072aa7924de3abdd1b5Johny Lin            if (err != OK) {
36552bffe176c343075c196c072aa7924de3abdd1b5Johny Lin                CHECK(buffer == nullptr);
36652bffe176c343075c196c072aa7924de3abdd1b5Johny Lin
36752bffe176c343075c196c072aa7924de3abdd1b5Johny Lin                if (err == INFO_FORMAT_CHANGED) {
36852bffe176c343075c196c072aa7924de3abdd1b5Johny Lin                    continue;
36952bffe176c343075c196c072aa7924de3abdd1b5Johny Lin                }
37052bffe176c343075c196c072aa7924de3abdd1b5Johny Lin
37152bffe176c343075c196c072aa7924de3abdd1b5Johny Lin                break;
37252bffe176c343075c196c072aa7924de3abdd1b5Johny Lin            }
373fcbd8a30bab48f4e9a1cb3d25e75fbba33afb06ePin-chih Lin#ifdef ANDROID_VERSION_NYC
374fcbd8a30bab48f4e9a1cb3d25e75fbba33afb06ePin-chih Lin            sp<MetaData> meta = buffer->meta_data();
375fcbd8a30bab48f4e9a1cb3d25e75fbba33afb06ePin-chih Lin            CHECK(meta->findInt64(kKeyTime, &timestamp));
376fcbd8a30bab48f4e9a1cb3d25e75fbba33afb06ePin-chih Lin#else
377ac29bf870c419dc38903896c50844b736fa8540eMarco Nelissen            MetaDataBase &meta = buffer->meta_data();
378ac29bf870c419dc38903896c50844b736fa8540eMarco Nelissen            CHECK(meta.findInt64(kKeyTime, &timestamp));
379fcbd8a30bab48f4e9a1cb3d25e75fbba33afb06ePin-chih Lin#endif
38052bffe176c343075c196c072aa7924de3abdd1b5Johny Lin
38152bffe176c343075c196c072aa7924de3abdd1b5Johny Lin            size = buffer->size();
38252bffe176c343075c196c072aa7924de3abdd1b5Johny Lin            data = buffer->data();
38352bffe176c343075c196c072aa7924de3abdd1b5Johny Lin        }
38452bffe176c343075c196c072aa7924de3abdd1b5Johny Lin
38552bffe176c343075c196c072aa7924de3abdd1b5Johny Lin        // Prepare C2Work
38652bffe176c343075c196c072aa7924de3abdd1b5Johny Lin
38752bffe176c343075c196c072aa7924de3abdd1b5Johny Lin        std::unique_ptr<C2Work> work;
38852bffe176c343075c196c072aa7924de3abdd1b5Johny Lin        while (!work) {
38952bffe176c343075c196c072aa7924de3abdd1b5Johny Lin            ULock l(mQueueLock);
39052bffe176c343075c196c072aa7924de3abdd1b5Johny Lin            if (!mWorkQueue.empty()) {
39152bffe176c343075c196c072aa7924de3abdd1b5Johny Lin                work = std::move(mWorkQueue.front());
39252bffe176c343075c196c072aa7924de3abdd1b5Johny Lin                mWorkQueue.pop_front();
39352bffe176c343075c196c072aa7924de3abdd1b5Johny Lin            } else {
39452bffe176c343075c196c072aa7924de3abdd1b5Johny Lin                mQueueCondition.wait_for(l, 100ms);
39552bffe176c343075c196c072aa7924de3abdd1b5Johny Lin            }
39652bffe176c343075c196c072aa7924de3abdd1b5Johny Lin        }
3972a2b90179d72e158c74982599752c92aac9029deLajos Molnar        work->input.flags = static_cast<C2FrameData::flags_t>(0);
39852bffe176c343075c196c072aa7924de3abdd1b5Johny Lin        work->input.ordinal.timestamp = timestamp;
3992a2b90179d72e158c74982599752c92aac9029deLajos Molnar        work->input.ordinal.frameIndex = numFrames;
40052bffe176c343075c196c072aa7924de3abdd1b5Johny Lin
40152bffe176c343075c196c072aa7924de3abdd1b5Johny Lin        // Allocate input buffer.
40252bffe176c343075c196c072aa7924de3abdd1b5Johny Lin        std::shared_ptr<C2LinearBlock> block;
40352bffe176c343075c196c072aa7924de3abdd1b5Johny Lin        mLinearBlockPool->fetchLinearBlock(
40420d1a263e74399f3a93e01bbe24db5b0066af653Johny Lin                size, {C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE}, &block);
40552bffe176c343075c196c072aa7924de3abdd1b5Johny Lin        C2WriteView view = block->map().get();
40652bffe176c343075c196c072aa7924de3abdd1b5Johny Lin        if (view.error() != C2_OK) {
40752bffe176c343075c196c072aa7924de3abdd1b5Johny Lin            fprintf(stderr, "C2LinearBlock::map() failed : %d\n", view.error());
40852bffe176c343075c196c072aa7924de3abdd1b5Johny Lin            break;
40952bffe176c343075c196c072aa7924de3abdd1b5Johny Lin        }
41052bffe176c343075c196c072aa7924de3abdd1b5Johny Lin        memcpy(view.base(), data, size);
41152bffe176c343075c196c072aa7924de3abdd1b5Johny Lin
41252bffe176c343075c196c072aa7924de3abdd1b5Johny Lin        work->input.buffers.clear();
41352bffe176c343075c196c072aa7924de3abdd1b5Johny Lin        work->input.buffers.emplace_back(new C2VDALinearBuffer(std::move(block)));
41452bffe176c343075c196c072aa7924de3abdd1b5Johny Lin        work->worklets.clear();
41552bffe176c343075c196c072aa7924de3abdd1b5Johny Lin        work->worklets.emplace_back(new C2Worklet);
41652bffe176c343075c196c072aa7924de3abdd1b5Johny Lin
41752bffe176c343075c196c072aa7924de3abdd1b5Johny Lin        std::list<std::unique_ptr<C2Work>> items;
41852bffe176c343075c196c072aa7924de3abdd1b5Johny Lin        items.push_back(std::move(work));
41952bffe176c343075c196c072aa7924de3abdd1b5Johny Lin
42052bffe176c343075c196c072aa7924de3abdd1b5Johny Lin        // DO THE DECODING
42152bffe176c343075c196c072aa7924de3abdd1b5Johny Lin        component->queue_nb(&items);
42252bffe176c343075c196c072aa7924de3abdd1b5Johny Lin
42352bffe176c343075c196c072aa7924de3abdd1b5Johny Lin        if (buffer) {
42452bffe176c343075c196c072aa7924de3abdd1b5Johny Lin            buffer->release();
42552bffe176c343075c196c072aa7924de3abdd1b5Johny Lin        }
42652bffe176c343075c196c072aa7924de3abdd1b5Johny Lin        ++numFrames;
42752bffe176c343075c196c072aa7924de3abdd1b5Johny Lin    }
428a891f0ea984eb1175467ebe1c0ec086977464a07Johny Lin    component->drain_nb(C2Component::DRAIN_COMPONENT_WITH_EOS);
42952bffe176c343075c196c072aa7924de3abdd1b5Johny Lin
43052bffe176c343075c196c072aa7924de3abdd1b5Johny Lin    surfaceThread.join();
43152bffe176c343075c196c072aa7924de3abdd1b5Johny Lin
43252bffe176c343075c196c072aa7924de3abdd1b5Johny Lin    source->stop();
43352bffe176c343075c196c072aa7924de3abdd1b5Johny Lin    component->stop();
43452bffe176c343075c196c072aa7924de3abdd1b5Johny Lin    printf("finished...\n");
43552bffe176c343075c196c072aa7924de3abdd1b5Johny Lin    return OK;
43652bffe176c343075c196c072aa7924de3abdd1b5Johny Lin}
43752bffe176c343075c196c072aa7924de3abdd1b5Johny Lin
43852bffe176c343075c196c072aa7924de3abdd1b5Johny Lin}  // namespace
43952bffe176c343075c196c072aa7924de3abdd1b5Johny Lin
44052bffe176c343075c196c072aa7924de3abdd1b5Johny Linstatic bool getMediaSourceFromFile(const char* filename, sp<IMediaSource>* source) {
44152bffe176c343075c196c072aa7924de3abdd1b5Johny Lin    source->clear();
44252bffe176c343075c196c072aa7924de3abdd1b5Johny Lin
4430deb659ab57ad7d9bac1c025cb5dd182946bc9f8Johny Lin#ifdef ANDROID_VERSION_NYC
444a891f0ea984eb1175467ebe1c0ec086977464a07Johny Lin    sp<DataSource> dataSource = DataSource::CreateFromURI(nullptr /* httpService */, filename);
4450deb659ab57ad7d9bac1c025cb5dd182946bc9f8Johny Lin#else
4460deb659ab57ad7d9bac1c025cb5dd182946bc9f8Johny Lin    sp<DataSource> dataSource =
4470deb659ab57ad7d9bac1c025cb5dd182946bc9f8Johny Lin            DataSourceFactory::CreateFromURI(nullptr /* httpService */, filename);
4480deb659ab57ad7d9bac1c025cb5dd182946bc9f8Johny Lin#endif
44952bffe176c343075c196c072aa7924de3abdd1b5Johny Lin
45052bffe176c343075c196c072aa7924de3abdd1b5Johny Lin    if (dataSource == nullptr) {
45152bffe176c343075c196c072aa7924de3abdd1b5Johny Lin        fprintf(stderr, "Unable to create data source.\n");
45252bffe176c343075c196c072aa7924de3abdd1b5Johny Lin        return false;
45352bffe176c343075c196c072aa7924de3abdd1b5Johny Lin    }
45452bffe176c343075c196c072aa7924de3abdd1b5Johny Lin
4550deb659ab57ad7d9bac1c025cb5dd182946bc9f8Johny Lin#ifdef ANDROID_VERSION_NYC
45652bffe176c343075c196c072aa7924de3abdd1b5Johny Lin    sp<IMediaExtractor> extractor = MediaExtractor::Create(dataSource);
4570deb659ab57ad7d9bac1c025cb5dd182946bc9f8Johny Lin#else
4580deb659ab57ad7d9bac1c025cb5dd182946bc9f8Johny Lin    sp<IMediaExtractor> extractor = MediaExtractorFactory::Create(dataSource);
4590deb659ab57ad7d9bac1c025cb5dd182946bc9f8Johny Lin#endif
46052bffe176c343075c196c072aa7924de3abdd1b5Johny Lin    if (extractor == nullptr) {
46152bffe176c343075c196c072aa7924de3abdd1b5Johny Lin        fprintf(stderr, "could not create extractor.\n");
46252bffe176c343075c196c072aa7924de3abdd1b5Johny Lin        return false;
46352bffe176c343075c196c072aa7924de3abdd1b5Johny Lin    }
46452bffe176c343075c196c072aa7924de3abdd1b5Johny Lin
4659be5270780fda8f9e7e4aff26e10d94a1d47517bJohny Lin    std::string expectedMime;
4669be5270780fda8f9e7e4aff26e10d94a1d47517bJohny Lin    if (kComponentName == kH264DecoderName) {
4679be5270780fda8f9e7e4aff26e10d94a1d47517bJohny Lin        expectedMime = "video/avc";
4689be5270780fda8f9e7e4aff26e10d94a1d47517bJohny Lin    } else if (kComponentName == kVP8DecoderName) {
4699be5270780fda8f9e7e4aff26e10d94a1d47517bJohny Lin        expectedMime = "video/x-vnd.on2.vp8";
47095d0e47610746d8c8444051e42413f6c0d454817Johny Lin    } else if (kComponentName == kVP9DecoderName) {
47195d0e47610746d8c8444051e42413f6c0d454817Johny Lin        expectedMime = "video/x-vnd.on2.vp9";
4729be5270780fda8f9e7e4aff26e10d94a1d47517bJohny Lin    } else {
4739be5270780fda8f9e7e4aff26e10d94a1d47517bJohny Lin        fprintf(stderr, "unrecognized component name: %s\n", kComponentName.c_str());
4749be5270780fda8f9e7e4aff26e10d94a1d47517bJohny Lin        return false;
4759be5270780fda8f9e7e4aff26e10d94a1d47517bJohny Lin    }
4769be5270780fda8f9e7e4aff26e10d94a1d47517bJohny Lin
47752bffe176c343075c196c072aa7924de3abdd1b5Johny Lin    for (size_t i = 0, numTracks = extractor->countTracks(); i < numTracks; ++i) {
47852bffe176c343075c196c072aa7924de3abdd1b5Johny Lin        sp<MetaData> meta =
47952bffe176c343075c196c072aa7924de3abdd1b5Johny Lin                extractor->getTrackMetaData(i, MediaExtractor::kIncludeExtensiveMetaData);
48052bffe176c343075c196c072aa7924de3abdd1b5Johny Lin        if (meta == nullptr) {
48152bffe176c343075c196c072aa7924de3abdd1b5Johny Lin            continue;
48252bffe176c343075c196c072aa7924de3abdd1b5Johny Lin        }
483a891f0ea984eb1175467ebe1c0ec086977464a07Johny Lin        const char* mime;
48452bffe176c343075c196c072aa7924de3abdd1b5Johny Lin        meta->findCString(kKeyMIMEType, &mime);
4859be5270780fda8f9e7e4aff26e10d94a1d47517bJohny Lin        if (!strcasecmp(mime, expectedMime.c_str())) {
48652bffe176c343075c196c072aa7924de3abdd1b5Johny Lin            *source = extractor->getTrack(i);
48752bffe176c343075c196c072aa7924de3abdd1b5Johny Lin            if (*source == nullptr) {
48852bffe176c343075c196c072aa7924de3abdd1b5Johny Lin                fprintf(stderr, "It's nullptr track for track %zu.\n", i);
48952bffe176c343075c196c072aa7924de3abdd1b5Johny Lin                return false;
49052bffe176c343075c196c072aa7924de3abdd1b5Johny Lin            }
49152bffe176c343075c196c072aa7924de3abdd1b5Johny Lin            return true;
49252bffe176c343075c196c072aa7924de3abdd1b5Johny Lin        }
49352bffe176c343075c196c072aa7924de3abdd1b5Johny Lin    }
4949be5270780fda8f9e7e4aff26e10d94a1d47517bJohny Lin    fprintf(stderr, "No track found.\n");
49552bffe176c343075c196c072aa7924de3abdd1b5Johny Lin    return false;
49652bffe176c343075c196c072aa7924de3abdd1b5Johny Lin}
49752bffe176c343075c196c072aa7924de3abdd1b5Johny Lin
498a891f0ea984eb1175467ebe1c0ec086977464a07Johny Linstatic void usage(const char* me) {
49952bffe176c343075c196c072aa7924de3abdd1b5Johny Lin    fprintf(stderr, "usage: %s [options] [input_filename]...\n", me);
50052bffe176c343075c196c072aa7924de3abdd1b5Johny Lin    fprintf(stderr, "       -h(elp)\n");
50152bffe176c343075c196c072aa7924de3abdd1b5Johny Lin}
50252bffe176c343075c196c072aa7924de3abdd1b5Johny Lin
503a891f0ea984eb1175467ebe1c0ec086977464a07Johny Linint main(int argc, char** argv) {
50452bffe176c343075c196c072aa7924de3abdd1b5Johny Lin    android::ProcessState::self()->startThreadPool();
50552bffe176c343075c196c072aa7924de3abdd1b5Johny Lin
50652bffe176c343075c196c072aa7924de3abdd1b5Johny Lin    int res;
50752bffe176c343075c196c072aa7924de3abdd1b5Johny Lin    while ((res = getopt(argc, argv, "h")) >= 0) {
50852bffe176c343075c196c072aa7924de3abdd1b5Johny Lin        switch (res) {
509a891f0ea984eb1175467ebe1c0ec086977464a07Johny Lin        case 'h':
510a891f0ea984eb1175467ebe1c0ec086977464a07Johny Lin        default: {
511a891f0ea984eb1175467ebe1c0ec086977464a07Johny Lin            usage(argv[0]);
512a891f0ea984eb1175467ebe1c0ec086977464a07Johny Lin            exit(1);
513a891f0ea984eb1175467ebe1c0ec086977464a07Johny Lin            break;
514a891f0ea984eb1175467ebe1c0ec086977464a07Johny Lin        }
51552bffe176c343075c196c072aa7924de3abdd1b5Johny Lin        }
51652bffe176c343075c196c072aa7924de3abdd1b5Johny Lin    }
51752bffe176c343075c196c072aa7924de3abdd1b5Johny Lin
51852bffe176c343075c196c072aa7924de3abdd1b5Johny Lin    argc -= optind;
51952bffe176c343075c196c072aa7924de3abdd1b5Johny Lin    argv += optind;
52052bffe176c343075c196c072aa7924de3abdd1b5Johny Lin
52152bffe176c343075c196c072aa7924de3abdd1b5Johny Lin    if (argc < 1) {
52252bffe176c343075c196c072aa7924de3abdd1b5Johny Lin        fprintf(stderr, "No input file specified\n");
52352bffe176c343075c196c072aa7924de3abdd1b5Johny Lin        return 1;
52452bffe176c343075c196c072aa7924de3abdd1b5Johny Lin    }
52552bffe176c343075c196c072aa7924de3abdd1b5Johny Lin
52652bffe176c343075c196c072aa7924de3abdd1b5Johny Lin    SimplePlayer player;
52752bffe176c343075c196c072aa7924de3abdd1b5Johny Lin
52852bffe176c343075c196c072aa7924de3abdd1b5Johny Lin    for (int k = 0; k < argc; ++k) {
52952bffe176c343075c196c072aa7924de3abdd1b5Johny Lin        sp<IMediaSource> mediaSource;
53052bffe176c343075c196c072aa7924de3abdd1b5Johny Lin        if (!getMediaSourceFromFile(argv[k], &mediaSource)) {
53152bffe176c343075c196c072aa7924de3abdd1b5Johny Lin            fprintf(stderr, "Unable to get media source from file: %s\n", argv[k]);
53252bffe176c343075c196c072aa7924de3abdd1b5Johny Lin            return -1;
53352bffe176c343075c196c072aa7924de3abdd1b5Johny Lin        }
53452bffe176c343075c196c072aa7924de3abdd1b5Johny Lin        if (player.play(mediaSource) != OK) {
53552bffe176c343075c196c072aa7924de3abdd1b5Johny Lin            fprintf(stderr, "Player failed to play media source: %s\n", argv[k]);
53652bffe176c343075c196c072aa7924de3abdd1b5Johny Lin            return -1;
53752bffe176c343075c196c072aa7924de3abdd1b5Johny Lin        }
53852bffe176c343075c196c072aa7924de3abdd1b5Johny Lin    }
53952bffe176c343075c196c072aa7924de3abdd1b5Johny Lin
54052bffe176c343075c196c072aa7924de3abdd1b5Johny Lin    return 0;
54152bffe176c343075c196c072aa7924de3abdd1b5Johny Lin}
542