1 /* Copyright (c) 2011-2012, 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  /*#error uncomment this for compiler test!*/
29 //#define ALOG_NDEBUG 0
30 #define ALOG_NIDEBUG 0
31 #define LOG_TAG "QualcommUsbCamera"
32 
33 #include <utils/Log.h>
34 #include <utils/threads.h>
35 #include <fcntl.h>
36 #include <sys/mman.h>
37 #include <sys/stat.h>
38 #include <unistd.h>
39 #include <sys/prctl.h>
40 #include <sys/resource.h>
41 #include <pthread.h>
42 #include <linux/uvcvideo.h>
43 
44 #include "QCameraHAL.h"
45 #include "QualcommUsbCamera.h"
46 #include "QCameraUsbPriv.h"
47 #include "QCameraMjpegDecode.h"
48 #include "QCameraUsbParm.h"
49 #include <gralloc_priv.h>
50 #include <genlock.h>
51 
52 extern "C" {
53 #include <sys/time.h>
54 }
55 
56 camera_device_ops_t usbcam_camera_ops = {
57   set_preview_window:         android::usbcam_set_preview_window,
58   set_callbacks:              android::usbcam_set_CallBacks,
59   enable_msg_type:            android::usbcam_enable_msg_type,
60   disable_msg_type:           android::usbcam_disable_msg_type,
61   msg_type_enabled:           android::usbcam_msg_type_enabled,
62 
63   start_preview:              android::usbcam_start_preview,
64   stop_preview:               android::usbcam_stop_preview,
65   preview_enabled:            android::usbcam_preview_enabled,
66   store_meta_data_in_buffers: android::usbcam_store_meta_data_in_buffers,
67 
68   start_recording:            android::usbcam_start_recording,
69   stop_recording:             android::usbcam_stop_recording,
70   recording_enabled:          android::usbcam_recording_enabled,
71   release_recording_frame:    android::usbcam_release_recording_frame,
72 
73   auto_focus:                 android::usbcam_auto_focus,
74   cancel_auto_focus:          android::usbcam_cancel_auto_focus,
75 
76   take_picture:               android::usbcam_take_picture,
77   cancel_picture:             android::usbcam_cancel_picture,
78 
79   set_parameters:             android::usbcam_set_parameters,
80   get_parameters:             android::usbcam_get_parameters,
81   put_parameters:             android::usbcam_put_parameters,
82   send_command:               android::usbcam_send_command,
83 
84   release:                    android::usbcam_release,
85   dump:                       android::usbcam_dump,
86 };
87 
88 #define CAPTURE                 1
89 #define DISPLAY                 1
90 #define CALL_BACK               1
91 #define MEMSET                  0
92 #define FREAD_JPEG_PICTURE      0
93 #define JPEG_ON_USB_CAMERA      1
94 #define FILE_DUMP_CAMERA        0
95 #define FILE_DUMP_B4_DISP       0
96 
97 namespace android {
98 
99 static int initUsbCamera(               camera_hardware_t *camHal,
100                                         int width, int height,
101                                         int pixelFormat);
102 static int startUsbCamCapture(          camera_hardware_t *camHal);
103 static int stopUsbCamCapture(           camera_hardware_t *camHal);
104 static int initV4L2mmap(                camera_hardware_t *camHal);
105 static int unInitV4L2mmap(              camera_hardware_t *camHal);
106 static int launch_preview_thread(       camera_hardware_t *camHal);
107 static int launchTakePictureThread(     camera_hardware_t *camHal);
108 static int initDisplayBuffers(          camera_hardware_t *camHal);
109 static int deInitDisplayBuffers(        camera_hardware_t *camHal);
110 static int stopPreviewInternal(         camera_hardware_t *camHal);
111 static int get_buf_from_cam(            camera_hardware_t *camHal);
112 static int put_buf_to_cam(              camera_hardware_t *camHal);
113 static int prvwThreadTakePictureInternal(camera_hardware_t *camHal);
114 static int get_buf_from_display( camera_hardware_t *camHal, int *buffer_id);
115 static int put_buf_to_display(   camera_hardware_t *camHal, int buffer_id);
116 static int convert_data_frm_cam_to_disp(camera_hardware_t *camHal, int buffer_id);
117 static void * previewloop(void *);
118 static void * takePictureThread(void *);
119 static int convert_YUYV_to_420_NV12(char *in_buf, char *out_buf, int wd, int ht);
120 static int get_uvc_device(char *devname);
121 static int getPreviewCaptureFmt(camera_hardware_t *camHal);
122 static int allocate_ion_memory(QCameraHalMemInfo_t *mem_info, int ion_type);
123 static int deallocate_ion_memory(QCameraHalMemInfo_t *mem_info);
124 static int ioctlLoop(int fd, int ioctlCmd, void *args);
125 static int readFromFile(char* fileName, char* buffer, int bufferSize);
126 static int fileDump(const char* fileName, char* data, int length, int* frm_cnt);
127 static int encodeJpeg(                  camera_hardware_t *camHal);
128 void jpegEncodeCb   (jpeg_job_status_t status,
129                        uint8_t thumbnailDroppedFlag,
130                        uint32_t client_hdl,
131                        uint32_t jobId,
132                        uint8_t* out_data,
133                        uint32_t data_size,
134                        void *userData);
135 
136 /* HAL function implementation goes here*/
137 
138 /**
139  * The functions need to be provided by the camera HAL.
140  *
141  * If getNumberOfCameras() returns N, the valid cameraId for getCameraInfo()
142  * and openCameraHardware() is 0 to N-1.
143  */
144 
usbcam_get_number_of_cameras()145 extern "C" int usbcam_get_number_of_cameras()
146 {
147     /* TBR: This is hardcoded currently to 1 USB camera */
148     int numCameras = 1;
149     ALOGI("%s: E", __func__);
150     ALOGI("%s: X", __func__);
151 
152     return numCameras;
153 }
154 
usbcam_get_camera_info(int camera_id,struct camera_info * info)155 extern "C" int usbcam_get_camera_info(int camera_id, struct camera_info *info)
156 {
157     int rc = -1;
158     ALOGI("%s: E", __func__);
159 
160     /* TBR: This info is hardcoded currently irrespective of camera_id */
161     if(info) {
162         struct CameraInfo camInfo;
163         memset(&camInfo, -1, sizeof (struct CameraInfo));
164 
165         info->facing = CAMERA_FACING_FRONT;//CAMERA_FACING_BACK;
166         info->orientation = 0;
167         rc = 0;
168     }
169     ALOGI("%s: X", __func__);
170     return rc;
171 }
172 
173 /* HAL should return NULL handle if it fails to open camera hardware. */
usbcam_camera_device_open(const struct hw_module_t * module,const char * id,struct hw_device_t ** hw_device)174 extern "C" int  usbcam_camera_device_open(
175   const struct hw_module_t* module, const char* id,
176           struct hw_device_t** hw_device)
177 {
178     int rc = -1;
179     camera_device       *device = NULL;
180     camera_hardware_t   *camHal;
181     char                *dev_name;
182 
183     ALOGI("%s: E", __func__);
184 
185     /* initialize return handle value to NULL */
186     *hw_device = NULL;
187 
188     camHal = new camera_hardware_t();
189     if(!camHal) {
190 
191             ALOGE("%s:  end in no mem", __func__);
192             return -1;
193     }
194 
195     rc = usbCamInitDefaultParameters(camHal);
196     if(0 != rc)
197     {
198         ALOGE("%s: usbCamInitDefaultParameters error", __func__);
199         return rc;
200     }
201 #if CAPTURE
202 
203     dev_name = camHal->dev_name;
204 
205     rc = get_uvc_device(dev_name);
206     if(rc || *dev_name == '\0'){
207         ALOGE("%s: No UVC node found \n", __func__);
208         return -1;
209     }
210 
211     camHal->fd = open(dev_name, O_RDWR /* required */ | O_NONBLOCK, 0);
212 
213     if (camHal->fd <  0) {
214         ALOGE("%s: Cannot open '%s'", __func__, dev_name);
215         free(camHal);
216         rc = -1;
217     }else{
218         rc = 0;
219     }
220 
221 #else /* CAPTURE */
222     rc = 0;
223 #endif /* CAPTURE */
224 
225     device                  = &camHal->hw_dev;
226     device->common.close    = usbcam_close_camera_device;
227     device->ops             = &usbcam_camera_ops;
228     device->priv            = (void *)camHal;
229     *hw_device              = &(device->common);
230 
231     ALOGD("%s: camHal: %p", __func__, camHal);
232     ALOGI("%s: X %d", __func__, rc);
233 
234     return rc;
235 }
236 
usbcam_close_camera_device(hw_device_t * hw_dev)237 extern "C"  int usbcam_close_camera_device( hw_device_t *hw_dev)
238 {
239     ALOGI("%s: device =%p E", __func__, hw_dev);
240     int rc =  -1;
241     camera_device_t *device     = (camera_device_t *)hw_dev;
242 
243     if(device) {
244         camera_hardware_t *camHal   = (camera_hardware_t *)device->priv;
245         if(camHal) {
246             rc = close(camHal->fd);
247             if(rc < 0) {
248                 ALOGE("%s: close failed ", __func__);
249             }
250             camHal->fd = 0;
251             delete camHal;
252         }else{
253                 ALOGE("%s: camHal is NULL pointer ", __func__);
254         }
255     }
256     ALOGI("%s: X device =%p, rc = %d", __func__, hw_dev, rc);
257     return rc;
258 }
259 
usbcam_set_preview_window(struct camera_device * device,struct preview_stream_ops * window)260 int usbcam_set_preview_window(struct camera_device * device,
261         struct preview_stream_ops *window)
262 {
263     ALOGI("%s: E", __func__);
264     int rc = 0;
265     camera_hardware_t *camHal;
266 
267     VALIDATE_DEVICE_HDL(camHal, device, -1);
268     Mutex::Autolock autoLock(camHal->lock);
269 
270     /* if window is already set, then de-init previous buffers */
271     if(camHal->window){
272         rc = deInitDisplayBuffers(camHal);
273         if(rc < 0) {
274             ALOGE("%s: deInitDisplayBuffers returned error", __func__);
275         }
276     }
277     camHal->window = window;
278 
279     if(camHal->window){
280         rc = initDisplayBuffers(camHal);
281         if(rc < 0) {
282             ALOGE("%s: initDisplayBuffers returned error", __func__);
283         }
284     }
285     ALOGI("%s: X. rc = %d", __func__, rc);
286     return rc;
287 }
288 
usbcam_set_CallBacks(struct camera_device * device,camera_notify_callback notify_cb,camera_data_callback data_cb,camera_data_timestamp_callback data_cb_timestamp,camera_request_memory get_memory,void * user)289 void usbcam_set_CallBacks(struct camera_device * device,
290         camera_notify_callback notify_cb,
291         camera_data_callback data_cb,
292         camera_data_timestamp_callback data_cb_timestamp,
293         camera_request_memory get_memory,
294         void *user)
295 {
296     ALOGI("%s: E", __func__);
297     camera_hardware_t *camHal;
298 
299     if(device && device->priv){
300         camHal = (camera_hardware_t *)device->priv;
301     }else{
302         ALOGE("%s: Null device or device->priv", __func__);
303         return;
304     }
305 
306     Mutex::Autolock autoLock(camHal->lock);
307 
308     camHal->notify_cb           = notify_cb;
309     camHal->data_cb             = data_cb;
310     camHal->data_cb_timestamp   = data_cb_timestamp;
311     camHal->get_memory          = get_memory;
312     camHal->cb_ctxt             = user;
313 
314     ALOGI("%s: X", __func__);
315 }
316 
usbcam_enable_msg_type(struct camera_device * device,int32_t msg_type)317 void usbcam_enable_msg_type(struct camera_device * device, int32_t msg_type)
318 {
319     ALOGI("%s: E", __func__);
320     ALOGI("%s: msg_type: %d", __func__, msg_type);
321 
322     camera_hardware_t *camHal;
323 
324     if(device && device->priv){
325         camHal = (camera_hardware_t *)device->priv;
326     }else{
327         ALOGE("%s: Null device or device->priv", __func__);
328         return;
329     }
330 
331     Mutex::Autolock autoLock(camHal->lock);
332 
333     camHal->msgEnabledFlag |= msg_type;
334 
335     ALOGI("%s: X", __func__);
336 }
337 
usbcam_disable_msg_type(struct camera_device * device,int32_t msg_type)338 void usbcam_disable_msg_type(struct camera_device * device, int32_t msg_type)
339 {
340     ALOGI("%s: E", __func__);
341     ALOGI("%s: msg_type: %d", __func__, msg_type);
342 
343     camera_hardware_t *camHal;
344     if(device && device->priv){
345         camHal = (camera_hardware_t *)device->priv;
346     }else{
347         ALOGE("%s: Null device or device->priv", __func__);
348         return;
349     }
350 
351     Mutex::Autolock autoLock(camHal->lock);
352 
353     camHal->msgEnabledFlag &= ~msg_type;
354 
355     ALOGI("%s: X", __func__);
356 }
357 
usbcam_msg_type_enabled(struct camera_device * device,int32_t msg_type)358 int usbcam_msg_type_enabled(struct camera_device * device, int32_t msg_type)
359 {
360     ALOGI("%s: E", __func__);
361 
362     camera_hardware_t *camHal;
363     if(device && device->priv){
364         camHal = (camera_hardware_t *)device->priv;
365     }else{
366         ALOGE("%s: Null device or device->priv", __func__);
367         return -1;
368     }
369 
370     Mutex::Autolock autoLock(camHal->lock);
371 
372     ALOGI("%s: X", __func__);
373     return (camHal->msgEnabledFlag & msg_type);
374 }
375 
usbcam_start_preview(struct camera_device * device)376 int usbcam_start_preview(struct camera_device * device)
377 {
378     ALOGI("%s: E", __func__);
379 
380     int rc = -1;
381     camera_hardware_t *camHal = NULL;
382 
383     VALIDATE_DEVICE_HDL(camHal, device, -1);
384     Mutex::Autolock autoLock(camHal->lock);
385 
386     /* If preivew is already running, nothing to be done */
387     if(camHal->previewEnabledFlag){
388         ALOGI("%s: Preview is already running", __func__);
389         return 0;
390     }
391 
392 #if CAPTURE
393     rc = initUsbCamera(camHal, camHal->prevWidth,
394                         camHal->prevHeight, getPreviewCaptureFmt(camHal));
395     if(rc < 0) {
396         ALOGE("%s: Failed to intialize the device", __func__);
397     }else{
398         rc = startUsbCamCapture(camHal);
399         if(rc < 0) {
400             ALOGE("%s: Failed to startUsbCamCapture", __func__);
401         }else{
402             rc = launch_preview_thread(camHal);
403             if(rc < 0) {
404                 ALOGE("%s: Failed to launch_preview_thread", __func__);
405             }
406         }
407     }
408 #else /* CAPTURE */
409     rc = launch_preview_thread(camHal);
410     if(rc < 0) {
411         ALOGE("%s: Failed to launch_preview_thread", __func__);
412     }
413 #endif /* CAPTURE */
414     /* if no errors, then set the flag */
415     if(!rc)
416         camHal->previewEnabledFlag = 1;
417 
418     ALOGD("%s: X", __func__);
419     return rc;
420 }
421 
usbcam_stop_preview(struct camera_device * device)422 void usbcam_stop_preview(struct camera_device * device)
423 {
424     ALOGD("%s: E", __func__);
425 
426     int rc = 0;
427     camera_hardware_t *camHal;
428 
429     if(device && device->priv){
430         camHal = (camera_hardware_t *)device->priv;
431     }else{
432         ALOGE("%s: Null device or device->priv", __func__);
433         return;
434     }
435 
436     Mutex::Autolock autoLock(camHal->lock);
437 
438     rc = stopPreviewInternal(camHal);
439     if(rc)
440         ALOGE("%s: stopPreviewInternal returned error", __func__);
441 
442     ALOGI("%s: X", __func__);
443     return;
444 }
445 
446 /* This function is equivalent to is_preview_enabled */
usbcam_preview_enabled(struct camera_device * device)447 int usbcam_preview_enabled(struct camera_device * device)
448 {
449     ALOGI("%s: E", __func__);
450     camera_hardware_t *camHal;
451 
452     if(device && device->priv){
453         camHal = (camera_hardware_t *)device->priv;
454     }else{
455         ALOGE("%s: Null device or device->priv", __func__);
456         return -1;
457     }
458     Mutex::Autolock autoLock(camHal->lock);
459 
460     ALOGI("%s: X", __func__);
461     return camHal->previewEnabledFlag;
462 }
463 
464 /* TBD */
usbcam_store_meta_data_in_buffers(struct camera_device * device,int enable)465 int usbcam_store_meta_data_in_buffers(struct camera_device * device, int enable)
466 {
467     ALOGI("%s: E", __func__);
468     int rc = 0;
469 
470     ALOGI("%s: X", __func__);
471     return rc;
472 }
473 
474 /* TBD */
usbcam_start_recording(struct camera_device * device)475 int usbcam_start_recording(struct camera_device * device)
476 {
477     int rc = 0;
478     ALOGD("%s: E", __func__);
479 
480     ALOGD("%s: X", __func__);
481 
482     return rc;
483 }
484 
485 /* TBD */
usbcam_stop_recording(struct camera_device * device)486 void usbcam_stop_recording(struct camera_device * device)
487 {
488     ALOGD("%s: E", __func__);
489 
490     ALOGD("%s: X", __func__);
491 }
492 
493 /* TBD */
usbcam_recording_enabled(struct camera_device * device)494 int usbcam_recording_enabled(struct camera_device * device)
495 {
496     int rc = 0;
497     ALOGD("%s: E", __func__);
498 
499     ALOGD("%s: X", __func__);
500     return rc;
501 }
502 
503 /* TBD */
usbcam_release_recording_frame(struct camera_device * device,const void * opaque)504 void usbcam_release_recording_frame(struct camera_device * device,
505                 const void *opaque)
506 {
507     ALOGV("%s: E", __func__);
508 
509     ALOGD("%s: X", __func__);
510 }
511 
512 /* TBD */
usbcam_auto_focus(struct camera_device * device)513 int usbcam_auto_focus(struct camera_device * device)
514 {
515     ALOGD("%s: E", __func__);
516     int rc = 0;
517 
518     ALOGD("%s: X", __func__);
519     return rc;
520 }
521 
522 /* TBD */
usbcam_cancel_auto_focus(struct camera_device * device)523 int usbcam_cancel_auto_focus(struct camera_device * device)
524 {
525     int rc = 0;
526     ALOGD("%s: E", __func__);
527 
528     ALOGD("%s: X", __func__);
529     return rc;
530 }
531 
usbcam_take_picture(struct camera_device * device)532 int usbcam_take_picture(struct camera_device * device)
533 {
534     ALOGI("%s: E", __func__);
535     int rc = 0;
536     camera_hardware_t *camHal;
537 
538     VALIDATE_DEVICE_HDL(camHal, device, -1);
539 
540     Mutex::Autolock autoLock(camHal->lock);
541 
542     /* If take picture is already in progress, nothing t be done */
543     if(camHal->takePictInProgress){
544         ALOGI("%s: Take picture already in progress", __func__);
545         return 0;
546     }
547 
548     if(camHal->previewEnabledFlag)
549     {
550         rc = stopPreviewInternal(camHal);
551         if(rc){
552             ALOGE("%s: stopPreviewInternal returned error", __func__);
553         }
554         USB_CAM_CLOSE(camHal);
555         camHal->prvwStoppedForPicture = 1;
556     }
557     /* TBD: Need to handle any dependencies on video recording state */
558     rc = launchTakePictureThread(camHal);
559     if(rc)
560         ALOGE("%s: launchTakePictureThread error", __func__);
561 
562 #if 0
563     /* This implementation requests preview thread to take picture */
564     if(camHal->previewEnabledFlag)
565     {
566         camHal->prvwCmdPending++;
567         camHal->prvwCmd         = USB_CAM_PREVIEW_TAKEPIC;
568         ALOGD("%s: Take picture command set ", __func__);
569     }else{
570         ALOGE("%s: Take picture without preview started!", __func__);
571         rc = -1;
572     }
573 #endif
574 
575     if(!rc)
576         camHal->takePictInProgress = 1;
577 
578     ALOGI("%s: X", __func__);
579     return rc;
580 }
581 
582 /* TBD */
usbcam_cancel_picture(struct camera_device * device)583 int usbcam_cancel_picture(struct camera_device * device)
584 
585 {
586     ALOGI("%s: E", __func__);
587     int rc = 0;
588 
589     ALOGI("%s: X", __func__);
590     return rc;
591 }
592 
usbcam_set_parameters(struct camera_device * device,const char * params)593 int usbcam_set_parameters(struct camera_device * device, const char *params)
594 
595 {
596     ALOGI("%s: E", __func__);
597     int rc = 0;
598     camera_hardware_t *camHal;
599 
600     VALIDATE_DEVICE_HDL(camHal, device, -1);
601 
602     Mutex::Autolock autoLock(camHal->lock);
603 
604     rc = usbCamSetParameters(camHal, params);
605 
606     ALOGI("%s: X", __func__);
607     return rc;
608 }
609 
usbcam_get_parameters(struct camera_device * device)610 char* usbcam_get_parameters(struct camera_device * device)
611 {
612     char *parms;
613     ALOGI("%s: E", __func__);
614 
615     camera_hardware_t *camHal;
616     VALIDATE_DEVICE_HDL(camHal, device, NULL);
617 
618     Mutex::Autolock autoLock(camHal->lock);
619 
620     parms = usbCamGetParameters(camHal);
621 
622     ALOGI("%s: X", __func__);
623     return parms;
624 }
625 
usbcam_put_parameters(struct camera_device * device,char * parm)626 void usbcam_put_parameters(struct camera_device * device, char *parm)
627 
628 {
629     ALOGI("%s: E", __func__);
630 
631     camera_hardware_t *camHal;
632 
633     if(device && device->priv){
634         camHal = (camera_hardware_t *)device->priv;
635     }else{
636         ALOGE("%s: Null device or device->priv", __func__);
637         return;
638     }
639 
640     usbCamPutParameters(camHal, parm);
641 
642     ALOGI("%s: X", __func__);
643     return;
644 }
645 
646 /* TBD */
usbcam_send_command(struct camera_device * device,int32_t cmd,int32_t arg1,int32_t arg2)647 int usbcam_send_command(struct camera_device * device,
648             int32_t cmd, int32_t arg1, int32_t arg2)
649 {
650     int rc = 0;
651     ALOGI("%s: E", __func__);
652     ALOGI("%d", cmd);
653 
654     ALOGI("%s: X", __func__);
655     return rc;
656 }
657 
658 /* TBD */
usbcam_release(struct camera_device * device)659 void usbcam_release(struct camera_device * device)
660 {
661     ALOGI("%s: E", __func__);
662 #if 0
663     Mutex::Autolock l(&mLock);
664 
665     switch(mPreviewState) {
666     case QCAMERA_HAL_PREVIEW_STOPPED:
667         break;
668     case QCAMERA_HAL_PREVIEW_START:
669         break;
670     case QCAMERA_HAL_PREVIEW_STARTED:
671         stopPreviewInternal();
672     break;
673     case QCAMERA_HAL_RECORDING_STARTED:
674         stopRecordingInternal();
675         stopPreviewInternal();
676         break;
677     case QCAMERA_HAL_TAKE_PICTURE:
678         cancelPictureInternal();
679         break;
680     default:
681         break;
682     }
683     mPreviewState = QCAMERA_HAL_PREVIEW_STOPPED;
684 #endif
685     ALOGI("%s: X", __func__);
686 }
687 
688 /* TBD */
usbcam_dump(struct camera_device * device,int fd)689 int usbcam_dump(struct camera_device * device, int fd)
690 {
691     ALOGI("%s: E", __func__);
692     int rc = 0;
693 
694     ALOGI("%s: X", __func__);
695     return rc;
696 }
697 /*****************************************************************************
698 *  Static function definitions below
699 *****************************************************************************/
700 
701 /******************************************************************************/
702 /* No in place conversion supported. Output buffer and input MUST should be   */
703 /* different input buffer for a 4x4 pixel video                             ***/
704 /******                  YUYVYUYV          00 01 02 03 04 05 06 07 ************/
705 /******                  YUYVYUYV          08 09 10 11 12 13 14 15 ************/
706 /******                  YUYVYUYV          16 17 18 19 20 21 22 23 ************/
707 /******                  YUYVYUYV          24 25 26 27 28 29 30 31 ************/
708 /******************************************************************************/
709 /* output generated by this function ******************************************/
710 /************************** YYYY            00 02 04 06            ************/
711 /************************** YYYY            08 10 12 14            ************/
712 /************************** YYYY            16 18 20 22            ************/
713 /************************** YYYY            24 26 28 30            ************/
714 /************************** VUVU            03 01 07 05            ************/
715 /************************** VUVU            19 17 23 21            ************/
716 /******************************************************************************/
717 
convert_YUYV_to_420_NV12(char * in_buf,char * out_buf,int wd,int ht)718 static int convert_YUYV_to_420_NV12(char *in_buf, char *out_buf, int wd, int ht)
719 {
720     int rc =0;
721     int row, col, uv_row;
722 
723     ALOGD("%s: E", __func__);
724     /* Arrange Y */
725     for(row = 0; row < ht; row++)
726         for(col = 0; col < wd * 2; col += 2)
727         {
728             out_buf[row * wd + col / 2] = in_buf[row * wd * 2 + col];
729         }
730 
731     /* Arrange UV */
732     for(row = 0, uv_row = ht; row < ht; row += 2, uv_row++)
733         for(col = 1; col < wd * 2; col += 4)
734         {
735             out_buf[uv_row * wd + col / 2]= in_buf[row * wd * 2 + col + 2];
736             out_buf[uv_row * wd + col / 2 + 1]  = in_buf[row * wd * 2 + col];
737         }
738 
739     ALOGD("%s: X", __func__);
740     return rc;
741 }
742 
743 /******************************************************************************
744  * Function: initDisplayBuffers
745  * Description: This function initializes the preview buffers
746  *
747  * Input parameters:
748  *   camHal              - camera HAL handle
749  *
750  * Return values:
751  *      0   Success
752  *      -1  Error
753  * Notes: none
754  *****************************************************************************/
initDisplayBuffers(camera_hardware_t * camHal)755 static int initDisplayBuffers(camera_hardware_t *camHal)
756 {
757     preview_stream_ops    *mPreviewWindow;
758     struct ion_fd_data    ion_info_fd;
759     int                   numMinUndequeuedBufs = 0;
760     int                   rc = 0;
761     int                   gralloc_usage = 0;
762     int                   err;
763     int                   color=30;
764 
765     ALOGD("%s: E", __func__);
766 
767 #if DISPLAY
768     if(camHal == NULL) {
769         ALOGE("%s: camHal = NULL", __func__);
770         return -1;
771     }
772 
773     mPreviewWindow = camHal->window;
774     if(!mPreviewWindow) {
775         ALOGE("%s: mPreviewWindow = NULL", __func__);
776         return -1;
777     }
778 
779     /************************************************************************/
780     /* - get_min_undequeued_buffer_count                                    */
781     /* - set_buffer_count                                                   */
782     /* - set_buffers_geometry                                               */
783     /* - set_usage                                                          */
784     /* - dequeue all the display buffers                                    */
785     /* - cancel buffers: release w/o displaying                             */
786     /************************************************************************/
787 
788     /************************************************************************/
789     /* - get_min_undequeued_buffer_count                                    */
790     /************************************************************************/
791     if(mPreviewWindow->get_min_undequeued_buffer_count) {
792         rc = mPreviewWindow->get_min_undequeued_buffer_count(
793             mPreviewWindow, &numMinUndequeuedBufs);
794         if (0 != rc) {
795             ALOGE("%s: get_min_undequeued_buffer_count returned error", __func__);
796         }
797         else
798             ALOGD("%s: get_min_undequeued_buffer_count returned: %d ",
799                __func__, numMinUndequeuedBufs);
800     }
801     else
802         ALOGE("%s: get_min_undequeued_buffer_count is NULL pointer", __func__);
803 
804     /************************************************************************/
805     /* - set_buffer_count                                                   */
806     /************************************************************************/
807     if(mPreviewWindow->set_buffer_count) {
808         camHal->previewMem.buffer_count = numMinUndequeuedBufs
809                                             + PRVW_DISP_BUF_CNT;
810         rc = mPreviewWindow->set_buffer_count(
811             mPreviewWindow,
812             camHal->previewMem.buffer_count);
813         if (rc != 0) {
814             ALOGE("%s: set_buffer_count returned error", __func__);
815         }else
816             ALOGD("%s: set_buffer_count returned success", __func__);
817     }else
818         ALOGE("%s: set_buffer_count is NULL pointer", __func__);
819 
820     /************************************************************************/
821     /* - set_buffers_geometry                                               */
822     /************************************************************************/
823     if(mPreviewWindow->set_buffers_geometry) {
824         rc = mPreviewWindow->set_buffers_geometry(mPreviewWindow,
825                                                 camHal->dispWidth,
826                                                 camHal->dispHeight,
827                                                 camHal->dispFormat);
828         if (rc != 0) {
829             ALOGE("%s: set_buffers_geometry returned error. %s (%d)",
830                __func__, strerror(-rc), -rc);
831         }else
832             ALOGD("%s: set_buffers_geometry returned success", __func__);
833     }else
834         ALOGE("%s: set_buffers_geometry is NULL pointer", __func__);
835 
836     /************************************************************************/
837     /* - set_usage                                                          */
838     /************************************************************************/
839     gralloc_usage = CAMERA_GRALLOC_HEAP_ID | CAMERA_GRALLOC_FALLBACK_HEAP_ID |
840                     GRALLOC_USAGE_PRIVATE_UNCACHED;
841 
842     if(mPreviewWindow->set_usage) {
843         rc = mPreviewWindow->set_usage(mPreviewWindow, gralloc_usage);
844         if (rc != 0) {
845             ALOGE("%s: set_usage returned error", __func__);
846         }else
847             ALOGD("%s: set_usage returned success", __func__);
848     }
849     else
850         ALOGE("%s: set_usage is NULL pointer", __func__);
851 
852     /************************************************************************/
853     /* - dequeue all the display buffers                                    */
854     /************************************************************************/
855     for (int cnt = 0; cnt < camHal->previewMem.buffer_count; cnt++) {
856         int stride;
857         err = mPreviewWindow->dequeue_buffer(
858                 mPreviewWindow,
859                 &camHal->previewMem.buffer_handle[cnt],
860                 &camHal->previewMem.stride[cnt]);
861         if(!err) {
862             ALOGD("%s: dequeue buf: %p\n",
863                  __func__, camHal->previewMem.buffer_handle[cnt]);
864 
865             if(mPreviewWindow->lock_buffer) {
866                 err = mPreviewWindow->lock_buffer(
867                     mPreviewWindow,
868                     camHal->previewMem.buffer_handle[cnt]);
869                 ALOGD("%s: mPreviewWindow->lock_buffer success",
870                      __func__);
871             }
872 
873             // lock the buffer using genlock
874             ALOGD("%s: camera call genlock_lock, hdl=%p",
875                 __func__, (*camHal->previewMem.buffer_handle[cnt]));
876 
877             if (GENLOCK_NO_ERROR !=
878                 genlock_lock_buffer(
879                     (native_handle_t *) (*camHal->previewMem.buffer_handle[cnt]),
880                     GENLOCK_WRITE_LOCK, GENLOCK_MAX_TIMEOUT))
881             {
882                 ALOGE("%s: genlock_lock_buffer(WRITE) failed",
883                     __func__);
884                 camHal->previewMem.local_flag[cnt] = BUFFER_UNLOCKED;
885             }else {
886                 ALOGD("%s: genlock_lock_buffer hdl =%p",
887                   __func__, *camHal->previewMem.buffer_handle[cnt]);
888                 camHal->previewMem.local_flag[cnt] = BUFFER_LOCKED;
889             }
890 
891             /* Store this buffer details in the context */
892             camHal->previewMem.private_buffer_handle[cnt] =
893                 (struct private_handle_t *) (*camHal->previewMem.buffer_handle[cnt]);
894 
895             ALOGD("%s: idx = %d, fd = %d, size = %d, offset = %d", __func__,
896                 cnt, camHal->previewMem.private_buffer_handle[cnt]->fd,
897                 camHal->previewMem.private_buffer_handle[cnt]->size,
898                 camHal->previewMem.private_buffer_handle[cnt]->offset);
899 
900             camHal->previewMem.camera_memory[cnt] =
901                 camHal->get_memory(
902                     camHal->previewMem.private_buffer_handle[cnt]->fd,
903                     camHal->previewMem.private_buffer_handle[cnt]->size,
904                     1, camHal->cb_ctxt);
905 
906             ALOGD("%s: data = %p, size = %d, handle = %p", __func__,
907                 camHal->previewMem.camera_memory[cnt]->data,
908                 camHal->previewMem.camera_memory[cnt]->size,
909                 camHal->previewMem.camera_memory[cnt]->handle);
910 
911 #ifdef USE_ION
912             /* In case of ION usage, open ION fd */
913             camHal->previewMem.mem_info[cnt].main_ion_fd =
914                                                 open("/dev/ion", O_RDONLY);
915             if (camHal->previewMem.mem_info[cnt].main_ion_fd < 0) {
916                 ALOGE("%s: failed: could not open ion device\n", __func__);
917             }else{
918                 memset(&ion_info_fd, 0, sizeof(ion_info_fd));
919                 ion_info_fd.fd =
920                     camHal->previewMem.private_buffer_handle[cnt]->fd;
921                 if (ioctl(camHal->previewMem.mem_info[cnt].main_ion_fd,
922                           ION_IOC_IMPORT, &ion_info_fd) < 0) {
923                     ALOGE("ION import failed\n");
924                 }
925             }
926             camHal->previewMem.mem_info[cnt].fd =
927                 camHal->previewMem.private_buffer_handle[cnt]->fd;
928             camHal->previewMem.mem_info[cnt].size =
929                 camHal->previewMem.private_buffer_handle[cnt]->size;
930             camHal->previewMem.mem_info[cnt].handle = ion_info_fd.handle;
931 
932 #endif
933         }
934         else
935             ALOGE("%s: dequeue buf %d failed \n", __func__, cnt);
936     }
937     /************************************************************************/
938     /* - cancel buffers: queue w/o displaying                               */
939     /************************************************************************/
940     for (int cnt = 0; cnt < camHal->previewMem.buffer_count; cnt++) {
941         if (GENLOCK_FAILURE == genlock_unlock_buffer(
942                 (native_handle_t *)(*(camHal->previewMem.buffer_handle[cnt])))){
943             ALOGE("%s: genlock_unlock_buffer failed: hdl =%p", __func__,
944                 (*(camHal->previewMem.buffer_handle[cnt])) );
945         } else {
946             camHal->previewMem.local_flag[cnt] = BUFFER_UNLOCKED;
947             ALOGD("%s: genlock_unlock_buffer success: hdl = %p",
948                __func__, (*(camHal->previewMem.buffer_handle[cnt])));
949         }
950 
951         err = mPreviewWindow->cancel_buffer(mPreviewWindow,
952             (buffer_handle_t *)camHal->previewMem.buffer_handle[cnt]);
953         if(!err) {
954             ALOGD("%s: cancel_buffer successful: %p\n",
955                  __func__, camHal->previewMem.buffer_handle[cnt]);
956         }else
957             ALOGE("%s: cancel_buffer failed: %p\n", __func__,
958                  camHal->previewMem.buffer_handle[cnt]);
959     }
960 #else
961     rc = 0;
962 #endif /* #if DISPLAY */
963     ALOGD("%s: X", __func__);
964     return rc;
965 }
966 
967 /******************************************************************************
968  * Function: deInitDisplayBuffers
969  * Description: This function de-initializes all the display buffers allocated
970  *              in initDisplayBuffers
971  *
972  * Input parameters:
973  *   camHal              - camera HAL handle
974  *
975  * Return values:
976  *      0   Success
977  *      -1  Error
978  * Notes: none
979  *****************************************************************************/
deInitDisplayBuffers(camera_hardware_t * camHal)980 static int deInitDisplayBuffers(camera_hardware_t *camHal)
981 {
982     int rc = 0;
983     preview_stream_ops    *previewWindow;
984 
985     ALOGD("%s: E", __func__);
986 
987     if(!camHal || !camHal->window) {
988       ALOGE("%s: camHal = NULL or window = NULL ", __func__);
989       return -1;
990     }
991 
992     previewWindow = camHal->window;
993 
994     /************************************************************************/
995     /* - Release all buffers that were acquired using get_memory            */
996     /* - If using ION memory, free ION related resources                    */
997     /* - genUnlock if buffer is genLocked                                   */
998     /* - Cancel buffers: queue w/o displaying                               */
999     /************************************************************************/
1000 
1001 #if DISPLAY
1002     for (int cnt = 0; cnt < camHal->previewMem.buffer_count; cnt++) {
1003 
1004         /* Release all buffers that were acquired using get_memory */
1005         camHal->previewMem.camera_memory[cnt]->release(
1006                                 camHal->previewMem.camera_memory[cnt]);
1007 
1008 #ifdef USE_ION
1009         /* If using ION memory, free ION related resources */
1010         struct ion_handle_data ion_handle;
1011         memset(&ion_handle, 0, sizeof(ion_handle));
1012         ion_handle.handle = camHal->previewMem.mem_info[cnt].handle;
1013         if (ioctl(camHal->previewMem.mem_info[cnt].main_ion_fd,
1014             ION_IOC_FREE, &ion_handle) < 0) {
1015             ALOGE("%s: ion free failed\n", __func__);
1016         }
1017         close(camHal->previewMem.mem_info[cnt].main_ion_fd);
1018 #endif
1019 
1020         /* genUnlock if buffer is genLocked */
1021         if(camHal->previewMem.local_flag[cnt] == BUFFER_LOCKED){
1022             if (GENLOCK_FAILURE == genlock_unlock_buffer(
1023                     (native_handle_t *)(*(camHal->previewMem.buffer_handle[cnt])))){
1024                 ALOGE("%s: genlock_unlock_buffer failed: hdl =%p", __func__,
1025                     (*(camHal->previewMem.buffer_handle[cnt])) );
1026             } else {
1027                 camHal->previewMem.local_flag[cnt] = BUFFER_UNLOCKED;
1028                 ALOGD("%s: genlock_unlock_buffer success: hdl = %p",
1029                    __func__, (*(camHal->previewMem.buffer_handle[cnt])));
1030             }
1031         }
1032         /* cancel buffers: enqueue w/o displaying */
1033         rc = previewWindow->cancel_buffer(previewWindow,
1034             (buffer_handle_t *)camHal->previewMem.buffer_handle[cnt]);
1035         if(!rc) {
1036             ALOGD("%s: cancel_buffer successful: %p\n",
1037                  __func__, camHal->previewMem.buffer_handle[cnt]);
1038         }else
1039             ALOGE("%s: cancel_buffer failed: %p\n", __func__,
1040                  camHal->previewMem.buffer_handle[cnt]);
1041     }
1042 #endif /* #if DISPLAY */
1043     memset(&camHal->previewMem, 0, sizeof(camHal->previewMem));
1044 
1045     ALOGD("%s: X", __func__);
1046     return rc;
1047 }
1048 
1049 /******************************************************************************
1050  * Function: getPreviewCaptureFmt
1051  * Description: This function implements the logic to decide appropriate
1052  *              capture format from the USB camera
1053  *
1054  * Input parameters:
1055  *   camHal              - camera HAL handle
1056  *
1057  * Return values:
1058  *      Capture format. Default (V4L2_PIX_FMT_MJPEG)
1059  *
1060  * Notes: none
1061  *****************************************************************************/
getPreviewCaptureFmt(camera_hardware_t * camHal)1062 static int getPreviewCaptureFmt(camera_hardware_t *camHal)
1063 {
1064     int     i = 0, mjpegSupported = 0, h264Supported = 0;
1065     struct v4l2_fmtdesc fmtdesc;
1066 
1067     memset(&fmtdesc, 0, sizeof(v4l2_fmtdesc));
1068 
1069     /************************************************************************/
1070     /* - Query the camera for all supported formats                         */
1071     /* - Based on the resolution, pick an apporpriate format                */
1072     /************************************************************************/
1073 
1074     /************************************************************************/
1075     /* - Query the camera for all supported formats                         */
1076     /************************************************************************/
1077     for(i = 0; ; i++) {
1078         fmtdesc.index = i;
1079         fmtdesc.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1080         if (-1 == ioctlLoop(camHal->fd, VIDIOC_ENUM_FMT, &fmtdesc)) {
1081             if (EINVAL == errno) {
1082                 ALOGI("%s: Queried all formats till index %d\n", __func__, i);
1083                 break;
1084             } else {
1085                 ALOGE("%s: VIDIOC_ENUM_FMT failed", __func__);
1086             }
1087         }
1088         if(V4L2_PIX_FMT_MJPEG == fmtdesc.pixelformat){
1089             mjpegSupported = 1;
1090             ALOGI("%s: V4L2_PIX_FMT_MJPEG is supported", __func__ );
1091         }
1092         if(V4L2_PIX_FMT_H264 == fmtdesc.pixelformat){
1093             h264Supported = 1;
1094             ALOGI("%s: V4L2_PIX_FMT_H264 is supported", __func__ );
1095         }
1096 
1097     }
1098 
1099     /************************************************************************/
1100     /* - Based on the resolution, pick an apporpriate format                */
1101     /************************************************************************/
1102     //V4L2_PIX_FMT_MJPEG; V4L2_PIX_FMT_YUYV; V4L2_PIX_FMT_H264 = 0x34363248;
1103     camHal->captureFormat = V4L2_PIX_FMT_YUYV;
1104     if(camHal->prevWidth > 640){
1105         if(1 == mjpegSupported)
1106             camHal->captureFormat = V4L2_PIX_FMT_MJPEG;
1107         else if(1 == h264Supported)
1108             camHal->captureFormat = V4L2_PIX_FMT_H264;
1109     }
1110     ALOGI("%s: Capture format chosen: 0x%x. 0x%x:YUYV. 0x%x:MJPEG. 0x%x: H264",
1111         __func__, camHal->captureFormat, V4L2_PIX_FMT_YUYV,
1112         V4L2_PIX_FMT_MJPEG, V4L2_PIX_FMT_H264);
1113 
1114     return camHal->captureFormat;
1115 }
1116 
1117 /******************************************************************************
1118  * Function: getMjpegdOutputFormat
1119  * Description: This function maps display pixel format enum to JPEG output
1120  *              format enum
1121  *
1122  * Input parameters:
1123  *   dispFormat              - Display pixel format
1124  *
1125  * Return values:
1126  *      (int)mjpegOutputFormat
1127  *
1128  * Notes: none
1129  *****************************************************************************/
getMjpegdOutputFormat(int dispFormat)1130 static int getMjpegdOutputFormat(int dispFormat)
1131 {
1132     int mjpegOutputFormat = YCRCBLP_H2V2;
1133 
1134     if(HAL_PIXEL_FORMAT_YCrCb_420_SP == dispFormat)
1135         mjpegOutputFormat = YCRCBLP_H2V2;
1136 
1137     return mjpegOutputFormat;
1138 }
1139 
1140 /******************************************************************************
1141  * Function: ioctlLoop
1142  * Description: This function is a blocking call around ioctl
1143  *
1144  * Input parameters:
1145  *   fd             - IOCTL fd
1146  *   ioctlCmd       - IOCTL command
1147  *   args           - IOCTL arguments
1148  *
1149  * Return values:
1150  *      (int)mjpegOutputFormat
1151  *
1152  * Notes: none
1153  *****************************************************************************/
ioctlLoop(int fd,int ioctlCmd,void * args)1154 static int ioctlLoop(int fd, int ioctlCmd, void *args)
1155 {
1156     int rc = -1;
1157 
1158     while(1)
1159     {
1160         rc = ioctl(fd, ioctlCmd, args);
1161         if(!((-1 == rc) && (EINTR == errno)))
1162             break;
1163     }
1164     return rc;
1165 }
1166 
1167 /******************************************************************************
1168  * Function: initV4L2mmap
1169  * Description: This function requests for V4L2 driver allocated buffers
1170  *
1171  * Input parameters:
1172  *   camHal              - camera HAL handle
1173  *
1174  * Return values:
1175  *   0      No error
1176  *   -1     Error
1177  *
1178  * Notes: none
1179  *****************************************************************************/
initV4L2mmap(camera_hardware_t * camHal)1180 static int initV4L2mmap(camera_hardware_t *camHal)
1181 {
1182     int rc = -1;
1183     struct v4l2_requestbuffers  reqBufs;
1184     struct v4l2_buffer          tempBuf;
1185 
1186     ALOGD("%s: E", __func__);
1187     memset(&reqBufs, 0, sizeof(v4l2_requestbuffers));
1188     reqBufs.type    = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1189     reqBufs.memory  = V4L2_MEMORY_MMAP;
1190     reqBufs.count   = PRVW_CAP_BUF_CNT;
1191 
1192     if (-1 == ioctlLoop(camHal->fd, VIDIOC_REQBUFS, &reqBufs)) {
1193         if (EINVAL == errno) {
1194             ALOGE("%s: does not support memory mapping\n", __func__);
1195         } else {
1196             ALOGE("%s: VIDIOC_REQBUFS failed", __func__);
1197         }
1198     }
1199     ALOGD("%s: VIDIOC_REQBUFS success", __func__);
1200 
1201     if (reqBufs.count < PRVW_CAP_BUF_CNT) {
1202         ALOGE("%s: Insufficient buffer memory on\n", __func__);
1203     }
1204 
1205     camHal->buffers =
1206         ( bufObj* ) calloc(reqBufs.count, sizeof(bufObj));
1207 
1208     if (!camHal->buffers) {
1209         ALOGE("%s: Out of memory\n", __func__);
1210     }
1211 
1212     /* Store the indexes in the context. Useful during releasing */
1213     for (camHal->n_buffers = 0;
1214          camHal->n_buffers < reqBufs.count;
1215          camHal->n_buffers++) {
1216 
1217         memset(&tempBuf, 0, sizeof(tempBuf));
1218 
1219         tempBuf.index       = camHal->n_buffers;
1220         tempBuf.type        = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1221         tempBuf.memory      = V4L2_MEMORY_MMAP;
1222 
1223         if (-1 == ioctlLoop(camHal->fd, VIDIOC_QUERYBUF, &tempBuf))
1224             ALOGE("%s: VIDIOC_QUERYBUF failed", __func__);
1225 
1226         ALOGD("%s: VIDIOC_QUERYBUF success", __func__);
1227 
1228         camHal->buffers[camHal->n_buffers].len = tempBuf.length;
1229         camHal->buffers[camHal->n_buffers].data =
1230         mmap(NULL /* start anywhere */,
1231                   tempBuf.length,
1232                   PROT_READ | PROT_WRITE,
1233                   MAP_SHARED,
1234                   camHal->fd, tempBuf.m.offset);
1235 
1236         if (MAP_FAILED == camHal->buffers[camHal->n_buffers].data)
1237             ALOGE("%s: mmap failed", __func__);
1238     }
1239     ALOGD("%s: X", __func__);
1240     return 0;
1241 }
1242 
1243 /******************************************************************************
1244  * Function: unInitV4L2mmap
1245  * Description: This function unmaps the V4L2 driver buffers
1246  *
1247  * Input parameters:
1248  *   camHal              - camera HAL handle
1249  *
1250  * Return values:
1251  *   0      No error
1252  *   -1     Error
1253  *
1254  * Notes: none
1255  *****************************************************************************/
unInitV4L2mmap(camera_hardware_t * camHal)1256 static int unInitV4L2mmap(camera_hardware_t *camHal)
1257 {
1258     int i, rc = 0;
1259     ALOGD("%s: E", __func__);
1260 
1261     for (i = 0; i < camHal->n_buffers; i++)
1262         if (-1 == munmap(camHal->buffers[i].data, camHal->buffers[i].len)){
1263             ALOGE("%s: munmap failed for buffer: %d", __func__, i);
1264             rc = -1;
1265         }
1266 
1267     ALOGD("%s: X", __func__);
1268     return rc;
1269 }
1270 
1271 /******************************************************************************
1272  * Function: initUsbCamera
1273  * Description: This function sets the resolution and pixel format of the
1274  *              USB camera
1275  *
1276  * Input parameters:
1277  *  camHal              - camera HAL handle
1278  *  width               - picture width in pixels
1279  *  height              - picture height in pixels
1280  *  pixelFormat         - capture format for the camera
1281  *
1282  * Return values:
1283  *   0      No error
1284  *   -1     Error
1285  *
1286  * Notes: none
1287  *****************************************************************************/
initUsbCamera(camera_hardware_t * camHal,int width,int height,int pixelFormat)1288 static int initUsbCamera(camera_hardware_t *camHal, int width, int height,
1289                         int pixelFormat)
1290 {
1291     int     rc = -1;
1292     struct  v4l2_capability     cap;
1293     struct  v4l2_cropcap        cropcap;
1294     struct  v4l2_crop           crop;
1295     struct  v4l2_format         v4l2format;
1296     unsigned int                min;
1297 
1298     ALOGI("%s: E", __func__);
1299 
1300     if (-1 == ioctlLoop(camHal->fd, VIDIOC_QUERYCAP, &cap)) {
1301         if (EINVAL == errno) {
1302             ALOGE( "%s: This is not V4L2 device\n", __func__);
1303             return -1;
1304         } else {
1305             ALOGE("%s: VIDIOC_QUERYCAP errno: %d", __func__, errno);
1306         }
1307     }
1308     ALOGD("%s: VIDIOC_QUERYCAP success", __func__);
1309 
1310     if (!(cap.capabilities & V4L2_CAP_VIDEO_CAPTURE)) {
1311         ALOGE("%s: This is not video capture device\n", __func__);
1312         return -1;
1313     }
1314 
1315     if (!(cap.capabilities & V4L2_CAP_STREAMING)) {
1316         ALOGE("%s: This does not support streaming i/o\n", __func__);
1317         return -1;
1318     }
1319 
1320     /* Select video input, video standard and tune here. */
1321     memset(&cropcap, 0, sizeof(cropcap));
1322 
1323     cropcap.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1324 
1325     if (0 == ioctlLoop(camHal->fd, VIDIOC_CROPCAP, &cropcap)) {
1326 
1327         /* reset to default */
1328         crop.c = cropcap.defrect;
1329         crop.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1330 
1331         ALOGD("%s: VIDIOC_CROPCAP success", __func__);
1332         if (-1 == ioctlLoop(camHal->fd, VIDIOC_S_CROP, &crop)) {
1333         switch (errno) {
1334             case EINVAL:
1335             /* Cropping not supported. */
1336                 break;
1337             default:
1338             /* Errors ignored. */
1339                 break;
1340             }
1341         }
1342                 ALOGD("%s: VIDIOC_S_CROP success", __func__);
1343 
1344     } else {
1345         /* Errors ignored. */
1346                ALOGE("%s: VIDIOC_S_CROP failed", __func__);
1347     }
1348 
1349 
1350     memset(&v4l2format, 0, sizeof(v4l2format));
1351 
1352     v4l2format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1353     {
1354         v4l2format.fmt.pix.field       = V4L2_FIELD_NONE;
1355         v4l2format.fmt.pix.pixelformat = pixelFormat;
1356         v4l2format.fmt.pix.width       = width;
1357         v4l2format.fmt.pix.height      = height;
1358 
1359         if (-1 == ioctlLoop(camHal->fd, VIDIOC_S_FMT, &v4l2format))
1360         {
1361             ALOGE("%s: VIDIOC_S_FMT failed", __func__);
1362             return -1;
1363         }
1364         ALOGD("%s: VIDIOC_S_FMT success", __func__);
1365 
1366         /* Note VIDIOC_S_FMT may change width and height. */
1367     }
1368 
1369     /* TBR: In case of user pointer buffers, v4l2format.fmt.pix.sizeimage */
1370     /* might have to be calculated as per V4L2 sample application due to */
1371     /* open source driver bug */
1372 
1373     rc = initV4L2mmap(camHal);
1374     ALOGI("%s: X", __func__);
1375     return rc;
1376 }
1377 
1378 /******************************************************************************
1379  * Function: startUsbCamCapture
1380  * Description: This function queues buffer objects to the driver and sends
1381  *              STREAM ON command to the USB camera driver
1382  *
1383  * Input parameters:
1384  *   camHal              - camera HAL handle
1385  *
1386  * Return values:
1387  *   0      No error
1388  *   -1     Error
1389  *
1390  * Notes: none
1391  *****************************************************************************/
startUsbCamCapture(camera_hardware_t * camHal)1392 static int startUsbCamCapture(camera_hardware_t *camHal)
1393 {
1394     int         rc = -1;
1395     unsigned    int i;
1396     enum        v4l2_buf_type   v4l2BufType;
1397     ALOGD("%s: E", __func__);
1398 
1399     for (i = 0; i < camHal->n_buffers; ++i) {
1400         struct v4l2_buffer tempBuf;
1401 
1402         memset(&tempBuf, 0, sizeof(tempBuf));
1403         tempBuf.type    = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1404         tempBuf.memory  = V4L2_MEMORY_MMAP;
1405         tempBuf.index   = i;
1406 
1407         if (-1 == ioctlLoop(camHal->fd, VIDIOC_QBUF, &tempBuf))
1408             ALOGE("%s: VIDIOC_QBUF for %d buffer failed", __func__, i);
1409         else
1410             ALOGD("%s: VIDIOC_QBUF for %d buffer success", __func__, i);
1411     }
1412 
1413     v4l2BufType = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1414     if (-1 == ioctlLoop(camHal->fd, VIDIOC_STREAMON, &v4l2BufType))
1415         ALOGE("%s: VIDIOC_STREAMON failed", __func__);
1416     else
1417     {
1418         ALOGD("%s: VIDIOC_STREAMON success", __func__);
1419         rc = 0;
1420     }
1421 
1422     ALOGD("%s: X", __func__);
1423     return rc;
1424 }
1425 
1426 /******************************************************************************
1427  * Function: stopUsbCamCapture
1428  * Description: This function sends STREAM OFF command to the USB camera driver
1429  *
1430  * Input parameters:
1431  *   camHal              - camera HAL handle
1432  *
1433  * Return values:
1434  *   0      No error
1435  *   -1     Error
1436  *
1437  * Notes: none
1438  *****************************************************************************/
stopUsbCamCapture(camera_hardware_t * camHal)1439 static int stopUsbCamCapture(camera_hardware_t *camHal)
1440 {
1441     int         rc = -1;
1442     unsigned    int i;
1443     enum        v4l2_buf_type   v4l2BufType;
1444     ALOGD("%s: E", __func__);
1445 
1446     if(!camHal->fd){
1447         ALOGE("%s: camHal->fd = NULL ", __func__);
1448         return -1;
1449     }
1450     v4l2BufType = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1451     if (-1 == ioctlLoop(camHal->fd, VIDIOC_STREAMOFF, &v4l2BufType)){
1452         ALOGE("%s: VIDIOC_STREAMOFF failed", __func__);
1453         rc = -1;
1454     }else{
1455         ALOGD("%s: VIDIOC_STREAMOFF success", __func__);
1456         rc = 0;
1457     }
1458 
1459     ALOGD("%s: X", __func__);
1460     return rc;
1461 }
1462 
1463 /******************************************************************************
1464  * Function: stopPreviewInternal
1465  * Description: This function sends EXIT command to prview loop thread,
1466  *              stops usb camera capture and uninitializes MMAP. This function
1467  *              assumes that calling function has locked camHal->lock
1468  *
1469  * Input parameters:
1470  *   camHal              - camera HAL handle
1471  *
1472  * Return values:
1473  *   0      No error
1474  *   -1     Error
1475  *
1476  * Notes: none
1477  *****************************************************************************/
stopPreviewInternal(camera_hardware_t * camHal)1478 static int stopPreviewInternal(camera_hardware_t *camHal)
1479 {
1480     int rc = 0;
1481     ALOGD("%s: E", __func__);
1482 
1483     if(camHal->previewEnabledFlag)
1484     {
1485         camHal->prvwCmdPending++;
1486         camHal->prvwCmd         = USB_CAM_PREVIEW_EXIT;
1487 
1488         /* yield lock while waiting for the preview thread to exit */
1489         camHal->lock.unlock();
1490         if(pthread_join(camHal->previewThread, NULL)){
1491             ALOGE("%s: Error in pthread_join preview thread", __func__);
1492         }
1493         camHal->lock.lock();
1494 
1495         if(stopUsbCamCapture(camHal)){
1496             ALOGE("%s: Error in stopUsbCamCapture", __func__);
1497             rc = -1;
1498         }
1499         if(unInitV4L2mmap(camHal)){
1500             ALOGE("%s: Error in stopUsbCamCapture", __func__);
1501             rc = -1;
1502         }
1503         camHal->previewEnabledFlag = 0;
1504     }
1505 
1506     ALOGD("%s: X, rc: %d", __func__, rc);
1507     return rc;
1508 }
1509 #if 1
1510 /******************************************************************************
1511  * Function: prvwThreadTakePictureInternal
1512  * Description: This function processes one camera frame to get JPEG encoded
1513  *              picture.
1514  *
1515  * Input parameters:
1516  *   camHal              - camera HAL handle
1517  *
1518  * Return values:
1519  *   0      No error
1520  *   -1     Error
1521  *
1522  * Notes: none
1523  *****************************************************************************/
prvwThreadTakePictureInternal(camera_hardware_t * camHal)1524 static int prvwThreadTakePictureInternal(camera_hardware_t *camHal)
1525 {
1526     int     rc = 0;
1527     QCameraHalMemInfo_t     *mem_info;
1528     ALOGD("%s: E", __func__);
1529 
1530     /************************************************************************/
1531     /* - If requested for shutter notfication, callback                     */
1532     /* - Dequeue capture buffer from USB camera                             */
1533     /* - Send capture buffer to JPEG encoder for JPEG compression           */
1534     /* - If jpeg frames callback is requested, callback with jpeg buffers   */
1535     /* - Enqueue capture buffer back to USB camera                          */
1536     /************************************************************************/
1537 
1538     /************************************************************************/
1539     /* - If requested for shutter notfication, callback                     */
1540     /************************************************************************/
1541     if (camHal->msgEnabledFlag & CAMERA_MSG_SHUTTER){
1542         camHal->lock.unlock();
1543         camHal->notify_cb(CAMERA_MSG_SHUTTER, 0, 0, camHal->cb_ctxt);
1544         camHal->lock.lock();
1545     }
1546 
1547 #if CAPTURE
1548     /************************************************************************/
1549     /* - Dequeue capture buffer from USB camera                             */
1550     /************************************************************************/
1551     if (0 == get_buf_from_cam(camHal))
1552         ALOGD("%s: get_buf_from_cam success", __func__);
1553     else
1554         ALOGE("%s: get_buf_from_cam error", __func__);
1555 #endif
1556 
1557     /************************************************************************/
1558     /* - Send capture buffer to JPEG encoder for JPEG compression           */
1559     /************************************************************************/
1560     /* Optimization: If camera capture is JPEG format, need not compress! */
1561     /* instead, just data copy from capture buffer to picture buffer */
1562     if(V4L2_PIX_FMT_MJPEG == camHal->captureFormat){
1563         /* allocate heap memory for JPEG output */
1564         mem_info = &camHal->pictMem.mem_info[0];
1565         mem_info->size = camHal->curCaptureBuf.bytesused;
1566         /* TBD: allocate_ion_memory
1567         rc = QCameraHardwareInterface::allocate_ion_memory(mem_info,
1568                             ((0x1 << CAMERA_ZSL_ION_HEAP_ID) |
1569                             (0x1 << CAMERA_ZSL_ION_FALLBACK_HEAP_ID)));
1570         */
1571         if(rc)
1572             ALOGE("%s: ION memory allocation failed", __func__);
1573 
1574         camHal->pictMem.camera_memory[0] = camHal->get_memory(
1575                             mem_info->fd, mem_info->size, 1, camHal->cb_ctxt);
1576         if(!camHal->pictMem.camera_memory[0])
1577             ALOGE("%s: get_mem failed", __func__);
1578 
1579         memcpy( camHal->pictMem.camera_memory[0]->data,
1580                 (char *)camHal->buffers[camHal->curCaptureBuf.index].data,
1581                 camHal->curCaptureBuf.bytesused);
1582     }
1583 
1584     /************************************************************************/
1585     /* - If jpeg frames callback is requested, callback with jpeg buffers   */
1586     /************************************************************************/
1587     if ((camHal->msgEnabledFlag & CAMERA_MSG_COMPRESSED_IMAGE) &&
1588             (camHal->data_cb)){
1589         camHal->lock.unlock();
1590         camHal->data_cb(CAMERA_MSG_COMPRESSED_IMAGE,
1591                         camHal->pictMem.camera_memory[0],
1592                         0, NULL, camHal->cb_ctxt);
1593         camHal->lock.lock();
1594     }
1595     /* release heap memory after the call back */
1596     if(camHal->pictMem.camera_memory[0])
1597         camHal->pictMem.camera_memory[0]->release(
1598             camHal->pictMem.camera_memory[0]);
1599 
1600     /* TBD: deallocate_ion_memory */
1601     //rc = QCameraHardwareInterface::deallocate_ion_memory(mem_info);
1602     if(rc)
1603         ALOGE("%s: ION memory de-allocation failed", __func__);
1604 
1605 #if CAPTURE
1606     /************************************************************************/
1607     /* - Enqueue capture buffer back to USB camera                          */
1608     /************************************************************************/
1609        if(0 == put_buf_to_cam(camHal)) {
1610             ALOGD("%s: put_buf_to_cam success", __func__);
1611         }
1612         else
1613             ALOGE("%s: put_buf_to_cam error", __func__);
1614 #endif
1615 
1616     ALOGD("%s: X, rc: %d", __func__, rc);
1617     return rc;
1618 }
1619 #endif //#if 0
1620 /******************************************************************************
1621  * Function: cache_ops
1622  * Description: This function calls ION ioctl for cache related operations
1623  *
1624  * Input parameters:
1625  *  mem_info                - QCameraHalMemInfo_t structure with ION info
1626  *  buf_ptr                 - Buffer pointer that needs to be cache operated
1627  *  cmd                     - Cache command - clean/invalidate
1628  *
1629  * Return values:
1630  *   MM_CAMERA_OK       No error
1631  *   -1                 Error
1632  *
1633  * Notes: none
1634  *****************************************************************************/
cache_ops(QCameraHalMemInfo_t * mem_info,void * buf_ptr,unsigned int cmd)1635 int cache_ops(QCameraHalMemInfo_t *mem_info,
1636                                     void *buf_ptr,
1637                                     unsigned int cmd)
1638 {
1639     struct ion_flush_data cache_inv_data;
1640     struct ion_custom_data custom_data;
1641     int ret = MM_CAMERA_OK;
1642 
1643 #ifdef USE_ION
1644     if (NULL == mem_info) {
1645         ALOGE("%s: mem_info is NULL, return here", __func__);
1646         return -1;
1647     }
1648 
1649     memset(&cache_inv_data, 0, sizeof(cache_inv_data));
1650     memset(&custom_data, 0, sizeof(custom_data));
1651     cache_inv_data.vaddr = buf_ptr;
1652     cache_inv_data.fd = mem_info->fd;
1653     cache_inv_data.handle = mem_info->handle;
1654     cache_inv_data.length = mem_info->size;
1655     custom_data.cmd = cmd;
1656     custom_data.arg = (unsigned long)&cache_inv_data;
1657 
1658     ALOGD("%s: addr = %p, fd = %d, handle = %p length = %d, ION Fd = %d",
1659          __func__, cache_inv_data.vaddr, cache_inv_data.fd,
1660          cache_inv_data.handle, cache_inv_data.length,
1661          mem_info->main_ion_fd);
1662     if(mem_info->main_ion_fd > 0) {
1663         if(ioctl(mem_info->main_ion_fd, ION_IOC_CUSTOM, &custom_data) < 0) {
1664             ALOGE("%s: Cache Invalidate failed\n", __func__);
1665             ret = -1;
1666         }
1667     }
1668 #endif
1669 
1670     return ret;
1671 }
1672 
1673 /******************************************************************************
1674  * Function: get_buf_from_cam
1675  * Description: This funtions gets/acquires 1 capture buffer from the camera
1676  *              driver. The fetched buffer is stored in curCaptureBuf
1677  *
1678  * Input parameters:
1679  *   camHal              - camera HAL handle
1680  *
1681  * Return values:
1682  *   0      No error
1683  *   -1     Error
1684  *
1685  * Notes: none
1686  *****************************************************************************/
get_buf_from_cam(camera_hardware_t * camHal)1687 static int get_buf_from_cam(camera_hardware_t *camHal)
1688 {
1689     int rc = -1;
1690 
1691     ALOGD("%s: E", __func__);
1692     {
1693         memset(&camHal->curCaptureBuf, 0, sizeof(camHal->curCaptureBuf));
1694 
1695         camHal->curCaptureBuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1696         camHal->curCaptureBuf.memory = V4L2_MEMORY_MMAP;
1697 
1698         if (-1 == ioctlLoop(camHal->fd, VIDIOC_DQBUF, &camHal->curCaptureBuf)){
1699             switch (errno) {
1700             case EAGAIN:
1701                 ALOGE("%s: EAGAIN error", __func__);
1702                 return 1;
1703 
1704             case EIO:
1705             /* Could ignore EIO, see spec. */
1706 
1707             /* fall through */
1708 
1709             default:
1710             ALOGE("%s: VIDIOC_DQBUF error", __func__);
1711             }
1712         }
1713         else
1714         {
1715             rc = 0;
1716             ALOGD("%s: VIDIOC_DQBUF: %d successful, %d bytes",
1717                  __func__, camHal->curCaptureBuf.index,
1718                  camHal->curCaptureBuf.bytesused);
1719         }
1720     }
1721     ALOGD("%s: X", __func__);
1722     return rc;
1723 }
1724 
1725 /******************************************************************************
1726  * Function: put_buf_to_cam
1727  * Description: This funtion puts/releases 1 capture buffer back to the camera
1728  *              driver
1729  *
1730  * Input parameters:
1731  *   camHal              - camera HAL handle
1732  *
1733  * Return values:
1734  *   0      No error
1735  *   -1     Error
1736  *
1737  * Notes: none
1738  *****************************************************************************/
put_buf_to_cam(camera_hardware_t * camHal)1739 static int put_buf_to_cam(camera_hardware_t *camHal)
1740 {
1741     ALOGD("%s: E", __func__);
1742 
1743     camHal->curCaptureBuf.type        = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1744     camHal->curCaptureBuf.memory      = V4L2_MEMORY_MMAP;
1745 
1746 
1747     if (-1 == ioctlLoop(camHal->fd, VIDIOC_QBUF, &camHal->curCaptureBuf))
1748     {
1749         ALOGE("%s: VIDIOC_QBUF failed ", __func__);
1750         return 1;
1751     }
1752     ALOGD("%s: X", __func__);
1753     return 0;
1754 }
1755 
1756 /******************************************************************************
1757  * Function: put_buf_to_cam
1758  * Description: This funtion gets/acquires 1 display buffer from the display
1759  *              window
1760  *
1761  * Input parameters:
1762  *  camHal                  - camera HAL handle
1763  *  buffer_id               - Buffer id pointer. The id of buffer obtained
1764  *                              by this function is returned in this arg
1765  *
1766  * Return values:
1767  *   0      No error
1768  *   -1     Error
1769  *
1770  * Notes: none
1771  *****************************************************************************/
get_buf_from_display(camera_hardware_t * camHal,int * buffer_id)1772 static int get_buf_from_display(camera_hardware_t *camHal, int *buffer_id)
1773 {
1774     int                     err = 0;
1775     preview_stream_ops      *mPreviewWindow = NULL;
1776     int                     stride = 0, cnt = 0;
1777     buffer_handle_t         *buffer_handle = NULL;
1778     struct private_handle_t *private_buffer_handle = NULL;
1779 
1780     ALOGD("%s: E", __func__);
1781 
1782     if (camHal == NULL) {
1783         ALOGE("%s: camHal = NULL", __func__);
1784         return -1;
1785     }
1786 
1787     mPreviewWindow = camHal->window;
1788     if( mPreviewWindow == NULL) {
1789         ALOGE("%s: mPreviewWindow = NULL", __func__);
1790         return -1;
1791     }
1792     err = mPreviewWindow->dequeue_buffer(mPreviewWindow,
1793                                     &buffer_handle,
1794                                     &stride);
1795     if(!err) {
1796         ALOGD("%s: dequeue buf buffer_handle: %p\n", __func__, buffer_handle);
1797 
1798         ALOGD("%s: mPreviewWindow->lock_buffer: %p",
1799              __func__, mPreviewWindow->lock_buffer);
1800         if(mPreviewWindow->lock_buffer) {
1801             err = mPreviewWindow->lock_buffer(mPreviewWindow, buffer_handle);
1802             ALOGD("%s: mPreviewWindow->lock_buffer success", __func__);
1803         }
1804         ALOGD("%s: camera call genlock_lock, hdl=%p",
1805              __func__, (*buffer_handle));
1806 
1807         if (GENLOCK_NO_ERROR !=
1808             genlock_lock_buffer((native_handle_t *)(*buffer_handle),
1809                                 GENLOCK_WRITE_LOCK, GENLOCK_MAX_TIMEOUT)) {
1810            ALOGE("%s: genlock_lock_buffer(WRITE) failed", __func__);
1811        } else {
1812          ALOGD("%s: genlock_lock_buffer hdl =%p", __func__, *buffer_handle);
1813        }
1814 
1815         private_buffer_handle = (struct private_handle_t *)(*buffer_handle);
1816 
1817         ALOGD("%s: fd = %d, size = %d, offset = %d, stride = %d",
1818              __func__, private_buffer_handle->fd,
1819         private_buffer_handle->size, private_buffer_handle->offset, stride);
1820 
1821         for(cnt = 0; cnt < camHal->previewMem.buffer_count + 2; cnt++) {
1822             if(private_buffer_handle->fd ==
1823                camHal->previewMem.private_buffer_handle[cnt]->fd) {
1824                 *buffer_id = cnt;
1825                 ALOGD("%s: deQueued fd = %d, index: %d",
1826                      __func__, private_buffer_handle->fd, cnt);
1827                 break;
1828             }
1829         }
1830     }
1831     else
1832         ALOGE("%s: dequeue buf failed \n", __func__);
1833 
1834     ALOGD("%s: X", __func__);
1835 
1836     return err;
1837 }
1838 
1839 /******************************************************************************
1840  * Function: put_buf_to_display
1841  * Description: This funtion puts/enqueues 1 buffer back to the display window
1842  *
1843  * Input parameters:
1844  *  camHal                  - camera HAL handle
1845  *  buffer_id               - id of the buffer that needs to be enqueued
1846  *
1847  * Return values:
1848  *   0      No error
1849  *   -1     Error
1850  *
1851  * Notes: none
1852  *****************************************************************************/
put_buf_to_display(camera_hardware_t * camHal,int buffer_id)1853 static int put_buf_to_display(camera_hardware_t *camHal, int buffer_id)
1854 {
1855     int err = 0;
1856     preview_stream_ops    *mPreviewWindow;
1857 
1858     ALOGD("%s: E", __func__);
1859 
1860     if (camHal == NULL) {
1861         ALOGE("%s: camHal = NULL", __func__);
1862         return -1;
1863     }
1864 
1865     mPreviewWindow = camHal->window;
1866     if( mPreviewWindow == NULL) {
1867         ALOGE("%s: mPreviewWindow = NULL", __func__);
1868         return -1;
1869     }
1870 
1871     if (GENLOCK_FAILURE ==
1872         genlock_unlock_buffer(
1873             (native_handle_t *)
1874             (*(camHal->previewMem.buffer_handle[buffer_id])))) {
1875        ALOGE("%s: genlock_unlock_buffer failed: hdl =%p",
1876             __func__, (*(camHal->previewMem.buffer_handle[buffer_id])) );
1877     } else {
1878       ALOGD("%s: genlock_unlock_buffer success: hdl =%p",
1879            __func__, (*(camHal->previewMem.buffer_handle[buffer_id])) );
1880     }
1881 
1882     /* Cache clean the output buffer so that cache is written back */
1883     cache_ops(&camHal->previewMem.mem_info[buffer_id],
1884                          (void *)camHal->previewMem.camera_memory[buffer_id]->data,
1885                          ION_IOC_CLEAN_CACHES);
1886                          /*
1887     cache_ops(&camHal->previewMem.mem_info[buffer_id],
1888                          (void *)camHal->previewMem.camera_memory[buffer_id]->data,
1889                          ION_IOC_CLEAN_INV_CACHES);
1890 */
1891     err = mPreviewWindow->enqueue_buffer(mPreviewWindow,
1892       (buffer_handle_t *)camHal->previewMem.buffer_handle[buffer_id]);
1893     if(!err) {
1894         ALOGD("%s: enqueue buf successful: %p\n",
1895              __func__, camHal->previewMem.buffer_handle[buffer_id]);
1896     }else
1897         ALOGE("%s: enqueue buf failed: %p\n",
1898              __func__, camHal->previewMem.buffer_handle[buffer_id]);
1899 
1900     ALOGD("%s: X", __func__);
1901 
1902     return err;
1903 }
1904 
1905 /******************************************************************************
1906  * Function: put_buf_to_display
1907  * Description: This funtion transfers the content from capture buffer to
1908  *              preiew display buffer after appropriate conversion
1909  *
1910  * Input parameters:
1911  *  camHal                  - camera HAL handle
1912  *  buffer_id               - id of the buffer that needs to be enqueued
1913  *
1914  * Return values:
1915  *   0      No error
1916  *   -1     Error
1917  *
1918  * Notes: none
1919  *****************************************************************************/
convert_data_frm_cam_to_disp(camera_hardware_t * camHal,int buffer_id)1920 static int convert_data_frm_cam_to_disp(camera_hardware_t *camHal, int buffer_id)
1921 {
1922     int rc = -1;
1923 
1924     if(!camHal) {
1925         ALOGE("%s: camHal is NULL", __func__);
1926         return -1;
1927     }
1928     /* If input and output are raw formats, but different color format, */
1929     /* call color conversion routine                                    */
1930     if( (V4L2_PIX_FMT_YUYV == camHal->captureFormat) &&
1931         (HAL_PIXEL_FORMAT_YCrCb_420_SP == camHal->dispFormat))
1932     {
1933         convert_YUYV_to_420_NV12(
1934             (char *)camHal->buffers[camHal->curCaptureBuf.index].data,
1935             (char *)camHal->previewMem.camera_memory[buffer_id]->data,
1936             camHal->prevWidth,
1937             camHal->prevHeight);
1938         ALOGD("%s: Copied %d bytes from camera buffer %d to display buffer: %d",
1939              __func__, camHal->curCaptureBuf.bytesused,
1940              camHal->curCaptureBuf.index, buffer_id);
1941         rc = 0;
1942     }
1943 
1944     /* If camera buffer is MJPEG encoded, call mjpeg decode call */
1945     if(V4L2_PIX_FMT_MJPEG == camHal->captureFormat)
1946     {
1947         if(NULL == camHal->mjpegd)
1948         {
1949             rc = mjpegDecoderInit(&camHal->mjpegd);
1950             if(rc < 0)
1951                 ALOGE("%s: mjpegDecoderInit Error: %d", __func__, rc);
1952         }
1953         if(camHal->mjpegd)
1954         {
1955             rc = mjpegDecode(
1956                 (void*)camHal->mjpegd,
1957                 (char *)camHal->buffers[camHal->curCaptureBuf.index].data,
1958                 camHal->curCaptureBuf.bytesused,
1959                 (char *)camHal->previewMem.camera_memory[buffer_id]->data,
1960                 (char *)camHal->previewMem.camera_memory[buffer_id]->data +
1961                     camHal->prevWidth * camHal->prevHeight,
1962                 getMjpegdOutputFormat(camHal->dispFormat));
1963             if(rc < 0)
1964                 ALOGE("%s: mjpegDecode Error: %d", __func__, rc);
1965         }
1966     }
1967     return rc;
1968 }
1969 
1970 /******************************************************************************
1971  * Function: launch_preview_thread
1972  * Description: This is a wrapper function to start preview thread
1973  *
1974  * Input parameters:
1975  *  camHal                  - camera HAL handle
1976  *
1977  * Return values:
1978  *   0      No error
1979  *   -1     Error
1980  *
1981  * Notes: none
1982  *****************************************************************************/
launch_preview_thread(camera_hardware_t * camHal)1983 static int launch_preview_thread(camera_hardware_t *camHal)
1984 {
1985     ALOGD("%s: E", __func__);
1986     int rc = 0;
1987 
1988     if(!camHal) {
1989         ALOGE("%s: camHal is NULL", __func__);
1990         return -1;
1991     }
1992 
1993     pthread_attr_t attr;
1994     pthread_attr_init(&attr);
1995     pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
1996     pthread_create(&camHal->previewThread, &attr, previewloop, camHal);
1997 
1998     ALOGD("%s: X", __func__);
1999     return rc;
2000 }
2001 
2002 /******************************************************************************
2003  * Function: launch_preview_thread
2004  * Description: This is thread funtion for preivew loop
2005  *
2006  * Input parameters:
2007  *  hcamHal                 - camera HAL handle
2008  *
2009  * Return values:
2010  *   0      No error
2011  *   -1     Error
2012  *
2013  * Notes: none
2014  *****************************************************************************/
previewloop(void * hcamHal)2015 static void * previewloop(void *hcamHal)
2016 {
2017     int                 rc;
2018     int                 buffer_id   = 0;
2019     pid_t               tid         = 0;
2020     camera_hardware_t   *camHal     = NULL;
2021     int                 msgType     = 0;
2022     camera_memory_t     *data       = NULL;
2023     camera_frame_metadata_t *metadata= NULL;
2024     camera_memory_t     *previewMem = NULL;
2025 
2026     camHal = (camera_hardware_t *)hcamHal;
2027     ALOGD("%s: E", __func__);
2028 
2029     if(!camHal) {
2030         ALOGE("%s: camHal is NULL", __func__);
2031         return NULL ;
2032     }
2033 
2034     tid  = gettid();
2035     /* TBR: Set appropriate thread priority */
2036     androidSetThreadPriority(tid, ANDROID_PRIORITY_NORMAL);
2037     prctl(PR_SET_NAME, (unsigned long)"Camera HAL preview thread", 0, 0, 0);
2038 
2039     /************************************************************************/
2040     /* - Time wait (select) on camera fd for input read buffer              */
2041     /* - Check if any preview thread commands are set. If set, process      */
2042     /* - Dequeue display buffer from surface                                */
2043     /* - Dequeue capture buffer from USB camera                             */
2044     /* - Convert capture format to display format                           */
2045     /* - If preview frames callback is requested, callback with prvw buffers*/
2046     /* - Enqueue display buffer back to surface                             */
2047     /* - Enqueue capture buffer back to USB camera                          */
2048     /************************************************************************/
2049     while(1) {
2050         fd_set fds;
2051         struct timeval tv;
2052         int r = 0;
2053 
2054         FD_ZERO(&fds);
2055 #if CAPTURE
2056         FD_SET(camHal->fd, &fds);
2057 #endif /* CAPTURE */
2058 
2059     /************************************************************************/
2060     /* - Time wait (select) on camera fd for input read buffer              */
2061     /************************************************************************/
2062         tv.tv_sec = 0;
2063         tv.tv_usec = 500000;
2064 
2065         ALOGD("%s: b4 select on camHal->fd + 1,fd: %d", __func__, camHal->fd);
2066 #if CAPTURE
2067         r = select(camHal->fd + 1, &fds, NULL, NULL, &tv);
2068 #else
2069         r = select(1, NULL, NULL, NULL, &tv);
2070 #endif /* CAPTURE */
2071         ALOGD("%s: after select : %d", __func__, camHal->fd);
2072 
2073         if (-1 == r) {
2074             if (EINTR == errno)
2075                 continue;
2076             ALOGE("%s: FDSelect error: %d", __func__, errno);
2077         }
2078 
2079         if (0 == r) {
2080             ALOGD("%s: select timeout\n", __func__);
2081         }
2082 
2083         /* Protect the context for one iteration of preview loop */
2084         /* this gets unlocked at the end of the while */
2085         Mutex::Autolock autoLock(camHal->lock);
2086 
2087     /************************************************************************/
2088     /* - Check if any preview thread commands are set. If set, process      */
2089     /************************************************************************/
2090         if(camHal->prvwCmdPending)
2091         {
2092             /* command is serviced. Hence command pending = 0  */
2093             camHal->prvwCmdPending--;
2094             //sempost(ack)
2095             if(USB_CAM_PREVIEW_EXIT == camHal->prvwCmd){
2096                 /* unlock before exiting the thread */
2097                 camHal->lock.unlock();
2098                 ALOGI("%s: Exiting coz USB_CAM_PREVIEW_EXIT", __func__);
2099                 return (void *)0;
2100             }else if(USB_CAM_PREVIEW_TAKEPIC == camHal->prvwCmd){
2101                 rc = prvwThreadTakePictureInternal(camHal);
2102                 if(rc)
2103                     ALOGE("%s: prvwThreadTakePictureInternal returned error",
2104                     __func__);
2105             }
2106         }
2107 
2108         /* Null check on preview window. If null, sleep */
2109         if(!camHal->window) {
2110             ALOGD("%s: sleeping coz camHal->window = NULL",__func__);
2111             camHal->lock.unlock();
2112             sleep(2);
2113             continue;
2114         }
2115 #if DISPLAY
2116     /************************************************************************/
2117     /* - Dequeue display buffer from surface                                */
2118     /************************************************************************/
2119         if(0 == get_buf_from_display(camHal, &buffer_id)) {
2120             ALOGD("%s: get_buf_from_display success: %d",
2121                  __func__, buffer_id);
2122         }else{
2123             ALOGE("%s: get_buf_from_display failed. Skipping the loop",
2124                  __func__);
2125             continue;
2126         }
2127 #endif
2128 
2129 #if CAPTURE
2130     /************************************************************************/
2131     /* - Dequeue capture buffer from USB camera                             */
2132     /************************************************************************/
2133         if (0 == get_buf_from_cam(camHal))
2134             ALOGD("%s: get_buf_from_cam success", __func__);
2135         else
2136             ALOGE("%s: get_buf_from_cam error", __func__);
2137 #endif
2138 
2139 #if FILE_DUMP_CAMERA
2140         /* Debug code to dump frames from camera */
2141         {
2142             static int frame_cnt = 0;
2143             /* currently hardcoded for Bytes-Per-Pixel = 1.5 */
2144             fileDump("/data/USBcam.yuv",
2145             (char*)camHal->buffers[camHal->curCaptureBuf.index].data,
2146             camHal->prevWidth * camHal->prevHeight * 1.5,
2147             &frame_cnt);
2148         }
2149 #endif
2150 
2151 #if MEMSET
2152         static int color = 30;
2153         color += 50;
2154         if(color > 200) {
2155             color = 30;
2156         }
2157         ALOGE("%s: Setting to the color: %d\n", __func__, color);
2158         /* currently hardcoded for format of type Bytes-Per-Pixel = 1.5 */
2159         memset(camHal->previewMem.camera_memory[buffer_id]->data,
2160                color, camHal->dispWidth * camHal->dispHeight * 1.5 + 2 * 1024);
2161 #else
2162         convert_data_frm_cam_to_disp(camHal, buffer_id);
2163         ALOGD("%s: Copied data to buffer_id: %d", __func__, buffer_id);
2164 #endif
2165 
2166 #if FILE_DUMP_B4_DISP
2167         /* Debug code to dump display buffers */
2168         {
2169             static int frame_cnt = 0;
2170             /* currently hardcoded for Bytes-Per-Pixel = 1.5 */
2171             fileDump("/data/display.yuv",
2172                 (char*) camHal->previewMem.camera_memory[buffer_id]->data,
2173                 camHal->dispWidth * camHal->dispHeight * 1.5,
2174                 &frame_cnt);
2175             ALOGD("%s: Written buf_index: %d ", __func__, buffer_id);
2176         }
2177 #endif
2178 
2179 #if DISPLAY
2180     /************************************************************************/
2181     /* - Enqueue display buffer back to surface                             */
2182     /************************************************************************/
2183        if(0 == put_buf_to_display(camHal, buffer_id)) {
2184             ALOGD("%s: put_buf_to_display success: %d", __func__, buffer_id);
2185         }
2186         else
2187             ALOGE("%s: put_buf_to_display error", __func__);
2188 #endif
2189 
2190 #if CAPTURE
2191      /************************************************************************/
2192     /* - Enqueue capture buffer back to USB camera                          */
2193     /************************************************************************/
2194        if(0 == put_buf_to_cam(camHal)) {
2195             ALOGD("%s: put_buf_to_cam success", __func__);
2196         }
2197         else
2198             ALOGE("%s: put_buf_to_cam error", __func__);
2199 #endif
2200 
2201 #if CALL_BACK
2202     /************************************************************************/
2203     /* - If preview frames callback is requested, callback with prvw buffers*/
2204     /************************************************************************/
2205         /* TBD: change the 1.5 hardcoding to Bytes Per Pixel */
2206         int previewBufSize = camHal->prevWidth * camHal->prevHeight * 1.5;
2207 
2208         msgType |=  CAMERA_MSG_PREVIEW_FRAME;
2209 
2210         if(previewBufSize !=
2211             camHal->previewMem.private_buffer_handle[buffer_id]->size) {
2212 
2213             previewMem = camHal->get_memory(
2214                 camHal->previewMem.private_buffer_handle[buffer_id]->fd,
2215                 previewBufSize,
2216                 1,
2217                 camHal->cb_ctxt);
2218 
2219               if (!previewMem || !previewMem->data) {
2220                   ALOGE("%s: get_memory failed.\n", __func__);
2221               }
2222               else {
2223                   data = previewMem;
2224                   ALOGD("%s: GetMemory successful. data = %p",
2225                             __func__, data);
2226                   ALOGD("%s: previewBufSize = %d, priv_buf_size: %d",
2227                     __func__, previewBufSize,
2228                     camHal->previewMem.private_buffer_handle[buffer_id]->size);
2229               }
2230         }
2231         else{
2232             data =   camHal->previewMem.camera_memory[buffer_id];
2233             ALOGD("%s: No GetMemory, no invalid fmt. data = %p, idx=%d",
2234                 __func__, data, buffer_id);
2235         }
2236         /* Unlock and lock around the callback. */
2237         /* Sometimes 'disable_msg' is issued in the callback context, */
2238         /* leading to deadlock */
2239         camHal->lock.unlock();
2240         if((camHal->msgEnabledFlag & CAMERA_MSG_PREVIEW_FRAME) &&
2241             camHal->data_cb){
2242             ALOGD("%s: before data callback", __func__);
2243             camHal->data_cb(msgType, data, 0,metadata, camHal->cb_ctxt);
2244             ALOGD("%s: after data callback: %p", __func__, camHal->data_cb);
2245         }
2246         camHal->lock.lock();
2247         if (previewMem)
2248             previewMem->release(previewMem);
2249 #endif
2250 
2251     }//while(1)
2252     ALOGD("%s: X", __func__);
2253     return (void *)0;
2254 }
2255 
2256 /******************************************************************************
2257  * Function: get_uvc_device
2258  * Description: This function loops through /dev/video entries and probes with
2259  *              UVCIOC query. If the device responds to the query, then it is
2260  *              detected as UVC webcam
2261  * Input parameters:
2262  *   devname             - String pointer. The function return dev entry
2263  *                          name in this string
2264  * Return values:
2265  *      0   Success
2266  *      -1  Error
2267  * Notes: none
2268  *****************************************************************************/
get_uvc_device(char * devname)2269 static int get_uvc_device(char *devname)
2270 {
2271     char    temp_devname[FILENAME_LENGTH];
2272     FILE    *fp = NULL;
2273     int     i = 0, ret = 0, fd;
2274 
2275     ALOGD("%s: E", __func__);
2276 #if 1
2277     strncpy(devname, "/dev/video1", FILENAME_LENGTH);
2278 
2279 /*
2280     struct          stat st;
2281 
2282     strncpy(dev_name, "/dev/video1", FILENAME_LENGTH);
2283     if (-1 == stat(dev_name, &st)) {
2284         ALOGE("%s: Cannot identify '%s': %d, %s\n",
2285              __func__, dev_name, errno, strerror(errno));
2286     }
2287 
2288     if (!S_ISCHR(st.st_mode)) {
2289         ALOGE("%s: %s is no device\n", __func__, dev_name);
2290         rc = -1;
2291     }
2292 */
2293 
2294 #else
2295 
2296     *devname = '\0';
2297     /************************************************************************/
2298     /* - List all /dev/video* entries to a file                             */
2299     /* - Open the video list file and loop through the list                 */
2300     /* - Send UVC specific control query and check the response             */
2301     /* - If device responds to the query as success, device is UVC webcam   */
2302     /************************************************************************/
2303 
2304     /************************************************************************/
2305     /* - List all /dev/video* entries to a file                             */
2306     /************************************************************************/
2307     /* Temporarily commented out. This logic doesnt seem to be working */
2308     //system("ls > /data/video_dev_list");
2309 
2310     /************************************************************************/
2311     /* - Open the video list file and loop through the list                 */
2312     /************************************************************************/
2313 
2314     /* Temporarily commented out. This logic doesnt seem to be working */
2315     /*
2316     fp = fopen("/data/video_dev_list", "rb");
2317     if(!fp) {
2318         ALOGE("%s: Error in opening /data/video_dev_list ", __func__);
2319         return -1;
2320     }
2321     */
2322 
2323     /* Temporarily commented out. Looping logic changed due to issue in */
2324     /* executing system("ls > /data/video_dev_list") */
2325     //while(EOF != fscanf(fp, "%s", devname)){
2326     while(1){
2327         uvc_xu_control_query    xqry;
2328 
2329         sprintf(temp_devname, "/dev/video%d", i);
2330         ALOGD("%s: Probing %s \n", __func__, temp_devname);
2331 
2332         fd = open(temp_devname, O_RDWR /* required */ | O_NONBLOCK, 0);
2333         if(-1 != fd){
2334             memset(&xqry, 0, sizeof(uvc_xu_control_query));
2335             ret = ioctl(fd, UVCIOC_CTRL_QUERY, &xqry);
2336             ALOGD("%s: UVCIOC ret: %d, errno: %d", __func__, ret, errno);
2337             /****************************************************************/
2338             /* if UVCIOC is executed successfully, ret = 0                  */
2339             /* if UVCIOC is executed but Control Unit = 0 does not exist,   */
2340             /*      ret = -1 and errno = ENOENT                             */
2341             /* if UVCIOC doesnot execute, ret = -1 and errno = EINVAL       */
2342             /****************************************************************/
2343             if((0 == ret) || (ret && (ENOENT == errno))){
2344                 ALOGD("%s: Found UVC node: %s\n", __func__, temp_devname);
2345                 strncpy(devname, temp_devname, FILENAME_LENGTH);
2346                 /* Exit the loop at the first UVC node detection */
2347                 break;
2348             }
2349             close(fd);
2350         }
2351         /* Temporarily logic to probe video0 to video10 nodes */
2352         if(i++ > 10)
2353         {
2354             if(fp)
2355                 fclose(fp);
2356             break;
2357         }
2358     }
2359 #endif /* #if 0 */
2360     ALOGD("%s: X", __func__);
2361     return 0;
2362 } /* get_uvc_device */
2363 
2364 /******************************************************************************
2365  * Function: fileDump
2366  * Description: This is a utility function to dump buffers into a file
2367  *
2368  * Input parameters:
2369  *  fn              - File name string
2370  *  data            - pointer to character buffer that needs to be dumped
2371  *  length          - Length of the buffer to be dumped
2372  *  frm_cnt         - Pointer to frame count. This count is incremented by this
2373  *                      function on successful file write
2374  * Return values:
2375  *      0   Success
2376  *      -1  Error
2377  * Notes: none
2378  *****************************************************************************/
fileDump(const char * fn,char * data,int length,int * frm_cnt)2379 static int fileDump(const char* fn, char* data, int length, int* frm_cnt)
2380 {
2381 
2382     FILE *fp = NULL;
2383     if (0 == *frm_cnt) {
2384         fp = fopen(fn, "wb");
2385         if (NULL == fp) {
2386             ALOGE("%s: Error in opening %s", __func__, fn);
2387         }
2388         fclose(fp);
2389     }
2390     fp = fopen(fn, "ab");
2391     if (NULL == fp) {
2392         ALOGE("%s: Error in opening %s", __func__, fn);
2393     }
2394     fwrite(data, 1, length, fp);
2395     fclose(fp);
2396     (*frm_cnt)++;
2397     ALOGD("%s: Written %d bytes for frame:%d, in %s",
2398         __func__, length, *frm_cnt, fn);
2399 
2400     return 0;
2401 }
2402 
2403 /******************************************************************************
2404  * Function: launchTakePictureThread
2405  * Description: This is a wrapper function to start take picture thread
2406  *
2407  * Input parameters:
2408  *  camHal                  - camera HAL handle
2409  *
2410  * Return values:
2411  *   0      No error
2412  *   -1     Error
2413  *
2414  * Notes: none
2415  *****************************************************************************/
launchTakePictureThread(camera_hardware_t * camHal)2416 static int launchTakePictureThread(camera_hardware_t *camHal)
2417 {
2418     ALOGD("%s: E", __func__);
2419     int rc = 0;
2420 
2421     if(!camHal) {
2422         ALOGE("%s: camHal is NULL", __func__);
2423         return -1;
2424     }
2425 
2426     pthread_attr_t attr;
2427     pthread_attr_init(&attr);
2428     /* create the thread in detatched state, when the thread exits all */
2429     /* memory resources are freed up */
2430     pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
2431     pthread_create(&camHal->takePictureThread, &attr, takePictureThread, camHal);
2432 
2433     ALOGD("%s: X", __func__);
2434     return rc;
2435 }
2436 
2437 /******************************************************************************
2438  * Function: takePictureThread
2439  * Description: This function is associated with take picture thread
2440  *
2441  * Input parameters:
2442  *  camHal                  - camera HAL handle
2443  *
2444  * Return values:
2445  *   0      No error
2446  *   -1     Error
2447  *
2448  * Notes: none
2449  *****************************************************************************/
takePictureThread(void * hcamHal)2450 static void * takePictureThread(void *hcamHal)
2451 {
2452     int                 rc = 0;
2453     int                 buffer_id   = 0;
2454     pid_t               tid         = 0;
2455     camera_hardware_t   *camHal     = NULL;
2456     int                 msgType     = 0;
2457     int                 jpegLength  = 0;
2458     QCameraHalMemInfo_t *mem_info   = NULL;
2459 
2460     camHal = (camera_hardware_t *)hcamHal;
2461     ALOGI("%s: E", __func__);
2462 
2463     if(!camHal) {
2464         ALOGE("%s: camHal is NULL", __func__);
2465         return NULL ;
2466     }
2467 
2468     tid  = gettid();
2469     /* TBR: Set appropriate thread priority */
2470     androidSetThreadPriority(tid, ANDROID_PRIORITY_NORMAL);
2471     prctl(PR_SET_NAME, (unsigned long)"Camera HAL preview thread", 0, 0, 0);
2472 
2473     /************************************************************************/
2474     /* - If requested for shutter notfication, notify                       */
2475     /* - Initialize USB camera with snapshot parameters                     */
2476     /* - Time wait (select) on camera fd for camera frame availability      */
2477     /* - Dequeue capture buffer from USB camera                             */
2478     /* - Send capture buffer to JPEG encoder for JPEG compression           */
2479     /* - If jpeg frames callback is requested, callback with jpeg buffers   */
2480     /* - Enqueue capture buffer back to USB camera                          */
2481     /* - Free USB camera resources and close camera                         */
2482     /* - If preview was stopped for taking picture, restart the preview     */
2483     /************************************************************************/
2484 
2485     Mutex::Autolock autoLock(camHal->lock);
2486     /************************************************************************/
2487     /* - If requested for shutter notfication, notify                       */
2488     /************************************************************************/
2489 #if 0 /* TBD: Temporarily commented out due to an issue. Sometimes it takes */
2490     /* long time to get back the lock once unlocked and notify callback */
2491     if (camHal->msgEnabledFlag & CAMERA_MSG_SHUTTER){
2492         camHal->lock.unlock();
2493         camHal->notify_cb(CAMERA_MSG_SHUTTER, 0, 0, camHal->cb_ctxt);
2494         camHal->lock.lock();
2495     }
2496 #endif
2497     /************************************************************************/
2498     /* - Initialize USB camera with snapshot parameters                     */
2499     /************************************************************************/
2500     USB_CAM_OPEN(camHal);
2501 
2502 #if JPEG_ON_USB_CAMERA
2503     rc = initUsbCamera(camHal, camHal->pictWidth, camHal->pictHeight,
2504                         V4L2_PIX_FMT_MJPEG);
2505 #else
2506     rc = initUsbCamera(camHal, camHal->pictWidth, camHal->pictHeight,
2507                         V4L2_PIX_FMT_YUYV);
2508 #endif
2509     ERROR_CHECK_EXIT_THREAD(rc, "initUsbCamera");
2510 
2511     rc = startUsbCamCapture(camHal);
2512     ERROR_CHECK_EXIT_THREAD(rc, "startUsbCamCapture");
2513 
2514     /************************************************************************/
2515     /* - Time wait (select) on camera fd for camera frame availability      */
2516     /************************************************************************/
2517     {
2518         fd_set fds;
2519         struct timeval tv;
2520         int r = 0;
2521 
2522         FD_ZERO(&fds);
2523         FD_SET(camHal->fd, &fds);
2524 
2525         tv.tv_sec = 1;
2526         tv.tv_usec = 0;
2527 
2528         do{
2529             ALOGD("%s: b4 select on camHal->fd : %d", __func__, camHal->fd);
2530             r = select(camHal->fd + 1, &fds, NULL, NULL, &tv);
2531             ALOGD("%s: after select", __func__);
2532         }while((0 == r) || ((-1 == r) && (EINTR == errno)));
2533 
2534         if ((-1 == r) && (EINTR != errno)){
2535             ALOGE("%s: FDSelect ret = %d error: %d", __func__, r, errno);
2536             return (void *)-1;
2537         }
2538 
2539     }
2540     /************************************************************************/
2541     /* - Dequeue capture buffer from USB camera                             */
2542     /************************************************************************/
2543     if (0 == get_buf_from_cam(camHal))
2544         ALOGD("%s: get_buf_from_cam success", __func__);
2545     else
2546         ALOGE("%s: get_buf_from_cam error", __func__);
2547 
2548     /************************************************************************/
2549     /* - Send capture buffer to JPEG encoder for JPEG compression           */
2550     /************************************************************************/
2551     mem_info = &camHal->pictMem.mem_info[0];
2552     mem_info->size = MAX_JPEG_BUFFER_SIZE;
2553 
2554     rc = allocate_ion_memory(mem_info,
2555                         ((0x1 << CAMERA_ZSL_ION_HEAP_ID) |
2556                         (0x1 << CAMERA_ZSL_ION_FALLBACK_HEAP_ID)));
2557     if(rc)
2558         ALOGE("%s: ION memory allocation failed", __func__);
2559 
2560     camHal->pictMem.camera_memory[0] = camHal->get_memory(
2561                         mem_info->fd, mem_info->size, 1, camHal->cb_ctxt);
2562     if(!camHal->pictMem.camera_memory[0])
2563         ALOGE("%s: get_mem failed", __func__);
2564 
2565 #if FREAD_JPEG_PICTURE
2566     jpegLength = readFromFile("/data/tempVGA.jpeg",
2567                     (char*)camHal->pictMem.camera_memory[0]->data,
2568                     camHal->pictMem.camera_memory[0]->size);
2569     camHal->pictMem.camera_memory[0]->size = jpegLength;
2570 
2571 #elif JPEG_ON_USB_CAMERA
2572     memcpy((char*)camHal->pictMem.camera_memory[0]->data,
2573             (char *)camHal->buffers[camHal->curCaptureBuf.index].data,
2574             camHal->curCaptureBuf.bytesused);
2575     camHal->pictMem.camera_memory[0]->size = camHal->curCaptureBuf.bytesused;
2576     jpegLength = camHal->curCaptureBuf.bytesused;
2577 
2578 #else
2579     rc = encodeJpeg(camHal);
2580     ERROR_CHECK_EXIT_THREAD(rc, "jpeg_encode");
2581 #endif
2582     if(jpegLength <= 0)
2583         ALOGI("%s: jpegLength : %d", __func__, jpegLength);
2584 
2585      ALOGD("%s: jpegLength : %d", __func__, jpegLength);
2586     /************************************************************************/
2587     /* - If jpeg frames callback is requested, callback with jpeg buffers   */
2588     /************************************************************************/
2589     /* TBD: CAMERA_MSG_RAW_IMAGE data call back */
2590 
2591     if ((camHal->msgEnabledFlag & CAMERA_MSG_COMPRESSED_IMAGE) &&
2592             (camHal->data_cb)){
2593         /* Unlock temporarily, callback might call HAL api in turn */
2594         camHal->lock.unlock();
2595 
2596         camHal->data_cb(CAMERA_MSG_COMPRESSED_IMAGE,
2597                         camHal->pictMem.camera_memory[0],
2598                         0, NULL, camHal->cb_ctxt);
2599         camHal->lock.lock();
2600     }
2601 
2602     /* release heap memory after the call back */
2603     if(camHal->pictMem.camera_memory[0])
2604         camHal->pictMem.camera_memory[0]->release(
2605             camHal->pictMem.camera_memory[0]);
2606 
2607     rc = deallocate_ion_memory(mem_info);
2608     if(rc)
2609         ALOGE("%s: ION memory de-allocation failed", __func__);
2610 
2611     /************************************************************************/
2612     /* - Enqueue capture buffer back to USB camera                          */
2613     /************************************************************************/
2614     if(0 == put_buf_to_cam(camHal)) {
2615         ALOGD("%s: put_buf_to_cam success", __func__);
2616     }
2617     else
2618         ALOGE("%s: put_buf_to_cam error", __func__);
2619 
2620     /************************************************************************/
2621     /* - Free USB camera resources and close camera                         */
2622     /************************************************************************/
2623     rc = stopUsbCamCapture(camHal);
2624     ERROR_CHECK_EXIT_THREAD(rc, "stopUsbCamCapture");
2625 
2626     rc = unInitV4L2mmap(camHal);
2627     ERROR_CHECK_EXIT_THREAD(rc, "unInitV4L2mmap");
2628 
2629     USB_CAM_CLOSE(camHal);
2630     /************************************************************************/
2631     /* - If preview was stopped for taking picture, restart the preview     */
2632     /************************************************************************/
2633     if(camHal->prvwStoppedForPicture)
2634     {
2635         struct camera_device    device;
2636         device.priv = (void *)camHal;
2637 
2638         USB_CAM_OPEN(camHal);
2639         /* Unlock temporarily coz usbcam_start_preview has a lock */
2640         camHal->lock.unlock();
2641         rc = usbcam_start_preview(&device);
2642         if(rc)
2643             ALOGE("%s: start_preview error after take picture", __func__);
2644         camHal->lock.lock();
2645         camHal->prvwStoppedForPicture = 0;
2646     }
2647 
2648     /* take picture activity is done */
2649     camHal->takePictInProgress = 0;
2650 
2651     ALOGI("%s: X", __func__);
2652     return (void *)0;
2653 }
2654 
2655 /******************************************************************************
2656  * Function: allocate_ion_memory
2657  * Description: This function is allocates ION memory
2658  *
2659  * Input parameters:
2660  *  camHal                  - camera HAL handle
2661  *
2662  * Return values:
2663  *   0      No error
2664  *   -1     Error
2665  *
2666  * Notes: none
2667  *****************************************************************************/
allocate_ion_memory(QCameraHalMemInfo_t * mem_info,int ion_type)2668 static int allocate_ion_memory(QCameraHalMemInfo_t *mem_info, int ion_type)
2669 {
2670     int                         rc = 0;
2671     struct ion_handle_data      handle_data;
2672     struct ion_allocation_data  alloc;
2673     struct ion_fd_data          ion_info_fd;
2674     int                         main_ion_fd = 0;
2675 
2676     main_ion_fd = open("/dev/ion", O_RDONLY);
2677     if (main_ion_fd <= 0) {
2678         ALOGE("Ion dev open failed %s\n", strerror(errno));
2679         goto ION_OPEN_FAILED;
2680     }
2681 
2682     memset(&alloc, 0, sizeof(alloc));
2683     alloc.len = mem_info->size;
2684     /* to make it page size aligned */
2685     alloc.len = (alloc.len + 4095) & (~4095);
2686     alloc.align = 4096;
2687     alloc.flags = ION_FLAG_CACHED;
2688     alloc.heap_mask = ion_type;
2689     rc = ioctl(main_ion_fd, ION_IOC_ALLOC, &alloc);
2690     if (rc < 0) {
2691         ALOGE("ION allocation failed\n");
2692         goto ION_ALLOC_FAILED;
2693     }
2694 
2695     memset(&ion_info_fd, 0, sizeof(ion_info_fd));
2696     ion_info_fd.handle = alloc.handle;
2697     rc = ioctl(main_ion_fd, ION_IOC_SHARE, &ion_info_fd);
2698     if (rc < 0) {
2699         ALOGE("ION map failed %s\n", strerror(errno));
2700         goto ION_MAP_FAILED;
2701     }
2702 
2703     mem_info->main_ion_fd = main_ion_fd;
2704     mem_info->fd = ion_info_fd.fd;
2705     mem_info->handle = ion_info_fd.handle;
2706     mem_info->size = alloc.len;
2707     return 0;
2708 
2709 ION_MAP_FAILED:
2710     memset(&handle_data, 0, sizeof(handle_data));
2711     handle_data.handle = ion_info_fd.handle;
2712     ioctl(main_ion_fd, ION_IOC_FREE, &handle_data);
2713 ION_ALLOC_FAILED:
2714     close(main_ion_fd);
2715 ION_OPEN_FAILED:
2716     return -1;
2717 }
2718 
2719 /******************************************************************************
2720  * Function: deallocate_ion_memory
2721  * Description: This function de allocates ION memory
2722  *
2723  * Input parameters:
2724  *  camHal                  - camera HAL handle
2725  *
2726  * Return values:
2727  *   0      No error
2728  *   -1     Error
2729  *
2730  * Notes: none
2731  *****************************************************************************/
deallocate_ion_memory(QCameraHalMemInfo_t * mem_info)2732 static int deallocate_ion_memory(QCameraHalMemInfo_t *mem_info)
2733 {
2734   struct ion_handle_data handle_data;
2735   int rc = 0;
2736 
2737   if (mem_info->fd > 0) {
2738       close(mem_info->fd);
2739       mem_info->fd = 0;
2740   }
2741 
2742   if (mem_info->main_ion_fd > 0) {
2743       memset(&handle_data, 0, sizeof(handle_data));
2744       handle_data.handle = mem_info->handle;
2745       ioctl(mem_info->main_ion_fd, ION_IOC_FREE, &handle_data);
2746       close(mem_info->main_ion_fd);
2747       mem_info->main_ion_fd = 0;
2748   }
2749   return rc;
2750 }
2751 
2752 /******************************************************************************
2753  * Function: readFromFile
2754  * Description: This function reads data from the given file into given buffer
2755  *
2756  * Input parameters:
2757  *  camHal                  - camera HAL handle
2758  *
2759  * Return values:
2760  *   int    bytesRead
2761  *
2762  * Notes: none
2763  *****************************************************************************/
readFromFile(char * fileName,char * buffer,int bufferSize)2764 static int readFromFile(char* fileName, char* buffer, int bufferSize)
2765 {
2766     int bytesRead = 0, fileSize = 0;
2767     FILE *fp;
2768 
2769     fp = fopen(fileName, "rb");
2770     if(!fp){
2771         ALOGE("%s: Error in opening %s ", __func__, fileName);
2772         return bytesRead;
2773     }
2774 
2775     /* If file is bigger for given buffer, exit */
2776     if (fileSize > bufferSize){
2777         ALOGE("%s: Error %d > %d", __func__, fileSize, bufferSize);
2778         return bytesRead;
2779     }
2780 
2781     bytesRead = fread(buffer, 1, bufferSize, fp);
2782     ALOGD(" %s: bytesRead: %d", __func__, bytesRead);
2783 
2784     return bytesRead;
2785 }
2786 
2787 /******************************************************************************
2788  * Function: encodeJpeg
2789  * Description: This function initializes Jpeg encoder and calls jpeg encoder
2790  *              call and waits for the encode to complete
2791  *
2792  * Input parameters:
2793  *  camHal                  - camera HAL handle
2794  *
2795  * Return values:
2796  *   0  No Error
2797  *  -1  Error
2798  *
2799  * Notes: none
2800  *****************************************************************************/
encodeJpeg(camera_hardware_t * camHal)2801 int encodeJpeg(camera_hardware_t *camHal)
2802 {
2803     int                 rc = 0;
2804     mm_jpeg_ops_t       mmJpegOps;
2805     int                 jpegEncHdl  = 0;
2806     mm_jpeg_job         mmJpegJob;
2807     src_image_buffer_info   *srcBuf = NULL;
2808     QCameraHalMemInfo_t jpegInMemInfo;
2809     camera_memory_t*    jpegInMem;
2810     uint32_t            jobId;
2811 
2812     ALOGI("%s: E", __func__);
2813 
2814     /************************************************************************/
2815     /* - Allocate Jpeg input buffer from ION memory                         */
2816     /************************************************************************/
2817     jpegInMemInfo.size = camHal->pictWidth * camHal->pictHeight * 2;
2818     rc = allocate_ion_memory(&jpegInMemInfo,
2819                         ((0x1 << CAMERA_ZSL_ION_HEAP_ID) |
2820                         (0x1 << CAMERA_ZSL_ION_FALLBACK_HEAP_ID)));
2821     ERROR_CHECK_EXIT(rc, "allocate_ion_memory");
2822 
2823     jpegInMem = camHal->get_memory(
2824                         jpegInMemInfo.fd, jpegInMemInfo.size, 1, camHal->cb_ctxt);
2825     if(!jpegInMem){
2826         ALOGE("%s: get_mem failed", __func__);
2827         return -1;
2828     }
2829 
2830     rc = convert_YUYV_to_420_NV12(
2831         (char *)camHal->buffers[camHal->curCaptureBuf.index].data,
2832         (char *)jpegInMem->data, camHal->pictWidth, camHal->pictHeight);
2833     ERROR_CHECK_EXIT(rc, "convert_YUYV_to_420_NV12");
2834     /************************************************************************/
2835     /* - Populate JPEG encoding parameters from the camHal context          */
2836     /************************************************************************/
2837     memset(&mmJpegJob, 0, sizeof(mmJpegJob));
2838 
2839     mmJpegJob.job_type              = JPEG_JOB_TYPE_ENCODE;
2840     mmJpegJob.encode_job.jpeg_cb    = jpegEncodeCb;
2841     mmJpegJob.encode_job.userdata   = (void *)camHal;
2842     /* TBD: Rotation to be set from settings sent from app */
2843     mmJpegJob.encode_job.encode_parm.rotation           = 0;
2844     mmJpegJob.encode_job.encode_parm.exif_numEntries    = 0;
2845     mmJpegJob.encode_job.encode_parm.exif_data          = NULL;
2846 
2847     /* TBD: Add thumbnail support */
2848     mmJpegJob.encode_job.encode_parm.buf_info.src_imgs.src_img_num = 1;
2849     mmJpegJob.encode_job.encode_parm.buf_info.src_imgs.is_video_frame = 0;
2850 
2851     /* Fill main image information */
2852     srcBuf = &mmJpegJob.encode_job.encode_parm.buf_info.src_imgs.src_img[0];
2853     srcBuf->type                = JPEG_SRC_IMAGE_TYPE_MAIN;
2854     srcBuf->img_fmt             = JPEG_SRC_IMAGE_FMT_YUV;
2855     /* TBD: convert from YUYV to CRCBH2V2 */
2856     srcBuf->color_format        = MM_JPEG_COLOR_FORMAT_YCRCBLP_H2V2;
2857     srcBuf->num_bufs            = 1;
2858     srcBuf->src_image[0].fd        = jpegInMemInfo.fd;
2859     srcBuf->src_image[0].buf_vaddr = (uint8_t*)jpegInMem->data;
2860     //srcBuf->src_image[0].offset    = 0;
2861     srcBuf->src_dim.width       = camHal->pictWidth;
2862     srcBuf->src_dim.height      = camHal->pictHeight;
2863     srcBuf->out_dim.width       = camHal->pictWidth;
2864     srcBuf->out_dim.height      = camHal->pictHeight;
2865     srcBuf->crop.offset_x       = 0;
2866     srcBuf->crop.offset_y       = 0;
2867     srcBuf->crop.width          = srcBuf->src_dim.width;
2868     srcBuf->crop.height         = srcBuf->src_dim.height;
2869     srcBuf->quality             = camHal->pictJpegQlty;
2870 
2871     /* TBD:Fill thumbnail image information */
2872 
2873     /* Fill out buf information */
2874     mmJpegJob.encode_job.encode_parm.buf_info.sink_img.buf_vaddr =
2875                             (uint8_t*)camHal->pictMem.camera_memory[0]->data;
2876     mmJpegJob.encode_job.encode_parm.buf_info.sink_img.fd = 0;
2877     /* TBD: hard coded for 1.5 bytes per pixel */
2878     mmJpegJob.encode_job.encode_parm.buf_info.sink_img.buf_len =
2879                             camHal->pictWidth * camHal->pictHeight * 1.5;
2880 
2881     /************************************************************************/
2882     /* - Initialize jpeg encoder and call Jpeg encoder start                */
2883     /************************************************************************/
2884     memset(&mmJpegOps, 0, sizeof(mm_jpeg_ops_t));
2885     jpegEncHdl = jpeg_open(&mmJpegOps);
2886     if(!jpegEncHdl){
2887         ALOGE("%s: Failed to open Jpeg Encoder instance", __func__);
2888     }else
2889         ALOGD("%s: jpegEncHdl = %d", __func__, jpegEncHdl);
2890 
2891     camHal->jpegEncInProgress = 1;
2892     rc = mmJpegOps.start_job(jpegEncHdl, &mmJpegJob, &jobId);
2893 
2894     /************************************************************************/
2895     /* - Wait for JPEG encoder to complete encoding                         */
2896     /************************************************************************/
2897     pthread_mutex_init(&camHal->jpegEncMutex, NULL);
2898     pthread_cond_init(&camHal->jpegEncCond, NULL);
2899 
2900     pthread_mutex_lock(&camHal->jpegEncMutex);
2901     while(camHal->jpegEncInProgress)
2902         pthread_cond_wait(&camHal->jpegEncCond, &camHal->jpegEncMutex);
2903     pthread_mutex_unlock(&camHal->jpegEncMutex);
2904 
2905     /************************************************************************/
2906     /* - De-allocate Jpeg input buffer from ION memory                      */
2907     /************************************************************************/
2908     if(jpegInMem)
2909         jpegInMem->release(jpegInMem);
2910 
2911     rc = deallocate_ion_memory(&jpegInMemInfo);
2912     if(rc)
2913         ALOGE("%s: ION memory de-allocation failed", __func__);
2914 
2915     ALOGI("%s: X rc = %d", __func__, rc);
2916     return rc;
2917 }
2918 
2919 /******************************************************************************
2920  * Function: jpegEncodeCb
2921  * Description: This is a call back function registered with JPEG encoder.
2922  *              Jpeg encoder calls this function on completion of encoding
2923  *
2924  * Input parameters:
2925  *  camHal                  - camera HAL handle
2926  *
2927  * Return values:
2928  *   0  No Error
2929  *  -1  Error
2930  *
2931  * Notes: none
2932  *****************************************************************************/
jpegEncodeCb(jpeg_job_status_t status,uint8_t thumbnailDroppedFlag,uint32_t client_hdl,uint32_t jobId,uint8_t * out_data,uint32_t data_size,void * userData)2933 void jpegEncodeCb   (jpeg_job_status_t status,
2934                        uint8_t thumbnailDroppedFlag,
2935                        uint32_t client_hdl,
2936                        uint32_t jobId,
2937                        uint8_t* out_data,
2938                        uint32_t data_size,
2939                        void *userData)
2940 {
2941     int rc = 0;
2942     camera_hardware_t *camHal = NULL;
2943 
2944     ALOGI("%s: E status = %d", __func__, status);
2945 
2946     camHal = (camera_hardware_t*) userData;
2947 
2948     if(JPEG_JOB_STATUS_DONE == status){
2949         ALOGD("%s: JPEG encode successful. out_data:%p, size: %d", __func__,
2950             out_data, data_size);
2951         camHal->jpegEncInProgress = 0;
2952     }
2953 
2954     pthread_mutex_lock(&camHal->jpegEncMutex);
2955     pthread_cond_signal(&camHal->jpegEncCond);
2956     pthread_mutex_unlock(&camHal->jpegEncMutex);
2957 
2958     ALOGI("%s: X", __func__);
2959     return;
2960 }
2961 
2962 /******************************************************************************/
2963 }; // namespace android
2964