Home | History | Annotate | Download | only in src
      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