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