Home | History | Annotate | Download | only in src
      1 /* Copyright (c) 2013-2014, 2016, 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 // System dependencies
     31 #include <pthread.h>
     32 
     33 // JPEG dependencies
     34 #include "mm_jpeg_dbg.h"
     35 #include "mm_jpeg_interface.h"
     36 #include "mm_jpeg.h"
     37 #include "mm_jpeg_inlines.h"
     38 
     39 OMX_ERRORTYPE mm_jpegdec_ebd(OMX_HANDLETYPE hComponent,
     40   OMX_PTR pAppData,
     41   OMX_BUFFERHEADERTYPE *pBuffer);
     42 OMX_ERRORTYPE mm_jpegdec_fbd(OMX_HANDLETYPE hComponent,
     43     OMX_PTR pAppData,
     44     OMX_BUFFERHEADERTYPE* pBuffer);
     45 OMX_ERRORTYPE mm_jpegdec_event_handler(OMX_HANDLETYPE hComponent,
     46     OMX_PTR pAppData,
     47     OMX_EVENTTYPE eEvent,
     48     OMX_U32 nData1,
     49     OMX_U32 nData2,
     50     OMX_PTR pEventData);
     51 
     52 
     53 /** mm_jpegdec_destroy_job
     54  *
     55  *  Arguments:
     56  *    @p_session: Session obj
     57  *
     58  *  Return:
     59  *       0 for success else failure
     60  *
     61  *  Description:
     62  *       Destroy the job based paramenters
     63  *
     64  **/
     65 static int32_t mm_jpegdec_destroy_job(mm_jpeg_job_session_t *p_session)
     66 {
     67   int32_t rc = 0;
     68 
     69   return rc;
     70 }
     71 
     72 /** mm_jpeg_job_done:
     73  *
     74  *  Arguments:
     75  *    @p_session: decode session
     76  *
     77  *  Return:
     78  *       OMX_ERRORTYPE
     79  *
     80  *  Description:
     81  *       Finalize the job
     82  *
     83  **/
     84 static void mm_jpegdec_job_done(mm_jpeg_job_session_t *p_session)
     85 {
     86   mm_jpeg_obj *my_obj = (mm_jpeg_obj *)p_session->jpeg_obj;
     87   mm_jpeg_job_q_node_t *node = NULL;
     88 
     89   /*Destroy job related params*/
     90   mm_jpegdec_destroy_job(p_session);
     91 
     92   /*remove the job*/
     93   node = mm_jpeg_queue_remove_job_by_job_id(&my_obj->ongoing_job_q,
     94     p_session->jobId);
     95   if (node) {
     96     free(node);
     97   }
     98   p_session->encoding = OMX_FALSE;
     99 
    100   /* wake up jobMgr thread to work on new job if there is any */
    101   cam_sem_post(&my_obj->job_mgr.job_sem);
    102 }
    103 
    104 
    105 /** mm_jpegdec_session_send_buffers:
    106  *
    107  *  Arguments:
    108  *    @data: job session
    109  *
    110  *  Return:
    111  *       OMX error values
    112  *
    113  *  Description:
    114  *       Send the buffers to OMX layer
    115  *
    116  **/
    117 OMX_ERRORTYPE mm_jpegdec_session_send_buffers(void *data)
    118 {
    119   uint32_t i = 0;
    120   mm_jpeg_job_session_t* p_session = (mm_jpeg_job_session_t *)data;
    121   OMX_ERRORTYPE ret = OMX_ErrorNone;
    122   QOMX_BUFFER_INFO lbuffer_info;
    123   mm_jpeg_decode_params_t *p_params = &p_session->dec_params;
    124 
    125   memset(&lbuffer_info, 0x0, sizeof(QOMX_BUFFER_INFO));
    126   for (i = 0; i < p_params->num_src_bufs; i++) {
    127     LOGD("Source buffer %d", i);
    128     lbuffer_info.fd = (OMX_U32)p_params->src_main_buf[i].fd;
    129     ret = OMX_UseBuffer(p_session->omx_handle, &(p_session->p_in_omx_buf[i]), 0,
    130       &lbuffer_info, p_params->src_main_buf[i].buf_size,
    131       p_params->src_main_buf[i].buf_vaddr);
    132     if (ret) {
    133       LOGE("Error %d", ret);
    134       return ret;
    135     }
    136   }
    137 
    138   LOGD("Exit");
    139   return ret;
    140 }
    141 
    142 /** mm_jpeg_session_free_buffers:
    143  *
    144  *  Arguments:
    145  *    @data: job session
    146  *
    147  *  Return:
    148  *       OMX error values
    149  *
    150  *  Description:
    151  *       Free the buffers from OMX layer
    152  *
    153  **/
    154 OMX_ERRORTYPE mm_jpegdec_session_free_buffers(void *data)
    155 {
    156   OMX_ERRORTYPE ret = OMX_ErrorNone;
    157   uint32_t i = 0;
    158   mm_jpeg_job_session_t* p_session = (mm_jpeg_job_session_t *)data;
    159   mm_jpeg_decode_params_t *p_params = &p_session->dec_params;
    160 
    161   for (i = 0; i < p_params->num_src_bufs; i++) {
    162     LOGD("Source buffer %d", i);
    163     ret = OMX_FreeBuffer(p_session->omx_handle, 0, p_session->p_in_omx_buf[i]);
    164     if (ret) {
    165       LOGE("Error %d", ret);
    166       return ret;
    167     }
    168   }
    169 
    170   for (i = 0; i < p_params->num_dst_bufs; i++) {
    171     LOGD("Dest buffer %d", i);
    172     ret = OMX_FreeBuffer(p_session->omx_handle, 1, p_session->p_out_omx_buf[i]);
    173     if (ret) {
    174       LOGE("Error");
    175       return ret;
    176     }
    177   }
    178   LOGD("Exit");
    179   return ret;
    180 }
    181 
    182 /** mm_jpegdec_session_create:
    183  *
    184  *  Arguments:
    185  *    @p_session: job session
    186  *
    187  *  Return:
    188  *       OMX error types
    189  *
    190  *  Description:
    191  *       Create a jpeg encode session
    192  *
    193  **/
    194 OMX_ERRORTYPE mm_jpegdec_session_create(mm_jpeg_job_session_t* p_session)
    195 {
    196   OMX_ERRORTYPE rc = OMX_ErrorNone;
    197 
    198   pthread_mutex_init(&p_session->lock, NULL);
    199   pthread_cond_init(&p_session->cond, NULL);
    200   cirq_reset(&p_session->cb_q);
    201   p_session->state_change_pending = OMX_FALSE;
    202   p_session->abort_state = MM_JPEG_ABORT_NONE;
    203   p_session->error_flag = OMX_ErrorNone;
    204   p_session->ebd_count = 0;
    205   p_session->fbd_count = 0;
    206   p_session->encode_pid = -1;
    207   p_session->config = OMX_FALSE;
    208 
    209   p_session->omx_callbacks.EmptyBufferDone = mm_jpegdec_ebd;
    210   p_session->omx_callbacks.FillBufferDone = mm_jpegdec_fbd;
    211   p_session->omx_callbacks.EventHandler = mm_jpegdec_event_handler;
    212   p_session->exif_count_local = 0;
    213 
    214   rc = OMX_GetHandle(&p_session->omx_handle,
    215     "OMX.qcom.image.jpeg.decoder",
    216     (void *)p_session,
    217     &p_session->omx_callbacks);
    218 
    219   if (OMX_ErrorNone != rc) {
    220     LOGE("OMX_GetHandle failed (%d)", rc);
    221     return rc;
    222   }
    223   return rc;
    224 }
    225 
    226 /** mm_jpegdec_session_destroy:
    227  *
    228  *  Arguments:
    229  *    @p_session: job session
    230  *
    231  *  Return:
    232  *       none
    233  *
    234  *  Description:
    235  *       Destroy a jpeg encode session
    236  *
    237  **/
    238 void mm_jpegdec_session_destroy(mm_jpeg_job_session_t* p_session)
    239 {
    240   OMX_ERRORTYPE rc = OMX_ErrorNone;
    241 
    242   LOGD("E");
    243   if (NULL == p_session->omx_handle) {
    244     LOGE("invalid handle");
    245     return;
    246   }
    247 
    248   rc = mm_jpeg_session_change_state(p_session, OMX_StateIdle, NULL);
    249   if (rc) {
    250     LOGE("Error");
    251   }
    252 
    253   rc = mm_jpeg_session_change_state(p_session, OMX_StateLoaded,
    254     mm_jpegdec_session_free_buffers);
    255   if (rc) {
    256     LOGE("Error");
    257   }
    258 
    259   rc = OMX_FreeHandle(p_session->omx_handle);
    260   if (0 != rc) {
    261     LOGE("OMX_FreeHandle failed (%d)", rc);
    262   }
    263   p_session->omx_handle = NULL;
    264 
    265 
    266   pthread_mutex_destroy(&p_session->lock);
    267   pthread_cond_destroy(&p_session->cond);
    268   LOGD("X");
    269 }
    270 
    271 /** mm_jpeg_session_config_port:
    272  *
    273  *  Arguments:
    274  *    @p_session: job session
    275  *
    276  *  Return:
    277  *       OMX error values
    278  *
    279  *  Description:
    280  *       Configure OMX ports
    281  *
    282  **/
    283 OMX_ERRORTYPE mm_jpegdec_session_config_ports(mm_jpeg_job_session_t* p_session)
    284 {
    285   OMX_ERRORTYPE ret = OMX_ErrorNone;
    286   mm_jpeg_decode_params_t *p_params = &p_session->dec_params;
    287   mm_jpeg_decode_job_t *p_jobparams = &p_session->decode_job;
    288 
    289   mm_jpeg_buf_t *p_src_buf =
    290     &p_params->src_main_buf[p_jobparams->src_index];
    291 
    292   p_session->inputPort.nPortIndex = 0;
    293   p_session->outputPort.nPortIndex = 1;
    294 
    295 
    296   ret = OMX_GetParameter(p_session->omx_handle, OMX_IndexParamPortDefinition,
    297     &p_session->inputPort);
    298   if (ret) {
    299     LOGE("failed");
    300     return ret;
    301   }
    302 
    303   ret = OMX_GetParameter(p_session->omx_handle, OMX_IndexParamPortDefinition,
    304     &p_session->outputPort);
    305   if (ret) {
    306     LOGE("failed");
    307     return ret;
    308   }
    309 
    310   p_session->inputPort.format.image.nFrameWidth =
    311     (OMX_U32)p_jobparams->main_dim.src_dim.width;
    312   p_session->inputPort.format.image.nFrameHeight =
    313     (OMX_U32)p_jobparams->main_dim.src_dim.height;
    314   p_session->inputPort.format.image.nStride =
    315     p_src_buf->offset.mp[0].stride;
    316   p_session->inputPort.format.image.nSliceHeight =
    317     (OMX_U32)p_src_buf->offset.mp[0].scanline;
    318   p_session->inputPort.format.image.eColorFormat =
    319     map_jpeg_format(p_params->color_format);
    320   p_session->inputPort.nBufferSize =
    321     p_params->src_main_buf[p_jobparams->src_index].buf_size;
    322   p_session->inputPort.nBufferCountActual = (OMX_U32)p_params->num_src_bufs;
    323   ret = OMX_SetParameter(p_session->omx_handle, OMX_IndexParamPortDefinition,
    324     &p_session->inputPort);
    325   if (ret) {
    326     LOGE("failed");
    327     return ret;
    328   }
    329 
    330   return ret;
    331 }
    332 
    333 
    334 /** mm_jpegdec_session_config_main:
    335  *
    336  *  Arguments:
    337  *    @p_session: job session
    338  *
    339  *  Return:
    340  *       OMX error values
    341  *
    342  *  Description:
    343  *       Configure main image
    344  *
    345  **/
    346 OMX_ERRORTYPE mm_jpegdec_session_config_main(mm_jpeg_job_session_t *p_session)
    347 {
    348   OMX_ERRORTYPE rc = OMX_ErrorNone;
    349 
    350   /* config port */
    351   LOGD("config port");
    352   rc = mm_jpegdec_session_config_ports(p_session);
    353   if (OMX_ErrorNone != rc) {
    354     LOGE("config port failed");
    355     return rc;
    356   }
    357 
    358 
    359   /* TODO: config crop */
    360 
    361   return rc;
    362 }
    363 
    364 /** mm_jpeg_session_configure:
    365  *
    366  *  Arguments:
    367  *    @data: encode session
    368  *
    369  *  Return:
    370  *       none
    371  *
    372  *  Description:
    373  *       Configure the session
    374  *
    375  **/
    376 static OMX_ERRORTYPE mm_jpegdec_session_configure(mm_jpeg_job_session_t *p_session)
    377 {
    378   OMX_ERRORTYPE ret = OMX_ErrorNone;
    379 
    380   LOGD("E ");
    381 
    382   MM_JPEG_CHK_ABORT(p_session, ret, error);
    383 
    384   /* config main img */
    385   ret = mm_jpegdec_session_config_main(p_session);
    386   if (OMX_ErrorNone != ret) {
    387     LOGE("config main img failed");
    388     goto error;
    389   }
    390 
    391   /* TODO: common config (if needed) */
    392 
    393   ret = mm_jpeg_session_change_state(p_session, OMX_StateIdle,
    394     mm_jpegdec_session_send_buffers);
    395   if (ret) {
    396     LOGE("change state to idle failed %d", ret);
    397     goto error;
    398   }
    399 
    400   ret = mm_jpeg_session_change_state(p_session, OMX_StateExecuting,
    401     NULL);
    402   if (ret) {
    403     LOGE("change state to executing failed %d", ret);
    404     goto error;
    405   }
    406 
    407 error:
    408   LOGD("X ret %d", ret);
    409   return ret;
    410 }
    411 
    412 static OMX_ERRORTYPE mm_jpeg_session_port_enable(
    413     mm_jpeg_job_session_t *p_session,
    414     OMX_U32 nPortIndex,
    415     OMX_BOOL wait)
    416 {
    417   OMX_ERRORTYPE ret = OMX_ErrorNone;
    418   OMX_EVENTTYPE lEvent;
    419 
    420   pthread_mutex_lock(&p_session->lock);
    421   p_session->event_pending = OMX_TRUE;
    422   pthread_mutex_unlock(&p_session->lock);
    423 
    424   ret = OMX_SendCommand(p_session->omx_handle, OMX_CommandPortEnable,
    425       nPortIndex, NULL);
    426 
    427   if (ret) {
    428     LOGE("failed");
    429     return ret;
    430   }
    431 
    432   if (wait == OMX_TRUE) {
    433     // Wait for cmd complete
    434     pthread_mutex_lock(&p_session->lock);
    435     if (p_session->event_pending == OMX_TRUE) {
    436       LOGD("before wait");
    437       pthread_cond_wait(&p_session->cond, &p_session->lock);
    438       lEvent = p_session->omxEvent;
    439       LOGD("after wait");
    440     }
    441     lEvent = p_session->omxEvent;
    442     pthread_mutex_unlock(&p_session->lock);
    443 
    444     if (lEvent != OMX_EventCmdComplete) {
    445       LOGD("Unexpected event %d",lEvent);
    446       return OMX_ErrorUndefined;
    447     }
    448   }
    449   return OMX_ErrorNone;
    450 }
    451 
    452 static OMX_ERRORTYPE mm_jpeg_session_port_disable(
    453     mm_jpeg_job_session_t *p_session,
    454     OMX_U32 nPortIndex,
    455     OMX_BOOL wait)
    456 {
    457   OMX_ERRORTYPE ret = OMX_ErrorNone;
    458   OMX_EVENTTYPE lEvent;
    459 
    460   pthread_mutex_lock(&p_session->lock);
    461   p_session->event_pending = OMX_TRUE;
    462   pthread_mutex_unlock(&p_session->lock);
    463 
    464   ret = OMX_SendCommand(p_session->omx_handle, OMX_CommandPortDisable,
    465       nPortIndex, NULL);
    466 
    467   if (ret) {
    468     LOGE("failed");
    469     return ret;
    470   }
    471   if (wait == OMX_TRUE) {
    472     // Wait for cmd complete
    473     pthread_mutex_lock(&p_session->lock);
    474     if (p_session->event_pending == OMX_TRUE) {
    475       LOGD("before wait");
    476       pthread_cond_wait(&p_session->cond, &p_session->lock);
    477 
    478       LOGD("after wait");
    479     }
    480     lEvent = p_session->omxEvent;
    481     pthread_mutex_unlock(&p_session->lock);
    482 
    483     if (lEvent != OMX_EventCmdComplete) {
    484       LOGD("Unexpected event %d",lEvent);
    485       return OMX_ErrorUndefined;
    486     }
    487   }
    488   return OMX_ErrorNone;
    489 }
    490 
    491 
    492 /** mm_jpegdec_session_decode:
    493  *
    494  *  Arguments:
    495  *    @p_session: encode session
    496  *
    497  *  Return:
    498  *       OMX_ERRORTYPE
    499  *
    500  *  Description:
    501  *       Start the encoding
    502  *
    503  **/
    504 static OMX_ERRORTYPE mm_jpegdec_session_decode(mm_jpeg_job_session_t *p_session)
    505 {
    506   OMX_ERRORTYPE ret = OMX_ErrorNone;
    507   mm_jpeg_decode_params_t *p_params = &p_session->dec_params;
    508   mm_jpeg_decode_job_t *p_jobparams = &p_session->decode_job;
    509   OMX_EVENTTYPE lEvent;
    510   uint32_t i;
    511   QOMX_BUFFER_INFO lbuffer_info;
    512 
    513   pthread_mutex_lock(&p_session->lock);
    514   p_session->abort_state = MM_JPEG_ABORT_NONE;
    515   p_session->encoding = OMX_FALSE;
    516   pthread_mutex_unlock(&p_session->lock);
    517 
    518   if (OMX_FALSE == p_session->config) {
    519     ret = mm_jpegdec_session_configure(p_session);
    520     if (ret) {
    521       LOGE("Error");
    522       goto error;
    523     }
    524     p_session->config = OMX_TRUE;
    525   }
    526 
    527   pthread_mutex_lock(&p_session->lock);
    528   p_session->encoding = OMX_TRUE;
    529   pthread_mutex_unlock(&p_session->lock);
    530 
    531   MM_JPEG_CHK_ABORT(p_session, ret, error);
    532 
    533   p_session->event_pending = OMX_TRUE;
    534 
    535   ret = OMX_EmptyThisBuffer(p_session->omx_handle,
    536     p_session->p_in_omx_buf[p_jobparams->src_index]);
    537   if (ret) {
    538     LOGE("Error");
    539     goto error;
    540   }
    541 
    542   // Wait for port settings changed
    543   pthread_mutex_lock(&p_session->lock);
    544   if (p_session->event_pending == OMX_TRUE) {
    545     LOGD("before wait");
    546     pthread_cond_wait(&p_session->cond, &p_session->lock);
    547   }
    548   lEvent = p_session->omxEvent;
    549   LOGD("after wait");
    550   pthread_mutex_unlock(&p_session->lock);
    551 
    552   if (lEvent != OMX_EventPortSettingsChanged) {
    553     LOGD("Unexpected event %d",lEvent);
    554     goto error;
    555   }
    556 
    557   // Disable output port (wait)
    558   mm_jpeg_session_port_disable(p_session,
    559       p_session->outputPort.nPortIndex,
    560       OMX_TRUE);
    561 
    562   // Get port definition
    563   ret = OMX_GetParameter(p_session->omx_handle, OMX_IndexParamPortDefinition,
    564       &p_session->outputPort);
    565   if (ret) {
    566     LOGE("failed");
    567     return ret;
    568   }
    569 
    570   // Set port definition
    571   p_session->outputPort.format.image.nFrameWidth =
    572     (OMX_U32)p_jobparams->main_dim.dst_dim.width;
    573   p_session->outputPort.format.image.nFrameHeight =
    574     (OMX_U32)p_jobparams->main_dim.dst_dim.height;
    575   p_session->outputPort.format.image.eColorFormat =
    576     map_jpeg_format(p_params->color_format);
    577 
    578   p_session->outputPort.nBufferSize =
    579      p_params->dest_buf[p_jobparams->dst_index].buf_size;
    580    p_session->outputPort.nBufferCountActual = (OMX_U32)p_params->num_dst_bufs;
    581 
    582    p_session->outputPort.format.image.nSliceHeight =
    583        (OMX_U32)
    584        p_params->dest_buf[p_jobparams->dst_index].offset.mp[0].scanline;
    585    p_session->outputPort.format.image.nStride =
    586        p_params->dest_buf[p_jobparams->dst_index].offset.mp[0].stride;
    587 
    588    ret = OMX_SetParameter(p_session->omx_handle, OMX_IndexParamPortDefinition,
    589      &p_session->outputPort);
    590    if (ret) {
    591      LOGE("failed");
    592      return ret;
    593    }
    594 
    595   // Enable port (no wait)
    596   mm_jpeg_session_port_enable(p_session,
    597       p_session->outputPort.nPortIndex,
    598       OMX_FALSE);
    599 
    600   memset(&lbuffer_info, 0x0, sizeof(QOMX_BUFFER_INFO));
    601   // Use buffers
    602   for (i = 0; i < p_params->num_dst_bufs; i++) {
    603     lbuffer_info.fd = (OMX_U32)p_params->dest_buf[i].fd;
    604     LOGD("Dest buffer %d", (unsigned int)i);
    605     ret = OMX_UseBuffer(p_session->omx_handle, &(p_session->p_out_omx_buf[i]),
    606         1, &lbuffer_info, p_params->dest_buf[i].buf_size,
    607         p_params->dest_buf[i].buf_vaddr);
    608     if (ret) {
    609       LOGE("Error");
    610       return ret;
    611     }
    612   }
    613 
    614   // Wait for port enable completion
    615   pthread_mutex_lock(&p_session->lock);
    616   if (p_session->event_pending == OMX_TRUE) {
    617     LOGD("before wait");
    618     pthread_cond_wait(&p_session->cond, &p_session->lock);
    619     lEvent = p_session->omxEvent;
    620     LOGD("after wait");
    621   }
    622   lEvent = p_session->omxEvent;
    623   pthread_mutex_unlock(&p_session->lock);
    624 
    625   if (lEvent != OMX_EventCmdComplete) {
    626     LOGD("Unexpected event %d",lEvent);
    627     goto error;
    628   }
    629 
    630   ret = OMX_FillThisBuffer(p_session->omx_handle,
    631     p_session->p_out_omx_buf[p_jobparams->dst_index]);
    632   if (ret) {
    633     LOGE("Error");
    634     goto error;
    635   }
    636 
    637   MM_JPEG_CHK_ABORT(p_session, ret, error);
    638 
    639 error:
    640 
    641   LOGD("X ");
    642   return ret;
    643 }
    644 
    645 /** mm_jpegdec_process_decoding_job:
    646  *
    647  *  Arguments:
    648  *    @my_obj: jpeg client
    649  *    @job_node: job node
    650  *
    651  *  Return:
    652  *       0 for success -1 otherwise
    653  *
    654  *  Description:
    655  *       Start the encoding job
    656  *
    657  **/
    658 int32_t mm_jpegdec_process_decoding_job(mm_jpeg_obj *my_obj, mm_jpeg_job_q_node_t* job_node)
    659 {
    660   mm_jpeg_q_data_t qdata;
    661   int32_t rc = 0;
    662   OMX_ERRORTYPE ret = OMX_ErrorNone;
    663   mm_jpeg_job_session_t *p_session = NULL;
    664 
    665   /* check if valid session */
    666   p_session = mm_jpeg_get_session(my_obj, job_node->dec_info.job_id);
    667   if (NULL == p_session) {
    668     LOGE("invalid job id %x",
    669       job_node->dec_info.job_id);
    670     return -1;
    671   }
    672 
    673   /* sent encode cmd to OMX, queue job into ongoing queue */
    674   qdata.p = job_node;
    675   rc = mm_jpeg_queue_enq(&my_obj->ongoing_job_q, qdata);
    676   if (rc) {
    677     LOGE("jpeg enqueue failed %d", ret);
    678     goto error;
    679   }
    680 
    681   p_session->decode_job = job_node->dec_info.decode_job;
    682   p_session->jobId = job_node->dec_info.job_id;
    683   ret = mm_jpegdec_session_decode(p_session);
    684   if (ret) {
    685     LOGE("encode session failed");
    686     goto error;
    687   }
    688 
    689   LOGD("Success X ");
    690   return rc;
    691 
    692 error:
    693 
    694   if ((OMX_ErrorNone != ret) &&
    695     (NULL != p_session->dec_params.jpeg_cb)) {
    696     p_session->job_status = JPEG_JOB_STATUS_ERROR;
    697     LOGD("send jpeg error callback %d",
    698       p_session->job_status);
    699     p_session->dec_params.jpeg_cb(p_session->job_status,
    700       p_session->client_hdl,
    701       p_session->jobId,
    702       NULL,
    703       p_session->dec_params.userdata);
    704   }
    705 
    706   /*remove the job*/
    707   mm_jpegdec_job_done(p_session);
    708   LOGD("Error X ");
    709 
    710   return rc;
    711 }
    712 
    713 /** mm_jpeg_start_decode_job:
    714  *
    715  *  Arguments:
    716  *    @my_obj: jpeg object
    717  *    @client_hdl: client handle
    718  *    @job: pointer to encode job
    719  *    @jobId: job id
    720  *
    721  *  Return:
    722  *       0 for success else failure
    723  *
    724  *  Description:
    725  *       Start the encoding job
    726  *
    727  **/
    728 int32_t mm_jpegdec_start_decode_job(mm_jpeg_obj *my_obj,
    729   mm_jpeg_job_t *job,
    730   uint32_t *job_id)
    731 {
    732   mm_jpeg_q_data_t qdata;
    733   int32_t rc = -1;
    734   uint8_t session_idx = 0;
    735   uint8_t client_idx = 0;
    736   mm_jpeg_job_q_node_t* node = NULL;
    737   mm_jpeg_job_session_t *p_session = NULL;
    738   mm_jpeg_decode_job_t *p_jobparams  = &job->decode_job;
    739 
    740   *job_id = 0;
    741 
    742   /* check if valid session */
    743   session_idx = GET_SESSION_IDX(p_jobparams->session_id);
    744   client_idx = GET_CLIENT_IDX(p_jobparams->session_id);
    745   LOGD("session_idx %d client idx %d",
    746     session_idx, client_idx);
    747 
    748   if ((session_idx >= MM_JPEG_MAX_SESSION) ||
    749     (client_idx >= MAX_JPEG_CLIENT_NUM)) {
    750     LOGE("invalid session id %x",
    751       job->decode_job.session_id);
    752     return rc;
    753   }
    754 
    755   p_session = &my_obj->clnt_mgr[client_idx].session[session_idx];
    756   if (OMX_FALSE == p_session->active) {
    757     LOGE("session not active %x",
    758       job->decode_job.session_id);
    759     return rc;
    760   }
    761 
    762   if ((p_jobparams->src_index >= (int32_t)p_session->dec_params.num_src_bufs) ||
    763     (p_jobparams->dst_index >= (int32_t)p_session->dec_params.num_dst_bufs)) {
    764     LOGE("invalid buffer indices");
    765     return rc;
    766   }
    767 
    768   /* enqueue new job into todo job queue */
    769   node = (mm_jpeg_job_q_node_t *)malloc(sizeof(mm_jpeg_job_q_node_t));
    770   if (NULL == node) {
    771     LOGE("No memory for mm_jpeg_job_q_node_t");
    772     return -1;
    773   }
    774 
    775   *job_id = job->decode_job.session_id |
    776     ((p_session->job_hist++ % JOB_HIST_MAX) << 16);
    777 
    778   memset(node, 0, sizeof(mm_jpeg_job_q_node_t));
    779   node->dec_info.decode_job = job->decode_job;
    780   node->dec_info.job_id = *job_id;
    781   node->dec_info.client_handle = p_session->client_hdl;
    782   node->type = MM_JPEG_CMD_TYPE_DECODE_JOB;
    783 
    784   qdata.p = node;
    785   rc = mm_jpeg_queue_enq(&my_obj->job_mgr.job_queue, qdata);
    786   if (0 == rc) {
    787     cam_sem_post(&my_obj->job_mgr.job_sem);
    788   }
    789 
    790   return rc;
    791 }
    792 
    793 /** mm_jpegdec_create_session:
    794  *
    795  *  Arguments:
    796  *    @my_obj: jpeg object
    797  *    @client_hdl: client handle
    798  *    @p_params: pointer to encode params
    799  *    @p_session_id: session id
    800  *
    801  *  Return:
    802  *       0 for success else failure
    803  *
    804  *  Description:
    805  *       Start the encoding session
    806  *
    807  **/
    808 int32_t mm_jpegdec_create_session(mm_jpeg_obj *my_obj,
    809   uint32_t client_hdl,
    810   mm_jpeg_decode_params_t *p_params,
    811   uint32_t* p_session_id)
    812 {
    813   int32_t rc = 0;
    814   OMX_ERRORTYPE ret = OMX_ErrorNone;
    815   uint8_t clnt_idx = 0;
    816   int session_idx = -1;
    817   mm_jpeg_job_session_t *p_session = NULL;
    818   *p_session_id = 0;
    819 
    820   /* validate the parameters */
    821   if ((p_params->num_src_bufs > MM_JPEG_MAX_BUF)
    822     || (p_params->num_dst_bufs > MM_JPEG_MAX_BUF)) {
    823     LOGE("invalid num buffers");
    824     return rc;
    825   }
    826 
    827   /* check if valid client */
    828   clnt_idx = mm_jpeg_util_get_index_by_handler(client_hdl);
    829   if (clnt_idx >= MAX_JPEG_CLIENT_NUM) {
    830     LOGE("invalid client with handler (%d)", client_hdl);
    831     return rc;
    832   }
    833 
    834   session_idx = mm_jpeg_get_new_session_idx(my_obj, clnt_idx, &p_session);
    835   if (session_idx < 0) {
    836     LOGE("invalid session id (%d)", session_idx);
    837     return rc;
    838   }
    839 
    840   ret = mm_jpegdec_session_create(p_session);
    841   if (OMX_ErrorNone != ret) {
    842     p_session->active = OMX_FALSE;
    843     LOGE("jpeg session create failed");
    844     return rc;
    845   }
    846 
    847   *p_session_id = (JOB_ID_MAGICVAL << 24) |
    848     ((unsigned)session_idx << 8) | clnt_idx;
    849 
    850   /*copy the params*/
    851   p_session->dec_params = *p_params;
    852   p_session->client_hdl = client_hdl;
    853   p_session->sessionId = *p_session_id;
    854   p_session->jpeg_obj = (void*)my_obj; /* save a ptr to jpeg_obj */
    855   LOGD("session id %x", *p_session_id);
    856 
    857   return rc;
    858 }
    859 
    860 /** mm_jpegdec_destroy_session:
    861  *
    862  *  Arguments:
    863  *    @my_obj: jpeg object
    864  *    @session_id: session index
    865  *
    866  *  Return:
    867  *       0 for success else failure
    868  *
    869  *  Description:
    870  *       Destroy the encoding session
    871  *
    872  **/
    873 int32_t mm_jpegdec_destroy_session(mm_jpeg_obj *my_obj,
    874   mm_jpeg_job_session_t *p_session)
    875 {
    876   int32_t rc = 0;
    877   mm_jpeg_job_q_node_t *node = NULL;
    878 
    879   if (NULL == p_session) {
    880     LOGE("invalid session");
    881     return rc;
    882   }
    883   uint32_t session_id = p_session->sessionId;
    884   pthread_mutex_lock(&my_obj->job_lock);
    885 
    886   /* abort job if in todo queue */
    887   LOGD("abort todo jobs");
    888   node = mm_jpeg_queue_remove_job_by_session_id(&my_obj->job_mgr.job_queue, session_id);
    889   while (NULL != node) {
    890     free(node);
    891     node = mm_jpeg_queue_remove_job_by_session_id(&my_obj->job_mgr.job_queue, session_id);
    892   }
    893 
    894   /* abort job if in ongoing queue */
    895   LOGD("abort ongoing jobs");
    896   node = mm_jpeg_queue_remove_job_by_session_id(&my_obj->ongoing_job_q, session_id);
    897   while (NULL != node) {
    898     free(node);
    899     node = mm_jpeg_queue_remove_job_by_session_id(&my_obj->ongoing_job_q, session_id);
    900   }
    901 
    902   /* abort the current session */
    903   mm_jpeg_session_abort(p_session);
    904   mm_jpegdec_session_destroy(p_session);
    905   mm_jpeg_remove_session_idx(my_obj, session_id);
    906   pthread_mutex_unlock(&my_obj->job_lock);
    907 
    908   /* wake up jobMgr thread to work on new job if there is any */
    909   cam_sem_post(&my_obj->job_mgr.job_sem);
    910   LOGD("X");
    911 
    912   return rc;
    913 }
    914 
    915 /** mm_jpegdec_destroy_session_by_id:
    916  *
    917  *  Arguments:
    918  *    @my_obj: jpeg object
    919  *    @session_id: session index
    920  *
    921  *  Return:
    922  *       0 for success else failure
    923  *
    924  *  Description:
    925  *       Destroy the encoding session
    926  *
    927  **/
    928 int32_t mm_jpegdec_destroy_session_by_id(mm_jpeg_obj *my_obj, uint32_t session_id)
    929 {
    930   int32_t rc = 0;
    931   mm_jpeg_job_session_t *p_session = mm_jpeg_get_session(my_obj, session_id);
    932 
    933   if (NULL == p_session) {
    934     LOGE("session is not valid");
    935     return rc;
    936   }
    937 
    938   return mm_jpegdec_destroy_session(my_obj, p_session);
    939 }
    940 
    941 
    942 
    943 OMX_ERRORTYPE mm_jpegdec_ebd(OMX_HANDLETYPE hComponent,
    944   OMX_PTR pAppData,
    945   OMX_BUFFERHEADERTYPE *pBuffer)
    946 {
    947   mm_jpeg_job_session_t *p_session = (mm_jpeg_job_session_t *) pAppData;
    948 
    949   LOGD("count %d ", p_session->ebd_count);
    950   pthread_mutex_lock(&p_session->lock);
    951   p_session->ebd_count++;
    952   pthread_mutex_unlock(&p_session->lock);
    953   return 0;
    954 }
    955 
    956 OMX_ERRORTYPE mm_jpegdec_fbd(OMX_HANDLETYPE hComponent,
    957   OMX_PTR pAppData,
    958   OMX_BUFFERHEADERTYPE *pBuffer)
    959 {
    960   OMX_ERRORTYPE ret = OMX_ErrorNone;
    961   mm_jpeg_job_session_t *p_session = (mm_jpeg_job_session_t *) pAppData;
    962   mm_jpeg_output_t output_buf;
    963 
    964   LOGD("count %d ", p_session->fbd_count);
    965 
    966   pthread_mutex_lock(&p_session->lock);
    967 
    968   if (MM_JPEG_ABORT_NONE != p_session->abort_state) {
    969     pthread_mutex_unlock(&p_session->lock);
    970     return ret;
    971   }
    972 
    973   p_session->fbd_count++;
    974   if (NULL != p_session->dec_params.jpeg_cb) {
    975     p_session->job_status = JPEG_JOB_STATUS_DONE;
    976     output_buf.buf_filled_len = (uint32_t)pBuffer->nFilledLen;
    977     output_buf.buf_vaddr = pBuffer->pBuffer;
    978     output_buf.fd = -1;
    979     LOGD("send jpeg callback %d",
    980       p_session->job_status);
    981     p_session->dec_params.jpeg_cb(p_session->job_status,
    982       p_session->client_hdl,
    983       p_session->jobId,
    984       &output_buf,
    985       p_session->dec_params.userdata);
    986 
    987     /* remove from ready queue */
    988     mm_jpegdec_job_done(p_session);
    989   }
    990   pthread_mutex_unlock(&p_session->lock);
    991   LOGD("Exit");
    992 
    993   return ret;
    994 }
    995 
    996 OMX_ERRORTYPE mm_jpegdec_event_handler(OMX_HANDLETYPE hComponent,
    997   OMX_PTR pAppData,
    998   OMX_EVENTTYPE eEvent,
    999   OMX_U32 nData1,
   1000   OMX_U32 nData2,
   1001   OMX_PTR pEventData)
   1002 {
   1003   mm_jpeg_job_session_t *p_session = (mm_jpeg_job_session_t *) pAppData;
   1004 
   1005   LOGD("%d %d %d state %d", eEvent, (int)nData1,
   1006     (int)nData2, p_session->abort_state);
   1007 
   1008   LOGD("AppData=%p ", pAppData);
   1009 
   1010   pthread_mutex_lock(&p_session->lock);
   1011   p_session->omxEvent = eEvent;
   1012   if (MM_JPEG_ABORT_INIT == p_session->abort_state) {
   1013     p_session->abort_state = MM_JPEG_ABORT_DONE;
   1014     pthread_cond_signal(&p_session->cond);
   1015     pthread_mutex_unlock(&p_session->lock);
   1016     return OMX_ErrorNone;
   1017   }
   1018 
   1019   if (eEvent == OMX_EventError) {
   1020     if (p_session->encoding == OMX_TRUE) {
   1021       LOGD("Error during encoding");
   1022 
   1023       /* send jpeg callback */
   1024       if (NULL != p_session->dec_params.jpeg_cb) {
   1025         p_session->job_status = JPEG_JOB_STATUS_ERROR;
   1026         LOGD("send jpeg error callback %d",
   1027           p_session->job_status);
   1028         p_session->dec_params.jpeg_cb(p_session->job_status,
   1029           p_session->client_hdl,
   1030           p_session->jobId,
   1031           NULL,
   1032           p_session->dec_params.userdata);
   1033       }
   1034 
   1035       /* remove from ready queue */
   1036       mm_jpegdec_job_done(p_session);
   1037     }
   1038     pthread_cond_signal(&p_session->cond);
   1039   } else if (eEvent == OMX_EventCmdComplete) {
   1040     p_session->state_change_pending = OMX_FALSE;
   1041     p_session->event_pending = OMX_FALSE;
   1042     pthread_cond_signal(&p_session->cond);
   1043   }  else if (eEvent == OMX_EventPortSettingsChanged) {
   1044     p_session->event_pending = OMX_FALSE;
   1045     pthread_cond_signal(&p_session->cond);
   1046   }
   1047 
   1048   pthread_mutex_unlock(&p_session->lock);
   1049   LOGD("Exit");
   1050   return OMX_ErrorNone;
   1051 }
   1052 
   1053 /** mm_jpegdec_abort_job:
   1054  *
   1055  *  Arguments:
   1056  *    @my_obj: jpeg object
   1057  *    @client_hdl: client handle
   1058  *    @jobId: job id
   1059  *
   1060  *  Return:
   1061  *       0 for success else failure
   1062  *
   1063  *  Description:
   1064  *       Abort the encoding session
   1065  *
   1066  **/
   1067 int32_t mm_jpegdec_abort_job(mm_jpeg_obj *my_obj,
   1068   uint32_t jobId)
   1069 {
   1070   int32_t rc = -1;
   1071   mm_jpeg_job_q_node_t *node = NULL;
   1072   mm_jpeg_job_session_t *p_session = NULL;
   1073 
   1074   LOGD("Enter");
   1075   pthread_mutex_lock(&my_obj->job_lock);
   1076 
   1077   /* abort job if in todo queue */
   1078   node = mm_jpeg_queue_remove_job_by_job_id(&my_obj->job_mgr.job_queue, jobId);
   1079   if (NULL != node) {
   1080     free(node);
   1081     goto abort_done;
   1082   }
   1083 
   1084   /* abort job if in ongoing queue */
   1085   node = mm_jpeg_queue_remove_job_by_job_id(&my_obj->ongoing_job_q, jobId);
   1086   if (NULL != node) {
   1087     /* find job that is OMX ongoing, ask OMX to abort the job */
   1088     p_session = mm_jpeg_get_session(my_obj, node->dec_info.job_id);
   1089     if (p_session) {
   1090       mm_jpeg_session_abort(p_session);
   1091     } else {
   1092       LOGE("Invalid job id 0x%x",
   1093         node->dec_info.job_id);
   1094     }
   1095     free(node);
   1096     goto abort_done;
   1097   }
   1098 
   1099 abort_done:
   1100   pthread_mutex_unlock(&my_obj->job_lock);
   1101 
   1102   return rc;
   1103 }
   1104 /** mm_jpegdec_init:
   1105  *
   1106  *  Arguments:
   1107  *    @my_obj: jpeg object
   1108  *
   1109  *  Return:
   1110  *       0 for success else failure
   1111  *
   1112  *  Description:
   1113  *       Initializes the jpeg client
   1114  *
   1115  **/
   1116 int32_t mm_jpegdec_init(mm_jpeg_obj *my_obj)
   1117 {
   1118   int32_t rc = 0;
   1119 
   1120   /* init locks */
   1121   pthread_mutex_init(&my_obj->job_lock, NULL);
   1122 
   1123   /* init ongoing job queue */
   1124   rc = mm_jpeg_queue_init(&my_obj->ongoing_job_q);
   1125   if (0 != rc) {
   1126     LOGE("Error");
   1127     return -1;
   1128   }
   1129 
   1130   /* init job semaphore and launch jobmgr thread */
   1131   LOGD("Launch jobmgr thread rc %d", rc);
   1132   rc = mm_jpeg_jobmgr_thread_launch(my_obj);
   1133   if (0 != rc) {
   1134     LOGE("Error");
   1135     return -1;
   1136   }
   1137 
   1138   /* load OMX */
   1139   if (OMX_ErrorNone != OMX_Init()) {
   1140     /* roll back in error case */
   1141     LOGE("OMX_Init failed (%d)", rc);
   1142     mm_jpeg_jobmgr_thread_release(my_obj);
   1143     mm_jpeg_queue_deinit(&my_obj->ongoing_job_q);
   1144     pthread_mutex_destroy(&my_obj->job_lock);
   1145   }
   1146 
   1147   return rc;
   1148 }
   1149 
   1150 /** mm_jpegdec_deinit:
   1151  *
   1152  *  Arguments:
   1153  *    @my_obj: jpeg object
   1154  *
   1155  *  Return:
   1156  *       0 for success else failure
   1157  *
   1158  *  Description:
   1159  *       Deinits the jpeg client
   1160  *
   1161  **/
   1162 int32_t mm_jpegdec_deinit(mm_jpeg_obj *my_obj)
   1163 {
   1164   int32_t rc = 0;
   1165 
   1166   /* release jobmgr thread */
   1167   rc = mm_jpeg_jobmgr_thread_release(my_obj);
   1168   if (0 != rc) {
   1169     LOGE("Error");
   1170   }
   1171 
   1172   /* unload OMX engine */
   1173   OMX_Deinit();
   1174 
   1175   /* deinit ongoing job and cb queue */
   1176   rc = mm_jpeg_queue_deinit(&my_obj->ongoing_job_q);
   1177   if (0 != rc) {
   1178     LOGE("Error");
   1179   }
   1180 
   1181   /* destroy locks */
   1182   pthread_mutex_destroy(&my_obj->job_lock);
   1183 
   1184   return rc;
   1185 }
   1186