Home | History | Annotate | Download | only in mm-camera-interface
      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