1 /* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
2  *
3  * Redistribution and use in source and binary forms, with or without
4  * modification, are permitted provided that the following conditions are
5  * met:
6  *     * Redistributions of source code must retain the above copyright
7  *       notice, this list of conditions and the following disclaimer.
8  *     * Redistributions in binary form must reproduce the above
9  *       copyright notice, this list of conditions and the following
10  *       disclaimer in the documentation and/or other materials provided
11  *       with the distribution.
12  *     * Neither the name of The Linux Foundation nor the names of its
13  *       contributors may be used to endorse or promote products derived
14  *       from this software without specific prior written permission.
15  *
16  * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
17  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
19  * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
20  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
23  * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
25  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
26  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  *
28  */
29 
30 #include <cutils/properties.h>
31 #include <fcntl.h>
32 #include <dlfcn.h>
33 #include <linux/msm_ion.h>
34 #include <sys/mman.h>
35 
36 #include "mm_qcamera_dbg.h"
37 #include "mm_qcamera_app.h"
38 
39 static pthread_mutex_t app_mutex;
40 static int thread_status = 0;
41 static pthread_cond_t app_cond_v;
42 
43 #define MM_QCAMERA_APP_NANOSEC_SCALE 1000000000
44 
mm_camera_app_timedwait(uint8_t seconds)45 int mm_camera_app_timedwait(uint8_t seconds)
46 {
47     int rc = 0;
48     pthread_mutex_lock(&app_mutex);
49     if(FALSE == thread_status) {
50         struct timespec tw;
51         memset(&tw, 0, sizeof tw);
52         tw.tv_sec = 0;
53         tw.tv_nsec = time(0) + seconds * MM_QCAMERA_APP_NANOSEC_SCALE;
54 
55         rc = pthread_cond_timedwait(&app_cond_v, &app_mutex,&tw);
56         thread_status = FALSE;
57     }
58     pthread_mutex_unlock(&app_mutex);
59     return rc;
60 }
61 
mm_camera_app_wait()62 int mm_camera_app_wait()
63 {
64     int rc = 0;
65     pthread_mutex_lock(&app_mutex);
66     if(FALSE == thread_status){
67         pthread_cond_wait(&app_cond_v, &app_mutex);
68         thread_status = FALSE;
69     }
70     pthread_mutex_unlock(&app_mutex);
71     return rc;
72 }
73 
mm_camera_app_done()74 void mm_camera_app_done()
75 {
76   pthread_mutex_lock(&app_mutex);
77   thread_status = TRUE;
78   pthread_cond_signal(&app_cond_v);
79   pthread_mutex_unlock(&app_mutex);
80 }
81 
mm_app_load_hal(mm_camera_app_t * my_cam_app)82 int mm_app_load_hal(mm_camera_app_t *my_cam_app)
83 {
84     memset(&my_cam_app->hal_lib, 0, sizeof(hal_interface_lib_t));
85     my_cam_app->hal_lib.ptr = dlopen("libmmcamera_interface.so", RTLD_NOW);
86     my_cam_app->hal_lib.ptr_jpeg = dlopen("libmmjpeg_interface.so", RTLD_NOW);
87     if (!my_cam_app->hal_lib.ptr || !my_cam_app->hal_lib.ptr_jpeg) {
88         CDBG_ERROR("%s Error opening HAL library %s\n", __func__, dlerror());
89         return -MM_CAMERA_E_GENERAL;
90     }
91     *(void **)&(my_cam_app->hal_lib.get_num_of_cameras) =
92         dlsym(my_cam_app->hal_lib.ptr, "get_num_of_cameras");
93     *(void **)&(my_cam_app->hal_lib.mm_camera_open) =
94         dlsym(my_cam_app->hal_lib.ptr, "camera_open");
95     *(void **)&(my_cam_app->hal_lib.jpeg_open) =
96         dlsym(my_cam_app->hal_lib.ptr_jpeg, "jpeg_open");
97 
98     if (my_cam_app->hal_lib.get_num_of_cameras == NULL ||
99         my_cam_app->hal_lib.mm_camera_open == NULL ||
100         my_cam_app->hal_lib.jpeg_open == NULL) {
101         CDBG_ERROR("%s Error loading HAL sym %s\n", __func__, dlerror());
102         return -MM_CAMERA_E_GENERAL;
103     }
104 
105     my_cam_app->num_cameras = my_cam_app->hal_lib.get_num_of_cameras();
106     CDBG("%s: num_cameras = %d\n", __func__, my_cam_app->num_cameras);
107 
108     return MM_CAMERA_OK;
109 }
110 
mm_app_allocate_ion_memory(mm_camera_app_buf_t * buf,int ion_type)111 int mm_app_allocate_ion_memory(mm_camera_app_buf_t *buf, int ion_type)
112 {
113     int rc = MM_CAMERA_OK;
114     struct ion_handle_data handle_data;
115     struct ion_allocation_data alloc;
116     struct ion_fd_data ion_info_fd;
117     int main_ion_fd = 0;
118     void *data = NULL;
119 
120     main_ion_fd = open("/dev/ion", O_RDONLY);
121     if (main_ion_fd <= 0) {
122         CDBG_ERROR("Ion dev open failed %s\n", strerror(errno));
123         goto ION_OPEN_FAILED;
124     }
125 
126     memset(&alloc, 0, sizeof(alloc));
127     alloc.len = buf->mem_info.size;
128     /* to make it page size aligned */
129     alloc.len = (alloc.len + 4095) & (~4095);
130     alloc.align = 4096;
131     alloc.flags = ION_FLAG_CACHED;
132     alloc.heap_id_mask = ion_type;
133     rc = ioctl(main_ion_fd, ION_IOC_ALLOC, &alloc);
134     if (rc < 0) {
135         CDBG_ERROR("ION allocation failed\n");
136         goto ION_ALLOC_FAILED;
137     }
138 
139     memset(&ion_info_fd, 0, sizeof(ion_info_fd));
140     ion_info_fd.handle = alloc.handle;
141     rc = ioctl(main_ion_fd, ION_IOC_SHARE, &ion_info_fd);
142     if (rc < 0) {
143         CDBG_ERROR("ION map failed %s\n", strerror(errno));
144         goto ION_MAP_FAILED;
145     }
146 
147     data = mmap(NULL,
148                 alloc.len,
149                 PROT_READ  | PROT_WRITE,
150                 MAP_SHARED,
151                 ion_info_fd.fd,
152                 0);
153 
154     if (data == MAP_FAILED) {
155         CDBG_ERROR("ION_MMAP_FAILED: %s (%d)\n", strerror(errno), errno);
156         goto ION_MAP_FAILED;
157     }
158     buf->mem_info.main_ion_fd = main_ion_fd;
159     buf->mem_info.fd = ion_info_fd.fd;
160     buf->mem_info.handle = ion_info_fd.handle;
161     buf->mem_info.size = alloc.len;
162     buf->mem_info.data = data;
163     return MM_CAMERA_OK;
164 
165 ION_MAP_FAILED:
166     memset(&handle_data, 0, sizeof(handle_data));
167     handle_data.handle = ion_info_fd.handle;
168     ioctl(main_ion_fd, ION_IOC_FREE, &handle_data);
169 ION_ALLOC_FAILED:
170     close(main_ion_fd);
171 ION_OPEN_FAILED:
172     return -MM_CAMERA_E_GENERAL;
173 }
174 
mm_app_deallocate_ion_memory(mm_camera_app_buf_t * buf)175 int mm_app_deallocate_ion_memory(mm_camera_app_buf_t *buf)
176 {
177   struct ion_handle_data handle_data;
178   int rc = 0;
179 
180   rc = munmap(buf->mem_info.data, buf->mem_info.size);
181 
182   if (buf->mem_info.fd > 0) {
183       close(buf->mem_info.fd);
184       buf->mem_info.fd = 0;
185   }
186 
187   if (buf->mem_info.main_ion_fd > 0) {
188       memset(&handle_data, 0, sizeof(handle_data));
189       handle_data.handle = buf->mem_info.handle;
190       ioctl(buf->mem_info.main_ion_fd, ION_IOC_FREE, &handle_data);
191       close(buf->mem_info.main_ion_fd);
192       buf->mem_info.main_ion_fd = 0;
193   }
194   return rc;
195 }
196 
197 /* cmd = ION_IOC_CLEAN_CACHES, ION_IOC_INV_CACHES, ION_IOC_CLEAN_INV_CACHES */
mm_app_cache_ops(mm_camera_app_meminfo_t * mem_info,unsigned int cmd)198 int mm_app_cache_ops(mm_camera_app_meminfo_t *mem_info,
199                      unsigned int cmd)
200 {
201     struct ion_flush_data cache_inv_data;
202     struct ion_custom_data custom_data;
203     int ret = MM_CAMERA_OK;
204 
205 #ifdef USE_ION
206     if (NULL == mem_info) {
207         CDBG_ERROR("%s: mem_info is NULL, return here", __func__);
208         return -MM_CAMERA_E_GENERAL;
209     }
210 
211     memset(&cache_inv_data, 0, sizeof(cache_inv_data));
212     memset(&custom_data, 0, sizeof(custom_data));
213     cache_inv_data.vaddr = mem_info->data;
214     cache_inv_data.fd = mem_info->fd;
215     cache_inv_data.handle = mem_info->handle;
216     cache_inv_data.length = mem_info->size;
217     custom_data.cmd = cmd;
218     custom_data.arg = (unsigned long)&cache_inv_data;
219 
220     CDBG("addr = %p, fd = %d, handle = %p length = %d, ION Fd = %d",
221          cache_inv_data.vaddr, cache_inv_data.fd,
222          cache_inv_data.handle, cache_inv_data.length,
223          mem_info->main_ion_fd);
224     if(mem_info->main_ion_fd > 0) {
225         if(ioctl(mem_info->main_ion_fd, ION_IOC_CUSTOM, &custom_data) < 0) {
226             ALOGE("%s: Cache Invalidate failed\n", __func__);
227             ret = -MM_CAMERA_E_GENERAL;
228         }
229     }
230 #endif
231 
232     return ret;
233 }
234 
mm_app_dump_frame(mm_camera_buf_def_t * frame,char * name,char * ext,int frame_idx)235 void mm_app_dump_frame(mm_camera_buf_def_t *frame,
236                        char *name,
237                        char *ext,
238                        int frame_idx)
239 {
240     char file_name[64];
241     int file_fd;
242     int i;
243     if ( frame != NULL) {
244         snprintf(file_name, sizeof(file_name), "/data/%s_%d.%s", name, frame_idx, ext);
245         file_fd = open(file_name, O_RDWR | O_CREAT, 0777);
246         if (file_fd < 0) {
247             CDBG_ERROR("%s: cannot open file %s \n", __func__, file_name);
248         } else {
249             for (i = 0; i < frame->num_planes; i++) {
250                 write(file_fd,
251                       (uint8_t *)frame->buffer + frame->planes[i].data_offset,
252                       frame->planes[i].length);
253             }
254 
255             close(file_fd);
256             CDBG("dump %s", file_name);
257         }
258     }
259 }
260 
mm_app_dump_jpeg_frame(const void * data,uint32_t size,char * name,char * ext,int index)261 void mm_app_dump_jpeg_frame(const void * data, uint32_t size, char* name, char* ext, int index)
262 {
263     char buf[32];
264     int file_fd;
265     if ( data != NULL) {
266         snprintf(buf, sizeof(buf), "/data/%s_%d.%s", name, index, ext);
267         CDBG("%s: %s size =%d, jobId=%d", __func__, buf, size, index);
268         file_fd = open(buf, O_RDWR | O_CREAT, 0777);
269         write(file_fd, data, size);
270         close(file_fd);
271     }
272 }
273 
mm_app_alloc_bufs(mm_camera_app_buf_t * app_bufs,cam_frame_len_offset_t * frame_offset_info,uint8_t num_bufs,uint8_t is_streambuf)274 int mm_app_alloc_bufs(mm_camera_app_buf_t* app_bufs,
275                       cam_frame_len_offset_t *frame_offset_info,
276                       uint8_t num_bufs,
277                       uint8_t is_streambuf)
278 {
279     int i, j;
280     int ion_type = 0x1 << CAMERA_ION_FALLBACK_HEAP_ID;
281 
282     if (is_streambuf) {
283         ion_type |= 0x1 << CAMERA_ION_HEAP_ID;
284     }
285 
286     for (i = 0; i < num_bufs ; i++) {
287         app_bufs[i].mem_info.size = frame_offset_info->frame_len;
288         mm_app_allocate_ion_memory(&app_bufs[i], ion_type);
289 
290         app_bufs[i].buf.buf_idx = i;
291         app_bufs[i].buf.num_planes = frame_offset_info->num_planes;
292         app_bufs[i].buf.fd = app_bufs[i].mem_info.fd;
293         app_bufs[i].buf.frame_len = app_bufs[i].mem_info.size;
294         app_bufs[i].buf.buffer = app_bufs[i].mem_info.data;
295         app_bufs[i].buf.mem_info = (void *)&app_bufs[i].mem_info;
296 
297         /* Plane 0 needs to be set seperately. Set other planes
298              * in a loop. */
299         app_bufs[i].buf.planes[0].length = frame_offset_info->mp[0].len;
300         app_bufs[i].buf.planes[0].m.userptr = app_bufs[i].buf.fd;
301         app_bufs[i].buf.planes[0].data_offset = frame_offset_info->mp[0].offset;
302         app_bufs[i].buf.planes[0].reserved[0] = 0;
303         for (j = 1; j < frame_offset_info->num_planes; j++) {
304             app_bufs[i].buf.planes[j].length = frame_offset_info->mp[j].len;
305             app_bufs[i].buf.planes[j].m.userptr = app_bufs[i].buf.fd;
306             app_bufs[i].buf.planes[j].data_offset = frame_offset_info->mp[j].offset;
307             app_bufs[i].buf.planes[j].reserved[0] =
308                 app_bufs[i].buf.planes[j-1].reserved[0] +
309                 app_bufs[i].buf.planes[j-1].length;
310         }
311     }
312     CDBG("%s: X", __func__);
313     return MM_CAMERA_OK;
314 }
315 
mm_app_release_bufs(uint8_t num_bufs,mm_camera_app_buf_t * app_bufs)316 int mm_app_release_bufs(uint8_t num_bufs,
317                         mm_camera_app_buf_t* app_bufs)
318 {
319     int i, rc = MM_CAMERA_OK;
320 
321     CDBG("%s: E", __func__);
322 
323     for (i = 0; i < num_bufs; i++) {
324         rc = mm_app_deallocate_ion_memory(&app_bufs[i]);
325     }
326     memset(app_bufs, 0, num_bufs * sizeof(mm_camera_app_buf_t));
327     CDBG("%s: X", __func__);
328     return rc;
329 }
330 
mm_app_stream_initbuf(cam_frame_len_offset_t * frame_offset_info,uint8_t * num_bufs,uint8_t ** initial_reg_flag,mm_camera_buf_def_t ** bufs,mm_camera_map_unmap_ops_tbl_t * ops_tbl,void * user_data)331 int mm_app_stream_initbuf(cam_frame_len_offset_t *frame_offset_info,
332                           uint8_t *num_bufs,
333                           uint8_t **initial_reg_flag,
334                           mm_camera_buf_def_t **bufs,
335                           mm_camera_map_unmap_ops_tbl_t *ops_tbl,
336                           void *user_data)
337 {
338     mm_camera_stream_t *stream = (mm_camera_stream_t *)user_data;
339     mm_camera_buf_def_t *pBufs = NULL;
340     uint8_t *reg_flags = NULL;
341     int i, rc;
342 
343     stream->offset = *frame_offset_info;
344     CDBG("%s: alloc buf for stream_id %d, len=%d",
345          __func__, stream->s_id, frame_offset_info->frame_len);
346 
347     pBufs = (mm_camera_buf_def_t *)malloc(sizeof(mm_camera_buf_def_t) * stream->num_of_bufs);
348     reg_flags = (uint8_t *)malloc(sizeof(uint8_t) * stream->num_of_bufs);
349     if (pBufs == NULL || reg_flags == NULL) {
350         CDBG_ERROR("%s: No mem for bufs", __func__);
351         if (pBufs != NULL) {
352             free(pBufs);
353         }
354         if (reg_flags != NULL) {
355             free(reg_flags);
356         }
357         return -1;
358     }
359 
360     rc = mm_app_alloc_bufs(&stream->s_bufs[0],
361                            frame_offset_info,
362                            stream->num_of_bufs,
363                            1);
364 
365     if (rc != MM_CAMERA_OK) {
366         CDBG_ERROR("%s: mm_stream_alloc_bufs err = %d", __func__, rc);
367         free(pBufs);
368         free(reg_flags);
369         return rc;
370     }
371 
372     for (i = 0; i < stream->num_of_bufs; i++) {
373         /* mapping stream bufs first */
374         pBufs[i] = stream->s_bufs[i].buf;
375         reg_flags[i] = 1;
376         rc = ops_tbl->map_ops(pBufs[i].buf_idx,
377                               -1,
378                               pBufs[i].fd,
379                               pBufs[i].frame_len,
380                               ops_tbl->userdata);
381         if (rc != MM_CAMERA_OK) {
382             CDBG_ERROR("%s: mapping buf[%d] err = %d", __func__, i, rc);
383             break;
384         }
385     }
386 
387     if (rc != MM_CAMERA_OK) {
388         int j;
389         for (j=0; j>i; j++) {
390             ops_tbl->unmap_ops(pBufs[j].buf_idx, -1, ops_tbl->userdata);
391         }
392         mm_app_release_bufs(stream->num_of_bufs, &stream->s_bufs[0]);
393         free(pBufs);
394         free(reg_flags);
395         return rc;
396     }
397 
398     *num_bufs = stream->num_of_bufs;
399     *bufs = pBufs;
400     *initial_reg_flag = reg_flags;
401 
402     CDBG("%s: X",__func__);
403     return rc;
404 }
405 
mm_app_stream_deinitbuf(mm_camera_map_unmap_ops_tbl_t * ops_tbl,void * user_data)406 int32_t mm_app_stream_deinitbuf(mm_camera_map_unmap_ops_tbl_t *ops_tbl,
407                                 void *user_data)
408 {
409     mm_camera_stream_t *stream = (mm_camera_stream_t *)user_data;
410     int i;
411 
412     for (i = 0; i < stream->num_of_bufs ; i++) {
413         /* mapping stream bufs first */
414         ops_tbl->unmap_ops(stream->s_bufs[i].buf.buf_idx, -1, ops_tbl->userdata);
415     }
416 
417     mm_app_release_bufs(stream->num_of_bufs, &stream->s_bufs[0]);
418 
419     CDBG("%s: X",__func__);
420     return 0;
421 }
422 
mm_app_stream_clean_invalidate_buf(int index,void * user_data)423 int32_t mm_app_stream_clean_invalidate_buf(int index, void *user_data)
424 {
425     mm_camera_stream_t *stream = (mm_camera_stream_t *)user_data;
426     return mm_app_cache_ops(&stream->s_bufs[index].mem_info,
427       ION_IOC_CLEAN_INV_CACHES);
428 }
429 
mm_app_stream_invalidate_buf(int index,void * user_data)430 int32_t mm_app_stream_invalidate_buf(int index, void *user_data)
431 {
432     mm_camera_stream_t *stream = (mm_camera_stream_t *)user_data;
433     return mm_app_cache_ops(&stream->s_bufs[index].mem_info, ION_IOC_INV_CACHES);
434 }
435 
notify_evt_cb(uint32_t camera_handle,mm_camera_event_t * evt,void * user_data)436 static void notify_evt_cb(uint32_t camera_handle,
437                           mm_camera_event_t *evt,
438                           void *user_data)
439 {
440     mm_camera_test_obj_t *test_obj =
441         (mm_camera_test_obj_t *)user_data;
442     if (test_obj == NULL || test_obj->cam->camera_handle != camera_handle) {
443         CDBG_ERROR("%s: Not a valid test obj", __func__);
444         return;
445     }
446 
447     CDBG("%s:E evt = %d", __func__, evt->server_event_type);
448     switch (evt->server_event_type) {
449        case CAM_EVENT_TYPE_AUTO_FOCUS_DONE:
450            CDBG("%s: rcvd auto focus done evt", __func__);
451            break;
452        case CAM_EVENT_TYPE_ZOOM_DONE:
453            CDBG("%s: rcvd zoom done evt", __func__);
454            break;
455        default:
456            break;
457     }
458 
459     CDBG("%s:X", __func__);
460 }
461 
mm_app_open(mm_camera_app_t * cam_app,uint8_t cam_id,mm_camera_test_obj_t * test_obj)462 int mm_app_open(mm_camera_app_t *cam_app,
463                 uint8_t cam_id,
464                 mm_camera_test_obj_t *test_obj)
465 {
466     int32_t rc;
467     cam_frame_len_offset_t offset_info;
468 
469     CDBG("%s:BEGIN\n", __func__);
470 
471     test_obj->cam = cam_app->hal_lib.mm_camera_open(cam_id);
472     if(test_obj->cam == NULL) {
473         CDBG_ERROR("%s:dev open error\n", __func__);
474         return -MM_CAMERA_E_GENERAL;
475     }
476 
477     CDBG("Open Camera id = %d handle = %d", cam_id, test_obj->cam->camera_handle);
478 
479     /* alloc ion mem for capability buf */
480     memset(&offset_info, 0, sizeof(offset_info));
481     offset_info.frame_len = sizeof(cam_capability_t);
482     rc = mm_app_alloc_bufs(&test_obj->cap_buf,
483                            &offset_info,
484                            1,
485                            0);
486     if (rc != MM_CAMERA_OK) {
487         CDBG_ERROR("%s:alloc buf for capability error\n", __func__);
488         goto error_after_cam_open;
489     }
490 
491     /* mapping capability buf */
492     rc = test_obj->cam->ops->map_buf(test_obj->cam->camera_handle,
493                                      CAM_MAPPING_BUF_TYPE_CAPABILITY,
494                                      test_obj->cap_buf.mem_info.fd,
495                                      test_obj->cap_buf.mem_info.size);
496     if (rc != MM_CAMERA_OK) {
497         CDBG_ERROR("%s:map for capability error\n", __func__);
498         goto error_after_cap_buf_alloc;
499     }
500 
501     /* alloc ion mem for getparm buf */
502     memset(&offset_info, 0, sizeof(offset_info));
503     offset_info.frame_len = sizeof(parm_buffer_t);
504     rc = mm_app_alloc_bufs(&test_obj->parm_buf,
505                            &offset_info,
506                            1,
507                            0);
508     if (rc != MM_CAMERA_OK) {
509         CDBG_ERROR("%s:alloc buf for getparm_buf error\n", __func__);
510         goto error_after_cap_buf_map;
511     }
512 
513     /* mapping getparm buf */
514     rc = test_obj->cam->ops->map_buf(test_obj->cam->camera_handle,
515                                      CAM_MAPPING_BUF_TYPE_PARM_BUF,
516                                      test_obj->parm_buf.mem_info.fd,
517                                      test_obj->parm_buf.mem_info.size);
518     if (rc != MM_CAMERA_OK) {
519         CDBG_ERROR("%s:map getparm_buf error\n", __func__);
520         goto error_after_getparm_buf_alloc;
521     }
522 
523     rc = test_obj->cam->ops->register_event_notify(test_obj->cam->camera_handle,
524                                                    notify_evt_cb,
525                                                    test_obj);
526     if (rc != MM_CAMERA_OK) {
527         CDBG_ERROR("%s: failed register_event_notify", __func__);
528         rc = -MM_CAMERA_E_GENERAL;
529         goto error_after_getparm_buf_map;
530     }
531 
532     rc = test_obj->cam->ops->query_capability(test_obj->cam->camera_handle);
533     if (rc != MM_CAMERA_OK) {
534         CDBG_ERROR("%s: failed query_capability", __func__);
535         rc = -MM_CAMERA_E_GENERAL;
536         goto error_after_getparm_buf_map;
537     }
538 
539     memset(&test_obj->jpeg_ops, 0, sizeof(mm_jpeg_ops_t));
540     test_obj->jpeg_hdl = cam_app->hal_lib.jpeg_open(&test_obj->jpeg_ops);
541     if (test_obj->jpeg_hdl == 0) {
542         CDBG_ERROR("%s: jpeg lib open err", __func__);
543         rc = -MM_CAMERA_E_GENERAL;
544         goto error_after_getparm_buf_map;
545     }
546 
547     return rc;
548 
549 error_after_getparm_buf_map:
550     test_obj->cam->ops->unmap_buf(test_obj->cam->camera_handle,
551                                   CAM_MAPPING_BUF_TYPE_PARM_BUF);
552 error_after_getparm_buf_alloc:
553     mm_app_release_bufs(1, &test_obj->parm_buf);
554 error_after_cap_buf_map:
555     test_obj->cam->ops->unmap_buf(test_obj->cam->camera_handle,
556                                   CAM_MAPPING_BUF_TYPE_CAPABILITY);
557 error_after_cap_buf_alloc:
558     mm_app_release_bufs(1, &test_obj->cap_buf);
559 error_after_cam_open:
560     test_obj->cam->ops->close_camera(test_obj->cam->camera_handle);
561     test_obj->cam = NULL;
562     return rc;
563 }
564 
mm_app_close(mm_camera_test_obj_t * test_obj)565 int mm_app_close(mm_camera_test_obj_t *test_obj)
566 {
567     uint32_t rc = MM_CAMERA_OK;
568 
569     if (test_obj == NULL || test_obj->cam ==NULL) {
570         CDBG_ERROR("%s: cam not opened", __func__);
571         return -MM_CAMERA_E_GENERAL;
572     }
573 
574     /* unmap capability buf */
575     rc = test_obj->cam->ops->unmap_buf(test_obj->cam->camera_handle,
576                                        CAM_MAPPING_BUF_TYPE_CAPABILITY);
577     if (rc != MM_CAMERA_OK) {
578         CDBG_ERROR("%s: unmap capability buf failed, rc=%d", __func__, rc);
579     }
580 
581     /* unmap parm buf */
582     rc = test_obj->cam->ops->unmap_buf(test_obj->cam->camera_handle,
583                                        CAM_MAPPING_BUF_TYPE_PARM_BUF);
584     if (rc != MM_CAMERA_OK) {
585         CDBG_ERROR("%s: unmap setparm buf failed, rc=%d", __func__, rc);
586     }
587 
588     rc = test_obj->cam->ops->close_camera(test_obj->cam->camera_handle);
589     if (rc != MM_CAMERA_OK) {
590         CDBG_ERROR("%s: close camera failed, rc=%d", __func__, rc);
591     }
592     test_obj->cam = NULL;
593 
594     /* close jpeg client */
595     if (test_obj->jpeg_hdl && test_obj->jpeg_ops.close) {
596         rc = test_obj->jpeg_ops.close(test_obj->jpeg_hdl);
597         test_obj->jpeg_hdl = 0;
598         if (rc != MM_CAMERA_OK) {
599             CDBG_ERROR("%s: close jpeg failed, rc=%d", __func__, rc);
600         }
601     }
602 
603     /* dealloc capability buf */
604     rc = mm_app_release_bufs(1, &test_obj->cap_buf);
605     if (rc != MM_CAMERA_OK) {
606         CDBG_ERROR("%s: release capability buf failed, rc=%d", __func__, rc);
607     }
608 
609     /* dealloc parm buf */
610     rc = mm_app_release_bufs(1, &test_obj->parm_buf);
611     if (rc != MM_CAMERA_OK) {
612         CDBG_ERROR("%s: release setparm buf failed, rc=%d", __func__, rc);
613     }
614 
615     return MM_CAMERA_OK;
616 }
617 
mm_app_add_channel(mm_camera_test_obj_t * test_obj,mm_camera_channel_type_t ch_type,mm_camera_channel_attr_t * attr,mm_camera_buf_notify_t channel_cb,void * userdata)618 mm_camera_channel_t * mm_app_add_channel(mm_camera_test_obj_t *test_obj,
619                                          mm_camera_channel_type_t ch_type,
620                                          mm_camera_channel_attr_t *attr,
621                                          mm_camera_buf_notify_t channel_cb,
622                                          void *userdata)
623 {
624     uint32_t ch_id = 0;
625     mm_camera_channel_t *channel = NULL;
626 
627     ch_id = test_obj->cam->ops->add_channel(test_obj->cam->camera_handle,
628                                             attr,
629                                             channel_cb,
630                                             userdata);
631     if (ch_id == 0) {
632         CDBG_ERROR("%s: add channel failed", __func__);
633         return NULL;
634     }
635     channel = &test_obj->channels[ch_type];
636     channel->ch_id = ch_id;
637     return channel;
638 }
639 
mm_app_del_channel(mm_camera_test_obj_t * test_obj,mm_camera_channel_t * channel)640 int mm_app_del_channel(mm_camera_test_obj_t *test_obj,
641                        mm_camera_channel_t *channel)
642 {
643     test_obj->cam->ops->delete_channel(test_obj->cam->camera_handle,
644                                        channel->ch_id);
645     memset(channel, 0, sizeof(mm_camera_channel_t));
646     return MM_CAMERA_OK;
647 }
648 
mm_app_add_stream(mm_camera_test_obj_t * test_obj,mm_camera_channel_t * channel)649 mm_camera_stream_t * mm_app_add_stream(mm_camera_test_obj_t *test_obj,
650                                        mm_camera_channel_t *channel)
651 {
652     mm_camera_stream_t *stream = NULL;
653     int rc = MM_CAMERA_OK;
654     cam_frame_len_offset_t offset_info;
655 
656     stream = &(channel->streams[channel->num_streams++]);
657     stream->s_id = test_obj->cam->ops->add_stream(test_obj->cam->camera_handle,
658                                                   channel->ch_id);
659     if (stream->s_id == 0) {
660         CDBG_ERROR("%s: add stream failed", __func__);
661         return NULL;
662     }
663 
664     /* alloc ion mem for stream_info buf */
665     memset(&offset_info, 0, sizeof(offset_info));
666     offset_info.frame_len = sizeof(cam_stream_info_t);
667     rc = mm_app_alloc_bufs(&stream->s_info_buf,
668                            &offset_info,
669                            1,
670                            0);
671     if (rc != MM_CAMERA_OK) {
672         CDBG_ERROR("%s:alloc buf for stream_info error\n", __func__);
673         test_obj->cam->ops->delete_stream(test_obj->cam->camera_handle,
674                                           channel->ch_id,
675                                           stream->s_id);
676         stream->s_id = 0;
677         return NULL;
678     }
679 
680     /* mapping streaminfo buf */
681     rc = test_obj->cam->ops->map_stream_buf(test_obj->cam->camera_handle,
682                                             channel->ch_id,
683                                             stream->s_id,
684                                             CAM_MAPPING_BUF_TYPE_STREAM_INFO,
685                                             0,
686                                             -1,
687                                             stream->s_info_buf.mem_info.fd,
688                                             stream->s_info_buf.mem_info.size);
689     if (rc != MM_CAMERA_OK) {
690         CDBG_ERROR("%s:map setparm_buf error\n", __func__);
691         mm_app_deallocate_ion_memory(&stream->s_info_buf);
692         test_obj->cam->ops->delete_stream(test_obj->cam->camera_handle,
693                                           channel->ch_id,
694                                           stream->s_id);
695         stream->s_id = 0;
696         return NULL;
697     }
698 
699     return stream;
700 }
701 
mm_app_del_stream(mm_camera_test_obj_t * test_obj,mm_camera_channel_t * channel,mm_camera_stream_t * stream)702 int mm_app_del_stream(mm_camera_test_obj_t *test_obj,
703                       mm_camera_channel_t *channel,
704                       mm_camera_stream_t *stream)
705 {
706     test_obj->cam->ops->unmap_stream_buf(test_obj->cam->camera_handle,
707                                          channel->ch_id,
708                                          stream->s_id,
709                                          CAM_MAPPING_BUF_TYPE_STREAM_INFO,
710                                          0,
711                                          -1);
712     mm_app_deallocate_ion_memory(&stream->s_info_buf);
713     test_obj->cam->ops->delete_stream(test_obj->cam->camera_handle,
714                                       channel->ch_id,
715                                       stream->s_id);
716     memset(stream, 0, sizeof(mm_camera_stream_t));
717     return MM_CAMERA_OK;
718 }
719 
mm_app_get_channel_by_type(mm_camera_test_obj_t * test_obj,mm_camera_channel_type_t ch_type)720 mm_camera_channel_t *mm_app_get_channel_by_type(mm_camera_test_obj_t *test_obj,
721                                                 mm_camera_channel_type_t ch_type)
722 {
723     return &test_obj->channels[ch_type];
724 }
725 
mm_app_config_stream(mm_camera_test_obj_t * test_obj,mm_camera_channel_t * channel,mm_camera_stream_t * stream,mm_camera_stream_config_t * config)726 int mm_app_config_stream(mm_camera_test_obj_t *test_obj,
727                          mm_camera_channel_t *channel,
728                          mm_camera_stream_t *stream,
729                          mm_camera_stream_config_t *config)
730 {
731     return test_obj->cam->ops->config_stream(test_obj->cam->camera_handle,
732                                              channel->ch_id,
733                                              stream->s_id,
734                                              config);
735 }
736 
mm_app_start_channel(mm_camera_test_obj_t * test_obj,mm_camera_channel_t * channel)737 int mm_app_start_channel(mm_camera_test_obj_t *test_obj,
738                          mm_camera_channel_t *channel)
739 {
740     return test_obj->cam->ops->start_channel(test_obj->cam->camera_handle,
741                                              channel->ch_id);
742 }
743 
mm_app_stop_channel(mm_camera_test_obj_t * test_obj,mm_camera_channel_t * channel)744 int mm_app_stop_channel(mm_camera_test_obj_t *test_obj,
745                         mm_camera_channel_t *channel)
746 {
747     return test_obj->cam->ops->stop_channel(test_obj->cam->camera_handle,
748                                             channel->ch_id);
749 }
750 
main(int argc,char ** argv)751 int main(int argc, char **argv)
752 {
753     int c;
754     int rc;
755     int run_tc = 0;
756     int run_dual_tc = 0;
757     mm_camera_app_t my_cam_app;
758 
759     CDBG("\nCamera Test Application\n");
760 
761     while ((c = getopt(argc, argv, "tdh")) != -1) {
762         switch (c) {
763            case 't':
764                run_tc = 1;
765                break;
766            case 'd':
767                run_dual_tc = 1;
768                break;
769            case 'h':
770            default:
771                printf("usage: %s [-t] [-d] \n", argv[0]);
772                printf("-t:   Unit test        \n");
773                printf("-d:   Dual camera test \n");
774                return 0;
775         }
776     }
777 
778     memset(&my_cam_app, 0, sizeof(mm_camera_app_t));
779     if((mm_app_load_hal(&my_cam_app) != MM_CAMERA_OK)) {
780         CDBG_ERROR("%s:mm_app_init err\n", __func__);
781         return -1;
782     }
783 
784     if(run_tc) {
785         printf("\tRunning unit test engine only\n");
786         rc = mm_app_unit_test_entry(&my_cam_app);
787         printf("\tUnit test engine. EXIT(%d)!!!\n", rc);
788         return rc;
789     }
790 #if 0
791     if(run_dual_tc) {
792         printf("\tRunning Dual camera test engine only\n");
793         rc = mm_app_dual_test_entry(&my_cam_app);
794         printf("\t Dual camera engine. EXIT(%d)!!!\n", rc);
795         exit(rc);
796     }
797 #endif
798     /* Clean up and exit. */
799     CDBG("Exiting test app\n");
800     return 0;
801 }
802