xref: /aosp_15_r20/frameworks/av/media/codec2/fuzzer/C2Fuzzer.cpp (revision ec779b8e0859a360c3d303172224686826e6e0e1)
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