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 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 
     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 
     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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 }
    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 
    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 
    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 
    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 
    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