1 /* Copyright (c) 2015-2016, The Linux Foundation. All rights reserved.
2 *
3 * Redistribution and use in source and binary forms, with or without
4 * modification, are permitted provided that the following conditions are
5 * met:
6 * * Redistributions of source code must retain the above copyright
7 * notice, this list of conditions and the following disclaimer.
8 * * Redistributions in binary form must reproduce the above
9 * copyright notice, this list of conditions and the following
10 * disclaimer in the documentation and/or other materials provided
11 * with the distribution.
12 * * Neither the name of The Linux Foundation nor the names of its
13 * contributors may be used to endorse or promote products derived
14 * from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
23 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
25 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
26 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 *
28 */
29
30 // System dependencies
31 #include <dlfcn.h>
32 #include <stdbool.h>
33 #include <stdlib.h>
34 #include <sys/time.h>
35
36 // Camera dependencies
37 #include "img_buffer.h"
38 #include "mm_lib2d.h"
39
40
41 #define ENABLE_OUTPUT_DUMP 1
42 #define ALIGN4K 4032
43 #define ALIGN(a, b) (((a) + (b)) & ~(b))
44
45
46 /** DUMP_TO_FILE:
47 * @filename: file name
48 * @p_addr: address of the buffer
49 * @len: buffer length
50 *
51 * dump the image to the file
52 **/
53 #define DUMP_TO_FILE(filename, p_addr, len) ({ \
54 size_t rc = 0; \
55 FILE *fp = fopen(filename, "w+"); \
56 if (fp) { \
57 rc = fwrite(p_addr, 1, len, fp); \
58 printf(" ] written size %zu \n", __LINE__, len); \
59 fclose(fp); \
60 } else { \
61 printf(" ] open %s failed \n", __LINE__, filename); \
62 } \
63 })
64
65 /** DUMP_TO_FILE2:
66 * @filename: file name
67 * @p_addr: address of the buffer
68 * @len: buffer length
69 *
70 * dump the image to the file if the memory is non-contiguous
71 **/
72 #define DUMP_TO_FILE2(filename, p_addr1, len1, p_addr2, len2) ({ \
73 size_t rc = 0; \
74 FILE *fp = fopen(filename, "w+"); \
75 if (fp) { \
76 rc = fwrite(p_addr1, 1, len1, fp); \
77 rc = fwrite(p_addr2, 1, len2, fp); \
78 printf(" ] written %zu %zu \n", __LINE__, len1, len2); \
79 fclose(fp); \
80 } else { \
81 printf(" ] open %s failed \n", __LINE__, filename); \
82 } \
83 })
84
85 /** img_lib_buffert
86 * @ptr: handle to the imglib library
87 * @img_buffer_get: function pointer to img_buffer_get
88 * @img_buffer_release: function pointer to img_buffer_release
89 * @img_buffer_cacheops: function pointer to img_buffer_cacheops
90 **/
91 typedef struct {
92 void *ptr;
93 int (*img_buffer_get)(img_buf_type_t type, int heapid, int8_t cached, int length,
94 img_mem_handle_t *p_handle);
95 int (*img_buffer_release)(img_mem_handle_t *p_handle);
96 int (*img_buffer_cacheops)(img_mem_handle_t *p_handle, img_cache_ops_t ops,
97 img_mem_alloc_type_t mem_alloc_type);
98 } img_lib_buffert;
99
100 /** input_yuv_data
101 * @filename: input test filename
102 * @format: format of the input yuv frame
103 * @wdith: wdith of the input yuv frame
104 * @height: height of the input yuv frame
105 * @stride: stride of the input yuv frame
106 * @offset: offset to the yuv data in the input file
107 **/
108 typedef struct input_yuv_data_t {
109 char filename[512];
110 cam_format_t format;
111 int32_t wdith;
112 int32_t height;
113 int32_t stride;
114 int32_t offset;
115 } input_yuv_data;
116
117 input_yuv_data input_nv21[] = {
118 {"sample0_768x512.yuv", CAM_FORMAT_YUV_420_NV21, 768, 512, 768, 0},
119 {"sample1_3200x2400.yuv", CAM_FORMAT_YUV_420_NV21, 3200, 2400, 3200, 0},
120 {"sample2_1920x1080.yuv", CAM_FORMAT_YUV_420_NV21, 1920, 1080, 1920, 0},
121 {"sample3_3200x2400.yuv", CAM_FORMAT_YUV_420_NV21, 3200, 2400, 3200, 0},
122 {"sample4_4208x3120.yuv", CAM_FORMAT_YUV_420_NV21, 4208, 3120, 4208, 0},
123 {"sample5_1984x2592.yuv", CAM_FORMAT_YUV_420_NV21, 1984, 2592, 1984, 0},
124 {"sample6_4000_3000.yuv", CAM_FORMAT_YUV_420_NV21, 4000, 3000, 4000, 0},
125 {"sample7_3200_2400.yuv", CAM_FORMAT_YUV_420_NV21, 3200, 2400, 3200, 0},
126 {"sample8_3008_4000.yuv", CAM_FORMAT_YUV_420_NV21, 3008, 4000, 3008, 0},
127 {"sample9_5312x2988.yuv", CAM_FORMAT_YUV_420_NV21, 5312, 2988, 5312, 0},
128 {"sample10_4128x3096.yuv", CAM_FORMAT_YUV_420_NV21, 4128, 3096, 4128, 0},
129 {"sample11_4208x3120.yuv", CAM_FORMAT_YUV_420_NV21, 4208, 3120, 4208, 0},
130 {"sample12_3200x2400.yuv", CAM_FORMAT_YUV_420_NV21, 3200, 2400, 3200, 0},
131 {"sample13_width_1080_height_1440_stride_1088.yuv", CAM_FORMAT_YUV_420_NV21, 1080, 1440, 1088, 0},
132 {"sample14_width_1080_height_1920_stride_1088.yuv", CAM_FORMAT_YUV_420_NV21, 1080, 1920, 1088, 0},
133 {"sample15_width_1944_height_2592_stride_1984.yuv", CAM_FORMAT_YUV_420_NV21, 1944, 2592, 1984, 0},
134 {"sample16_width_3000_height_4000_stride_3008.yuv", CAM_FORMAT_YUV_420_NV21, 3000, 4000, 3008, 0},
135 {"sample17_width_3120_height_4208_stride_3136.yuv", CAM_FORMAT_YUV_420_NV21, 3120, 4208, 3136, 0},
136 {"sample18_width_3200_height_2400_stride_3200.yuv", CAM_FORMAT_YUV_420_NV21, 3200, 2400, 3200, 0},
137 {"sample19_width_1944_height_2592_stride_1984.yuv", CAM_FORMAT_YUV_420_NV21, 1944, 2592, 1984, 0},
138 };
139
140 // assuming buffer format is always ARGB
lib2d_dump_tga(void * addr,cam_format_t format,int width,int height,int stride,char * fname)141 void lib2d_dump_tga(void *addr, cam_format_t format, int width,
142 int height, int stride, char *fname)
143 {
144 int i, j;
145 FILE *f;
146 unsigned char *pb = (unsigned char *)addr;
147 uint32_t *pd = (uint32_t *)addr;
148 int bpp = 32;
149
150 f = fopen(fname, "wb");
151 if (f) {
152 // header
153 fprintf(f, "%c%c%c%c", 0, 0, 2, 0);
154 fprintf(f, "%c%c%c%c", 0, 0, 0, 0);
155 fprintf(f, "%c%c%c%c", 0, 0, 0, 0);
156 fprintf(f, "%c%c%c%c", width & 0xff, width >> 8, height & 0xff, height >> 8);
157 fprintf(f, "%c%c", bpp, 32);
158
159 for (i = 0; i < height; i++) {
160 for (j = 0; j < width; j++) {
161 fprintf(f, "%c%c%c%c",
162 pd[(i*stride>>2)+j] & 0xff, // b
163 (pd[(i*stride>>2)+j] >> 8) & 0xff, // g
164 (pd[(i*stride>>2)+j] >> 16) & 0xff, // r
165 (pd[(i*stride>>2)+j] >> 24) & 0xff); // a
166 }
167 }
168 fclose(f);
169 }
170 }
171
172 /**
173 * Function: lib2d_test_client_cb
174 *
175 * Description: Callback that is called on completion of requested job.
176 *
177 * Input parameters:
178 * userdata - App userdata
179 * jobid - job id that is finished execution
180 *
181 * Return values:
182 * MM_LIB2D_SUCCESS
183 * MM_LIB2D_ERR_GENERAL
184 *
185 * Notes: none
186 **/
lib2d_test_client_cb(void * userdata,int jobid)187 lib2d_error lib2d_test_client_cb(void *userdata, int jobid)
188 {
189 printf("%s %d, jobid=%d \n", __LINE__, jobid);
190 return MM_LIB2D_SUCCESS;
191 }
192
193 /**
194 * Function: lib2d_test_load_input_yuv_data
195 *
196 * Description: Loads yuv data from input file.
197 *
198 * Input parameters:
199 * fileName - input yuv filename
200 * offset - offset to the yuv data in the input file
201 * y_size - y plane size in input yuv file
202 * crcb_size - crcb plane size in input yuv file
203 * crcb_offset - crcb offset in the memory at
204 * which crcb data need to be loaded
205 * addr - y plane memory address where y plane
206 * data need to be loaded.
207 *
208 * Return values:
209 * MM_LIB2D_SUCCESS
210 * MM_LIB2D_ERR_GENERAL
211 *
212 * Notes: none
213 **/
lib2d_test_load_input_yuv_data(char * fileName,int offset,int32_t y_size,int32_t crcb_size,int32_t crcb_offset,void * addr)214 lib2d_error lib2d_test_load_input_yuv_data(char *fileName, int offset,
215 int32_t y_size, int32_t crcb_size, int32_t crcb_offset,
216 void *addr)
217 {
218 size_t i;
219 FILE *fp = 0;
220 void *y_ptr = addr;
221 void *crcb_ptr = (uint8_t *)addr + crcb_offset;
222
223 printf("y_ptr=%p, crcb_ptr=%p \n", y_ptr, crcb_ptr);
224
225 fp = fopen(fileName, "rb");
226 if(fp) {
227 if(offset) {
228 fseek(fp, offset, SEEK_SET);
229 }
230 i = fread(y_ptr, 1, y_size, fp);
231 i = fread(crcb_ptr, 1, crcb_size, fp);
232
233 fclose( fp );
234 } else {
235 printf("failed to open file %s \n", fileName);
236 return MM_LIB2D_ERR_GENERAL;
237 }
238
239 return MM_LIB2D_SUCCESS;
240 }
241
242 /**
243 * Function: lib2d_test_load_input_yuv_data
244 *
245 * Description: Loads yuv data from input file.
246 *
247 * Input parameters:
248 * fileName - input yuv filename
249 * offset - offset to the yuv data in the input file
250 * input_yuv_stride - y plane stride in input yuv file
251 * y_plane_stride - y plane stride in buffer memory
252 * height - height of yuv image
253 * crcb_offset - crcb offset in the memory at
254 * which crcb data need to be loaded
255 * addr - y plane memory address where y plane
256 * data need to be loaded.
257 *
258 * Return values:
259 * MM_LIB2D_SUCCESS
260 * MM_LIB2D_ERR_GENERAL
261 *
262 * Notes: none
263 **/
lib2d_test_load_input_yuv_data_linebyline(char * fileName,int offset,int32_t input_yuv_stride,int32_t y_plane_stride,int32_t height,int32_t crcb_offset,void * addr)264 lib2d_error lib2d_test_load_input_yuv_data_linebyline(char *fileName,
265 int offset, int32_t input_yuv_stride, int32_t y_plane_stride,
266 int32_t height, int32_t crcb_offset, void *addr)
267 {
268 size_t i;
269 FILE *fp = 0;
270 void *y_ptr = addr;
271 void *crcb_ptr = (uint8_t *)addr + crcb_offset;
272
273 printf("y_ptr=%p, crcb_ptr=%p \n", y_ptr, crcb_ptr);
274
275 fp = fopen(fileName, "rb");
276 if(fp) {
277 if(offset) {
278 fseek(fp, offset, SEEK_SET);
279 }
280 if (input_yuv_stride == y_plane_stride) {
281 //load y plane
282 i = fread(y_ptr, 1, (input_yuv_stride * height), fp);
283 // load UV plane
284 i = fread(crcb_ptr, 1, (input_yuv_stride * height / 2), fp);
285 } else {
286 int line = 0;
287 // load Y plane
288 for (line = 0;line < height; line++) {
289 i = fread(y_ptr, 1, input_yuv_stride, fp);
290 y_ptr = (void *)((uint8_t *)y_ptr + y_plane_stride);
291 }
292 for (line = 0;line < height; line++) {
293 i = fread(crcb_ptr, 1, input_yuv_stride, fp);
294 crcb_ptr = (void *)((uint8_t *)crcb_ptr + y_plane_stride);
295 }
296 }
297
298 fclose( fp );
299 } else {
300 printf("failed to open file %s \n", fileName);
301 return MM_LIB2D_ERR_GENERAL;
302 }
303
304 return MM_LIB2D_SUCCESS;
305 }
306
307 /**
308 * Function: main
309 *
310 * Description: main function for execution
311 *
312 * Input parameters:
313 * argc - no.of input arguments
314 * argv - list of arguments
315 *
316 * Return values:
317 * 0 on success
318 * -1 on failure
319 *
320 * Notes: none
321 **/
main(int32_t argc,const char * argv[])322 int main(int32_t argc, const char * argv[])
323 {
324 void *lib2d_handle = NULL;
325 lib2d_error lib2d_err = MM_LIB2D_SUCCESS;
326 mm_lib2d_buffer src_buffer = {0};
327 mm_lib2d_buffer dst_buffer = {0};
328 int8_t ret = IMG_SUCCESS;
329 int32_t width = 0;
330 int32_t height = 0;
331 int32_t input_yuv_stride = 0;
332 int32_t stride = 0;
333 int32_t y_plane_stride = 0;
334 int32_t crcb_plane_stride = 0;
335 int32_t y_plane_size = 0;
336 int32_t y_plane_size_align = 0;
337 int32_t crcb_plane_size = 0;
338 int32_t yuv_size = 0;
339 int32_t rgb_size = 0;
340 img_mem_handle_t m_yuv_memHandle = { 0 };
341 img_mem_handle_t m_rgb_memHandle = { 0 };
342 char filename_in[512] = { 0 };
343 char filename_out[512] = { 0 };
344 char filename_raw[512] = { 0 };
345 int32_t offset = 0;
346 unsigned int total_tests = 1;
347 cam_format_t format = CAM_FORMAT_YUV_420_NV21;
348 unsigned int index;
349 const char *filename;
350
351 // Open Imglib library and get the function pointers for
352 // buffer allocation, free, cacheops
353 img_lib_buffert img_lib;
354 img_lib.ptr = dlopen("libmmcamera_imglib.so", RTLD_NOW);
355 if (!img_lib.ptr) {
356 printf("%s ERROR: couldn't dlopen libmmcamera_imglib.so: %s",
357 dlerror());
358 return -1;
359 }
360
361 /* Get function pointer for functions to allocate ion memory */
362 *(void **)&img_lib.img_buffer_get =
363 dlsym(img_lib.ptr, "img_buffer_get");
364 *(void **)&img_lib.img_buffer_release =
365 dlsym(img_lib.ptr, "img_buffer_release");
366 *(void **)&img_lib.img_buffer_cacheops =
367 dlsym(img_lib.ptr, "img_buffer_cacheops");
368
369 /* Validate function pointers */
370 if ((img_lib.img_buffer_get == NULL) ||
371 (img_lib.img_buffer_release == NULL) ||
372 (img_lib.img_buffer_cacheops == NULL)) {
373 printf(" ERROR mapping symbols from libmmcamera_imglib.so");
374 dlclose(img_lib.ptr);
375 return -1;
376 }
377
378 lib2d_err = mm_lib2d_init(MM_LIB2D_SYNC_MODE, CAM_FORMAT_YUV_420_NV21,
379 CAM_FORMAT_8888_ARGB, &lib2d_handle);
380 if ((lib2d_err != MM_LIB2D_SUCCESS) || (lib2d_handle == NULL)) {
381 return -1;
382 }
383
384 bool run_default = FALSE;
385
386 if ( argc == 7) {
387 filename = argv[1];
388 width = (uint32_t)atoi(argv[2]);
389 height = (uint32_t)atoi(argv[3]);
390 input_yuv_stride = (uint32_t)atoi(argv[4]);
391 offset = (uint32_t)atoi(argv[5]);
392 format = (uint32_t)atoi(argv[6]);
393 run_default = TRUE;
394 printf("Running user provided conversion \n");
395 }
396 else {
397 total_tests = sizeof(input_nv21)/sizeof(input_yuv_data);
398 printf("usage: <binary> <filname> <width> <height> "
399 "<stride> <offset> <format> \n");
400 }
401
402 for (index = 0; index < total_tests; index++)
403 {
404 if(run_default == FALSE) {
405 filename = input_nv21[index].filename;
406 width = input_nv21[index].wdith;
407 height = input_nv21[index].height;
408 input_yuv_stride = input_nv21[index].stride;
409 offset = input_nv21[index].offset;
410 format = input_nv21[index].format;
411 }
412
413 snprintf(filename_in, 512, "/data/lib2d/input/%s", filename);
414 snprintf(filename_out, 512, "/data/lib2d/output/%s.tga", filename);
415 snprintf(filename_raw, 512, "/data/lib2d/output/%s.rgba", filename);
416
417 printf("-----------------Running test=%d/%d------------------------- \n",
418 index+1, total_tests);
419 printf("filename=%s, full path=%s, width=%d, height=%d, stride=%d \n",
420 filename, filename_in, width, height, stride);
421
422 // Allocate NV12 buffer
423 y_plane_stride = ALIGN(width, 32);
424 y_plane_size = y_plane_stride * height;
425 y_plane_size_align = ALIGN(y_plane_size, ALIGN4K);
426 crcb_plane_stride = y_plane_stride;
427 crcb_plane_size = crcb_plane_stride * height / 2;
428 yuv_size = y_plane_size_align + crcb_plane_size;
429 ret = img_lib.img_buffer_get(IMG_BUFFER_ION_IOMMU, -1, TRUE,
430 yuv_size, &m_yuv_memHandle);
431 if (ret != IMG_SUCCESS) {
432 printf(" ] Error, img buf get failed \n");
433 goto deinit;
434 }
435
436 printf("%s %d yuv buffer properties : w=%d, h=%d, y_stride=%d, "
437 "crcb_stride=%d, y_size=%d, crcb_size=%d, yuv_size=%d, "
438 "crcb_offset=%d \n",
439 __LINE__,
440 width, height, y_plane_stride, crcb_plane_stride, y_plane_size,
441 crcb_plane_size, yuv_size, y_plane_size_align);
442 printf("%s %d yuv buffer properties : fd=%d, ptr=%p, size=%d \n",
443 __LINE__, m_yuv_memHandle.fd, m_yuv_memHandle.vaddr,
444 m_yuv_memHandle.length);
445
446 // Allocate ARGB buffer
447 stride = width * 4;
448 stride = ALIGN(stride, 32);
449 rgb_size = stride * height;
450 ret = img_lib.img_buffer_get(IMG_BUFFER_ION_IOMMU, -1, TRUE,
451 rgb_size, &m_rgb_memHandle);
452 if (ret != IMG_SUCCESS) {
453 printf(" ] Error, img buf get failed");
454 img_lib.img_buffer_release(&m_yuv_memHandle);
455 goto deinit;
456 }
457
458 printf("%s %d rgb buffer properties : w=%d, h=%d, stride=%d, size=%d \n",
459 __LINE__, width, height, stride, rgb_size);
460 printf("%s %d rgb buffer properties : fd=%d, ptr=%p, size=%d \n",
461 __LINE__, m_rgb_memHandle.fd, m_rgb_memHandle.vaddr,
462 m_rgb_memHandle.length);
463
464 #if 0
465 lib2d_err = lib2d_test_load_input_yuv_data(filename_in, offset,
466 (input_yuv_stride * height), (input_yuv_stride * height / 2), y_plane_size_align,
467 m_yuv_memHandle.vaddr);
468 if (lib2d_err != MM_LIB2D_SUCCESS) {
469 printf(" ] Error loading the input buffer \n");
470 goto release;
471 }
472 #else
473 lib2d_err = lib2d_test_load_input_yuv_data_linebyline(filename_in, offset,
474 input_yuv_stride, y_plane_stride,height, y_plane_size_align,
475 m_yuv_memHandle.vaddr);
476 if (lib2d_err != MM_LIB2D_SUCCESS) {
477 printf(" ] Error loading the input buffer \n");
478 goto release;
479 }
480 #endif
481 // Setup source buffer
482 src_buffer.buffer_type = MM_LIB2D_BUFFER_TYPE_YUV;
483 src_buffer.yuv_buffer.fd = m_yuv_memHandle.fd;
484 src_buffer.yuv_buffer.format = format;
485 src_buffer.yuv_buffer.width = width;
486 src_buffer.yuv_buffer.height = height;
487 src_buffer.yuv_buffer.plane0 = m_yuv_memHandle.vaddr;
488 src_buffer.yuv_buffer.stride0 = y_plane_stride;
489 src_buffer.yuv_buffer.plane1 = (int8_t *)m_yuv_memHandle.vaddr +
490 y_plane_size_align;
491 src_buffer.yuv_buffer.stride1 = crcb_plane_stride;
492
493 // Setup dst buffer
494 dst_buffer.buffer_type = MM_LIB2D_BUFFER_TYPE_RGB;
495 dst_buffer.rgb_buffer.fd = m_rgb_memHandle.fd;
496 dst_buffer.rgb_buffer.format = CAM_FORMAT_8888_ARGB;
497 dst_buffer.rgb_buffer.width = width;
498 dst_buffer.rgb_buffer.height = height;
499 dst_buffer.rgb_buffer.buffer = m_rgb_memHandle.vaddr;
500 dst_buffer.rgb_buffer.stride = stride;
501
502 img_lib.img_buffer_cacheops(&m_yuv_memHandle,
503 IMG_CACHE_CLEAN_INV, IMG_INTERNAL);
504
505 lib2d_err = mm_lib2d_start_job(lib2d_handle, &src_buffer, &dst_buffer,
506 index, NULL, lib2d_test_client_cb);
507 if (lib2d_err != MM_LIB2D_SUCCESS) {
508 printf(" ] Error in mm_lib2d_start_job \n");
509 goto release;
510 }
511
512 img_lib.img_buffer_cacheops(&m_rgb_memHandle,
513 IMG_CACHE_CLEAN_INV, IMG_INTERNAL);
514
515 #ifdef ENABLE_OUTPUT_DUMP
516 // Dump output files
517 // snprintf(filename_in, 512, "/data/lib2d/output/%s", filename);
518 // DUMP_TO_FILE2(filename_in, src_buffer.yuv_buffer.plane0, y_plane_size, src_buffer.yuv_buffer.plane1, crcb_plane_size);
519 // DUMP_TO_FILE(filename_raw, dst_buffer.rgb_buffer.buffer, rgb_size);
520 printf("Dumping output file %s \n", filename_out);
521 lib2d_dump_tga(dst_buffer.rgb_buffer.buffer, 1,
522 width, height, stride, filename_out);
523 #endif
524
525 img_lib.img_buffer_release(&m_rgb_memHandle);
526 img_lib.img_buffer_release(&m_yuv_memHandle);
527 }
528
529 mm_lib2d_deinit(lib2d_handle);
530
531 return 0;
532
533 release:
534 img_lib.img_buffer_release(&m_rgb_memHandle);
535 img_lib.img_buffer_release(&m_yuv_memHandle);
536 deinit:
537 mm_lib2d_deinit(lib2d_handle);
538 printf("%s %d some error happened, tests completed = %d/%d \n",
539 __LINE__, index - 1, total_tests);
540 return -1;
541 }
542
543
544