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