1*ec779b8eSAndroid Build Coastguard Worker /******************************************************************************
2*ec779b8eSAndroid Build Coastguard Worker *
3*ec779b8eSAndroid Build Coastguard Worker * Copyright (C) 2020 The Android Open Source Project
4*ec779b8eSAndroid Build Coastguard Worker *
5*ec779b8eSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
6*ec779b8eSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
7*ec779b8eSAndroid Build Coastguard Worker * You may obtain a copy of the License at:
8*ec779b8eSAndroid Build Coastguard Worker *
9*ec779b8eSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0
10*ec779b8eSAndroid Build Coastguard Worker *
11*ec779b8eSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
12*ec779b8eSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
13*ec779b8eSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14*ec779b8eSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
15*ec779b8eSAndroid Build Coastguard Worker * limitations under the License.
16*ec779b8eSAndroid Build Coastguard Worker *
17*ec779b8eSAndroid Build Coastguard Worker *****************************************************************************
18*ec779b8eSAndroid Build Coastguard Worker * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
19*ec779b8eSAndroid Build Coastguard Worker */
20*ec779b8eSAndroid Build Coastguard Worker #include <stdio.h>
21*ec779b8eSAndroid Build Coastguard Worker
22*ec779b8eSAndroid Build Coastguard Worker #include <C2Fuzzer.h>
23*ec779b8eSAndroid Build Coastguard Worker
24*ec779b8eSAndroid Build Coastguard Worker using namespace android;
25*ec779b8eSAndroid Build Coastguard Worker
26*ec779b8eSAndroid Build Coastguard Worker class LinearBuffer : public C2Buffer {
27*ec779b8eSAndroid Build Coastguard Worker public:
LinearBuffer(const std::shared_ptr<C2LinearBlock> & block)28*ec779b8eSAndroid Build Coastguard Worker explicit LinearBuffer(const std::shared_ptr<C2LinearBlock>& block)
29*ec779b8eSAndroid Build Coastguard Worker : C2Buffer({block->share(block->offset(), block->size(), ::C2Fence())}) {}
30*ec779b8eSAndroid Build Coastguard Worker
LinearBuffer(const std::shared_ptr<C2LinearBlock> & block,size_t size)31*ec779b8eSAndroid Build Coastguard Worker explicit LinearBuffer(const std::shared_ptr<C2LinearBlock>& block, size_t size)
32*ec779b8eSAndroid Build Coastguard Worker : C2Buffer({block->share(block->offset(), size, ::C2Fence())}) {}
33*ec779b8eSAndroid Build Coastguard Worker };
34*ec779b8eSAndroid Build Coastguard Worker
35*ec779b8eSAndroid Build Coastguard Worker /**
36*ec779b8eSAndroid Build Coastguard Worker * Handle Callback functions onWorkDone_nb(), onTripped_nb(), onError_nb() for C2 Components
37*ec779b8eSAndroid Build Coastguard Worker */
38*ec779b8eSAndroid Build Coastguard Worker struct CodecListener : public C2Component::Listener {
39*ec779b8eSAndroid Build Coastguard Worker public:
CodecListenerCodecListener40*ec779b8eSAndroid Build Coastguard Worker CodecListener(const std::function<void(std::weak_ptr<C2Component> comp,
41*ec779b8eSAndroid Build Coastguard Worker std::list<std::unique_ptr<C2Work>>& workItems)>
42*ec779b8eSAndroid Build Coastguard Worker fn = nullptr)
43*ec779b8eSAndroid Build Coastguard Worker : callBack(fn) {}
onWorkDone_nbCodecListener44*ec779b8eSAndroid Build Coastguard Worker virtual void onWorkDone_nb(const std::weak_ptr<C2Component> comp,
45*ec779b8eSAndroid Build Coastguard Worker std::list<std::unique_ptr<C2Work>> workItems) {
46*ec779b8eSAndroid Build Coastguard Worker if (callBack) {
47*ec779b8eSAndroid Build Coastguard Worker callBack(comp, workItems);
48*ec779b8eSAndroid Build Coastguard Worker }
49*ec779b8eSAndroid Build Coastguard Worker }
50*ec779b8eSAndroid Build Coastguard Worker
onTripped_nbCodecListener51*ec779b8eSAndroid Build Coastguard Worker virtual void onTripped_nb(const std::weak_ptr<C2Component> comp,
52*ec779b8eSAndroid Build Coastguard Worker const std::vector<std::shared_ptr<C2SettingResult>> settingResults) {
53*ec779b8eSAndroid Build Coastguard Worker (void)comp;
54*ec779b8eSAndroid Build Coastguard Worker (void)settingResults;
55*ec779b8eSAndroid Build Coastguard Worker }
56*ec779b8eSAndroid Build Coastguard Worker
onError_nbCodecListener57*ec779b8eSAndroid Build Coastguard Worker virtual void onError_nb(const std::weak_ptr<C2Component> comp, uint32_t errorCode) {
58*ec779b8eSAndroid Build Coastguard Worker (void)comp;
59*ec779b8eSAndroid Build Coastguard Worker (void)errorCode;
60*ec779b8eSAndroid Build Coastguard Worker }
61*ec779b8eSAndroid Build Coastguard Worker
62*ec779b8eSAndroid Build Coastguard Worker std::function<void(std::weak_ptr<C2Component> comp,
63*ec779b8eSAndroid Build Coastguard Worker std::list<std::unique_ptr<C2Work>>& workItems)> callBack;
64*ec779b8eSAndroid Build Coastguard Worker };
65*ec779b8eSAndroid Build Coastguard Worker
66*ec779b8eSAndroid Build Coastguard Worker /**
67*ec779b8eSAndroid Build Coastguard Worker * Buffer source implementations to identify a frame and its size
68*ec779b8eSAndroid Build Coastguard Worker */
searchForMarker()69*ec779b8eSAndroid Build Coastguard Worker bool Codec2Fuzzer::BufferSource::searchForMarker() {
70*ec779b8eSAndroid Build Coastguard Worker while (true) {
71*ec779b8eSAndroid Build Coastguard Worker if (isMarker()) {
72*ec779b8eSAndroid Build Coastguard Worker return true;
73*ec779b8eSAndroid Build Coastguard Worker }
74*ec779b8eSAndroid Build Coastguard Worker --mReadIndex;
75*ec779b8eSAndroid Build Coastguard Worker if (mReadIndex > mSize) {
76*ec779b8eSAndroid Build Coastguard Worker break;
77*ec779b8eSAndroid Build Coastguard Worker }
78*ec779b8eSAndroid Build Coastguard Worker }
79*ec779b8eSAndroid Build Coastguard Worker return false;
80*ec779b8eSAndroid Build Coastguard Worker }
81*ec779b8eSAndroid Build Coastguard Worker
parse()82*ec779b8eSAndroid Build Coastguard Worker void Codec2Fuzzer::BufferSource::parse() {
83*ec779b8eSAndroid Build Coastguard Worker bool isFrameAvailable = true;
84*ec779b8eSAndroid Build Coastguard Worker size_t bytesRemaining = mSize;
85*ec779b8eSAndroid Build Coastguard Worker while (isFrameAvailable) {
86*ec779b8eSAndroid Build Coastguard Worker isFrameAvailable = searchForMarker();
87*ec779b8eSAndroid Build Coastguard Worker if (isFrameAvailable) {
88*ec779b8eSAndroid Build Coastguard Worker size_t location = mReadIndex + kMarkerSize;
89*ec779b8eSAndroid Build Coastguard Worker bool isCSD = isCSDMarker(location);
90*ec779b8eSAndroid Build Coastguard Worker location += kMarkerSuffixSize;
91*ec779b8eSAndroid Build Coastguard Worker uint8_t* framePtr = const_cast<uint8_t*>(&mData[location]);
92*ec779b8eSAndroid Build Coastguard Worker size_t frameSize = bytesRemaining - location;
93*ec779b8eSAndroid Build Coastguard Worker uint32_t flags = 0;
94*ec779b8eSAndroid Build Coastguard Worker if (mFrameList.empty()) {
95*ec779b8eSAndroid Build Coastguard Worker flags |= C2FrameData::FLAG_END_OF_STREAM;
96*ec779b8eSAndroid Build Coastguard Worker } else if (isCSD) {
97*ec779b8eSAndroid Build Coastguard Worker flags |= C2FrameData::FLAG_CODEC_CONFIG;
98*ec779b8eSAndroid Build Coastguard Worker }
99*ec779b8eSAndroid Build Coastguard Worker mFrameList.emplace_back(std::make_tuple(framePtr, frameSize, flags));
100*ec779b8eSAndroid Build Coastguard Worker bytesRemaining -= (frameSize + kMarkerSize + kMarkerSuffixSize);
101*ec779b8eSAndroid Build Coastguard Worker --mReadIndex;
102*ec779b8eSAndroid Build Coastguard Worker }
103*ec779b8eSAndroid Build Coastguard Worker }
104*ec779b8eSAndroid Build Coastguard Worker if (mFrameList.empty()) {
105*ec779b8eSAndroid Build Coastguard Worker /**
106*ec779b8eSAndroid Build Coastguard Worker * Scenario where input data does not contain the custom frame markers.
107*ec779b8eSAndroid Build Coastguard Worker * Hence feed the entire data as single frame.
108*ec779b8eSAndroid Build Coastguard Worker */
109*ec779b8eSAndroid Build Coastguard Worker mFrameList.emplace_back(
110*ec779b8eSAndroid Build Coastguard Worker std::make_tuple(const_cast<uint8_t*>(mData), 0, C2FrameData::FLAG_END_OF_STREAM));
111*ec779b8eSAndroid Build Coastguard Worker mFrameList.emplace_back(
112*ec779b8eSAndroid Build Coastguard Worker std::make_tuple(const_cast<uint8_t*>(mData), mSize, C2FrameData::FLAG_CODEC_CONFIG));
113*ec779b8eSAndroid Build Coastguard Worker }
114*ec779b8eSAndroid Build Coastguard Worker }
115*ec779b8eSAndroid Build Coastguard Worker
getFrame()116*ec779b8eSAndroid Build Coastguard Worker FrameData Codec2Fuzzer::BufferSource::getFrame() {
117*ec779b8eSAndroid Build Coastguard Worker FrameData frame = mFrameList.back();
118*ec779b8eSAndroid Build Coastguard Worker mFrameList.pop_back();
119*ec779b8eSAndroid Build Coastguard Worker return frame;
120*ec779b8eSAndroid Build Coastguard Worker }
121*ec779b8eSAndroid Build Coastguard Worker
handleWorkDone(std::weak_ptr<C2Component> comp,std::list<std::unique_ptr<C2Work>> & workItems)122*ec779b8eSAndroid Build Coastguard Worker void Codec2Fuzzer::handleWorkDone(std::weak_ptr<C2Component> comp,
123*ec779b8eSAndroid Build Coastguard Worker std::list<std::unique_ptr<C2Work>>& workItems) {
124*ec779b8eSAndroid Build Coastguard Worker (void)comp;
125*ec779b8eSAndroid Build Coastguard Worker for (std::unique_ptr<C2Work>& work : workItems) {
126*ec779b8eSAndroid Build Coastguard Worker if (!work->worklets.empty()) {
127*ec779b8eSAndroid Build Coastguard Worker if (work->worklets.front()->output.flags != C2FrameData::FLAG_INCOMPLETE) {
128*ec779b8eSAndroid Build Coastguard Worker mEos = (work->worklets.front()->output.flags & C2FrameData::FLAG_END_OF_STREAM) != 0;
129*ec779b8eSAndroid Build Coastguard Worker work->input.buffers.clear();
130*ec779b8eSAndroid Build Coastguard Worker work->worklets.clear();
131*ec779b8eSAndroid Build Coastguard Worker {
132*ec779b8eSAndroid Build Coastguard Worker std::unique_lock<std::mutex> lock(mQueueLock);
133*ec779b8eSAndroid Build Coastguard Worker mWorkQueue.push_back(std::move(work));
134*ec779b8eSAndroid Build Coastguard Worker mQueueCondition.notify_all();
135*ec779b8eSAndroid Build Coastguard Worker }
136*ec779b8eSAndroid Build Coastguard Worker if (mEos) {
137*ec779b8eSAndroid Build Coastguard Worker {
138*ec779b8eSAndroid Build Coastguard Worker std::lock_guard<std::mutex> waitForDecodeComplete(mDecodeCompleteMutex);
139*ec779b8eSAndroid Build Coastguard Worker }
140*ec779b8eSAndroid Build Coastguard Worker mConditionalVariable.notify_one();
141*ec779b8eSAndroid Build Coastguard Worker }
142*ec779b8eSAndroid Build Coastguard Worker }
143*ec779b8eSAndroid Build Coastguard Worker }
144*ec779b8eSAndroid Build Coastguard Worker }
145*ec779b8eSAndroid Build Coastguard Worker }
146*ec779b8eSAndroid Build Coastguard Worker
initDecoder()147*ec779b8eSAndroid Build Coastguard Worker bool Codec2Fuzzer::initDecoder() {
148*ec779b8eSAndroid Build Coastguard Worker std::vector<std::tuple<C2String, C2ComponentFactory::CreateCodec2FactoryFunc,
149*ec779b8eSAndroid Build Coastguard Worker C2ComponentFactory::DestroyCodec2FactoryFunc>> codec2FactoryFunc;
150*ec779b8eSAndroid Build Coastguard Worker
151*ec779b8eSAndroid Build Coastguard Worker codec2FactoryFunc.emplace_back(
152*ec779b8eSAndroid Build Coastguard Worker std::make_tuple(C2COMPONENTNAME, &CreateCodec2Factory, &DestroyCodec2Factory));
153*ec779b8eSAndroid Build Coastguard Worker
154*ec779b8eSAndroid Build Coastguard Worker std::shared_ptr<C2ComponentStore> componentStore = GetTestComponentStore(codec2FactoryFunc);
155*ec779b8eSAndroid Build Coastguard Worker if (!componentStore) {
156*ec779b8eSAndroid Build Coastguard Worker return false;
157*ec779b8eSAndroid Build Coastguard Worker }
158*ec779b8eSAndroid Build Coastguard Worker
159*ec779b8eSAndroid Build Coastguard Worker std::shared_ptr<C2AllocatorStore> allocatorStore = GetCodec2PlatformAllocatorStore();
160*ec779b8eSAndroid Build Coastguard Worker if (!allocatorStore) {
161*ec779b8eSAndroid Build Coastguard Worker return false;
162*ec779b8eSAndroid Build Coastguard Worker }
163*ec779b8eSAndroid Build Coastguard Worker
164*ec779b8eSAndroid Build Coastguard Worker c2_status_t status =
165*ec779b8eSAndroid Build Coastguard Worker allocatorStore->fetchAllocator(C2AllocatorStore::DEFAULT_LINEAR, &mLinearAllocator);
166*ec779b8eSAndroid Build Coastguard Worker if (status != C2_OK) {
167*ec779b8eSAndroid Build Coastguard Worker return false;
168*ec779b8eSAndroid Build Coastguard Worker }
169*ec779b8eSAndroid Build Coastguard Worker
170*ec779b8eSAndroid Build Coastguard Worker mLinearPool = std::make_shared<C2PooledBlockPool>(mLinearAllocator, ++mBlockPoolId);
171*ec779b8eSAndroid Build Coastguard Worker if (!mLinearPool) {
172*ec779b8eSAndroid Build Coastguard Worker return false;
173*ec779b8eSAndroid Build Coastguard Worker }
174*ec779b8eSAndroid Build Coastguard Worker
175*ec779b8eSAndroid Build Coastguard Worker for (int32_t i = 0; i < kNumberOfC2WorkItems; ++i) {
176*ec779b8eSAndroid Build Coastguard Worker mWorkQueue.emplace_back(new C2Work);
177*ec779b8eSAndroid Build Coastguard Worker }
178*ec779b8eSAndroid Build Coastguard Worker
179*ec779b8eSAndroid Build Coastguard Worker status = componentStore->createComponent(C2COMPONENTNAME, &mComponent);
180*ec779b8eSAndroid Build Coastguard Worker if (status != C2_OK) {
181*ec779b8eSAndroid Build Coastguard Worker return false;
182*ec779b8eSAndroid Build Coastguard Worker }
183*ec779b8eSAndroid Build Coastguard Worker
184*ec779b8eSAndroid Build Coastguard Worker status = componentStore->createInterface(C2COMPONENTNAME, &mInterface);
185*ec779b8eSAndroid Build Coastguard Worker if (status != C2_OK) {
186*ec779b8eSAndroid Build Coastguard Worker return false;
187*ec779b8eSAndroid Build Coastguard Worker }
188*ec779b8eSAndroid Build Coastguard Worker
189*ec779b8eSAndroid Build Coastguard Worker C2ComponentKindSetting kind;
190*ec779b8eSAndroid Build Coastguard Worker C2ComponentDomainSetting domain;
191*ec779b8eSAndroid Build Coastguard Worker status = mInterface->query_vb({&kind, &domain}, {}, C2_MAY_BLOCK, nullptr);
192*ec779b8eSAndroid Build Coastguard Worker if (status != C2_OK) {
193*ec779b8eSAndroid Build Coastguard Worker return false;
194*ec779b8eSAndroid Build Coastguard Worker }
195*ec779b8eSAndroid Build Coastguard Worker
196*ec779b8eSAndroid Build Coastguard Worker std::vector<C2Param*> configParams;
197*ec779b8eSAndroid Build Coastguard Worker C2StreamPictureSizeInfo::input inputSize(0u, kWidthOfVideo, kHeightOfVideo);
198*ec779b8eSAndroid Build Coastguard Worker C2StreamSampleRateInfo::output sampleRateInfo(0u, kSamplingRateOfAudio);
199*ec779b8eSAndroid Build Coastguard Worker C2StreamChannelCountInfo::output channelCountInfo(0u, kChannelsOfAudio);
200*ec779b8eSAndroid Build Coastguard Worker if (domain.value == DOMAIN_VIDEO) {
201*ec779b8eSAndroid Build Coastguard Worker configParams.push_back(&inputSize);
202*ec779b8eSAndroid Build Coastguard Worker } else if (domain.value == DOMAIN_AUDIO) {
203*ec779b8eSAndroid Build Coastguard Worker configParams.push_back(&sampleRateInfo);
204*ec779b8eSAndroid Build Coastguard Worker configParams.push_back(&channelCountInfo);
205*ec779b8eSAndroid Build Coastguard Worker }
206*ec779b8eSAndroid Build Coastguard Worker
207*ec779b8eSAndroid Build Coastguard Worker mListener.reset(new CodecListener(
208*ec779b8eSAndroid Build Coastguard Worker [this](std::weak_ptr<C2Component> comp, std::list<std::unique_ptr<C2Work>>& workItems) {
209*ec779b8eSAndroid Build Coastguard Worker handleWorkDone(comp, workItems);
210*ec779b8eSAndroid Build Coastguard Worker }));
211*ec779b8eSAndroid Build Coastguard Worker if (!mListener) {
212*ec779b8eSAndroid Build Coastguard Worker return false;
213*ec779b8eSAndroid Build Coastguard Worker }
214*ec779b8eSAndroid Build Coastguard Worker
215*ec779b8eSAndroid Build Coastguard Worker status = mComponent->setListener_vb(mListener, C2_DONT_BLOCK);
216*ec779b8eSAndroid Build Coastguard Worker if (status != C2_OK) {
217*ec779b8eSAndroid Build Coastguard Worker return false;
218*ec779b8eSAndroid Build Coastguard Worker }
219*ec779b8eSAndroid Build Coastguard Worker
220*ec779b8eSAndroid Build Coastguard Worker std::vector<std::unique_ptr<C2SettingResult>> failures;
221*ec779b8eSAndroid Build Coastguard Worker componentStore->config_sm(configParams, &failures);
222*ec779b8eSAndroid Build Coastguard Worker if (failures.size() != 0) {
223*ec779b8eSAndroid Build Coastguard Worker return false;
224*ec779b8eSAndroid Build Coastguard Worker }
225*ec779b8eSAndroid Build Coastguard Worker
226*ec779b8eSAndroid Build Coastguard Worker status = mComponent->start();
227*ec779b8eSAndroid Build Coastguard Worker if (status != C2_OK) {
228*ec779b8eSAndroid Build Coastguard Worker return false;
229*ec779b8eSAndroid Build Coastguard Worker }
230*ec779b8eSAndroid Build Coastguard Worker
231*ec779b8eSAndroid Build Coastguard Worker return true;
232*ec779b8eSAndroid Build Coastguard Worker }
233*ec779b8eSAndroid Build Coastguard Worker
deInitDecoder()234*ec779b8eSAndroid Build Coastguard Worker void Codec2Fuzzer::deInitDecoder() {
235*ec779b8eSAndroid Build Coastguard Worker mComponent->stop();
236*ec779b8eSAndroid Build Coastguard Worker mComponent->reset();
237*ec779b8eSAndroid Build Coastguard Worker mComponent->release();
238*ec779b8eSAndroid Build Coastguard Worker mComponent = nullptr;
239*ec779b8eSAndroid Build Coastguard Worker }
240*ec779b8eSAndroid Build Coastguard Worker
decodeFrames(const uint8_t * data,size_t size)241*ec779b8eSAndroid Build Coastguard Worker void Codec2Fuzzer::decodeFrames(const uint8_t* data, size_t size) {
242*ec779b8eSAndroid Build Coastguard Worker static const size_t kPageSize = getpagesize();
243*ec779b8eSAndroid Build Coastguard Worker std::unique_ptr<BufferSource> bufferSource = std::make_unique<BufferSource>(data, size);
244*ec779b8eSAndroid Build Coastguard Worker if (!bufferSource) {
245*ec779b8eSAndroid Build Coastguard Worker return;
246*ec779b8eSAndroid Build Coastguard Worker }
247*ec779b8eSAndroid Build Coastguard Worker bufferSource->parse();
248*ec779b8eSAndroid Build Coastguard Worker c2_status_t status = C2_OK;
249*ec779b8eSAndroid Build Coastguard Worker size_t numFrames = 0;
250*ec779b8eSAndroid Build Coastguard Worker int32_t iterationCount = 0;
251*ec779b8eSAndroid Build Coastguard Worker while (!bufferSource->isEos() && ++iterationCount <= kMaxIterations) {
252*ec779b8eSAndroid Build Coastguard Worker uint8_t* frame = nullptr;
253*ec779b8eSAndroid Build Coastguard Worker size_t frameSize = 0;
254*ec779b8eSAndroid Build Coastguard Worker FrameData frameData = bufferSource->getFrame();
255*ec779b8eSAndroid Build Coastguard Worker frame = std::get<0>(frameData);
256*ec779b8eSAndroid Build Coastguard Worker frameSize = std::get<1>(frameData);
257*ec779b8eSAndroid Build Coastguard Worker
258*ec779b8eSAndroid Build Coastguard Worker std::unique_ptr<C2Work> work;
259*ec779b8eSAndroid Build Coastguard Worker {
260*ec779b8eSAndroid Build Coastguard Worker std::unique_lock<std::mutex> lock(mQueueLock);
261*ec779b8eSAndroid Build Coastguard Worker if (mWorkQueue.empty()) mQueueCondition.wait_for(lock, kC2FuzzerTimeOut);
262*ec779b8eSAndroid Build Coastguard Worker if (!mWorkQueue.empty()) {
263*ec779b8eSAndroid Build Coastguard Worker work.swap(mWorkQueue.front());
264*ec779b8eSAndroid Build Coastguard Worker mWorkQueue.pop_front();
265*ec779b8eSAndroid Build Coastguard Worker } else {
266*ec779b8eSAndroid Build Coastguard Worker return;
267*ec779b8eSAndroid Build Coastguard Worker }
268*ec779b8eSAndroid Build Coastguard Worker }
269*ec779b8eSAndroid Build Coastguard Worker
270*ec779b8eSAndroid Build Coastguard Worker work->input.flags = (C2FrameData::flags_t)std::get<2>(frameData);
271*ec779b8eSAndroid Build Coastguard Worker work->input.ordinal.timestamp = 0;
272*ec779b8eSAndroid Build Coastguard Worker work->input.ordinal.frameIndex = ++numFrames;
273*ec779b8eSAndroid Build Coastguard Worker work->input.buffers.clear();
274*ec779b8eSAndroid Build Coastguard Worker int32_t alignedSize = C2FUZZER_ALIGN(frameSize, kPageSize);
275*ec779b8eSAndroid Build Coastguard Worker
276*ec779b8eSAndroid Build Coastguard Worker std::shared_ptr<C2LinearBlock> block;
277*ec779b8eSAndroid Build Coastguard Worker status = mLinearPool->fetchLinearBlock(
278*ec779b8eSAndroid Build Coastguard Worker alignedSize, {C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE}, &block);
279*ec779b8eSAndroid Build Coastguard Worker if (status != C2_OK || block == nullptr) {
280*ec779b8eSAndroid Build Coastguard Worker return;
281*ec779b8eSAndroid Build Coastguard Worker }
282*ec779b8eSAndroid Build Coastguard Worker
283*ec779b8eSAndroid Build Coastguard Worker C2WriteView view = block->map().get();
284*ec779b8eSAndroid Build Coastguard Worker if (view.error() != C2_OK) {
285*ec779b8eSAndroid Build Coastguard Worker return;
286*ec779b8eSAndroid Build Coastguard Worker }
287*ec779b8eSAndroid Build Coastguard Worker memcpy(view.base(), frame, frameSize);
288*ec779b8eSAndroid Build Coastguard Worker work->input.buffers.emplace_back(new LinearBuffer(block, frameSize));
289*ec779b8eSAndroid Build Coastguard Worker work->worklets.clear();
290*ec779b8eSAndroid Build Coastguard Worker work->worklets.emplace_back(new C2Worklet);
291*ec779b8eSAndroid Build Coastguard Worker
292*ec779b8eSAndroid Build Coastguard Worker std::list<std::unique_ptr<C2Work>> items;
293*ec779b8eSAndroid Build Coastguard Worker items.push_back(std::move(work));
294*ec779b8eSAndroid Build Coastguard Worker status = mComponent->queue_nb(&items);
295*ec779b8eSAndroid Build Coastguard Worker if (status != C2_OK) {
296*ec779b8eSAndroid Build Coastguard Worker return;
297*ec779b8eSAndroid Build Coastguard Worker }
298*ec779b8eSAndroid Build Coastguard Worker }
299*ec779b8eSAndroid Build Coastguard Worker std::unique_lock<std::mutex> waitForDecodeComplete(mDecodeCompleteMutex);
300*ec779b8eSAndroid Build Coastguard Worker mConditionalVariable.wait_for(waitForDecodeComplete, kC2FuzzerTimeOut, [this] { return mEos; });
301*ec779b8eSAndroid Build Coastguard Worker std::list<std::unique_ptr<C2Work>> c2flushedWorks;
302*ec779b8eSAndroid Build Coastguard Worker mComponent->flush_sm(C2Component::FLUSH_COMPONENT, &c2flushedWorks);
303*ec779b8eSAndroid Build Coastguard Worker }
304*ec779b8eSAndroid Build Coastguard Worker
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)305*ec779b8eSAndroid Build Coastguard Worker extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
306*ec779b8eSAndroid Build Coastguard Worker if (size < 1) {
307*ec779b8eSAndroid Build Coastguard Worker return 0;
308*ec779b8eSAndroid Build Coastguard Worker }
309*ec779b8eSAndroid Build Coastguard Worker Codec2Fuzzer* codec = new Codec2Fuzzer();
310*ec779b8eSAndroid Build Coastguard Worker if (!codec) {
311*ec779b8eSAndroid Build Coastguard Worker return 0;
312*ec779b8eSAndroid Build Coastguard Worker }
313*ec779b8eSAndroid Build Coastguard Worker if (codec->initDecoder()) {
314*ec779b8eSAndroid Build Coastguard Worker codec->decodeFrames(data, size);
315*ec779b8eSAndroid Build Coastguard Worker }
316*ec779b8eSAndroid Build Coastguard Worker delete codec;
317*ec779b8eSAndroid Build Coastguard Worker return 0;
318*ec779b8eSAndroid Build Coastguard Worker }
319