summaryrefslogtreecommitdiff
path: root/camera/QCamera/stack/mm-jpeg-interface/src/mm_jpeg.c
diff options
context:
space:
mode:
Diffstat (limited to 'camera/QCamera/stack/mm-jpeg-interface/src/mm_jpeg.c')
-rwxr-xr-xcamera/QCamera/stack/mm-jpeg-interface/src/mm_jpeg.c1417
1 files changed, 0 insertions, 1417 deletions
diff --git a/camera/QCamera/stack/mm-jpeg-interface/src/mm_jpeg.c b/camera/QCamera/stack/mm-jpeg-interface/src/mm_jpeg.c
deleted file mode 100755
index 442ecb9..0000000
--- a/camera/QCamera/stack/mm-jpeg-interface/src/mm_jpeg.c
+++ /dev/null
@@ -1,1417 +0,0 @@
-/*
-Copyright (c) 2012, The Linux Foundation. All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are
-met:
- * Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the following
- disclaimer in the documentation and/or other materials provided
- with the distribution.
- * Neither the name of The Linux Foundation nor the names of its
- contributors may be used to endorse or promote products derived
- from this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
-WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
-BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
-BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
-OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
-IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#include <pthread.h>
-#include <errno.h>
-#include <sys/ioctl.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <poll.h>
-#include <semaphore.h>
-
-#include "mm_jpeg_dbg.h"
-#include "mm_jpeg_interface.h"
-#include "mm_jpeg.h"
-
-/* define max num of supported concurrent jpeg jobs by OMX engine.
- * Current, only one per time */
-#define NUM_MAX_JPEG_CNCURRENT_JOBS 1
-
-#define INPUT_PORT_MAIN 0
-#define INPUT_PORT_THUMBNAIL 2
-#define OUTPUT_PORT 1
-
-void mm_jpeg_job_wait_for_event(mm_jpeg_obj *my_obj, uint32_t evt_mask);
-void mm_jpeg_job_wait_for_cmd_complete(mm_jpeg_obj *my_obj,
- int cmd,
- int status);
-OMX_ERRORTYPE mm_jpeg_etbdone(OMX_HANDLETYPE hComponent,
- OMX_PTR pAppData,
- OMX_BUFFERHEADERTYPE* pBuffer);
-OMX_ERRORTYPE mm_jpeg_ftbdone(OMX_HANDLETYPE hComponent,
- OMX_PTR pAppData,
- OMX_BUFFERHEADERTYPE* pBuffer);
-OMX_ERRORTYPE mm_jpeg_handle_omx_event(OMX_HANDLETYPE hComponent,
- OMX_PTR pAppData,
- OMX_EVENTTYPE eEvent,
- OMX_U32 nData1,
- OMX_U32 nData2,
- OMX_PTR pEventData);
-/* special queue functions for job queue */
-int32_t mm_jpeg_queue_update_flag(mm_jpeg_queue_t* queue, uint32_t job_id, uint8_t flag);
-mm_jpeg_job_q_node_t* mm_jpeg_queue_remove_job_by_client_id(mm_jpeg_queue_t* queue, uint32_t client_hdl);
-mm_jpeg_job_q_node_t* mm_jpeg_queue_remove_job_by_job_id(mm_jpeg_queue_t* queue, uint32_t job_id);
-
-static OMX_INDEXTYPE mobicat_data;
-static omx_jpeg_mobicat mobicat_d;
-
-int32_t mm_jpeg_omx_load(mm_jpeg_obj* my_obj)
-{
- int32_t rc = 0;
-
- my_obj->omx_callbacks.EmptyBufferDone = mm_jpeg_etbdone;
- my_obj->omx_callbacks.FillBufferDone = mm_jpeg_ftbdone;
- my_obj->omx_callbacks.EventHandler = mm_jpeg_handle_omx_event;
- rc = OMX_GetHandle(&my_obj->omx_handle,
- "OMX.qcom.image.jpeg.encoder",
- (void*)my_obj,
- &my_obj->omx_callbacks);
-
- if (0 != rc) {
- CDBG_ERROR("%s : OMX_GetHandle failed (%d)",__func__, rc);
- return rc;
- }
-
- rc = OMX_Init();
- if (0 != rc) {
- CDBG_ERROR("%s : OMX_Init failed (%d)",__func__, rc);
- }
-
- return rc;
-}
-
-int32_t mm_jpeg_omx_unload(mm_jpeg_obj *my_obj)
-{
- int32_t rc = 0;
- rc = OMX_Deinit();
- return rc;
-}
-
-int32_t mm_jpeg_clean_omx_job(mm_jpeg_obj *my_obj, mm_jpeg_job_entry* job_entry)
-{
- int32_t rc = 0;
- uint8_t i, j;
-
- OMX_SendCommand(my_obj->omx_handle, OMX_CommandStateSet, OMX_StateIdle, NULL);
- OMX_SendCommand(my_obj->omx_handle, OMX_CommandStateSet, OMX_StateLoaded, NULL);
-
- /* free buffers used in OMX processing */
- for (i = 0; i < JPEG_SRC_IMAGE_TYPE_MAX; i++) {
- for (j = 0; j < job_entry->src_bufs[i].num_bufs; j++) {
- if (NULL != job_entry->src_bufs[i].bufs[j].buf_header) {
- OMX_FreeBuffer(my_obj->omx_handle,
- job_entry->src_bufs[i].bufs[j].portIdx,
- job_entry->src_bufs[i].bufs[j].buf_header);
- }
- }
- }
- OMX_FreeBuffer(my_obj->omx_handle,
- job_entry->sink_buf.portIdx,
- job_entry->sink_buf.buf_header);
-
- return rc;
-}
-
-int32_t mm_jpeg_omx_abort_job(mm_jpeg_obj *my_obj, mm_jpeg_job_entry* job_entry)
-{
- int32_t rc = 0;
-
- OMX_SendCommand(my_obj->omx_handle, OMX_CommandFlush, 0, NULL);
- mm_jpeg_job_wait_for_event(my_obj,
- MM_JPEG_EVENT_MASK_JPEG_DONE|MM_JPEG_EVENT_MASK_JPEG_ABORT|MM_JPEG_EVENT_MASK_JPEG_ERROR);
- CDBG("%s:waitForEvent: OMX_CommandFlush: DONE", __func__);
-
- /* clean omx job */
- mm_jpeg_clean_omx_job(my_obj, job_entry);
-
- return rc;
-}
-
-/* TODO: needs revisit after omx lib supports multi src buffers */
-int32_t mm_jpeg_omx_config_main_buffer_offset(mm_jpeg_obj* my_obj,
- src_image_buffer_info *src_buf,
- uint8_t is_video_frame)
-{
- int32_t rc = 0;
- uint8_t i;
- OMX_INDEXTYPE buf_offset_idx;
- omx_jpeg_buffer_offset buffer_offset;
-
- for (i = 0; i < src_buf->num_bufs; i++) {
- OMX_GetExtensionIndex(my_obj->omx_handle,
- "omx.qcom.jpeg.exttype.buffer_offset",
- &buf_offset_idx);
- memset(&buffer_offset, 0, sizeof(buffer_offset));
-
- switch (src_buf->img_fmt) {
- case JPEG_SRC_IMAGE_FMT_YUV:
- if (1 == src_buf->src_image[i].offset.num_planes) {
- buffer_offset.yOffset =
- src_buf->src_image[i].offset.sp.y_offset;
- buffer_offset.cbcrOffset =
- src_buf->src_image[i].offset.sp.cbcr_offset;
- buffer_offset.totalSize =
- src_buf->src_image[i].offset.sp.len;
- } else {
- buffer_offset.yOffset =
- src_buf->src_image[i].offset.mp[0].offset;
- buffer_offset.cbcrOffset =
- src_buf->src_image[i].offset.mp[1].offset;
- buffer_offset.totalSize =
- src_buf->src_image[i].offset.frame_len;
- }
- CDBG("%s: idx=%d, yOffset =%d, cbcrOffset =%d, totalSize = %d\n",
- __func__, i, buffer_offset.yOffset, buffer_offset.cbcrOffset, buffer_offset.totalSize);
- OMX_SetParameter(my_obj->omx_handle, buf_offset_idx, &buffer_offset);
-
- /* set acbcr (special case for video-sized live snapshot)*/
- if (is_video_frame) {
- CDBG("Using acbcroffset\n");
- memset(&buffer_offset, 0, sizeof(buffer_offset));
- buffer_offset.cbcrOffset = src_buf->src_image[i].offset.mp[0].offset +
- src_buf->src_image[i].offset.mp[0].len +
- src_buf->src_image[i].offset.mp[1].offset;;
- OMX_GetExtensionIndex(my_obj->omx_handle,"omx.qcom.jpeg.exttype.acbcr_offset",&buf_offset_idx);
- OMX_SetParameter(my_obj->omx_handle, buf_offset_idx, &buffer_offset);
- }
- break;
- case JPEG_SRC_IMAGE_FMT_BITSTREAM:
- /* TODO: need visit here when bit stream is supported */
- buffer_offset.yOffset =
- src_buf->bit_stream[i].data_offset;
- buffer_offset.totalSize =
- src_buf->bit_stream[i].buf_size;
- CDBG("%s: idx=%d, yOffset =%d, cbcrOffset =%d, totalSize = %d\n",
- __func__, i, buffer_offset.yOffset, buffer_offset.cbcrOffset, buffer_offset.totalSize);
- OMX_SetParameter(my_obj->omx_handle, buf_offset_idx, &buffer_offset);
- break;
- default:
- break;
- }
- }
-
- return rc;
-}
-
-/* TODO: needs revisit after omx lib supports multi src buffers */
-int32_t mm_jpeg_omx_config_port(mm_jpeg_obj* my_obj, src_image_buffer_info *src_buf, int port_idx)
-{
- int32_t rc = 0;
- uint8_t i;
- OMX_PARAM_PORTDEFINITIONTYPE input_port;
-
- for (i = 0; i < src_buf->num_bufs; i++) {
- memset(&input_port, 0, sizeof(input_port));
- input_port.nPortIndex = port_idx;
- OMX_GetParameter(my_obj->omx_handle, OMX_IndexParamPortDefinition, &input_port);
- input_port.format.image.nFrameWidth = src_buf->src_dim.width;
- input_port.format.image.nFrameHeight =src_buf->src_dim.height;
- input_port.format.image.nStride = src_buf->src_dim.width;
- input_port.format.image.nSliceHeight = src_buf->src_dim.height;
- switch (src_buf->img_fmt) {
- case JPEG_SRC_IMAGE_FMT_YUV:
- input_port.nBufferSize = src_buf->src_image[i].offset.frame_len;
- break;
- case JPEG_SRC_IMAGE_FMT_BITSTREAM:
- input_port.nBufferSize = src_buf->bit_stream[i].buf_size;
- break;
- }
-
- CDBG("%s: port_idx=%d, width =%d, height =%d, stride = %d, slice = %d, bufsize = %d\n",
- __func__, port_idx,
- input_port.format.image.nFrameWidth, input_port.format.image.nFrameHeight,
- input_port.format.image.nStride, input_port.format.image.nSliceHeight,
- input_port.nBufferSize);
- OMX_SetParameter(my_obj->omx_handle, OMX_IndexParamPortDefinition, &input_port);
- }
-
- return rc;
-}
-
-omx_jpeg_color_format map_jpeg_format(mm_jpeg_color_format color_fmt)
-{
- switch (color_fmt) {
- case MM_JPEG_COLOR_FORMAT_YCRCBLP_H2V2:
- return OMX_YCRCBLP_H2V2;
- case MM_JPEG_COLOR_FORMAT_YCBCRLP_H2V2:
- return OMX_YCBCRLP_H2V2;
- case MM_JPEG_COLOR_FORMAT_YCRCBLP_H2V1:
- return OMX_YCRCBLP_H2V1;
- case MM_JPEG_COLOR_FORMAT_YCBCRLP_H2V1:
- return OMX_YCBCRLP_H2V1;
- case MM_JPEG_COLOR_FORMAT_YCRCBLP_H1V2:
- return OMX_YCRCBLP_H1V2;
- case MM_JPEG_COLOR_FORMAT_YCBCRLP_H1V2:
- return OMX_YCBCRLP_H1V2;
- case MM_JPEG_COLOR_FORMAT_YCRCBLP_H1V1:
- return OMX_YCRCBLP_H1V1;
- case MM_JPEG_COLOR_FORMAT_YCBCRLP_H1V1:
- return OMX_YCBCRLP_H1V1;
- case MM_JPEG_COLOR_FORMAT_RGB565:
- return OMX_RGB565;
- case MM_JPEG_COLOR_FORMAT_RGB888:
- return OMX_RGB888;
- case MM_JPEG_COLOR_FORMAT_RGBa:
- return OMX_RGBa;
- case MM_JPEG_COLOR_FORMAT_BITSTREAM:
- /* TODO: need to change to new bitstream value once omx interface changes */
- return OMX_JPEG_BITSTREAM_H2V2;
- default:
- return OMX_JPEG_COLOR_FORMAT_MAX;
- }
-}
-
-int32_t mm_jpeg_omx_config_user_preference(mm_jpeg_obj* my_obj, mm_jpeg_encode_job* job)
-{
- int32_t rc = 0;
- OMX_INDEXTYPE user_pref_idx;
- omx_jpeg_user_preferences user_preferences;
-
- memset(&user_preferences, 0, sizeof(user_preferences));
- user_preferences.color_format =
- map_jpeg_format(job->encode_parm.buf_info.src_imgs.src_img[JPEG_SRC_IMAGE_TYPE_MAIN].color_format);
- if (job->encode_parm.buf_info.src_imgs.src_img_num > 1) {
- user_preferences.thumbnail_color_format =
- map_jpeg_format(job->encode_parm.buf_info.src_imgs.src_img[JPEG_SRC_IMAGE_TYPE_THUMB].color_format);
- }
- OMX_GetExtensionIndex(my_obj->omx_handle,
- "omx.qcom.jpeg.exttype.user_preferences",
- &user_pref_idx);
- CDBG("%s:User Preferences: color_format %d, thumbnail_color_format = %d",
- __func__, user_preferences.color_format, user_preferences.thumbnail_color_format);
-
- if (job->encode_parm.buf_info.src_imgs.is_video_frame != 0) {
- user_preferences.preference = OMX_JPEG_PREF_SOFTWARE_ONLY;
- } else {
- user_preferences.preference = OMX_JPEG_PREF_HW_ACCELERATED_PREFERRED;
- }
-
- OMX_SetParameter(my_obj->omx_handle, user_pref_idx, &user_preferences);
- return rc;
-}
-
-int32_t mm_jpeg_omx_config_thumbnail(mm_jpeg_obj* my_obj, mm_jpeg_encode_job* job)
-{
- int32_t rc = -1;
- OMX_INDEXTYPE thumb_idx, q_idx;
- omx_jpeg_thumbnail thumbnail;
- omx_jpeg_thumbnail_quality quality;
-
- if (job->encode_parm.buf_info.src_imgs.src_img_num < 2) {
- /*No thumbnail is required*/
- return 0;
- }
- src_image_buffer_info *src_buf =
- &(job->encode_parm.buf_info.src_imgs.src_img[JPEG_SRC_IMAGE_TYPE_THUMB]);
-
- /* config port */
- CDBG("%s: config port", __func__);
- rc = mm_jpeg_omx_config_port(my_obj, src_buf, INPUT_PORT_THUMBNAIL);
- if (0 != rc) {
- CDBG_ERROR("%s: config port failed", __func__);
- return rc;
- }
-
- if ((src_buf->crop.width == 0) || (src_buf->crop.height == 0)) {
- src_buf->crop.width = src_buf->src_dim.width;
- src_buf->crop.height = src_buf->src_dim.height;
- }
-
- /* check crop boundary */
- if ((src_buf->crop.width + src_buf->crop.offset_x > src_buf->src_dim.width) ||
- (src_buf->crop.height + src_buf->crop.offset_y > src_buf->src_dim.height)) {
- CDBG_ERROR("%s: invalid crop boundary (%d, %d) offset (%d, %d) out of (%d, %d)",
- __func__,
- src_buf->crop.width,
- src_buf->crop.height,
- src_buf->crop.offset_x,
- src_buf->crop.offset_y,
- src_buf->src_dim.width,
- src_buf->src_dim.height);
- return -1;
- }
-
- memset(&thumbnail, 0, sizeof(thumbnail));
-
- /* thumbnail crop info */
- thumbnail.cropWidth = CEILING2(src_buf->crop.width);
- thumbnail.cropHeight = CEILING2(src_buf->crop.height);
- thumbnail.left = src_buf->crop.offset_x;
- thumbnail.top = src_buf->crop.offset_y;
-
- /* thumbnail output dimention */
- thumbnail.width = src_buf->out_dim.width;
- thumbnail.height = src_buf->out_dim.height;
-
- /* set scaling flag */
- if (thumbnail.left > 0 || thumbnail.top > 0 ||
- src_buf->crop.width != src_buf->src_dim.width ||
- src_buf->crop.height != src_buf->src_dim.height ||
- src_buf->src_dim.width != src_buf->out_dim.width ||
- src_buf->src_dim.height != src_buf->out_dim.height) {
- thumbnail.scaling = 1;
- }
-
- /* set omx thumbnail info */
- OMX_GetExtensionIndex(my_obj->omx_handle, "omx.qcom.jpeg.exttype.thumbnail", &thumb_idx);
- OMX_SetParameter(my_obj->omx_handle, thumb_idx, &thumbnail);
- CDBG("%s: set thumbnail info: crop_w=%d, crop_h=%d, l=%d, t=%d, w=%d, h=%d, scaling=%d",
- __func__, thumbnail.cropWidth, thumbnail.cropHeight,
- thumbnail.left, thumbnail.top, thumbnail.width, thumbnail.height,
- thumbnail.scaling);
-
- OMX_GetExtensionIndex(my_obj->omx_handle, "omx.qcom.jpeg.exttype.thumbnail_quality", &q_idx);
- OMX_GetParameter(my_obj->omx_handle, q_idx, &quality);
- quality.nQFactor = src_buf->quality;
- OMX_SetParameter(my_obj->omx_handle, q_idx, &quality);
- CDBG("%s: thumbnail_quality=%d", __func__, quality.nQFactor);
-
- rc = 0;
- return rc;
-}
-
-int32_t mm_jpeg_omx_config_main_crop(mm_jpeg_obj* my_obj, src_image_buffer_info *src_buf)
-{
- int32_t rc = 0;
- OMX_CONFIG_RECTTYPE rect_type_in, rect_type_out;
-
- if ((src_buf->crop.width == 0) || (src_buf->crop.height == 0)) {
- src_buf->crop.width = src_buf->src_dim.width;
- src_buf->crop.height = src_buf->src_dim.height;
- }
- /* error check first */
- if ((src_buf->crop.width + src_buf->crop.offset_x > src_buf->src_dim.width) ||
- (src_buf->crop.height + src_buf->crop.offset_y > src_buf->src_dim.height)) {
- CDBG_ERROR("%s: invalid crop boundary (%d, %d) out of (%d, %d)", __func__,
- src_buf->crop.width + src_buf->crop.offset_x,
- src_buf->crop.height + src_buf->crop.offset_y,
- src_buf->src_dim.width,
- src_buf->src_dim.height);
- return -1;
- }
-
- memset(&rect_type_in, 0, sizeof(rect_type_in));
- memset(&rect_type_out, 0, sizeof(rect_type_out));
- rect_type_in.nPortIndex = OUTPUT_PORT;
- rect_type_out.nPortIndex = OUTPUT_PORT;
-
- if ((src_buf->src_dim.width != src_buf->crop.width) ||
- (src_buf->src_dim.height != src_buf->crop.height) ||
- (src_buf->src_dim.width != src_buf->out_dim.width) ||
- (src_buf->src_dim.height != src_buf->out_dim.height)) {
- /* Scaler information */
- rect_type_in.nWidth = CEILING2(src_buf->crop.width);
- rect_type_in.nHeight = CEILING2(src_buf->crop.height);
- rect_type_in.nLeft = src_buf->crop.offset_x;
- rect_type_in.nTop = src_buf->crop.offset_y;
-
- if (src_buf->out_dim.width && src_buf->out_dim.height) {
- rect_type_out.nWidth = src_buf->out_dim.width;
- rect_type_out.nHeight = src_buf->out_dim.height;
- }
- }
-
- OMX_SetConfig(my_obj->omx_handle, OMX_IndexConfigCommonInputCrop, &rect_type_in);
- CDBG("%s: OMX_IndexConfigCommonInputCrop w=%d, h=%d, l=%d, t=%d, port_idx=%d", __func__,
- rect_type_in.nWidth, rect_type_in.nHeight,
- rect_type_in.nLeft, rect_type_in.nTop,
- rect_type_in.nPortIndex);
-
- OMX_SetConfig(my_obj->omx_handle, OMX_IndexConfigCommonOutputCrop, &rect_type_out);
- CDBG("%s: OMX_IndexConfigCommonOutputCrop w=%d, h=%d, port_idx=%d", __func__,
- rect_type_out.nWidth, rect_type_out.nHeight,
- rect_type_out.nPortIndex);
-
- return rc;
-}
-
-int32_t mm_jpeg_omx_config_main(mm_jpeg_obj* my_obj, mm_jpeg_encode_job* job)
-{
- int32_t rc = 0;
- src_image_buffer_info *src_buf =
- &(job->encode_parm.buf_info.src_imgs.src_img[JPEG_SRC_IMAGE_TYPE_MAIN]);
- OMX_IMAGE_PARAM_QFACTORTYPE q_factor;
-
- /* config port */
- CDBG("%s: config port", __func__);
- rc = mm_jpeg_omx_config_port(my_obj, src_buf, INPUT_PORT_MAIN);
- if (0 != rc) {
- CDBG_ERROR("%s: config port failed", __func__);
- return rc;
- }
-
- /* config buffer offset */
- CDBG("%s: config main buf offset", __func__);
- rc = mm_jpeg_omx_config_main_buffer_offset(my_obj, src_buf, job->encode_parm.buf_info.src_imgs.is_video_frame);
- if (0 != rc) {
- CDBG_ERROR("%s: config buffer offset failed", __func__);
- return rc;
- }
-
- /* config crop */
- CDBG("%s: config main crop", __func__);
- rc = mm_jpeg_omx_config_main_crop(my_obj, src_buf);
- if (0 != rc) {
- CDBG_ERROR("%s: config crop failed", __func__);
- return rc;
- }
-
- /* set quality */
- memset(&q_factor, 0, sizeof(q_factor));
- q_factor.nPortIndex = INPUT_PORT_MAIN;
- OMX_GetParameter(my_obj->omx_handle, OMX_IndexParamQFactor, &q_factor);
- q_factor.nQFactor = src_buf->quality;
- OMX_SetParameter(my_obj->omx_handle, OMX_IndexParamQFactor, &q_factor);
- CDBG("%s: config QFactor: %d", __func__, q_factor.nQFactor);
-
- return rc;
-}
-
-int32_t mm_jpeg_omx_config_common(mm_jpeg_obj* my_obj, mm_jpeg_encode_job* job)
-{
- int32_t rc;
- int i;
- OMX_INDEXTYPE exif_idx;
- omx_jpeg_exif_info_tag tag;
- OMX_CONFIG_ROTATIONTYPE rotate;
-
- /* config user prefernces */
- CDBG("%s: config user preferences", __func__);
- rc = mm_jpeg_omx_config_user_preference(my_obj, job);
- if (0 != rc) {
- CDBG_ERROR("%s: config user preferences failed", __func__);
- return rc;
- }
-
- /* set rotation */
- memset(&rotate, 0, sizeof(rotate));
- rotate.nPortIndex = OUTPUT_PORT;
- rotate.nRotation = job->encode_parm.rotation;
- OMX_SetConfig(my_obj->omx_handle, OMX_IndexConfigCommonRotate, &rotate);
- CDBG("%s: Set rotation to %d at port_idx=%d", __func__,
- job->encode_parm.rotation, rotate.nPortIndex);
-
- /* set exif tags */
- CDBG("%s: Set rexif tags", __func__);
- OMX_GetExtensionIndex(my_obj->omx_handle, "omx.qcom.jpeg.exttype.exif", &exif_idx);
- for(i = 0; i < job->encode_parm.exif_numEntries; i++) {
- memcpy(&tag, job->encode_parm.exif_data + i, sizeof(omx_jpeg_exif_info_tag));
- OMX_SetParameter(my_obj->omx_handle, exif_idx, &tag);
- }
-
- /* set mobicat info */
- CDBG("%s: set Mobicat info", __func__);
- if(job->encode_parm.hasmobicat) {
- mobicat_d.mobicatData = job->encode_parm.mobicat_data;
- mobicat_d.mobicatDataLength = job->encode_parm.mobicat_data_length;
- OMX_GetExtensionIndex(my_obj->omx_handle, "omx.qcom.jpeg.exttype.mobicat", &mobicat_data);
- OMX_SetParameter(my_obj->omx_handle, mobicat_data, &mobicat_d);
- }
-
- return rc;
-}
-
-int32_t mm_jpeg_omx_use_buf(mm_jpeg_obj* my_obj,
- src_image_buffer_info *src_buf,
- mm_jpeg_omx_src_buf* omx_src_buf,
- int port_idx)
-{
- int32_t rc = 0;
- uint8_t i;
- omx_jpeg_pmem_info pmem_info;
-
- omx_src_buf->num_bufs = src_buf->num_bufs;
- for (i = 0; i < src_buf->num_bufs; i++) {
- memset(&pmem_info, 0, sizeof(pmem_info));
- switch (src_buf->img_fmt) {
- case JPEG_SRC_IMAGE_FMT_YUV:
- pmem_info.fd = src_buf->src_image[i].fd;
- pmem_info.offset = 0;
- omx_src_buf->bufs[i].portIdx = port_idx;
- OMX_UseBuffer(my_obj->omx_handle,
- &omx_src_buf->bufs[i].buf_header,
- port_idx,
- &pmem_info,
- src_buf->src_image[i].offset.frame_len,
- (void *)src_buf->src_image[i].buf_vaddr);
- CDBG("%s: port_idx=%d, fd=%d, offset=%d, len=%d, ptr=%p",
- __func__, port_idx, pmem_info.fd, pmem_info.offset,
- src_buf->src_image[i].offset.frame_len,
- src_buf->src_image[i].buf_vaddr);
- break;
- case JPEG_SRC_IMAGE_FMT_BITSTREAM:
- pmem_info.fd = src_buf->bit_stream[i].fd;
- pmem_info.offset = 0;
- omx_src_buf->bufs[i].portIdx = port_idx;
- OMX_UseBuffer(my_obj->omx_handle,
- &omx_src_buf->bufs[i].buf_header,
- port_idx,
- &pmem_info,
- src_buf->bit_stream[i].buf_size,
- (void *)src_buf->bit_stream[i].buf_vaddr);
- break;
- default:
- rc = -1;
- break;
- }
- }
-
- return rc;
-}
-
-int32_t mm_jpeg_omx_encode(mm_jpeg_obj* my_obj, mm_jpeg_job_entry* job_entry)
-{
- int32_t rc = 0;
- uint8_t i;
- mm_jpeg_encode_job* job = &job_entry->job.encode_job;
- uint8_t has_thumbnail = job->encode_parm.buf_info.src_imgs.src_img_num > 1? 1 : 0;
- src_image_buffer_info *src_buf[JPEG_SRC_IMAGE_TYPE_MAX];
- mm_jpeg_omx_src_buf *omx_src_buf[JPEG_SRC_IMAGE_TYPE_MAX];
-
- /* config main img */
- rc = mm_jpeg_omx_config_main(my_obj, job);
- if (0 != rc) {
- CDBG_ERROR("%s: config main img failed", __func__);
- return rc;
- }
-
- /* config thumbnail */
- if (has_thumbnail) {
- rc = mm_jpeg_omx_config_thumbnail(my_obj, job);
- if (0 != rc) {
- CDBG_ERROR("%s: config thumbnail img failed", __func__);
- return rc;
- }
- }
-
- /* common config */
- rc = mm_jpeg_omx_config_common(my_obj, job);
- if (0 != rc) {
- CDBG_ERROR("%s: config common failed", __func__);
- return rc;
- }
-
- /* config input omx buffer for main input */
- src_buf[JPEG_SRC_IMAGE_TYPE_MAIN] = &(job->encode_parm.buf_info.src_imgs.src_img[JPEG_SRC_IMAGE_TYPE_MAIN]);
- omx_src_buf[JPEG_SRC_IMAGE_TYPE_MAIN] = &job_entry->src_bufs[JPEG_SRC_IMAGE_TYPE_MAIN];
- rc = mm_jpeg_omx_use_buf(my_obj,
- src_buf[JPEG_SRC_IMAGE_TYPE_MAIN],
- omx_src_buf[JPEG_SRC_IMAGE_TYPE_MAIN],
- INPUT_PORT_MAIN);
- if (0 != rc) {
- CDBG_ERROR("%s: config main input omx buffer failed", __func__);
- return rc;
- }
-
- /* config input omx buffer for thumbnail input if there is thumbnail */
- if (has_thumbnail) {
- src_buf[JPEG_SRC_IMAGE_TYPE_THUMB] = &(job->encode_parm.buf_info.src_imgs.src_img[JPEG_SRC_IMAGE_TYPE_THUMB]);
- omx_src_buf[JPEG_SRC_IMAGE_TYPE_THUMB] = &job_entry->src_bufs[JPEG_SRC_IMAGE_TYPE_THUMB];
- rc = mm_jpeg_omx_use_buf(my_obj,
- src_buf[JPEG_SRC_IMAGE_TYPE_THUMB],
- omx_src_buf[JPEG_SRC_IMAGE_TYPE_THUMB],
- INPUT_PORT_THUMBNAIL);
- if (0 != rc) {
- CDBG_ERROR("%s: config thumbnail input omx buffer failed", __func__);
- return rc;
- }
- }
-
- /* config output omx buffer */
- job_entry->sink_buf.portIdx = OUTPUT_PORT;
- OMX_UseBuffer(my_obj->omx_handle,
- &job_entry->sink_buf.buf_header,
- job_entry->sink_buf.portIdx,
- NULL,
- job->encode_parm.buf_info.sink_img.buf_len,
- (void *)job->encode_parm.buf_info.sink_img.buf_vaddr);
- CDBG("%s: Use output buf: port_idx=%d, len=%d, ptr=%p",
- __func__, job_entry->sink_buf.portIdx,
- job->encode_parm.buf_info.sink_img.buf_len,
- job->encode_parm.buf_info.sink_img.buf_vaddr);
-
- /* wait for OMX state ready */
- CDBG("%s: Wait for state change to idle \n", __func__);
- mm_jpeg_job_wait_for_cmd_complete(my_obj, OMX_CommandStateSet, OMX_StateIdle);
- CDBG("%s: State changed to OMX_StateIdle\n", __func__);
-
- /* start OMX encoding by sending executing cmd */
- CDBG("%s: Send command to executing\n", __func__);
- OMX_SendCommand(my_obj->omx_handle, OMX_CommandStateSet, OMX_StateExecuting, NULL);
- mm_jpeg_job_wait_for_cmd_complete(my_obj, OMX_CommandStateSet, OMX_StateExecuting);
-
- /* start input feeding and output writing */
- CDBG("%s: start main input feeding\n", __func__);
- for (i = 0; i < job_entry->src_bufs[JPEG_SRC_IMAGE_TYPE_MAIN].num_bufs; i++) {
- OMX_EmptyThisBuffer(my_obj->omx_handle,
- job_entry->src_bufs[JPEG_SRC_IMAGE_TYPE_MAIN].bufs[i].buf_header);
- }
- if (has_thumbnail) {
- CDBG("%s: start thumbnail input feeding\n", __func__);
- for (i = 0; i < job_entry->src_bufs[JPEG_SRC_IMAGE_TYPE_THUMB].num_bufs; i++) {
- OMX_EmptyThisBuffer(my_obj->omx_handle,
- job_entry->src_bufs[JPEG_SRC_IMAGE_TYPE_THUMB].bufs[i].buf_header);
- }
- }
- CDBG("%s: start output writing\n", __func__);
- OMX_FillThisBuffer(my_obj->omx_handle, job_entry->sink_buf.buf_header);
- return rc;
-}
-
-static void *mm_jpeg_notify_thread(void *data)
-{
- mm_jpeg_job_q_node_t* job_node = (mm_jpeg_job_q_node_t *)data;
- mm_jpeg_job_entry * job_entry = &job_node->entry;
- mm_jpeg_obj* my_obj = (mm_jpeg_obj *)job_entry->jpeg_obj;
- void* node = NULL;
- int32_t rc = 0;
- uint32_t jobId = job_entry->jobId;
-
- if (NULL == my_obj) {
- CDBG_ERROR("%s: jpeg obj is NULL", __func__);
- return NULL;
- }
-
- /* call cb */
- if (NULL != job_entry->job.encode_job.jpeg_cb) {
- /* Add to cb queue */
- rc = mm_jpeg_queue_enq(&my_obj->cb_q, data);
- if (0 != rc) {
- CDBG_ERROR("%s: enqueue into cb_q failed", __func__);
- free(job_node);
- return NULL;
- }
-
- CDBG("%s: send jpeg callback", __func__);
- /* has callback, send CB */
- job_entry->job.encode_job.jpeg_cb(job_entry->job_status,
- job_entry->thumbnail_dropped,
- job_entry->client_hdl,
- job_entry->jobId,
- job_entry->job.encode_job.encode_parm.buf_info.sink_img.buf_vaddr,
- job_entry->jpeg_size,
- job_entry->job.encode_job.userdata);
-
- /* Remove from cb queue */
- CDBG_ERROR("%s: remove job %d from cb queue", __func__, jobId);
- node = mm_jpeg_queue_remove_job_by_job_id(&my_obj->cb_q, jobId);
- if (NULL != node) {
- free(node);
- }
- } else {
- CDBG_ERROR("%s: no cb provided, no action", __func__);
- /* note here we are not freeing any internal memory */
- free(data);
- }
-
- return NULL;
-}
-
-/* process encoding job */
-int32_t mm_jpeg_process_encoding_job(mm_jpeg_obj *my_obj, mm_jpeg_job_q_node_t* job_node)
-{
- int32_t rc = 0;
- mm_jpeg_job_entry* job_entry = &job_node->entry;
-
- /* call OMX_Encode */
- rc = mm_jpeg_omx_encode(my_obj, job_entry);
- if (0 == rc) {
- /* sent encode cmd to OMX, queue job into ongoing queue */
- rc = mm_jpeg_queue_enq(&my_obj->ongoing_job_q, job_node);
- } else {
- /* OMX encode failed, notify error through callback */
- job_entry->job_status = JPEG_JOB_STATUS_ERROR;
- if (NULL != job_entry->job.encode_job.jpeg_cb) {
- /* has callback, create a thread to send CB */
- pthread_create(&job_entry->cb_pid,
- NULL,
- mm_jpeg_notify_thread,
- (void *)job_node);
-
- } else {
- CDBG_ERROR("%s: no cb provided, return here", __func__);
- free(job_node);
- }
- }
-
- return rc;
-}
-/* process job (encoding/decoding) */
-int32_t mm_jpeg_process_job(mm_jpeg_obj *my_obj, mm_jpeg_job_q_node_t* job_node)
-{
- int32_t rc = 0;
-
- switch (job_node->entry.job.job_type) {
- case JPEG_JOB_TYPE_ENCODE:
- rc = mm_jpeg_process_encoding_job(my_obj, job_node);
- break;
- default:
- CDBG_ERROR("%s: job type not supported (%d)",
- __func__, job_node->entry.job.job_type);
- free(job_node);
- rc = -1;
- break;
- }
-
- return rc;
-}
-
-static void *mm_jpeg_jobmgr_thread(void *data)
-{
- int rc = 0;
- int running = 1;
- uint32_t num_ongoing_jobs = 0;
- mm_jpeg_obj *my_obj = (mm_jpeg_obj*)data;
- mm_jpeg_job_cmd_thread_t *cmd_thread = &my_obj->job_mgr;
- mm_jpeg_job_q_node_t* node = NULL;
-
- do {
- do {
- rc = sem_wait(&cmd_thread->job_sem);
- if (rc != 0 && errno != EINVAL) {
- CDBG_ERROR("%s: sem_wait error (%s)",
- __func__, strerror(errno));
- return NULL;
- }
- } while (rc != 0);
-
- /* check ongoing q size */
- num_ongoing_jobs = mm_jpeg_queue_get_size(&my_obj->ongoing_job_q);
- if (num_ongoing_jobs >= NUM_MAX_JPEG_CNCURRENT_JOBS) {
- CDBG("%s: ongoing job already reach max %d", __func__, num_ongoing_jobs);
- continue;
- }
-
- pthread_mutex_lock(&my_obj->job_lock);
- /* can go ahead with new work */
- node = (mm_jpeg_job_q_node_t*)mm_jpeg_queue_deq(&cmd_thread->job_queue);
- if (node != NULL) {
- switch (node->type) {
- case MM_JPEG_CMD_TYPE_JOB:
- mm_jpeg_process_job(my_obj, node);
- break;
- case MM_JPEG_CMD_TYPE_EXIT:
- default:
- /* free node */
- free(node);
- /* set running flag to false */
- running = 0;
- break;
- }
- }
- pthread_mutex_unlock(&my_obj->job_lock);
-
- } while (running);
- return NULL;
-}
-
-int32_t mm_jpeg_jobmgr_thread_launch(mm_jpeg_obj * my_obj)
-{
- int32_t rc = 0;
- mm_jpeg_job_cmd_thread_t * job_mgr = &my_obj->job_mgr;
-
- sem_init(&job_mgr->job_sem, 0, 0);
- mm_jpeg_queue_init(&job_mgr->job_queue);
-
- /* launch the thread */
- pthread_create(&job_mgr->pid,
- NULL,
- mm_jpeg_jobmgr_thread,
- (void *)my_obj);
- return rc;
-}
-
-int32_t mm_jpeg_jobmgr_thread_release(mm_jpeg_obj * my_obj)
-{
- int32_t rc = 0;
- mm_jpeg_job_cmd_thread_t * cmd_thread = &my_obj->job_mgr;
- mm_jpeg_job_q_node_t* node =
- (mm_jpeg_job_q_node_t *)malloc(sizeof(mm_jpeg_job_q_node_t));
- if (NULL == node) {
- CDBG_ERROR("%s: No memory for mm_jpeg_job_q_node_t", __func__);
- return -1;
- }
-
- memset(node, 0, sizeof(mm_jpeg_job_q_node_t));
- node->type = MM_JPEG_CMD_TYPE_EXIT;
-
- mm_jpeg_queue_enq(&cmd_thread->job_queue, node);
- sem_post(&cmd_thread->job_sem);
-
- /* wait until cmd thread exits */
- if (pthread_join(cmd_thread->pid, NULL) != 0) {
- CDBG("%s: pthread dead already\n", __func__);
- }
- mm_jpeg_queue_deinit(&cmd_thread->job_queue);
-
- sem_destroy(&cmd_thread->job_sem);
- memset(cmd_thread, 0, sizeof(mm_jpeg_job_cmd_thread_t));
- return rc;
-}
-
-int32_t mm_jpeg_init(mm_jpeg_obj *my_obj)
-{
- int32_t rc = 0;
-
- /* init locks */
- pthread_mutex_init(&my_obj->job_lock, NULL);
- pthread_mutex_init(&my_obj->omx_evt_lock, NULL);
- pthread_cond_init(&my_obj->omx_evt_cond, NULL);
-
- /* init ongoing job queue */
- rc = mm_jpeg_queue_init(&my_obj->ongoing_job_q);
- rc = mm_jpeg_queue_init(&my_obj->cb_q);
-
- /* init job semaphore and launch jobmgr thread */
- CDBG("%s : Launch jobmgr thread",__func__);
- rc = mm_jpeg_jobmgr_thread_launch(my_obj);
-
- /* load OMX */
- rc = mm_jpeg_omx_load(my_obj);
- if (0 != rc) {
- /* roll back in error case */
- mm_jpeg_jobmgr_thread_release(my_obj);
- mm_jpeg_queue_deinit(&my_obj->ongoing_job_q);
- pthread_mutex_destroy(&my_obj->job_lock);
- pthread_mutex_destroy(&my_obj->omx_evt_lock);
- pthread_cond_destroy(&my_obj->omx_evt_cond);
- }
-
- return rc;
-}
-
-int32_t mm_jpeg_deinit(mm_jpeg_obj *my_obj)
-{
- int32_t rc = 0;
-
- /* unload OMX engine */
- rc = mm_jpeg_omx_unload(my_obj);
-
- /* release jobmgr thread */
- rc = mm_jpeg_jobmgr_thread_release(my_obj);
-
- /* deinit ongoing job and cb queue */
- rc = mm_jpeg_queue_deinit(&my_obj->ongoing_job_q);
- rc = mm_jpeg_queue_deinit(&my_obj->cb_q);
-
- /* destroy locks */
- pthread_mutex_destroy(&my_obj->job_lock);
- pthread_mutex_destroy(&my_obj->omx_evt_lock);
- pthread_cond_destroy(&my_obj->omx_evt_cond);
-
- return rc;
-}
-
-uint32_t mm_jpeg_new_client(mm_jpeg_obj *my_obj)
-{
- uint32_t client_hdl = 0;
- uint8_t idx;
-
- if (my_obj->num_clients >= MAX_JPEG_CLIENT_NUM) {
- CDBG_ERROR("%s: num of clients reached limit", __func__);
- return client_hdl;
- }
-
- for (idx = 0; idx < MAX_JPEG_CLIENT_NUM; idx++) {
- if (0 == my_obj->clnt_mgr[idx].is_used) {
- break;
- }
- }
-
- if (idx < MAX_JPEG_CLIENT_NUM) {
- /* client entry avail */
- /* generate client handler by index */
- client_hdl = mm_jpeg_util_generate_handler(idx);
-
- /* update client entry */
- my_obj->clnt_mgr[idx].is_used = 1;
- my_obj->clnt_mgr[idx].client_handle = client_hdl;
-
- /* increse client count */
- my_obj->num_clients++;
- }
-
- return client_hdl;
-}
-
-int32_t mm_jpeg_start_job(mm_jpeg_obj *my_obj,
- uint32_t client_hdl,
- mm_jpeg_job* job,
- uint32_t* jobId)
-{
- int32_t rc = -1;
- uint8_t clnt_idx = 0;
- uint32_t job_id = 0;
- mm_jpeg_job_q_node_t* node = NULL;
-
- *jobId = 0;
-
- /* check if valid client */
- clnt_idx = mm_jpeg_util_get_index_by_handler(client_hdl);
- if (clnt_idx >= MAX_JPEG_CLIENT_NUM ) {
- CDBG_ERROR("%s: invalid client with handler (%d)", __func__, client_hdl);
- return rc;
- }
-
- /* generate client handler by index */
- job_id = mm_jpeg_util_generate_handler(clnt_idx);
-
- /* enqueue new job into todo job queue */
- node = (mm_jpeg_job_q_node_t *)malloc(sizeof(mm_jpeg_job_q_node_t));
- if (NULL == node) {
- CDBG_ERROR("%s: No memory for mm_jpeg_job_q_node_t", __func__);
- return -rc;
- }
-
- memset(node, 0, sizeof(mm_jpeg_job_q_node_t));
- node->type = MM_JPEG_CMD_TYPE_JOB;
- node->entry.client_hdl = client_hdl;
- node->entry.jobId = job_id;
- memcpy(&node->entry.job, job, sizeof(mm_jpeg_job));
- node->entry.jpeg_obj = (void*)my_obj; /* save a ptr to jpeg_obj */
-
- rc = mm_jpeg_queue_enq(&my_obj->job_mgr.job_queue, node);
- if (0 == rc) {
- sem_post(&my_obj->job_mgr.job_sem);
- *jobId = job_id;
- }
-
- return rc;
-}
-
-int32_t mm_jpeg_abort_job(mm_jpeg_obj *my_obj,
- uint32_t client_hdl,
- uint32_t jobId)
-{
- int32_t rc = -1;
- uint8_t clnt_idx = 0;
- void * node = NULL;
- mm_jpeg_job_entry* job_entry = NULL;
-
- /* check if valid client */
- clnt_idx = mm_jpeg_util_get_index_by_handler(client_hdl);
- if (clnt_idx >= MAX_JPEG_CLIENT_NUM ) {
- CDBG_ERROR("%s: invalid client with handler (%d)", __func__, client_hdl);
- return rc;
- }
-
- pthread_mutex_lock(&my_obj->job_lock);
-
- /* abort job if in ongoing queue */
- node = mm_jpeg_queue_remove_job_by_job_id(&my_obj->ongoing_job_q, jobId);
- if (NULL != node) {
- /* find job that is OMX ongoing, ask OMX to abort the job */
- job_entry = &(((mm_jpeg_job_q_node_t *)node)->entry);
- rc = mm_jpeg_omx_abort_job(my_obj, job_entry);
- free(node);
- goto abort_done;
- }
-
- /* abort job if in todo queue */
- node = mm_jpeg_queue_remove_job_by_job_id(&my_obj->job_mgr.job_queue, jobId);
- if (NULL != node) {
- /* simply delete it */
- free(node);
- goto abort_done;
- }
- /* abort job if in cb queue */
- node = mm_jpeg_queue_remove_job_by_job_id(&my_obj->cb_q, jobId);
- if (NULL != node) {
- /* join cb thread */
- job_entry = &(((mm_jpeg_job_q_node_t *)node)->entry);
- if (pthread_join(job_entry->cb_pid, NULL) != 0) {
- CDBG("%s: pthread dead already\n", __func__);
- }
- free(node);
- }
-abort_done:
- pthread_mutex_unlock(&my_obj->job_lock);
-
- /* wake up jobMgr thread to work on new job if there is any */
- sem_post(&my_obj->job_mgr.job_sem);
-
- return rc;
-}
-
-int32_t mm_jpeg_close(mm_jpeg_obj *my_obj, uint32_t client_hdl)
-{
- int32_t rc = -1;
- uint8_t clnt_idx = 0;
- void* node = NULL;
- mm_jpeg_job_entry* job_entry = NULL;
-
- /* check if valid client */
- clnt_idx = mm_jpeg_util_get_index_by_handler(client_hdl);
- if (clnt_idx >= MAX_JPEG_CLIENT_NUM ) {
- CDBG_ERROR("%s: invalid client with handler (%d)", __func__, client_hdl);
- return rc;
- }
-
- CDBG("%s: E", __func__);
-
- /* abort all jobs from the client */
- pthread_mutex_lock(&my_obj->job_lock);
-
- /* abort job if in ongoing queue */
- CDBG("%s: abort ongoing jobs", __func__);
- node = mm_jpeg_queue_remove_job_by_client_id(&my_obj->ongoing_job_q, client_hdl);
- while (NULL != node) {
- /* find job that is OMX ongoing, ask OMX to abort the job */
- job_entry = &(((mm_jpeg_job_q_node_t *)node)->entry);
- rc = mm_jpeg_omx_abort_job(my_obj, job_entry);
- free(node);
-
- /* find next job from ongoing queue that belongs to this client */
- node = mm_jpeg_queue_remove_job_by_client_id(&my_obj->ongoing_job_q, client_hdl);
- }
-
- /* abort job if in todo queue */
- CDBG("%s: abort todo jobs", __func__);
- node = mm_jpeg_queue_remove_job_by_client_id(&my_obj->job_mgr.job_queue, client_hdl);
- while (NULL != node) {
- /* simply delete the job if in todo queue */
- free(node);
-
- /* find next job from todo queue that belongs to this client */
- node = mm_jpeg_queue_remove_job_by_client_id(&my_obj->job_mgr.job_queue, client_hdl);
- }
-
- /* abort job if in cb queue */
- CDBG("%s: abort done jobs in cb threads", __func__);
- node = mm_jpeg_queue_remove_job_by_client_id(&my_obj->cb_q, client_hdl);
- while (NULL != node) {
- /* join cb thread */
- job_entry = &(((mm_jpeg_job_q_node_t *)node)->entry);
- if (pthread_join(job_entry->cb_pid, NULL) != 0) {
- CDBG("%s: pthread dead already\n", __func__);
- }
- free(node);
-
- /* find next job from cb queue that belongs to this client */
- node = mm_jpeg_queue_remove_job_by_client_id(&my_obj->cb_q, client_hdl);
- }
-
- pthread_mutex_unlock(&my_obj->job_lock);
-
- /* invalidate client entry */
- memset(&my_obj->clnt_mgr[clnt_idx], 0, sizeof(mm_jpeg_client_t));
-
- rc = 0;
- CDBG("%s: X", __func__);
- return rc;
-}
-
-void mm_jpeg_job_wait_for_event(mm_jpeg_obj *my_obj, uint32_t evt_mask)
-{
- pthread_mutex_lock(&my_obj->omx_evt_lock);
- while (!(my_obj->omx_evt_rcvd.evt & evt_mask)) {
- pthread_cond_wait(&my_obj->omx_evt_cond, &my_obj->omx_evt_lock);
- }
- CDBG("%s:done", __func__);
- pthread_mutex_unlock(&my_obj->omx_evt_lock);
-}
-
-void mm_jpeg_job_wait_for_cmd_complete(mm_jpeg_obj *my_obj,
- int cmd,
- int status)
-{
- pthread_mutex_lock(&my_obj->omx_evt_lock);
- while (!((my_obj->omx_evt_rcvd.evt & MM_JPEG_EVENT_MASK_CMD_COMPLETE) &&
- (my_obj->omx_evt_rcvd.omx_value1 == cmd) &&
- (my_obj->omx_evt_rcvd.omx_value2 == status))) {
- pthread_cond_wait(&my_obj->omx_evt_cond, &my_obj->omx_evt_lock);
- }
- CDBG("%s:done", __func__);
- pthread_mutex_unlock(&my_obj->omx_evt_lock);
-}
-
-OMX_ERRORTYPE mm_jpeg_etbdone(OMX_HANDLETYPE hComponent,
- OMX_PTR pAppData,
- OMX_BUFFERHEADERTYPE* pBuffer)
-{
- /* no process needed for etbdone, return here */
- return 0;
-}
-
-OMX_ERRORTYPE mm_jpeg_ftbdone(OMX_HANDLETYPE hComponent,
- OMX_PTR pAppData,
- OMX_BUFFERHEADERTYPE* pBuffer)
-{
- int rc = 0;
- void* node = NULL;
- mm_jpeg_job_entry* job_entry = NULL;
- mm_jpeg_obj * my_obj = (mm_jpeg_obj*)pAppData;
-
- if (NULL == my_obj) {
- CDBG_ERROR("%s: pAppData is NULL, return here", __func__);
- return rc;
- }
-
- CDBG("%s: jpeg done", __func__);
-
- /* signal JPEG_DONE event */
- pthread_mutex_lock(&my_obj->omx_evt_lock);
- my_obj->omx_evt_rcvd.evt = MM_JPEG_EVENT_MASK_JPEG_DONE;
- pthread_cond_signal(&my_obj->omx_evt_cond);
- pthread_mutex_unlock(&my_obj->omx_evt_lock);
-
- /* find job that is OMX ongoing */
- /* If OMX can support multi encoding, it should provide a way to pass jobID.
- * then we can find job by jobID from ongoing queue.
- * For now, since OMX only support one job per time, we simply dequeue it. */
- pthread_mutex_lock(&my_obj->job_lock);
- node = mm_jpeg_queue_deq(&my_obj->ongoing_job_q);
- if (NULL != node) {
- job_entry = &(((mm_jpeg_job_q_node_t *)node)->entry);
-
- /* update status in job entry */
- job_entry->jpeg_size = pBuffer->nFilledLen;
- job_entry->job_status = JPEG_JOB_STATUS_DONE;
- CDBG("%s:filled len = %u, status = %d",
- __func__, job_entry->jpeg_size, job_entry->job_status);
-
- /* clean omx job */
- mm_jpeg_clean_omx_job(my_obj, job_entry);
-
- if (NULL != job_entry->job.encode_job.jpeg_cb) {
- /* has callback, create a thread to send CB */
- pthread_create(&job_entry->cb_pid,
- NULL,
- mm_jpeg_notify_thread,
- node);
-
- } else {
- CDBG_ERROR("%s: no cb provided, return here", __func__);
- free(node);
- }
- }
- pthread_mutex_unlock(&my_obj->job_lock);
-
- /* Wake up jobMgr thread to work on next job if there is any */
- sem_post(&my_obj->job_mgr.job_sem);
-
- return rc;
-}
-
-OMX_ERRORTYPE mm_jpeg_handle_omx_event(OMX_HANDLETYPE hComponent,
- OMX_PTR pAppData,
- OMX_EVENTTYPE eEvent,
- OMX_U32 nData1,
- OMX_U32 nData2,
- OMX_PTR pEventData)
-{
- int rc = 0;
- void* node = NULL;
- mm_jpeg_job_entry* job_entry = NULL;
- mm_jpeg_obj * my_obj = (mm_jpeg_obj*)pAppData;
- uint32_t jobId = 0;
-
- if (NULL == my_obj) {
- CDBG_ERROR("%s: pAppData is NULL, return here", __func__);
- return rc;
- }
-
- /* signal event */
- switch (eEvent) {
- case OMX_EVENT_JPEG_ABORT:
- {
- CDBG("%s: eEvent=OMX_EVENT_JPEG_ABORT", __func__);
- /* signal error evt */
- pthread_mutex_lock(&my_obj->omx_evt_lock);
- my_obj->omx_evt_rcvd.evt = MM_JPEG_EVENT_MASK_JPEG_ABORT;
- pthread_cond_signal(&my_obj->omx_evt_cond);
- pthread_mutex_unlock(&my_obj->omx_evt_lock);
- }
- break;
- case OMX_EventError:
- {
- CDBG("%s: eEvent=OMX_EventError", __func__);
- switch (nData1) {
- case OMX_EVENT_THUMBNAIL_DROPPED:
- {
- uint8_t thumbnail_dropped_flag = 1;
- mm_jpeg_job_q_node_t* data = (mm_jpeg_job_q_node_t*)mm_jpeg_queue_peek(&my_obj->ongoing_job_q);
- jobId = data->entry.jobId;
- mm_jpeg_queue_update_flag(&my_obj->ongoing_job_q,
- jobId,
- thumbnail_dropped_flag);
- }
- break;
- case OMX_EVENT_JPEG_ERROR:
- {
- /* signal error evt */
- pthread_mutex_lock(&my_obj->omx_evt_lock);
- my_obj->omx_evt_rcvd.evt = MM_JPEG_EVENT_MASK_JPEG_ERROR;
- pthread_cond_signal(&my_obj->omx_evt_cond);
- pthread_mutex_unlock(&my_obj->omx_evt_lock);
-
- /* send CB for error case */
- /* If OMX can support multi encoding, it should provide a way to pass jobID.
- * then we can find job by jobID from ongoing queue.
- * For now, since OMX only support one job per time, we simply dequeue it. */
- pthread_mutex_lock(&my_obj->job_lock);
- node = mm_jpeg_queue_deq(&my_obj->ongoing_job_q);
- if (NULL != node) {
- job_entry = &(((mm_jpeg_job_q_node_t *)node)->entry);;
-
- /* clean omx job */
- mm_jpeg_clean_omx_job(my_obj, job_entry);
-
- /* find job that is OMX ongoing */
- job_entry->job_status = JPEG_JOB_STATUS_ERROR;
- if (NULL != job_entry->job.encode_job.jpeg_cb) {
- /* has callback, create a thread to send CB */
- pthread_create(&job_entry->cb_pid,
- NULL,
- mm_jpeg_notify_thread,
- node);
-
- } else {
- CDBG_ERROR("%s: no cb provided, return here", __func__);
- free(node);
- }
- }
- pthread_mutex_unlock(&my_obj->job_lock);
-
- /* Wake up jobMgr thread to work on next job if there is any */
- sem_post(&my_obj->job_mgr.job_sem);
- }
- break;
- default:
- break;
- }
- }
- break;
- case OMX_EventCmdComplete:
- {
- CDBG("%s: eEvent=OMX_EventCmdComplete, value1=%d, value2=%d",
- __func__, nData1, nData2);
- /* signal cmd complete evt */
- pthread_mutex_lock(&my_obj->omx_evt_lock);
- my_obj->omx_evt_rcvd.evt = MM_JPEG_EVENT_MASK_CMD_COMPLETE;
- my_obj->omx_evt_rcvd.omx_value1 = nData1;
- my_obj->omx_evt_rcvd.omx_value2 = nData2;
- pthread_cond_signal(&my_obj->omx_evt_cond);
- pthread_mutex_unlock(&my_obj->omx_evt_lock);
- }
- break;
- default:
- break;
- }
- return rc;
-}
-
-/* remove the first job from the queue with matching client handle */
-mm_jpeg_job_q_node_t* mm_jpeg_queue_remove_job_by_client_id(mm_jpeg_queue_t* queue, uint32_t client_hdl)
-{
- mm_jpeg_q_node_t* node = NULL;
- mm_jpeg_job_q_node_t* data = NULL;
- mm_jpeg_job_q_node_t* job_node = NULL;
- struct cam_list *head = NULL;
- struct cam_list *pos = NULL;
-
- pthread_mutex_lock(&queue->lock);
- head = &queue->head.list;
- pos = head->next;
- while(pos != head) {
- node = member_of(pos, mm_jpeg_q_node_t, list);
- data = (mm_jpeg_job_q_node_t *)node->data;
-
- if (data && (data->entry.client_hdl == client_hdl)) {
- CDBG_ERROR("%s: found matching client node", __func__);
- job_node = data;
- cam_list_del_node(&node->list);
- queue->size--;
- free(node);
- CDBG_ERROR("%s: queue size = %d", __func__, queue->size);
- break;
- }
- pos = pos->next;
- }
-
- pthread_mutex_unlock(&queue->lock);
-
- return job_node;
-}
-
-/* remove job from the queue with matching job id */
-mm_jpeg_job_q_node_t* mm_jpeg_queue_remove_job_by_job_id(mm_jpeg_queue_t* queue, uint32_t job_id)
-{
- mm_jpeg_q_node_t* node = NULL;
- mm_jpeg_job_q_node_t* data = NULL;
- mm_jpeg_job_q_node_t* job_node = NULL;
- struct cam_list *head = NULL;
- struct cam_list *pos = NULL;
-
- pthread_mutex_lock(&queue->lock);
- head = &queue->head.list;
- pos = head->next;
- while(pos != head) {
- node = member_of(pos, mm_jpeg_q_node_t, list);
- data = (mm_jpeg_job_q_node_t *)node->data;
-
- if (data && (data->entry.jobId == job_id)) {
- job_node = data;
- cam_list_del_node(&node->list);
- queue->size--;
- free(node);
- break;
- }
- pos = pos->next;
- }
-
- pthread_mutex_unlock(&queue->lock);
-
- return job_node;
-}
-
-/* update thumbnail dropped flag in job queue */
-int32_t mm_jpeg_queue_update_flag(mm_jpeg_queue_t* queue, uint32_t job_id, uint8_t flag)
-{
- int32_t rc = 0;
- mm_jpeg_q_node_t* node = NULL;
- mm_jpeg_job_q_node_t* data = NULL;
- mm_jpeg_job_q_node_t* job_node = NULL;
- struct cam_list *head = NULL;
- struct cam_list *pos = NULL;
-
- pthread_mutex_lock(&queue->lock);
- head = &queue->head.list;
- pos = head->next;
- while(pos != head) {
- node = member_of(pos, mm_jpeg_q_node_t, list);
- data = (mm_jpeg_job_q_node_t *)node->data;
- if (data && (data->entry.jobId == job_id)) {
- job_node = data;
- break;
- }
- pos = pos->next;
- }
-
- if (job_node) {
- /* find matching job for its job id */
- job_node->entry.thumbnail_dropped = flag;
- } else {
- CDBG_ERROR("%s: No entry for jobId = %d", __func__, job_id);
- rc = -1;
- }
- pthread_mutex_unlock(&queue->lock);
- return rc;
-}