Home | History | Annotate | Download | only in test
      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
    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  **/
    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  **/
    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  **/
    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  **/
    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, 0);
    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