Home | History | Annotate | Download | only in src
      1 /* Copyright (c) 2012-2015, 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 "mm_qcamera_dbg.h"
     31 #include "mm_qcamera_app.h"
     32 
     33 /* This callback is received once the complete JPEG encoding is done */
     34 static void jpeg_encode_cb(jpeg_job_status_t status,
     35                            uint32_t client_hdl,
     36                            uint32_t jobId,
     37                            mm_jpeg_output_t *p_buf,
     38                            void *userData)
     39 {
     40     uint32_t i = 0;
     41     mm_camera_test_obj_t *pme = NULL;
     42     CDBG("%s: BEGIN\n", __func__);
     43 
     44     pme = (mm_camera_test_obj_t *)userData;
     45     if (pme->jpeg_hdl != client_hdl ||
     46         jobId != pme->current_job_id ||
     47         !pme->current_job_frames) {
     48         CDBG_ERROR("%s: NULL current job frames or not matching job ID (%d, %d)",
     49                    __func__, jobId, pme->current_job_id);
     50         return;
     51     }
     52 
     53     /* dump jpeg img */
     54     CDBG_ERROR("%s: job %d, status=%d", __func__, jobId, status);
     55     if (status == JPEG_JOB_STATUS_DONE && p_buf != NULL) {
     56         mm_app_dump_jpeg_frame(p_buf->buf_vaddr, p_buf->buf_filled_len, "jpeg", "jpg", jobId);
     57     }
     58 
     59     /* buf done current encoding frames */
     60     pme->current_job_id = 0;
     61     for (i = 0; i < pme->current_job_frames->num_bufs; i++) {
     62         if (MM_CAMERA_OK != pme->cam->ops->qbuf(pme->current_job_frames->camera_handle,
     63                                                 pme->current_job_frames->ch_id,
     64                                                 pme->current_job_frames->bufs[i])) {
     65             CDBG_ERROR("%s: Failed in Qbuf\n", __func__);
     66         }
     67         mm_app_cache_ops((mm_camera_app_meminfo_t *) pme->current_job_frames->bufs[i]->mem_info,
     68                          ION_IOC_INV_CACHES);
     69     }
     70 
     71     free(pme->jpeg_buf.buf.buffer);
     72     free(pme->current_job_frames);
     73     pme->current_job_frames = NULL;
     74 
     75     /* signal snapshot is done */
     76     mm_camera_app_done();
     77 }
     78 
     79 int encodeData(mm_camera_test_obj_t *test_obj, mm_camera_super_buf_t* recvd_frame,
     80                mm_camera_stream_t *m_stream)
     81 {
     82     cam_capability_t *cam_cap = (cam_capability_t *)(test_obj->cap_buf.buf.buffer);
     83 
     84     int rc = -MM_CAMERA_E_GENERAL;
     85     mm_jpeg_job_t job;
     86 
     87     /* remember current frames being encoded */
     88     test_obj->current_job_frames =
     89         (mm_camera_super_buf_t *)malloc(sizeof(mm_camera_super_buf_t));
     90     if (!test_obj->current_job_frames) {
     91         CDBG_ERROR("%s: No memory for current_job_frames", __func__);
     92         return rc;
     93     }
     94     *(test_obj->current_job_frames) = *recvd_frame;
     95 
     96     memset(&job, 0, sizeof(job));
     97     job.job_type = JPEG_JOB_TYPE_ENCODE;
     98     job.encode_job.session_id = test_obj->current_jpeg_sess_id;
     99 
    100     // TODO: Rotation should be set according to
    101     //       sensor&device orientation
    102     job.encode_job.rotation = 0;
    103     if (cam_cap->position == CAM_POSITION_BACK) {
    104         job.encode_job.rotation = 270;
    105     }
    106 
    107     /* fill in main src img encode param */
    108     job.encode_job.main_dim.src_dim = m_stream->s_config.stream_info->dim;
    109     job.encode_job.main_dim.dst_dim = m_stream->s_config.stream_info->dim;
    110     job.encode_job.src_index = 0;
    111 
    112     job.encode_job.thumb_dim.src_dim = m_stream->s_config.stream_info->dim;
    113     job.encode_job.thumb_dim.dst_dim.width = DEFAULT_PREVIEW_WIDTH;
    114     job.encode_job.thumb_dim.dst_dim.height = DEFAULT_PREVIEW_HEIGHT;
    115 
    116     /* fill in sink img param */
    117     job.encode_job.dst_index = 0;
    118 
    119     if (test_obj->metadata != NULL) {
    120         job.encode_job.p_metadata = test_obj->metadata;
    121     } else {
    122         CDBG_ERROR("%s: Metadata null, not set for jpeg encoding", __func__);
    123     }
    124 
    125     rc = test_obj->jpeg_ops.start_job(&job, &test_obj->current_job_id);
    126     if ( 0 != rc ) {
    127         free(test_obj->current_job_frames);
    128         test_obj->current_job_frames = NULL;
    129     }
    130 
    131     return rc;
    132 }
    133 
    134 int createEncodingSession(mm_camera_test_obj_t *test_obj,
    135                           mm_camera_stream_t *m_stream,
    136                           mm_camera_buf_def_t *m_frame)
    137 {
    138     mm_jpeg_encode_params_t encode_param;
    139 
    140     memset(&encode_param, 0, sizeof(mm_jpeg_encode_params_t));
    141     encode_param.jpeg_cb = jpeg_encode_cb;
    142     encode_param.userdata = (void*)test_obj;
    143     encode_param.encode_thumbnail = 0;
    144     encode_param.quality = 85;
    145     encode_param.color_format = MM_JPEG_COLOR_FORMAT_YCRCBLP_H2V2;
    146     encode_param.thumb_color_format = MM_JPEG_COLOR_FORMAT_YCRCBLP_H2V2;
    147 
    148     /* fill in main src img encode param */
    149     encode_param.num_src_bufs = 1;
    150     encode_param.src_main_buf[0].index = 0;
    151     encode_param.src_main_buf[0].buf_size = m_frame->frame_len;
    152     encode_param.src_main_buf[0].buf_vaddr = (uint8_t *)m_frame->buffer;
    153     encode_param.src_main_buf[0].fd = m_frame->fd;
    154     encode_param.src_main_buf[0].format = MM_JPEG_FMT_YUV;
    155     encode_param.src_main_buf[0].offset = m_stream->offset;
    156 
    157     /* fill in sink img param */
    158     encode_param.num_dst_bufs = 1;
    159     encode_param.dest_buf[0].index = 0;
    160     encode_param.dest_buf[0].buf_size = test_obj->jpeg_buf.buf.frame_len;
    161     encode_param.dest_buf[0].buf_vaddr = (uint8_t *)test_obj->jpeg_buf.buf.buffer;
    162     encode_param.dest_buf[0].fd = test_obj->jpeg_buf.buf.fd;
    163     encode_param.dest_buf[0].format = MM_JPEG_FMT_YUV;
    164 
    165     /* main dimension */
    166     encode_param.main_dim.src_dim = m_stream->s_config.stream_info->dim;
    167     encode_param.main_dim.dst_dim = m_stream->s_config.stream_info->dim;
    168 
    169     return test_obj->jpeg_ops.create_session(test_obj->jpeg_hdl,
    170                                              &encode_param,
    171                                              &test_obj->current_jpeg_sess_id);
    172 }
    173 
    174 /** mm_app_snapshot_metadata_notify_cb
    175  *  @bufs: Pointer to super buffer
    176  *  @user_data: Pointer to user data
    177  *
    178  *
    179  **/
    180 static void mm_app_snapshot_metadata_notify_cb(mm_camera_super_buf_t *bufs,
    181   void *user_data)
    182 {
    183   uint32_t i = 0;
    184   mm_camera_channel_t *channel = NULL;
    185   mm_camera_stream_t *p_stream = NULL;
    186   mm_camera_test_obj_t *pme = (mm_camera_test_obj_t *)user_data;
    187   mm_camera_buf_def_t *frame;
    188   metadata_buffer_t *pMetadata;
    189 
    190   if (NULL == bufs || NULL == user_data) {
    191     CDBG_ERROR("%s: bufs or user_data are not valid ", __func__);
    192     return;
    193   }
    194   frame = bufs->bufs[0];
    195 
    196   /* find channel */
    197   for (i = 0; i < MM_CHANNEL_TYPE_MAX; i++) {
    198     if (pme->channels[i].ch_id == bufs->ch_id) {
    199       channel = &pme->channels[i];
    200       break;
    201     }
    202   }
    203 
    204   if (NULL == channel) {
    205     CDBG_ERROR("%s: Channel object is null", __func__);
    206     return;
    207   }
    208 
    209   /* find meta stream */
    210   for (i = 0; i < channel->num_streams; i++) {
    211     if (channel->streams[i].s_config.stream_info->stream_type == CAM_STREAM_TYPE_METADATA) {
    212       p_stream = &channel->streams[i];
    213       break;
    214     }
    215   }
    216 
    217   if (NULL == p_stream) {
    218     CDBG_ERROR("%s: cannot find metadata stream", __func__);
    219     return;
    220   }
    221 
    222   /* find meta frame */
    223   for (i = 0; i < bufs->num_bufs; i++) {
    224     if (bufs->bufs[i]->stream_id == p_stream->s_id) {
    225       frame = bufs->bufs[i];
    226       break;
    227     }
    228   }
    229 
    230   if (!pme->metadata) {
    231     /* The app will free the metadata, we don't need to bother here */
    232     pme->metadata = malloc(sizeof(metadata_buffer_t));
    233     if (NULL == pme->metadata) {
    234         CDBG_ERROR("%s: malloc failed", __func__);
    235         return;
    236     }
    237   }
    238 
    239   memcpy(pme->metadata , frame->buffer, sizeof(metadata_buffer_t));
    240 
    241   pMetadata = (metadata_buffer_t *)frame->buffer;
    242 
    243   IF_META_AVAILABLE(cam_auto_focus_data_t, focus_data,
    244         CAM_INTF_META_AUTOFOCUS_DATA, pMetadata) {
    245     if (focus_data->focus_state == CAM_AF_FOCUSED) {
    246       CDBG_ERROR("%s: AutoFocus Done Call Back Received\n",__func__);
    247       mm_camera_app_done();
    248     } else if (focus_data->focus_state == CAM_AF_NOT_FOCUSED) {
    249       CDBG_ERROR("%s: AutoFocus failed\n",__func__);
    250       mm_camera_app_done();
    251     }
    252   }
    253 
    254   if (MM_CAMERA_OK != pme->cam->ops->qbuf(bufs->camera_handle,
    255                                           bufs->ch_id,
    256                                           frame)) {
    257     CDBG_ERROR("%s: Failed in Preview Qbuf\n", __func__);
    258   }
    259   mm_app_cache_ops((mm_camera_app_meminfo_t *)frame->mem_info,
    260                    ION_IOC_INV_CACHES);
    261 }
    262 
    263 static void mm_app_snapshot_notify_cb_raw(mm_camera_super_buf_t *bufs,
    264                                           void *user_data)
    265 {
    266 
    267     int rc;
    268     uint32_t i = 0;
    269     mm_camera_test_obj_t *pme = (mm_camera_test_obj_t *)user_data;
    270     mm_camera_channel_t *channel = NULL;
    271     mm_camera_stream_t *m_stream = NULL;
    272     mm_camera_buf_def_t *m_frame = NULL;
    273 
    274     CDBG("%s: BEGIN\n", __func__);
    275 
    276     /* find channel */
    277     for (i = 0; i < MM_CHANNEL_TYPE_MAX; i++) {
    278         if (pme->channels[i].ch_id == bufs->ch_id) {
    279             channel = &pme->channels[i];
    280             break;
    281         }
    282     }
    283     if (NULL == channel) {
    284         CDBG_ERROR("%s: Wrong channel id (%d)", __func__, bufs->ch_id);
    285         rc = -1;
    286         goto EXIT;
    287     }
    288 
    289     /* find snapshot stream */
    290     for (i = 0; i < channel->num_streams; i++) {
    291         if (channel->streams[i].s_config.stream_info->stream_type == CAM_STREAM_TYPE_RAW) {
    292             m_stream = &channel->streams[i];
    293             break;
    294         }
    295     }
    296     if (NULL == m_stream) {
    297         CDBG_ERROR("%s: cannot find snapshot stream", __func__);
    298         rc = -1;
    299         goto EXIT;
    300     }
    301 
    302     /* find snapshot frame */
    303     for (i = 0; i < bufs->num_bufs; i++) {
    304         if (bufs->bufs[i]->stream_id == m_stream->s_id) {
    305             m_frame = bufs->bufs[i];
    306             break;
    307         }
    308     }
    309     if (NULL == m_frame) {
    310         CDBG_ERROR("%s: main frame is NULL", __func__);
    311         rc = -1;
    312         goto EXIT;
    313     }
    314 
    315     mm_app_dump_frame(m_frame, "main", "raw", m_frame->frame_idx);
    316 
    317 EXIT:
    318     for (i=0; i<bufs->num_bufs; i++) {
    319         if (MM_CAMERA_OK != pme->cam->ops->qbuf(bufs->camera_handle,
    320                                                 bufs->ch_id,
    321                                                 bufs->bufs[i])) {
    322             CDBG_ERROR("%s: Failed in Qbuf\n", __func__);
    323         }
    324     }
    325 
    326     mm_camera_app_done();
    327 
    328     CDBG("%s: END\n", __func__);
    329 }
    330 
    331 static void mm_app_snapshot_notify_cb(mm_camera_super_buf_t *bufs,
    332                                       void *user_data)
    333 {
    334 
    335     int rc = 0;
    336     uint32_t i = 0;
    337     mm_camera_test_obj_t *pme = (mm_camera_test_obj_t *)user_data;
    338     mm_camera_channel_t *channel = NULL;
    339     mm_camera_stream_t *p_stream = NULL;
    340     mm_camera_stream_t *m_stream = NULL;
    341     mm_camera_buf_def_t *p_frame = NULL;
    342     mm_camera_buf_def_t *m_frame = NULL;
    343 
    344     CDBG("%s: BEGIN\n", __func__);
    345 
    346     /* find channel */
    347     for (i = 0; i < MM_CHANNEL_TYPE_MAX; i++) {
    348         if (pme->channels[i].ch_id == bufs->ch_id) {
    349             channel = &pme->channels[i];
    350             break;
    351         }
    352     }
    353     if (NULL == channel) {
    354         CDBG_ERROR("%s: Wrong channel id (%d)", __func__, bufs->ch_id);
    355         rc = -1;
    356         goto error;
    357     }
    358 
    359     /* find snapshot stream */
    360     for (i = 0; i < channel->num_streams; i++) {
    361         if (channel->streams[i].s_config.stream_info->stream_type == CAM_STREAM_TYPE_SNAPSHOT) {
    362             m_stream = &channel->streams[i];
    363             break;
    364         }
    365     }
    366     if (NULL == m_stream) {
    367         CDBG_ERROR("%s: cannot find snapshot stream", __func__);
    368         rc = -1;
    369         goto error;
    370     }
    371 
    372     /* find snapshot frame */
    373     for (i = 0; i < bufs->num_bufs; i++) {
    374         if (bufs->bufs[i]->stream_id == m_stream->s_id) {
    375             m_frame = bufs->bufs[i];
    376             break;
    377         }
    378     }
    379     if (NULL == m_frame) {
    380         CDBG_ERROR("%s: main frame is NULL", __func__);
    381         rc = -1;
    382         goto error;
    383     }
    384 
    385     mm_app_dump_frame(m_frame, "main", "yuv", m_frame->frame_idx);
    386 
    387     /* find postview stream */
    388     for (i = 0; i < channel->num_streams; i++) {
    389         if (channel->streams[i].s_config.stream_info->stream_type == CAM_STREAM_TYPE_POSTVIEW) {
    390             p_stream = &channel->streams[i];
    391             break;
    392         }
    393     }
    394     if (NULL != p_stream) {
    395         /* find preview frame */
    396         for (i = 0; i < bufs->num_bufs; i++) {
    397             if (bufs->bufs[i]->stream_id == p_stream->s_id) {
    398                 p_frame = bufs->bufs[i];
    399                 break;
    400             }
    401         }
    402         if (NULL != p_frame) {
    403             mm_app_dump_frame(p_frame, "postview", "yuv", p_frame->frame_idx);
    404         }
    405     }
    406 
    407     mm_app_cache_ops((mm_camera_app_meminfo_t *)m_frame->mem_info,
    408                      ION_IOC_CLEAN_INV_CACHES);
    409 
    410     pme->jpeg_buf.buf.buffer = (uint8_t *)malloc(m_frame->frame_len);
    411     if ( NULL == pme->jpeg_buf.buf.buffer ) {
    412         CDBG_ERROR("%s: error allocating jpeg output buffer", __func__);
    413         goto error;
    414     }
    415 
    416     pme->jpeg_buf.buf.frame_len = m_frame->frame_len;
    417     /* create a new jpeg encoding session */
    418     rc = createEncodingSession(pme, m_stream, m_frame);
    419     if (0 != rc) {
    420         CDBG_ERROR("%s: error creating jpeg session", __func__);
    421         free(pme->jpeg_buf.buf.buffer);
    422         goto error;
    423     }
    424 
    425     /* start jpeg encoding job */
    426     rc = encodeData(pme, bufs, m_stream);
    427     if (0 != rc) {
    428         CDBG_ERROR("%s: error creating jpeg session", __func__);
    429         free(pme->jpeg_buf.buf.buffer);
    430         goto error;
    431     }
    432 
    433 error:
    434     /* buf done rcvd frames in error case */
    435     if ( 0 != rc ) {
    436         for (i=0; i<bufs->num_bufs; i++) {
    437             if (MM_CAMERA_OK != pme->cam->ops->qbuf(bufs->camera_handle,
    438                                                     bufs->ch_id,
    439                                                     bufs->bufs[i])) {
    440                 CDBG_ERROR("%s: Failed in Qbuf\n", __func__);
    441             }
    442             mm_app_cache_ops((mm_camera_app_meminfo_t *)bufs->bufs[i]->mem_info,
    443                              ION_IOC_INV_CACHES);
    444         }
    445     }
    446 
    447     CDBG("%s: END\n", __func__);
    448 }
    449 
    450 mm_camera_channel_t * mm_app_add_snapshot_channel(mm_camera_test_obj_t *test_obj)
    451 {
    452     mm_camera_channel_t *channel = NULL;
    453     mm_camera_stream_t *stream = NULL;
    454 
    455     channel = mm_app_add_channel(test_obj,
    456                                  MM_CHANNEL_TYPE_SNAPSHOT,
    457                                  NULL,
    458                                  NULL,
    459                                  NULL);
    460     if (NULL == channel) {
    461         CDBG_ERROR("%s: add channel failed", __func__);
    462         return NULL;
    463     }
    464 
    465     stream = mm_app_add_snapshot_stream(test_obj,
    466                                         channel,
    467                                         mm_app_snapshot_notify_cb,
    468                                         (void *)test_obj,
    469                                         1,
    470                                         1);
    471     if (NULL == stream) {
    472         CDBG_ERROR("%s: add snapshot stream failed\n", __func__);
    473         mm_app_del_channel(test_obj, channel);
    474         return NULL;
    475     }
    476 
    477     return channel;
    478 }
    479 
    480 mm_camera_stream_t * mm_app_add_postview_stream(mm_camera_test_obj_t *test_obj,
    481                                                 mm_camera_channel_t *channel,
    482                                                 mm_camera_buf_notify_t stream_cb,
    483                                                 void *userdata,
    484                                                 uint8_t num_bufs,
    485                                                 uint8_t num_burst)
    486 {
    487     int rc = MM_CAMERA_OK;
    488     mm_camera_stream_t *stream = NULL;
    489     cam_capability_t *cam_cap = (cam_capability_t *)(test_obj->cap_buf.buf.buffer);
    490 
    491     stream = mm_app_add_stream(test_obj, channel);
    492     if (NULL == stream) {
    493         CDBG_ERROR("%s: add stream failed\n", __func__);
    494         return NULL;
    495     }
    496 
    497     stream->s_config.mem_vtbl.get_bufs = mm_app_stream_initbuf;
    498     stream->s_config.mem_vtbl.put_bufs = mm_app_stream_deinitbuf;
    499     stream->s_config.mem_vtbl.clean_invalidate_buf =
    500       mm_app_stream_clean_invalidate_buf;
    501     stream->s_config.mem_vtbl.invalidate_buf = mm_app_stream_invalidate_buf;
    502     stream->s_config.mem_vtbl.user_data = (void *)stream;
    503     stream->s_config.stream_cb = stream_cb;
    504     stream->s_config.userdata = userdata;
    505     stream->num_of_bufs = num_bufs;
    506 
    507     stream->s_config.stream_info = (cam_stream_info_t *)stream->s_info_buf.buf.buffer;
    508     memset(stream->s_config.stream_info, 0, sizeof(cam_stream_info_t));
    509     stream->s_config.stream_info->stream_type = CAM_STREAM_TYPE_POSTVIEW;
    510     if (num_burst == 0) {
    511         stream->s_config.stream_info->streaming_mode = CAM_STREAMING_MODE_CONTINUOUS;
    512     } else {
    513         stream->s_config.stream_info->streaming_mode = CAM_STREAMING_MODE_BURST;
    514         stream->s_config.stream_info->num_of_burst = num_burst;
    515     }
    516     stream->s_config.stream_info->fmt = DEFAULT_PREVIEW_FORMAT;
    517     stream->s_config.stream_info->dim.width = DEFAULT_PREVIEW_WIDTH;
    518     stream->s_config.stream_info->dim.height = DEFAULT_PREVIEW_HEIGHT;
    519     stream->s_config.padding_info = cam_cap->padding_info;
    520 
    521     rc = mm_app_config_stream(test_obj, channel, stream, &stream->s_config);
    522     if (MM_CAMERA_OK != rc) {
    523         CDBG_ERROR("%s:config preview stream err=%d\n", __func__, rc);
    524         return NULL;
    525     }
    526 
    527     return stream;
    528 }
    529 
    530 int mm_app_start_capture_raw(mm_camera_test_obj_t *test_obj, uint8_t num_snapshots)
    531 {
    532     int32_t rc = MM_CAMERA_OK;
    533     mm_camera_channel_t *channel = NULL;
    534     mm_camera_stream_t *s_main = NULL;
    535     mm_camera_channel_attr_t attr;
    536 
    537     memset(&attr, 0, sizeof(mm_camera_channel_attr_t));
    538     attr.notify_mode = MM_CAMERA_SUPER_BUF_NOTIFY_BURST;
    539     attr.max_unmatched_frames = 3;
    540     channel = mm_app_add_channel(test_obj,
    541                                  MM_CHANNEL_TYPE_CAPTURE,
    542                                  &attr,
    543                                  mm_app_snapshot_notify_cb_raw,
    544                                  test_obj);
    545     if (NULL == channel) {
    546         CDBG_ERROR("%s: add channel failed", __func__);
    547         return -MM_CAMERA_E_GENERAL;
    548     }
    549 
    550     test_obj->buffer_format = DEFAULT_RAW_FORMAT;
    551     s_main = mm_app_add_raw_stream(test_obj,
    552                                    channel,
    553                                    mm_app_snapshot_notify_cb_raw,
    554                                    test_obj,
    555                                    num_snapshots,
    556                                    num_snapshots);
    557     if (NULL == s_main) {
    558         CDBG_ERROR("%s: add main snapshot stream failed\n", __func__);
    559         mm_app_del_channel(test_obj, channel);
    560         return rc;
    561     }
    562 
    563     rc = mm_app_start_channel(test_obj, channel);
    564     if (MM_CAMERA_OK != rc) {
    565         CDBG_ERROR("%s:start zsl failed rc=%d\n", __func__, rc);
    566         mm_app_del_stream(test_obj, channel, s_main);
    567         mm_app_del_channel(test_obj, channel);
    568         return rc;
    569     }
    570 
    571     return rc;
    572 }
    573 
    574 int mm_app_stop_capture_raw(mm_camera_test_obj_t *test_obj)
    575 {
    576     int rc = MM_CAMERA_OK;
    577     mm_camera_channel_t *ch = NULL;
    578     int i;
    579 
    580     ch = mm_app_get_channel_by_type(test_obj, MM_CHANNEL_TYPE_CAPTURE);
    581 
    582     rc = mm_app_stop_channel(test_obj, ch);
    583     if (MM_CAMERA_OK != rc) {
    584         CDBG_ERROR("%s:stop recording failed rc=%d\n", __func__, rc);
    585     }
    586 
    587     for ( i = 0 ; i < ch->num_streams ; i++ ) {
    588         mm_app_del_stream(test_obj, ch, &ch->streams[i]);
    589     }
    590 
    591     mm_app_del_channel(test_obj, ch);
    592 
    593     return rc;
    594 }
    595 
    596 int mm_app_start_capture(mm_camera_test_obj_t *test_obj,
    597                          uint8_t num_snapshots)
    598 {
    599     int32_t rc = MM_CAMERA_OK;
    600     mm_camera_channel_t *channel = NULL;
    601     mm_camera_stream_t *s_main = NULL;
    602     mm_camera_stream_t *s_metadata = NULL;
    603     mm_camera_channel_attr_t attr;
    604 
    605     memset(&attr, 0, sizeof(mm_camera_channel_attr_t));
    606     attr.notify_mode = MM_CAMERA_SUPER_BUF_NOTIFY_CONTINUOUS;
    607     attr.max_unmatched_frames = 3;
    608     channel = mm_app_add_channel(test_obj,
    609                                  MM_CHANNEL_TYPE_CAPTURE,
    610                                  &attr,
    611                                  mm_app_snapshot_notify_cb,
    612                                  test_obj);
    613     if (NULL == channel) {
    614         CDBG_ERROR("%s: add channel failed", __func__);
    615         return -MM_CAMERA_E_GENERAL;
    616     }
    617     s_metadata = mm_app_add_metadata_stream(test_obj,
    618                                             channel,
    619                                             mm_app_snapshot_metadata_notify_cb,
    620                                             (void *)test_obj,
    621                                             CAPTURE_BUF_NUM);
    622      if (NULL == s_metadata) {
    623         CDBG_ERROR("%s: add metadata stream failed\n", __func__);
    624         mm_app_del_channel(test_obj, channel);
    625         return -MM_CAMERA_E_GENERAL;
    626     }
    627 
    628     s_main = mm_app_add_snapshot_stream(test_obj,
    629                                         channel,
    630                                         NULL,
    631                                         NULL,
    632                                         CAPTURE_BUF_NUM,
    633                                         num_snapshots);
    634     if (NULL == s_main) {
    635         CDBG_ERROR("%s: add main snapshot stream failed\n", __func__);
    636         mm_app_del_channel(test_obj, channel);
    637         return rc;
    638     }
    639 
    640     rc = mm_app_start_channel(test_obj, channel);
    641     if (MM_CAMERA_OK != rc) {
    642         CDBG_ERROR("%s:start zsl failed rc=%d\n", __func__, rc);
    643         mm_app_del_stream(test_obj, channel, s_main);
    644         mm_app_del_stream(test_obj, channel, s_metadata);
    645         mm_app_del_channel(test_obj, channel);
    646         return rc;
    647     }
    648 
    649     return rc;
    650 }
    651 
    652 int mm_app_stop_capture(mm_camera_test_obj_t *test_obj)
    653 {
    654     int rc = MM_CAMERA_OK;
    655     mm_camera_channel_t *ch = NULL;
    656 
    657     ch = mm_app_get_channel_by_type(test_obj, MM_CHANNEL_TYPE_CAPTURE);
    658 
    659     rc = mm_app_stop_and_del_channel(test_obj, ch);
    660     if (MM_CAMERA_OK != rc) {
    661         CDBG_ERROR("%s:stop capture channel failed rc=%d\n", __func__, rc);
    662     }
    663 
    664     return rc;
    665 }
    666 
    667 int mm_app_take_picture(mm_camera_test_obj_t *test_obj, uint8_t is_burst_mode)
    668 {
    669     CDBG_HIGH("\nEnter %s!!\n",__func__);
    670     int rc = MM_CAMERA_OK;
    671     uint8_t num_snapshot = 1;
    672     int num_rcvd_snapshot = 0;
    673 
    674     if (is_burst_mode)
    675        num_snapshot = 6;
    676 
    677     //stop preview before starting capture.
    678     rc = mm_app_stop_preview(test_obj);
    679     if (rc != MM_CAMERA_OK) {
    680         CDBG_ERROR("%s: stop preview failed before capture!!, err=%d\n",__func__, rc);
    681         return rc;
    682     }
    683 
    684     rc = mm_app_start_capture(test_obj, num_snapshot);
    685     if (rc != MM_CAMERA_OK) {
    686         CDBG_ERROR("%s: mm_app_start_capture(), err=%d\n", __func__,rc);
    687         return rc;
    688     }
    689     while (num_rcvd_snapshot < num_snapshot) {
    690         CDBG_HIGH("\nWaiting mm_camera_app_wait !!\n");
    691         mm_camera_app_wait();
    692         num_rcvd_snapshot++;
    693     }
    694     rc = mm_app_stop_capture(test_obj);
    695     if (rc != MM_CAMERA_OK) {
    696        CDBG_ERROR("%s: mm_app_stop_capture(), err=%d\n",__func__, rc);
    697        return rc;
    698     }
    699     //start preview after capture.
    700     rc = mm_app_start_preview(test_obj);
    701     if (rc != MM_CAMERA_OK) {
    702         CDBG_ERROR("%s: start preview failed after capture!!, err=%d\n",__func__,rc);
    703     }
    704     return rc;
    705 }
    706