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