1 /*
2  * Copyright (C) 2019 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 //#define LOG_NDEBUG 0
18 #define LOG_TAG "BenchmarkC2Common"
19 
20 #include "BenchmarkC2Common.h"
21 
setupCodec2()22 int32_t BenchmarkC2Common::setupCodec2() {
23     ALOGV("In %s", __func__);
24     mClient = android::Codec2Client::CreateFromService("default");
25     if (!mClient) {
26         mClient = android::Codec2Client::CreateFromService("software");
27     }
28     if (!mClient) return -1;
29 
30     std::shared_ptr<C2AllocatorStore> store = android::GetCodec2PlatformAllocatorStore();
31     if (!store) return -1;
32 
33     c2_status_t status = store->fetchAllocator(C2AllocatorStore::DEFAULT_LINEAR, &mLinearAllocator);
34     if (status != C2_OK) return status;
35 
36     mLinearPool = std::make_shared<C2PooledBlockPool>(mLinearAllocator, mBlockPoolId++);
37     if (!mLinearPool) return -1;
38 
39     status = store->fetchAllocator(C2AllocatorStore::DEFAULT_GRAPHIC, &mGraphicAllocator);
40     if (status != C2_OK) return status;
41 
42     mGraphicPool = std::make_shared<C2PooledBlockPool>(mGraphicAllocator, mBlockPoolId++);
43     if (!mGraphicPool) return -1;
44 
45     for (int i = 0; i < MAX_INPUT_BUFFERS; ++i) {
46         mWorkQueue.emplace_back(new C2Work);
47     }
48     if (!mStats) mStats = new Stats();
49 
50     return status;
51 }
52 
getSupportedComponentList(bool isEncoder)53 vector<string> BenchmarkC2Common::getSupportedComponentList(bool isEncoder) {
54     // Get List of components from all known services
55     vector<string> codecList;
56     const std::vector<C2Component::Traits> listTraits = mClient->ListComponents();
57     if (listTraits.size() == 0)
58         ALOGE("ComponentInfo list empty.");
59     else {
60         for (size_t i = 0; i < listTraits.size(); i++) {
61             if (isEncoder && C2Component::KIND_ENCODER == listTraits[i].kind) {
62                 codecList.push_back(listTraits[i].name);
63             } else if (!isEncoder && C2Component::KIND_DECODER == listTraits[i].kind) {
64                 codecList.push_back(listTraits[i].name);
65             }
66         }
67     }
68     return codecList;
69 }
70 
waitOnInputConsumption()71 void BenchmarkC2Common::waitOnInputConsumption() {
72     typedef std::unique_lock<std::mutex> ULock;
73     uint32_t queueSize;
74     uint32_t maxRetry = 0;
75     {
76         ULock l(mQueueLock);
77         queueSize = mWorkQueue.size();
78     }
79     while ((maxRetry < MAX_RETRY) && (queueSize < MAX_INPUT_BUFFERS)) {
80         ULock l(mQueueLock);
81         if (queueSize != mWorkQueue.size()) {
82             queueSize = mWorkQueue.size();
83             maxRetry = 0;
84         } else {
85             mQueueCondition.wait_for(l, TIME_OUT);
86             maxRetry++;
87         }
88     }
89 }
90 
handleWorkDone(std::list<std::unique_ptr<C2Work>> & workItems)91 void BenchmarkC2Common::handleWorkDone(std::list<std::unique_ptr<C2Work>> &workItems) {
92     ALOGV("In %s", __func__);
93     mStats->addOutputTime();
94     for (std::unique_ptr<C2Work> &work : workItems) {
95         if (!work->worklets.empty()) {
96             if (work->worklets.front()->output.flags != C2FrameData::FLAG_INCOMPLETE) {
97                 mEos = (work->worklets.front()->output.flags & C2FrameData::FLAG_END_OF_STREAM) !=
98                        0;
99                 ALOGV("WorkDone: frameID received %d , mEos : %d",
100                       (int)work->worklets.front()->output.ordinal.frameIndex.peeku(), mEos);
101                 work->input.buffers.clear();
102                 work->worklets.clear();
103                 {
104                     typedef std::unique_lock<std::mutex> ULock;
105                     ULock l(mQueueLock);
106                     mWorkQueue.push_back(std::move(work));
107                     mQueueCondition.notify_all();
108                 }
109             }
110         }
111     }
112 }
113 
114