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