Home | History | Annotate | Download | only in src
      1 /*
      2 Copyright (c) 2012, The Linux Foundation. All rights reserved.
      3 
      4 Redistribution and use in source and binary forms, with or without
      5 modification, are permitted provided that the following conditions are
      6 met:
      7     * Redistributions of source code must retain the above copyright
      8       notice, this list of conditions and the following disclaimer.
      9     * Redistributions in binary form must reproduce the above
     10       copyright notice, this list of conditions and the following
     11       disclaimer in the documentation and/or other materials provided
     12       with the distribution.
     13     * Neither the name of The Linux Foundation nor the names of its
     14       contributors may be used to endorse or promote products derived
     15       from this software without specific prior written permission.
     16 
     17 THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
     18 WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
     19 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
     20 ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
     21 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     22 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     23 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
     24 BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
     25 WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
     26 OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
     27 IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     28 */
     29 
     30 #include <pthread.h>
     31 #include "mm_camera_dbg.h"
     32 #include <errno.h>
     33 #include <sys/ioctl.h>
     34 #include <sys/types.h>
     35 #include <sys/stat.h>
     36 #include <fcntl.h>
     37 #include <poll.h>
     38 #include <linux/ion.h>
     39 #include "mm_qcamera_app.h"
     40 
     41 extern int system_dimension_set(int cam_id);
     42 extern void dumpFrameToFile(mm_camera_buf_def_t* newFrame, int w, int h, char* name, int main_422);
     43 
     44 int32_t mm_qcamera_queue_init(mm_qcamera_queue_t* queue);
     45 int32_t mm_qcamera_queue_enq(mm_qcamera_queue_t* queue, void* data);
     46 void* mm_qcamera_queue_deq(mm_qcamera_queue_t* queue);
     47 void* mm_qcamera_queue_peek(mm_qcamera_queue_t* queue);
     48 int32_t mm_qcamera_queue_deinit(mm_qcamera_queue_t* queue);
     49 int32_t mm_qcamera_queue_flush(mm_qcamera_queue_t* queue);
     50 
     51 static void mm_app_preview_pp_notify_cb(mm_camera_super_buf_t *bufs,
     52                                         void *user_data)
     53 {
     54     int rc;
     55     mm_camera_buf_def_t *frame = NULL;
     56     mm_camera_app_obj_t *pme = NULL;
     57     repro_src_buf_info *buf_info = NULL;
     58 
     59     CDBG("%s: BEGIN\n", __func__);
     60     frame = bufs->bufs[0];
     61     pme = (mm_camera_app_obj_t *)user_data;
     62 
     63     CDBG("%s: BEGIN - length=%d, frame idx = %d\n",
     64          __func__, frame->frame_len, frame->frame_idx);
     65 
     66     dumpFrameToFile(frame, pme->dim.display_width, pme->dim.display_height,"preview", 1);
     67 
     68     buf_info = (repro_src_buf_info *)mm_qcamera_queue_peek(&pme->repro_q);
     69     if (NULL != buf_info) {
     70         buf_info->ref_cnt--;
     71         if (0 == buf_info->ref_cnt) {
     72             mm_qcamera_queue_deq(&pme->repro_q);
     73             pme->cam->ops->qbuf(pme->cam->camera_handle, pme->ch_id, buf_info->frame);
     74             mm_stream_invalid_cache(pme, buf_info->frame);
     75             buf_info->frame = NULL;
     76         }
     77     }
     78 
     79     if (MM_CAMERA_OK != pme->cam->ops->qbuf(pme->cam->camera_handle, pme->ch_id, frame)) {
     80         CDBG_ERROR("%s: Failed in Preview Qbuf\n", __func__);
     81         return;
     82     }
     83     mm_stream_invalid_cache(pme,frame);
     84     CDBG("%s: END\n", __func__);
     85 }
     86 
     87 static void mm_app_video_pp_notify_cb(mm_camera_super_buf_t *bufs,
     88                                       void *user_data)
     89 {
     90 	int rc;
     91 	mm_camera_buf_def_t *frame = NULL;
     92 	mm_camera_app_obj_t *pme = NULL;
     93     repro_src_buf_info *buf_info = NULL;
     94 
     95 	CDBG("%s: BEGIN\n", __func__);
     96 	frame = bufs->bufs[0] ;
     97 	pme = (mm_camera_app_obj_t *)user_data;
     98 
     99 	CDBG("%s: BEGIN - length=%d, frame idx = %d\n",
    100          __func__, frame->frame_len, frame->frame_idx);
    101 
    102 	dumpFrameToFile(frame,pme->dim.orig_video_width,pme->dim.orig_video_height,"video", 1);
    103 
    104     buf_info = (repro_src_buf_info *)mm_qcamera_queue_peek(&pme->repro_q);
    105     if (NULL != buf_info) {
    106         buf_info->ref_cnt--;
    107         if (0 == buf_info->ref_cnt) {
    108             mm_qcamera_queue_deq(&pme->repro_q);
    109             pme->cam->ops->qbuf(pme->cam->camera_handle, pme->ch_id, buf_info->frame);
    110             mm_stream_invalid_cache(pme, buf_info->frame);
    111             buf_info->frame = NULL;
    112         }
    113     }
    114 
    115     if(MM_CAMERA_OK != pme->cam->ops->qbuf(pme->cam->camera_handle, pme->ch_id, frame))
    116     {
    117         CDBG_ERROR("%s: Failed in Snapshot Qbuf\n", __func__);
    118         return;
    119     }
    120     mm_stream_invalid_cache(pme,frame);
    121     CDBG("%s: END\n", __func__);
    122 }
    123 
    124 static void mm_app_isp_pix_notify_cb(mm_camera_super_buf_t *bufs,
    125                                      void *user_data)
    126 {
    127     int rc = MM_CAMERA_OK;
    128     mm_camera_buf_def_t *frame = NULL;
    129     mm_camera_app_obj_t *pme = NULL;
    130     mm_camera_repro_data_t repro_data;
    131 
    132     CDBG("%s: BEGIN\n", __func__);
    133     frame = bufs->bufs[0] ;
    134     pme = (mm_camera_app_obj_t *)user_data;
    135 
    136     CDBG("%s: BEGIN - length=%d, frame idx = %d\n",
    137      __func__, frame->frame_len, frame->frame_idx);
    138 
    139     pme->repro_buf_info[frame->buf_idx].frame = frame;
    140     pme->repro_buf_info[frame->buf_idx].ref_cnt = pme->repro_dest_num;
    141     mm_qcamera_queue_enq(&pme->repro_q,
    142                          (void *)&pme->repro_buf_info[frame->buf_idx]);
    143 
    144     memset(&repro_data, 0, sizeof(mm_camera_repro_data_t));
    145     repro_data.src_frame = frame;
    146 
    147     rc = pme->cam->ops->reprocess(
    148                                  pme->cam->camera_handle,
    149                                  pme->ch_id,
    150                                  pme->isp_repro_handle,
    151                                  &repro_data);
    152     if (MM_CAMERA_OK != rc) {
    153         CDBG_ERROR("%s: reprocess error = %d", __func__, rc);
    154     }
    155 
    156 	CDBG("%s: END\n", __func__);
    157 }
    158 
    159 int prepareReprocess(int cam_id)
    160 {
    161     int rc = MM_CAMERA_OK;
    162     int op_mode;
    163     mm_camera_repro_isp_config_t config;
    164     mm_camera_app_obj_t *pme = mm_app_get_cam_obj(cam_id);
    165 
    166     CDBG("%s: E",__func__);
    167     pme->mem_cam->get_buf = mm_stream_initbuf;
    168     pme->mem_cam->put_buf = mm_stream_deinitbuf;
    169     pme->mem_cam->user_data = pme;
    170 
    171     /* set mode */
    172     op_mode = MM_CAMERA_OP_MODE_VIDEO;
    173     if (MM_CAMERA_OK != (rc = pme->cam->ops->set_parm(
    174                                      pme->cam->camera_handle,
    175                                      MM_CAMERA_PARM_OP_MODE,
    176                                      &op_mode))) {
    177         CDBG_ERROR("%s: Set preview op mode error", __func__);
    178         goto end;
    179     }
    180 
    181     /* init reprocess queue */
    182     mm_qcamera_queue_init(&pme->repro_q);
    183     memset(pme->repro_buf_info, 0, sizeof(pme->repro_buf_info));
    184 
    185     /* add isp pix output1 stream */
    186     pme->stream[MM_CAMERA_ISP_PIX_OUTPUT1].id = pme->cam->ops->add_stream(
    187                                                         pme->cam->camera_handle,
    188                                                         pme->ch_id,
    189                                                         mm_app_isp_pix_notify_cb,
    190                                                         pme,
    191                                                         MM_CAMERA_ISP_PIX_OUTPUT1,
    192                                                         0);
    193 
    194     if (!pme->stream[MM_CAMERA_ISP_PIX_OUTPUT1].id) {
    195         CDBG_ERROR("%s:Add isp_pix_output1 error\n", __func__);
    196         rc = -1;
    197         goto end;
    198     }
    199 
    200     /* add preview stream */
    201     pme->stream[MM_CAMERA_PREVIEW].id = pme->cam->ops->add_stream(
    202                                                         pme->cam->camera_handle,
    203                                                         pme->ch_id,
    204                                                         mm_app_preview_pp_notify_cb,
    205                                                         pme,
    206                                                         MM_CAMERA_PREVIEW,
    207                                                         0);
    208 
    209     if (!pme->stream[MM_CAMERA_PREVIEW].id) {
    210         CDBG_ERROR("%s:Add stream preview error\n", __func__);
    211         rc = -1;
    212         pme->cam->ops->del_stream(pme->cam->camera_handle,
    213                                   pme->ch_id,
    214                                   pme->stream[MM_CAMERA_ISP_PIX_OUTPUT1].id);
    215         pme->stream[MM_CAMERA_ISP_PIX_OUTPUT1].id = 0;
    216         goto end;
    217     }
    218 
    219     /* add record stream */
    220     pme->stream[MM_CAMERA_VIDEO].id = pme->cam->ops->add_stream(
    221                                                         pme->cam->camera_handle,
    222                                                         pme->ch_id,
    223                                                         mm_app_video_pp_notify_cb,
    224                                                         pme,
    225                                                         MM_CAMERA_VIDEO,
    226                                                         0);
    227 
    228     if (!pme->stream[MM_CAMERA_VIDEO].id) {
    229         CDBG_ERROR("%s:Add stream video error\n", __func__);
    230         rc = -1;
    231         pme->cam->ops->del_stream(pme->cam->camera_handle,
    232                                   pme->ch_id,
    233                                   pme->stream[MM_CAMERA_PREVIEW].id);
    234         pme->stream[MM_CAMERA_PREVIEW].id = 0;
    235         pme->cam->ops->del_stream(pme->cam->camera_handle,
    236                                   pme->ch_id,
    237                                   pme->stream[MM_CAMERA_ISP_PIX_OUTPUT1].id);
    238         pme->stream[MM_CAMERA_ISP_PIX_OUTPUT1].id = 0;
    239         goto end;
    240     }
    241 
    242     /* open isp reprocess */
    243     pme->isp_repro_handle = pme->cam->ops->open_repro_isp(
    244                                                         pme->cam->camera_handle,
    245                                                         pme->ch_id,
    246                                                         MM_CAMERA_REPRO_ISP_PIX);
    247 
    248     if (!pme->isp_repro_handle) {
    249         CDBG_ERROR("%s:open isp reprocess error\n", __func__);
    250         rc = -1;
    251         pme->cam->ops->del_stream(pme->cam->camera_handle,
    252                                   pme->ch_id,
    253                                   pme->stream[MM_CAMERA_VIDEO].id);
    254         pme->stream[MM_CAMERA_VIDEO].id = 0;
    255         pme->cam->ops->del_stream(pme->cam->camera_handle,
    256                                   pme->ch_id,
    257                                   pme->stream[MM_CAMERA_PREVIEW].id);
    258         pme->stream[MM_CAMERA_PREVIEW].id = 0;
    259         pme->cam->ops->del_stream(pme->cam->camera_handle,
    260                                   pme->ch_id,
    261                                   pme->stream[MM_CAMERA_ISP_PIX_OUTPUT1].id);
    262         pme->stream[MM_CAMERA_ISP_PIX_OUTPUT1].id = 0;
    263         goto end;
    264     }
    265 
    266     /* prepare repro isp config */
    267     memset(&pme->repro_config, 0, sizeof(mm_camera_repro_config_data_t));
    268     pme->repro_config.image_mode = MM_CAMERA_ISP_PIX_OUTPUT1;
    269     if (pme->dim.display_width * pme->dim.display_height >
    270         pme->dim.video_width * pme->dim.video_height) {
    271         /* preview size is larger than video, use preview config as repro isp config */
    272         pme->repro_config.format = pme->dim.prev_format;
    273         pme->repro_config.width = pme->dim.display_width;
    274         pme->repro_config.height = pme->dim.display_height;
    275     } else {
    276         pme->repro_config.format = pme->dim.enc_format;
    277         pme->repro_config.width = pme->dim.video_width;
    278         pme->repro_config.height = pme->dim.video_height;
    279     }
    280 
    281     /* config isp reprocess */
    282     memset(&config, 0, sizeof(mm_camera_repro_isp_config_t));
    283     config.src.format = pme->repro_config.format;
    284     config.src.image_mode = pme->repro_config.image_mode;
    285     config.src.width = pme->repro_config.width;
    286     config.src.height = pme->repro_config.height;
    287     config.src.inst_handle = pme->stream[MM_CAMERA_ISP_PIX_OUTPUT1].id;
    288 
    289     pme->repro_dest_num = 0;
    290     config.num_dest = 2;
    291     config.dest[0].image_mode = MM_CAMERA_PREVIEW;
    292     config.dest[0].format = pme->dim.prev_format;
    293     config.dest[0].width = pme->dim.display_width;
    294     config.dest[0].height = pme->dim.display_height;
    295     config.dest[0].inst_handle = pme->stream[MM_CAMERA_PREVIEW].id;
    296     config.dest[1].image_mode = MM_CAMERA_VIDEO;
    297     config.dest[1].format = pme->dim.enc_format;
    298     config.dest[1].width = pme->dim.video_width;
    299     config.dest[1].height = pme->dim.video_height;
    300     config.dest[1].inst_handle = pme->stream[MM_CAMERA_VIDEO].id;
    301 
    302     rc = pme->cam->ops->config_repro_isp(
    303                                         pme->cam->camera_handle,
    304                                         pme->ch_id,
    305                                         pme->isp_repro_handle,
    306                                         &config);
    307 
    308     if (MM_CAMERA_OK != rc) {
    309         CDBG_ERROR("%s:config isp reprocess error = %d\n", __func__, rc);
    310         pme->cam->ops->close_repro_isp(pme->cam->camera_handle,
    311                                        pme->ch_id,
    312                                        pme->isp_repro_handle);
    313         pme->isp_repro_handle = 0;
    314         pme->cam->ops->del_stream(pme->cam->camera_handle,
    315                                   pme->ch_id,
    316                                   pme->stream[MM_CAMERA_VIDEO].id);
    317         pme->stream[MM_CAMERA_VIDEO].id = 0;
    318         pme->cam->ops->del_stream(pme->cam->camera_handle,
    319                                   pme->ch_id,
    320                                   pme->stream[MM_CAMERA_PREVIEW].id);
    321         pme->stream[MM_CAMERA_PREVIEW].id = 0;
    322         pme->cam->ops->del_stream(pme->cam->camera_handle,
    323                                   pme->ch_id,
    324                                   pme->stream[MM_CAMERA_ISP_PIX_OUTPUT1].id);
    325         pme->stream[MM_CAMERA_ISP_PIX_OUTPUT1].id = 0;
    326     }
    327 
    328 end:
    329     CDBG("%s: X rc = %d", __func__, rc);
    330     return rc;
    331 }
    332 
    333 int unprepareReprocess(int cam_id)
    334 {
    335     int rc = MM_CAMERA_OK;
    336 
    337     mm_camera_app_obj_t *pme = mm_app_get_cam_obj(cam_id);
    338 
    339     CDBG("%s: E",__func__);
    340     rc = pme->cam->ops->close_repro_isp(pme->cam->camera_handle,
    341                                         pme->ch_id,
    342                                         pme->isp_repro_handle);
    343     pme->isp_repro_handle = 0;
    344     mm_qcamera_queue_deinit(&pme->repro_q);
    345 
    346     CDBG("%s: X rc = %d", __func__, rc);
    347     return rc;
    348 }
    349 
    350 int startPreviewPP(int cam_id)
    351 {
    352     int rc = MM_CAMERA_OK;
    353     uint32_t stream[1];
    354     mm_camera_app_obj_t *pme = mm_app_get_cam_obj(cam_id);
    355 
    356     CDBG("%s: E",__func__);
    357 
    358     /* attach preview stream to isp reprocess pipe */
    359     if (MM_CAMERA_OK != (rc = pme->cam->ops->attach_stream_to_repro_isp(
    360                                                             pme->cam->camera_handle,
    361                                                             pme->ch_id,
    362                                                             pme->isp_repro_handle,
    363                                                             pme->stream[MM_CAMERA_PREVIEW].id))) {
    364         CDBG_ERROR("%s : Attach preview to reprocess error",__func__);
    365         goto end;
    366     }
    367 
    368     /* start isp reprocess pipe for preview */
    369     if (MM_CAMERA_OK != (rc = pme->cam->ops->start_repro_isp(pme->cam->camera_handle,
    370                                                             pme->ch_id,
    371                                                             pme->isp_repro_handle,
    372                                                             pme->stream[MM_CAMERA_PREVIEW].id))) {
    373         CDBG_ERROR("%s : Start reprocess for preview error",__func__);
    374         pme->cam->ops->detach_stream_from_repro_isp(
    375                                                 pme->cam->camera_handle,
    376                                                 pme->ch_id,
    377                                                 pme->isp_repro_handle,
    378                                                 pme->stream[MM_CAMERA_PREVIEW].id);
    379         goto end;
    380     }
    381 
    382     /* increase actual reprocess dest num */
    383     pme->repro_dest_num++;
    384 
    385     /* start preview stream */
    386     pme->stream[MM_CAMERA_PREVIEW].str_config.fmt.meta_header = MM_CAMEAR_META_DATA_TYPE_DEF;
    387     pme->stream[MM_CAMERA_PREVIEW].str_config.fmt.fmt = pme->dim.prev_format;
    388     pme->stream[MM_CAMERA_PREVIEW].str_config.fmt.width = pme->dim.display_width;
    389     pme->stream[MM_CAMERA_PREVIEW].str_config.fmt.height = pme->dim.display_height;
    390     pme->stream[MM_CAMERA_PREVIEW].str_config.need_stream_on = 1;
    391     pme->stream[MM_CAMERA_PREVIEW].str_config.num_of_bufs = PREVIEW_BUF_NUM;
    392     if (MM_CAMERA_OK != (rc = pme->cam->ops->config_stream(pme->cam->camera_handle,
    393                                                            pme->ch_id,
    394                                                            pme->stream[MM_CAMERA_PREVIEW].id,
    395                                                            &pme->stream[MM_CAMERA_PREVIEW].str_config))) {
    396         CDBG_ERROR("%s:config preview err=%d\n", __func__, rc);
    397         pme->cam->ops->stop_repro_isp(
    398                                     pme->cam->camera_handle,
    399                                     pme->ch_id,
    400                                     pme->isp_repro_handle,
    401                                     pme->stream[MM_CAMERA_PREVIEW].id);
    402         pme->cam->ops->detach_stream_from_repro_isp(
    403                                                 pme->cam->camera_handle,
    404                                                 pme->ch_id,
    405                                                 pme->isp_repro_handle,
    406                                                 pme->stream[MM_CAMERA_PREVIEW].id);
    407         pme->repro_dest_num--;
    408         goto end;
    409     }
    410     stream[0] = pme->stream[MM_CAMERA_PREVIEW].id;
    411     if (MM_CAMERA_OK != (rc = pme->cam->ops->start_streams(pme->cam->camera_handle,
    412                                                           pme->ch_id,
    413                                                           1,
    414                                                           stream))) {
    415         CDBG_ERROR("%s : Preview Stream on Error",__func__);
    416         pme->cam->ops->stop_repro_isp(
    417                                     pme->cam->camera_handle,
    418                                     pme->ch_id,
    419                                     pme->isp_repro_handle,
    420                                     pme->stream[MM_CAMERA_PREVIEW].id);
    421         pme->cam->ops->detach_stream_from_repro_isp(
    422                                                 pme->cam->camera_handle,
    423                                                 pme->ch_id,
    424                                                 pme->isp_repro_handle,
    425                                                 pme->stream[MM_CAMERA_PREVIEW].id);
    426         pme->repro_dest_num--;
    427         goto end;
    428     }
    429 
    430     /* start isp pix output1 stream */
    431     pme->stream[MM_CAMERA_ISP_PIX_OUTPUT1].str_config.fmt.meta_header = MM_CAMEAR_META_DATA_TYPE_DEF;
    432     pme->stream[MM_CAMERA_ISP_PIX_OUTPUT1].str_config.fmt.fmt = pme->repro_config.format;
    433     pme->stream[MM_CAMERA_ISP_PIX_OUTPUT1].str_config.fmt.width = pme->repro_config.width;
    434     pme->stream[MM_CAMERA_ISP_PIX_OUTPUT1].str_config.fmt.height = pme->repro_config.height;
    435     pme->stream[MM_CAMERA_ISP_PIX_OUTPUT1].str_config.need_stream_on = 1;
    436     pme->stream[MM_CAMERA_ISP_PIX_OUTPUT1].str_config.num_of_bufs = ISP_PIX_BUF_NUM;
    437     if (MM_CAMERA_OK != (rc = pme->cam->ops->config_stream(pme->cam->camera_handle,
    438                                                            pme->ch_id,
    439                                                            pme->stream[MM_CAMERA_ISP_PIX_OUTPUT1].id,
    440                                                            &pme->stream[MM_CAMERA_ISP_PIX_OUTPUT1].str_config))) {
    441         CDBG_ERROR("%s:config isp pix stream err=%d\n", __func__, rc);
    442         pme->cam->ops->stop_repro_isp(
    443                                     pme->cam->camera_handle,
    444                                     pme->ch_id,
    445                                     pme->isp_repro_handle,
    446                                     pme->stream[MM_CAMERA_PREVIEW].id);
    447         pme->cam->ops->detach_stream_from_repro_isp(
    448                                                 pme->cam->camera_handle,
    449                                                 pme->ch_id,
    450                                                 pme->isp_repro_handle,
    451                                                 pme->stream[MM_CAMERA_PREVIEW].id);
    452         pme->repro_dest_num--;
    453     }
    454     stream[0] = pme->stream[MM_CAMERA_ISP_PIX_OUTPUT1].id;
    455     if (MM_CAMERA_OK != (rc = pme->cam->ops->start_streams(pme->cam->camera_handle,
    456                                                           pme->ch_id,
    457                                                           1,
    458                                                           stream))) {
    459         CDBG_ERROR("%s : Preview Stream on Error",__func__);
    460         pme->cam->ops->stop_repro_isp(
    461                                     pme->cam->camera_handle,
    462                                     pme->ch_id,
    463                                     pme->isp_repro_handle,
    464                                     pme->stream[MM_CAMERA_PREVIEW].id);
    465         pme->cam->ops->detach_stream_from_repro_isp(
    466                                                 pme->cam->camera_handle,
    467                                                 pme->ch_id,
    468                                                 pme->isp_repro_handle,
    469                                                 pme->stream[MM_CAMERA_PREVIEW].id);
    470         pme->repro_dest_num--;
    471         goto end;
    472     }
    473 
    474 end:
    475     CDBG("%s: X rc=%d\n", __func__, rc);
    476     return rc;
    477 }
    478 
    479 int stopPreviewPP(int cam_id)
    480 {
    481     int rc = MM_CAMERA_OK;
    482     uint32_t stream[1];
    483     mm_camera_app_obj_t *pme = mm_app_get_cam_obj(cam_id);
    484 
    485     CDBG("%s: E",__func__);
    486 
    487     /* stop preview stream */
    488     stream[0] = pme->stream[MM_CAMERA_PREVIEW].id;
    489     if (MM_CAMERA_OK != (rc = pme->cam->ops->stop_streams(pme->cam->camera_handle,
    490                                                           pme->ch_id,
    491                                                           1,
    492                                                           stream))) {
    493         CDBG_ERROR("%s : Preview Stream off Error",__func__);
    494     }
    495 
    496     if (MM_CAMERA_OK != (rc = pme->cam->ops->del_stream(pme->cam->camera_handle,
    497                                                         pme->ch_id,
    498                                                         pme->stream[MM_CAMERA_PREVIEW].id))) {
    499         CDBG_ERROR("%s : Delete Stream Preview error",__func__);
    500     }
    501 
    502     /* stop isp reprocess pipe for preview */
    503     if (MM_CAMERA_OK != (rc = pme->cam->ops->stop_repro_isp(pme->cam->camera_handle,
    504                                                             pme->ch_id,
    505                                                             pme->isp_repro_handle,
    506                                                             pme->stream[MM_CAMERA_PREVIEW].id))) {
    507         CDBG_ERROR("%s : Stop reprocess for preview error",__func__);
    508     }
    509 
    510     /* decrease actual reprocess dest num */
    511     pme->repro_dest_num--;
    512 
    513     /* detach preview stream from isp reprocess pipe */
    514     if (MM_CAMERA_OK != (rc = pme->cam->ops->detach_stream_from_repro_isp(
    515                                                             pme->cam->camera_handle,
    516                                                             pme->ch_id,
    517                                                             pme->isp_repro_handle,
    518                                                             pme->stream[MM_CAMERA_PREVIEW].id))) {
    519         CDBG_ERROR("%s : Detach preview from reprocess error",__func__);
    520     }
    521 
    522     /* stop isp pix output1 stream */
    523     stream[0] = pme->stream[MM_CAMERA_ISP_PIX_OUTPUT1].id;
    524     if (MM_CAMERA_OK != (rc = pme->cam->ops->stop_streams(pme->cam->camera_handle,
    525                                                           pme->ch_id,
    526                                                           1,
    527                                                           stream))) {
    528         CDBG_ERROR("%s : ISP pix Stream off Error",__func__);
    529     }
    530 
    531     if (MM_CAMERA_OK != (rc = pme->cam->ops->del_stream(pme->cam->camera_handle,
    532                                                         pme->ch_id,
    533                                                         pme->stream[MM_CAMERA_ISP_PIX_OUTPUT1].id))) {
    534         CDBG_ERROR("%s : Delete Stream isp pix error",__func__);
    535     }
    536 
    537 end:
    538     CDBG("%s: X rc=%d\n", __func__, rc);
    539     return rc;
    540 }
    541 
    542 int startRecordPP(int cam_id)
    543 {
    544     int rc = MM_CAMERA_OK;
    545     uint32_t stream[1];
    546     mm_camera_app_obj_t *pme = mm_app_get_cam_obj(cam_id);
    547 
    548     CDBG("%s: E",__func__);
    549 
    550     /* attach video stream to isp reprocess pipe */
    551     if (MM_CAMERA_OK != (rc = pme->cam->ops->attach_stream_to_repro_isp(
    552                                                             pme->cam->camera_handle,
    553                                                             pme->ch_id,
    554                                                             pme->isp_repro_handle,
    555                                                             pme->stream[MM_CAMERA_VIDEO].id))) {
    556         CDBG_ERROR("%s : Attach video to reprocess error",__func__);
    557         goto end;
    558     }
    559 
    560     /* start isp reprocess pipe for video */
    561     if (MM_CAMERA_OK != (rc = pme->cam->ops->start_repro_isp(pme->cam->camera_handle,
    562                                                             pme->ch_id,
    563                                                             pme->isp_repro_handle,
    564                                                             pme->stream[MM_CAMERA_VIDEO].id))) {
    565         CDBG_ERROR("%s : Start reprocess for video error",__func__);
    566         pme->cam->ops->detach_stream_from_repro_isp(
    567                                                 pme->cam->camera_handle,
    568                                                 pme->ch_id,
    569                                                 pme->isp_repro_handle,
    570                                                 pme->stream[MM_CAMERA_VIDEO].id);
    571         goto end;
    572     }
    573 
    574     /* increase actual reprocess dest num */
    575     pme->repro_dest_num++;
    576 
    577     /* start preview stream */
    578     pme->stream[MM_CAMERA_VIDEO].str_config.fmt.meta_header = MM_CAMEAR_META_DATA_TYPE_DEF;
    579     pme->stream[MM_CAMERA_VIDEO].str_config.fmt.fmt = pme->dim.enc_format;
    580     pme->stream[MM_CAMERA_VIDEO].str_config.fmt.width = pme->dim.video_width;
    581     pme->stream[MM_CAMERA_VIDEO].str_config.fmt.height = pme->dim.video_height;
    582     pme->stream[MM_CAMERA_VIDEO].str_config.need_stream_on = 1;
    583     pme->stream[MM_CAMERA_VIDEO].str_config.num_of_bufs = VIDEO_BUF_NUM;
    584     if (MM_CAMERA_OK != (rc = pme->cam->ops->config_stream(pme->cam->camera_handle,
    585                                                            pme->ch_id,
    586                                                            pme->stream[MM_CAMERA_VIDEO].id,
    587                                                            &pme->stream[MM_CAMERA_VIDEO].str_config))) {
    588         CDBG_ERROR("%s:config video err=%d\n", __func__, rc);
    589         pme->cam->ops->stop_repro_isp(
    590                                     pme->cam->camera_handle,
    591                                     pme->ch_id,
    592                                     pme->isp_repro_handle,
    593                                     pme->stream[MM_CAMERA_VIDEO].id);
    594         pme->cam->ops->detach_stream_from_repro_isp(
    595                                                 pme->cam->camera_handle,
    596                                                 pme->ch_id,
    597                                                 pme->isp_repro_handle,
    598                                                 pme->stream[MM_CAMERA_VIDEO].id);
    599         pme->repro_dest_num--;
    600         goto end;
    601     }
    602     stream[0] = pme->stream[MM_CAMERA_VIDEO].id;
    603     if (MM_CAMERA_OK != (rc = pme->cam->ops->start_streams(pme->cam->camera_handle,
    604                                                           pme->ch_id,
    605                                                           1,
    606                                                           stream))) {
    607         CDBG_ERROR("%s : Preview Stream on Error",__func__);
    608         pme->cam->ops->stop_repro_isp(
    609                                     pme->cam->camera_handle,
    610                                     pme->ch_id,
    611                                     pme->isp_repro_handle,
    612                                     pme->stream[MM_CAMERA_VIDEO].id);
    613         pme->cam->ops->detach_stream_from_repro_isp(
    614                                                 pme->cam->camera_handle,
    615                                                 pme->ch_id,
    616                                                 pme->isp_repro_handle,
    617                                                 pme->stream[MM_CAMERA_VIDEO].id);
    618         pme->repro_dest_num--;
    619         goto end;
    620     }
    621 
    622 end:
    623     CDBG("%s: X rc=%d\n", __func__, rc);
    624     return rc;
    625 }
    626 
    627 int stopRecordPP(int cam_id)
    628 {
    629     int rc = MM_CAMERA_OK;
    630     uint32_t stream[1];
    631     mm_camera_app_obj_t *pme = mm_app_get_cam_obj(cam_id);
    632 
    633     CDBG("%s: E",__func__);
    634 
    635     /* stop video stream */
    636     stream[0] = pme->stream[MM_CAMERA_VIDEO].id;
    637     if (MM_CAMERA_OK != (rc = pme->cam->ops->stop_streams(pme->cam->camera_handle,
    638                                                           pme->ch_id,
    639                                                           1,
    640                                                           stream))) {
    641         CDBG_ERROR("%s : Video Stream off Error",__func__);
    642     }
    643 
    644     if (MM_CAMERA_OK != (rc = pme->cam->ops->del_stream(pme->cam->camera_handle,
    645                                                         pme->ch_id,
    646                                                         pme->stream[MM_CAMERA_VIDEO].id))) {
    647         CDBG_ERROR("%s : Delete Stream Preview error",__func__);
    648     }
    649 
    650     /* stop isp reprocess pipe for video */
    651     if (MM_CAMERA_OK != (rc = pme->cam->ops->stop_repro_isp(pme->cam->camera_handle,
    652                                                             pme->ch_id,
    653                                                             pme->isp_repro_handle,
    654                                                             pme->stream[MM_CAMERA_VIDEO].id))) {
    655         CDBG_ERROR("%s : Stop reprocess for video error",__func__);
    656     }
    657 
    658     /* decrease actual reprocess dest num */
    659     pme->repro_dest_num--;
    660 
    661     /* detach preview stream from isp reprocess pipe */
    662     if (MM_CAMERA_OK != (rc = pme->cam->ops->detach_stream_from_repro_isp(
    663                                                             pme->cam->camera_handle,
    664                                                             pme->ch_id,
    665                                                             pme->isp_repro_handle,
    666                                                             pme->stream[MM_CAMERA_VIDEO].id))) {
    667         CDBG_ERROR("%s : Detach video from reprocess error",__func__);
    668     }
    669 
    670     CDBG("%s: X rc=%d\n", __func__, rc);
    671     return rc;
    672 }
    673 
    674 int32_t mm_qcamera_queue_init(mm_qcamera_queue_t* queue)
    675 {
    676     pthread_mutex_init(&queue->lock, NULL);
    677     cam_list_init(&queue->head.list);
    678     queue->size = 0;
    679     return 0;
    680 }
    681 
    682 int32_t mm_qcamera_queue_enq(mm_qcamera_queue_t* queue, void* data)
    683 {
    684     mm_qcamera_q_node_t* node =
    685         (mm_qcamera_q_node_t *)malloc(sizeof(mm_qcamera_q_node_t));
    686     if (NULL == node) {
    687         CDBG_ERROR("%s: No memory for mm_camera_q_node_t", __func__);
    688         return -1;
    689     }
    690 
    691     memset(node, 0, sizeof(mm_qcamera_q_node_t));
    692     node->data = data;
    693 
    694     pthread_mutex_lock(&queue->lock);
    695     cam_list_add_tail_node(&node->list, &queue->head.list);
    696     queue->size++;
    697     pthread_mutex_unlock(&queue->lock);
    698 
    699     return 0;
    700 
    701 }
    702 
    703 void* mm_qcamera_queue_deq(mm_qcamera_queue_t* queue)
    704 {
    705     mm_qcamera_q_node_t* node = NULL;
    706     void* data = NULL;
    707     struct cam_list *head = NULL;
    708     struct cam_list *pos = NULL;
    709 
    710     pthread_mutex_lock(&queue->lock);
    711     head = &queue->head.list;
    712     pos = head->next;
    713     if (pos != head) {
    714         node = member_of(pos, mm_qcamera_q_node_t, list);
    715         cam_list_del_node(&node->list);
    716         queue->size--;
    717     }
    718     pthread_mutex_unlock(&queue->lock);
    719 
    720     if (NULL != node) {
    721         data = node->data;
    722         free(node);
    723     }
    724 
    725     return data;
    726 }
    727 
    728 void* mm_qcamera_queue_peek(mm_qcamera_queue_t* queue)
    729 {
    730     mm_qcamera_q_node_t* node = NULL;
    731     void* data = NULL;
    732     struct cam_list *head = NULL;
    733     struct cam_list *pos = NULL;
    734 
    735     pthread_mutex_lock(&queue->lock);
    736     head = &queue->head.list;
    737     pos = head->next;
    738     if (pos != head) {
    739         node = member_of(pos, mm_qcamera_q_node_t, list);
    740     }
    741     pthread_mutex_unlock(&queue->lock);
    742 
    743     if (NULL != node) {
    744         data = node->data;
    745     }
    746 
    747     return data;
    748 }
    749 
    750 int32_t mm_qcamera_queue_deinit(mm_qcamera_queue_t* queue)
    751 {
    752     mm_qcamera_queue_flush(queue);
    753     pthread_mutex_destroy(&queue->lock);
    754     return 0;
    755 }
    756 
    757 int32_t mm_qcamera_queue_flush(mm_qcamera_queue_t* queue)
    758 {
    759     mm_qcamera_q_node_t* node = NULL;
    760     void* data = NULL;
    761     struct cam_list *head = NULL;
    762     struct cam_list *pos = NULL;
    763 
    764     pthread_mutex_lock(&queue->lock);
    765     head = &queue->head.list;
    766     pos = head->next;
    767 
    768     while(pos != head) {
    769         node = member_of(pos, mm_qcamera_q_node_t, list);
    770         pos = pos->next;
    771         cam_list_del_node(&node->list);
    772         queue->size--;
    773 
    774         /* TODO later to consider ptr inside data */
    775         /* for now we only assume there is no ptr inside data
    776          * so we free data directly */
    777         if (NULL != node->data) {
    778             free(node->data);
    779         }
    780         free(node);
    781 
    782     }
    783     queue->size = 0;
    784     pthread_mutex_unlock(&queue->lock);
    785     return 0;
    786 }
    787 
    788 /* re-processing test case for preview only */
    789 int mm_app_tc_reprocess_preview_only(mm_camera_app_t *cam_apps)
    790 {
    791     int rc = MM_CAMERA_OK;
    792     int i,j,k;
    793     int result = 0;
    794 
    795     printf("\n Verifying reprocess for preview on front and back camera...\n");
    796     if (cam_apps->num_cameras == 0) {
    797         CDBG_ERROR("%s:Query Failed: Num of cameras = %d\n",__func__, cam_apps->num_cameras);
    798         rc = -1;
    799         goto end;
    800     }
    801     CDBG_ERROR("Re-processing test case for preview");
    802     for (i = 1; i < cam_apps->num_cameras; i++) {
    803         CDBG_ERROR("Open camera %d", i);
    804         if ( mm_app_open(i) != MM_CAMERA_OK) {
    805             CDBG_ERROR("%s:mm_app_open() err=%d\n",__func__, rc);
    806             rc = -1;
    807             goto end;
    808         }
    809         if (system_dimension_set(my_cam_app.cam_open) != MM_CAMERA_OK) {
    810             CDBG_ERROR("%s:system_dimension_set() err=%d\n",__func__, rc);
    811             rc = -1;
    812             goto end;
    813         }
    814         CDBG_ERROR("Prepare re-process");
    815         if ( MM_CAMERA_OK != (rc = prepareReprocess(my_cam_app.cam_open))) {
    816             CDBG_ERROR("%s: prepareReprocess() err=%d\n", __func__, rc);
    817             break;
    818         }
    819         result = 0;
    820         for (k = 0; k < MM_QCAMERA_APP_INTERATION; k++) {
    821           CDBG_ERROR("Start preview with pp");
    822           if ( MM_CAMERA_OK != (rc = startPreviewPP(my_cam_app.cam_open))) {
    823             CDBG_ERROR("%s: startPreviewPP() err=%d\n", __func__, rc);
    824             break;
    825           }
    826 
    827           CDBG_ERROR("Let preview run for 1s");
    828           /* sleep for 1s */
    829           usleep(1000*1000);
    830 
    831           CDBG_ERROR("Stop preview with pp");
    832           if ( MM_CAMERA_OK != (rc = stopPreviewPP(my_cam_app.cam_open))) {
    833             CDBG_ERROR("%s: stopPreviewPP() err=%d\n", __func__, rc);
    834             break;
    835           }
    836           result++;
    837           usleep(10*1000);
    838         }
    839 
    840         CDBG_ERROR("Unprepare re-process");
    841         if ( MM_CAMERA_OK != (rc = unprepareReprocess(my_cam_app.cam_open))) {
    842             CDBG_ERROR("%s: unprepareReprocess() err=%d\n", __func__, rc);
    843         }
    844 
    845         CDBG_ERROR("Close camera");
    846         if ( mm_app_close(my_cam_app.cam_open) != MM_CAMERA_OK) {
    847             CDBG_ERROR("%s:mm_app_close() err=%d\n",__func__, rc);
    848             rc = -1;
    849             goto end;
    850         }
    851         if (result != MM_QCAMERA_APP_INTERATION) {
    852             printf("%s: preview re-reprocess Fails for Camera %d", __func__, i);
    853             rc = -1;
    854             break;
    855         }
    856     }
    857 end:
    858     if (rc == 0) {
    859         printf("\nPassed\n");
    860     } else {
    861         printf("\nFailed\n");
    862     }
    863     CDBG("%s:END, rc = %d\n", __func__, rc);
    864     return rc;
    865 }
    866 
    867 /* re-processing test case for preview and recording */
    868 int mm_app_tc_reprocess_preview_and_recording(mm_camera_app_t *cam_apps)
    869 {
    870     int rc = MM_CAMERA_OK;
    871     int i,j,k;
    872     int result = 0;
    873 
    874     printf("\n Verifying reprocess for preview/recording on front and back camera...\n");
    875     if (cam_apps->num_cameras == 0) {
    876         CDBG_ERROR("%s:Query Failed: Num of cameras = %d\n",__func__, cam_apps->num_cameras);
    877         rc = -1;
    878         goto end;
    879     }
    880     CDBG_ERROR("Re-processing test case for preview");
    881     for (i = 1; i < cam_apps->num_cameras; i++) {
    882         CDBG_ERROR("Open camera %d", i);
    883         if ( mm_app_open(i) != MM_CAMERA_OK) {
    884             CDBG_ERROR("%s:mm_app_open() err=%d\n",__func__, rc);
    885             rc = -1;
    886             goto end;
    887         }
    888         if (system_dimension_set(my_cam_app.cam_open) != MM_CAMERA_OK) {
    889             CDBG_ERROR("%s:system_dimension_set() err=%d\n",__func__, rc);
    890             rc = -1;
    891             goto end;
    892         }
    893         CDBG_ERROR("Prepare re-process");
    894         if ( MM_CAMERA_OK != (rc = prepareReprocess(my_cam_app.cam_open))) {
    895             CDBG_ERROR("%s: prepareReprocess() err=%d\n", __func__, rc);
    896             break;
    897         }
    898         result = 0;
    899         for (k = 0; k < MM_QCAMERA_APP_INTERATION; k++) {
    900           CDBG_ERROR("Start preview with pp");
    901           if ( MM_CAMERA_OK != (rc = startPreviewPP(my_cam_app.cam_open))) {
    902             CDBG_ERROR("%s: startPreviewPP() err=%d\n", __func__, rc);
    903             break;
    904           }
    905 
    906           CDBG_ERROR("Let preview run for 1s");
    907           /* sleep for 1s */
    908           usleep(1000*1000);
    909 
    910           for (j = 0; j < 2; j++) {
    911               CDBG_ERROR("Start recording with pp");
    912               if ( MM_CAMERA_OK != (rc = startRecordPP(my_cam_app.cam_open))) {
    913                 CDBG_ERROR("%s: startRecordPP() err=%d\n", __func__, rc);
    914                 break;
    915               }
    916 
    917               CDBG_ERROR("Let recording run for 1s");
    918               /* sleep for 1s */
    919               usleep(1000*1000);
    920 
    921               CDBG_ERROR("Stop recording with pp");
    922               if ( MM_CAMERA_OK != (rc = stopRecordPP(my_cam_app.cam_open))) {
    923                 CDBG_ERROR("%s: stopRecordPP() err=%d\n", __func__, rc);
    924                 break;
    925               }
    926           }
    927 
    928           CDBG_ERROR("Stop preview with pp");
    929           if ( MM_CAMERA_OK != (rc = stopPreviewPP(my_cam_app.cam_open))) {
    930             CDBG_ERROR("%s: stopPreviewPP() err=%d\n", __func__, rc);
    931             break;
    932           }
    933           result++;
    934           usleep(10*1000);
    935         }
    936 
    937         CDBG_ERROR("Unprepare re-process");
    938         if ( MM_CAMERA_OK != (rc = unprepareReprocess(my_cam_app.cam_open))) {
    939             CDBG_ERROR("%s: unprepareReprocess() err=%d\n", __func__, rc);
    940         }
    941 
    942         CDBG_ERROR("Close camera");
    943         if ( mm_app_close(my_cam_app.cam_open) != MM_CAMERA_OK) {
    944             CDBG_ERROR("%s:mm_app_close() err=%d\n",__func__, rc);
    945             rc = -1;
    946             goto end;
    947         }
    948         if (result != MM_QCAMERA_APP_INTERATION) {
    949             printf("%s: preview+recording re-reprocess Fails for Camera %d", __func__, i);
    950             rc = -1;
    951             break;
    952         }
    953     }
    954 end:
    955     if (rc == 0) {
    956         printf("\nPassed\n");
    957     } else {
    958         printf("\nFailed\n");
    959     }
    960     CDBG("%s:END, rc = %d\n", __func__, rc);
    961     return rc;
    962 }
    963 
    964