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
mm_camera_app_timedwait()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
mm_camera_app_wait()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
mm_camera_app_done()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
mm_app_get_cam_obj(int8_t cam_id)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
mm_app_user_ptr(int use_user_ptr)100 void mm_app_user_ptr(int use_user_ptr)
101 {
102 my_cam_app.use_user_ptr = use_user_ptr;
103 }
104
mm_app_set_dim_def(cam_ctrl_dimension_t * dim)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
mm_app_load_hal()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
mm_app_init()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
notify_evt_cb(uint32_t camera_handle,mm_camera_event_t * evt,void * user_data)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
mm_app_open(uint8_t cam_id)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
mm_app_close(int8_t cam_id)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
switchRes(int cam_id)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 }
switchCamera(int cam_id)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
mm_app_set_dim(int8_t cam_id,cam_ctrl_dimension_t * dim)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
mm_app_get_dim(int8_t cam_id,cam_ctrl_dimension_t * dim)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
mm_app_close_ch(int cam_id,int ch_type)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
mm_app_unit_test()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
mm_app_dual_test()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
mm_stream_invalid_cache(mm_camera_app_obj_t * pme,mm_camera_buf_def_t * frame)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
mm_stream_clear_invalid_cache(mm_camera_app_obj_t * pme,mm_camera_buf_def_t * frame)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
mm_stream_alloc_bufs(mm_camera_app_obj_t * pme,mm_camear_app_buf_t * app_bufs,mm_camera_frame_len_offset * frame_offset_info,uint8_t num_bufs)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
mm_stream_release_bufs(mm_camera_app_obj_t * pme,mm_camear_app_buf_t * app_bufs)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