Home | History | Annotate | Download | only in src
      1 /* Copyright (c) 2012-2014, The Linux Foundation. All rights reserved.
      2  *
      3  * Redistribution and use in source and binary forms, with or without
      4  * modification, are permitted provided that the following conditions are
      5  * met:
      6  *     * Redistributions of source code must retain the above copyright
      7  *       notice, this list of conditions and the following disclaimer.
      8  *     * Redistributions in binary form must reproduce the above
      9  *       copyright notice, this list of conditions and the following
     10  *       disclaimer in the documentation and/or other materials provided
     11  *       with the distribution.
     12  *     * Neither the name of The Linux Foundation nor the names of its
     13  *       contributors may be used to endorse or promote products derived
     14  *       from this software without specific prior written permission.
     15  *
     16  * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
     17  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
     18  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
     19  * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
     20  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     21  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     22  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
     23  * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
     24  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
     25  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
     26  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     27  *
     28  */
     29 
     30 #include "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     int 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   int 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 = bufs->bufs[0];
    188   metadata_buffer_t *pMetadata;
    189   cam_auto_focus_data_t *focus_data;
    190 
    191   if (NULL == bufs || NULL == user_data) {
    192     CDBG_ERROR("%s: bufs or user_data are not valid ", __func__);
    193     return;
    194   }
    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   /* find meta stream */
    204   for (i = 0; i < channel->num_streams; i++) {
    205     if (channel->streams[i].s_config.stream_info->stream_type == CAM_STREAM_TYPE_METADATA) {
    206       p_stream = &channel->streams[i];
    207       break;
    208     }
    209   }
    210   /* find meta frame */
    211   for (i = 0; i < bufs->num_bufs; i++) {
    212     if (bufs->bufs[i]->stream_id == p_stream->s_id) {
    213       frame = bufs->bufs[i];
    214       break;
    215     }
    216   }
    217 
    218   if (NULL == p_stream) {
    219     CDBG_ERROR("%s: cannot find metadata stream", __func__);
    220     return;
    221   }
    222   if (!pme->metadata) {
    223     /* The app will free the metadata, we don't need to bother here */
    224     pme->metadata = malloc(sizeof(metadata_buffer_t));
    225   }
    226   memcpy(pme->metadata , frame->buffer, sizeof(metadata_buffer_t));
    227 
    228   pMetadata = (metadata_buffer_t *)frame->buffer;
    229 
    230   if (IS_META_AVAILABLE(CAM_INTF_META_AUTOFOCUS_DATA, pMetadata)) {
    231     focus_data = (cam_auto_focus_data_t *)
    232       POINTER_OF_META(CAM_INTF_META_AUTOFOCUS_DATA, pMetadata);
    233     if (focus_data->focus_state == CAM_AF_FOCUSED) {
    234       CDBG_ERROR("%s: AutoFocus Done Call Back Received\n",__func__);
    235       mm_camera_app_done();
    236     } else if (focus_data->focus_state == CAM_AF_NOT_FOCUSED) {
    237       CDBG_ERROR("%s: AutoFocus failed\n",__func__);
    238       mm_camera_app_done();
    239     }
    240   }
    241 
    242   if (MM_CAMERA_OK != pme->cam->ops->qbuf(bufs->camera_handle,
    243                                           bufs->ch_id,
    244                                           frame)) {
    245     CDBG_ERROR("%s: Failed in Preview Qbuf\n", __func__);
    246   }
    247   mm_app_cache_ops((mm_camera_app_meminfo_t *)frame->mem_info,
    248                    ION_IOC_INV_CACHES);
    249 }
    250 
    251 static void mm_app_snapshot_notify_cb_raw(mm_camera_super_buf_t *bufs,
    252                                           void *user_data)
    253 {
    254 
    255     int rc;
    256     int i = 0;
    257     mm_camera_test_obj_t *pme = (mm_camera_test_obj_t *)user_data;
    258     mm_camera_channel_t *channel = NULL;
    259     mm_camera_stream_t *m_stream = NULL;
    260     mm_camera_buf_def_t *m_frame = NULL;
    261 
    262     CDBG("%s: BEGIN\n", __func__);
    263 
    264     /* find channel */
    265     for (i = 0; i < MM_CHANNEL_TYPE_MAX; i++) {
    266         if (pme->channels[i].ch_id == bufs->ch_id) {
    267             channel = &pme->channels[i];
    268             break;
    269         }
    270     }
    271     if (NULL == channel) {
    272         CDBG_ERROR("%s: Wrong channel id (%d)", __func__, bufs->ch_id);
    273         rc = -1;
    274         goto EXIT;
    275     }
    276 
    277     /* find snapshot stream */
    278     for (i = 0; i < channel->num_streams; i++) {
    279         if (channel->streams[i].s_config.stream_info->stream_type == CAM_STREAM_TYPE_RAW) {
    280             m_stream = &channel->streams[i];
    281             break;
    282         }
    283     }
    284     if (NULL == m_stream) {
    285         CDBG_ERROR("%s: cannot find snapshot stream", __func__);
    286         rc = -1;
    287         goto EXIT;
    288     }
    289 
    290     /* find snapshot frame */
    291     for (i = 0; i < bufs->num_bufs; i++) {
    292         if (bufs->bufs[i]->stream_id == m_stream->s_id) {
    293             m_frame = bufs->bufs[i];
    294             break;
    295         }
    296     }
    297     if (NULL == m_frame) {
    298         CDBG_ERROR("%s: main frame is NULL", __func__);
    299         rc = -1;
    300         goto EXIT;
    301     }
    302 
    303     mm_app_dump_frame(m_frame, "main", "raw", m_frame->frame_idx);
    304 
    305 EXIT:
    306     for (i=0; i<bufs->num_bufs; i++) {
    307         if (MM_CAMERA_OK != pme->cam->ops->qbuf(bufs->camera_handle,
    308                                                 bufs->ch_id,
    309                                                 bufs->bufs[i])) {
    310             CDBG_ERROR("%s: Failed in Qbuf\n", __func__);
    311         }
    312     }
    313 
    314     mm_camera_app_done();
    315 
    316     CDBG("%s: END\n", __func__);
    317 }
    318 
    319 static void mm_app_snapshot_notify_cb(mm_camera_super_buf_t *bufs,
    320                                       void *user_data)
    321 {
    322 
    323     int rc = 0;
    324     int i = 0;
    325     mm_camera_test_obj_t *pme = (mm_camera_test_obj_t *)user_data;
    326     mm_camera_channel_t *channel = NULL;
    327     mm_camera_stream_t *p_stream = NULL;
    328     mm_camera_stream_t *m_stream = NULL;
    329     mm_camera_buf_def_t *p_frame = NULL;
    330     mm_camera_buf_def_t *m_frame = NULL;
    331 
    332     CDBG("%s: BEGIN\n", __func__);
    333 
    334     /* find channel */
    335     for (i = 0; i < MM_CHANNEL_TYPE_MAX; i++) {
    336         if (pme->channels[i].ch_id == bufs->ch_id) {
    337             channel = &pme->channels[i];
    338             break;
    339         }
    340     }
    341     if (NULL == channel) {
    342         CDBG_ERROR("%s: Wrong channel id (%d)", __func__, bufs->ch_id);
    343         rc = -1;
    344         goto error;
    345     }
    346 
    347     /* find snapshot stream */
    348     for (i = 0; i < channel->num_streams; i++) {
    349         if (channel->streams[i].s_config.stream_info->stream_type == CAM_STREAM_TYPE_SNAPSHOT) {
    350             m_stream = &channel->streams[i];
    351             break;
    352         }
    353     }
    354     if (NULL == m_stream) {
    355         CDBG_ERROR("%s: cannot find snapshot stream", __func__);
    356         rc = -1;
    357         goto error;
    358     }
    359 
    360     /* find snapshot frame */
    361     for (i = 0; i < bufs->num_bufs; i++) {
    362         if (bufs->bufs[i]->stream_id == m_stream->s_id) {
    363             m_frame = bufs->bufs[i];
    364             break;
    365         }
    366     }
    367     if (NULL == m_frame) {
    368         CDBG_ERROR("%s: main frame is NULL", __func__);
    369         rc = -1;
    370         goto error;
    371     }
    372 
    373     mm_app_dump_frame(m_frame, "main", "yuv", m_frame->frame_idx);
    374 
    375     /* find postview stream */
    376     for (i = 0; i < channel->num_streams; i++) {
    377         if (channel->streams[i].s_config.stream_info->stream_type == CAM_STREAM_TYPE_POSTVIEW) {
    378             p_stream = &channel->streams[i];
    379             break;
    380         }
    381     }
    382     if (NULL != p_stream) {
    383         /* find preview frame */
    384         for (i = 0; i < bufs->num_bufs; i++) {
    385             if (bufs->bufs[i]->stream_id == p_stream->s_id) {
    386                 p_frame = bufs->bufs[i];
    387                 break;
    388             }
    389         }
    390         if (NULL != p_frame) {
    391             mm_app_dump_frame(p_frame, "postview", "yuv", p_frame->frame_idx);
    392         }
    393     }
    394 
    395     mm_app_cache_ops((mm_camera_app_meminfo_t *)m_frame->mem_info,
    396                      ION_IOC_CLEAN_INV_CACHES);
    397 
    398     pme->jpeg_buf.buf.buffer = (uint8_t *)malloc(m_frame->frame_len);
    399     if ( NULL == pme->jpeg_buf.buf.buffer ) {
    400         CDBG_ERROR("%s: error allocating jpeg output buffer", __func__);
    401         goto error;
    402     }
    403 
    404     pme->jpeg_buf.buf.frame_len = m_frame->frame_len;
    405     /* create a new jpeg encoding session */
    406     rc = createEncodingSession(pme, m_stream, m_frame);
    407     if (0 != rc) {
    408         CDBG_ERROR("%s: error creating jpeg session", __func__);
    409         free(pme->jpeg_buf.buf.buffer);
    410         goto error;
    411     }
    412 
    413     /* start jpeg encoding job */
    414     rc = encodeData(pme, bufs, m_stream);
    415     if (0 != rc) {
    416         CDBG_ERROR("%s: error creating jpeg session", __func__);
    417         free(pme->jpeg_buf.buf.buffer);
    418         goto error;
    419     }
    420 
    421 error:
    422     /* buf done rcvd frames in error case */
    423     if ( 0 != rc ) {
    424         for (i=0; i<bufs->num_bufs; i++) {
    425             if (MM_CAMERA_OK != pme->cam->ops->qbuf(bufs->camera_handle,
    426                                                     bufs->ch_id,
    427                                                     bufs->bufs[i])) {
    428                 CDBG_ERROR("%s: Failed in Qbuf\n", __func__);
    429             }
    430             mm_app_cache_ops((mm_camera_app_meminfo_t *)bufs->bufs[i]->mem_info,
    431                              ION_IOC_INV_CACHES);
    432         }
    433     }
    434 
    435     CDBG("%s: END\n", __func__);
    436 }
    437 
    438 mm_camera_channel_t * mm_app_add_snapshot_channel(mm_camera_test_obj_t *test_obj)
    439 {
    440     mm_camera_channel_t *channel = NULL;
    441     mm_camera_stream_t *stream = NULL;
    442 
    443     channel = mm_app_add_channel(test_obj,
    444                                  MM_CHANNEL_TYPE_SNAPSHOT,
    445                                  NULL,
    446                                  NULL,
    447                                  NULL);
    448     if (NULL == channel) {
    449         CDBG_ERROR("%s: add channel failed", __func__);
    450         return NULL;
    451     }
    452 
    453     stream = mm_app_add_snapshot_stream(test_obj,
    454                                         channel,
    455                                         mm_app_snapshot_notify_cb,
    456                                         (void *)test_obj,
    457                                         1,
    458                                         1);
    459     if (NULL == stream) {
    460         CDBG_ERROR("%s: add snapshot stream failed\n", __func__);
    461         mm_app_del_channel(test_obj, channel);
    462         return NULL;
    463     }
    464 
    465     return channel;
    466 }
    467 
    468 mm_camera_stream_t * mm_app_add_postview_stream(mm_camera_test_obj_t *test_obj,
    469                                                 mm_camera_channel_t *channel,
    470                                                 mm_camera_buf_notify_t stream_cb,
    471                                                 void *userdata,
    472                                                 uint8_t num_bufs,
    473                                                 uint8_t num_burst)
    474 {
    475     int rc = MM_CAMERA_OK;
    476     mm_camera_stream_t *stream = NULL;
    477     cam_capability_t *cam_cap = (cam_capability_t *)(test_obj->cap_buf.buf.buffer);
    478 
    479     stream = mm_app_add_stream(test_obj, channel);
    480     if (NULL == stream) {
    481         CDBG_ERROR("%s: add stream failed\n", __func__);
    482         return NULL;
    483     }
    484 
    485     stream->s_config.mem_vtbl.get_bufs = mm_app_stream_initbuf;
    486     stream->s_config.mem_vtbl.put_bufs = mm_app_stream_deinitbuf;
    487     stream->s_config.mem_vtbl.clean_invalidate_buf =
    488       mm_app_stream_clean_invalidate_buf;
    489     stream->s_config.mem_vtbl.invalidate_buf = mm_app_stream_invalidate_buf;
    490     stream->s_config.mem_vtbl.user_data = (void *)stream;
    491     stream->s_config.stream_cb = stream_cb;
    492     stream->s_config.userdata = userdata;
    493     stream->num_of_bufs = num_bufs;
    494 
    495     stream->s_config.stream_info = (cam_stream_info_t *)stream->s_info_buf.buf.buffer;
    496     memset(stream->s_config.stream_info, 0, sizeof(cam_stream_info_t));
    497     stream->s_config.stream_info->stream_type = CAM_STREAM_TYPE_POSTVIEW;
    498     if (num_burst == 0) {
    499         stream->s_config.stream_info->streaming_mode = CAM_STREAMING_MODE_CONTINUOUS;
    500     } else {
    501         stream->s_config.stream_info->streaming_mode = CAM_STREAMING_MODE_BURST;
    502         stream->s_config.stream_info->num_of_burst = num_burst;
    503     }
    504     stream->s_config.stream_info->fmt = DEFAULT_PREVIEW_FORMAT;
    505     stream->s_config.stream_info->dim.width = DEFAULT_PREVIEW_WIDTH;
    506     stream->s_config.stream_info->dim.height = DEFAULT_PREVIEW_HEIGHT;
    507     stream->s_config.padding_info = cam_cap->padding_info;
    508 
    509     rc = mm_app_config_stream(test_obj, channel, stream, &stream->s_config);
    510     if (MM_CAMERA_OK != rc) {
    511         CDBG_ERROR("%s:config preview stream err=%d\n", __func__, rc);
    512         return NULL;
    513     }
    514 
    515     return stream;
    516 }
    517 
    518 int mm_app_start_capture_raw(mm_camera_test_obj_t *test_obj, uint8_t num_snapshots)
    519 {
    520     int32_t rc = MM_CAMERA_OK;
    521     mm_camera_channel_t *channel = NULL;
    522     mm_camera_stream_t *s_main = NULL;
    523     mm_camera_channel_attr_t attr;
    524 
    525     memset(&attr, 0, sizeof(mm_camera_channel_attr_t));
    526     attr.notify_mode = MM_CAMERA_SUPER_BUF_NOTIFY_BURST;
    527     attr.max_unmatched_frames = 3;
    528     channel = mm_app_add_channel(test_obj,
    529                                  MM_CHANNEL_TYPE_CAPTURE,
    530                                  &attr,
    531                                  mm_app_snapshot_notify_cb_raw,
    532                                  test_obj);
    533     if (NULL == channel) {
    534         CDBG_ERROR("%s: add channel failed", __func__);
    535         return -MM_CAMERA_E_GENERAL;
    536     }
    537 
    538     test_obj->buffer_format = DEFAULT_RAW_FORMAT;
    539     s_main = mm_app_add_raw_stream(test_obj,
    540                                    channel,
    541                                    mm_app_snapshot_notify_cb_raw,
    542                                    test_obj,
    543                                    num_snapshots,
    544                                    num_snapshots);
    545     if (NULL == s_main) {
    546         CDBG_ERROR("%s: add main snapshot stream failed\n", __func__);
    547         mm_app_del_channel(test_obj, channel);
    548         return rc;
    549     }
    550 
    551     rc = mm_app_start_channel(test_obj, channel);
    552     if (MM_CAMERA_OK != rc) {
    553         CDBG_ERROR("%s:start zsl failed rc=%d\n", __func__, rc);
    554         mm_app_del_stream(test_obj, channel, s_main);
    555         mm_app_del_channel(test_obj, channel);
    556         return rc;
    557     }
    558 
    559     return rc;
    560 }
    561 
    562 int mm_app_stop_capture_raw(mm_camera_test_obj_t *test_obj)
    563 {
    564     int rc = MM_CAMERA_OK;
    565     mm_camera_channel_t *ch = NULL;
    566     int i;
    567 
    568     ch = mm_app_get_channel_by_type(test_obj, MM_CHANNEL_TYPE_CAPTURE);
    569 
    570     rc = mm_app_stop_channel(test_obj, ch);
    571     if (MM_CAMERA_OK != rc) {
    572         CDBG_ERROR("%s:stop recording failed rc=%d\n", __func__, rc);
    573     }
    574 
    575     for ( i = 0 ; i < ch->num_streams ; i++ ) {
    576         mm_app_del_stream(test_obj, ch, &ch->streams[i]);
    577     }
    578 
    579     mm_app_del_channel(test_obj, ch);
    580 
    581     return rc;
    582 }
    583 
    584 int mm_app_start_capture(mm_camera_test_obj_t *test_obj,
    585                          uint8_t num_snapshots)
    586 {
    587     int32_t rc = MM_CAMERA_OK;
    588     mm_camera_channel_t *channel = NULL;
    589     mm_camera_stream_t *s_main = NULL;
    590     mm_camera_stream_t *s_metadata = NULL;
    591     mm_camera_channel_attr_t attr;
    592 
    593     memset(&attr, 0, sizeof(mm_camera_channel_attr_t));
    594     attr.notify_mode = MM_CAMERA_SUPER_BUF_NOTIFY_CONTINUOUS;
    595     attr.max_unmatched_frames = 3;
    596     channel = mm_app_add_channel(test_obj,
    597                                  MM_CHANNEL_TYPE_CAPTURE,
    598                                  &attr,
    599                                  mm_app_snapshot_notify_cb,
    600                                  test_obj);
    601     if (NULL == channel) {
    602         CDBG_ERROR("%s: add channel failed", __func__);
    603         return -MM_CAMERA_E_GENERAL;
    604     }
    605     s_metadata = mm_app_add_metadata_stream(test_obj,
    606                                             channel,
    607                                             mm_app_snapshot_metadata_notify_cb,
    608                                             (void *)test_obj,
    609                                             CAPTURE_BUF_NUM);
    610      if (NULL == s_metadata) {
    611         CDBG_ERROR("%s: add metadata stream failed\n", __func__);
    612         mm_app_del_channel(test_obj, channel);
    613         return -MM_CAMERA_E_GENERAL;
    614     }
    615 
    616     s_main = mm_app_add_snapshot_stream(test_obj,
    617                                         channel,
    618                                         NULL,
    619                                         NULL,
    620                                         CAPTURE_BUF_NUM,
    621                                         num_snapshots);
    622     if (NULL == s_main) {
    623         CDBG_ERROR("%s: add main snapshot stream failed\n", __func__);
    624         mm_app_del_channel(test_obj, channel);
    625         return rc;
    626     }
    627 
    628     rc = mm_app_start_channel(test_obj, channel);
    629     if (MM_CAMERA_OK != rc) {
    630         CDBG_ERROR("%s:start zsl failed rc=%d\n", __func__, rc);
    631         mm_app_del_stream(test_obj, channel, s_main);
    632         mm_app_del_stream(test_obj, channel, s_metadata);
    633         mm_app_del_channel(test_obj, channel);
    634         return rc;
    635     }
    636 
    637     return rc;
    638 }
    639 
    640 int mm_app_stop_capture(mm_camera_test_obj_t *test_obj)
    641 {
    642     int rc = MM_CAMERA_OK;
    643     mm_camera_channel_t *ch = NULL;
    644 
    645     ch = mm_app_get_channel_by_type(test_obj, MM_CHANNEL_TYPE_CAPTURE);
    646 
    647     rc = mm_app_stop_and_del_channel(test_obj, ch);
    648     if (MM_CAMERA_OK != rc) {
    649         CDBG_ERROR("%s:stop capture channel failed rc=%d\n", __func__, rc);
    650     }
    651 
    652     return rc;
    653 }
    654 
    655 int mm_app_take_picture(mm_camera_test_obj_t *test_obj, uint8_t is_burst_mode)
    656 {
    657     CDBG_HIGH("\nEnter %s!!\n",__func__);
    658     int rc = MM_CAMERA_OK;
    659     int num_snapshot = 1;
    660     int num_rcvd_snapshot = 0;
    661 
    662     if (is_burst_mode)
    663        num_snapshot = 6;
    664 
    665     //stop preview before starting capture.
    666     rc = mm_app_stop_preview(test_obj);
    667     if (rc != MM_CAMERA_OK) {
    668         CDBG_ERROR("%s: stop preview failed before capture!!, err=%d\n",__func__, rc);
    669         return rc;
    670     }
    671 
    672     rc = mm_app_start_capture(test_obj, num_snapshot);
    673     if (rc != MM_CAMERA_OK) {
    674         CDBG_ERROR("%s: mm_app_start_capture(), err=%d\n", __func__,rc);
    675         return rc;
    676     }
    677     while (num_rcvd_snapshot < num_snapshot) {
    678         CDBG_HIGH("\nWaiting mm_camera_app_wait !!\n");
    679         mm_camera_app_wait();
    680         num_rcvd_snapshot++;
    681     }
    682     rc = mm_app_stop_capture(test_obj);
    683     if (rc != MM_CAMERA_OK) {
    684        CDBG_ERROR("%s: mm_app_stop_capture(), err=%d\n",__func__, rc);
    685        return rc;
    686     }
    687     //start preview after capture.
    688     rc = mm_app_start_preview(test_obj);
    689     if (rc != MM_CAMERA_OK) {
    690         CDBG_ERROR("%s: start preview failed after capture!!, err=%d\n",__func__,rc);
    691     }
    692     return rc;
    693 }
    694