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