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_id_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