1/* 2Copyright (c) 2012-2013, The Linux Foundation. All rights reserved. 3 4Redistribution and use in source and binary forms, with or without 5modification, are permitted provided that the following conditions are 6met: 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 17THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED 18WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 19MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT 20ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS 21BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 24BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 25WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 26OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 27IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28*/ 29 30#include "mm_qcamera_dbg.h" 31#include "mm_qcamera_app.h" 32 33static uint32_t rdi_len = 0; 34 35static void mm_app_rdi_dump_frame(mm_camera_buf_def_t *frame, 36 char *name, 37 char *ext, 38 int frame_idx) 39{ 40 char file_name[64]; 41 int file_fd; 42 int i; 43 if (frame != NULL) { 44 snprintf(file_name, sizeof(file_name), "/data/%s_%03d.%s", name, frame_idx, ext); 45 file_fd = open(file_name, O_RDWR | O_CREAT, 0777); 46 if (file_fd < 0) { 47 CDBG_ERROR("%s: cannot open file %s \n", __func__, file_name); 48 } else { 49 for (i = 0; i < frame->num_planes; i++) { 50 write(file_fd, 51 (uint8_t *)frame->buffer + frame->planes[i].data_offset, 52 rdi_len); 53 } 54 55 close(file_fd); 56 CDBG("dump %s", file_name); 57 } 58 } 59} 60 61static void mm_app_rdi_notify_cb(mm_camera_super_buf_t *bufs, 62 void *user_data) 63{ 64 char file_name[64]; 65 mm_camera_buf_def_t *frame = bufs->bufs[0]; 66 mm_camera_test_obj_t *pme = (mm_camera_test_obj_t *)user_data; 67 68 CDBG("%s: BEGIN - length=%d, frame idx = %d stream_id=%d\n", 69 __func__, frame->frame_len, frame->frame_idx, frame->stream_id); 70 snprintf(file_name, sizeof(file_name), "RDI_dump_%d", pme->cam->camera_handle); 71 mm_app_rdi_dump_frame(frame, file_name, "raw", frame->frame_idx); 72 73 if (MM_CAMERA_OK != pme->cam->ops->qbuf(bufs->camera_handle, 74 bufs->ch_id, 75 frame)) { 76 CDBG_ERROR("%s: Failed in RDI Qbuf\n", __func__); 77 } 78 mm_app_cache_ops((mm_camera_app_meminfo_t *)frame->mem_info, 79 ION_IOC_INV_CACHES); 80 81 CDBG("%s: END\n", __func__); 82} 83 84mm_camera_stream_t * mm_app_add_rdi_stream(mm_camera_test_obj_t *test_obj, 85 mm_camera_channel_t *channel, 86 mm_camera_buf_notify_t stream_cb, 87 void *userdata, 88 uint8_t num_bufs, 89 uint8_t num_burst) 90{ 91 int rc = MM_CAMERA_OK; 92 int i; 93 mm_camera_stream_t *stream = NULL; 94 cam_capability_t *cam_cap = (cam_capability_t *)(test_obj->cap_buf.buf.buffer); 95 cam_format_t fmt = CAM_FORMAT_MAX; 96 cam_stream_buf_plane_info_t *buf_planes; 97 98 stream = mm_app_add_stream(test_obj, channel); 99 if (NULL == stream) { 100 CDBG_ERROR("%s: add stream failed\n", __func__); 101 return NULL; 102 } 103 104 CDBG_ERROR("%s: raw_dim w:%d height:%d\n", __func__, cam_cap->raw_dim.width, cam_cap->raw_dim.height); 105 for (i = 0;i < cam_cap->supported_raw_fmt_cnt;i++) { 106 CDBG_ERROR("%s: supported_raw_fmts[%d]=%d\n", __func__, i, cam_cap->supported_raw_fmts[i]); 107 if (CAM_FORMAT_BAYER_MIPI_RAW_8BPP_GBRG <= cam_cap->supported_raw_fmts[i] && 108 CAM_FORMAT_BAYER_MIPI_RAW_12BPP_BGGR >= cam_cap->supported_raw_fmts[i]) 109 { 110 fmt = cam_cap->supported_raw_fmts[i]; 111 CDBG_ERROR("%s: fmt=%d\n", __func__, fmt); 112 } 113 } 114 115 if (CAM_FORMAT_MAX == fmt) { 116 CDBG_ERROR("%s: rdi format not supported\n", __func__); 117 return NULL; 118 } 119 120 stream->s_config.mem_vtbl.get_bufs = mm_app_stream_initbuf; 121 stream->s_config.mem_vtbl.put_bufs = mm_app_stream_deinitbuf; 122 stream->s_config.mem_vtbl.clean_invalidate_buf = 123 mm_app_stream_clean_invalidate_buf; 124 stream->s_config.mem_vtbl.invalidate_buf = mm_app_stream_invalidate_buf; 125 stream->s_config.mem_vtbl.user_data = (void *)stream; 126 stream->s_config.stream_cb = stream_cb; 127 stream->s_config.userdata = userdata; 128 stream->num_of_bufs = num_bufs; 129 130 stream->s_config.stream_info = (cam_stream_info_t *)stream->s_info_buf.buf.buffer; 131 memset(stream->s_config.stream_info, 0, sizeof(cam_stream_info_t)); 132 stream->s_config.stream_info->stream_type = CAM_STREAM_TYPE_RAW; 133 if (num_burst == 0) { 134 stream->s_config.stream_info->streaming_mode = CAM_STREAMING_MODE_CONTINUOUS; 135 } else { 136 stream->s_config.stream_info->streaming_mode = CAM_STREAMING_MODE_BURST; 137 stream->s_config.stream_info->num_of_burst = num_burst; 138 } 139 stream->s_config.stream_info->fmt = fmt; 140 stream->s_config.stream_info->dim.width = cam_cap->raw_dim.width; 141 stream->s_config.stream_info->dim.height = cam_cap->raw_dim.height; 142 stream->s_config.padding_info = cam_cap->padding_info; 143 144 rc = mm_app_config_stream(test_obj, channel, stream, &stream->s_config); 145 if (MM_CAMERA_OK != rc) { 146 CDBG_ERROR("%s:config rdi stream err=%d\n", __func__, rc); 147 return NULL; 148 } 149 150 buf_planes = &stream->s_config.stream_info->buf_planes; 151 rdi_len = buf_planes->plane_info.mp[0].len; 152 CDBG("%s: plane_info %dx%d len:%d frame_len:%d\n", __func__, 153 buf_planes->plane_info.mp[0].stride, buf_planes->plane_info.mp[0].scanline, 154 buf_planes->plane_info.mp[0].len, buf_planes->plane_info.frame_len); 155 156 return stream; 157} 158 159mm_camera_stream_t * mm_app_add_rdi_snapshot_stream(mm_camera_test_obj_t *test_obj, 160 mm_camera_channel_t *channel, 161 mm_camera_buf_notify_t stream_cb, 162 void *userdata, 163 uint8_t num_bufs, 164 uint8_t num_burst) 165{ 166 int rc = MM_CAMERA_OK; 167 mm_camera_stream_t *stream = NULL; 168 cam_capability_t *cam_cap = (cam_capability_t *)(test_obj->cap_buf.buf.buffer); 169 170 stream = mm_app_add_stream(test_obj, channel); 171 if (NULL == stream) { 172 CDBG_ERROR("%s: add stream failed\n", __func__); 173 return NULL; 174 } 175 176 stream->s_config.mem_vtbl.get_bufs = mm_app_stream_initbuf; 177 stream->s_config.mem_vtbl.put_bufs = mm_app_stream_deinitbuf; 178 stream->s_config.mem_vtbl.clean_invalidate_buf = 179 mm_app_stream_clean_invalidate_buf; 180 stream->s_config.mem_vtbl.invalidate_buf = mm_app_stream_invalidate_buf; 181 stream->s_config.mem_vtbl.user_data = (void *)stream; 182 stream->s_config.stream_cb = stream_cb; 183 stream->s_config.userdata = userdata; 184 stream->num_of_bufs = num_bufs; 185 186 stream->s_config.stream_info = (cam_stream_info_t *)stream->s_info_buf.buf.buffer; 187 memset(stream->s_config.stream_info, 0, sizeof(cam_stream_info_t)); 188 stream->s_config.stream_info->stream_type = CAM_STREAM_TYPE_SNAPSHOT; 189 if (num_burst == 0) { 190 stream->s_config.stream_info->streaming_mode = CAM_STREAMING_MODE_CONTINUOUS; 191 } else { 192 stream->s_config.stream_info->streaming_mode = CAM_STREAMING_MODE_BURST; 193 stream->s_config.stream_info->num_of_burst = num_burst; 194 } 195 stream->s_config.stream_info->fmt = DEFAULT_SNAPSHOT_FORMAT; 196 stream->s_config.stream_info->dim.width = DEFAULT_SNAPSHOT_WIDTH; 197 stream->s_config.stream_info->dim.height = DEFAULT_SNAPSHOT_HEIGHT; 198 stream->s_config.padding_info = cam_cap->padding_info; 199 200 rc = mm_app_config_stream(test_obj, channel, stream, &stream->s_config); 201 if (MM_CAMERA_OK != rc) { 202 CDBG_ERROR("%s:config rdi stream err=%d\n", __func__, rc); 203 return NULL; 204 } 205 206 return stream; 207} 208 209mm_camera_channel_t * mm_app_add_rdi_channel(mm_camera_test_obj_t *test_obj, uint8_t num_burst) 210{ 211 mm_camera_channel_t *channel = NULL; 212 mm_camera_stream_t *stream = NULL; 213 214 channel = mm_app_add_channel(test_obj, 215 MM_CHANNEL_TYPE_RDI, 216 NULL, 217 NULL, 218 NULL); 219 if (NULL == channel) { 220 CDBG_ERROR("%s: add channel failed", __func__); 221 return NULL; 222 } 223 224 stream = mm_app_add_rdi_stream(test_obj, 225 channel, 226 mm_app_rdi_notify_cb, 227 (void *)test_obj, 228 RDI_BUF_NUM, 229 num_burst); 230 if (NULL == stream) { 231 CDBG_ERROR("%s: add stream failed\n", __func__); 232 mm_app_del_channel(test_obj, channel); 233 return NULL; 234 } 235 236 CDBG("%s: channel=%d stream=%d\n", __func__, channel->ch_id, stream->s_id); 237 return channel; 238} 239 240int mm_app_stop_and_del_rdi_channel(mm_camera_test_obj_t *test_obj, 241 mm_camera_channel_t *channel) 242{ 243 int rc = MM_CAMERA_OK; 244 mm_camera_stream_t *stream = NULL; 245 uint8_t i; 246 247 rc = mm_app_stop_channel(test_obj, channel); 248 if (MM_CAMERA_OK != rc) { 249 CDBG_ERROR("%s:Stop RDI failed rc=%d\n", __func__, rc); 250 } 251 252 for (i = 0; i < channel->num_streams; i++) { 253 stream = &channel->streams[i]; 254 rc = mm_app_del_stream(test_obj, channel, stream); 255 if (MM_CAMERA_OK != rc) { 256 CDBG_ERROR("%s:del stream(%d) failed rc=%d\n", __func__, i, rc); 257 } 258 } 259 260 rc = mm_app_del_channel(test_obj, channel); 261 if (MM_CAMERA_OK != rc) { 262 CDBG_ERROR("%s:delete channel failed rc=%d\n", __func__, rc); 263 } 264 265 return rc; 266} 267 268int mm_app_start_rdi(mm_camera_test_obj_t *test_obj, uint8_t num_burst) 269{ 270 int rc = MM_CAMERA_OK; 271 mm_camera_channel_t *channel = NULL; 272 273 channel = mm_app_add_rdi_channel(test_obj, num_burst); 274 if (NULL == channel) { 275 CDBG_ERROR("%s: add channel failed", __func__); 276 return -MM_CAMERA_E_GENERAL; 277 } 278 279 rc = mm_app_start_channel(test_obj, channel); 280 if (MM_CAMERA_OK != rc) { 281 CDBG_ERROR("%s:start rdi failed rc=%d\n", __func__, rc); 282 mm_app_del_channel(test_obj, channel); 283 return rc; 284 } 285 286 return rc; 287} 288 289int mm_app_stop_rdi(mm_camera_test_obj_t *test_obj) 290{ 291 int rc = MM_CAMERA_OK; 292 293 mm_camera_channel_t *channel = 294 mm_app_get_channel_by_type(test_obj, MM_CHANNEL_TYPE_RDI); 295 296 rc = mm_app_stop_and_del_rdi_channel(test_obj, channel); 297 if (MM_CAMERA_OK != rc) { 298 CDBG_ERROR("%s:Stop RDI failed rc=%d\n", __func__, rc); 299 } 300 301 return rc; 302} 303 304