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