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 
     33 static uint32_t rdi_len = 0;
     34 
     35 static void mm_app_rdi_dump_frame(mm_camera_buf_def_t *frame,
     36                                   char *name,
     37                                   char *ext,
     38                                   uint32_t frame_idx)
     39 {
     40     char file_name[FILENAME_MAX];
     41     int file_fd;
     42     int i;
     43 
     44     if (frame != NULL) {
     45         snprintf(file_name, sizeof(file_name),
     46             QCAMERA_DUMP_FRM_LOCATION"%s_%03u.%s", name, frame_idx, ext);
     47         file_fd = open(file_name, O_RDWR | O_CREAT, 0777);
     48         if (file_fd < 0) {
     49             CDBG_ERROR("%s: cannot open file %s \n", __func__, file_name);
     50         } else {
     51             for (i = 0; i < frame->planes_buf.num_planes; i++) {
     52                 write(file_fd,
     53                       (uint8_t *)frame->buffer + frame->planes_buf.planes[i].data_offset,
     54                       rdi_len);
     55             }
     56 
     57             close(file_fd);
     58             CDBG("%s: dump rdi frame %s", __func__,file_name);
     59         }
     60     }
     61 }
     62 
     63 static void mm_app_rdi_notify_cb(mm_camera_super_buf_t *bufs,
     64                                  void *user_data)
     65 {
     66     char file_name[FILENAME_MAX];
     67     mm_camera_buf_def_t *frame = bufs->bufs[0];
     68     mm_camera_test_obj_t *pme = (mm_camera_test_obj_t *)user_data;
     69 
     70     CDBG("%s: BEGIN - length=%zu, frame idx = %d stream_id=%d\n",
     71          __func__, frame->frame_len, frame->frame_idx, frame->stream_id);
     72     snprintf(file_name, sizeof(file_name), "RDI_dump_%d", pme->cam->camera_handle);
     73     mm_app_rdi_dump_frame(frame, file_name, "raw", frame->frame_idx);
     74 
     75     if (MM_CAMERA_OK != pme->cam->ops->qbuf(bufs->camera_handle,
     76                                             bufs->ch_id,
     77                                             frame)) {
     78         CDBG_ERROR("%s: Failed in RDI Qbuf\n", __func__);
     79     }
     80     mm_app_cache_ops((mm_camera_app_meminfo_t *)frame->mem_info,
     81                      ION_IOC_INV_CACHES);
     82 
     83     CDBG("%s: END\n", __func__);
     84 }
     85 
     86 mm_camera_stream_t * mm_app_add_rdi_stream(mm_camera_test_obj_t *test_obj,
     87                                                mm_camera_channel_t *channel,
     88                                                mm_camera_buf_notify_t stream_cb,
     89                                                void *userdata,
     90                                                uint8_t num_bufs,
     91                                                uint8_t num_burst)
     92 {
     93     int rc = MM_CAMERA_OK;
     94     size_t i;
     95     mm_camera_stream_t *stream = NULL;
     96     cam_capability_t *cam_cap = (cam_capability_t *)(test_obj->cap_buf.buf.buffer);
     97     cam_format_t fmt = CAM_FORMAT_MAX;
     98     cam_stream_buf_plane_info_t *buf_planes;
     99 
    100     stream = mm_app_add_stream(test_obj, channel);
    101     if (NULL == stream) {
    102         CDBG_ERROR("%s: add stream failed\n", __func__);
    103         return NULL;
    104     }
    105 
    106     CDBG_ERROR("%s: raw_dim w:%d height:%d\n", __func__, cam_cap->raw_dim[0].width, cam_cap->raw_dim[0].height);
    107     for (i = 0;i < cam_cap->supported_raw_fmt_cnt;i++) {
    108         CDBG_ERROR("%s: supported_raw_fmts[%zd]=%d\n", __func__,
    109             i, (int)cam_cap->supported_raw_fmts[i]);
    110         if (((CAM_FORMAT_BAYER_MIPI_RAW_8BPP_GBRG <= cam_cap->supported_raw_fmts[i]) &&
    111             (CAM_FORMAT_BAYER_MIPI_RAW_12BPP_BGGR >= cam_cap->supported_raw_fmts[i])) ||
    112             (cam_cap->supported_raw_fmts[i] == CAM_FORMAT_META_RAW_8BIT) ||
    113             (cam_cap->supported_raw_fmts[i] == CAM_FORMAT_JPEG_RAW_8BIT))
    114         {
    115             fmt = cam_cap->supported_raw_fmts[i];
    116             CDBG_ERROR("%s: fmt=%d\n", __func__, fmt);
    117         }
    118     }
    119 
    120     if (CAM_FORMAT_MAX == fmt) {
    121         CDBG_ERROR("%s: rdi format not supported\n", __func__);
    122         return NULL;
    123     }
    124 
    125     stream->s_config.mem_vtbl.get_bufs = mm_app_stream_initbuf;
    126     stream->s_config.mem_vtbl.put_bufs = mm_app_stream_deinitbuf;
    127     stream->s_config.mem_vtbl.clean_invalidate_buf =
    128       mm_app_stream_clean_invalidate_buf;
    129     stream->s_config.mem_vtbl.invalidate_buf = mm_app_stream_invalidate_buf;
    130     stream->s_config.mem_vtbl.user_data = (void *)stream;
    131     stream->s_config.stream_cb = stream_cb;
    132     stream->s_config.userdata = userdata;
    133     stream->num_of_bufs = num_bufs;
    134 
    135     stream->s_config.stream_info = (cam_stream_info_t *)stream->s_info_buf.buf.buffer;
    136     memset(stream->s_config.stream_info, 0, sizeof(cam_stream_info_t));
    137     stream->s_config.stream_info->stream_type = CAM_STREAM_TYPE_RAW;
    138     if (num_burst == 0) {
    139         stream->s_config.stream_info->streaming_mode = CAM_STREAMING_MODE_CONTINUOUS;
    140     } else {
    141         stream->s_config.stream_info->streaming_mode = CAM_STREAMING_MODE_BURST;
    142         stream->s_config.stream_info->num_of_burst = num_burst;
    143     }
    144     stream->s_config.stream_info->fmt = fmt;
    145     CDBG("%s: RAW: w: %d, h: %d ", __func__,
    146        cam_cap->raw_dim[0].width, cam_cap->raw_dim[0].height);
    147 
    148     stream->s_config.stream_info->dim.width = cam_cap->raw_dim[0].width;
    149     stream->s_config.stream_info->dim.height = cam_cap->raw_dim[0].height;
    150     stream->s_config.padding_info = cam_cap->padding_info;
    151 
    152     rc = mm_app_config_stream(test_obj, channel, stream, &stream->s_config);
    153     if (MM_CAMERA_OK != rc) {
    154         CDBG_ERROR("%s:config rdi stream err=%d\n", __func__, rc);
    155         return NULL;
    156     }
    157 
    158     buf_planes = &stream->s_config.stream_info->buf_planes;
    159     rdi_len = buf_planes->plane_info.mp[0].len;
    160     CDBG("%s: plane_info %dx%d len:%d frame_len:%d\n", __func__,
    161         buf_planes->plane_info.mp[0].stride, buf_planes->plane_info.mp[0].scanline,
    162         buf_planes->plane_info.mp[0].len, buf_planes->plane_info.frame_len);
    163 
    164     return stream;
    165 }
    166 
    167 mm_camera_stream_t * mm_app_add_rdi_snapshot_stream(mm_camera_test_obj_t *test_obj,
    168                                                 mm_camera_channel_t *channel,
    169                                                 mm_camera_buf_notify_t stream_cb,
    170                                                 void *userdata,
    171                                                 uint8_t num_bufs,
    172                                                 uint8_t num_burst)
    173 {
    174     int rc = MM_CAMERA_OK;
    175     mm_camera_stream_t *stream = NULL;
    176     cam_capability_t *cam_cap = (cam_capability_t *)(test_obj->cap_buf.buf.buffer);
    177 
    178     stream = mm_app_add_stream(test_obj, channel);
    179     if (NULL == stream) {
    180         CDBG_ERROR("%s: add stream failed\n", __func__);
    181         return NULL;
    182     }
    183 
    184     stream->s_config.mem_vtbl.get_bufs = mm_app_stream_initbuf;
    185     stream->s_config.mem_vtbl.put_bufs = mm_app_stream_deinitbuf;
    186     stream->s_config.mem_vtbl.clean_invalidate_buf =
    187       mm_app_stream_clean_invalidate_buf;
    188     stream->s_config.mem_vtbl.invalidate_buf = mm_app_stream_invalidate_buf;
    189     stream->s_config.mem_vtbl.user_data = (void *)stream;
    190     stream->s_config.stream_cb = stream_cb;
    191     stream->s_config.userdata = userdata;
    192     stream->num_of_bufs = num_bufs;
    193 
    194     stream->s_config.stream_info = (cam_stream_info_t *)stream->s_info_buf.buf.buffer;
    195     memset(stream->s_config.stream_info, 0, sizeof(cam_stream_info_t));
    196     stream->s_config.stream_info->stream_type = CAM_STREAM_TYPE_SNAPSHOT;
    197     if (num_burst == 0) {
    198         stream->s_config.stream_info->streaming_mode = CAM_STREAMING_MODE_CONTINUOUS;
    199     } else {
    200         stream->s_config.stream_info->streaming_mode = CAM_STREAMING_MODE_BURST;
    201         stream->s_config.stream_info->num_of_burst = num_burst;
    202     }
    203     stream->s_config.stream_info->fmt = DEFAULT_SNAPSHOT_FORMAT;
    204     stream->s_config.stream_info->dim.width = DEFAULT_SNAPSHOT_WIDTH;
    205     stream->s_config.stream_info->dim.height = DEFAULT_SNAPSHOT_HEIGHT;
    206     stream->s_config.padding_info = cam_cap->padding_info;
    207 
    208     rc = mm_app_config_stream(test_obj, channel, stream, &stream->s_config);
    209     if (MM_CAMERA_OK != rc) {
    210         CDBG_ERROR("%s:config rdi stream err=%d\n", __func__, rc);
    211         return NULL;
    212     }
    213 
    214     return stream;
    215 }
    216 
    217 mm_camera_channel_t * mm_app_add_rdi_channel(mm_camera_test_obj_t *test_obj, uint8_t num_burst)
    218 {
    219     mm_camera_channel_t *channel = NULL;
    220     mm_camera_stream_t *stream = NULL;
    221 
    222     channel = mm_app_add_channel(test_obj,
    223                                  MM_CHANNEL_TYPE_RDI,
    224                                  NULL,
    225                                  NULL,
    226                                  NULL);
    227     if (NULL == channel) {
    228         CDBG_ERROR("%s: add channel failed", __func__);
    229         return NULL;
    230     }
    231 
    232     stream = mm_app_add_rdi_stream(test_obj,
    233                                        channel,
    234                                        mm_app_rdi_notify_cb,
    235                                        (void *)test_obj,
    236                                        RDI_BUF_NUM,
    237                                        num_burst);
    238     if (NULL == stream) {
    239         CDBG_ERROR("%s: add stream failed\n", __func__);
    240         mm_app_del_channel(test_obj, channel);
    241         return NULL;
    242     }
    243 
    244     CDBG("%s: channel=%d stream=%d\n", __func__, channel->ch_id, stream->s_id);
    245     return channel;
    246 }
    247 
    248 int mm_app_stop_and_del_rdi_channel(mm_camera_test_obj_t *test_obj,
    249                                 mm_camera_channel_t *channel)
    250 {
    251     int rc = MM_CAMERA_OK;
    252     mm_camera_stream_t *stream = NULL;
    253     uint8_t i;
    254 
    255     rc = mm_app_stop_channel(test_obj, channel);
    256     if (MM_CAMERA_OK != rc) {
    257         CDBG_ERROR("%s:Stop RDI failed rc=%d\n", __func__, rc);
    258     }
    259 
    260     if (channel->num_streams <= MAX_STREAM_NUM_IN_BUNDLE) {
    261         for (i = 0; i < channel->num_streams; i++) {
    262             stream = &channel->streams[i];
    263             rc = mm_app_del_stream(test_obj, channel, stream);
    264             if (MM_CAMERA_OK != rc) {
    265                 CDBG_ERROR("%s:del stream(%d) failed rc=%d\n", __func__, i, rc);
    266             }
    267         }
    268     } else {
    269         CDBG_ERROR("%s: num_streams = %d. Should not be more than %d\n",
    270             __func__, channel->num_streams, MAX_STREAM_NUM_IN_BUNDLE);
    271     }
    272 
    273     rc = mm_app_del_channel(test_obj, channel);
    274     if (MM_CAMERA_OK != rc) {
    275         CDBG_ERROR("%s:delete channel failed rc=%d\n", __func__, rc);
    276     }
    277 
    278     return rc;
    279 }
    280 
    281 int mm_app_start_rdi(mm_camera_test_obj_t *test_obj, uint8_t num_burst)
    282 {
    283     int rc = MM_CAMERA_OK;
    284     mm_camera_channel_t *channel = NULL;
    285 
    286     channel = mm_app_add_rdi_channel(test_obj, num_burst);
    287     if (NULL == channel) {
    288         CDBG_ERROR("%s: add channel failed", __func__);
    289         return -MM_CAMERA_E_GENERAL;
    290     }
    291 
    292     rc = mm_app_start_channel(test_obj, channel);
    293     if (MM_CAMERA_OK != rc) {
    294         CDBG_ERROR("%s:start rdi failed rc=%d\n", __func__, rc);
    295         mm_app_del_channel(test_obj, channel);
    296         return rc;
    297     }
    298 
    299     return rc;
    300 }
    301 
    302 int mm_app_stop_rdi(mm_camera_test_obj_t *test_obj)
    303 {
    304     int rc = MM_CAMERA_OK;
    305 
    306     mm_camera_channel_t *channel =
    307         mm_app_get_channel_by_type(test_obj, MM_CHANNEL_TYPE_RDI);
    308 
    309     rc = mm_app_stop_and_del_rdi_channel(test_obj, channel);
    310     if (MM_CAMERA_OK != rc) {
    311         CDBG_ERROR("%s:Stop RDI failed rc=%d\n", __func__, rc);
    312     }
    313 
    314     return rc;
    315 }
    316 
    317