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 FILE *fp = fopen(filename, "w+"); \ 44 if (fp) { \ 45 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 FILE *fp = NULL; 143 int file_size = 0; 144 fp = fopen(p_obj->filename, "rb"); 145 if (!fp) { 146 CDBG_ERROR("%s:%d] error", __func__, __LINE__); 147 return -1; 148 } 149 fseek(fp, 0, SEEK_END); 150 file_size = ftell(fp); 151 fseek(fp, 0, SEEK_SET); 152 CDBG_ERROR("%s:%d] input file size is %d buf_size %ld", 153 __func__, __LINE__, file_size, p_obj->input.size); 154 155 if (p_obj->input.size > file_size) { 156 CDBG_ERROR("%s:%d] error", __func__, __LINE__); 157 fclose(fp); 158 return -1; 159 } 160 fread(p_obj->input.addr, 1, p_obj->input.size, fp); 161 fclose(fp); 162 return 0; 163 } 164 165 static int encode_init(jpeg_test_input_t *p_input, mm_jpeg_intf_test_t *p_obj) 166 { 167 int rc = -1; 168 int size = p_input->width * p_input->height; 169 mm_jpeg_encode_params_t *p_params = &p_obj->params; 170 mm_jpeg_encode_job_t *p_job_params = &p_obj->job.encode_job; 171 172 p_obj->filename = p_input->filename; 173 p_obj->width = p_input->width; 174 p_obj->height = p_input->height; 175 p_obj->out_filename = p_input->out_filename; 176 p_obj->use_ion = 1; 177 178 pthread_mutex_init(&p_obj->lock, NULL); 179 pthread_cond_init(&p_obj->cond, NULL); 180 181 /* allocate buffers */ 182 p_obj->input.size = size * 3/2; 183 rc = mm_jpeg_test_alloc(&p_obj->input, p_obj->use_ion); 184 if (rc) { 185 CDBG_ERROR("%s:%d] Error",__func__, __LINE__); 186 return -1; 187 } 188 189 p_obj->output.size = size * 3/2; 190 rc = mm_jpeg_test_alloc(&p_obj->output, 0); 191 if (rc) { 192 CDBG_ERROR("%s:%d] Error",__func__, __LINE__); 193 return -1; 194 } 195 196 rc = mm_jpeg_test_read(p_obj); 197 if (rc) { 198 CDBG_ERROR("%s:%d] Error",__func__, __LINE__); 199 return -1; 200 } 201 202 /* set encode parameters */ 203 p_params->jpeg_cb = mm_jpeg_encode_callback; 204 p_params->userdata = p_obj; 205 p_params->color_format = MM_JPEG_COLOR_FORMAT_YCRCBLP_H2V2; 206 207 /* dest buffer config */ 208 p_params->dest_buf[0].buf_size = p_obj->output.size; 209 p_params->dest_buf[0].buf_vaddr = p_obj->output.addr; 210 p_params->dest_buf[0].fd = p_obj->output.p_pmem_fd; 211 p_params->dest_buf[0].index = 0; 212 p_params->num_dst_bufs = 1; 213 214 /* src buffer config*/ 215 p_params->src_main_buf[0].buf_size = p_obj->input.size; 216 p_params->src_main_buf[0].buf_vaddr = p_obj->input.addr; 217 p_params->src_main_buf[0].fd = p_obj->input.p_pmem_fd; 218 p_params->src_main_buf[0].index = 0; 219 p_params->src_main_buf[0].format = MM_JPEG_FMT_YUV; 220 p_params->src_main_buf[0].offset.mp[0].len = size; 221 p_params->src_main_buf[0].offset.mp[1].len = size >> 1; 222 p_params->num_src_bufs = 1; 223 224 p_params->encode_thumbnail = 1; 225 p_params->exif_info.numOfEntries = 0; 226 p_params->quality = 80; 227 228 p_job_params->dst_index = 0; 229 p_job_params->src_index = 0; 230 p_job_params->rotation = 0; 231 232 /* main dimension */ 233 p_job_params->main_dim.src_dim.width = p_obj->width; 234 p_job_params->main_dim.src_dim.height = p_obj->height; 235 p_job_params->main_dim.dst_dim.width = p_obj->width; 236 p_job_params->main_dim.dst_dim.height = p_obj->height; 237 p_job_params->main_dim.crop.top = 0; 238 p_job_params->main_dim.crop.left = 0; 239 p_job_params->main_dim.crop.width = p_obj->width; 240 p_job_params->main_dim.crop.height = p_obj->height; 241 242 /* thumb dimension */ 243 p_job_params->thumb_dim.src_dim.width = p_obj->width; 244 p_job_params->thumb_dim.src_dim.height = p_obj->height; 245 p_job_params->thumb_dim.dst_dim.width = 512; 246 p_job_params->thumb_dim.dst_dim.height = 384; 247 p_job_params->thumb_dim.crop.top = 0; 248 p_job_params->thumb_dim.crop.left = 0; 249 p_job_params->thumb_dim.crop.width = p_obj->width; 250 p_job_params->thumb_dim.crop.height = p_obj->height; 251 return 0; 252 } 253 254 static int encode_test(jpeg_test_input_t *p_input) 255 { 256 int rc = 0; 257 mm_jpeg_intf_test_t jpeg_obj; 258 int i = 0; 259 260 memset(&jpeg_obj, 0x0, sizeof(jpeg_obj)); 261 rc = encode_init(p_input, &jpeg_obj); 262 if (rc) { 263 CDBG_ERROR("%s:%d] Error",__func__, __LINE__); 264 return -1; 265 } 266 267 jpeg_obj.handle = jpeg_open(&jpeg_obj.ops); 268 if (jpeg_obj.handle == 0) { 269 CDBG_ERROR("%s:%d] Error",__func__, __LINE__); 270 goto end; 271 } 272 273 rc = jpeg_obj.ops.create_session(jpeg_obj.handle, &jpeg_obj.params, 274 &jpeg_obj.job.encode_job.session_id); 275 if (jpeg_obj.job.encode_job.session_id == 0) { 276 CDBG_ERROR("%s:%d] Error",__func__, __LINE__); 277 goto end; 278 } 279 280 for (i = 0; i < g_count; i++) { 281 jpeg_obj.job.job_type = JPEG_JOB_TYPE_ENCODE; 282 rc = jpeg_obj.ops.start_job(&jpeg_obj.job, &jpeg_obj.job_id[i]); 283 if (rc) { 284 CDBG_ERROR("%s:%d] Error",__func__, __LINE__); 285 goto end; 286 } 287 } 288 289 /* 290 usleep(5); 291 jpeg_obj.ops.abort_job(jpeg_obj.job_id[0]); 292 */ 293 pthread_mutex_lock(&jpeg_obj.lock); 294 pthread_cond_wait(&jpeg_obj.cond, &jpeg_obj.lock); 295 pthread_mutex_unlock(&jpeg_obj.lock); 296 297 jpeg_obj.ops.destroy_session(jpeg_obj.job.encode_job.session_id); 298 299 jpeg_obj.ops.close(jpeg_obj.handle); 300 301 302 end: 303 mm_jpeg_test_free(&jpeg_obj.input); 304 mm_jpeg_test_free(&jpeg_obj.output); 305 return 0; 306 } 307 308 /** main: 309 * 310 * Arguments: 311 * @argc 312 * @argv 313 * 314 * Return: 315 * 0 or -ve values 316 * 317 * Description: 318 * main function 319 * 320 **/ 321 int main(int argc, char* argv[]) 322 { 323 return encode_test(&jpeg_input[0]); 324 } 325 326 327