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 <dlfcn.h>
     39 #include "mm_qcamera_main_menu.h"
     40 #include "mm_qcamera_app.h"
     41 
     42 mm_camera_app_t my_cam_app;
     43 
     44 extern uint8_t *mm_camera_do_mmap_ion(int ion_fd, struct ion_allocation_data *alloc,
     45                                       struct ion_fd_data *ion_info_fd, int *mapFd);
     46 extern int mm_camera_do_munmap_ion (int ion_fd, struct ion_fd_data *ion_info_fd,
     47                                     void *addr, size_t size);
     48 
     49 static pthread_mutex_t app_mutex;
     50 static int thread_status = 0;
     51 static pthread_cond_t app_cond_v;
     52 
     53 #define MM_QCAMERA_APP_WAIT_TIME 1000000000
     54 
     55 int mm_camera_app_timedwait()
     56 {
     57     int rc = 0;
     58     pthread_mutex_lock(&app_mutex);
     59     if(FALSE == thread_status) {
     60         struct timespec tw;
     61         memset(&tw, 0, sizeof tw);
     62         tw.tv_sec = 0;
     63         tw.tv_nsec = time(0) + MM_QCAMERA_APP_WAIT_TIME;
     64 
     65         //pthread_cond_wait(&app_cond_v, &app_mutex);
     66         rc = pthread_cond_timedwait(&app_cond_v, &app_mutex,&tw);
     67         thread_status = FALSE;
     68     }
     69     pthread_mutex_unlock(&app_mutex);
     70     return rc;
     71 }
     72 
     73 int mm_camera_app_wait()
     74 {
     75     int rc = 0;
     76     pthread_mutex_lock(&app_mutex);
     77     if(FALSE == thread_status){
     78         pthread_cond_wait(&app_cond_v, &app_mutex);
     79         thread_status = FALSE;
     80     }
     81     pthread_mutex_unlock(&app_mutex);
     82     return rc;
     83 }
     84 
     85 void mm_camera_app_done()
     86 {
     87   pthread_mutex_lock(&app_mutex);
     88   thread_status = TRUE;
     89   pthread_cond_signal(&app_cond_v);
     90   pthread_mutex_unlock(&app_mutex);
     91 }
     92 
     93 
     94 mm_camera_app_obj_t *mm_app_get_cam_obj(int8_t cam_id)
     95 {
     96     mm_camera_app_obj_t *temp = my_cam_app.obj[cam_id];
     97     return temp;
     98 }
     99 
    100 void mm_app_user_ptr(int use_user_ptr)
    101 {
    102     my_cam_app.use_user_ptr = use_user_ptr;
    103 }
    104 
    105 void mm_app_set_dim_def(cam_ctrl_dimension_t *dim)
    106 {
    107     dim->display_width = WVGA_WIDTH;
    108     dim->display_height = WVGA_HEIGHT;
    109     input_display.user_input_display_width = dim->display_width;
    110     input_display.user_input_display_height = dim->display_height;
    111     dim->video_width = WVGA_WIDTH;
    112     dim->video_width = CEILING32(dim->video_width);
    113     dim->video_height = WVGA_HEIGHT;
    114     dim->orig_video_width = dim->video_width;
    115     dim->orig_video_height = dim->video_height;
    116     dim->picture_width = MP1_WIDTH;
    117     dim->picture_height = MP1_HEIGHT;
    118     dim->orig_picture_dx = dim->picture_width;
    119     dim->orig_picture_dy = dim->picture_height;
    120     dim->ui_thumbnail_height = QVGA_HEIGHT;
    121     dim->ui_thumbnail_width = QVGA_WIDTH;
    122     dim->thumbnail_height = dim->ui_thumbnail_height;
    123     dim->thumbnail_width = dim->ui_thumbnail_width;
    124     dim->orig_picture_width = dim->picture_width;
    125     dim->orig_picture_height = dim->picture_height;
    126     dim->orig_thumb_width = dim->thumbnail_width;
    127     dim->orig_thumb_height = dim->thumbnail_height;
    128     dim->raw_picture_height = MP1_HEIGHT;
    129     dim->raw_picture_width = MP1_WIDTH;
    130     dim->hjr_xtra_buff_for_bayer_filtering;
    131     dim->prev_format = CAMERA_YUV_420_NV21;
    132     dim->enc_format = CAMERA_YUV_420_NV12;
    133     dim->thumb_format = CAMERA_YUV_420_NV21;
    134     dim->main_img_format = CAMERA_YUV_420_NV21;
    135     dim->raw_img_format = CAMERA_BAYER_SBGGR10;
    136     dim->rdi0_format = CAMERA_YUV_422_YUYV;
    137     dim->prev_padding_format = CAMERA_PAD_TO_4K;
    138     dim->display_luma_width = dim->display_width;
    139     dim->display_luma_height = dim->display_height;
    140     dim->display_chroma_width = dim->display_width;
    141     dim->display_chroma_height = dim->display_height;
    142     dim->video_luma_width = dim->orig_video_width;
    143     dim->video_luma_height = dim->orig_video_height;
    144     dim->video_chroma_width = dim->orig_video_width;
    145     dim->video_chroma_height = dim->orig_video_height;
    146     dim->thumbnail_luma_width = dim->thumbnail_width;
    147     dim->thumbnail_luma_height = dim->thumbnail_height;
    148     dim->thumbnail_chroma_width = dim->thumbnail_width;
    149     dim->thumbnail_chroma_height = dim->thumbnail_height;
    150     dim->main_img_luma_width = dim->picture_width;
    151     dim->main_img_luma_height = dim->picture_height;
    152     dim->main_img_chroma_width = dim->picture_width;
    153     dim->main_img_chroma_height = dim->picture_height;
    154 }
    155 
    156 int mm_app_load_hal()
    157 {
    158   memset(&my_cam_app, 0, sizeof(my_cam_app));
    159   memset(&my_cam_app.hal_lib, 0, sizeof(hal_interface_lib_t));
    160 #if defined(_MSM7630_)
    161    my_cam_app.hal_lib.ptr = dlopen("/usr/lib/hw/camera.msm7630.so", RTLD_LAZY);
    162 #elif defined(_MSM7627A_)
    163    my_cam_app.hal_lib.ptr = dlopen("/usr/lib/hw/camera.msm7627A.so", RTLD_LAZY);
    164 #else
    165   //my_cam_app.hal_lib.ptr = dlopen("hw/camera.msm8960.so", RTLD_NOW);
    166    my_cam_app.hal_lib.ptr = dlopen("libmmcamera_interface.so", RTLD_NOW);
    167    my_cam_app.hal_lib.ptr_jpeg = dlopen("libmmjpeg_interface.so", RTLD_NOW);
    168 #endif
    169   if (!my_cam_app.hal_lib.ptr) {
    170     CDBG_ERROR("%s Error opening HAL library %s\n", __func__, dlerror());
    171     return -1;
    172   }
    173   *(void **)&(my_cam_app.hal_lib.mm_camera_query) =
    174         dlsym(my_cam_app.hal_lib.ptr,
    175               "camera_query");
    176   *(void **)&(my_cam_app.hal_lib.mm_camera_open) =
    177         dlsym(my_cam_app.hal_lib.ptr,
    178               "camera_open");
    179   *(void **)&(my_cam_app.hal_lib.jpeg_open) =
    180         dlsym(my_cam_app.hal_lib.ptr_jpeg,
    181               "jpeg_open");
    182   return 0;
    183 }
    184 
    185 int mm_app_init()
    186 {
    187     int rc = MM_CAMERA_OK;
    188     CDBG("%s:BEGIN\n", __func__);
    189     my_cam_app.cam_info =  (mm_camera_info_t *)my_cam_app.hal_lib.mm_camera_query(&my_cam_app.num_cameras);
    190     if(my_cam_app.cam_info == NULL) {
    191         CDBG_ERROR("%s: Failed to query camera\n", __func__);
    192         rc = -1;
    193     }
    194     CDBG("%s:END, num_cameras = %d\n", __func__, my_cam_app.num_cameras);
    195     return rc;
    196 }
    197 
    198 static void notify_evt_cb(uint32_t camera_handle,
    199                          mm_camera_event_t *evt,void *user_data)
    200 {
    201     CDBG("%s:E evt = %d",__func__,evt->event_type);
    202 
    203     switch(evt->event_type)
    204     {
    205         case MM_CAMERA_EVT_TYPE_CH:
    206         break;
    207         case MM_CAMERA_EVT_TYPE_CTRL:
    208             break;
    209         case MM_CAMERA_EVT_TYPE_STATS:
    210             break;
    211         case MM_CAMERA_EVT_TYPE_INFO:
    212             break;
    213         case MM_CAMERA_EVT_TYPE_PRIVATE_EVT:
    214             CDBG("%s: private evt (%s)", __func__, (char *)evt->e.pri_evt.evt_data);
    215             break;
    216         default:
    217             break;
    218     }
    219     CDBG("%s:X",__func__);
    220 }
    221 
    222 int mm_app_open(uint8_t cam_id)
    223 {
    224     int rc = MM_CAMERA_OK;
    225     mm_camera_app_obj_t *pme = NULL;
    226     int i;
    227     mm_camera_event_type_t evt;
    228 
    229     pme = mm_app_get_cam_obj(cam_id);
    230 
    231     CDBG("%s:BEGIN\n", __func__);
    232     if(pme != NULL) {
    233         CDBG("%s:cam already open.nop\n",__func__);
    234         goto end;
    235     }
    236     my_cam_app.cam_open = cam_id;
    237     my_cam_app.obj[cam_id] = (mm_camera_app_obj_t *)malloc(sizeof(mm_camera_app_obj_t));
    238     pme = my_cam_app.obj[cam_id];
    239 
    240     pme->mem_cam = (mm_camear_mem_vtbl_t *)malloc(sizeof(mm_camear_mem_vtbl_t));
    241     memset(pme->mem_cam,0,sizeof(mm_camear_mem_vtbl_t));
    242     pme->mem_cam->user_data = pme;
    243 
    244     pme->cam = my_cam_app.hal_lib.mm_camera_open(cam_id,pme->mem_cam);
    245     if(pme->cam == NULL) {
    246         CDBG("%s:dev open error=%d\n", __func__, rc);
    247         memset(pme,0, sizeof(pme));
    248         return -1;
    249     }
    250     CDBG("Open Camera id = %d handle = %d", cam_id, pme->cam->camera_handle);
    251 
    252     pme->cam->ops->sync(pme->cam->camera_handle);
    253 
    254     pme->my_id = cam_id;
    255     pme->open_flag = TRUE;
    256     mm_app_set_dim_def(&pme->dim);
    257 
    258     for (i = 0; i < MM_CAMERA_EVT_TYPE_MAX; i++) {
    259         evt = (mm_camera_event_type_t) i;
    260         pme->cam->ops->register_event_notify(pme->cam->camera_handle, notify_evt_cb, pme,evt);
    261     }
    262     pme->cam_state = CAMERA_STATE_OPEN;
    263     pme->cam_mode = CAMERA_MODE;
    264     pme->fullSizeSnapshot = 0;
    265 
    266     pme->ch_id = pme->cam->ops->ch_acquire(pme->cam->camera_handle);
    267     CDBG("Channel Acquired Successfully %d",pme->ch_id);
    268 
    269     memset(&pme->jpeg_ops, 0, sizeof(mm_jpeg_ops_t));
    270     pme->jpeg_hdl = my_cam_app.hal_lib.jpeg_open(&pme->jpeg_ops);
    271     if (pme->jpeg_hdl == 0) {
    272         CDBG_ERROR("%s: jpeg lib open err", __func__);
    273         rc = -1;
    274         goto end;
    275     }
    276 
    277     pme->ionfd = open("/dev/ion", O_RDONLY);
    278     if (pme->ionfd < 0) {
    279         CDBG_ERROR("Ion dev open failed\n");
    280         CDBG_ERROR("Error is %s\n", strerror(errno));
    281         rc = -1;
    282     }
    283 
    284 end:
    285     CDBG("%s:END, rc=%d\n", __func__, rc);
    286     return rc;
    287 }
    288 
    289 int mm_app_close(int8_t cam_id)
    290 {
    291     int rc = MM_CAMERA_OK;
    292     mm_camera_app_obj_t *pme = mm_app_get_cam_obj(cam_id);
    293 
    294     CDBG("%s:BEGIN\n", __func__);
    295     if(!pme->cam) {
    296         CDBG("%s:cam already closed. nop\n",__func__);
    297         goto end;
    298     }
    299 
    300     pme->cam->ops->ch_release(pme->cam->camera_handle,pme->ch_id);
    301     pme->cam->ops->camera_close(pme->cam->camera_handle);
    302     pme->open_flag = FALSE;
    303     pme->cam = NULL;
    304     pme->my_id = 0;
    305     free(pme->mem_cam);
    306     pme->mem_cam = NULL;
    307     memset(&pme->dim, 0, sizeof(pme->dim));
    308 
    309     /* close jpeg client */
    310     if (pme->jpeg_hdl && pme->jpeg_ops.close) {
    311         pme->jpeg_ops.close(pme->jpeg_hdl);
    312         pme->jpeg_hdl = 0;
    313     }
    314     close(pme->ionfd);
    315 
    316     free(pme);
    317     pme = NULL;
    318     my_cam_app.obj[cam_id] = NULL;
    319 
    320 end:
    321     CDBG("%s:END, rc=%d\n", __func__, rc);
    322     return rc;
    323 }
    324 
    325 void switchRes(int cam_id)
    326 {
    327     int rc = MM_CAMERA_OK;
    328     mm_camera_app_obj_t *pme = mm_app_get_cam_obj(cam_id);
    329     switch(pme->cam_state) {
    330     case CAMERA_STATE_RECORD:
    331     if(MM_CAMERA_OK != stopRecording(cam_id)){
    332         CDBG_ERROR("%s:Cannot stop video err=%d\n", __func__, rc);
    333         return;
    334     }
    335     case CAMERA_STATE_PREVIEW:
    336         if(MM_CAMERA_OK !=  mm_app_stop_preview(cam_id)){
    337             CDBG_ERROR("%s: Cannot switch to camera mode\n", __func__);
    338             return;
    339         }
    340         break;
    341     case CAMERA_STATE_SNAPSHOT:
    342     default:
    343         break;
    344     }
    345 }
    346 void switchCamera(int cam_id)
    347 {
    348     int rc = MM_CAMERA_OK;
    349     mm_camera_app_obj_t *pme = mm_app_get_cam_obj(cam_id);
    350 
    351     if(my_cam_app.cam_open == cam_id){
    352         return;
    353     }
    354 
    355     switch(pme->cam_state) {
    356         case CAMERA_STATE_RECORD:
    357             if(MM_CAMERA_OK != stopRecording(cam_id)){
    358                 CDBG_ERROR("%s:Cannot stop video err=%d\n", __func__, rc);
    359                 return;
    360             }
    361         case CAMERA_STATE_PREVIEW:
    362             if(MM_CAMERA_OK !=  mm_app_stop_preview(cam_id)){
    363                 CDBG_ERROR("%s: Cannot switch to camera mode\n", __func__);
    364                 return;
    365             }
    366             break;
    367         case CAMERA_STATE_SNAPSHOT:
    368         default:
    369             break;
    370     }
    371 
    372     mm_app_close(my_cam_app.cam_open);
    373     mm_app_open(cam_id);
    374 }
    375 
    376 int mm_app_set_dim(int8_t cam_id, cam_ctrl_dimension_t *dim)
    377 {
    378     int rc = MM_CAMERA_OK;
    379     mm_camera_app_obj_t *pme = mm_app_get_cam_obj(cam_id);
    380 
    381     CDBG("%s:BEGIN\n", __func__);
    382 
    383     memcpy(&pme->dim, dim, sizeof(cam_ctrl_dimension_t));
    384     if(MM_CAMERA_OK != (rc = pme->cam->ops->set_parm(
    385             pme->cam->camera_handle,MM_CAMERA_PARM_DIMENSION, &pme->dim)))
    386     {
    387         CDBG_ERROR("%s: set dimension err=%d\n", __func__, rc);
    388     }
    389     CDBG("%s:END, rc=%d\n", __func__, rc);
    390     return rc;
    391 }
    392 
    393 int mm_app_get_dim(int8_t cam_id, cam_ctrl_dimension_t *dim)
    394 {
    395     int rc = MM_CAMERA_OK;
    396 #if 0
    397     mm_camera_app_obj_t *pme = mm_app_get_cam_obj(cam_id);
    398     CDBG("%s:BEGIN\n", __func__);
    399     if(pme->open_flag != TRUE) {
    400         CDBG("%s: dev not open yet\n", __func__);
    401         rc = -MM_CAMERA_E_INVALID_OPERATION;
    402         goto end;
    403     }
    404     /* now we only use the upper portion. TBD: needs to be fixed later */
    405     //memcpy(&pme->dim, dim, sizeof(cam_ctrl_dimension_t));
    406     if(MM_CAMERA_OK != (rc = pme->cam->cfg->get_parm(pme->cam,
    407                                                     MM_CAMERA_PARM_DIMENSION, &pme->dim))) {
    408         CDBG("%s: set dimension err=%d\n", __func__, rc);
    409     }
    410     CDBG("%s: raw_w=%d,raw_h=%d\n",
    411             __func__, pme->dim.orig_picture_width, pme->dim.orig_picture_height);
    412     if(dim)
    413     memcpy(dim, &pme->dim, sizeof(cam_ctrl_dimension_t));
    414 
    415 end:
    416     CDBG("%s:END, rc=%d\n", __func__, rc);
    417 #endif
    418     return rc;
    419 }
    420 
    421 void mm_app_close_ch(int cam_id, int ch_type)
    422 {
    423     mm_camera_app_obj_t *pme = mm_app_get_cam_obj(cam_id);
    424 
    425     pme->cam->ops->ch_release(pme->cam->camera_handle,pme->ch_id);
    426     CDBG("%s:END,cam_id = %d, ch = %d\n", __func__, cam_id, ch_type);
    427 
    428 }
    429 
    430 int mm_app_unit_test()
    431 {
    432     my_cam_app.run_sanity = 1;
    433     mm_app_unit_test_entry(&my_cam_app);
    434     return 0;
    435 }
    436 
    437 int mm_app_dual_test()
    438 {
    439     my_cam_app.run_sanity = 1;
    440     mm_app_dual_test_entry(&my_cam_app);
    441     return 0;
    442 }
    443 
    444 int mm_stream_invalid_cache(mm_camera_app_obj_t *pme,mm_camera_buf_def_t *frame)
    445 {
    446     struct ion_flush_data cache_inv_data;
    447     struct ion_custom_data custom_data;
    448     mm_camear_app_buf_t* app_bufs = NULL;
    449     int ion_fd;
    450     int index = -1;
    451     int i;
    452 
    453     if(frame == NULL) {
    454         CDBG_ERROR("%s: Invalid input",__func__);
    455         return -1;
    456     }
    457 #ifdef USE_ION
    458     for (i = 0; i < MM_QCAM_APP_MAX_STREAM_NUM; i++) {
    459         if (pme->stream[i].id == frame->stream_id) {
    460             app_bufs = &pme->stream [i].app_bufs;
    461             break;
    462         }
    463     }
    464     if(app_bufs == NULL) {
    465         CDBG_ERROR("Failed to match Stream");
    466         return -1;
    467     }
    468     for (i = 0; i < MM_CAMERA_MAX_NUM_FRAMES; i++) {
    469         if (app_bufs->bufs[i].buf_idx == frame->buf_idx) {
    470             index = i;
    471             break;
    472         }
    473     }
    474     if(index < 0) {
    475         CDBG_ERROR("Failed to match Frame");
    476         return -1;
    477     }
    478 
    479     cache_inv_data.vaddr = app_bufs->bufs[index].buffer;
    480     cache_inv_data.fd = app_bufs->bufs[index].fd;
    481     cache_inv_data.handle = app_bufs->ion_info_fd[index].handle;
    482     cache_inv_data.length = app_bufs->alloc[index].len;
    483     cache_inv_data.offset = 0;
    484     custom_data.cmd = ION_IOC_INV_CACHES;
    485     custom_data.arg = (unsigned long)&cache_inv_data;
    486     ion_fd = pme->ionfd;
    487 
    488     CDBG("addr = %p, fd = %d, handle = %p length = %d, ION Fd = %d",
    489          cache_inv_data.vaddr,cache_inv_data.fd,cache_inv_data.handle,cache_inv_data.length,ion_fd);
    490     if(ion_fd > 0) {
    491         if(ioctl(ion_fd, ION_IOC_CUSTOM, &custom_data) < 0)
    492             CDBG_ERROR("%s: Cache Invalidate failed\n", __func__);
    493         else {
    494             CDBG("%s: Successful cache invalidate\n", __func__);
    495         }
    496     }
    497 #endif
    498     return MM_CAMERA_OK;
    499 }
    500 
    501 int mm_stream_clear_invalid_cache(mm_camera_app_obj_t *pme,mm_camera_buf_def_t *frame)
    502 {
    503 
    504 #ifdef USE_ION
    505     int i,index = -1;
    506     struct ion_flush_data cache_inv_data;
    507     struct ion_custom_data custom_data;
    508     mm_camear_app_buf_t* app_bufs = NULL;
    509     int ion_fd;
    510 
    511     if (frame) {
    512         memset(&cache_inv_data, 0, sizeof(struct ion_flush_data));
    513 
    514         for (i = 0; i < MM_QCAM_APP_MAX_STREAM_NUM; i++) {
    515             if (pme->stream[i].id == frame->stream_id) {
    516                 app_bufs = &pme->stream [i].app_bufs;
    517                 break;
    518             }
    519         }
    520         if(app_bufs == NULL) {
    521             CDBG_ERROR("Failed to match Stream");
    522             return -1;
    523         }
    524         for (i = 0; i < MM_CAMERA_MAX_NUM_FRAMES; i++) {
    525             if (app_bufs->bufs[i].buf_idx == frame->buf_idx) {
    526                 index = i;
    527                 break;
    528             }
    529         }
    530         if(index < 0) {
    531             CDBG_ERROR("Failed to match Frame");
    532             return -1;
    533         }
    534 
    535         cache_inv_data.vaddr = app_bufs->bufs[index].buffer;
    536         cache_inv_data.fd = app_bufs->bufs[index].fd;
    537         cache_inv_data.handle = app_bufs->ion_info_fd[index].handle;
    538         cache_inv_data.length = app_bufs->alloc[index].len;
    539         cache_inv_data.offset = 0;
    540         custom_data.cmd = ION_IOC_CLEAN_INV_CACHES;
    541         custom_data.arg = (unsigned long)&cache_inv_data;
    542         ion_fd = pme->ionfd;
    543         if(ion_fd > 0) {
    544           if(ioctl(ion_fd, ION_IOC_CUSTOM, &custom_data) < 0)
    545               ALOGE("%s: Cache Invalidate failed\n", __func__);
    546           else {
    547               ALOGD("%s: Successful cache invalidate\n", __func__);
    548           }
    549         }
    550     }
    551 #endif
    552     return MM_CAMERA_OK;
    553 }
    554 
    555 int mm_stream_alloc_bufs(mm_camera_app_obj_t *pme,
    556                          mm_camear_app_buf_t* app_bufs,
    557                          mm_camera_frame_len_offset *frame_offset_info,
    558                          uint8_t num_bufs)
    559 {
    560     int i, num_planes;
    561 
    562     num_planes = frame_offset_info->num_planes;
    563     CDBG("%s: num_planes = %d",__func__,num_planes);
    564 
    565     app_bufs->num = num_bufs;
    566     for (i = 0; i < num_bufs ; i++) {
    567         int j;
    568         app_bufs->bufs[i].buf_idx = i;
    569         app_bufs->alloc[i].len = frame_offset_info->frame_len;
    570         app_bufs->alloc[i].flags = ION_FLAG_CACHED;
    571         app_bufs->alloc[i].heap_mask =
    572         (0x1 << CAMERA_ION_HEAP_ID | 0x1 << ION_IOMMU_HEAP_ID);
    573         app_bufs->alloc[i].align = 4096;
    574 
    575         app_bufs->bufs[i].buffer = mm_camera_do_mmap_ion(pme->ionfd,
    576                                                          &app_bufs->alloc[i],
    577                                                          &app_bufs->ion_info_fd[i],
    578                                                          &app_bufs->bufs[i].fd);
    579         CDBG(" %s : Buffer allocated fd = %d, length = %d",
    580              __func__,app_bufs->bufs[i].fd,app_bufs->alloc[i].len);
    581 
    582         app_bufs->bufs[i].frame_len = app_bufs->alloc[i].len;
    583         app_bufs->bufs[i].num_planes = num_planes;
    584 
    585         /* Plane 0 needs to be set seperately. Set other planes
    586              * in a loop. */
    587         app_bufs->bufs[i].planes[0].length = frame_offset_info->mp[0].len;
    588         app_bufs->bufs[i].planes[0].m.userptr = app_bufs->bufs[i].fd;
    589         app_bufs->bufs[i].planes[0].data_offset = frame_offset_info->mp[0].offset;
    590         app_bufs->bufs[i].planes[0].reserved[0] = 0;
    591         for (j = 1; j < num_planes; j++) {
    592             app_bufs->bufs[i].planes[j].length = frame_offset_info->mp[j].len;
    593             app_bufs->bufs[i].planes[j].m.userptr = app_bufs->bufs[i].fd;
    594             app_bufs->bufs[i].planes[j].data_offset = frame_offset_info->mp[j].offset;
    595             app_bufs->bufs[i].planes[j].reserved[0] =
    596                 app_bufs->bufs[i].planes[j-1].reserved[0] +
    597                 app_bufs->bufs[i].planes[j-1].length;
    598         }
    599     }
    600     CDBG("%s: X",__func__);
    601     return MM_CAMERA_OK;
    602 }
    603 
    604 int mm_stream_release_bufs(mm_camera_app_obj_t *pme,
    605                         mm_camear_app_buf_t* app_bufs)
    606 {
    607     int i, rc = MM_CAMERA_OK;
    608 
    609     CDBG("%s: E",__func__);
    610 
    611     for (i = 0; i < app_bufs->num; i++) {
    612         rc = mm_camera_do_munmap_ion (pme->ionfd,
    613                                       &app_bufs->ion_info_fd[i],
    614                                       (void *)app_bufs->bufs[i].buffer,
    615                                       app_bufs->bufs[i].frame_len);
    616     }
    617     memset(app_bufs, 0, sizeof(mm_camear_app_buf_t));
    618     CDBG("%s: X",__func__);
    619     return rc;
    620 }
    621 
    622