1 /* Copyright (c) 2013, 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 #include "mm_jpeg_interface.h" 31 #include "mm_jpeg_ionbuf.h" 32 #include <sys/time.h> 33 34 /** DUMP_TO_FILE: 35 * @filename: file name 36 * @p_addr: address of the buffer 37 * @len: buffer length 38 * 39 * dump the image to the file 40 **/ 41 #define DUMP_TO_FILE(filename, p_addr, len) ({ \ 42 int rc = 0; \ 43 FILE *fp = fopen(filename, "w+"); \ 44 if (fp) { \ 45 rc = fwrite(p_addr, 1, len, fp); \ 46 fclose(fp); \ 47 } else { \ 48 CDBG_ERROR("%s:%d] cannot dump image", __func__, __LINE__); \ 49 } \ 50 }) 51 52 static int g_count = 1, g_i; 53 54 typedef struct { 55 char *filename; 56 int width; 57 int height; 58 char *out_filename; 59 } jpeg_test_input_t; 60 61 static jpeg_test_input_t jpeg_input[] = { 62 {"/data/test.yuv", 1280, 720, "/data/test.jpg"} 63 }; 64 65 typedef struct { 66 char *filename; 67 int width; 68 int height; 69 char *out_filename; 70 pthread_mutex_t lock; 71 pthread_cond_t cond; 72 buffer_test_t input; 73 buffer_test_t output; 74 int use_ion; 75 uint32_t handle; 76 mm_jpeg_ops_t ops; 77 uint32_t job_id[5]; 78 mm_jpeg_encode_params_t params; 79 mm_jpeg_job_t job; 80 uint32_t session_id; 81 } mm_jpeg_intf_test_t; 82 83 static void mm_jpeg_encode_callback(jpeg_job_status_t status, 84 uint32_t client_hdl, 85 uint32_t jobId, 86 mm_jpeg_output_t *p_output, 87 void *userData) 88 { 89 mm_jpeg_intf_test_t *p_obj = (mm_jpeg_intf_test_t *)userData; 90 91 if (status == JPEG_JOB_STATUS_ERROR) { 92 CDBG_ERROR("%s:%d] Encode error", __func__, __LINE__); 93 } else { 94 CDBG_ERROR("%s:%d] Encode success file%s addr %p len %d", 95 __func__, __LINE__, p_obj->out_filename, 96 p_output->buf_vaddr, p_output->buf_filled_len); 97 DUMP_TO_FILE(p_obj->out_filename, p_output->buf_vaddr, p_output->buf_filled_len); 98 } 99 g_i++; 100 if (g_i >= g_count) { 101 CDBG_ERROR("%s:%d] Signal the thread", __func__, __LINE__); 102 pthread_cond_signal(&p_obj->cond); 103 } 104 } 105 106 int mm_jpeg_test_alloc(buffer_test_t *p_buffer, int use_pmem) 107 { 108 int ret = 0; 109 /*Allocate buffers*/ 110 if (use_pmem) { 111 p_buffer->addr = (uint8_t *)buffer_allocate(p_buffer); 112 if (NULL == p_buffer->addr) { 113 CDBG_ERROR("%s:%d] Error",__func__, __LINE__); 114 return -1; 115 } 116 } else { 117 /* Allocate heap memory */ 118 p_buffer->addr = (uint8_t *)malloc(p_buffer->size); 119 if (NULL == p_buffer->addr) { 120 CDBG_ERROR("%s:%d] Error",__func__, __LINE__); 121 return -1; 122 } 123 } 124 return ret; 125 } 126 127 void mm_jpeg_test_free(buffer_test_t *p_buffer) 128 { 129 if (p_buffer->addr == NULL) 130 return; 131 132 if (p_buffer->p_pmem_fd > 0) 133 buffer_deallocate(p_buffer); 134 else 135 free(p_buffer->addr); 136 137 memset(p_buffer, 0x0, sizeof(buffer_test_t)); 138 } 139 140 int mm_jpeg_test_read(mm_jpeg_intf_test_t *p_obj) 141 { 142 int rc = 0; 143 FILE *fp = NULL; 144 int file_size = 0; 145 fp = fopen(p_obj->filename, "rb"); 146 if (!fp) { 147 CDBG_ERROR("%s:%d] error", __func__, __LINE__); 148 return -1; 149 } 150 fseek(fp, 0, SEEK_END); 151 file_size = ftell(fp); 152 fseek(fp, 0, SEEK_SET); 153 CDBG_ERROR("%s:%d] input file size is %d buf_size %ld", 154 __func__, __LINE__, file_size, p_obj->input.size); 155 156 if (p_obj->input.size > file_size) { 157 CDBG_ERROR("%s:%d] error", __func__, __LINE__); 158 fclose(fp); 159 return -1; 160 } 161 fread(p_obj->input.addr, 1, p_obj->input.size, fp); 162 fclose(fp); 163 return 0; 164 } 165 166 static int encode_init(jpeg_test_input_t *p_input, mm_jpeg_intf_test_t *p_obj) 167 { 168 int rc = -1; 169 int size = p_input->width * p_input->height; 170 mm_jpeg_encode_params_t *p_params = &p_obj->params; 171 mm_jpeg_encode_job_t *p_job_params = &p_obj->job.encode_job; 172 173 p_obj->filename = p_input->filename; 174 p_obj->width = p_input->width; 175 p_obj->height = p_input->height; 176 p_obj->out_filename = p_input->out_filename; 177 p_obj->use_ion = 1; 178 179 pthread_mutex_init(&p_obj->lock, NULL); 180 pthread_cond_init(&p_obj->cond, NULL); 181 182 /* allocate buffers */ 183 p_obj->input.size = size * 3/2; 184 rc = mm_jpeg_test_alloc(&p_obj->input, p_obj->use_ion); 185 if (rc) { 186 CDBG_ERROR("%s:%d] Error",__func__, __LINE__); 187 return -1; 188 } 189 190 p_obj->output.size = size * 3/2; 191 rc = mm_jpeg_test_alloc(&p_obj->output, 0); 192 if (rc) { 193 CDBG_ERROR("%s:%d] Error",__func__, __LINE__); 194 return -1; 195 } 196 197 rc = mm_jpeg_test_read(p_obj); 198 if (rc) { 199 CDBG_ERROR("%s:%d] Error",__func__, __LINE__); 200 return -1; 201 } 202 203 /* set encode parameters */ 204 p_params->jpeg_cb = mm_jpeg_encode_callback; 205 p_params->userdata = p_obj; 206 p_params->color_format = MM_JPEG_COLOR_FORMAT_YCRCBLP_H2V2; 207 208 /* dest buffer config */ 209 p_params->dest_buf[0].buf_size = p_obj->output.size; 210 p_params->dest_buf[0].buf_vaddr = p_obj->output.addr; 211 p_params->dest_buf[0].fd = p_obj->output.p_pmem_fd; 212 p_params->dest_buf[0].index = 0; 213 p_params->num_dst_bufs = 1; 214 215 /* src buffer config*/ 216 p_params->src_main_buf[0].buf_size = p_obj->input.size; 217 p_params->src_main_buf[0].buf_vaddr = p_obj->input.addr; 218 p_params->src_main_buf[0].fd = p_obj->input.p_pmem_fd; 219 p_params->src_main_buf[0].index = 0; 220 p_params->src_main_buf[0].format = MM_JPEG_FMT_YUV; 221 p_params->src_main_buf[0].offset.mp[0].len = size; 222 p_params->src_main_buf[0].offset.mp[1].len = size >> 1; 223 p_params->num_src_bufs = 1; 224 225 p_params->encode_thumbnail = 1; 226 p_params->exif_info.numOfEntries = 0; 227 p_params->quality = 80; 228 229 p_job_params->dst_index = 0; 230 p_job_params->src_index = 0; 231 p_job_params->rotation = 0; 232 233 /* main dimension */ 234 p_job_params->main_dim.src_dim.width = p_obj->width; 235 p_job_params->main_dim.src_dim.height = p_obj->height; 236 p_job_params->main_dim.dst_dim.width = p_obj->width; 237 p_job_params->main_dim.dst_dim.height = p_obj->height; 238 p_job_params->main_dim.crop.top = 0; 239 p_job_params->main_dim.crop.left = 0; 240 p_job_params->main_dim.crop.width = p_obj->width; 241 p_job_params->main_dim.crop.height = p_obj->height; 242 243 /* thumb dimension */ 244 p_job_params->thumb_dim.src_dim.width = p_obj->width; 245 p_job_params->thumb_dim.src_dim.height = p_obj->height; 246 p_job_params->thumb_dim.dst_dim.width = 512; 247 p_job_params->thumb_dim.dst_dim.height = 384; 248 p_job_params->thumb_dim.crop.top = 0; 249 p_job_params->thumb_dim.crop.left = 0; 250 p_job_params->thumb_dim.crop.width = p_obj->width; 251 p_job_params->thumb_dim.crop.height = p_obj->height; 252 return 0; 253 } 254 255 static int encode_test(jpeg_test_input_t *p_input) 256 { 257 int rc = 0; 258 mm_jpeg_intf_test_t jpeg_obj; 259 int i = 0; 260 261 memset(&jpeg_obj, 0x0, sizeof(jpeg_obj)); 262 rc = encode_init(p_input, &jpeg_obj); 263 if (rc) { 264 CDBG_ERROR("%s:%d] Error",__func__, __LINE__); 265 return -1; 266 } 267 268 jpeg_obj.handle = jpeg_open(&jpeg_obj.ops); 269 if (jpeg_obj.handle == 0) { 270 CDBG_ERROR("%s:%d] Error",__func__, __LINE__); 271 goto end; 272 } 273 274 rc = jpeg_obj.ops.create_session(jpeg_obj.handle, &jpeg_obj.params, 275 &jpeg_obj.job.encode_job.session_id); 276 if (jpeg_obj.job.encode_job.session_id == 0) { 277 CDBG_ERROR("%s:%d] Error",__func__, __LINE__); 278 goto end; 279 } 280 281 for (i = 0; i < g_count; i++) { 282 jpeg_obj.job.job_type = JPEG_JOB_TYPE_ENCODE; 283 rc = jpeg_obj.ops.start_job(&jpeg_obj.job, &jpeg_obj.job_id[i]); 284 if (rc) { 285 CDBG_ERROR("%s:%d] Error",__func__, __LINE__); 286 goto end; 287 } 288 } 289 290 /* 291 usleep(5); 292 jpeg_obj.ops.abort_job(jpeg_obj.job_id[0]); 293 */ 294 pthread_mutex_lock(&jpeg_obj.lock); 295 pthread_cond_wait(&jpeg_obj.cond, &jpeg_obj.lock); 296 pthread_mutex_unlock(&jpeg_obj.lock); 297 298 jpeg_obj.ops.destroy_session(jpeg_obj.job.encode_job.session_id); 299 300 jpeg_obj.ops.close(jpeg_obj.handle); 301 302 303 end: 304 mm_jpeg_test_free(&jpeg_obj.input); 305 mm_jpeg_test_free(&jpeg_obj.output); 306 return 0; 307 } 308 309 /** main: 310 * 311 * Arguments: 312 * @argc 313 * @argv 314 * 315 * Return: 316 * 0 or -ve values 317 * 318 * Description: 319 * main function 320 * 321 **/ 322 int main(int argc, char* argv[]) 323 { 324 return encode_test(&jpeg_input[0]); 325 } 326 327 328