1 /* 2 Copyright (c) 2011-2012, The Linux Foundation. All rights reserved. 3 4 Redistribution and use in source and binary forms, with or without 5 modification, are permitted provided that the following conditions are 6 met: 7 * Redistributions of source code must retain the above copyright 8 notice, this list of conditions and the following disclaimer. 9 * Redistributions in binary form must reproduce the above 10 copyright notice, this list of conditions and the following 11 disclaimer in the documentation and/or other materials provided 12 with the distribution. 13 * Neither the name of The Linux Foundation nor the names of its 14 contributors may be used to endorse or promote products derived 15 from this software without specific prior written permission. 16 17 THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED 18 WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 19 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT 20 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS 21 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 24 BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 25 WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 26 OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 27 IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 */ 29 30 #include <sys/time.h> 31 #include <pthread.h> 32 #include <semaphore.h> 33 #include <errno.h> 34 #include "mm_jpeg_encoder.h" 35 #include "mm_camera_dbg.h" 36 #include <sys/system_properties.h> 37 #include "mm_camera_interface2.h" 38 39 #ifdef JPG_DBG 40 #undef CDBG 41 #ifdef _ANDROID_ 42 #undef LOG_NIDEBUG 43 #undef LOG_TAG 44 #define LOG_NIDEBUG 0 45 #define LOG_TAG "mm-camera jpeg" 46 #include <utils/Log.h> 47 #define CDBG(fmt, args...) ALOGV(fmt, ##args) 48 #endif 49 #endif 50 51 #define JPEG_DEFAULT_MAINIMAGE_QUALITY 75 52 #define JPEG_DEFAULT_THUMBNAIL_QUALITY 75 53 54 int is_encoding = 0; 55 pthread_mutex_t jpege_mutex = PTHREAD_MUTEX_INITIALIZER; 56 pthread_mutex_t jpegcb_mutex = PTHREAD_MUTEX_INITIALIZER; 57 58 int rc; 59 jpege_src_t jpege_source; 60 jpege_dst_t jpege_dest; 61 jpege_cfg_t jpege_config; 62 jpege_img_data_t main_img_info, tn_img_info; 63 jpeg_buffer_t temp; 64 jpege_obj_t jpeg_encoder; 65 exif_info_obj_t exif_info; 66 exif_tag_entry_t sample_tag; 67 struct timeval tdBefore, tdAfter; 68 struct timezone tz; 69 static uint32_t jpegMainimageQuality = JPEG_DEFAULT_MAINIMAGE_QUALITY; 70 static uint32_t jpegThumbnailQuality = JPEG_DEFAULT_THUMBNAIL_QUALITY; 71 static uint32_t jpegRotation = 0; 72 static int8_t usethumbnail = 1; 73 static int8_t use_thumbnail_padding = 0; 74 #ifdef HW_ENCODE 75 static uint8_t hw_encode = true; 76 #else 77 static uint8_t hw_encode = false; 78 #endif 79 static int8_t is_3dmode = 0; 80 static cam_3d_frame_format_t img_format_3d; 81 jpegfragment_callback_t mmcamera_jpegfragment_callback = NULL; 82 jpeg_callback_t mmcamera_jpeg_callback = NULL; 83 84 void* user_data = NULL; 85 #define JPEGE_FRAGMENT_SIZE (64*1024) 86 87 /*=========================================================================== 88 FUNCTION jpege_event_handler 89 90 DESCRIPTION Handler function for jpeg encoder events 91 ===========================================================================*/ 92 inline void jpege_use_thumb_padding(uint8_t a_use_thumb_padding) 93 { 94 use_thumbnail_padding = a_use_thumb_padding; 95 } 96 97 void mm_jpeg_encoder_cancel() 98 { 99 pthread_mutex_lock(&jpegcb_mutex); 100 mmcamera_jpegfragment_callback = NULL; 101 mmcamera_jpeg_callback = NULL; 102 user_data = NULL; 103 pthread_mutex_unlock(&jpegcb_mutex); 104 mm_jpeg_encoder_join(); 105 } 106 107 void set_callbacks( 108 jpegfragment_callback_t fragcallback, 109 jpeg_callback_t eventcallback, 110 void* userdata 111 112 ){ 113 pthread_mutex_lock(&jpegcb_mutex); 114 mmcamera_jpegfragment_callback = fragcallback; 115 mmcamera_jpeg_callback = eventcallback; 116 user_data = userdata; 117 pthread_mutex_unlock(&jpegcb_mutex); 118 } 119 120 /*=========================================================================== 121 FUNCTION jpege_event_handler 122 123 DESCRIPTION Handler function for jpeg encoder events 124 ===========================================================================*/ 125 void mm_jpege_event_handler(void *p_user_data, jpeg_event_t event, void *p_arg) 126 { 127 uint32_t buf_size; 128 uint8_t *buf_ptr = NULL; 129 int mainimg_fd, thumbnail_fd; 130 131 if (event == JPEG_EVENT_DONE) { 132 133 jpeg_buffer_t thumbnail_buffer, snapshot_buffer; 134 135 thumbnail_buffer = tn_img_info.p_fragments[0].color.yuv.luma_buf; 136 thumbnail_fd = jpeg_buffer_get_pmem_fd(thumbnail_buffer); 137 jpeg_buffer_get_actual_size(thumbnail_buffer, &buf_size); 138 jpeg_buffer_get_addr(thumbnail_buffer, &buf_ptr); 139 140 snapshot_buffer = main_img_info.p_fragments[0].color.yuv.luma_buf; 141 mainimg_fd = jpeg_buffer_get_pmem_fd(snapshot_buffer); 142 jpeg_buffer_get_actual_size(snapshot_buffer, &buf_size); 143 jpeg_buffer_get_addr(snapshot_buffer, &buf_ptr); 144 145 #if 0 146 gettimeofday(&tdAfter, &tz); 147 CDBG("Profiling: JPEG encoding latency %ld microseconds\n", 148 1000000 * (tdAfter.tv_sec - tdBefore.tv_sec) + tdAfter.tv_usec - 149 tdBefore.tv_usec); 150 #endif 151 // mmcamera_util_profile("encoder done"); 152 } 153 154 if(mmcamera_jpeg_callback) 155 mmcamera_jpeg_callback(event, user_data); 156 } 157 158 /*=========================================================================== 159 FUNCTION jpege_output_produced_handler 160 161 DESCRIPTION Handler function for when jpeg encoder has output produced 162 ===========================================================================*/ 163 void mm_jpege_output_produced_handler(void *p_user_data, void *p_arg, 164 jpeg_buffer_t buffer) 165 { 166 uint32_t buf_size; 167 uint8_t *buf_ptr; 168 169 /* The mutex is to prevent the very rare case where the file writing is */ 170 /* so slow that the next ping-pong output is delivered before the */ 171 /* current one is finished writing, in which case the writing of the new */ 172 /* buffer will be performed after the first one finishes (because of the lock) */ 173 174 jpeg_buffer_get_actual_size(buffer, &buf_size); 175 jpeg_buffer_get_addr(buffer, &buf_ptr); 176 177 pthread_mutex_lock(&jpegcb_mutex); 178 if(mmcamera_jpegfragment_callback) 179 mmcamera_jpegfragment_callback(buf_ptr, buf_size, user_data); 180 pthread_mutex_unlock(&jpegcb_mutex); 181 } 182 183 #if !defined(_TARGET_7x2x_) && !defined(_TARGET_7x27A_) 184 /*=========================================================================== 185 FUNCTION jpege_output_produced_handler2 186 187 DESCRIPTION Handler function for when jpeg encoder has output produced 188 ===========================================================================*/ 189 int mm_jpege_output_produced_handler2(void *p_user_data, void *p_arg, 190 jpeg_buffer_t buffer, uint8_t last_buf_flag) 191 { 192 uint32_t buf_size; 193 uint8_t *buf_ptr; 194 int rv; 195 196 /* The mutex is to prevent the very rare case where the file writing is */ 197 /* so slow that the next ping-pong output is delivered before the */ 198 /* current one is finished writing, in which case the writing of the new */ 199 /* buffer will be performed after the first one finishes (because of the lock) */ 200 jpeg_buffer_get_actual_size(buffer, &buf_size); 201 jpeg_buffer_get_addr(buffer, &buf_ptr); 202 203 pthread_mutex_lock(&jpegcb_mutex); 204 if(mmcamera_jpegfragment_callback) 205 mmcamera_jpegfragment_callback(buf_ptr, buf_size, user_data); 206 pthread_mutex_unlock(&jpegcb_mutex); 207 208 rv = jpeg_buffer_set_actual_size(buffer, 0); 209 if(rv == JPEGERR_SUCCESS){ 210 rv = jpege_enqueue_output_buffer( 211 jpeg_encoder, 212 &buffer, 1); 213 } 214 return rv; 215 } 216 #endif 217 218 static int jpeg_encoder_initialized = 0; 219 220 void mm_jpeg_encoder_set_3D_info(cam_3d_frame_format_t format) 221 { 222 pthread_mutex_lock(&jpege_mutex); 223 is_3dmode = 1; 224 img_format_3d = format; 225 pthread_mutex_unlock(&jpege_mutex); 226 } 227 228 extern int8_t mm_jpeg_encoder_init() 229 { 230 pthread_mutex_lock(&jpege_mutex); 231 is_3dmode = 0; 232 /* Initialize jpeg encoder */ 233 rc = jpege_init(&jpeg_encoder, mm_jpege_event_handler, NULL); 234 if (rc) { 235 //CDBG("jpege_init failed: %d\n", rc); 236 pthread_mutex_unlock(&jpege_mutex); 237 return FALSE; 238 } 239 240 jpeg_encoder_initialized = 1; 241 pthread_mutex_unlock(&jpege_mutex); 242 243 return TRUE; 244 } 245 246 void mm_jpeg_encoder_join(void) 247 { 248 pthread_mutex_lock(&jpege_mutex); 249 if (jpeg_encoder_initialized) { 250 jpeg_encoder_initialized = 0; 251 pthread_mutex_destroy(&jpege_mutex); 252 jpege_abort(jpeg_encoder); 253 jpeg_buffer_destroy(&temp); 254 if (usethumbnail) { 255 jpeg_buffer_destroy(&tn_img_info.p_fragments[0].color.yuv.luma_buf); 256 jpeg_buffer_destroy(&tn_img_info.p_fragments[0].color.yuv.chroma_buf); 257 } 258 jpeg_buffer_destroy(&main_img_info.p_fragments[0].color.yuv.luma_buf); 259 jpeg_buffer_destroy(&main_img_info.p_fragments[0].color.yuv.chroma_buf); 260 jpeg_buffer_destroy(&jpege_dest.buffers[0]); 261 jpeg_buffer_destroy(&jpege_dest.buffers[1]); 262 exif_destroy(&exif_info); 263 jpege_destroy(&jpeg_encoder); 264 } 265 is_3dmode = 0; 266 pthread_mutex_unlock(&jpege_mutex); 267 } 268 /* This function returns the Yoffset and CbCr offset requirements for the Jpeg encoding*/ 269 int8_t mm_jpeg_encoder_get_buffer_offset(uint32_t width, uint32_t height, 270 uint32_t* p_y_offset, uint32_t* p_cbcr_offset, 271 uint32_t* p_buf_size, uint8_t *num_planes, 272 uint32_t planes[]) 273 { 274 CDBG("jpeg_encoder_get_buffer_offset"); 275 if ((NULL == p_y_offset) || (NULL == p_cbcr_offset)) { 276 return FALSE; 277 } 278 /* Hardcode num planes and planes array for now. TBD Check if this 279 * needs to be set based on format. */ 280 *num_planes = 2; 281 if (hw_encode) { 282 int cbcr_offset = 0; 283 uint32_t actual_size = width*height; 284 uint32_t padded_size = width * CEILING16(height); 285 *p_y_offset = 0; 286 *p_cbcr_offset = 0; 287 if ((jpegRotation == 90) || (jpegRotation == 180)) { 288 *p_y_offset = padded_size - actual_size; 289 *p_cbcr_offset = ((padded_size - actual_size) >> 1); 290 } 291 *p_buf_size = padded_size * 3/2; 292 planes[0] = width * CEILING16(height); 293 planes[1] = width * CEILING16(height)/2; 294 } else { 295 *p_y_offset = 0; 296 *p_cbcr_offset = PAD_TO_WORD(width*CEILING16(height)); 297 *p_buf_size = *p_cbcr_offset * 3/2; 298 planes[0] = PAD_TO_WORD(width*CEILING16(height)); 299 planes[1] = PAD_TO_WORD(width*CEILING16(height)/2); 300 } 301 return TRUE; 302 } 303 304 int8_t mm_jpeg_encoder_encode(const cam_ctrl_dimension_t * dimension, 305 const uint8_t * thumbnail_buf, 306 int thumbnail_fd, uint32_t thumbnail_offset, 307 const uint8_t * snapshot_buf, 308 int snapshot_fd, 309 uint32_t snapshot_offset, 310 common_crop_t *scaling_params, 311 exif_tags_info_t *exif_data, 312 int exif_numEntries, 313 const int32_t a_cbcroffset, 314 cam_point_t* main_crop_offset, 315 cam_point_t* thumb_crop_offset) 316 { 317 int buf_size = 0; 318 int ret = 0; 319 int i = 0; 320 int cbcroffset = 0; 321 int actual_size = 0, padded_size = 0; 322 usethumbnail = thumbnail_buf ? 1 : 0; 323 int w_scale_factor = (is_3dmode && img_format_3d == SIDE_BY_SIDE_FULL) ? 2 : 1; 324 325 pthread_mutex_lock(&jpege_mutex); 326 //mmcamera_util_profile("encoder configure"); 327 328 /* Do not allow snapshot if the previous one is not done */ 329 /* Alternately we can queue the snapshot to be done after the one in progress is completed, */ 330 /* but it involves more complex logic */ 331 if (is_encoding) { 332 CDBG("Previous Jpeg Encoding is not done!\n"); 333 pthread_mutex_unlock(&jpege_mutex); 334 return FALSE; 335 } 336 CDBG("jpeg_encoder_encode: thumbnail_fd = %d snapshot_fd = %d usethumbnail %d\n", 337 thumbnail_fd, snapshot_fd, usethumbnail); 338 339 gettimeofday(&tdBefore, &tz); 340 /* Initialize exif info */ 341 exif_init(&exif_info); 342 /* Zero out supporting structures */ 343 memset(&main_img_info, 0, sizeof(jpege_img_data_t)); 344 memset(&tn_img_info, 0, sizeof(jpege_img_data_t)); 345 memset(&jpege_source, 0, sizeof(jpege_src_t)); 346 memset(&jpege_dest, 0, sizeof(jpege_dst_t)); 347 348 /* Initialize JPEG buffers */ 349 jpege_dest.buffer_cnt = 2; 350 if ((rc = jpeg_buffer_init(&temp)) || 351 (usethumbnail && (rc = jpeg_buffer_init(&tn_img_info.p_fragments[0].color.yuv.luma_buf))) || 352 (usethumbnail && (rc = jpeg_buffer_init(&tn_img_info.p_fragments[0].color.yuv.chroma_buf))) || 353 (rc = jpeg_buffer_init(&main_img_info.p_fragments[0].color.yuv.luma_buf)) || 354 (rc = jpeg_buffer_init(&main_img_info.p_fragments[0].color.yuv.chroma_buf)) 355 || (rc = jpeg_buffer_init(&jpege_dest.buffers[0])) 356 || (rc = jpeg_buffer_init(&jpege_dest.buffers[1]))) { 357 CDBG_ERROR("jpeg_buffer_init failed: %d\n", rc); 358 pthread_mutex_unlock(&jpege_mutex); 359 jpege_dest.buffer_cnt = 0; 360 return FALSE; 361 } 362 #if !defined(_TARGET_7x2x_) && !defined(_TARGET_7x27A_) 363 jpege_dest.p_buffer = &jpege_dest.buffers[0]; 364 #endif 365 366 #if defined(_TARGET_7x27A_) 367 /* Allocate 2 ping-pong buffers on the heap for jpeg encoder outputs */ 368 if ((rc = jpeg_buffer_allocate(jpege_dest.buffers[0], JPEGE_FRAGMENT_SIZE, 1)) || 369 (rc = jpeg_buffer_allocate(jpege_dest.buffers[1], JPEGE_FRAGMENT_SIZE, 1))) { 370 CDBG("jpeg_buffer_allocate failed: %d\n", rc); 371 pthread_mutex_unlock(&jpege_mutex); 372 return FALSE; 373 } 374 #else 375 /* Allocate 2 ping-pong buffers on the heap for jpeg encoder outputs */ 376 if ((rc = jpeg_buffer_allocate(jpege_dest.buffers[0], JPEGE_FRAGMENT_SIZE, 0)) || 377 (rc = jpeg_buffer_allocate(jpege_dest.buffers[1], JPEGE_FRAGMENT_SIZE, 0))) { 378 CDBG("jpeg_buffer_allocate failed: %d\n", rc); 379 pthread_mutex_unlock(&jpege_mutex); 380 return FALSE; 381 } 382 #endif 383 384 385 if (usethumbnail) { 386 tn_img_info.width = dimension->thumbnail_width * w_scale_factor; 387 tn_img_info.height = dimension->thumbnail_height; 388 buf_size = tn_img_info.width * tn_img_info.height * 2; 389 tn_img_info.fragment_cnt = 1; 390 tn_img_info.color_format = YCRCBLP_H2V2; 391 tn_img_info.p_fragments[0].width = tn_img_info.width; 392 tn_img_info.p_fragments[0].height = CEILING16(dimension->thumbnail_height); 393 jpeg_buffer_reset(tn_img_info.p_fragments[0].color.yuv.luma_buf); 394 jpeg_buffer_reset(tn_img_info.p_fragments[0].color.yuv.chroma_buf); 395 396 CDBG("%s: Thumbnail: fd: %d offset: %d Main: fd: %d offset: %d", __func__, 397 thumbnail_fd, thumbnail_offset, snapshot_fd, snapshot_offset); 398 rc = jpeg_buffer_use_external_buffer( 399 tn_img_info.p_fragments[0].color.yuv.luma_buf, 400 (uint8_t *)thumbnail_buf, buf_size, 401 thumbnail_fd); 402 403 if (rc == JPEGERR_EFAILED) { 404 CDBG_ERROR("jpeg_buffer_use_external_buffer Thumbnail pmem failed...\n"); 405 pthread_mutex_unlock(&jpege_mutex); 406 return FALSE; 407 } 408 409 cbcroffset = PAD_TO_WORD(tn_img_info.width * tn_img_info.height); 410 if (hw_encode) { 411 actual_size = dimension->thumbnail_width * dimension->thumbnail_height; 412 padded_size = dimension->thumbnail_width * 413 CEILING16(dimension->thumbnail_height); 414 cbcroffset = padded_size; 415 } 416 417 // The chroma plane in YUV4:2:0 semiplanar is at the end of the luma plane, 418 // so we attach the chroma buf to the luma buffer, which we've allocated to 419 // be large enough to hold the entire YUV image. 420 // 421 jpeg_buffer_attach_existing(tn_img_info.p_fragments[0].color.yuv.chroma_buf, 422 tn_img_info.p_fragments[0].color.yuv.luma_buf, 423 cbcroffset); 424 jpeg_buffer_set_actual_size(tn_img_info.p_fragments[0].color.yuv.luma_buf, 425 tn_img_info.width * tn_img_info.height); 426 jpeg_buffer_set_actual_size( 427 tn_img_info.p_fragments[0].color.yuv.chroma_buf, tn_img_info.width * 428 tn_img_info.height / 2); 429 430 if (hw_encode) { 431 if ((jpegRotation == 90) || (jpegRotation == 180)) { 432 jpeg_buffer_set_start_offset(tn_img_info.p_fragments[0].color.yuv.luma_buf, (padded_size - actual_size)); 433 jpeg_buffer_set_start_offset(tn_img_info.p_fragments[0].color.yuv.chroma_buf, ((padded_size - actual_size) >> 1)); 434 } 435 } 436 } 437 438 /* Set phy offset */ 439 jpeg_buffer_set_phy_offset(tn_img_info.p_fragments[0].color.yuv.luma_buf, thumbnail_offset); 440 441 CDBG("jpeg_encoder_encode size %dx%d\n",dimension->orig_picture_dx,dimension->orig_picture_dy); 442 main_img_info.width = dimension->orig_picture_dx * w_scale_factor; 443 main_img_info.height = dimension->orig_picture_dy; 444 buf_size = main_img_info.width * main_img_info.height * 2; 445 main_img_info.fragment_cnt = 1; 446 main_img_info.color_format = YCRCBLP_H2V2; 447 main_img_info.p_fragments[0].width = main_img_info.width; 448 main_img_info.p_fragments[0].height = CEILING16(main_img_info.height); 449 jpeg_buffer_reset(main_img_info.p_fragments[0].color.yuv.luma_buf); 450 jpeg_buffer_reset(main_img_info.p_fragments[0].color.yuv.chroma_buf); 451 452 rc = 453 jpeg_buffer_use_external_buffer( 454 main_img_info.p_fragments[0].color.yuv.luma_buf, 455 (uint8_t *)snapshot_buf, buf_size, 456 snapshot_fd); 457 458 if (rc == JPEGERR_EFAILED) { 459 CDBG("jpeg_buffer_use_external_buffer Snapshot pmem failed...\n"); 460 pthread_mutex_unlock(&jpege_mutex); 461 return FALSE; 462 } 463 cbcroffset = PAD_TO_WORD(main_img_info.width * CEILING16(main_img_info.height)); 464 actual_size = 0; 465 padded_size = 0; 466 if (a_cbcroffset >= 0) { 467 cbcroffset = a_cbcroffset; 468 } else { 469 if (hw_encode) { 470 actual_size = dimension->orig_picture_dx * dimension->orig_picture_dy; 471 padded_size = dimension->orig_picture_dx * CEILING16(dimension->orig_picture_dy); 472 cbcroffset = padded_size; 473 } 474 } 475 476 CDBG("jpeg_encoder_encode: cbcroffset %d",cbcroffset); 477 jpeg_buffer_attach_existing(main_img_info.p_fragments[0].color.yuv.chroma_buf, 478 main_img_info.p_fragments[0].color.yuv.luma_buf, 479 cbcroffset); 480 jpeg_buffer_set_actual_size(main_img_info.p_fragments[0].color.yuv.luma_buf, main_img_info.width * main_img_info.height); 481 jpeg_buffer_set_actual_size(main_img_info.p_fragments[0].color.yuv.chroma_buf, main_img_info.width * main_img_info.height / 2); 482 483 if (hw_encode) { 484 if ((jpegRotation == 90) || (jpegRotation == 180)) { 485 jpeg_buffer_set_start_offset(main_img_info.p_fragments[0].color.yuv.luma_buf, (padded_size - actual_size)); 486 jpeg_buffer_set_start_offset(main_img_info.p_fragments[0].color.yuv.chroma_buf, ((padded_size - actual_size) >> 1)); 487 } 488 } 489 490 jpeg_buffer_set_phy_offset(main_img_info.p_fragments[0].color.yuv.luma_buf, snapshot_offset); 491 492 /* Set Source */ 493 jpege_source.p_main = &main_img_info; 494 if (usethumbnail) { 495 jpege_source.p_thumbnail = &tn_img_info; 496 CDBG("fragment_cnt: thumb %d \n", jpege_source.p_thumbnail->fragment_cnt); 497 } 498 499 CDBG("fragment_cnt: main %d \n", jpege_source.p_main->fragment_cnt); 500 501 rc = jpege_set_source(jpeg_encoder, &jpege_source); 502 if (rc) { 503 CDBG("jpege_set_source failed: %d\n", rc); 504 pthread_mutex_unlock(&jpege_mutex); 505 return FALSE; 506 } 507 508 #if defined(_TARGET_7x2x_) || defined(_TARGET_7x27A_) 509 jpege_dest.p_output_handler = (jpege_output_handler_t) mm_jpege_output_produced_handler; 510 #else 511 jpege_dest.p_output_handler = mm_jpege_output_produced_handler2; 512 #endif 513 514 jpege_dest.buffer_cnt = 2; 515 rc = jpege_set_destination(jpeg_encoder, &jpege_dest); 516 if (rc) { 517 CDBG("jpege_set_desination failed: %d\n", rc); 518 pthread_mutex_unlock(&jpege_mutex); 519 return FALSE; 520 } 521 /* Get default configuration */ 522 jpege_get_default_config(&jpege_config); 523 jpege_config.thumbnail_present = usethumbnail; 524 if(hw_encode) 525 jpege_config.preference = JPEG_ENCODER_PREF_HW_ACCELERATED_PREFERRED; 526 else 527 jpege_config.preference = JPEG_ENCODER_PREF_SOFTWARE_ONLY; 528 529 CDBG("%s: preference %d ", __func__, jpege_config.preference); 530 jpege_config.main_cfg.quality = jpegMainimageQuality; 531 jpege_config.thumbnail_cfg.quality = jpegThumbnailQuality; 532 533 CDBG("Scaling params thumb in1_w %d in1_h %d out1_w %d out1_h %d " 534 "main_img in2_w %d in2_h %d out2_w %d out2_h %d\n", 535 scaling_params->in1_w, scaling_params->in1_h, 536 scaling_params->out1_w, scaling_params->out1_h, 537 scaling_params->in2_w, scaling_params->in2_h, 538 scaling_params->out2_w, scaling_params->out2_h); 539 540 if(scaling_params->in2_w && scaling_params->in2_h) { 541 542 if(jpegRotation) 543 jpege_config.preference = JPEG_ENCODER_PREF_SOFTWARE_ONLY; 544 545 /* Scaler information for main image */ 546 jpege_config.main_cfg.scale_cfg.enable = TRUE; 547 548 jpege_config.main_cfg.scale_cfg.input_width = CEILING2(scaling_params->in2_w); 549 jpege_config.main_cfg.scale_cfg.input_height = CEILING2(scaling_params->in2_h); 550 551 if (main_crop_offset) { 552 jpege_config.main_cfg.scale_cfg.h_offset = main_crop_offset->x; 553 jpege_config.main_cfg.scale_cfg.v_offset = main_crop_offset->y; 554 } else { 555 jpege_config.main_cfg.scale_cfg.h_offset = 0; 556 jpege_config.main_cfg.scale_cfg.v_offset = 0; 557 } 558 559 jpege_config.main_cfg.scale_cfg.output_width = scaling_params->out2_w; 560 jpege_config.main_cfg.scale_cfg.output_height = scaling_params->out2_h; 561 } else { 562 CDBG("There is no scaling information for JPEG main image scaling."); 563 } 564 565 if(scaling_params->in1_w && scaling_params->in1_h) { 566 /* Scaler information for thumbnail */ 567 jpege_config.thumbnail_cfg.scale_cfg.enable = TRUE; 568 569 jpege_config.thumbnail_cfg.scale_cfg.input_width = CEILING2(scaling_params->in1_w); 570 jpege_config.thumbnail_cfg.scale_cfg.input_height = CEILING2(scaling_params->in1_h); 571 572 if (thumb_crop_offset) { 573 jpege_config.thumbnail_cfg.scale_cfg.h_offset = thumb_crop_offset->x; 574 jpege_config.thumbnail_cfg.scale_cfg.v_offset = thumb_crop_offset->y; 575 } else { 576 jpege_config.thumbnail_cfg.scale_cfg.h_offset = 0; 577 jpege_config.thumbnail_cfg.scale_cfg.v_offset = 0; 578 } 579 580 jpege_config.thumbnail_cfg.scale_cfg.output_width = scaling_params->out1_w; 581 jpege_config.thumbnail_cfg.scale_cfg.output_height = scaling_params->out1_h; 582 } else { 583 CDBG("There is no scaling information for JPEG thumbnail upscaling."); 584 } 585 586 /* Set rotation based on the mode selected */ 587 CDBG(" Setting Jpeg Rotation mode to %d ", jpegRotation ); 588 jpege_config.main_cfg.rotation_degree_clk = jpegRotation; 589 jpege_config.thumbnail_cfg.rotation_degree_clk = jpegRotation; 590 591 if( exif_data != NULL) { 592 for(i = 0; i < exif_numEntries; i++) { 593 rc = exif_set_tag(exif_info, exif_data[i].tag_id, 594 &(exif_data[i].tag_entry)); 595 if (rc) { 596 CDBG("exif_set_tag failed: %d\n", rc); 597 pthread_mutex_unlock(&jpege_mutex); 598 return FALSE; 599 } 600 } 601 } 602 603 #if 0 /* Enable when JPS/MPO is ready */ 604 /* 3D config */ 605 CDBG("%s: is_3dmode %d ", __func__, is_3dmode ); 606 if (is_3dmode) { 607 jps_cfg_3d_t cfg_3d; 608 if (jpege_config.main_cfg.scale_cfg.enable || 609 (jpege_config.main_cfg.rotation_degree_clk > 0)) { 610 CDBG("%s: img_format_3d %d ", __func__, img_format_3d ); 611 return FALSE; 612 } 613 CDBG("%s: img_format_3d %d ", __func__, img_format_3d ); 614 615 switch (img_format_3d) { 616 case TOP_DOWN_HALF: 617 cfg_3d.layout = OVER_UNDER; 618 cfg_3d.width_flag = FULL_WIDTH; 619 cfg_3d.height_flag = HALF_HEIGHT; 620 cfg_3d.field_order = LEFT_FIELD_FIRST; 621 cfg_3d.separation = 0; 622 break; 623 case TOP_DOWN_FULL: 624 cfg_3d.layout = OVER_UNDER; 625 cfg_3d.width_flag = FULL_WIDTH; 626 cfg_3d.height_flag = FULL_HEIGHT; 627 cfg_3d.field_order = LEFT_FIELD_FIRST; 628 cfg_3d.separation = 0; 629 break; 630 case SIDE_BY_SIDE_HALF: 631 cfg_3d.layout = SIDE_BY_SIDE; 632 cfg_3d.width_flag = HALF_WIDTH; 633 cfg_3d.height_flag = FULL_HEIGHT; 634 cfg_3d.field_order = LEFT_FIELD_FIRST; 635 cfg_3d.separation = 0; 636 break; 637 default: 638 case SIDE_BY_SIDE_FULL: 639 cfg_3d.layout = SIDE_BY_SIDE; 640 cfg_3d.width_flag = FULL_WIDTH; 641 cfg_3d.height_flag = FULL_HEIGHT; 642 cfg_3d.field_order = LEFT_FIELD_FIRST; 643 cfg_3d.separation = 0; 644 break; 645 } 646 647 rc = jpse_config_3d(jpeg_encoder, cfg_3d); 648 if (rc) { 649 CDBG_ERROR("%s: jpse_config_3d failed: %d\n", __func__, rc); 650 pthread_mutex_unlock(&jpege_mutex); 651 return FALSE; 652 } 653 } 654 #endif 655 656 /* Start encoder */ 657 /* 658 if( jpege_config.main_cfg.scale_cfg.enable) { 659 mmcamera_util_profile("SW encoder starting encoding"); 660 } else { 661 mmcamera_util_profile("HW encoder starting encoding"); 662 } 663 */ 664 rc = jpege_start(jpeg_encoder, &jpege_config, &exif_info); 665 if (rc) { 666 CDBG("jpege_start failed: %d\n", rc); 667 pthread_mutex_unlock(&jpege_mutex); 668 return FALSE; 669 } 670 671 pthread_mutex_unlock(&jpege_mutex); 672 return TRUE; 673 } 674 675 int8_t mm_jpeg_encoder_setMainImageQuality(uint32_t quality) 676 { 677 pthread_mutex_lock(&jpege_mutex); 678 CDBG(" jpeg_encoder_setMainImageQuality current main inage quality %d ," \ 679 " new quality : %d\n", jpegMainimageQuality, quality); 680 if (quality <= 100) 681 jpegMainimageQuality = quality; 682 pthread_mutex_unlock(&jpege_mutex); 683 return TRUE; 684 } 685 686 int8_t mm_jpeg_encoder_setThumbnailQuality(uint32_t quality) 687 { 688 pthread_mutex_lock(&jpege_mutex); 689 CDBG(" jpeg_encoder_setThumbnailQuality current thumbnail quality %d ," \ 690 " new quality : %d\n", jpegThumbnailQuality, quality); 691 if (quality <= 100) 692 jpegThumbnailQuality = quality; 693 pthread_mutex_unlock(&jpege_mutex); 694 return TRUE; 695 } 696 697 int8_t mm_jpeg_encoder_setRotation(int rotation) 698 { 699 pthread_mutex_lock(&jpege_mutex); 700 /* Set rotation configuration */ 701 switch(rotation) 702 { 703 case 0: 704 case 90: 705 case 180: 706 case 270: 707 jpegRotation = rotation; 708 break; 709 default: 710 /* Invalid rotation mode, set to default */ 711 CDBG(" Setting Default rotation mode "); 712 jpegRotation = 0; 713 break; 714 } 715 pthread_mutex_unlock(&jpege_mutex); 716 return TRUE; 717 } 718