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