1 /* 2 Copyright (c) 2012, 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 <pthread.h> 31 #include "mm_camera_dbg.h" 32 #include <errno.h> 33 #include <sys/ioctl.h> 34 #include <sys/types.h> 35 #include <sys/stat.h> 36 #include <fcntl.h> 37 #include <poll.h> 38 #include <linux/msm_ion.h> 39 #include "mm_qcamera_app.h" 40 41 /*typedef enum { 42 STREAM_IMAGE, 43 STREAM_RAW, 44 STREAM_IMAGE_AND_RAW, 45 STREAM_RAW_AND_RAW, 46 STREAM_MAX, 47 } mm_camera_channel_stream_info_t;*/ 48 49 #define RDI_MASK STREAM_RAW 50 mm_camera_channel_stream_info_t rdi_mode; 51 static int rdi_op_mode; 52 extern int stopPreview(int cam_id); 53 extern void dumpFrameToFile(mm_camera_buf_def_t* newFrame, int w, int h, 54 char* name, int main_422,char *ext); 55 extern int mm_stream_invalid_cache(mm_camera_app_obj_t *pme, 56 mm_camera_buf_def_t *frame); 57 58 static int rdi_counter = 0; 59 static void dumpRdi(mm_camera_buf_def_t* newFrame, int w, int h, char* name, int main_422) 60 { 61 char buf[32]; 62 int file_fd; 63 int i; 64 char *ext = "yuv"; 65 if ( newFrame != NULL) { 66 char * str; 67 snprintf(buf, sizeof(buf), "/data/%s_%d.%s", name, rdi_counter, ext); 68 file_fd = open(buf, O_RDWR | O_CREAT, 0777); 69 if (file_fd < 0) { 70 CDBG_ERROR("%s: cannot open file\n", __func__); 71 } else { 72 void *y_off = newFrame->buffer + newFrame->planes[0].data_offset; 73 //int cbcr_off = newFrame->buffer + newFrame->planes[1].data_offset;//newFrame->buffer + newFrame->planes[0].length; 74 void *cbcr_off = newFrame->buffer + newFrame->planes[0].length; 75 CDBG("%s: Y_off = %p cbcr_off = %p", __func__, y_off,cbcr_off); 76 CDBG("%s: Y_off length = %d cbcr_off length = %d", __func__, newFrame->planes[0].length,newFrame->planes[1].length); 77 78 write(file_fd, (const void *)(y_off), newFrame->planes[0].length); 79 write(file_fd, (const void *)(cbcr_off), 80 (newFrame->planes[1].length * newFrame->num_planes)); 81 close(file_fd); 82 CDBG("dump %s", buf); 83 } 84 } 85 } 86 87 static int mm_app_set_opmode(int cam_id, mm_camera_op_mode_type_t op_mode) 88 { 89 int rc = MM_CAMERA_OK; 90 mm_camera_app_obj_t *pme = mm_app_get_cam_obj(cam_id); 91 CDBG_ERROR("%s: Set rdi op mode = %d",__func__, op_mode); 92 if (MM_CAMERA_OK != (rc = pme->cam->ops->set_parm( 93 pme->cam->camera_handle,MM_CAMERA_PARM_OP_MODE, &op_mode))) { 94 CDBG_ERROR("%s: Set rdi op mode error mode = %d",__func__, op_mode); 95 } 96 return rc; 97 } 98 99 static int mm_app_set_rdi_fmt(int cam_id, mm_camera_image_fmt_t *fmt) 100 { 101 int rc = MM_CAMERA_OK; 102 cam_ctrl_dimension_t dim; 103 mm_camera_app_obj_t *pme = mm_app_get_cam_obj(cam_id); 104 105 fmt->meta_header = MM_CAMEAR_META_DATA_TYPE_DEF; 106 //pme->cam->ops->get_parm(pme->cam->camera_handle,MM_CAMERA_PARM_DIMENSION, &dim); 107 fmt->fmt = pme->dim.rdi0_format; 108 fmt->width = 0; 109 fmt->height = 0; 110 fmt->rotation = 0; 111 112 CDBG("%s: RDI Dimensions = %d X %d", __func__, fmt->width, fmt->height); 113 return rc; 114 } 115 116 int mm_app_open_rdi(int cam_id) 117 { 118 int rc = MM_CAMERA_OK; 119 int value = RDI_MASK; 120 mm_camera_app_obj_t *pme = mm_app_get_cam_obj(cam_id); 121 122 if (pme->cam_mode == RDI_MODE) { 123 return rc; 124 } 125 126 if (MM_CAMERA_OK != (rc = stopPreview(cam_id))) { 127 CDBG_ERROR("%s:Stop preview err=%d\n", __func__, rc); 128 goto end; 129 } 130 pme->cam_mode = RDI_MODE; 131 end: 132 CDBG("%s: END, rc=%d\n", __func__, rc); 133 return rc; 134 } 135 136 void rdi_cb_signal(mm_camera_app_obj_t *pme) 137 { 138 if (pme->cam_mode == RDI_MODE) { 139 mm_camera_app_done(); 140 } 141 } 142 143 static void mm_app_rdi_notify_cb(mm_camera_super_buf_t *bufs, 144 void *user_data) 145 { 146 int rc; 147 mm_camera_buf_def_t *frame = NULL; 148 mm_camera_app_obj_t *pme = NULL; 149 CDBG("%s: BEGIN\n", __func__); 150 frame = bufs->bufs[0] ; 151 pme = (mm_camera_app_obj_t *)user_data; 152 153 CDBG("%s: BEGIN - length=%d, frame idx = %d\n", __func__, frame->frame_len, frame->frame_idx); 154 155 if (rdi_op_mode == MM_CAMERA_OP_MODE_VIDEO) 156 dumpFrameToFile(frame,pme->dim.rdi0_width,pme->dim.rdi0_height,"rdi_p", 1,"raw"); 157 else { 158 rdi_counter++; 159 if (rdi_counter <=5) 160 dumpRdi(frame,pme->dim.rdi0_width,pme->dim.rdi0_height,"rdi_s", 1); 161 } 162 if (MM_CAMERA_OK != pme->cam->ops->qbuf(pme->cam->camera_handle, 163 pme->ch_id, 164 frame)) { 165 CDBG_ERROR("%s: Failed in Preview Qbuf\n", __func__); 166 return; 167 } 168 mm_stream_invalid_cache(pme,frame); 169 if (my_cam_app.run_sanity) { 170 mm_camera_app_done(pme); 171 } 172 CDBG("%s: END\n", __func__); 173 174 } 175 176 int mm_app_prepare_rdi(int cam_id, uint8_t num_buf) 177 { 178 int rc = MM_CAMERA_OK; 179 int op_mode; 180 int value = RDI_MASK; 181 182 CDBG("%s: E",__func__); 183 mm_camera_app_obj_t *pme = mm_app_get_cam_obj(cam_id); 184 185 pme->mem_cam->get_buf = mm_stream_initbuf; 186 pme->mem_cam->put_buf = mm_stream_deinitbuf; 187 pme->mem_cam->user_data = pme; 188 189 //pme->cam->ops->set_parm(pme->cam->camera_handle,MM_CAMERA_PARM_CH_INTERFACE, &value); 190 //pme->cam->ops->get_parm(pme->cam->camera_handle,MM_CAMERA_PARM_CH_INTERFACE, &rdi_mode); 191 192 pme->stream[MM_CAMERA_RDI].id = pme->cam->ops->add_stream(pme->cam->camera_handle, 193 pme->ch_id, 194 mm_app_rdi_notify_cb, 195 pme, 196 MM_CAMERA_RDI, 197 0); 198 199 if (!pme->stream[MM_CAMERA_RDI].id) { 200 CDBG_ERROR("%s:Add RDI error =%d\n", __func__, rc); 201 rc = -1; 202 goto end; 203 } 204 CDBG("%s :Add RDI stream is successfull stream ID = %d",__func__,pme->stream[MM_CAMERA_RDI].id); 205 206 mm_app_set_rdi_fmt(cam_id,&pme->stream[MM_CAMERA_RDI].str_config.fmt); 207 pme->stream[MM_CAMERA_RDI].str_config.need_stream_on = 1; 208 pme->stream[MM_CAMERA_RDI].str_config.num_of_bufs = num_buf; 209 210 if (MM_CAMERA_OK != (rc = pme->cam->ops->config_stream(pme->cam->camera_handle, 211 pme->ch_id, 212 pme->stream[MM_CAMERA_RDI].id, 213 &pme->stream[MM_CAMERA_RDI].str_config))) { 214 CDBG_ERROR("%s:RDI streaming err=%d\n", __func__, rc); 215 goto end; 216 } 217 end: 218 return rc; 219 } 220 221 int mm_app_unprepare_rdi(int cam_id) 222 { 223 int rc = MM_CAMERA_OK; 224 return rc; 225 } 226 227 int mm_app_streamon_rdi(int cam_id) 228 { 229 int rc = MM_CAMERA_OK; 230 uint32_t stream[2]; 231 mm_camera_app_obj_t *pme = mm_app_get_cam_obj(cam_id); 232 int num_of_streams; 233 234 /*if(rdi_mode == STREAM_IMAGE_AND_RAW){ 235 num_of_streams = 2; 236 stream[0] = pme->stream[MM_CAMERA_RDI].id; 237 stream[1] = pme->stream[MM_CAMERA_PREVIEW].id; 238 }else */{ 239 num_of_streams = 1; 240 stream[0] = pme->stream[MM_CAMERA_RDI].id; 241 } 242 243 if (MM_CAMERA_OK != (rc = pme->cam->ops->start_streams(pme->cam->camera_handle, 244 pme->ch_id, 245 num_of_streams, 246 stream))) { 247 CDBG_ERROR("%s : Start RDI Stream preview Error",__func__); 248 goto end; 249 } 250 pme->cam_state = CAMERA_STATE_RDI; 251 end: 252 CDBG("%s: X rc = %d",__func__,rc); 253 return rc; 254 } 255 256 int mm_app_start_rdi(int cam_id) 257 { 258 int rc = MM_CAMERA_OK; 259 260 mm_camera_app_obj_t *pme = mm_app_get_cam_obj(cam_id); 261 int op_mode = 0; 262 263 CDBG_ERROR("pme = %p, pme->cam =%p, pme->cam->camera_handle = %d", 264 pme,pme->cam,pme->cam->camera_handle); 265 266 if (pme->cam_state == CAMERA_STATE_RDI) { 267 return rc; 268 } 269 270 rdi_op_mode = MM_CAMERA_OP_MODE_VIDEO; 271 mm_app_set_opmode(cam_id, MM_CAMERA_OP_MODE_VIDEO); 272 273 if (MM_CAMERA_OK != (rc = mm_app_prepare_rdi(cam_id, 7))) { 274 CDBG_ERROR("%s:Prepare RDI failed rc=%d\n", __func__, rc); 275 goto end; 276 } 277 278 if (MM_CAMERA_OK != (rc = mm_app_streamon_rdi(cam_id))) { 279 CDBG_ERROR("%s:Stream On RDI failed rc=%d\n", __func__, rc); 280 goto end; 281 } 282 283 end: 284 CDBG("%s: END, rc=%d\n", __func__, rc); 285 return rc; 286 } 287 288 static int mm_app_streamoff_rdi(int cam_id) 289 { 290 int rc = MM_CAMERA_OK; 291 uint32_t stream[2]; 292 int num_of_streams; 293 294 mm_camera_app_obj_t *pme = mm_app_get_cam_obj(cam_id); 295 296 /*if(rdi_mode == STREAM_IMAGE_AND_RAW){ 297 num_of_streams = 2; 298 stream[0] = pme->stream[MM_CAMERA_RDI].id; 299 stream[1] = pme->stream[MM_CAMERA_PREVIEW].id; 300 }else*/{ 301 num_of_streams = 1; 302 stream[0] = pme->stream[MM_CAMERA_RDI].id; 303 } 304 305 if (MM_CAMERA_OK != (rc = pme->cam->ops->stop_streams(pme->cam->camera_handle, 306 pme->ch_id, 307 num_of_streams, 308 stream))) { 309 CDBG_ERROR("%s : RDI Stream off Error",__func__); 310 goto end; 311 } 312 313 /*if(rdi_mode == STREAM_IMAGE_AND_RAW) { 314 if(MM_CAMERA_OK != (rc = pme->cam->ops->del_stream(pme->cam->camera_handle,pme->ch_id,pme->stream[MM_CAMERA_PREVIEW].id))) 315 { 316 CDBG_ERROR("%s : Delete Preview error",__func__); 317 goto end; 318 } 319 }*/ 320 if (MM_CAMERA_OK != (rc = pme->cam->ops->del_stream(pme->cam->camera_handle, 321 pme->ch_id, 322 pme->stream[MM_CAMERA_RDI].id))) { 323 CDBG_ERROR("%s : Delete Stream RDI error",__func__); 324 goto end; 325 } 326 CDBG("del_stream successfull"); 327 pme->cam_state = CAMERA_STATE_OPEN; 328 end: 329 CDBG("%s: END, rc=%d\n", __func__, rc); 330 331 return rc; 332 } 333 334 static int mm_app_streamdel_rdi(int cam_id) 335 { 336 int rc = MM_CAMERA_OK; 337 int stream[2]; 338 int num_of_streams; 339 340 mm_camera_app_obj_t *pme = mm_app_get_cam_obj(cam_id); 341 342 /*if(rdi_mode == STREAM_IMAGE_AND_RAW){ 343 num_of_streams = 2; 344 stream[0] = pme->stream[MM_CAMERA_RDI].id; 345 stream[1] = pme->stream[MM_CAMERA_PREVIEW].id; 346 }else*/{ 347 num_of_streams = 1; 348 stream[0] = pme->stream[MM_CAMERA_RDI].id; 349 } 350 351 if (MM_CAMERA_OK != (rc = pme->cam->ops->del_stream(pme->cam->camera_handle,pme->ch_id,pme->stream[MM_CAMERA_RDI].id))) { 352 CDBG_ERROR("%s : Delete Stream RDI error",__func__); 353 goto end; 354 } 355 CDBG("del_stream successfull"); 356 pme->cam_state = CAMERA_STATE_OPEN; 357 end: 358 CDBG("%s: END, rc=%d\n", __func__, rc); 359 360 return rc; 361 } 362 363 364 int startRdi(int cam_id) 365 { 366 int rc = MM_CAMERA_OK; 367 368 mm_camera_app_obj_t *pme = mm_app_get_cam_obj(cam_id); 369 370 CDBG("%s: Start Preview",__func__); 371 372 if (pme->cam_mode == ZSL_MODE || pme->cam_mode == RECORDER_MODE || pme->cam_mode == CAMERA_MODE) { 373 switch (pme->cam_state) { 374 case CAMERA_STATE_RECORD: 375 if (MM_CAMERA_OK != mm_app_stop_video(cam_id)) { 376 CDBG_ERROR("%s:Cannot stop video err=%d\n", __func__, rc); 377 return -1; 378 } 379 case CAMERA_STATE_PREVIEW: 380 if (MM_CAMERA_OK != mm_app_open_rdi(cam_id)) { 381 CDBG_ERROR("%s: Cannot switch to camera mode\n", __func__); 382 return -1; 383 } 384 case CAMERA_STATE_SNAPSHOT: 385 default: 386 break; 387 } 388 } 389 mm_app_start_rdi(cam_id); 390 return rc; 391 } 392 393 int stopRdi(int cam_id) 394 { 395 int rc = MM_CAMERA_OK; 396 mm_camera_app_obj_t *pme = mm_app_get_cam_obj(cam_id); 397 rdi_counter = 0; 398 mm_app_streamoff_rdi(cam_id); 399 400 end: 401 return rc; 402 } 403 404 int takePicture_rdi(int cam_id) 405 { 406 int rc = MM_CAMERA_OK; 407 mm_camera_app_obj_t *pme = mm_app_get_cam_obj(cam_id); 408 409 mm_app_streamoff_rdi(cam_id); 410 rdi_op_mode = MM_CAMERA_OP_MODE_CAPTURE; 411 mm_app_set_opmode(cam_id, MM_CAMERA_OP_MODE_CAPTURE); 412 if (MM_CAMERA_OK != (rc = mm_app_prepare_rdi(cam_id, 1))) { 413 CDBG_ERROR("%s:Prepare RDI failed rc=%d\n", __func__, rc); 414 goto end; 415 } 416 if (MM_CAMERA_OK != (rc = mm_app_streamon_rdi(cam_id))) { 417 CDBG_ERROR("%s:Stream On RDI failed rc=%d\n", __func__, rc); 418 goto end; 419 } 420 mm_camera_app_wait(cam_id); 421 usleep(50*1000); 422 mm_app_streamoff_rdi(cam_id); 423 mm_app_start_rdi(cam_id); 424 end: 425 return rc; 426 } 427 428