xref: /aosp_15_r20/external/libavc/fuzzer/avc_dec_fuzzer.cpp (revision 495ae853bb871d1e5a258cb02c2cc13cde8ddb9a)
1*495ae853SAndroid Build Coastguard Worker /******************************************************************************
2*495ae853SAndroid Build Coastguard Worker  *
3*495ae853SAndroid Build Coastguard Worker  * Copyright (C) 2019 The Android Open Source Project
4*495ae853SAndroid Build Coastguard Worker  *
5*495ae853SAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
6*495ae853SAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
7*495ae853SAndroid Build Coastguard Worker  * You may obtain a copy of the License at:
8*495ae853SAndroid Build Coastguard Worker  *
9*495ae853SAndroid Build Coastguard Worker  * http://www.apache.org/licenses/LICENSE-2.0
10*495ae853SAndroid Build Coastguard Worker  *
11*495ae853SAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
12*495ae853SAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
13*495ae853SAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14*495ae853SAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
15*495ae853SAndroid Build Coastguard Worker  * limitations under the License.
16*495ae853SAndroid Build Coastguard Worker  *
17*495ae853SAndroid Build Coastguard Worker  *****************************************************************************
18*495ae853SAndroid Build Coastguard Worker  * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
19*495ae853SAndroid Build Coastguard Worker  */
20*495ae853SAndroid Build Coastguard Worker 
21*495ae853SAndroid Build Coastguard Worker #include <stddef.h>
22*495ae853SAndroid Build Coastguard Worker #include <stdint.h>
23*495ae853SAndroid Build Coastguard Worker #include <stdio.h>
24*495ae853SAndroid Build Coastguard Worker #include <stdlib.h>
25*495ae853SAndroid Build Coastguard Worker #include <string.h>
26*495ae853SAndroid Build Coastguard Worker 
27*495ae853SAndroid Build Coastguard Worker #include <algorithm>
28*495ae853SAndroid Build Coastguard Worker #include <memory>
29*495ae853SAndroid Build Coastguard Worker 
30*495ae853SAndroid Build Coastguard Worker #include "ih264_typedefs.h"
31*495ae853SAndroid Build Coastguard Worker #include "ih264d.h"
32*495ae853SAndroid Build Coastguard Worker #include "iv.h"
33*495ae853SAndroid Build Coastguard Worker #include "ivd.h"
34*495ae853SAndroid Build Coastguard Worker 
35*495ae853SAndroid Build Coastguard Worker #define NELEMENTS(x) (sizeof(x) / sizeof(x[0]))
36*495ae853SAndroid Build Coastguard Worker #define ivd_api_function ih264d_api_function
37*495ae853SAndroid Build Coastguard Worker const IV_COLOR_FORMAT_T supportedColorFormats[] = {
38*495ae853SAndroid Build Coastguard Worker     IV_YUV_420P,   IV_YUV_420SP_UV, IV_YUV_420SP_VU,
39*495ae853SAndroid Build Coastguard Worker     IV_YUV_422ILE, IV_RGB_565,      IV_RGBA_8888};
40*495ae853SAndroid Build Coastguard Worker 
41*495ae853SAndroid Build Coastguard Worker /* Decoder ignores invalid arch, i.e. for arm build, if SSSE3 is requested,
42*495ae853SAndroid Build Coastguard Worker  * decoder defaults to a supported configuration. So same set of supported
43*495ae853SAndroid Build Coastguard Worker  * architectures can be used in arm/arm64/x86 builds */
44*495ae853SAndroid Build Coastguard Worker const IVD_ARCH_T supportedArchitectures[] = {
45*495ae853SAndroid Build Coastguard Worker     ARCH_ARM_NONEON,  ARCH_ARM_A9Q,   ARCH_ARM_NEONINTR, ARCH_ARMV8_GENERIC,
46*495ae853SAndroid Build Coastguard Worker     ARCH_X86_GENERIC, ARCH_X86_SSSE3, ARCH_X86_SSE42};
47*495ae853SAndroid Build Coastguard Worker 
48*495ae853SAndroid Build Coastguard Worker enum {
49*495ae853SAndroid Build Coastguard Worker   OFFSET_COLOR_FORMAT = 6,
50*495ae853SAndroid Build Coastguard Worker   OFFSET_NUM_CORES,
51*495ae853SAndroid Build Coastguard Worker   OFFSET_ARCH,
52*495ae853SAndroid Build Coastguard Worker   /* Should be the last entry */
53*495ae853SAndroid Build Coastguard Worker   OFFSET_MAX,
54*495ae853SAndroid Build Coastguard Worker };
55*495ae853SAndroid Build Coastguard Worker 
56*495ae853SAndroid Build Coastguard Worker const static int kMaxNumDecodeCalls = 100;
57*495ae853SAndroid Build Coastguard Worker const static int kSupportedColorFormats = NELEMENTS(supportedColorFormats);
58*495ae853SAndroid Build Coastguard Worker const static int kSupportedArchitectures = NELEMENTS(supportedArchitectures);
59*495ae853SAndroid Build Coastguard Worker const static int kMaxCores = 4;
iv_aligned_malloc(void * ctxt,WORD32 alignment,WORD32 size)60*495ae853SAndroid Build Coastguard Worker void *iv_aligned_malloc(void *ctxt, WORD32 alignment, WORD32 size) {
61*495ae853SAndroid Build Coastguard Worker   void *buf = NULL;
62*495ae853SAndroid Build Coastguard Worker   (void)ctxt;
63*495ae853SAndroid Build Coastguard Worker   if (0 != posix_memalign(&buf, alignment, size)) {
64*495ae853SAndroid Build Coastguard Worker       return NULL;
65*495ae853SAndroid Build Coastguard Worker   }
66*495ae853SAndroid Build Coastguard Worker   return buf;
67*495ae853SAndroid Build Coastguard Worker }
68*495ae853SAndroid Build Coastguard Worker 
iv_aligned_free(void * ctxt,void * buf)69*495ae853SAndroid Build Coastguard Worker void iv_aligned_free(void *ctxt, void *buf) {
70*495ae853SAndroid Build Coastguard Worker   (void)ctxt;
71*495ae853SAndroid Build Coastguard Worker   free(buf);
72*495ae853SAndroid Build Coastguard Worker }
73*495ae853SAndroid Build Coastguard Worker 
74*495ae853SAndroid Build Coastguard Worker class Codec {
75*495ae853SAndroid Build Coastguard Worker  public:
76*495ae853SAndroid Build Coastguard Worker   Codec(IV_COLOR_FORMAT_T colorFormat, size_t numCores);
77*495ae853SAndroid Build Coastguard Worker   ~Codec();
78*495ae853SAndroid Build Coastguard Worker 
79*495ae853SAndroid Build Coastguard Worker   void createCodec();
80*495ae853SAndroid Build Coastguard Worker   void deleteCodec();
81*495ae853SAndroid Build Coastguard Worker   void resetCodec();
82*495ae853SAndroid Build Coastguard Worker   void setCores();
83*495ae853SAndroid Build Coastguard Worker   void allocFrame();
84*495ae853SAndroid Build Coastguard Worker   void freeFrame();
85*495ae853SAndroid Build Coastguard Worker   void decodeHeader(const uint8_t *data, size_t size);
86*495ae853SAndroid Build Coastguard Worker   IV_API_CALL_STATUS_T decodeFrame(const uint8_t *data, size_t size,
87*495ae853SAndroid Build Coastguard Worker                                    size_t *bytesConsumed);
88*495ae853SAndroid Build Coastguard Worker   void setParams(IVD_VIDEO_DECODE_MODE_T mode);
89*495ae853SAndroid Build Coastguard Worker   void setArchitecture(IVD_ARCH_T arch);
90*495ae853SAndroid Build Coastguard Worker 
91*495ae853SAndroid Build Coastguard Worker  private:
92*495ae853SAndroid Build Coastguard Worker   IV_COLOR_FORMAT_T mColorFormat;
93*495ae853SAndroid Build Coastguard Worker   size_t mNumCores;
94*495ae853SAndroid Build Coastguard Worker   iv_obj_t *mCodec;
95*495ae853SAndroid Build Coastguard Worker   ivd_out_bufdesc_t mOutBufHandle;
96*495ae853SAndroid Build Coastguard Worker   uint32_t mWidth;
97*495ae853SAndroid Build Coastguard Worker   uint32_t mHeight;
98*495ae853SAndroid Build Coastguard Worker };
99*495ae853SAndroid Build Coastguard Worker 
Codec(IV_COLOR_FORMAT_T colorFormat,size_t numCores)100*495ae853SAndroid Build Coastguard Worker Codec::Codec(IV_COLOR_FORMAT_T colorFormat, size_t numCores) {
101*495ae853SAndroid Build Coastguard Worker   mColorFormat = colorFormat;
102*495ae853SAndroid Build Coastguard Worker   mNumCores = numCores;
103*495ae853SAndroid Build Coastguard Worker   mCodec = nullptr;
104*495ae853SAndroid Build Coastguard Worker   mWidth = 0;
105*495ae853SAndroid Build Coastguard Worker   mHeight = 0;
106*495ae853SAndroid Build Coastguard Worker 
107*495ae853SAndroid Build Coastguard Worker   memset(&mOutBufHandle, 0, sizeof(mOutBufHandle));
108*495ae853SAndroid Build Coastguard Worker }
~Codec()109*495ae853SAndroid Build Coastguard Worker Codec::~Codec() {}
createCodec()110*495ae853SAndroid Build Coastguard Worker void Codec::createCodec() {
111*495ae853SAndroid Build Coastguard Worker   IV_API_CALL_STATUS_T ret;
112*495ae853SAndroid Build Coastguard Worker   ih264d_create_ip_t create_ip{};
113*495ae853SAndroid Build Coastguard Worker   ih264d_create_op_t create_op{};
114*495ae853SAndroid Build Coastguard Worker   void *fxns = (void *)&ivd_api_function;
115*495ae853SAndroid Build Coastguard Worker 
116*495ae853SAndroid Build Coastguard Worker   create_ip.s_ivd_create_ip_t.e_cmd = IVD_CMD_CREATE;
117*495ae853SAndroid Build Coastguard Worker   create_ip.s_ivd_create_ip_t.u4_share_disp_buf = 0;
118*495ae853SAndroid Build Coastguard Worker   create_ip.s_ivd_create_ip_t.e_output_format = mColorFormat;
119*495ae853SAndroid Build Coastguard Worker   create_ip.s_ivd_create_ip_t.pf_aligned_alloc = iv_aligned_malloc;
120*495ae853SAndroid Build Coastguard Worker   create_ip.s_ivd_create_ip_t.pf_aligned_free = iv_aligned_free;
121*495ae853SAndroid Build Coastguard Worker   create_ip.u4_keep_threads_active = 1;
122*495ae853SAndroid Build Coastguard Worker   create_ip.s_ivd_create_ip_t.pv_mem_ctxt = NULL;
123*495ae853SAndroid Build Coastguard Worker   create_ip.s_ivd_create_ip_t.u4_size = sizeof(ih264d_create_ip_t);
124*495ae853SAndroid Build Coastguard Worker   create_op.s_ivd_create_op_t.u4_size = sizeof(ih264d_create_op_t);
125*495ae853SAndroid Build Coastguard Worker 
126*495ae853SAndroid Build Coastguard Worker   ret = ivd_api_function(NULL, (void *)&create_ip, (void *)&create_op);
127*495ae853SAndroid Build Coastguard Worker   if (ret != IV_SUCCESS) {
128*495ae853SAndroid Build Coastguard Worker     return;
129*495ae853SAndroid Build Coastguard Worker   }
130*495ae853SAndroid Build Coastguard Worker   mCodec = (iv_obj_t *)create_op.s_ivd_create_op_t.pv_handle;
131*495ae853SAndroid Build Coastguard Worker   mCodec->pv_fxns = fxns;
132*495ae853SAndroid Build Coastguard Worker   mCodec->u4_size = sizeof(iv_obj_t);
133*495ae853SAndroid Build Coastguard Worker }
134*495ae853SAndroid Build Coastguard Worker 
deleteCodec()135*495ae853SAndroid Build Coastguard Worker void Codec::deleteCodec() {
136*495ae853SAndroid Build Coastguard Worker   ivd_delete_ip_t delete_ip{};
137*495ae853SAndroid Build Coastguard Worker   ivd_delete_op_t delete_op{};
138*495ae853SAndroid Build Coastguard Worker 
139*495ae853SAndroid Build Coastguard Worker   delete_ip.e_cmd = IVD_CMD_DELETE;
140*495ae853SAndroid Build Coastguard Worker   delete_ip.u4_size = sizeof(ivd_delete_ip_t);
141*495ae853SAndroid Build Coastguard Worker   delete_op.u4_size = sizeof(ivd_delete_op_t);
142*495ae853SAndroid Build Coastguard Worker 
143*495ae853SAndroid Build Coastguard Worker   ivd_api_function(mCodec, (void *)&delete_ip, (void *)&delete_op);
144*495ae853SAndroid Build Coastguard Worker }
resetCodec()145*495ae853SAndroid Build Coastguard Worker void Codec::resetCodec() {
146*495ae853SAndroid Build Coastguard Worker   ivd_ctl_reset_ip_t s_ctl_ip{};
147*495ae853SAndroid Build Coastguard Worker   ivd_ctl_reset_op_t s_ctl_op{};
148*495ae853SAndroid Build Coastguard Worker 
149*495ae853SAndroid Build Coastguard Worker   s_ctl_ip.e_cmd = IVD_CMD_VIDEO_CTL;
150*495ae853SAndroid Build Coastguard Worker   s_ctl_ip.e_sub_cmd = IVD_CMD_CTL_RESET;
151*495ae853SAndroid Build Coastguard Worker   s_ctl_ip.u4_size = sizeof(ivd_ctl_reset_ip_t);
152*495ae853SAndroid Build Coastguard Worker   s_ctl_op.u4_size = sizeof(ivd_ctl_reset_op_t);
153*495ae853SAndroid Build Coastguard Worker 
154*495ae853SAndroid Build Coastguard Worker   ivd_api_function(mCodec, (void *)&s_ctl_ip, (void *)&s_ctl_op);
155*495ae853SAndroid Build Coastguard Worker }
156*495ae853SAndroid Build Coastguard Worker 
setCores()157*495ae853SAndroid Build Coastguard Worker void Codec::setCores() {
158*495ae853SAndroid Build Coastguard Worker   ih264d_ctl_set_num_cores_ip_t s_ctl_ip{};
159*495ae853SAndroid Build Coastguard Worker   ih264d_ctl_set_num_cores_op_t s_ctl_op{};
160*495ae853SAndroid Build Coastguard Worker 
161*495ae853SAndroid Build Coastguard Worker   s_ctl_ip.e_cmd = IVD_CMD_VIDEO_CTL;
162*495ae853SAndroid Build Coastguard Worker   s_ctl_ip.e_sub_cmd =
163*495ae853SAndroid Build Coastguard Worker       (IVD_CONTROL_API_COMMAND_TYPE_T)IH264D_CMD_CTL_SET_NUM_CORES;
164*495ae853SAndroid Build Coastguard Worker   s_ctl_ip.u4_num_cores = mNumCores;
165*495ae853SAndroid Build Coastguard Worker   s_ctl_ip.u4_size = sizeof(ih264d_ctl_set_num_cores_ip_t);
166*495ae853SAndroid Build Coastguard Worker   s_ctl_op.u4_size = sizeof(ih264d_ctl_set_num_cores_op_t);
167*495ae853SAndroid Build Coastguard Worker 
168*495ae853SAndroid Build Coastguard Worker   ivd_api_function(mCodec, (void *)&s_ctl_ip, (void *)&s_ctl_op);
169*495ae853SAndroid Build Coastguard Worker }
170*495ae853SAndroid Build Coastguard Worker 
setParams(IVD_VIDEO_DECODE_MODE_T mode)171*495ae853SAndroid Build Coastguard Worker void Codec::setParams(IVD_VIDEO_DECODE_MODE_T mode) {
172*495ae853SAndroid Build Coastguard Worker   ivd_ctl_set_config_ip_t s_ctl_ip{};
173*495ae853SAndroid Build Coastguard Worker   ivd_ctl_set_config_op_t s_ctl_op{};
174*495ae853SAndroid Build Coastguard Worker 
175*495ae853SAndroid Build Coastguard Worker   s_ctl_ip.u4_disp_wd = 0;
176*495ae853SAndroid Build Coastguard Worker   s_ctl_ip.e_frm_skip_mode = IVD_SKIP_NONE;
177*495ae853SAndroid Build Coastguard Worker   s_ctl_ip.e_frm_out_mode = IVD_DISPLAY_FRAME_OUT;
178*495ae853SAndroid Build Coastguard Worker   s_ctl_ip.e_vid_dec_mode = mode;
179*495ae853SAndroid Build Coastguard Worker   s_ctl_ip.e_cmd = IVD_CMD_VIDEO_CTL;
180*495ae853SAndroid Build Coastguard Worker   s_ctl_ip.e_sub_cmd = IVD_CMD_CTL_SETPARAMS;
181*495ae853SAndroid Build Coastguard Worker   s_ctl_ip.u4_size = sizeof(ivd_ctl_set_config_ip_t);
182*495ae853SAndroid Build Coastguard Worker   s_ctl_op.u4_size = sizeof(ivd_ctl_set_config_op_t);
183*495ae853SAndroid Build Coastguard Worker 
184*495ae853SAndroid Build Coastguard Worker   ivd_api_function(mCodec, (void *)&s_ctl_ip, (void *)&s_ctl_op);
185*495ae853SAndroid Build Coastguard Worker }
186*495ae853SAndroid Build Coastguard Worker 
setArchitecture(IVD_ARCH_T arch)187*495ae853SAndroid Build Coastguard Worker void Codec::setArchitecture(IVD_ARCH_T arch) {
188*495ae853SAndroid Build Coastguard Worker   ih264d_ctl_set_processor_ip_t s_ctl_ip{};
189*495ae853SAndroid Build Coastguard Worker   ih264d_ctl_set_processor_op_t s_ctl_op{};
190*495ae853SAndroid Build Coastguard Worker 
191*495ae853SAndroid Build Coastguard Worker   s_ctl_ip.e_cmd = IVD_CMD_VIDEO_CTL;
192*495ae853SAndroid Build Coastguard Worker   s_ctl_ip.e_sub_cmd =
193*495ae853SAndroid Build Coastguard Worker       (IVD_CONTROL_API_COMMAND_TYPE_T)IH264D_CMD_CTL_SET_PROCESSOR;
194*495ae853SAndroid Build Coastguard Worker   s_ctl_ip.u4_arch = arch;
195*495ae853SAndroid Build Coastguard Worker   s_ctl_ip.u4_soc = SOC_GENERIC;
196*495ae853SAndroid Build Coastguard Worker   s_ctl_ip.u4_size = sizeof(ih264d_ctl_set_processor_ip_t);
197*495ae853SAndroid Build Coastguard Worker   s_ctl_op.u4_size = sizeof(ih264d_ctl_set_processor_op_t);
198*495ae853SAndroid Build Coastguard Worker 
199*495ae853SAndroid Build Coastguard Worker   ivd_api_function(mCodec, (void *)&s_ctl_ip, (void *)&s_ctl_op);
200*495ae853SAndroid Build Coastguard Worker }
freeFrame()201*495ae853SAndroid Build Coastguard Worker void Codec::freeFrame() {
202*495ae853SAndroid Build Coastguard Worker   for (int i = 0; i < mOutBufHandle.u4_num_bufs; i++) {
203*495ae853SAndroid Build Coastguard Worker     if (mOutBufHandle.pu1_bufs[i]) {
204*495ae853SAndroid Build Coastguard Worker       free(mOutBufHandle.pu1_bufs[i]);
205*495ae853SAndroid Build Coastguard Worker       mOutBufHandle.pu1_bufs[i] = nullptr;
206*495ae853SAndroid Build Coastguard Worker     }
207*495ae853SAndroid Build Coastguard Worker   }
208*495ae853SAndroid Build Coastguard Worker }
allocFrame()209*495ae853SAndroid Build Coastguard Worker void Codec::allocFrame() {
210*495ae853SAndroid Build Coastguard Worker   size_t sizes[4] = {0};
211*495ae853SAndroid Build Coastguard Worker   size_t num_bufs = 0;
212*495ae853SAndroid Build Coastguard Worker 
213*495ae853SAndroid Build Coastguard Worker   freeFrame();
214*495ae853SAndroid Build Coastguard Worker 
215*495ae853SAndroid Build Coastguard Worker   memset(&mOutBufHandle, 0, sizeof(mOutBufHandle));
216*495ae853SAndroid Build Coastguard Worker 
217*495ae853SAndroid Build Coastguard Worker   switch (mColorFormat) {
218*495ae853SAndroid Build Coastguard Worker     case IV_YUV_420SP_UV:
219*495ae853SAndroid Build Coastguard Worker       [[fallthrough]];
220*495ae853SAndroid Build Coastguard Worker     case IV_YUV_420SP_VU:
221*495ae853SAndroid Build Coastguard Worker       sizes[0] = mWidth * mHeight;
222*495ae853SAndroid Build Coastguard Worker       sizes[1] = mWidth * mHeight >> 1;
223*495ae853SAndroid Build Coastguard Worker       num_bufs = 2;
224*495ae853SAndroid Build Coastguard Worker       break;
225*495ae853SAndroid Build Coastguard Worker     case IV_YUV_422ILE:
226*495ae853SAndroid Build Coastguard Worker       sizes[0] = mWidth * mHeight * 2;
227*495ae853SAndroid Build Coastguard Worker       num_bufs = 1;
228*495ae853SAndroid Build Coastguard Worker       break;
229*495ae853SAndroid Build Coastguard Worker     case IV_RGB_565:
230*495ae853SAndroid Build Coastguard Worker       sizes[0] = mWidth * mHeight * 2;
231*495ae853SAndroid Build Coastguard Worker       num_bufs = 1;
232*495ae853SAndroid Build Coastguard Worker       break;
233*495ae853SAndroid Build Coastguard Worker     case IV_RGBA_8888:
234*495ae853SAndroid Build Coastguard Worker       sizes[0] = mWidth * mHeight * 4;
235*495ae853SAndroid Build Coastguard Worker       num_bufs = 1;
236*495ae853SAndroid Build Coastguard Worker       break;
237*495ae853SAndroid Build Coastguard Worker     case IV_YUV_420P:
238*495ae853SAndroid Build Coastguard Worker       [[fallthrough]];
239*495ae853SAndroid Build Coastguard Worker     default:
240*495ae853SAndroid Build Coastguard Worker       sizes[0] = mWidth * mHeight;
241*495ae853SAndroid Build Coastguard Worker       sizes[1] = mWidth * mHeight >> 2;
242*495ae853SAndroid Build Coastguard Worker       sizes[2] = mWidth * mHeight >> 2;
243*495ae853SAndroid Build Coastguard Worker       num_bufs = 3;
244*495ae853SAndroid Build Coastguard Worker       break;
245*495ae853SAndroid Build Coastguard Worker   }
246*495ae853SAndroid Build Coastguard Worker   mOutBufHandle.u4_num_bufs = num_bufs;
247*495ae853SAndroid Build Coastguard Worker   for (int i = 0; i < num_bufs; i++) {
248*495ae853SAndroid Build Coastguard Worker     mOutBufHandle.u4_min_out_buf_size[i] = sizes[i];
249*495ae853SAndroid Build Coastguard Worker     mOutBufHandle.pu1_bufs[i] = (UWORD8 *)iv_aligned_malloc(NULL, 16, sizes[i]);
250*495ae853SAndroid Build Coastguard Worker   }
251*495ae853SAndroid Build Coastguard Worker }
decodeHeader(const uint8_t * data,size_t size)252*495ae853SAndroid Build Coastguard Worker void Codec::decodeHeader(const uint8_t *data, size_t size) {
253*495ae853SAndroid Build Coastguard Worker   setParams(IVD_DECODE_HEADER);
254*495ae853SAndroid Build Coastguard Worker 
255*495ae853SAndroid Build Coastguard Worker   size_t numDecodeCalls = 0;
256*495ae853SAndroid Build Coastguard Worker 
257*495ae853SAndroid Build Coastguard Worker   while (size > 0 && numDecodeCalls < kMaxNumDecodeCalls) {
258*495ae853SAndroid Build Coastguard Worker     IV_API_CALL_STATUS_T ret;
259*495ae853SAndroid Build Coastguard Worker     ivd_video_decode_ip_t dec_ip{};
260*495ae853SAndroid Build Coastguard Worker     ivd_video_decode_op_t dec_op{};
261*495ae853SAndroid Build Coastguard Worker     size_t bytes_consumed;
262*495ae853SAndroid Build Coastguard Worker 
263*495ae853SAndroid Build Coastguard Worker     dec_ip.e_cmd = IVD_CMD_VIDEO_DECODE;
264*495ae853SAndroid Build Coastguard Worker     dec_ip.u4_ts = 0;
265*495ae853SAndroid Build Coastguard Worker     dec_ip.pv_stream_buffer = (void *)data;
266*495ae853SAndroid Build Coastguard Worker     dec_ip.u4_num_Bytes = size;
267*495ae853SAndroid Build Coastguard Worker     dec_ip.u4_size = sizeof(ivd_video_decode_ip_t);
268*495ae853SAndroid Build Coastguard Worker     dec_op.u4_size = sizeof(ivd_video_decode_op_t);
269*495ae853SAndroid Build Coastguard Worker 
270*495ae853SAndroid Build Coastguard Worker     ret = ivd_api_function(mCodec, (void *)&dec_ip, (void *)&dec_op);
271*495ae853SAndroid Build Coastguard Worker 
272*495ae853SAndroid Build Coastguard Worker     bytes_consumed = dec_op.u4_num_bytes_consumed;
273*495ae853SAndroid Build Coastguard Worker     /* If no bytes are consumed, then consume 4 bytes to ensure fuzzer proceeds
274*495ae853SAndroid Build Coastguard Worker      * to feed next data */
275*495ae853SAndroid Build Coastguard Worker     if (!bytes_consumed) bytes_consumed = 4;
276*495ae853SAndroid Build Coastguard Worker 
277*495ae853SAndroid Build Coastguard Worker     bytes_consumed = std::min(size, bytes_consumed);
278*495ae853SAndroid Build Coastguard Worker 
279*495ae853SAndroid Build Coastguard Worker     data += bytes_consumed;
280*495ae853SAndroid Build Coastguard Worker     size -= bytes_consumed;
281*495ae853SAndroid Build Coastguard Worker     numDecodeCalls++;
282*495ae853SAndroid Build Coastguard Worker 
283*495ae853SAndroid Build Coastguard Worker     mWidth = std::min(dec_op.u4_pic_wd, (UWORD32)10240);
284*495ae853SAndroid Build Coastguard Worker     mHeight = std::min(dec_op.u4_pic_ht, (UWORD32)10240);
285*495ae853SAndroid Build Coastguard Worker 
286*495ae853SAndroid Build Coastguard Worker     /* Break after successful header decode */
287*495ae853SAndroid Build Coastguard Worker     if (mWidth && mHeight) {
288*495ae853SAndroid Build Coastguard Worker       break;
289*495ae853SAndroid Build Coastguard Worker     }
290*495ae853SAndroid Build Coastguard Worker   }
291*495ae853SAndroid Build Coastguard Worker   /* if width / height are invalid, set them to defaults */
292*495ae853SAndroid Build Coastguard Worker   if (!mWidth) mWidth = 1920;
293*495ae853SAndroid Build Coastguard Worker   if (!mHeight) mHeight = 1088;
294*495ae853SAndroid Build Coastguard Worker }
295*495ae853SAndroid Build Coastguard Worker 
decodeFrame(const uint8_t * data,size_t size,size_t * bytesConsumed)296*495ae853SAndroid Build Coastguard Worker IV_API_CALL_STATUS_T Codec::decodeFrame(const uint8_t *data, size_t size,
297*495ae853SAndroid Build Coastguard Worker                                         size_t *bytesConsumed) {
298*495ae853SAndroid Build Coastguard Worker   IV_API_CALL_STATUS_T ret;
299*495ae853SAndroid Build Coastguard Worker   ivd_video_decode_ip_t dec_ip{};
300*495ae853SAndroid Build Coastguard Worker   ivd_video_decode_op_t dec_op{};
301*495ae853SAndroid Build Coastguard Worker 
302*495ae853SAndroid Build Coastguard Worker   dec_ip.e_cmd = IVD_CMD_VIDEO_DECODE;
303*495ae853SAndroid Build Coastguard Worker   dec_ip.u4_ts = 0;
304*495ae853SAndroid Build Coastguard Worker   dec_ip.pv_stream_buffer = (void *)data;
305*495ae853SAndroid Build Coastguard Worker   dec_ip.u4_num_Bytes = size;
306*495ae853SAndroid Build Coastguard Worker   dec_ip.u4_size = sizeof(ivd_video_decode_ip_t);
307*495ae853SAndroid Build Coastguard Worker   dec_ip.s_out_buffer = mOutBufHandle;
308*495ae853SAndroid Build Coastguard Worker 
309*495ae853SAndroid Build Coastguard Worker   dec_op.u4_size = sizeof(ivd_video_decode_op_t);
310*495ae853SAndroid Build Coastguard Worker 
311*495ae853SAndroid Build Coastguard Worker   ret = ivd_api_function(mCodec, (void *)&dec_ip, (void *)&dec_op);
312*495ae853SAndroid Build Coastguard Worker 
313*495ae853SAndroid Build Coastguard Worker   /* In case of change in resolution, reset codec and feed the same data again
314*495ae853SAndroid Build Coastguard Worker    */
315*495ae853SAndroid Build Coastguard Worker   if (IVD_RES_CHANGED == (dec_op.u4_error_code & 0xFF)) {
316*495ae853SAndroid Build Coastguard Worker     resetCodec();
317*495ae853SAndroid Build Coastguard Worker     ret = ivd_api_function(mCodec, (void *)&dec_ip, (void *)&dec_op);
318*495ae853SAndroid Build Coastguard Worker   }
319*495ae853SAndroid Build Coastguard Worker   *bytesConsumed = dec_op.u4_num_bytes_consumed;
320*495ae853SAndroid Build Coastguard Worker 
321*495ae853SAndroid Build Coastguard Worker   /* If no bytes are consumed, then consume 4 bytes to ensure fuzzer proceeds
322*495ae853SAndroid Build Coastguard Worker    * to feed next data */
323*495ae853SAndroid Build Coastguard Worker   if (!*bytesConsumed) *bytesConsumed = 4;
324*495ae853SAndroid Build Coastguard Worker 
325*495ae853SAndroid Build Coastguard Worker   if (dec_op.u4_pic_wd && dec_op.u4_pic_ht &&
326*495ae853SAndroid Build Coastguard Worker       (mWidth != dec_op.u4_pic_wd || mHeight != dec_op.u4_pic_ht)) {
327*495ae853SAndroid Build Coastguard Worker     mWidth = std::min(dec_op.u4_pic_wd, (UWORD32)10240);
328*495ae853SAndroid Build Coastguard Worker     mHeight = std::min(dec_op.u4_pic_ht, (UWORD32)10240);
329*495ae853SAndroid Build Coastguard Worker     allocFrame();
330*495ae853SAndroid Build Coastguard Worker   }
331*495ae853SAndroid Build Coastguard Worker 
332*495ae853SAndroid Build Coastguard Worker   return ret;
333*495ae853SAndroid Build Coastguard Worker }
334*495ae853SAndroid Build Coastguard Worker 
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)335*495ae853SAndroid Build Coastguard Worker extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
336*495ae853SAndroid Build Coastguard Worker   if (size < 1) {
337*495ae853SAndroid Build Coastguard Worker     return 0;
338*495ae853SAndroid Build Coastguard Worker   }
339*495ae853SAndroid Build Coastguard Worker   size_t colorFormatOfst = std::min((size_t)OFFSET_COLOR_FORMAT, size - 1);
340*495ae853SAndroid Build Coastguard Worker   size_t numCoresOfst = std::min((size_t)OFFSET_NUM_CORES, size - 1);
341*495ae853SAndroid Build Coastguard Worker   size_t architectureOfst = std::min((size_t)OFFSET_ARCH, size - 1);
342*495ae853SAndroid Build Coastguard Worker   size_t architectureIdx = data[architectureOfst] % kSupportedArchitectures;
343*495ae853SAndroid Build Coastguard Worker   IVD_ARCH_T arch = (IVD_ARCH_T)supportedArchitectures[architectureIdx];
344*495ae853SAndroid Build Coastguard Worker   size_t colorFormatIdx = data[colorFormatOfst] % kSupportedColorFormats;
345*495ae853SAndroid Build Coastguard Worker   IV_COLOR_FORMAT_T colorFormat =
346*495ae853SAndroid Build Coastguard Worker       (IV_COLOR_FORMAT_T)(supportedColorFormats[colorFormatIdx]);
347*495ae853SAndroid Build Coastguard Worker   uint32_t numCores = (data[numCoresOfst] % kMaxCores) + 1;
348*495ae853SAndroid Build Coastguard Worker   size_t numDecodeCalls = 0;
349*495ae853SAndroid Build Coastguard Worker   Codec *codec = new Codec(colorFormat, numCores);
350*495ae853SAndroid Build Coastguard Worker   codec->createCodec();
351*495ae853SAndroid Build Coastguard Worker   codec->setArchitecture(arch);
352*495ae853SAndroid Build Coastguard Worker   codec->setCores();
353*495ae853SAndroid Build Coastguard Worker   codec->decodeHeader(data, size);
354*495ae853SAndroid Build Coastguard Worker   codec->setParams(IVD_DECODE_FRAME);
355*495ae853SAndroid Build Coastguard Worker   codec->allocFrame();
356*495ae853SAndroid Build Coastguard Worker 
357*495ae853SAndroid Build Coastguard Worker   while (size > 0 && numDecodeCalls < kMaxNumDecodeCalls) {
358*495ae853SAndroid Build Coastguard Worker     IV_API_CALL_STATUS_T ret;
359*495ae853SAndroid Build Coastguard Worker     size_t bytesConsumed;
360*495ae853SAndroid Build Coastguard Worker     ret = codec->decodeFrame(data, size, &bytesConsumed);
361*495ae853SAndroid Build Coastguard Worker 
362*495ae853SAndroid Build Coastguard Worker     bytesConsumed = std::min(size, bytesConsumed);
363*495ae853SAndroid Build Coastguard Worker     data += bytesConsumed;
364*495ae853SAndroid Build Coastguard Worker     size -= bytesConsumed;
365*495ae853SAndroid Build Coastguard Worker     numDecodeCalls++;
366*495ae853SAndroid Build Coastguard Worker   }
367*495ae853SAndroid Build Coastguard Worker 
368*495ae853SAndroid Build Coastguard Worker   codec->freeFrame();
369*495ae853SAndroid Build Coastguard Worker   codec->deleteCodec();
370*495ae853SAndroid Build Coastguard Worker   delete codec;
371*495ae853SAndroid Build Coastguard Worker   return 0;
372*495ae853SAndroid Build Coastguard Worker }
373