Home | History | Annotate | Download | only in src
      1 /*
      2 Copyright (c) 2012-2014, 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 "mm_qcamera_dbg.h"
     31 #include "mm_qcamera_app.h"
     32 #include <assert.h>
     33 #include <sys/mman.h>
     34 #include <semaphore.h>
     35 
     36 static void mm_app_metadata_notify_cb(mm_camera_super_buf_t *bufs,
     37                                      void *user_data)
     38 {
     39   int i = 0;
     40   mm_camera_channel_t *channel = NULL;
     41   mm_camera_stream_t *p_stream = NULL;
     42   mm_camera_test_obj_t *pme = (mm_camera_test_obj_t *)user_data;
     43   mm_camera_buf_def_t *frame = bufs->bufs[0];
     44   metadata_buffer_t *pMetadata;
     45   cam_auto_focus_data_t *focus_data;
     46 
     47   if (NULL == bufs || NULL == user_data) {
     48       CDBG_ERROR("%s: bufs or user_data are not valid ", __func__);
     49       return;
     50   }
     51 
     52   /* find channel */
     53   for (i = 0; i < MM_CHANNEL_TYPE_MAX; i++) {
     54       if (pme->channels[i].ch_id == bufs->ch_id) {
     55           channel = &pme->channels[i];
     56           break;
     57       }
     58   }
     59   /* find preview stream */
     60   for (i = 0; i < channel->num_streams; i++) {
     61       if (channel->streams[i].s_config.stream_info->stream_type == CAM_STREAM_TYPE_METADATA) {
     62           p_stream = &channel->streams[i];
     63           break;
     64       }
     65   }
     66   /* find preview frame */
     67   for (i = 0; i < bufs->num_bufs; i++) {
     68       if (bufs->bufs[i]->stream_id == p_stream->s_id) {
     69           frame = bufs->bufs[i];
     70           break;
     71       }
     72   }
     73 
     74   if (NULL == p_stream) {
     75       CDBG_ERROR("%s: cannot find metadata stream", __func__);
     76       return;
     77   }
     78   if (pme->metadata == NULL) {
     79     /* The app will free the meta data, we don't need to bother here */
     80     pme->metadata = malloc(sizeof(metadata_buffer_t));
     81     if (NULL == pme->metadata) {
     82         CDBG_ERROR("%s: Canot allocate metadata memory\n", __func__);
     83         return;
     84     }
     85   }
     86   memcpy(pme->metadata, frame->buffer, sizeof(metadata_buffer_t));
     87 
     88   pMetadata = (metadata_buffer_t *)frame->buffer;
     89   if (IS_META_AVAILABLE(CAM_INTF_META_AUTOFOCUS_DATA, pMetadata)) {
     90     focus_data = (cam_auto_focus_data_t *)
     91       POINTER_OF_META(CAM_INTF_META_AUTOFOCUS_DATA, pMetadata);
     92     if (focus_data->focus_state == CAM_AF_FOCUSED ||
     93       focus_data->focus_state == CAM_AF_NOT_FOCUSED) {
     94       CDBG_ERROR("%s: AutoFocus Done Call Back Received\n",__func__);
     95       mm_camera_app_done();
     96     } else if (focus_data->focus_state == CAM_AF_NOT_FOCUSED) {
     97       CDBG_ERROR("%s: AutoFocus failed\n",__func__);
     98       mm_camera_app_done();
     99     }
    100   }
    101 
    102   if (MM_CAMERA_OK != pme->cam->ops->qbuf(bufs->camera_handle,
    103                                           bufs->ch_id,
    104                                           frame)) {
    105       CDBG_ERROR("%s: Failed in Preview Qbuf\n", __func__);
    106   }
    107   mm_app_cache_ops((mm_camera_app_meminfo_t *)frame->mem_info,
    108                    ION_IOC_INV_CACHES);
    109 }
    110 
    111 static void mm_app_preview_notify_cb(mm_camera_super_buf_t *bufs,
    112                                      void *user_data)
    113 {
    114     int i = 0;
    115     mm_camera_channel_t *channel = NULL;
    116     mm_camera_stream_t *p_stream = NULL;
    117     mm_camera_buf_def_t *frame = bufs->bufs[0];
    118     mm_camera_test_obj_t *pme = (mm_camera_test_obj_t *)user_data;
    119 
    120     CDBG_ERROR("%s: BEGIN - length=%d, frame idx = %d\n",
    121          __func__, frame->frame_len, frame->frame_idx);
    122 
    123     if (NULL == bufs || NULL == user_data) {
    124         CDBG_ERROR("%s: bufs or user_data are not valid ", __func__);
    125         return;
    126     }
    127 
    128     /* find channel */
    129     for (i = 0; i < MM_CHANNEL_TYPE_MAX; i++) {
    130         if (pme->channels[i].ch_id == bufs->ch_id) {
    131             channel = &pme->channels[i];
    132             break;
    133         }
    134     }
    135     /* find preview stream */
    136     for (i = 0; i < channel->num_streams; i++) {
    137         if (channel->streams[i].s_config.stream_info->stream_type == CAM_STREAM_TYPE_PREVIEW) {
    138             p_stream = &channel->streams[i];
    139             break;
    140         }
    141     }
    142     /* find preview frame */
    143     for (i = 0; i < bufs->num_bufs; i++) {
    144         if (bufs->bufs[i]->stream_id == p_stream->s_id) {
    145             frame = bufs->bufs[i];
    146             break;
    147         }
    148     }
    149 
    150     if (NULL == p_stream) {
    151         CDBG_ERROR("%s: cannot find preview stream", __func__);
    152         return;
    153     }
    154 
    155     if ( 0 < pme->fb_fd ) {
    156         mm_app_overlay_display(pme, frame->fd);
    157     }
    158 #ifdef DUMP_PRV_IN_FILE
    159     {
    160       char file_name[64];
    161       snprintf(file_name, sizeof(file_name), "P_C%d", pme->cam->camera_handle);
    162       mm_app_dump_frame(frame, file_name, "yuv", frame->frame_idx);
    163     }
    164 #endif
    165     if (pme->user_preview_cb) {
    166         CDBG_ERROR("[DBG] %s, user defined own preview cb. calling it...", __func__);
    167         pme->user_preview_cb(frame);
    168     }
    169     if (MM_CAMERA_OK != pme->cam->ops->qbuf(bufs->camera_handle,
    170                                             bufs->ch_id,
    171                                             frame)) {
    172         CDBG_ERROR("%s: Failed in Preview Qbuf\n", __func__);
    173     }
    174     mm_app_cache_ops((mm_camera_app_meminfo_t *)frame->mem_info,
    175                      ION_IOC_INV_CACHES);
    176 
    177     CDBG("%s: END\n", __func__);
    178 }
    179 
    180 static void mm_app_zsl_notify_cb(mm_camera_super_buf_t *bufs,
    181                                  void *user_data)
    182 {
    183     int rc = 0;
    184     int i = 0;
    185     mm_camera_test_obj_t *pme = (mm_camera_test_obj_t *)user_data;
    186     mm_camera_channel_t *channel = NULL;
    187     mm_camera_stream_t *p_stream = NULL;
    188     mm_camera_stream_t *m_stream = NULL;
    189     mm_camera_stream_t *md_stream = NULL;
    190     mm_camera_buf_def_t *p_frame = NULL;
    191     mm_camera_buf_def_t *m_frame = NULL;
    192     mm_camera_buf_def_t *md_frame = NULL;
    193 
    194     CDBG("%s: BEGIN\n", __func__);
    195 
    196     if (NULL == bufs || NULL == user_data) {
    197         CDBG_ERROR("%s: bufs or user_data are not valid ", __func__);
    198         return;
    199     }
    200 
    201     /* find channel */
    202     for (i = 0; i < MM_CHANNEL_TYPE_MAX; i++) {
    203         if (pme->channels[i].ch_id == bufs->ch_id) {
    204             channel = &pme->channels[i];
    205             break;
    206         }
    207     }
    208     if (NULL == channel) {
    209         CDBG_ERROR("%s: Wrong channel id (%d)", __func__, bufs->ch_id);
    210         return;
    211     }
    212 
    213     /* find preview stream */
    214     for (i = 0; i < channel->num_streams; i++) {
    215         if (channel->streams[i].s_config.stream_info->stream_type == CAM_STREAM_TYPE_PREVIEW) {
    216             p_stream = &channel->streams[i];
    217             break;
    218         }
    219     }
    220     if (NULL == p_stream) {
    221         CDBG_ERROR("%s: cannot find preview stream", __func__);
    222         return;
    223     }
    224 
    225     /* find snapshot stream */
    226     for (i = 0; i < channel->num_streams; i++) {
    227         if (channel->streams[i].s_config.stream_info->stream_type == CAM_STREAM_TYPE_SNAPSHOT) {
    228             m_stream = &channel->streams[i];
    229             break;
    230         }
    231     }
    232     if (NULL == m_stream) {
    233         CDBG_ERROR("%s: cannot find snapshot stream", __func__);
    234         return;
    235     }
    236 
    237     /* find metadata stream */
    238     for (i = 0; i < channel->num_streams; i++) {
    239         if (channel->streams[i].s_config.stream_info->stream_type == CAM_STREAM_TYPE_METADATA) {
    240             md_stream = &channel->streams[i];
    241             break;
    242         }
    243     }
    244     if (NULL == md_stream) {
    245         CDBG_ERROR("%s: cannot find metadata stream", __func__);
    246     }
    247 
    248     /* find preview frame */
    249     for (i = 0; i < bufs->num_bufs; i++) {
    250         if (bufs->bufs[i]->stream_id == p_stream->s_id) {
    251             p_frame = bufs->bufs[i];
    252             break;
    253         }
    254     }
    255 
    256     if(md_stream) {
    257       /* find metadata frame */
    258       for (i = 0; i < bufs->num_bufs; i++) {
    259           if (bufs->bufs[i]->stream_id == md_stream->s_id) {
    260               md_frame = bufs->bufs[i];
    261               break;
    262           }
    263       }
    264       if (!pme->metadata) {
    265           /* App will free the metadata */
    266           pme->metadata = malloc(sizeof(metadata_buffer_t));
    267       }
    268       memcpy(pme->metadata , md_frame->buffer, sizeof(metadata_buffer_t));
    269     }
    270     /* find snapshot frame */
    271     for (i = 0; i < bufs->num_bufs; i++) {
    272         if (bufs->bufs[i]->stream_id == m_stream->s_id) {
    273             m_frame = bufs->bufs[i];
    274             break;
    275         }
    276     }
    277 
    278     if (!m_frame || !p_frame) {
    279         CDBG_ERROR("%s: cannot find preview/snapshot frame", __func__);
    280         return;
    281     }
    282 
    283     CDBG("%s: ZSL CB with fb_fd = %d, m_frame = 0x%x, p_frame = 0x%x \n",
    284          __func__,
    285          pme->fb_fd,
    286          (uint32_t )m_frame,
    287          (uint32_t )p_frame);
    288 
    289     if ( 0 < pme->fb_fd ) {
    290         mm_app_overlay_display(pme, p_frame->fd);
    291     }/* else {
    292         mm_app_dump_frame(p_frame, "zsl_preview", "yuv", p_frame->frame_idx);
    293         mm_app_dump_frame(m_frame, "zsl_main", "yuv", m_frame->frame_idx);
    294     }*/
    295 
    296     if ( pme->enable_reproc && ( NULL != pme->reproc_stream ) ) {
    297         rc = mm_app_do_reprocess(pme,
    298                                  m_frame,
    299                                  md_frame->buf_idx,
    300                                  bufs,
    301                                  md_stream);
    302         if (MM_CAMERA_OK != rc ) {
    303             CDBG_ERROR("%s: reprocess failed rc = %d", __func__, rc);
    304         }
    305 
    306         return;
    307     }
    308 
    309     if ( pme->encodeJpeg ) {
    310         pme->jpeg_buf.buf.buffer = (uint8_t *)malloc(m_frame->frame_len);
    311         if ( NULL == pme->jpeg_buf.buf.buffer ) {
    312             CDBG_ERROR("%s: error allocating jpeg output buffer", __func__);
    313             goto exit;
    314         }
    315 
    316         pme->jpeg_buf.buf.frame_len = m_frame->frame_len;
    317         /* create a new jpeg encoding session */
    318         rc = createEncodingSession(pme, m_stream, m_frame);
    319         if (0 != rc) {
    320             CDBG_ERROR("%s: error creating jpeg session", __func__);
    321             free(pme->jpeg_buf.buf.buffer);
    322             goto exit;
    323         }
    324 
    325         /* start jpeg encoding job */
    326         rc = encodeData(pme, bufs, m_stream);
    327         pme->encodeJpeg = 0;
    328     } else {
    329         if (MM_CAMERA_OK != pme->cam->ops->qbuf(bufs->camera_handle,
    330                                                 bufs->ch_id,
    331                                                 m_frame)) {
    332             CDBG_ERROR("%s: Failed in main Qbuf\n", __func__);
    333         }
    334         mm_app_cache_ops((mm_camera_app_meminfo_t *)m_frame->mem_info,
    335                          ION_IOC_INV_CACHES);
    336     }
    337 
    338 exit:
    339 
    340     if (MM_CAMERA_OK != pme->cam->ops->qbuf(bufs->camera_handle,
    341                                             bufs->ch_id,
    342                                             p_frame)) {
    343         CDBG_ERROR("%s: Failed in preview Qbuf\n", __func__);
    344     }
    345     mm_app_cache_ops((mm_camera_app_meminfo_t *)p_frame->mem_info,
    346                      ION_IOC_INV_CACHES);
    347 
    348     if(md_frame) {
    349       if (MM_CAMERA_OK != pme->cam->ops->qbuf(bufs->camera_handle,
    350                                               bufs->ch_id,
    351                                               md_frame)) {
    352           CDBG_ERROR("%s: Failed in metadata Qbuf\n", __func__);
    353       }
    354       mm_app_cache_ops((mm_camera_app_meminfo_t *)md_frame->mem_info,
    355                        ION_IOC_INV_CACHES);
    356     }
    357 
    358     CDBG("%s: END\n", __func__);
    359 }
    360 
    361 mm_camera_stream_t * mm_app_add_metadata_stream(mm_camera_test_obj_t *test_obj,
    362                                                mm_camera_channel_t *channel,
    363                                                mm_camera_buf_notify_t stream_cb,
    364                                                void *userdata,
    365                                                uint8_t num_bufs)
    366 {
    367     int rc = MM_CAMERA_OK;
    368     mm_camera_stream_t *stream = NULL;
    369     cam_capability_t *cam_cap = (cam_capability_t *)(test_obj->cap_buf.buf.buffer);
    370 
    371     stream = mm_app_add_stream(test_obj, channel);
    372     if (NULL == stream) {
    373         CDBG_ERROR("%s: add stream failed\n", __func__);
    374         return NULL;
    375     }
    376 
    377     stream->s_config.mem_vtbl.get_bufs = mm_app_stream_initbuf;
    378     stream->s_config.mem_vtbl.put_bufs = mm_app_stream_deinitbuf;
    379     stream->s_config.mem_vtbl.clean_invalidate_buf =
    380       mm_app_stream_clean_invalidate_buf;
    381     stream->s_config.mem_vtbl.invalidate_buf = mm_app_stream_invalidate_buf;
    382     stream->s_config.mem_vtbl.user_data = (void *)stream;
    383     stream->s_config.stream_cb = stream_cb;
    384     stream->s_config.userdata = userdata;
    385     stream->num_of_bufs = num_bufs;
    386 
    387     stream->s_config.stream_info = (cam_stream_info_t *)stream->s_info_buf.buf.buffer;
    388     memset(stream->s_config.stream_info, 0, sizeof(cam_stream_info_t));
    389     stream->s_config.stream_info->stream_type = CAM_STREAM_TYPE_METADATA;
    390     stream->s_config.stream_info->streaming_mode = CAM_STREAMING_MODE_CONTINUOUS;
    391     stream->s_config.stream_info->fmt = DEFAULT_PREVIEW_FORMAT;
    392     stream->s_config.stream_info->dim.width = sizeof(metadata_buffer_t);
    393     stream->s_config.stream_info->dim.height = 1;
    394     stream->s_config.padding_info = cam_cap->padding_info;
    395 
    396     rc = mm_app_config_stream(test_obj, channel, stream, &stream->s_config);
    397     if (MM_CAMERA_OK != rc) {
    398         CDBG_ERROR("%s:config preview stream err=%d\n", __func__, rc);
    399         return NULL;
    400     }
    401 
    402     return stream;
    403 }
    404 
    405 mm_camera_stream_t * mm_app_add_preview_stream(mm_camera_test_obj_t *test_obj,
    406                                                mm_camera_channel_t *channel,
    407                                                mm_camera_buf_notify_t stream_cb,
    408                                                void *userdata,
    409                                                uint8_t num_bufs)
    410 {
    411     int rc = MM_CAMERA_OK;
    412     mm_camera_stream_t *stream = NULL;
    413     cam_capability_t *cam_cap = (cam_capability_t *)(test_obj->cap_buf.buf.buffer);
    414 
    415     stream = mm_app_add_stream(test_obj, channel);
    416     if (NULL == stream) {
    417         CDBG_ERROR("%s: add stream failed\n", __func__);
    418         return NULL;
    419     }
    420     stream->s_config.mem_vtbl.get_bufs = mm_app_stream_initbuf;
    421     stream->s_config.mem_vtbl.put_bufs = mm_app_stream_deinitbuf;
    422     stream->s_config.mem_vtbl.clean_invalidate_buf =
    423       mm_app_stream_clean_invalidate_buf;
    424     stream->s_config.mem_vtbl.invalidate_buf = mm_app_stream_invalidate_buf;
    425     stream->s_config.mem_vtbl.user_data = (void *)stream;
    426     stream->s_config.stream_cb = stream_cb;
    427     stream->s_config.userdata = userdata;
    428     stream->num_of_bufs = num_bufs;
    429 
    430     stream->s_config.stream_info = (cam_stream_info_t *)stream->s_info_buf.buf.buffer;
    431     memset(stream->s_config.stream_info, 0, sizeof(cam_stream_info_t));
    432     stream->s_config.stream_info->stream_type = CAM_STREAM_TYPE_PREVIEW;
    433     stream->s_config.stream_info->streaming_mode = CAM_STREAMING_MODE_CONTINUOUS;
    434     stream->s_config.stream_info->fmt = DEFAULT_PREVIEW_FORMAT;
    435 
    436     if ((test_obj->preview_resolution.user_input_display_width == 0) ||
    437            ( test_obj->preview_resolution.user_input_display_height == 0)) {
    438         stream->s_config.stream_info->dim.width = DEFAULT_PREVIEW_WIDTH;
    439         stream->s_config.stream_info->dim.height = DEFAULT_PREVIEW_HEIGHT;
    440     } else {
    441         stream->s_config.stream_info->dim.width = test_obj->preview_resolution.user_input_display_width;
    442         stream->s_config.stream_info->dim.height = test_obj->preview_resolution.user_input_display_height;
    443     }
    444 
    445     stream->s_config.padding_info = cam_cap->padding_info;
    446 
    447     rc = mm_app_config_stream(test_obj, channel, stream, &stream->s_config);
    448     if (MM_CAMERA_OK != rc) {
    449         CDBG_ERROR("%s:config preview stream err=%d\n", __func__, rc);
    450         return NULL;
    451     }
    452 
    453     return stream;
    454 }
    455 
    456 mm_camera_stream_t * mm_app_add_raw_stream(mm_camera_test_obj_t *test_obj,
    457                                                 mm_camera_channel_t *channel,
    458                                                 mm_camera_buf_notify_t stream_cb,
    459                                                 void *userdata,
    460                                                 uint8_t num_bufs,
    461                                                 uint8_t num_burst)
    462 {
    463     int rc = MM_CAMERA_OK;
    464     mm_camera_stream_t *stream = NULL;
    465     cam_capability_t *cam_cap = (cam_capability_t *)(test_obj->cap_buf.buf.buffer);
    466 
    467     stream = mm_app_add_stream(test_obj, channel);
    468     if (NULL == stream) {
    469         CDBG_ERROR("%s: add stream failed\n", __func__);
    470         return NULL;
    471     }
    472 
    473     stream->s_config.mem_vtbl.get_bufs = mm_app_stream_initbuf;
    474     stream->s_config.mem_vtbl.put_bufs = mm_app_stream_deinitbuf;
    475     stream->s_config.mem_vtbl.invalidate_buf = mm_app_stream_invalidate_buf;
    476     stream->s_config.mem_vtbl.user_data = (void *)stream;
    477     stream->s_config.stream_cb = stream_cb;
    478     stream->s_config.userdata = userdata;
    479     stream->num_of_bufs = num_bufs;
    480 
    481     stream->s_config.stream_info = (cam_stream_info_t *)stream->s_info_buf.buf.buffer;
    482     memset(stream->s_config.stream_info, 0, sizeof(cam_stream_info_t));
    483     stream->s_config.stream_info->stream_type = CAM_STREAM_TYPE_RAW;
    484     if (num_burst == 0) {
    485         stream->s_config.stream_info->streaming_mode = CAM_STREAMING_MODE_CONTINUOUS;
    486     } else {
    487         stream->s_config.stream_info->streaming_mode = CAM_STREAMING_MODE_BURST;
    488         stream->s_config.stream_info->num_of_burst = num_burst;
    489     }
    490     stream->s_config.stream_info->fmt = test_obj->buffer_format;
    491     if ( test_obj->buffer_width == 0 || test_obj->buffer_height == 0 ) {
    492         stream->s_config.stream_info->dim.width = DEFAULT_SNAPSHOT_WIDTH;
    493         stream->s_config.stream_info->dim.height = DEFAULT_SNAPSHOT_HEIGHT;
    494     } else {
    495         stream->s_config.stream_info->dim.width = test_obj->buffer_width;
    496         stream->s_config.stream_info->dim.height = test_obj->buffer_height;
    497     }
    498     stream->s_config.padding_info = cam_cap->padding_info;
    499 
    500     rc = mm_app_config_stream(test_obj, channel, stream, &stream->s_config);
    501     if (MM_CAMERA_OK != rc) {
    502         CDBG_ERROR("%s:config preview stream err=%d\n", __func__, rc);
    503         return NULL;
    504     }
    505 
    506     return stream;
    507 }
    508 
    509 mm_camera_stream_t * mm_app_add_snapshot_stream(mm_camera_test_obj_t *test_obj,
    510                                                 mm_camera_channel_t *channel,
    511                                                 mm_camera_buf_notify_t stream_cb,
    512                                                 void *userdata,
    513                                                 uint8_t num_bufs,
    514                                                 uint8_t num_burst)
    515 {
    516     int rc = MM_CAMERA_OK;
    517     mm_camera_stream_t *stream = NULL;
    518     cam_capability_t *cam_cap = (cam_capability_t *)(test_obj->cap_buf.buf.buffer);
    519 
    520     stream = mm_app_add_stream(test_obj, channel);
    521     if (NULL == stream) {
    522         CDBG_ERROR("%s: add stream failed\n", __func__);
    523         return NULL;
    524     }
    525 
    526     stream->s_config.mem_vtbl.get_bufs = mm_app_stream_initbuf;
    527     stream->s_config.mem_vtbl.put_bufs = mm_app_stream_deinitbuf;
    528     stream->s_config.mem_vtbl.clean_invalidate_buf =
    529       mm_app_stream_clean_invalidate_buf;
    530     stream->s_config.mem_vtbl.invalidate_buf = mm_app_stream_invalidate_buf;
    531     stream->s_config.mem_vtbl.user_data = (void *)stream;
    532     stream->s_config.stream_cb = stream_cb;
    533     stream->s_config.userdata = userdata;
    534     stream->num_of_bufs = num_bufs;
    535 
    536     stream->s_config.stream_info = (cam_stream_info_t *)stream->s_info_buf.buf.buffer;
    537     memset(stream->s_config.stream_info, 0, sizeof(cam_stream_info_t));
    538     stream->s_config.stream_info->stream_type = CAM_STREAM_TYPE_SNAPSHOT;
    539     if (num_burst == 0) {
    540         stream->s_config.stream_info->streaming_mode = CAM_STREAMING_MODE_CONTINUOUS;
    541     } else {
    542         stream->s_config.stream_info->streaming_mode = CAM_STREAMING_MODE_BURST;
    543         stream->s_config.stream_info->num_of_burst = num_burst;
    544     }
    545     stream->s_config.stream_info->fmt = DEFAULT_SNAPSHOT_FORMAT;
    546     if ( test_obj->buffer_width == 0 || test_obj->buffer_height == 0 ) {
    547         stream->s_config.stream_info->dim.width = DEFAULT_SNAPSHOT_WIDTH;
    548         stream->s_config.stream_info->dim.height = DEFAULT_SNAPSHOT_HEIGHT;
    549     } else {
    550         stream->s_config.stream_info->dim.width = test_obj->buffer_width;
    551         stream->s_config.stream_info->dim.height = test_obj->buffer_height;
    552     }
    553     stream->s_config.padding_info = cam_cap->padding_info;
    554 
    555     rc = mm_app_config_stream(test_obj, channel, stream, &stream->s_config);
    556     if (MM_CAMERA_OK != rc) {
    557         CDBG_ERROR("%s:config preview stream err=%d\n", __func__, rc);
    558         return NULL;
    559     }
    560 
    561     return stream;
    562 }
    563 
    564 mm_camera_channel_t * mm_app_add_preview_channel(mm_camera_test_obj_t *test_obj)
    565 {
    566     mm_camera_channel_t *channel = NULL;
    567     mm_camera_stream_t *stream = NULL;
    568 
    569     channel = mm_app_add_channel(test_obj,
    570                                  MM_CHANNEL_TYPE_PREVIEW,
    571                                  NULL,
    572                                  NULL,
    573                                  NULL);
    574     if (NULL == channel) {
    575         CDBG_ERROR("%s: add channel failed", __func__);
    576         return NULL;
    577     }
    578 
    579     stream = mm_app_add_preview_stream(test_obj,
    580                                        channel,
    581                                        mm_app_preview_notify_cb,
    582                                        (void *)test_obj,
    583                                        PREVIEW_BUF_NUM);
    584     if (NULL == stream) {
    585         CDBG_ERROR("%s: add stream failed\n", __func__);
    586         mm_app_del_channel(test_obj, channel);
    587         return NULL;
    588     }
    589 
    590     return channel;
    591 }
    592 
    593 int mm_app_stop_and_del_channel(mm_camera_test_obj_t *test_obj,
    594                                 mm_camera_channel_t *channel)
    595 {
    596     int rc = MM_CAMERA_OK;
    597     mm_camera_stream_t *stream = NULL;
    598     uint8_t i;
    599 
    600     rc = mm_app_stop_channel(test_obj, channel);
    601     if (MM_CAMERA_OK != rc) {
    602         CDBG_ERROR("%s:Stop Preview failed rc=%d\n", __func__, rc);
    603     }
    604 
    605     if (channel->num_streams <= MAX_STREAM_NUM_IN_BUNDLE) {
    606         for (i = 0; i < channel->num_streams; i++) {
    607             stream = &channel->streams[i];
    608             rc = mm_app_del_stream(test_obj, channel, stream);
    609             if (MM_CAMERA_OK != rc) {
    610                 CDBG_ERROR("%s:del stream(%d) failed rc=%d\n", __func__, i, rc);
    611             }
    612         }
    613     } else {
    614         CDBG_ERROR("%s: num_streams = %d. Should not be more than %d\n",
    615             __func__, channel->num_streams, MAX_STREAM_NUM_IN_BUNDLE);
    616     }
    617     rc = mm_app_del_channel(test_obj, channel);
    618     if (MM_CAMERA_OK != rc) {
    619         CDBG_ERROR("%s:delete channel failed rc=%d\n", __func__, rc);
    620     }
    621 
    622     return rc;
    623 }
    624 
    625 int mm_app_start_preview(mm_camera_test_obj_t *test_obj)
    626 {
    627     int rc = MM_CAMERA_OK;
    628     mm_camera_channel_t *channel = NULL;
    629     mm_camera_stream_t *stream = NULL;
    630     mm_camera_stream_t *s_metadata = NULL;
    631     uint8_t i;
    632 
    633     channel =  mm_app_add_preview_channel(test_obj);
    634     if (NULL == channel) {
    635         CDBG_ERROR("%s: add channel failed", __func__);
    636         return -MM_CAMERA_E_GENERAL;
    637     }
    638 
    639     s_metadata = mm_app_add_metadata_stream(test_obj,
    640                                             channel,
    641                                             mm_app_metadata_notify_cb,
    642                                             (void *)test_obj,
    643                                             PREVIEW_BUF_NUM);
    644     if (NULL == s_metadata) {
    645         CDBG_ERROR("%s: add metadata stream failed\n", __func__);
    646         mm_app_del_channel(test_obj, channel);
    647         return rc;
    648     }
    649 
    650     rc = mm_app_start_channel(test_obj, channel);
    651     if (MM_CAMERA_OK != rc) {
    652         CDBG_ERROR("%s:start preview failed rc=%d\n", __func__, rc);
    653         if (channel->num_streams <= MAX_STREAM_NUM_IN_BUNDLE) {
    654             for (i = 0; i < channel->num_streams; i++) {
    655                 stream = &channel->streams[i];
    656                 mm_app_del_stream(test_obj, channel, stream);
    657             }
    658         }
    659         mm_app_del_channel(test_obj, channel);
    660         return rc;
    661     }
    662 
    663     return rc;
    664 }
    665 
    666 int mm_app_stop_preview(mm_camera_test_obj_t *test_obj)
    667 {
    668     int rc = MM_CAMERA_OK;
    669 
    670     mm_camera_channel_t *channel =
    671         mm_app_get_channel_by_type(test_obj, MM_CHANNEL_TYPE_PREVIEW);
    672 
    673     rc = mm_app_stop_and_del_channel(test_obj, channel);
    674     if (MM_CAMERA_OK != rc) {
    675         CDBG_ERROR("%s:Stop Preview failed rc=%d\n", __func__, rc);
    676     }
    677 
    678     return rc;
    679 }
    680 
    681 int mm_app_start_preview_zsl(mm_camera_test_obj_t *test_obj)
    682 {
    683     int32_t rc = MM_CAMERA_OK;
    684     mm_camera_channel_t *channel = NULL;
    685     mm_camera_stream_t *s_preview = NULL;
    686     mm_camera_stream_t *s_metadata = NULL;
    687     mm_camera_stream_t *s_main = NULL;
    688     mm_camera_channel_attr_t attr;
    689 
    690     memset(&attr, 0, sizeof(mm_camera_channel_attr_t));
    691     attr.notify_mode = MM_CAMERA_SUPER_BUF_NOTIFY_CONTINUOUS;
    692     attr.look_back = 2;
    693     attr.post_frame_skip = 0;
    694     attr.water_mark = 2;
    695     attr.max_unmatched_frames = 3;
    696     channel = mm_app_add_channel(test_obj,
    697                                  MM_CHANNEL_TYPE_ZSL,
    698                                  &attr,
    699                                  mm_app_zsl_notify_cb,
    700                                  test_obj);
    701     if (NULL == channel) {
    702         CDBG_ERROR("%s: add channel failed", __func__);
    703         return -MM_CAMERA_E_GENERAL;
    704     }
    705 
    706     s_preview = mm_app_add_preview_stream(test_obj,
    707                                           channel,
    708                                           mm_app_preview_notify_cb,
    709                                           (void *)test_obj,
    710                                           PREVIEW_BUF_NUM);
    711     if (NULL == s_preview) {
    712         CDBG_ERROR("%s: add preview stream failed\n", __func__);
    713         mm_app_del_channel(test_obj, channel);
    714         return rc;
    715     }
    716 
    717     s_metadata = mm_app_add_metadata_stream(test_obj,
    718                                             channel,
    719                                             mm_app_metadata_notify_cb,
    720                                             (void *)test_obj,
    721                                             PREVIEW_BUF_NUM);
    722     if (NULL == s_metadata) {
    723         CDBG_ERROR("%s: add metadata stream failed\n", __func__);
    724         mm_app_del_channel(test_obj, channel);
    725         return rc;
    726     }
    727 
    728     s_main = mm_app_add_snapshot_stream(test_obj,
    729                                         channel,
    730                                         NULL,
    731                                         NULL,
    732                                         PREVIEW_BUF_NUM,
    733                                         0);
    734     if (NULL == s_main) {
    735         CDBG_ERROR("%s: add main snapshot stream failed\n", __func__);
    736         mm_app_del_stream(test_obj, channel, s_preview);
    737         mm_app_del_channel(test_obj, channel);
    738         return rc;
    739     }
    740 
    741     rc = mm_app_start_channel(test_obj, channel);
    742     if (MM_CAMERA_OK != rc) {
    743         CDBG_ERROR("%s:start zsl failed rc=%d\n", __func__, rc);
    744         mm_app_del_stream(test_obj, channel, s_preview);
    745         mm_app_del_stream(test_obj, channel, s_metadata);
    746         mm_app_del_stream(test_obj, channel, s_main);
    747         mm_app_del_channel(test_obj, channel);
    748         return rc;
    749     }
    750 
    751     if ( test_obj->enable_reproc ) {
    752         if ( NULL == mm_app_add_reprocess_channel(test_obj, s_main) ) {
    753             CDBG_ERROR("%s: Reprocess channel failed to initialize \n", __func__);
    754             mm_app_del_stream(test_obj, channel, s_preview);
    755 #ifdef USE_METADATA_STREAM
    756             mm_app_del_stream(test_obj, channel, s_metadata);
    757 #endif
    758             mm_app_del_stream(test_obj, channel, s_main);
    759             mm_app_del_channel(test_obj, channel);
    760             return rc;
    761         }
    762         rc = mm_app_start_reprocess(test_obj);
    763         if (MM_CAMERA_OK != rc) {
    764             CDBG_ERROR("%s: reprocess start failed rc=%d\n", __func__, rc);
    765             mm_app_del_stream(test_obj, channel, s_preview);
    766 #ifdef USE_METADATA_STREAM
    767             mm_app_del_stream(test_obj, channel, s_metadata);
    768 #endif
    769             mm_app_del_stream(test_obj, channel, s_main);
    770             mm_app_del_channel(test_obj, channel);
    771             return rc;
    772         }
    773     }
    774 
    775     return rc;
    776 }
    777 
    778 int mm_app_stop_preview_zsl(mm_camera_test_obj_t *test_obj)
    779 {
    780     int rc = MM_CAMERA_OK;
    781 
    782     mm_camera_channel_t *channel =
    783         mm_app_get_channel_by_type(test_obj, MM_CHANNEL_TYPE_ZSL);
    784 
    785     rc = mm_app_stop_and_del_channel(test_obj, channel);
    786     if (MM_CAMERA_OK != rc) {
    787         CDBG_ERROR("%s:Stop Preview failed rc=%d\n", __func__, rc);
    788     }
    789 
    790     if ( test_obj->enable_reproc ) {
    791         rc |= mm_app_stop_reprocess(test_obj);
    792     }
    793 
    794     return rc;
    795 }
    796 
    797 int mm_app_initialize_fb(mm_camera_test_obj_t *test_obj)
    798 {
    799     int rc = MM_CAMERA_OK;
    800     int brightness_fd;
    801     const char brightness_level[] = BACKLIGHT_LEVEL;
    802     void *fb_base = NULL;
    803 
    804     assert( ( NULL != test_obj ) && ( 0 == test_obj->fb_fd ) );
    805 
    806     test_obj->fb_fd = open(FB_PATH, O_RDWR);
    807     if ( 0 > test_obj->fb_fd ) {
    808         CDBG_ERROR("%s: FB device open failed rc=%d, %s\n",
    809                    __func__,
    810                    -errno,
    811                    strerror(errno));
    812         rc = -errno;
    813         goto FAIL;
    814     }
    815 
    816     rc = ioctl(test_obj->fb_fd, FBIOGET_VSCREENINFO, &test_obj->vinfo);
    817     if ( MM_CAMERA_OK != rc ) {
    818         CDBG_ERROR("%s: Can not retrieve screen info rc=%d, %s\n",
    819                    __func__,
    820                    -errno,
    821                    strerror(errno));
    822         rc = -errno;
    823         goto FAIL;
    824     }
    825 
    826     if ( ( 0 == test_obj->vinfo.yres_virtual ) ||
    827          ( 0 == test_obj->vinfo.yres ) ||
    828          ( test_obj->vinfo.yres > test_obj->vinfo.yres_virtual ) ) {
    829         CDBG_ERROR("%s: Invalid FB virtual yres: %d, yres: %d\n",
    830                    __func__,
    831                    test_obj->vinfo.yres_virtual,
    832                    test_obj->vinfo.yres);
    833         rc = MM_CAMERA_E_GENERAL;
    834         goto FAIL;
    835     }
    836 
    837     if ( ( 0 == test_obj->vinfo.xres_virtual ) ||
    838          ( 0 == test_obj->vinfo.xres ) ||
    839          ( test_obj->vinfo.xres > test_obj->vinfo.xres_virtual ) ) {
    840         CDBG_ERROR("%s: Invalid FB virtual xres: %d, xres: %d\n",
    841                    __func__,
    842                    test_obj->vinfo.xres_virtual,
    843                    test_obj->vinfo.xres);
    844         rc = MM_CAMERA_E_GENERAL;
    845         goto FAIL;
    846     }
    847 
    848     brightness_fd = open(BACKLIGHT_CONTROL, O_RDWR);
    849     if ( brightness_fd >= 0 ) {
    850         write(brightness_fd, brightness_level, strlen(brightness_level));
    851         close(brightness_fd);
    852     }
    853 
    854     test_obj->slice_size = test_obj->vinfo.xres * ( test_obj->vinfo.yres - 1 ) * DEFAULT_OV_FORMAT_BPP;
    855     memset(&test_obj->data_overlay, 0, sizeof(struct mdp_overlay));
    856     test_obj->data_overlay.src.width  = test_obj->buffer_width;
    857     test_obj->data_overlay.src.height = test_obj->buffer_height;
    858     test_obj->data_overlay.src_rect.w = test_obj->buffer_width;
    859     test_obj->data_overlay.src_rect.h = test_obj->buffer_height;
    860     test_obj->data_overlay.dst_rect.w = test_obj->buffer_width;
    861     test_obj->data_overlay.dst_rect.h = test_obj->buffer_height;
    862     test_obj->data_overlay.src.format = DEFAULT_OV_FORMAT;
    863     test_obj->data_overlay.src_rect.x = 0;
    864     test_obj->data_overlay.src_rect.y = 0;
    865     test_obj->data_overlay.dst_rect.x = 0;
    866     test_obj->data_overlay.dst_rect.y = 0;
    867     test_obj->data_overlay.z_order = 2;
    868     test_obj->data_overlay.alpha = 0x80;
    869     test_obj->data_overlay.transp_mask = 0xffe0;
    870     test_obj->data_overlay.flags = MDP_FLIP_LR | MDP_FLIP_UD;
    871 
    872     // Map and clear FB portion
    873     fb_base = mmap(0,
    874                    test_obj->slice_size,
    875                    PROT_WRITE,
    876                    MAP_SHARED,
    877                    test_obj->fb_fd,
    878                    0);
    879     if ( MAP_FAILED  == fb_base ) {
    880             CDBG_ERROR("%s: ( Error while memory mapping frame buffer %s",
    881                        __func__,
    882                        strerror(errno));
    883             rc = -errno;
    884             goto FAIL;
    885     }
    886 
    887     memset(fb_base, 0, test_obj->slice_size);
    888 
    889     if (ioctl(test_obj->fb_fd, FBIOPAN_DISPLAY, &test_obj->vinfo) < 0) {
    890         CDBG_ERROR("%s : FBIOPAN_DISPLAY failed!", __func__);
    891         rc = -errno;
    892         goto FAIL;
    893     }
    894 
    895     munmap(fb_base, test_obj->slice_size);
    896     test_obj->data_overlay.id = MSMFB_NEW_REQUEST;
    897     rc = ioctl(test_obj->fb_fd, MSMFB_OVERLAY_SET, &test_obj->data_overlay);
    898     if (rc < 0) {
    899         CDBG_ERROR("%s : MSMFB_OVERLAY_SET failed! err=%d\n",
    900                    __func__,
    901                    test_obj->data_overlay.id);
    902         return MM_CAMERA_E_GENERAL;
    903     }
    904     CDBG_ERROR("%s: Overlay set with overlay id: %d", __func__, test_obj->data_overlay.id);
    905 
    906     return rc;
    907 
    908 FAIL:
    909 
    910     if ( 0 < test_obj->fb_fd ) {
    911         close(test_obj->fb_fd);
    912     }
    913 
    914     return rc;
    915 }
    916 
    917 int mm_app_close_fb(mm_camera_test_obj_t *test_obj)
    918 {
    919     int rc = MM_CAMERA_OK;
    920 
    921     assert( ( NULL != test_obj ) && ( 0 < test_obj->fb_fd ) );
    922 
    923     if (ioctl(test_obj->fb_fd, MSMFB_OVERLAY_UNSET, &test_obj->data_overlay.id)) {
    924         CDBG_ERROR("\nERROR! MSMFB_OVERLAY_UNSET failed! (Line %d)\n", __LINE__);
    925     }
    926 
    927     if (ioctl(test_obj->fb_fd, FBIOPAN_DISPLAY, &test_obj->vinfo) < 0) {
    928         CDBG_ERROR("ERROR: FBIOPAN_DISPLAY failed! line=%d\n", __LINE__);
    929     }
    930 
    931     close(test_obj->fb_fd);
    932     test_obj->fb_fd = 0;
    933 
    934     return rc;
    935 }
    936 
    937 void memset16(void *pDst, uint16_t value, int count)
    938 {
    939     uint16_t *ptr = pDst;
    940     while (count--)
    941         *ptr++ = value;
    942 }
    943 
    944 int mm_app_overlay_display(mm_camera_test_obj_t *test_obj, int bufferFd)
    945 {
    946     int rc = MM_CAMERA_OK;
    947     struct msmfb_overlay_data ovdata;
    948 
    949 
    950     memset(&ovdata, 0, sizeof(struct msmfb_overlay_data));
    951     ovdata.id = test_obj->data_overlay.id;
    952     ovdata.data.memory_id = bufferFd;
    953 
    954     if (ioctl(test_obj->fb_fd, MSMFB_OVERLAY_PLAY, &ovdata)) {
    955         CDBG_ERROR("%s : MSMFB_OVERLAY_PLAY failed!", __func__);
    956         return MM_CAMERA_E_GENERAL;
    957     }
    958 
    959     if (ioctl(test_obj->fb_fd, FBIOPAN_DISPLAY, &test_obj->vinfo) < 0) {
    960         CDBG_ERROR("%s : FBIOPAN_DISPLAY failed!", __func__);
    961         return MM_CAMERA_E_GENERAL;
    962     }
    963 
    964     return rc;
    965 }
    966