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 
mm_app_dump_video_frame(struct msm_frame * frame,uint32_t len)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 
mm_app_set_video_fmt(int cam_id,mm_camera_image_fmt_t * fmt)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 
video_cb_signal(mm_camera_app_obj_t * pme)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 
mm_app_video_notify_cb(mm_camera_super_buf_t * bufs,void * user_data)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 
mm_app_config_video(int cam_id)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 
mm_app_prepare_video(int cam_id)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 
mm_app_unprepare_video(int cam_id)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 
mm_app_streamon_video(int cam_id)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 
mm_app_streamoff_video(int cam_id)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 }
mm_app_stop_video(int cam_id)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 
mm_app_start_video(int cam_id)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 
mm_app_open_recorder(int cam_id)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 
startRecording(int cam_id)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 
stopRecording(int cam_id)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