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