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