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