1 /* 2 Copyright (c) 2011-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 "mm_qcamera_app.h" 39 40 #define BUFF_SIZE_128 128 41 static int num_run = 0; 42 43 static int mm_app_dump_video_frame(struct msm_frame *frame, 44 uint32_t len) 45 { 46 static int v_cnt = 0; 47 char bufp[BUFF_SIZE_128]; 48 int file_fdp; 49 int rc = 0; 50 51 return rc; /* disable dump */ 52 53 v_cnt++; 54 if(0 == (v_cnt % 10)) 55 snprintf(bufp, BUFF_SIZE_128, "/data/v_%d.yuv", v_cnt); 56 else 57 return 0; 58 59 file_fdp = open(bufp, O_RDWR | O_CREAT, 0777); 60 61 if (file_fdp < 0) { 62 CDBG("cannot open file %s\n", bufp); 63 rc = -1; 64 goto end; 65 } 66 CDBG("%s:dump frame to '%s'\n", __func__, bufp); 67 write(file_fdp, 68 (const void *)frame->buffer, len); 69 close(file_fdp); 70 end: 71 return rc; 72 } 73 74 static int mm_app_set_video_fmt(int cam_id,mm_camera_image_fmt_t *fmt) 75 { 76 int rc = MM_CAMERA_OK; 77 mm_camera_app_obj_t *pme = mm_app_get_cam_obj(cam_id); 78 79 fmt->meta_header = MM_CAMEAR_META_DATA_TYPE_DEF; 80 fmt->fmt = pme->dim.enc_format; 81 fmt->width = pme->dim.video_width; 82 fmt->height = pme->dim.video_height; 83 return rc; 84 } 85 86 #if 0 87 int mm_stream_deinit_video_buf(uint32_t camera_handle, 88 uint32_t ch_id, uint32_t stream_id, 89 void *user_data, uint8_t num_bufs, 90 mm_camera_buf_def_t *bufs) 91 { 92 int i, rc = MM_CAMERA_OK; 93 mm_camera_app_obj_t *pme = (mm_camera_app_obj_t *)user_data; 94 95 for(i = 0; i < num_bufs; i++) { 96 rc = my_cam_app.hal_lib.mm_camera_do_munmap_ion (pme->ionfd, &(pme->video_buf.frame[i].fd_data), 97 (void *)pme->video_buf.frame[i].buffer, pme->video_buf.frame_len); 98 if(rc != MM_CAMERA_OK) { 99 CDBG_ERROR("%s: mm_camera_do_munmap err, pmem_fd = %d, rc = %d", 100 __func__, bufs[i].fd, rc); 101 } 102 } 103 return rc; 104 } 105 106 int mm_stream_init_video_buf(uint32_t camera_handle, 107 uint32_t ch_id, uint32_t stream_id, 108 void *user_data, 109 mm_camera_frame_len_offset *frame_offset_info, 110 uint8_t num_bufs, 111 uint8_t *initial_reg_flag, 112 mm_camera_buf_def_t *bufs) 113 { 114 int i,j,num_planes, frame_len, y_off, cbcr_off; 115 uint32_t planes[VIDEO_MAX_PLANES]; 116 uint32_t pmem_addr = 0; 117 118 mm_camera_app_obj_t *pme = (mm_camera_app_obj_t *)user_data; 119 120 num_planes = frame_offset_info->num_planes; 121 for ( i = 0; i < num_planes; i++) { 122 planes[i] = frame_offset_info->mp[i].len; 123 } 124 125 frame_len = frame_offset_info->frame_len; 126 y_off = frame_offset_info->mp[0].offset; 127 cbcr_off = frame_offset_info->mp[1].offset; 128 129 CDBG("Allocating video Memory for %d buffers frame_len = %d",num_bufs,frame_offset_info->frame_len); 130 131 for (i = 0; i < num_bufs ; i++) { 132 int j; 133 pme->video_buf.reg[i] = 1; 134 initial_reg_flag[i] = 1; 135 136 pme->video_buf.frame_len = frame_len; 137 pme->video_buf.frame[i].ion_alloc.len = pme->video_buf.frame_len; 138 pme->video_buf.frame[i].ion_alloc.flags = 139 (0x1 << CAMERA_ION_HEAP_ID | 0x1 << ION_IOMMU_HEAP_ID); 140 pme->video_buf.frame[i].ion_alloc.align = 4096; 141 142 pmem_addr = (unsigned long) my_cam_app.hal_lib.mm_camera_do_mmap_ion(pme->ionfd, 143 &(pme->video_buf.frame[i].ion_alloc), &(pme->video_buf.frame[i].fd_data), 144 &pme->video_buf.frame[i].fd); 145 146 pme->video_buf.frame[i].buffer = pmem_addr; 147 pme->video_buf.frame[i].path = OUTPUT_TYPE_V; 148 pme->video_buf.frame[i].y_off = 0; 149 pme->video_buf.frame[i].cbcr_off = planes[0]; 150 pme->video_buf.frame[i].phy_offset = 0; 151 152 CDBG("Buffer allocated Successfully fd = %d",pme->video_buf.frame[i].fd); 153 154 bufs[i].fd = pme->video_buf.frame[i].fd; 155 //bufs[i].buffer = pmem_addr; 156 bufs[i].frame_len = pme->video_buf.frame[i].ion_alloc.len; 157 bufs[i].num_planes = num_planes; 158 159 bufs[i].frame = &pme->video_buf.frame[i]; 160 161 /* Plane 0 needs to be set seperately. Set other planes 162 * in a loop. */ 163 bufs[i].planes[0].length = planes[0]; 164 bufs[i].planes[0].m.userptr = bufs[i].fd; 165 bufs[i].planes[0].data_offset = y_off; 166 bufs[i].planes[0].reserved[0] = 0; 167 //buf_def->buf.mp[i].frame_offset; 168 for (j = 1; j < num_planes; j++) { 169 bufs[i].planes[j].length = planes[j]; 170 bufs[i].planes[j].m.userptr = bufs[i].fd; 171 bufs[i].planes[j].data_offset = cbcr_off; 172 bufs[i].planes[j].reserved[0] = 173 bufs[i].planes[j-1].reserved[0] + 174 bufs[i].planes[j-1].length; 175 } 176 } 177 return MM_CAMERA_OK; 178 } 179 #endif 180 181 void video_cb_signal(mm_camera_app_obj_t *pme) 182 { 183 if(pme->cam_state == CAMERA_STATE_RECORD) { 184 mm_camera_app_done(); 185 } 186 } 187 188 static void mm_app_video_notify_cb(mm_camera_super_buf_t *bufs, 189 void *user_data) 190 { 191 int rc; 192 mm_camera_buf_def_t *frame = NULL; 193 mm_camera_app_obj_t *pme = NULL; 194 CDBG("%s: BEGIN\n", __func__); 195 frame = bufs->bufs[MM_CAMERA_PREVIEW] ; 196 pme = (mm_camera_app_obj_t *)user_data; 197 198 CDBG("%s: BEGIN - length=%d, frame idx = %d\n", __func__, frame->frame_len, frame->frame_idx); 199 //Need to code to Send to Encoder .. Simulat 200 CDBG("In CB function i/p = %p o/p = %p",bufs->bufs[MM_CAMERA_PREVIEW],frame); 201 202 dumpFrameToFile(frame,pme->dim.orig_video_width,pme->dim.orig_video_height,"video", 1); 203 if(MM_CAMERA_OK != pme->cam->ops->qbuf(pme->cam->camera_handle,pme->ch_id,frame)) 204 { 205 CDBG_ERROR("%s: Failed in Snapshot Qbuf\n", __func__); 206 return; 207 } 208 video_cb_signal(pme); 209 CDBG("%s: END\n", __func__); 210 211 } 212 213 int mm_app_config_video(int cam_id) 214 { 215 int rc = MM_CAMERA_OK; 216 mm_camera_app_obj_t *pme = mm_app_get_cam_obj(cam_id); 217 218 mm_app_set_video_fmt(cam_id,&pme->stream[MM_CAMERA_VIDEO].str_config.fmt); 219 pme->stream[MM_CAMERA_VIDEO].str_config.need_stream_on = 1; 220 pme->stream[MM_CAMERA_VIDEO].str_config.num_of_bufs = VIDEO_BUF_NUM; 221 222 if(MM_CAMERA_OK != (rc = pme->cam->ops->config_stream(pme->cam->camera_handle,pme->ch_id,pme->stream[MM_CAMERA_VIDEO].id, 223 &pme->stream[MM_CAMERA_VIDEO].str_config))) { 224 CDBG_ERROR("%s:MM_CAMERA_VIDEO config streaming err=%d\n", __func__, rc); 225 goto end; 226 } 227 228 CDBG("config_stream stream is successfull"); 229 230 pme->stream[MM_CAMERA_SNAPSHOT_MAIN].str_config.need_stream_on = pme->fullSizeSnapshot; 231 pme->stream[MM_CAMERA_SNAPSHOT_MAIN].str_config.num_of_bufs = 1; 232 233 mm_app_set_live_snapshot_fmt(cam_id,&pme->stream[MM_CAMERA_SNAPSHOT_MAIN].str_config.fmt); 234 235 if(MM_CAMERA_OK != (rc = pme->cam->ops->config_stream(pme->cam->camera_handle,pme->ch_id,pme->stream[MM_CAMERA_SNAPSHOT_MAIN].id, 236 &pme->stream[MM_CAMERA_SNAPSHOT_MAIN].str_config))) { 237 CDBG_ERROR("%s:preview streaming err=%d\n", __func__, rc); 238 goto end; 239 } 240 end: 241 return rc; 242 243 } 244 245 int mm_app_prepare_video(int cam_id) 246 { 247 int rc = MM_CAMERA_OK; 248 249 mm_camera_app_obj_t *pme = mm_app_get_cam_obj(cam_id); 250 251 pme->stream[MM_CAMERA_VIDEO].id = pme->cam->ops->add_stream(pme->cam->camera_handle,pme->ch_id, 252 mm_app_video_notify_cb,pme, 253 MM_CAMERA_VIDEO, 0); 254 255 if(!pme->stream[MM_CAMERA_VIDEO].id) { 256 CDBG("%s:MM_CAMERA_VIDEO streaming err = %d\n", __func__, rc); 257 rc = -1; 258 goto end; 259 } 260 261 CDBG("Add stream is successfull stream ID = %d",pme->stream[MM_CAMERA_PREVIEW].id); 262 263 /* Code to add live snapshot*/ 264 pme->stream[MM_CAMERA_SNAPSHOT_MAIN].id = pme->cam->ops->add_stream(pme->cam->camera_handle,pme->ch_id, 265 NULL,pme, 266 MM_CAMERA_SNAPSHOT_MAIN, 0); 267 268 CDBG("Add Snapshot main is successfull stream ID = %d",pme->stream[MM_CAMERA_SNAPSHOT_MAIN].id); 269 if(!pme->stream[MM_CAMERA_SNAPSHOT_MAIN].id) { 270 CDBG_ERROR("%s:preview streaming err=%d\n", __func__, rc); 271 rc = -1; 272 goto end; 273 } 274 /*if(mm_app_config_video(cam_id) != MM_CAMERA_OK) 275 { 276 CDBG_ERROR("%s:Video config err=%d\n", __func__, rc); 277 }*/ 278 end: 279 return rc; 280 } 281 282 int mm_app_unprepare_video(int cam_id) 283 { 284 int rc = MM_CAMERA_OK; 285 mm_camera_app_obj_t *pme = mm_app_get_cam_obj(cam_id); 286 287 if(MM_CAMERA_OK != (rc = pme->cam->ops->del_stream(pme->cam->camera_handle,pme->ch_id,pme->stream[MM_CAMERA_VIDEO].id))){ 288 CDBG_ERROR("%s : Delete Stream Video error",__func__); 289 goto end; 290 } 291 292 if(MM_CAMERA_OK != (rc = pme->cam->ops->del_stream(pme->cam->camera_handle,pme->ch_id,pme->stream[MM_CAMERA_SNAPSHOT_MAIN].id))){ 293 CDBG_ERROR("%s : Delete Stream Video error",__func__); 294 goto end; 295 } 296 end: 297 CDBG("del_stream successfull"); 298 return rc; 299 } 300 301 static int mm_app_streamon_video(int cam_id) 302 { 303 int stream[2]; 304 int rc = MM_CAMERA_OK; 305 306 mm_camera_app_obj_t *pme = mm_app_get_cam_obj(cam_id); 307 308 if(mm_app_config_video(cam_id) != MM_CAMERA_OK) 309 { 310 CDBG_ERROR("%s:Video config err=%d\n", __func__, rc); 311 } 312 313 stream[MM_CAMERA_VIDEO] = pme->stream[MM_CAMERA_VIDEO].id; 314 if(MM_CAMERA_OK != (rc = pme->cam->ops->start_streams(pme->cam->camera_handle,pme->ch_id,1,&stream[1]))) 315 { 316 CDBG_ERROR("%s : Start Stream video Error",__func__); 317 return -1; 318 } 319 CDBG("Start video stream is successfull"); 320 pme->cam_state = CAMERA_STATE_RECORD; 321 return rc; 322 } 323 324 static int mm_app_streamoff_video(int cam_id) 325 { 326 int stream[2]; 327 int rc = MM_CAMERA_OK; 328 329 mm_camera_app_obj_t *pme = mm_app_get_cam_obj(cam_id); 330 331 stream[0] = pme->stream[MM_CAMERA_VIDEO].id; 332 333 if(MM_CAMERA_OK != (rc =pme->cam->ops->stop_streams(pme->cam->camera_handle,pme->ch_id,1,&stream))) 334 { 335 CDBG_ERROR("%s : stop Stream video Error",__func__); 336 goto end; 337 } 338 CDBG("stop video stream is successfull"); 339 pme->cam_state = CAMERA_STATE_PREVIEW; 340 end: 341 return rc; 342 343 } 344 int mm_app_stop_video(int cam_id) 345 { 346 int stream[2]; 347 int rc = MM_CAMERA_OK; 348 349 mm_camera_app_obj_t *pme = mm_app_get_cam_obj(cam_id); 350 351 stream[0] = pme->stream[MM_CAMERA_VIDEO].id; 352 353 if(MM_CAMERA_OK != (rc = mm_app_streamoff_video(cam_id))){ 354 CDBG_ERROR("%s : Video Stream off error",__func__); 355 goto end; 356 } 357 end: 358 return rc; 359 } 360 361 static int mm_app_start_video(int cam_id) 362 { 363 int rc = MM_CAMERA_OK; 364 mm_camera_app_obj_t *pme = mm_app_get_cam_obj(cam_id); 365 366 CDBG("pme = %p, pme->cam =%p, pme->ch = %d pme->cam->camera_handle = %d", 367 pme,pme->cam,pme->ch_id,pme->cam->camera_handle); 368 369 if(MM_CAMERA_OK != (rc = mm_app_prepare_video(cam_id))){ 370 CDBG_ERROR("%s:MM_CAMERA_VIDEO streaming err = %d\n", __func__, rc); 371 goto end; 372 } 373 if(MM_CAMERA_OK != (rc = mm_app_streamon_video(cam_id))){ 374 CDBG_ERROR("%s:MM_CAMERA_VIDEO streaming err = %d\n", __func__, rc); 375 goto end; 376 } 377 378 end: 379 CDBG("%s: END, rc=%d\n", __func__, rc); 380 381 return rc; 382 } 383 384 int mm_app_open_recorder(int cam_id) 385 { 386 int rc = MM_CAMERA_OK; 387 int value = 1; 388 int powermode = 1; 389 390 mm_camera_app_obj_t *pme = mm_app_get_cam_obj(cam_id); 391 392 CDBG("%s: mm_app_open_recorder",__func__); 393 if(pme->cam_mode == RECORDER_MODE) { 394 CDBG("%s : Already in record mode",__func__); 395 return rc; 396 } 397 398 if(MM_CAMERA_OK != (rc = mm_app_stop_preview(cam_id))){ 399 CDBG_ERROR("%s:Stop preview err=%d\n", __func__, rc); 400 goto end; 401 } 402 403 if(MM_CAMERA_OK != initDisplay()) 404 { 405 CDBG_ERROR("%s : Could not initalize display",__func__); 406 goto end; 407 } 408 409 pme->cam->ops->set_parm(pme->cam->camera_handle,MM_CAMERA_PARM_RECORDING_HINT, &value); 410 411 pme->cam->ops->set_parm(pme->cam->camera_handle,MM_CAMERA_PARM_LOW_POWER_MODE, &powermode); 412 413 414 if(MM_CAMERA_OK != (rc = mm_app_prepare_preview(cam_id))){ 415 CDBG_ERROR("%s:stream on preview err=%d\n", __func__, rc); 416 goto end; 417 } 418 419 if(MM_CAMERA_OK != (rc = mm_app_prepare_video(cam_id))){ 420 CDBG_ERROR("%s:stream on video err=%d\n", __func__, rc); 421 goto end; 422 } 423 424 if(MM_CAMERA_OK != (rc = mm_app_streamon_preview(cam_id))){ 425 CDBG_ERROR("%s:start preview err=%d\n", __func__, rc); 426 goto end; 427 } 428 pme->cam_mode = RECORDER_MODE; 429 end: 430 CDBG("%s: END, rc=%d\n", __func__, rc); 431 return rc; 432 } 433 434 int startRecording(int cam_id) 435 { 436 int rc = MM_CAMERA_OK; 437 438 mm_camera_app_obj_t *pme = mm_app_get_cam_obj(cam_id); 439 440 CDBG("%s: Start Recording mode = %d state = %d",__func__,pme->cam_mode,pme->cam_state); 441 442 if(pme->cam_mode == CAMERA_MODE || pme->cam_mode == ZSL_MODE) { 443 switch(pme->cam_state) { 444 case CAMERA_STATE_PREVIEW: 445 if(MM_CAMERA_OK != mm_app_open_recorder(cam_id)){ 446 CDBG_ERROR("%s: Open Record Failed \n", __func__); 447 return -1; 448 } 449 break; 450 case CAMERA_STATE_RECORD: 451 case CAMERA_STATE_SNAPSHOT: 452 default: 453 break; 454 } 455 }/*else{ 456 mm_app_prepare_video(cam_id); 457 }*/ 458 CDBG("%s : startRecording : mode = %d state = %d",__func__,pme->cam_mode,pme->cam_state); 459 if(pme->cam_mode == RECORDER_MODE && pme->cam_state == CAMERA_STATE_PREVIEW){ 460 if(MM_CAMERA_OK != mm_app_streamon_video(cam_id)){ 461 CDBG_ERROR("%s:start video err=%d\n", __func__, rc); 462 return -1; 463 } 464 } 465 CDBG("%s: END, rc=%d\n", __func__, rc); 466 return rc; 467 } 468 469 int stopRecording(int cam_id) 470 { 471 472 int rc = MM_CAMERA_OK; 473 mm_camera_app_obj_t *pme = mm_app_get_cam_obj(cam_id); 474 475 if(pme->cam_mode != RECORDER_MODE || pme->cam_state != CAMERA_STATE_RECORD) { 476 return rc; 477 } 478 if(MM_CAMERA_OK != mm_app_stop_video(cam_id)){ 479 CDBG_ERROR("%s:stop video err=%d\n", __func__, rc); 480 return -1; 481 } 482 return rc; 483 } 484 485