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 <stdbool.h>
34 #include <sys/ioctl.h>
35 #include <sys/types.h>
36 #include <sys/stat.h>
37 #include <fcntl.h>
38 #include <poll.h>
39 #include <dlfcn.h>
40 #include "mm_qcamera_main_menu.h"
41 #include "mm_qcamera_app.h"
42 
43 
44 mm_camera_app_t my_cam_app;
45 
46 static pthread_mutex_t app_mutex;
47 static int thread_status = 0;
48 static pthread_cond_t app_cond_v;
49 
50 #define MM_QCAMERA_APP_WAIT_TIME 1000000000
51 
mm_camera_app_timedwait()52 int mm_camera_app_timedwait()
53 {
54     int rc = 0;
55     pthread_mutex_lock(&app_mutex);
56     if(false == thread_status) {
57         struct timespec tw;
58         memset(&tw, 0, sizeof tw);
59         tw.tv_sec = 0;
60         tw.tv_nsec = time(0) + MM_QCAMERA_APP_WAIT_TIME;
61 
62         //pthread_cond_wait(&app_cond_v, &app_mutex);
63         rc = pthread_cond_timedwait(&app_cond_v, &app_mutex,&tw);
64         thread_status = false;
65     }
66     pthread_mutex_unlock(&app_mutex);
67     return rc;
68 }
69 
mm_camera_app_wait()70 int mm_camera_app_wait()
71 {
72     int rc = 0;
73     pthread_mutex_lock(&app_mutex);
74     if(false == thread_status){
75         pthread_cond_wait(&app_cond_v, &app_mutex);
76         thread_status = false;
77     }
78     pthread_mutex_unlock(&app_mutex);
79     return rc;
80 }
81 
mm_camera_app_done()82 void mm_camera_app_done()
83 {
84   pthread_mutex_lock(&app_mutex);
85   thread_status = true;
86   pthread_cond_signal(&app_cond_v);
87   pthread_mutex_unlock(&app_mutex);
88 }
89 
90 
mm_app_get_cam_obj(int8_t cam_id)91 mm_camera_app_obj_t *mm_app_get_cam_obj(int8_t cam_id)
92 {
93     mm_camera_app_obj_t *temp = my_cam_app.obj[cam_id];
94     return temp;
95 }
96 
mm_app_user_ptr(int use_user_ptr)97 void mm_app_user_ptr(int use_user_ptr)
98 {
99     my_cam_app.use_user_ptr = use_user_ptr;
100 }
101 
mm_app_set_dim_def(cam_ctrl_dimension_t * dim)102 void mm_app_set_dim_def(cam_ctrl_dimension_t *dim)
103 {
104     dim->display_width = WVGA_WIDTH;
105     dim->display_height = WVGA_HEIGHT;
106     input_display.user_input_display_width = dim->display_width;
107     input_display.user_input_display_height = dim->display_height;
108     dim->video_width = WVGA_WIDTH;
109     dim->video_width = CEILING32(dim->video_width);
110     dim->video_height = WVGA_HEIGHT;
111     dim->orig_video_width = dim->video_width;
112     dim->orig_video_height = dim->video_height;
113     dim->picture_width = MP1_WIDTH;
114     dim->picture_height = MP1_HEIGHT;
115     dim->orig_picture_dx = dim->picture_width;
116     dim->orig_picture_dy = dim->picture_height;
117     dim->ui_thumbnail_height = QVGA_HEIGHT;
118     dim->ui_thumbnail_width = QVGA_WIDTH;
119     dim->thumbnail_height = dim->ui_thumbnail_height;
120     dim->thumbnail_width = dim->ui_thumbnail_width;
121     dim->orig_picture_width = dim->picture_width;
122     dim->orig_picture_height = dim->picture_height;
123     dim->orig_thumb_width = dim->thumbnail_width;
124     dim->orig_thumb_height = dim->thumbnail_height;
125     dim->raw_picture_height = MP1_HEIGHT;
126     dim->raw_picture_width = MP1_WIDTH;
127     dim->hjr_xtra_buff_for_bayer_filtering;
128     dim->prev_format = CAMERA_YUV_420_NV21;
129     dim->enc_format = CAMERA_YUV_420_NV12;
130     dim->thumb_format = CAMERA_YUV_420_NV21;
131     dim->main_img_format = CAMERA_YUV_420_NV21;
132     dim->prev_padding_format = CAMERA_PAD_TO_4K;
133     dim->display_luma_width = dim->display_width;
134     dim->display_luma_height = dim->display_height;
135     dim->display_chroma_width = dim->display_width;
136     dim->display_chroma_height = dim->display_height;
137     dim->video_luma_width = dim->orig_video_width;
138     dim->video_luma_height = dim->orig_video_height;
139     dim->video_chroma_width = dim->orig_video_width;
140     dim->video_chroma_height = dim->orig_video_height;
141     dim->thumbnail_luma_width = dim->thumbnail_width;
142     dim->thumbnail_luma_height = dim->thumbnail_height;
143     dim->thumbnail_chroma_width = dim->thumbnail_width;
144     dim->thumbnail_chroma_height = dim->thumbnail_height;
145     dim->main_img_luma_width = dim->picture_width;
146     dim->main_img_luma_height = dim->picture_height;
147     dim->main_img_chroma_width = dim->picture_width;
148     dim->main_img_chroma_height = dim->picture_height;
149 }
150 
mm_app_load_hal()151 int mm_app_load_hal()
152 {
153   memset(&my_cam_app, 0, sizeof(my_cam_app));
154   memset(&my_cam_app.hal_lib, 0, sizeof(hal_interface_lib_t));
155 #if defined(_MSM7630_)
156    my_cam_app.hal_lib.ptr = dlopen("/usr/lib/hw/camera.msm7630.so", RTLD_LAZY);
157 #elif defined(_MSM7627A_)
158    my_cam_app.hal_lib.ptr = dlopen("/usr/lib/hw/camera.msm7627A.so", RTLD_LAZY);
159 #else
160   //my_cam_app.hal_lib.ptr = dlopen("hw/camera.msm8960.so", RTLD_NOW);
161    my_cam_app.hal_lib.ptr = dlopen("libmmcamera_interface_badger.so", RTLD_NOW);
162 #endif
163   if (!my_cam_app.hal_lib.ptr) {
164     CDBG_ERROR("%s Error opening HAL library %s\n", __func__, dlerror());
165     return -1;
166   }
167   *(void **)&(my_cam_app.hal_lib.mm_camera_query) =
168         dlsym(my_cam_app.hal_lib.ptr,
169               "camera_query");
170   *(void **)&(my_cam_app.hal_lib.mm_camera_open) =
171         dlsym(my_cam_app.hal_lib.ptr,
172               "camera_open");
173   return 0;
174 }
175 
mm_app_init()176 int mm_app_init()
177 {
178     int rc = MM_CAMERA_OK;
179     CDBG("%s:BEGIN\n", __func__);
180     my_cam_app.cam_info =  (mm_camera_info_t *)my_cam_app.hal_lib.mm_camera_query(&my_cam_app.num_cameras);
181     if(my_cam_app.cam_info == NULL) {
182         CDBG_ERROR("%s: Failed to query camera\n", __func__);
183         rc = -1;
184     }
185     CDBG("%s:END, num_cameras = %d\n", __func__, my_cam_app.num_cameras);
186     return rc;
187 }
188 
notify_evt_cb(uint32_t camera_handle,mm_camera_event_t * evt,void * user_data)189 static void notify_evt_cb(uint32_t camera_handle,
190                          mm_camera_event_t *evt,void *user_data)
191 {
192     CDBG("%s:E evt = %d",__func__,evt->event_type);
193 
194     switch(evt->event_type)
195     {
196         case MM_CAMERA_EVT_TYPE_CH:
197         break;
198         case MM_CAMERA_EVT_TYPE_CTRL:
199             break;
200         case MM_CAMERA_EVT_TYPE_STATS:
201             break;
202         case MM_CAMERA_EVT_TYPE_INFO:
203         break;
204         default:
205             break;
206     }
207     CDBG("%s:X",__func__);
208 }
209 
mm_app_open(uint8_t cam_id)210 int mm_app_open(uint8_t cam_id)
211 {
212     int rc = MM_CAMERA_OK;
213     mm_camera_app_obj_t *pme = NULL;
214     int i;
215     mm_camera_event_type_t evt;
216 
217     pme = mm_app_get_cam_obj(cam_id);
218 
219     CDBG("%s:BEGIN\n", __func__);
220     if(pme != NULL) {
221         CDBG("%s:cam already open.nop\n",__func__);
222         goto end;
223     }
224     my_cam_app.cam_open = cam_id;
225     my_cam_app.obj[cam_id] = (mm_camera_app_obj_t *)malloc(sizeof(mm_camera_app_obj_t));
226     pme = my_cam_app.obj[cam_id];
227 
228     pme->mem_cam = (mm_camear_mem_vtbl_t *)malloc(sizeof(mm_camear_mem_vtbl_t));
229     memset(pme->mem_cam,0,sizeof(mm_camear_mem_vtbl_t));
230     pme->mem_cam->user_data = pme;
231 
232     pme->cam = my_cam_app.hal_lib.mm_camera_open(cam_id,pme->mem_cam);
233     if(pme->cam == NULL) {
234         CDBG("%s:dev open error=%d\n", __func__, rc);
235         memset(pme,0, sizeof(pme));
236         return -1;
237     }
238     CDBG("Open Camera id = %d handle = %d",cam_id,pme->cam->camera_handle);
239 
240     pme->ch_id = cam_id;
241     pme->open_flag = true;
242     mm_app_set_dim_def(&pme->dim);
243 
244     for (i = 0; i < MM_CAMERA_EVT_TYPE_MAX; i++) {
245         evt = (mm_camera_event_type_t) i;
246         pme->cam->ops->register_event_notify(pme->cam->camera_handle,notify_evt_cb,pme,evt);
247     }
248     pme->cam_state = CAMERA_STATE_OPEN;
249     pme->cam_mode = CAMERA_MODE;
250     pme->fullSizeSnapshot = 0;
251 
252     pme->ch_id = pme->cam->ops->ch_acquire(pme->cam->camera_handle);
253     CDBG("Channel Acquired Successfully %d",pme->ch_id);
254 end:
255     CDBG("%s:END, rc=%d\n", __func__, rc);
256     return rc;
257 }
258 
mm_app_close(int8_t cam_id)259 int mm_app_close(int8_t cam_id)
260 {
261     int rc = MM_CAMERA_OK;
262     mm_camera_app_obj_t *pme = mm_app_get_cam_obj(cam_id);
263 
264     CDBG("%s:BEGIN\n", __func__);
265     if(!pme->cam) {
266         CDBG("%s:cam already closed. nop\n",__func__);
267         goto end;
268     }
269 
270     pme->cam->ops->ch_release(pme->cam->camera_handle,pme->ch_id);
271     pme->cam->ops->camera_close(pme->cam->camera_handle);
272     pme->open_flag = false;
273     pme->cam = NULL;
274     pme->my_id = 0;
275     free(pme->mem_cam);
276     pme->mem_cam = NULL;
277     memset(&pme->dim, 0, sizeof(pme->dim));
278     memset(&pme->dim, 0, sizeof(pme->dim));
279 
280     free(pme);
281     pme = NULL;
282     my_cam_app.obj[cam_id] = NULL;
283 
284 end:
285     CDBG("%s:END, rc=%d\n", __func__, rc);
286     return rc;
287 }
288 
switchRes(int cam_id)289 void switchRes(int cam_id)
290 {
291     int rc = MM_CAMERA_OK;
292     mm_camera_app_obj_t *pme = mm_app_get_cam_obj(cam_id);
293     switch(pme->cam_state) {
294     case CAMERA_STATE_RECORD:
295     if(MM_CAMERA_OK != stopRecording(cam_id)){
296         CDBG_ERROR("%s:Cannot stop video err=%d\n", __func__, rc);
297         return -1;
298     }
299     case CAMERA_STATE_PREVIEW:
300         if(MM_CAMERA_OK !=  mm_app_stop_preview(cam_id)){
301             CDBG_ERROR("%s: Cannot switch to camera mode=%d\n", __func__);
302             return -1;
303         }
304         break;
305     case CAMERA_STATE_SNAPSHOT:
306     default:
307         break;
308     }
309 }
switchCamera(int cam_id)310 void switchCamera(int cam_id)
311 {
312     int rc = MM_CAMERA_OK;
313     mm_camera_app_obj_t *pme = mm_app_get_cam_obj(cam_id);
314 
315     if(my_cam_app.cam_open == cam_id){
316         return;
317     }
318 
319     switch(pme->cam_state) {
320         case CAMERA_STATE_RECORD:
321             if(MM_CAMERA_OK != stopRecording(cam_id)){
322                 CDBG_ERROR("%s:Cannot stop video err=%d\n", __func__, rc);
323                 return -1;
324             }
325         case CAMERA_STATE_PREVIEW:
326             if(MM_CAMERA_OK !=  mm_app_stop_preview(cam_id)){
327                 CDBG_ERROR("%s: Cannot switch to camera mode=%d\n", __func__);
328                 return -1;
329             }
330             break;
331         case CAMERA_STATE_SNAPSHOT:
332         default:
333             break;
334     }
335 
336     mm_app_close(my_cam_app.cam_open);
337     mm_app_open(cam_id);
338 }
339 
mm_app_set_dim(int8_t cam_id,cam_ctrl_dimension_t * dim)340 int mm_app_set_dim(int8_t cam_id, cam_ctrl_dimension_t *dim)
341 {
342     int rc = MM_CAMERA_OK;
343     mm_camera_app_obj_t *pme = mm_app_get_cam_obj(cam_id);
344 
345     CDBG("%s:BEGIN\n", __func__);
346 
347     memcpy(&pme->dim, dim, sizeof(cam_ctrl_dimension_t));
348     if(MM_CAMERA_OK != (rc = pme->cam->ops->set_parm(
349             pme->cam->camera_handle,MM_CAMERA_PARM_DIMENSION, &pme->dim)))
350     {
351         CDBG_ERROR("%s: set dimension err=%d\n", __func__, rc);
352     }
353     CDBG("%s:END, rc=%d\n", __func__, rc);
354     return rc;
355 }
356 
mm_app_get_dim(int8_t cam_id,cam_ctrl_dimension_t * dim)357 int mm_app_get_dim(int8_t cam_id, cam_ctrl_dimension_t *dim)
358 {
359     int rc = MM_CAMERA_OK;
360 #if 0
361     mm_camera_app_obj_t *pme = mm_app_get_cam_obj(cam_id);
362     CDBG("%s:BEGIN\n", __func__);
363     if(pme->open_flag != true) {
364         CDBG("%s: dev not open yet\n", __func__);
365         rc = -MM_CAMERA_E_INVALID_OPERATION;
366         goto end;
367     }
368     /* now we only use the upper portion. TBD: needs to be fixed later */
369     //memcpy(&pme->dim, dim, sizeof(cam_ctrl_dimension_t));
370     if(MM_CAMERA_OK != (rc = pme->cam->cfg->get_parm(pme->cam,
371                                                     MM_CAMERA_PARM_DIMENSION, &pme->dim))) {
372         CDBG("%s: set dimension err=%d\n", __func__, rc);
373     }
374     CDBG("%s: raw_w=%d,raw_h=%d\n",
375             __func__, pme->dim.orig_picture_width, pme->dim.orig_picture_height);
376     if(dim)
377     memcpy(dim, &pme->dim, sizeof(cam_ctrl_dimension_t));
378 
379 end:
380     CDBG("%s:END, rc=%d\n", __func__, rc);
381 #endif
382     return rc;
383 }
384 
mm_app_close_ch(int cam_id,int ch_type)385 void mm_app_close_ch(int cam_id, int ch_type)
386 {
387     mm_camera_app_obj_t *pme = mm_app_get_cam_obj(cam_id);
388 
389     pme->cam->ops->ch_release(pme->cam->camera_handle,pme->ch_id);
390     CDBG("%s:END,cam_id = %d, ch = %d\n", __func__, cam_id, ch_type);
391 
392 }
393 
mm_app_unit_test()394 int mm_app_unit_test()
395 {
396     my_cam_app.run_sanity = 1;
397     mm_app_unit_test_entry(&my_cam_app);
398     return 0;
399 }
400 
mm_app_dual_test()401 int mm_app_dual_test()
402 {
403     my_cam_app.run_sanity = 1;
404     mm_app_dual_test_entry(&my_cam_app);
405     return 0;
406 }
407