1 /* Copyright (c) 2015-2016, The Linux Foundation. All rights reserved.
2 *
3 * Redistribution and use in source and binary forms, with or without
4 * modification, are permitted provided that the following conditions are
5 * met:
6 * * Redistributions of source code must retain the above copyright
7 * notice, this list of conditions and the following disclaimer.
8 * * Redistributions in binary form must reproduce the above
9 * copyright notice, this list of conditions and the following
10 * disclaimer in the documentation and/or other materials provided
11 * with the distribution.
12 * * Neither the name of The Linux Foundation nor the names of its
13 * contributors may be used to endorse or promote products derived
14 * from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
23 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
25 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
26 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 *
28 */
29
30 #define LOG_TAG "QCameraMuxer"
31
32 // System dependencies
33 #include <fcntl.h>
34 #include <stdio.h>
35 #include <stdlib.h>
36 #include <utils/Errors.h>
37 #define STAT_H <SYSTEM_HEADER_PREFIX/stat.h>
38 #include STAT_H
39
40 // Camera dependencies
41 #include "QCameraMuxer.h"
42 #include "QCamera2HWI.h"
43 #include "QCamera3HWI.h"
44
45 extern "C" {
46 #include "mm_camera_dbg.h"
47 }
48
49 /* Muxer implementation */
50 using namespace android;
51 namespace qcamera {
52
53 QCameraMuxer *gMuxer = NULL;
54
55 //Error Check Macros
56 #define CHECK_MUXER() \
57 if (!gMuxer) { \
58 LOGE("Error getting muxer "); \
59 return; \
60 } \
61
62 #define CHECK_MUXER_ERROR() \
63 if (!gMuxer) { \
64 LOGE("Error getting muxer "); \
65 return -ENODEV; \
66 } \
67
68 #define CHECK_CAMERA(pCam) \
69 if (!pCam) { \
70 LOGE("Error getting physical camera"); \
71 return; \
72 } \
73
74 #define CHECK_CAMERA_ERROR(pCam) \
75 if (!pCam) { \
76 LOGE("Error getting physical camera"); \
77 return -ENODEV; \
78 } \
79
80 #define CHECK_HWI(hwi) \
81 if (!hwi) { \
82 LOGE("Error !! HWI not found!!"); \
83 return; \
84 } \
85
86 #define CHECK_HWI_ERROR(hwi) \
87 if (!hwi) { \
88 LOGE("Error !! HWI not found!!"); \
89 return -ENODEV; \
90 } \
91
92
93 /*===========================================================================
94 * FUNCTION : getCameraMuxer
95 *
96 * DESCRIPTION : Creates Camera Muxer if not created
97 *
98 * PARAMETERS:
99 * @pMuxer : Pointer to retrieve Camera Muxer
100 * @num_of_cameras : Number of Physical Cameras on device
101 *
102 * RETURN : NONE
103 *==========================================================================*/
getCameraMuxer(QCameraMuxer ** pMuxer,uint32_t num_of_cameras)104 void QCameraMuxer::getCameraMuxer(
105 QCameraMuxer** pMuxer, uint32_t num_of_cameras)
106 {
107 *pMuxer = NULL;
108 if (!gMuxer) {
109 gMuxer = new QCameraMuxer(num_of_cameras);
110 }
111 CHECK_MUXER();
112 *pMuxer = gMuxer;
113 LOGH("gMuxer: %p ", gMuxer);
114 return;
115 }
116
117 /*===========================================================================
118 * FUNCTION : QCameraMuxer
119 *
120 * DESCRIPTION : QCameraMuxer Constructor
121 *
122 * PARAMETERS:
123 * @num_of_cameras : Number of Physical Cameras on device
124 *
125 *==========================================================================*/
QCameraMuxer(uint32_t num_of_cameras)126 QCameraMuxer::QCameraMuxer(uint32_t num_of_cameras)
127 : mJpegClientHandle(0),
128 m_pPhyCamera(NULL),
129 m_pLogicalCamera(NULL),
130 m_pCallbacks(NULL),
131 m_bAuxCameraExposed(FALSE),
132 m_nPhyCameras(num_of_cameras),
133 m_nLogicalCameras(0),
134 m_MainJpegQ(releaseJpegInfo, this),
135 m_AuxJpegQ(releaseJpegInfo, this),
136 m_pRelCamMpoJpeg(NULL),
137 m_pMpoCallbackCookie(NULL),
138 m_pJpegCallbackCookie(NULL),
139 m_bDumpImages(FALSE),
140 m_bMpoEnabled(TRUE),
141 m_bFrameSyncEnabled(FALSE),
142 m_bRecordingHintInternallySet(FALSE)
143 {
144 setupLogicalCameras();
145 memset(&mJpegOps, 0, sizeof(mJpegOps));
146 memset(&mJpegMpoOps, 0, sizeof(mJpegMpoOps));
147 memset(&mGetMemoryCb, 0, sizeof(mGetMemoryCb));
148 memset(&mDataCb, 0, sizeof(mDataCb));
149
150 // initialize mutex for MPO composition
151 pthread_mutex_init(&m_JpegLock, NULL);
152 // launch MPO composition thread
153 m_ComposeMpoTh.launch(composeMpoRoutine, this);
154
155 //Check whether dual camera images need to be dumped
156 char prop[PROPERTY_VALUE_MAX];
157 property_get("persist.camera.dual.camera.dump", prop, "0");
158 m_bDumpImages = atoi(prop);
159 LOGH("dualCamera dump images:%d ", m_bDumpImages);
160 }
161
162 /*===========================================================================
163 * FUNCTION : ~QCameraMuxer
164 *
165 * DESCRIPTION : QCameraMuxer Desctructor
166 *
167 *==========================================================================*/
~QCameraMuxer()168 QCameraMuxer::~QCameraMuxer() {
169 if (m_pLogicalCamera) {
170 delete [] m_pLogicalCamera;
171 m_pLogicalCamera = NULL;
172 }
173 if (m_pPhyCamera) {
174 delete [] m_pPhyCamera;
175 m_pPhyCamera = NULL;
176 }
177
178 if (NULL != m_pRelCamMpoJpeg) {
179 m_pRelCamMpoJpeg->release(m_pRelCamMpoJpeg);
180 m_pRelCamMpoJpeg = NULL;
181 }
182 // flush Jpeg Queues
183 m_MainJpegQ.flush();
184 m_AuxJpegQ.flush();
185
186 // stop and exit MPO composition thread
187 m_ComposeMpoTh.sendCmd(CAMERA_CMD_TYPE_STOP_DATA_PROC, TRUE, FALSE);
188 m_ComposeMpoTh.exit();
189
190 pthread_mutex_destroy(&m_JpegLock);
191 }
192
193 /*===========================================================================
194 * FUNCTION : get_number_of_cameras
195 *
196 * DESCRIPTION : Provide number of Logical Cameras
197 *
198 * RETURN : Number of logical Cameras
199 *==========================================================================*/
get_number_of_cameras()200 int QCameraMuxer::get_number_of_cameras()
201 {
202 return gMuxer->getNumberOfCameras();
203 }
204
205 /*===========================================================================
206 * FUNCTION : get_camera_info
207 *
208 * DESCRIPTION : get logical camera info
209 *
210 * PARAMETERS:
211 * @camera_id : Logical Camera ID
212 * @info : Logical Main Camera Info
213 *
214 * RETURN :
215 * NO_ERROR : success
216 * ENODEV : Camera not found
217 * other: non-zero failure code
218 *==========================================================================*/
get_camera_info(int camera_id,struct camera_info * info)219 int QCameraMuxer::get_camera_info(int camera_id, struct camera_info *info)
220 {
221 int rc = NO_ERROR;
222 LOGH("E");
223 cam_sync_type_t type;
224 if ((camera_id < 0) || (camera_id >= gMuxer->getNumberOfCameras())) {
225 LOGE("Camera id %d not found!", camera_id);
226 return -ENODEV;
227 }
228 if(info) {
229 rc = gMuxer->getCameraInfo(camera_id, info, &type);
230 }
231 LOGH("X, rc: %d", rc);
232 return rc;
233 }
234
235
236 /*===========================================================================
237 * FUNCTION : set_callbacks
238 *
239 * DESCRIPTION : Not Implemented
240 *
241 * PARAMETERS:
242 * @callbacks : Camera Module Callbacks
243 *
244 * RETURN :
245 * NO_ERROR : success
246 * other: non-zero failure code
247 *==========================================================================*/
set_callbacks(__unused const camera_module_callbacks_t * callbacks)248 int QCameraMuxer::set_callbacks(__unused const camera_module_callbacks_t *callbacks)
249 {
250 // Not implemented
251 return NO_ERROR;
252 }
253
254 /*===========================================================================
255 * FUNCTION : camera_device_open
256 *
257 * DESCRIPTION: static function to open a camera device by its ID
258 *
259 * PARAMETERS :
260 * @modue: hw module
261 * @id : camera ID
262 * @hw_device : ptr to struct storing camera hardware device info
263 *
264 * RETURN :
265 * NO_ERROR : success
266 * BAD_VALUE : Invalid Camera ID
267 * other: non-zero failure code
268 *==========================================================================*/
camera_device_open(__unused const struct hw_module_t * module,const char * id,struct hw_device_t ** hw_device)269 int QCameraMuxer::camera_device_open(
270 __unused const struct hw_module_t *module, const char *id,
271 struct hw_device_t **hw_device)
272 {
273 int rc = NO_ERROR;
274 LOGH("id= %d",atoi(id));
275 if (!id) {
276 LOGE("Invalid camera id");
277 return BAD_VALUE;
278 }
279
280 rc = gMuxer->cameraDeviceOpen(atoi(id), hw_device);
281 LOGH("id= %d, rc: %d", atoi(id), rc);
282 return rc;
283 }
284
285 /*===========================================================================
286 * FUNCTION : open_legacy
287 *
288 * DESCRIPTION: static function to open a camera device by its ID
289 *
290 * PARAMETERS :
291 * @modue: hw module
292 * @id : camera ID
293 * @halVersion: hal version
294 * @hw_device : ptr to struct storing camera hardware device info
295 *
296 * RETURN :
297 * NO_ERROR : success
298 * BAD_VALUE : Invalid Camera ID
299 * other: non-zero failure code
300 *==========================================================================*/
open_legacy(__unused const struct hw_module_t * module,const char * id,__unused uint32_t halVersion,struct hw_device_t ** hw_device)301 int QCameraMuxer::open_legacy(__unused const struct hw_module_t* module,
302 const char* id, __unused uint32_t halVersion, struct hw_device_t** hw_device)
303 {
304 int rc = NO_ERROR;
305 LOGH("id= %d", atoi(id));
306 if (!id) {
307 LOGE("Invalid camera id");
308 return BAD_VALUE;
309 }
310
311 rc = gMuxer->cameraDeviceOpen(atoi(id), hw_device);
312 LOGH("id= %d, rc: %d", atoi(id), rc);
313 return rc;
314 }
315
316 /*===========================================================================
317 * FUNCTION : set_preview_window
318 *
319 * DESCRIPTION: Set Preview window for main camera
320 *
321 * PARAMETERS :
322 * @device : camera hardware device info
323 * @window: Preview window ops
324 *
325 * RETURN :
326 * NO_ERROR : success
327 * other: non-zero failure code
328 *==========================================================================*/
set_preview_window(struct camera_device * device,struct preview_stream_ops * window)329 int QCameraMuxer::set_preview_window(struct camera_device * device,
330 struct preview_stream_ops *window)
331 {
332 int rc = NO_ERROR;
333 CHECK_MUXER_ERROR();
334 qcamera_physical_descriptor_t *pCam = NULL;
335 qcamera_logical_descriptor_t *cam = gMuxer->getLogicalCamera(device);
336 CHECK_CAMERA_ERROR(cam);
337
338 for (uint32_t i = 0; i < cam->numCameras; i++) {
339 pCam = gMuxer->getPhysicalCamera(cam, i);
340 CHECK_CAMERA_ERROR(pCam);
341
342 // Set preview window only for primary camera
343 if (pCam->mode == CAM_MODE_PRIMARY) {
344 QCamera2HardwareInterface *hwi = pCam->hwi;
345 CHECK_HWI_ERROR(hwi);
346 rc = hwi->set_preview_window(pCam->dev, window);
347 if (rc != NO_ERROR) {
348 LOGE("Error!! setting preview window");
349 return rc;
350 }
351 break;
352 }
353 }
354 return rc;
355 }
356
357 /*===========================================================================
358 * FUNCTION : set_callBacks
359 *
360 * DESCRIPTION: Set Framework callbacks to notify various frame data asynchronously
361 *
362 * PARAMETERS :
363 * @device : camera hardware device info
364 * @notify_cb: Notification callback
365 * @data_cb: data callback
366 * @data_cb_timestamp: data timestamp callback
367 * @get_memory: callback to obtain memory
368 * @user : userdata
369 *
370 * RETURN : None
371 *==========================================================================*/
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)372 void QCameraMuxer::set_callBacks(struct camera_device * device,
373 camera_notify_callback notify_cb,
374 camera_data_callback data_cb,
375 camera_data_timestamp_callback data_cb_timestamp,
376 camera_request_memory get_memory,
377 void *user)
378 {
379 LOGH("E");
380 CHECK_MUXER();
381 int rc = NO_ERROR;
382 qcamera_physical_descriptor_t *pCam = NULL;
383 qcamera_logical_descriptor_t *cam = gMuxer->getLogicalCamera(device);
384 CHECK_CAMERA(cam);
385
386 // Set callbacks to HWI
387 for (uint32_t i = 0; i < cam->numCameras; i++) {
388 pCam = gMuxer->getPhysicalCamera(cam, i);
389 CHECK_CAMERA(pCam);
390
391 QCamera2HardwareInterface *hwi = pCam->hwi;
392 CHECK_HWI(hwi);
393
394 hwi->set_CallBacks(pCam->dev, notify_cb, data_cb, data_cb_timestamp,
395 get_memory, user);
396
397 // Set JPG callbacks
398 // sending the physical camera description with the Jpeg callback
399 // this will be retrieved in callbacks to get the cam instance
400 // delivering JPEGs
401 hwi->setJpegCallBacks(jpeg_data_callback, (void*)pCam);
402
403 if (pCam->mode == CAM_MODE_PRIMARY) {
404 rc = gMuxer->setMainJpegCallbackCookie((void*)(pCam));
405 if(rc != NO_ERROR) {
406 LOGW("Error setting Jpeg callback cookie");
407 }
408 }
409 }
410 // Store callback in Muxer to send data callbacks
411 rc = gMuxer->setDataCallback(data_cb);
412 if(rc != NO_ERROR) {
413 LOGW("Error setting data callback");
414 }
415 // memory callback stored to allocate memory for MPO buffer
416 rc = gMuxer->setMemoryCallback(get_memory);
417 if(rc != NO_ERROR) {
418 LOGW("Error setting memory callback");
419 }
420 // actual user callback cookie is saved in Muxer
421 // this will be used to deliver final MPO callback to the framework
422 rc = gMuxer->setMpoCallbackCookie(user);
423 if(rc != NO_ERROR) {
424 LOGW("Error setting mpo cookie");
425 }
426
427 LOGH("X");
428
429 }
430
431 /*===========================================================================
432 * FUNCTION : enable_msg_type
433 *
434 * DESCRIPTION: Enable msg_type to send callbacks
435 *
436 * PARAMETERS :
437 * @device : camera hardware device info
438 * @msg_type: callback Message type to be enabled
439 *
440 * RETURN : None
441 *==========================================================================*/
enable_msg_type(struct camera_device * device,int32_t msg_type)442 void QCameraMuxer::enable_msg_type(struct camera_device * device, int32_t msg_type)
443 {
444 LOGH("E");
445 CHECK_MUXER();
446 qcamera_physical_descriptor_t *pCam = NULL;
447 qcamera_logical_descriptor_t *cam = gMuxer->getLogicalCamera(device);
448 CHECK_CAMERA(cam);
449
450 for (uint32_t i = 0; i < cam->numCameras; i++) {
451 pCam = gMuxer->getPhysicalCamera(cam, i);
452 CHECK_CAMERA(pCam);
453 QCamera2HardwareInterface *hwi = pCam->hwi;
454 CHECK_HWI(hwi);
455 hwi->enable_msg_type(pCam->dev, msg_type);
456 }
457 LOGH("X");
458 }
459
460 /*===========================================================================
461 * FUNCTION : disable_msg_type
462 *
463 * DESCRIPTION: disable msg_type to send callbacks
464 *
465 * PARAMETERS :
466 * @device : camera hardware device info
467 * @msg_type: callback Message type to be disabled
468 *
469 * RETURN : None
470 *==========================================================================*/
disable_msg_type(struct camera_device * device,int32_t msg_type)471 void QCameraMuxer::disable_msg_type(struct camera_device * device, int32_t msg_type)
472 {
473 LOGH("E");
474 CHECK_MUXER();
475 qcamera_physical_descriptor_t *pCam = NULL;
476 qcamera_logical_descriptor_t *cam = gMuxer->getLogicalCamera(device);
477 CHECK_CAMERA(cam);
478
479 for (uint32_t i = 0; i < cam->numCameras; i++) {
480 pCam = gMuxer->getPhysicalCamera(cam, i);
481 CHECK_CAMERA(pCam);
482 QCamera2HardwareInterface *hwi = pCam->hwi;
483 CHECK_HWI(hwi);
484 hwi->disable_msg_type(pCam->dev, msg_type);
485 }
486 LOGH("X");
487 }
488
489 /*===========================================================================
490 * FUNCTION : msg_type_enabled
491 *
492 * DESCRIPTION: Check if message type enabled
493 *
494 * PARAMETERS :
495 * @device : camera hardware device info
496 * @msg_type: message type
497 *
498 * RETURN : true/false
499 *==========================================================================*/
msg_type_enabled(struct camera_device * device,int32_t msg_type)500 int QCameraMuxer::msg_type_enabled(struct camera_device * device, int32_t msg_type)
501 {
502 LOGH("E");
503 CHECK_MUXER_ERROR();
504 qcamera_physical_descriptor_t *pCam = NULL;
505 qcamera_logical_descriptor_t *cam = gMuxer->getLogicalCamera(device);
506 CHECK_CAMERA_ERROR(cam);
507
508 for (uint32_t i = 0; i < cam->numCameras; i++) {
509 pCam = gMuxer->getPhysicalCamera(cam, i);
510 CHECK_CAMERA_ERROR(pCam);
511
512 QCamera2HardwareInterface *hwi = pCam->hwi;
513 CHECK_HWI_ERROR(hwi);
514
515 if (pCam->mode == CAM_MODE_PRIMARY) {
516 return hwi->msg_type_enabled(pCam->dev, msg_type);
517 }
518 }
519 LOGH("X");
520 return false;
521 }
522
523 /*===========================================================================
524 * FUNCTION : start_preview
525 *
526 * DESCRIPTION: Starts logical camera preview
527 *
528 * PARAMETERS :
529 * @device : camera hardware device info
530 *
531 * RETURN :
532 * NO_ERROR : success
533 * other: non-zero failure code
534 *==========================================================================*/
start_preview(struct camera_device * device)535 int QCameraMuxer::start_preview(struct camera_device * device)
536 {
537 LOGH("E");
538 CHECK_MUXER_ERROR();
539 int rc = NO_ERROR;
540 qcamera_physical_descriptor_t *pCam = NULL;
541 qcamera_logical_descriptor_t *cam = gMuxer->getLogicalCamera(device);
542 CHECK_CAMERA_ERROR(cam);
543
544 // prepare preview first for all cameras
545 for (uint32_t i = 0; i < cam->numCameras; i++) {
546 pCam = gMuxer->getPhysicalCamera(cam, i);
547 CHECK_CAMERA_ERROR(pCam);
548
549 QCamera2HardwareInterface *hwi = pCam->hwi;
550 CHECK_HWI_ERROR(hwi);
551
552 rc = hwi->prepare_preview(pCam->dev);
553 if (rc != NO_ERROR) {
554 LOGE("Error preparing preview !! ");
555 return rc;
556 }
557 }
558
559 if (cam->numCameras > 1) {
560 uint sessionId = 0;
561 // Set up sync for camera sessions
562 for (uint32_t i = 0; i < cam->numCameras; i++) {
563 pCam = gMuxer->getPhysicalCamera(cam, i);
564 CHECK_CAMERA_ERROR(pCam);
565
566 QCamera2HardwareInterface *hwi = pCam->hwi;
567 CHECK_HWI_ERROR(hwi);
568
569 if(pCam->mode == CAM_MODE_PRIMARY) {
570 // bundle primary cam with all aux cameras
571 for (uint32_t j = 0; j < cam->numCameras; j++) {
572 if (j == cam->nPrimaryPhyCamIndex) {
573 continue;
574 }
575 sessionId = cam->sId[j];
576 LOGH("Related cam id: %d, server id: %d sync ON"
577 " related session_id %d",
578 cam->pId[i], cam->sId[i], sessionId);
579 rc = hwi->bundleRelatedCameras(true, sessionId);
580 if (rc != NO_ERROR) {
581 LOGE("Error Bundling physical cameras !! ");
582 return rc;
583 }
584 }
585 }
586
587 if (pCam->mode == CAM_MODE_SECONDARY) {
588 // bundle all aux cam with primary cams
589 sessionId = cam->sId[cam->nPrimaryPhyCamIndex];
590 LOGH("Related cam id: %d, server id: %d sync ON"
591 " related session_id %d",
592 cam->pId[i], cam->sId[i], sessionId);
593 rc = hwi->bundleRelatedCameras(true, sessionId);
594 if (rc != NO_ERROR) {
595 LOGE("Error Bundling physical cameras !! ");
596 return rc;
597 }
598 }
599 }
600
601 // Remember Sync is ON
602 cam->bSyncOn = true;
603 }
604 // Start Preview for all cameras
605 for (uint32_t i = 0; i < cam->numCameras; i++) {
606 pCam = gMuxer->getPhysicalCamera(cam, i);
607 CHECK_CAMERA_ERROR(pCam);
608
609 QCamera2HardwareInterface *hwi = pCam->hwi;
610 CHECK_HWI_ERROR(hwi);
611 rc = hwi->start_preview(pCam->dev);
612 if (rc != NO_ERROR) {
613 LOGE("Error starting preview !! ");
614 return rc;
615 }
616 }
617 LOGH("X");
618 return rc;
619 }
620
621 /*===========================================================================
622 * FUNCTION : stop_preview
623 *
624 * DESCRIPTION: Stops logical camera preview
625 *
626 * PARAMETERS :
627 * @device : camera hardware device info
628 *
629 * RETURN : None
630 *==========================================================================*/
stop_preview(struct camera_device * device)631 void QCameraMuxer::stop_preview(struct camera_device * device)
632 {
633 LOGH("E");
634 CHECK_MUXER();
635 qcamera_physical_descriptor_t *pCam = NULL;
636 qcamera_logical_descriptor_t *cam = gMuxer->getLogicalCamera(device);
637 CHECK_CAMERA(cam);
638
639 for (uint32_t i = 0; i < cam->numCameras; i++) {
640 pCam = gMuxer->getPhysicalCamera(cam, i);
641 CHECK_CAMERA(pCam);
642
643 QCamera2HardwareInterface *hwi = pCam->hwi;
644 CHECK_HWI(hwi);
645
646 QCamera2HardwareInterface::stop_preview(pCam->dev);
647 }
648
649 //Flush JPEG Queues. Nodes in Main and Aux JPEGQ are not valid after preview stopped.
650 gMuxer->m_MainJpegQ.flush();
651 gMuxer->m_AuxJpegQ.flush();
652 LOGH(" X");
653 }
654
655 /*===========================================================================
656 * FUNCTION : preview_enabled
657 *
658 * DESCRIPTION: Checks preview enabled
659 *
660 * PARAMETERS :
661 * @device : camera hardware device info
662 *
663 * RETURN : true/false
664 *==========================================================================*/
preview_enabled(struct camera_device * device)665 int QCameraMuxer::preview_enabled(struct camera_device * device)
666 {
667 LOGH("E");
668 CHECK_MUXER_ERROR();
669 qcamera_physical_descriptor_t *pCam = NULL;
670 qcamera_logical_descriptor_t *cam = gMuxer->getLogicalCamera(device);
671 CHECK_CAMERA_ERROR(cam);
672
673 for (uint32_t i = 0; i < cam->numCameras; i++) {
674 pCam = gMuxer->getPhysicalCamera(cam, i);
675 CHECK_CAMERA_ERROR(pCam);
676
677 QCamera2HardwareInterface *hwi = pCam->hwi;
678 CHECK_HWI_ERROR(hwi);
679
680 if (pCam->mode == CAM_MODE_PRIMARY) {
681 return hwi->preview_enabled(pCam->dev);
682 }
683 }
684 LOGH("X");
685 return false;
686 }
687
688 /*===========================================================================
689 * FUNCTION : store_meta_data_in_buffers
690 *
691 * DESCRIPTION: Stores metadata in buffers
692 *
693 * PARAMETERS :
694 * @device : camera hardware device info
695 * @enable: Enable/disable metadata
696 *
697 * RETURN :
698 * NO_ERROR : success
699 * other: non-zero failure code
700 *==========================================================================*/
store_meta_data_in_buffers(struct camera_device * device,int enable)701 int QCameraMuxer::store_meta_data_in_buffers(struct camera_device * device, int enable)
702 {
703 LOGH("E");
704 CHECK_MUXER_ERROR();
705 int rc = NO_ERROR;
706 qcamera_physical_descriptor_t *pCam = NULL;
707 qcamera_logical_descriptor_t *cam = gMuxer->getLogicalCamera(device);
708 CHECK_CAMERA_ERROR(cam);
709
710 for (uint32_t i = 0; i < cam->numCameras; i++) {
711 pCam = gMuxer->getPhysicalCamera(cam, i);
712 CHECK_CAMERA_ERROR(pCam);
713
714 QCamera2HardwareInterface *hwi = pCam->hwi;
715 CHECK_HWI_ERROR(hwi);
716
717 rc = hwi->store_meta_data_in_buffers(pCam->dev, enable);
718 if (rc != NO_ERROR) {
719 LOGE("Error storing metat data !! ");
720 return rc;
721 }
722 }
723 LOGH("X");
724 return rc;
725 }
726
727 /*===========================================================================
728 * FUNCTION : start_recording
729 *
730 * DESCRIPTION: Starts recording on camcorder
731 *
732 * PARAMETERS :
733 * @device : camera hardware device info
734 *
735 * RETURN :
736 * NO_ERROR : success
737 * other: non-zero failure code
738 *==========================================================================*/
start_recording(struct camera_device * device)739 int QCameraMuxer::start_recording(struct camera_device * device)
740 {
741 LOGH("E");
742 CHECK_MUXER_ERROR();
743 int rc = NO_ERROR;
744 bool previewRestartNeeded = false;
745 qcamera_physical_descriptor_t *pCam = NULL;
746 qcamera_logical_descriptor_t *cam = gMuxer->getLogicalCamera(device);
747 CHECK_CAMERA_ERROR(cam);
748
749 // In cases where recording hint is not set, hwi->start_recording will
750 // internally restart the preview.
751 // To take the preview restart control in muxer,
752 // 1. call pre_start_recording first
753 for (uint32_t i = 0; i < cam->numCameras; i++) {
754 pCam = gMuxer->getPhysicalCamera(cam, i);
755 CHECK_CAMERA_ERROR(pCam);
756
757 QCamera2HardwareInterface *hwi = pCam->hwi;
758 CHECK_HWI_ERROR(hwi);
759
760 rc = hwi->pre_start_recording(pCam->dev);
761 if (rc != NO_ERROR) {
762 LOGE("Error preparing recording start!! ");
763 return rc;
764 }
765 }
766
767 // 2. Check if preview restart is needed. Check all cameras.
768 for (uint32_t i = 0; i < cam->numCameras; i++) {
769 pCam = gMuxer->getPhysicalCamera(cam, i);
770 CHECK_CAMERA_ERROR(pCam);
771
772 QCamera2HardwareInterface *hwi = pCam->hwi;
773 CHECK_HWI_ERROR(hwi);
774
775 if (hwi->isPreviewRestartNeeded()) {
776 previewRestartNeeded = hwi->isPreviewRestartNeeded();
777 break;
778 }
779 }
780
781 if (previewRestartNeeded) {
782 // 3. if preview restart needed. stop the preview first
783 for (uint32_t i = 0; i < cam->numCameras; i++) {
784 pCam = gMuxer->getPhysicalCamera(cam, i);
785 CHECK_CAMERA_ERROR(pCam);
786
787 QCamera2HardwareInterface *hwi = pCam->hwi;
788 CHECK_HWI_ERROR(hwi);
789
790 rc = hwi->restart_stop_preview(pCam->dev);
791 if (rc != NO_ERROR) {
792 LOGE("Error in restart stop preview!! ");
793 return rc;
794 }
795 }
796
797 //4. Update the recording hint value to TRUE
798 for (uint32_t i = 0; i < cam->numCameras; i++) {
799 pCam = gMuxer->getPhysicalCamera(cam, i);
800 CHECK_CAMERA_ERROR(pCam);
801
802 QCamera2HardwareInterface *hwi = pCam->hwi;
803 CHECK_HWI_ERROR(hwi);
804
805 rc = hwi->setRecordingHintValue(TRUE);
806 if (rc != NO_ERROR) {
807 LOGE("Error in setting recording hint value!! ");
808 return rc;
809 }
810 gMuxer->m_bRecordingHintInternallySet = TRUE;
811 }
812
813 // 5. start the preview
814 for (uint32_t i = 0; i < cam->numCameras; i++) {
815 pCam = gMuxer->getPhysicalCamera(cam, i);
816 CHECK_CAMERA_ERROR(pCam);
817
818 QCamera2HardwareInterface *hwi = pCam->hwi;
819 CHECK_HWI_ERROR(hwi);
820
821 rc = hwi->restart_start_preview(pCam->dev);
822 if (rc != NO_ERROR) {
823 LOGE("Error in restart start preview!! ");
824 return rc;
825 }
826 }
827 }
828
829 for (uint32_t i = 0; i < cam->numCameras; i++) {
830 pCam = gMuxer->getPhysicalCamera(cam, i);
831 CHECK_CAMERA_ERROR(pCam);
832
833 QCamera2HardwareInterface *hwi = pCam->hwi;
834 CHECK_HWI_ERROR(hwi);
835
836 if (pCam->mode == CAM_MODE_PRIMARY) {
837 rc = hwi->start_recording(pCam->dev);
838 if (rc != NO_ERROR) {
839 LOGE("Error starting recording!! ");
840 }
841 break;
842 }
843 }
844 LOGH("X");
845 return rc;
846 }
847
848 /*===========================================================================
849 * FUNCTION : stop_recording
850 *
851 * DESCRIPTION: Stops recording on camcorder
852 *
853 * PARAMETERS :
854 * @device : camera hardware device info
855 *
856 * RETURN : None
857 *==========================================================================*/
stop_recording(struct camera_device * device)858 void QCameraMuxer::stop_recording(struct camera_device * device)
859 {
860
861 int rc = NO_ERROR;
862 LOGH("E");
863
864 CHECK_MUXER();
865 qcamera_physical_descriptor_t *pCam = NULL;
866 qcamera_logical_descriptor_t *cam = gMuxer->getLogicalCamera(device);
867 CHECK_CAMERA(cam);
868
869 for (uint32_t i = 0; i < cam->numCameras; i++) {
870 pCam = gMuxer->getPhysicalCamera(cam, i);
871 CHECK_CAMERA(pCam);
872
873 QCamera2HardwareInterface *hwi = pCam->hwi;
874 CHECK_HWI(hwi);
875
876 if (pCam->mode == CAM_MODE_PRIMARY) {
877 QCamera2HardwareInterface::stop_recording(pCam->dev);
878 break;
879 }
880 }
881
882 // If recording hint is set internally to TRUE,
883 // we need to set it to FALSE.
884 // preview restart is needed in between
885 if (gMuxer->m_bRecordingHintInternallySet) {
886 // stop the preview first
887 for (uint32_t i = 0; i < cam->numCameras; i++) {
888 pCam = gMuxer->getPhysicalCamera(cam, i);
889 CHECK_CAMERA(pCam);
890
891 QCamera2HardwareInterface *hwi = pCam->hwi;
892 CHECK_HWI(hwi);
893
894 rc = hwi->restart_stop_preview(pCam->dev);
895 if (rc != NO_ERROR) {
896 LOGE("Error in restart stop preview!! ");
897 return;
898 }
899 }
900
901 // Update the recording hint value to FALSE
902 for (uint32_t i = 0; i < cam->numCameras; i++) {
903 pCam = gMuxer->getPhysicalCamera(cam, i);
904 CHECK_CAMERA(pCam);
905
906 QCamera2HardwareInterface *hwi = pCam->hwi;
907 CHECK_HWI(hwi);
908
909 rc = hwi->setRecordingHintValue(FALSE);
910 if (rc != NO_ERROR) {
911 LOGE("Error in setting recording hint value!! ");
912 return;
913 }
914 gMuxer->m_bRecordingHintInternallySet = FALSE;
915 }
916
917 // start the preview
918 for (uint32_t i = 0; i < cam->numCameras; i++) {
919 pCam = gMuxer->getPhysicalCamera(cam, i);
920 CHECK_CAMERA(pCam);
921
922 QCamera2HardwareInterface *hwi = pCam->hwi;
923 CHECK_HWI(hwi);
924
925 rc = hwi->restart_start_preview(pCam->dev);
926 if (rc != NO_ERROR) {
927 LOGE("Error in restart start preview!! ");
928 return;
929 }
930 }
931 }
932 LOGH("X");
933 }
934
935 /*===========================================================================
936 * FUNCTION : recording_enabled
937 *
938 * DESCRIPTION: Checks for recording enabled
939 *
940 * PARAMETERS :
941 * @device : camera hardware device info
942 *
943 * RETURN : true/false
944 *==========================================================================*/
recording_enabled(struct camera_device * device)945 int QCameraMuxer::recording_enabled(struct camera_device * device)
946 {
947 LOGH("E");
948 CHECK_MUXER_ERROR();
949 qcamera_physical_descriptor_t *pCam = NULL;
950 qcamera_logical_descriptor_t *cam = gMuxer->getLogicalCamera(device);
951 CHECK_CAMERA_ERROR(cam);
952
953 for (uint32_t i = 0; i < cam->numCameras; i++) {
954 pCam = gMuxer->getPhysicalCamera(cam, i);
955 CHECK_CAMERA_ERROR(pCam);
956
957 QCamera2HardwareInterface *hwi = pCam->hwi;
958 CHECK_HWI_ERROR(hwi);
959
960 if (pCam->mode == CAM_MODE_PRIMARY) {
961 return hwi->recording_enabled(pCam->dev);
962 }
963 }
964 LOGH("X");
965 return false;
966 }
967
968 /*===========================================================================
969 * FUNCTION : release_recording_frame
970 *
971 * DESCRIPTION: Release the recording frame
972 *
973 * PARAMETERS :
974 * @device : camera hardware device info
975 * @opaque: Frame to be released
976 *
977 * RETURN : None
978 *==========================================================================*/
release_recording_frame(struct camera_device * device,const void * opaque)979 void QCameraMuxer::release_recording_frame(struct camera_device * device,
980 const void *opaque)
981 {
982 LOGH("E");
983 CHECK_MUXER();
984 qcamera_physical_descriptor_t *pCam = NULL;
985 qcamera_logical_descriptor_t *cam = gMuxer->getLogicalCamera(device);
986 CHECK_CAMERA(cam);
987
988 for (uint32_t i = 0; i < cam->numCameras; i++) {
989 pCam = gMuxer->getPhysicalCamera(cam, i);
990 CHECK_CAMERA(pCam);
991
992 QCamera2HardwareInterface *hwi = pCam->hwi;
993 CHECK_HWI(hwi);
994
995 if (pCam->mode == CAM_MODE_PRIMARY) {
996 QCamera2HardwareInterface::release_recording_frame(pCam->dev, opaque);
997 break;
998 }
999 }
1000 LOGH("X");
1001 }
1002
1003 /*===========================================================================
1004 * FUNCTION : auto_focus
1005 *
1006 * DESCRIPTION: Performs auto focus on camera
1007 *
1008 * PARAMETERS :
1009 * @device : camera hardware device info
1010 *
1011 * RETURN :
1012 * NO_ERROR : success
1013 * other: non-zero failure code
1014 *==========================================================================*/
auto_focus(struct camera_device * device)1015 int QCameraMuxer::auto_focus(struct camera_device * device)
1016 {
1017 LOGH("E");
1018 CHECK_MUXER_ERROR();
1019 int rc = NO_ERROR;
1020 qcamera_physical_descriptor_t *pCam = NULL;
1021 qcamera_logical_descriptor_t *cam = gMuxer->getLogicalCamera(device);
1022 CHECK_CAMERA_ERROR(cam);
1023
1024 for (uint32_t i = 0; i < cam->numCameras; i++) {
1025 pCam = gMuxer->getPhysicalCamera(cam, i);
1026 CHECK_CAMERA_ERROR(pCam);
1027
1028 QCamera2HardwareInterface *hwi = pCam->hwi;
1029 CHECK_HWI_ERROR(hwi);
1030 // Call auto focus on main camera
1031 if (pCam->mode == CAM_MODE_PRIMARY) {
1032 rc = QCamera2HardwareInterface::auto_focus(pCam->dev);
1033 if (rc != NO_ERROR) {
1034 LOGE("Error auto focusing !! ");
1035 return rc;
1036 }
1037 break;
1038 }
1039 }
1040 LOGH("X");
1041 return rc;
1042 }
1043
1044 /*===========================================================================
1045 * FUNCTION : cancel_auto_focus
1046 *
1047 * DESCRIPTION: Cancels auto focus
1048 *
1049 * PARAMETERS :
1050 * @device : camera hardware device info
1051 *
1052 * RETURN :
1053 * NO_ERROR : success
1054 * other: non-zero failure code
1055 *==========================================================================*/
cancel_auto_focus(struct camera_device * device)1056 int QCameraMuxer::cancel_auto_focus(struct camera_device * device)
1057 {
1058 LOGH("E");
1059 CHECK_MUXER_ERROR();
1060 int rc = NO_ERROR;
1061 qcamera_physical_descriptor_t *pCam = NULL;
1062 qcamera_logical_descriptor_t *cam = gMuxer->getLogicalCamera(device);
1063 CHECK_CAMERA_ERROR(cam);
1064
1065 for (uint32_t i = 0; i < cam->numCameras; i++) {
1066 pCam = gMuxer->getPhysicalCamera(cam, i);
1067 CHECK_CAMERA_ERROR(pCam);
1068
1069 QCamera2HardwareInterface *hwi = pCam->hwi;
1070 CHECK_HWI_ERROR(hwi);
1071 // Cancel auto focus on primary camera
1072 if (pCam->mode == CAM_MODE_PRIMARY) {
1073 rc = QCamera2HardwareInterface::cancel_auto_focus(pCam->dev);
1074 if (rc != NO_ERROR) {
1075 LOGE("Error cancelling auto focus !! ");
1076 return rc;
1077 }
1078 break;
1079 }
1080 }
1081 LOGH("X");
1082 return rc;
1083 }
1084
1085 /*===========================================================================
1086 * FUNCTION : take_picture
1087 *
1088 * DESCRIPTION: Take snapshots on device
1089 *
1090 * PARAMETERS :
1091 * @device : camera hardware device info
1092 *
1093 * RETURN :
1094 * NO_ERROR : success
1095 * other: non-zero failure code
1096 *==========================================================================*/
take_picture(struct camera_device * device)1097 int QCameraMuxer::take_picture(struct camera_device * device)
1098 {
1099 LOGH("E");
1100 CHECK_MUXER_ERROR();
1101 int rc = NO_ERROR;
1102 bool previewRestartNeeded = false;
1103 qcamera_physical_descriptor_t *pCam = NULL;
1104 qcamera_logical_descriptor_t *cam = gMuxer->getLogicalCamera(device);
1105 CHECK_CAMERA_ERROR(cam);
1106
1107 char prop[PROPERTY_VALUE_MAX];
1108 property_get("persist.camera.dual.camera.mpo", prop, "1");
1109 gMuxer->m_bMpoEnabled = atoi(prop);
1110 // If only one Physical Camera included in Logical, disable MPO
1111 int numOfAcitvePhyCam = 0;
1112 gMuxer->getActiveNumOfPhyCam(cam, numOfAcitvePhyCam);
1113 if (gMuxer->m_bMpoEnabled && numOfAcitvePhyCam <= 1) {
1114 gMuxer->m_bMpoEnabled = 0;
1115 }
1116 LOGH("dualCamera MPO Enabled:%d ", gMuxer->m_bMpoEnabled);
1117
1118 if (!gMuxer->mJpegClientHandle) {
1119 // set up jpeg handles
1120 pCam = gMuxer->getPhysicalCamera(cam, 0);
1121 CHECK_CAMERA_ERROR(pCam);
1122
1123 QCamera2HardwareInterface *hwi = pCam->hwi;
1124 CHECK_HWI_ERROR(hwi);
1125
1126 rc = hwi->getJpegHandleInfo(&gMuxer->mJpegOps, &gMuxer->mJpegMpoOps,
1127 &gMuxer->mJpegClientHandle);
1128 if (rc != NO_ERROR) {
1129 LOGE("Error retrieving jpeg handle!");
1130 return rc;
1131 }
1132
1133 for (uint32_t i = 1; i < cam->numCameras; i++) {
1134 pCam = gMuxer->getPhysicalCamera(cam, i);
1135 CHECK_CAMERA_ERROR(pCam);
1136
1137 QCamera2HardwareInterface *hwi = pCam->hwi;
1138 CHECK_HWI_ERROR(hwi);
1139
1140 rc = hwi->setJpegHandleInfo(&gMuxer->mJpegOps, &gMuxer->mJpegMpoOps,
1141 gMuxer->mJpegClientHandle);
1142 if (rc != NO_ERROR) {
1143 LOGE("Error setting jpeg handle %d!", i);
1144 return rc;
1145 }
1146 }
1147 }
1148
1149 // prepare snapshot for main camera
1150 for (uint32_t i = 0; i < cam->numCameras; i++) {
1151 pCam = gMuxer->getPhysicalCamera(cam, i);
1152 CHECK_CAMERA_ERROR(pCam);
1153
1154 QCamera2HardwareInterface *hwi = pCam->hwi;
1155 CHECK_HWI_ERROR(hwi);
1156
1157 if (pCam->mode == CAM_MODE_PRIMARY) {
1158 rc = hwi->prepare_snapshot(pCam->dev);
1159 if (rc != NO_ERROR) {
1160 LOGE("Error preparing for snapshot !! ");
1161 return rc;
1162 }
1163 }
1164 // set Mpo composition for each session
1165 rc = hwi->setMpoComposition(gMuxer->m_bMpoEnabled);
1166 //disable MPO if AOST features are enabled
1167 if (rc != NO_ERROR) {
1168 gMuxer->m_bMpoEnabled = 0;
1169 rc = NO_ERROR;
1170 }
1171 }
1172
1173 // initialize Jpeg Queues
1174 gMuxer->m_MainJpegQ.init();
1175 gMuxer->m_AuxJpegQ.init();
1176 gMuxer->m_ComposeMpoTh.sendCmd(
1177 CAMERA_CMD_TYPE_START_DATA_PROC, FALSE, FALSE);
1178
1179 // In cases where recording hint is set, preview is running,
1180 // hwi->take_picture will internally restart the preview.
1181 // To take the preview restart control in muxer,
1182 // 1. call pre_take_picture first
1183 for (uint32_t i = 0; i < cam->numCameras; i++) {
1184 pCam = gMuxer->getPhysicalCamera(cam, i);
1185 CHECK_CAMERA_ERROR(pCam);
1186
1187 QCamera2HardwareInterface *hwi = pCam->hwi;
1188 CHECK_HWI_ERROR(hwi);
1189
1190 // no need to call pre_take_pic on Aux if not MPO (for AOST,liveshot...etc.)
1191 if ( (gMuxer->m_bMpoEnabled == 1) || (pCam->mode == CAM_MODE_PRIMARY) ) {
1192 rc = hwi->pre_take_picture(pCam->dev);
1193 if (rc != NO_ERROR) {
1194 LOGE("Error preparing take_picture!! ");
1195 return rc;
1196 }
1197 }
1198 }
1199
1200 // 2. Check if preview restart is needed. Check all cameras.
1201 for (uint32_t i = 0; i < cam->numCameras; i++) {
1202 pCam = gMuxer->getPhysicalCamera(cam, i);
1203 CHECK_CAMERA_ERROR(pCam);
1204
1205 QCamera2HardwareInterface *hwi = pCam->hwi;
1206 CHECK_HWI_ERROR(hwi);
1207
1208 if (hwi->isPreviewRestartNeeded()) {
1209 previewRestartNeeded = hwi->isPreviewRestartNeeded();
1210 break;
1211 }
1212 }
1213
1214 if (previewRestartNeeded) {
1215 // 3. if preview restart needed. stop the preview first
1216 for (uint32_t i = 0; i < cam->numCameras; i++) {
1217 pCam = gMuxer->getPhysicalCamera(cam, i);
1218 CHECK_CAMERA_ERROR(pCam);
1219
1220 QCamera2HardwareInterface *hwi = pCam->hwi;
1221 CHECK_HWI_ERROR(hwi);
1222
1223 rc = hwi->restart_stop_preview(pCam->dev);
1224 if (rc != NO_ERROR) {
1225 LOGE("Error in restart stop preview!! ");
1226 return rc;
1227 }
1228 }
1229
1230 //4. Update the recording hint value to FALSE
1231 for (uint32_t i = 0; i < cam->numCameras; i++) {
1232 pCam = gMuxer->getPhysicalCamera(cam, i);
1233 CHECK_CAMERA_ERROR(pCam);
1234
1235 QCamera2HardwareInterface *hwi = pCam->hwi;
1236 CHECK_HWI_ERROR(hwi);
1237
1238 rc = hwi->setRecordingHintValue(FALSE);
1239 if (rc != NO_ERROR) {
1240 LOGE("Error in setting recording hint value!! ");
1241 return rc;
1242 }
1243 }
1244
1245 // 5. start the preview
1246 for (uint32_t i = 0; i < cam->numCameras; i++) {
1247 pCam = gMuxer->getPhysicalCamera(cam, i);
1248 CHECK_CAMERA_ERROR(pCam);
1249
1250 QCamera2HardwareInterface *hwi = pCam->hwi;
1251 CHECK_HWI_ERROR(hwi);
1252
1253 rc = hwi->restart_start_preview(pCam->dev);
1254 if (rc != NO_ERROR) {
1255 LOGE("Error in restart start preview!! ");
1256 return rc;
1257 }
1258 }
1259 }
1260
1261 // As frame sync for dual cameras is enabled, the take picture call
1262 // for secondary camera is handled only till HAL level to init corresponding
1263 // pproc channel and update statemachine.
1264 // This call is forwarded to mm-camera-intf only for primary camera
1265 // Primary camera should receive the take picture call after all secondary
1266 // camera statemachines are updated
1267 for (int32_t i = cam->numCameras-1 ; i >= 0; i--) {
1268 pCam = gMuxer->getPhysicalCamera(cam, i);
1269 CHECK_CAMERA_ERROR(pCam);
1270
1271 QCamera2HardwareInterface *hwi = pCam->hwi;
1272 CHECK_HWI_ERROR(hwi);
1273
1274 // no need to call take_pic on Aux if not MPO (for AOST)
1275 if ( (gMuxer->m_bMpoEnabled == 1) || (pCam->mode == CAM_MODE_PRIMARY) ) {
1276 rc = QCamera2HardwareInterface::take_picture(pCam->dev);
1277 if (rc != NO_ERROR) {
1278 LOGE("Error taking picture !! ");
1279 return rc;
1280 }
1281 }
1282 }
1283 LOGH("X");
1284 return rc;
1285 }
1286
1287 /*===========================================================================
1288 * FUNCTION : cancel_picture
1289 *
1290 * DESCRIPTION: Cancel the take picture call
1291 *
1292 * PARAMETERS :
1293 * @device : camera hardware device info
1294 *
1295 * RETURN :
1296 * NO_ERROR : success
1297 * other: non-zero failure code
1298 *==========================================================================*/
cancel_picture(struct camera_device * device)1299 int QCameraMuxer::cancel_picture(struct camera_device * device)
1300 {
1301 LOGH("E");
1302 CHECK_MUXER_ERROR();
1303 int rc = NO_ERROR;
1304 qcamera_physical_descriptor_t *pCam = NULL;
1305 qcamera_logical_descriptor_t *cam = gMuxer->getLogicalCamera(device);
1306 CHECK_CAMERA_ERROR(cam);
1307
1308 for (uint32_t i = 0; i < cam->numCameras; i++) {
1309 pCam = gMuxer->getPhysicalCamera(cam, i);
1310 CHECK_CAMERA_ERROR(pCam);
1311
1312 QCamera2HardwareInterface *hwi = pCam->hwi;
1313 CHECK_HWI_ERROR(hwi);
1314
1315 rc = QCamera2HardwareInterface::cancel_picture(pCam->dev);
1316 if (rc != NO_ERROR) {
1317 LOGE("Error cancelling picture !! ");
1318 return rc;
1319 }
1320 }
1321 gMuxer->m_ComposeMpoTh.sendCmd(CAMERA_CMD_TYPE_STOP_DATA_PROC, FALSE, FALSE);
1322 // flush Jpeg Queues
1323 gMuxer->m_MainJpegQ.flush();
1324 gMuxer->m_AuxJpegQ.flush();
1325
1326 LOGH("X");
1327 return rc;
1328 }
1329
1330 /*===========================================================================
1331 * FUNCTION : set_parameters
1332 *
1333 * DESCRIPTION: Sets the parameters on camera
1334 *
1335 * PARAMETERS :
1336 * @device : camera hardware device info
1337 * @parms : Parameters to be set on camera
1338 *
1339 * RETURN :
1340 * NO_ERROR : success
1341 * other: non-zero failure code
1342 *==========================================================================*/
set_parameters(struct camera_device * device,const char * parms)1343 int QCameraMuxer::set_parameters(struct camera_device * device,
1344 const char *parms)
1345
1346 {
1347 LOGH("E");
1348 CHECK_MUXER_ERROR();
1349 int rc = NO_ERROR;
1350 qcamera_physical_descriptor_t *pCam = NULL;
1351 qcamera_logical_descriptor_t *cam = gMuxer->getLogicalCamera(device);
1352 bool needRestart = false;
1353 CHECK_CAMERA_ERROR(cam);
1354
1355 for (uint32_t i = 0; i < cam->numCameras; i++) {
1356 pCam = gMuxer->getPhysicalCamera(cam, i);
1357 CHECK_CAMERA_ERROR(pCam);
1358
1359 QCamera2HardwareInterface *hwi = pCam->hwi;
1360 CHECK_HWI_ERROR(hwi);
1361
1362 rc = QCamera2HardwareInterface::set_parameters(pCam->dev, parms);
1363 if (rc != NO_ERROR) {
1364 LOGE("Error setting parameters !! ");
1365 return rc;
1366 }
1367
1368 needRestart |= hwi->getNeedRestart();
1369 }
1370
1371 if (needRestart) {
1372 for (uint32_t i = 0; i < cam->numCameras; i++) {
1373 pCam = gMuxer->getPhysicalCamera(cam, i);
1374 CHECK_CAMERA_ERROR(pCam);
1375
1376 QCamera2HardwareInterface *hwi = pCam->hwi;
1377 CHECK_HWI_ERROR(hwi);
1378
1379 LOGD("stopping preview for cam %d", i);
1380 rc = QCamera2HardwareInterface::stop_after_set_params(pCam->dev);
1381 if (rc != NO_ERROR) {
1382 LOGE("Error stopping camera rc=%d!! ", rc);
1383 return rc;
1384 }
1385 }
1386 }
1387
1388 for (uint32_t i = 0; i < cam->numCameras; i++) {
1389 pCam = gMuxer->getPhysicalCamera(cam, i);
1390 CHECK_CAMERA_ERROR(pCam);
1391
1392 QCamera2HardwareInterface *hwi = pCam->hwi;
1393 CHECK_HWI_ERROR(hwi);
1394
1395 LOGD("commiting parameters for cam %d", i);
1396 rc = QCamera2HardwareInterface::commit_params(pCam->dev);
1397 if (rc != NO_ERROR) {
1398 LOGE("Error committing parameters rc=%d!! ", rc);
1399 return rc;
1400 }
1401 }
1402
1403 if (needRestart) {
1404 for (uint32_t i = 0; i < cam->numCameras; i++) {
1405 pCam = gMuxer->getPhysicalCamera(cam, i);
1406 CHECK_CAMERA_ERROR(pCam);
1407
1408 QCamera2HardwareInterface *hwi = pCam->hwi;
1409 CHECK_HWI_ERROR(hwi);
1410
1411 LOGD("restarting preview for cam %d", i);
1412 rc = QCamera2HardwareInterface::restart_after_set_params(pCam->dev);
1413 if (rc != NO_ERROR) {
1414 LOGE("Error restarting camera rc=%d!! ", rc);
1415 return rc;
1416 }
1417 }
1418 }
1419
1420 LOGH(" X");
1421 return rc;
1422 }
1423
1424 /*===========================================================================
1425 * FUNCTION : get_parameters
1426 *
1427 * DESCRIPTION: Gets the parameters on camera
1428 *
1429 * PARAMETERS :
1430 * @device : camera hardware device info
1431 *
1432 * RETURN : Parameter string or NULL
1433 *==========================================================================*/
get_parameters(struct camera_device * device)1434 char* QCameraMuxer::get_parameters(struct camera_device * device)
1435 {
1436 LOGH("E");
1437
1438 if (!gMuxer)
1439 return NULL;
1440
1441 char* ret = NULL;
1442 qcamera_physical_descriptor_t *pCam = NULL;
1443 qcamera_logical_descriptor_t *cam = gMuxer->getLogicalCamera(device);
1444 if (!cam) {
1445 LOGE("Error getting logical camera");
1446 return NULL;
1447 }
1448
1449 for (uint32_t i = 0; i < cam->numCameras; i++) {
1450 pCam = gMuxer->getPhysicalCamera(cam, i);
1451 if (!pCam) {
1452 LOGE("Error getting physical camera");
1453 return NULL;
1454 }
1455 QCamera2HardwareInterface *hwi = pCam->hwi;
1456 if (!hwi) {
1457 LOGE("Allocation of hardware interface failed");
1458 return NULL;
1459 }
1460 if (pCam->mode == CAM_MODE_PRIMARY) {
1461 // Get only primary camera parameters
1462 ret = QCamera2HardwareInterface::get_parameters(pCam->dev);
1463 break;
1464 }
1465 }
1466
1467 LOGH("X");
1468 return ret;
1469 }
1470
1471 /*===========================================================================
1472 * FUNCTION : put_parameters
1473 *
1474 * DESCRIPTION: Puts parameters on camera
1475 *
1476 * PARAMETERS :
1477 * @device : camera hardware device info
1478 * @parm : parameters
1479 *
1480 * RETURN : None
1481 *==========================================================================*/
put_parameters(struct camera_device * device,char * parm)1482 void QCameraMuxer::put_parameters(struct camera_device * device, char *parm)
1483 {
1484 LOGH("E");
1485 CHECK_MUXER();
1486 qcamera_physical_descriptor_t *pCam = NULL;
1487 qcamera_logical_descriptor_t *cam = gMuxer->getLogicalCamera(device);
1488 CHECK_CAMERA(cam);
1489
1490 for (uint32_t i = 0; i < cam->numCameras; i++) {
1491 pCam = gMuxer->getPhysicalCamera(cam, i);
1492 CHECK_CAMERA(pCam);
1493
1494 QCamera2HardwareInterface *hwi = pCam->hwi;
1495 CHECK_HWI(hwi);
1496
1497 if (pCam->mode == CAM_MODE_PRIMARY) {
1498 // Parameters are not used in HWI and hence freed
1499 QCamera2HardwareInterface::put_parameters(pCam->dev, parm);
1500 break;
1501 }
1502 }
1503 LOGH("X");
1504 }
1505
1506 /*===========================================================================
1507 * FUNCTION : send_command
1508 *
1509 * DESCRIPTION: Send command to camera
1510 *
1511 * PARAMETERS :
1512 * @device : camera hardware device info
1513 * @cmd : Command
1514 * @arg1/arg2 : command arguments
1515 *
1516 * RETURN :
1517 * NO_ERROR : success
1518 * other: non-zero failure code
1519 *==========================================================================*/
send_command(struct camera_device * device,int32_t cmd,int32_t arg1,int32_t arg2)1520 int QCameraMuxer::send_command(struct camera_device * device,
1521 int32_t cmd, int32_t arg1, int32_t arg2)
1522 {
1523 LOGH("E");
1524 CHECK_MUXER_ERROR();
1525 int rc = NO_ERROR;
1526 qcamera_physical_descriptor_t *pCam = NULL;
1527 qcamera_logical_descriptor_t *cam = gMuxer->getLogicalCamera(device);
1528 CHECK_CAMERA_ERROR(cam);
1529
1530 for (uint32_t i = 0; i < cam->numCameras; i++) {
1531 pCam = gMuxer->getPhysicalCamera(cam, i);
1532 CHECK_CAMERA_ERROR(pCam);
1533
1534 QCamera2HardwareInterface *hwi = pCam->hwi;
1535 CHECK_HWI_ERROR(hwi);
1536
1537 rc = QCamera2HardwareInterface::send_command(pCam->dev, cmd, arg1, arg2);
1538 if (rc != NO_ERROR) {
1539 LOGE("Error sending command !! ");
1540 return rc;
1541 }
1542 }
1543
1544 switch (cmd) {
1545 #ifndef VANILLA_HAL
1546 case CAMERA_CMD_LONGSHOT_ON:
1547 for (uint32_t i = 0; i < cam->numCameras; i++) {
1548 pCam = gMuxer->getPhysicalCamera(cam, i);
1549 CHECK_CAMERA_ERROR(pCam);
1550
1551 QCamera2HardwareInterface *hwi = pCam->hwi;
1552 CHECK_HWI_ERROR(hwi);
1553
1554 rc = QCamera2HardwareInterface::send_command_restart(pCam->dev,
1555 cmd, arg1, arg2);
1556 if (rc != NO_ERROR) {
1557 LOGE("Error sending command restart !! ");
1558 return rc;
1559 }
1560 }
1561 break;
1562 case CAMERA_CMD_LONGSHOT_OFF:
1563 gMuxer->m_ComposeMpoTh.sendCmd(CAMERA_CMD_TYPE_STOP_DATA_PROC,
1564 FALSE, FALSE);
1565 // flush Jpeg Queues
1566 gMuxer->m_MainJpegQ.flush();
1567 gMuxer->m_AuxJpegQ.flush();
1568 break;
1569 #endif
1570 default:
1571 // do nothing
1572 rc = NO_ERROR;
1573 break;
1574 }
1575
1576 LOGH("X");
1577 return rc;
1578 }
1579
1580 /*===========================================================================
1581 * FUNCTION : release
1582 *
1583 * DESCRIPTION: Release the camera
1584 *
1585 * PARAMETERS :
1586 * @device : camera hardware device info
1587 *
1588 * RETURN : None
1589 *==========================================================================*/
release(struct camera_device * device)1590 void QCameraMuxer::release(struct camera_device * device)
1591 {
1592 LOGH("E");
1593 CHECK_MUXER();
1594 qcamera_physical_descriptor_t *pCam = NULL;
1595 qcamera_logical_descriptor_t *cam = gMuxer->getLogicalCamera(device);
1596 CHECK_CAMERA(cam);
1597
1598 for (uint32_t i = 0; i < cam->numCameras; i++) {
1599 pCam = gMuxer->getPhysicalCamera(cam, i);
1600 CHECK_CAMERA(pCam);
1601
1602 QCamera2HardwareInterface *hwi = pCam->hwi;
1603 CHECK_HWI(hwi);
1604
1605 QCamera2HardwareInterface::release(pCam->dev);
1606 }
1607 LOGH("X");
1608 }
1609
1610 /*===========================================================================
1611 * FUNCTION : dump
1612 *
1613 * DESCRIPTION: Dump the camera info
1614 *
1615 * PARAMETERS :
1616 * @device : camera hardware device info
1617 * @fd : fd
1618 *
1619 * RETURN :
1620 * NO_ERROR : success
1621 * other: non-zero failure code
1622 *==========================================================================*/
dump(struct camera_device * device,int fd)1623 int QCameraMuxer::dump(struct camera_device * device, int fd)
1624 {
1625 LOGH("E");
1626 CHECK_MUXER_ERROR();
1627 int rc = NO_ERROR;
1628 qcamera_physical_descriptor_t *pCam = NULL;
1629 qcamera_logical_descriptor_t *cam = gMuxer->getLogicalCamera(device);
1630 CHECK_CAMERA_ERROR(cam);
1631
1632 for (uint32_t i = 0; i < cam->numCameras; i++) {
1633 pCam = gMuxer->getPhysicalCamera(cam, i);
1634 CHECK_CAMERA_ERROR(pCam);
1635
1636 QCamera2HardwareInterface *hwi = pCam->hwi;
1637 CHECK_HWI_ERROR(hwi);
1638
1639 rc = QCamera2HardwareInterface::dump(pCam->dev, fd);
1640 if (rc != NO_ERROR) {
1641 LOGE("Error dumping");
1642 return rc;
1643 }
1644 }
1645 LOGH("X");
1646 return rc;
1647 }
1648
1649 /*===========================================================================
1650 * FUNCTION : close_camera_device
1651 *
1652 * DESCRIPTION: Close the camera
1653 *
1654 * PARAMETERS :
1655 * @hw_dev : camera hardware device info
1656 *
1657 * RETURN :
1658 * NO_ERROR : success
1659 * other: non-zero failure code
1660 *==========================================================================*/
close_camera_device(hw_device_t * hw_dev)1661 int QCameraMuxer::close_camera_device(hw_device_t *hw_dev)
1662 {
1663 LOGH("E");
1664 CHECK_MUXER_ERROR();
1665 int rc = NO_ERROR;
1666 qcamera_physical_descriptor_t *pCam = NULL;
1667 camera_device_t *cam_dev = (camera_device_t*)hw_dev;
1668 qcamera_logical_descriptor_t *cam = gMuxer->getLogicalCamera(cam_dev);
1669 CHECK_CAMERA_ERROR(cam);
1670
1671 // Unlink camera sessions
1672 if (cam->bSyncOn) {
1673 if (cam->numCameras > 1) {
1674 uint sessionId = 0;
1675 // unbundle primary camera with all aux cameras
1676 for (uint32_t i = 0; i < cam->numCameras; i++) {
1677 pCam = gMuxer->getPhysicalCamera(cam, i);
1678 CHECK_CAMERA_ERROR(pCam);
1679
1680 QCamera2HardwareInterface *hwi = pCam->hwi;
1681 CHECK_HWI_ERROR(hwi);
1682
1683 if(pCam->mode == CAM_MODE_PRIMARY) {
1684 // bundle primary cam with all aux cameras
1685 for (uint32_t j = 0; j < cam->numCameras; j++) {
1686 if (j == cam->nPrimaryPhyCamIndex) {
1687 continue;
1688 }
1689 sessionId = cam->sId[j];
1690 LOGH("Related cam id: %d, server id: %d sync OFF"
1691 " related session_id %d",
1692 cam->pId[i], cam->sId[i], sessionId);
1693 rc = hwi->bundleRelatedCameras(false, sessionId);
1694 if (rc != NO_ERROR) {
1695 LOGE("Error Bundling physical cameras !! ");
1696 break;
1697 }
1698 }
1699 }
1700
1701 if (pCam->mode == CAM_MODE_SECONDARY) {
1702 // unbundle all aux cam with primary cams
1703 sessionId = cam->sId[cam->nPrimaryPhyCamIndex];
1704 LOGH("Related cam id: %d, server id: %d sync OFF"
1705 " related session_id %d",
1706 cam->pId[i], cam->sId[i], sessionId);
1707 rc = hwi->bundleRelatedCameras(false, sessionId);
1708 if (rc != NO_ERROR) {
1709 LOGE("Error Bundling physical cameras !! ");
1710 break;
1711 }
1712 }
1713 }
1714 }
1715 cam->bSyncOn = false;
1716 }
1717
1718 // Attempt to close all cameras regardless of unbundle results
1719 for (uint32_t i = 0; i < cam->numCameras; i++) {
1720 pCam = gMuxer->getPhysicalCamera(cam, i);
1721 CHECK_CAMERA_ERROR(pCam);
1722
1723 hw_device_t *dev = (hw_device_t*)(pCam->dev);
1724 LOGH("hw device %x, hw %x", dev, pCam->hwi);
1725
1726 rc = QCamera2HardwareInterface::close_camera_device(dev);
1727 if (rc != NO_ERROR) {
1728 LOGE("Error closing camera");
1729 }
1730 pCam->hwi = NULL;
1731 pCam->dev = NULL;
1732 }
1733
1734 // Reset JPEG client handle
1735 gMuxer->setJpegHandle(0);
1736 LOGH("X, rc: %d", rc);
1737 return rc;
1738 }
1739
1740 /*===========================================================================
1741 * FUNCTION : setupLogicalCameras
1742 *
1743 * DESCRIPTION : Creates Camera Muxer if not created
1744 *
1745 * RETURN :
1746 * NO_ERROR : success
1747 * other: non-zero failure code
1748 *==========================================================================*/
setupLogicalCameras()1749 int QCameraMuxer::setupLogicalCameras()
1750 {
1751 int rc = NO_ERROR;
1752 char prop[PROPERTY_VALUE_MAX];
1753 int i = 0;
1754 int primaryType = CAM_TYPE_MAIN;
1755
1756 LOGH("[%d] E: rc = %d", rc);
1757 // Signifies whether AUX camera has to be exposed as physical camera
1758 property_get("persist.camera.aux.camera", prop, "0");
1759 m_bAuxCameraExposed = atoi(prop);
1760
1761 // Signifies whether AUX camera needs to be swapped
1762 property_get("persist.camera.auxcamera.swap", prop, "0");
1763 int swapAux = atoi(prop);
1764 if (swapAux != 0) {
1765 primaryType = CAM_TYPE_AUX;
1766 }
1767
1768 // Check for number of camera present on device
1769 if (!m_nPhyCameras || (m_nPhyCameras > MM_CAMERA_MAX_NUM_SENSORS)) {
1770 LOGE("Error!! Invalid number of cameras: %d",
1771 m_nPhyCameras);
1772 return BAD_VALUE;
1773 }
1774
1775 m_pPhyCamera = new qcamera_physical_descriptor_t[m_nPhyCameras];
1776 if (!m_pPhyCamera) {
1777 LOGE("Error allocating camera info buffer!!");
1778 return NO_MEMORY;
1779 }
1780 memset(m_pPhyCamera, 0x00,
1781 (m_nPhyCameras * sizeof(qcamera_physical_descriptor_t)));
1782 uint32_t cameraId = 0;
1783 m_nLogicalCameras = 0;
1784
1785 // Enumerate physical cameras and logical
1786 for (i = 0; i < m_nPhyCameras ; i++, cameraId++) {
1787 camera_info *info = &m_pPhyCamera[i].cam_info;
1788 rc = QCamera2HardwareInterface::getCapabilities(cameraId,
1789 info, &m_pPhyCamera[i].type);
1790 m_pPhyCamera[i].id = cameraId;
1791 m_pPhyCamera[i].device_version = CAMERA_DEVICE_API_VERSION_1_0;
1792 m_pPhyCamera[i].mode = CAM_MODE_PRIMARY;
1793
1794 if (!m_bAuxCameraExposed && (m_pPhyCamera[i].type != primaryType)) {
1795 m_pPhyCamera[i].mode = CAM_MODE_SECONDARY;
1796 LOGH("Camera ID: %d, Aux Camera, type: %d, facing: %d",
1797 cameraId, m_pPhyCamera[i].type,
1798 m_pPhyCamera[i].cam_info.facing);
1799 }
1800 else {
1801 m_nLogicalCameras++;
1802 LOGH("Camera ID: %d, Main Camera, type: %d, facing: %d",
1803 cameraId, m_pPhyCamera[i].type,
1804 m_pPhyCamera[i].cam_info.facing);
1805 }
1806 }
1807
1808 if (!m_nLogicalCameras) {
1809 // No Main camera detected, return from here
1810 LOGE("Error !!!! detecting main camera!!");
1811 delete [] m_pPhyCamera;
1812 m_pPhyCamera = NULL;
1813 return -ENODEV;
1814 }
1815 // Allocate Logical Camera descriptors
1816 m_pLogicalCamera = new qcamera_logical_descriptor_t[m_nLogicalCameras];
1817 if (!m_pLogicalCamera) {
1818 LOGE("Error !!!! allocating camera info buffer!!");
1819 delete [] m_pPhyCamera;
1820 m_pPhyCamera = NULL;
1821 return NO_MEMORY;
1822 }
1823 memset(m_pLogicalCamera, 0x00,
1824 (m_nLogicalCameras * sizeof(qcamera_logical_descriptor_t)));
1825 // Assign MAIN cameras for each logical camera
1826 int index = 0;
1827 for (i = 0; i < m_nPhyCameras ; i++) {
1828 if (m_pPhyCamera[i].mode == CAM_MODE_PRIMARY) {
1829 m_pLogicalCamera[index].nPrimaryPhyCamIndex = 0;
1830 m_pLogicalCamera[index].id = index;
1831 m_pLogicalCamera[index].device_version = CAMERA_DEVICE_API_VERSION_1_0;
1832 m_pLogicalCamera[index].pId[0] = i;
1833 m_pLogicalCamera[index].type[0] = CAM_TYPE_MAIN;
1834 m_pLogicalCamera[index].mode[0] = CAM_MODE_PRIMARY;
1835 m_pLogicalCamera[index].facing = m_pPhyCamera[i].cam_info.facing;
1836 m_pLogicalCamera[index].numCameras++;
1837 LOGH("Logical Main Camera ID: %d, facing: %d,"
1838 "Phy Id: %d type: %d mode: %d",
1839 m_pLogicalCamera[index].id,
1840 m_pLogicalCamera[index].facing,
1841 m_pLogicalCamera[index].pId[0],
1842 m_pLogicalCamera[index].type[0],
1843 m_pLogicalCamera[index].mode[0]);
1844
1845 index++;
1846 }
1847 }
1848 //Now assign AUX cameras to logical camera
1849 for (i = 0; i < m_nPhyCameras ; i++) {
1850 if (m_pPhyCamera[i].mode == CAM_MODE_SECONDARY) {
1851 for (int j = 0; j < m_nLogicalCameras; j++) {
1852 int n = m_pLogicalCamera[j].numCameras;
1853 ///@note n can only be 1 at this point
1854 if ((n < MAX_NUM_CAMERA_PER_BUNDLE) &&
1855 (m_pLogicalCamera[j].facing ==
1856 m_pPhyCamera[i].cam_info.facing)) {
1857 m_pLogicalCamera[j].pId[n] = i;
1858 m_pLogicalCamera[j].type[n] = CAM_TYPE_AUX;
1859 m_pLogicalCamera[j].mode[n] = CAM_MODE_SECONDARY;
1860 m_pLogicalCamera[j].numCameras++;
1861 LOGH("Aux %d for Logical Camera ID: %d,"
1862 "aux phy id:%d, type: %d mode: %d",
1863 n, j, m_pLogicalCamera[j].pId[n],
1864 m_pLogicalCamera[j].type[n], m_pLogicalCamera[j].mode[n]);
1865 }
1866 }
1867 }
1868 }
1869 //Print logical and physical camera tables
1870 for (i = 0; i < m_nLogicalCameras ; i++) {
1871 for (uint8_t j = 0; j < m_pLogicalCamera[i].numCameras; j++) {
1872 LOGH("Logical Camera ID: %d, index: %d, "
1873 "facing: %d, Phy Id: %d type: %d mode: %d",
1874 i, j, m_pLogicalCamera[i].facing,
1875 m_pLogicalCamera[i].pId[j], m_pLogicalCamera[i].type[j],
1876 m_pLogicalCamera[i].mode[j]);
1877 }
1878 }
1879 LOGH("[%d] X: rc = %d", rc);
1880 return rc;
1881 }
1882
1883 /*===========================================================================
1884 * FUNCTION : getNumberOfCameras
1885 *
1886 * DESCRIPTION: query number of logical cameras detected
1887 *
1888 * RETURN : number of cameras detected
1889 *==========================================================================*/
getNumberOfCameras()1890 int QCameraMuxer::getNumberOfCameras()
1891 {
1892 return m_nLogicalCameras;
1893 }
1894
1895 /*===========================================================================
1896 * FUNCTION : getCameraInfo
1897 *
1898 * DESCRIPTION: query camera information with its ID
1899 *
1900 * PARAMETERS :
1901 * @camera_id : camera ID
1902 * @info : ptr to camera info struct
1903 *
1904 * RETURN : int32_t type of status
1905 * NO_ERROR -- success
1906 * none-zero failure code
1907 *==========================================================================*/
getCameraInfo(int camera_id,struct camera_info * info,__unused cam_sync_type_t * p_cam_type)1908 int QCameraMuxer::getCameraInfo(int camera_id,
1909 struct camera_info *info, __unused cam_sync_type_t *p_cam_type)
1910 {
1911 int rc = NO_ERROR;
1912 LOGH("E, camera_id = %d", camera_id);
1913
1914 if (!m_nLogicalCameras || (camera_id >= m_nLogicalCameras) ||
1915 !info || (camera_id < 0)) {
1916 LOGE("m_nLogicalCameras: %d, camera id: %d",
1917 m_nLogicalCameras, camera_id);
1918 return -ENODEV;
1919 }
1920
1921 if (!m_pLogicalCamera || !m_pPhyCamera) {
1922 LOGE("Error! Cameras not initialized!");
1923 return NO_INIT;
1924 }
1925 uint32_t phy_id =
1926 m_pLogicalCamera[camera_id].pId[
1927 m_pLogicalCamera[camera_id].nPrimaryPhyCamIndex];
1928 // Call HAL3 getCamInfo to get the flash light info through static metatdata
1929 // regardless of HAL version
1930 rc = QCamera3HardwareInterface::getCamInfo(phy_id, info);
1931 info->device_version = CAMERA_DEVICE_API_VERSION_1_0; // Hardcode the HAL to HAL1
1932 LOGH("X");
1933 return rc;
1934 }
1935
1936 /*===========================================================================
1937 * FUNCTION : setCallbacks
1938 *
1939 * DESCRIPTION: set callback functions to send asynchronous notifications to
1940 * frameworks.
1941 *
1942 * PARAMETERS :
1943 * @callbacks : callback function pointer
1944 *
1945 * RETURN : int32_t type of status
1946 * NO_ERROR -- success
1947 * none-zero failure code
1948 *==========================================================================*/
setCallbacks(const camera_module_callbacks_t * callbacks)1949 int32_t QCameraMuxer::setCallbacks(const camera_module_callbacks_t *callbacks)
1950 {
1951 if(callbacks) {
1952 m_pCallbacks = callbacks;
1953 return NO_ERROR;
1954 } else {
1955 return BAD_TYPE;
1956 }
1957 }
1958
1959 /*===========================================================================
1960 * FUNCTION : setDataCallback
1961 *
1962 * DESCRIPTION: set data callback function for snapshots
1963 *
1964 * PARAMETERS :
1965 * @data_cb : callback function pointer
1966 *
1967 * RETURN : int32_t type of status
1968 * NO_ERROR -- success
1969 * none-zero failure code
1970 *==========================================================================*/
setDataCallback(camera_data_callback data_cb)1971 int32_t QCameraMuxer::setDataCallback(camera_data_callback data_cb)
1972 {
1973 if(data_cb) {
1974 mDataCb = data_cb;
1975 return NO_ERROR;
1976 } else {
1977 return BAD_TYPE;
1978 }
1979 }
1980
1981 /*===========================================================================
1982 * FUNCTION : setMemoryCallback
1983 *
1984 * DESCRIPTION: set get memory callback for memory allocations
1985 *
1986 * PARAMETERS :
1987 * @get_memory : callback function pointer
1988 *
1989 * RETURN : int32_t type of status
1990 * NO_ERROR -- success
1991 * none-zero failure code
1992 *==========================================================================*/
setMemoryCallback(camera_request_memory get_memory)1993 int32_t QCameraMuxer::setMemoryCallback(camera_request_memory get_memory)
1994 {
1995 if(get_memory) {
1996 mGetMemoryCb = get_memory;
1997 return NO_ERROR;
1998 } else {
1999 return BAD_TYPE;
2000 }
2001 }
2002
2003 /*===========================================================================
2004 * FUNCTION : setMpoCallbackCookie
2005 *
2006 * DESCRIPTION: set mpo callback cookie. will be used for sending final MPO callbacks
2007 * to framework
2008 *
2009 * PARAMETERS :
2010 * @mpoCbCookie : callback function pointer
2011 *
2012 * RETURN : int32_t type of status
2013 * NO_ERROR -- success
2014 * none-zero failure code
2015 *==========================================================================*/
setMpoCallbackCookie(void * mpoCbCookie)2016 int32_t QCameraMuxer::setMpoCallbackCookie(void* mpoCbCookie)
2017 {
2018 if(mpoCbCookie) {
2019 m_pMpoCallbackCookie = mpoCbCookie;
2020 return NO_ERROR;
2021 } else {
2022 return BAD_TYPE;
2023 }
2024 }
2025
2026 /*===========================================================================
2027 * FUNCTION : getMpoCallbackCookie
2028 *
2029 * DESCRIPTION: gets the mpo callback cookie. will be used for sending final MPO callbacks
2030 * to framework
2031 *
2032 * PARAMETERS :none
2033 *
2034 * RETURN :void ptr to the mpo callback cookie
2035 *==========================================================================*/
getMpoCallbackCookie(void)2036 void* QCameraMuxer::getMpoCallbackCookie(void)
2037 {
2038 return m_pMpoCallbackCookie;
2039 }
2040
2041 /*===========================================================================
2042 * FUNCTION : setMainJpegCallbackCookie
2043 *
2044 * DESCRIPTION: set jpeg callback cookie.
2045 * set to phy cam instance of the primary related cam instance
2046 *
2047 * PARAMETERS :
2048 * @jpegCbCookie : ptr to jpeg cookie
2049 *
2050 * RETURN : int32_t type of status
2051 * NO_ERROR -- success
2052 * none-zero failure code
2053 *==========================================================================*/
setMainJpegCallbackCookie(void * jpegCbCookie)2054 int32_t QCameraMuxer::setMainJpegCallbackCookie(void* jpegCbCookie)
2055 {
2056 if(jpegCbCookie) {
2057 m_pJpegCallbackCookie = jpegCbCookie;
2058 return NO_ERROR;
2059 } else {
2060 return BAD_TYPE;
2061 }
2062 }
2063
2064 /*===========================================================================
2065 * FUNCTION : getMainJpegCallbackCookie
2066 *
2067 * DESCRIPTION: gets the jpeg callback cookie for primary related cam instance
2068 * set to phy cam instance of the primary related cam instance
2069 *
2070 * PARAMETERS :none
2071 *
2072 * RETURN :void ptr to the jpeg callback cookie
2073 *==========================================================================*/
getMainJpegCallbackCookie(void)2074 void* QCameraMuxer::getMainJpegCallbackCookie(void)
2075 {
2076 return m_pJpegCallbackCookie;
2077 }
2078
2079 /*===========================================================================
2080 * FUNCTION : cameraDeviceOpen
2081 *
2082 * DESCRIPTION: open a camera device with its ID
2083 *
2084 * PARAMETERS :
2085 * @camera_id : camera ID
2086 * @hw_device : ptr to struct storing camera hardware device info
2087 *
2088 * RETURN : int32_t type of status
2089 * NO_ERROR -- success
2090 * none-zero failure code
2091 *==========================================================================*/
cameraDeviceOpen(int camera_id,struct hw_device_t ** hw_device)2092 int QCameraMuxer::cameraDeviceOpen(int camera_id,
2093 struct hw_device_t **hw_device)
2094 {
2095 int rc = NO_ERROR;
2096 uint32_t phyId = 0;
2097 qcamera_logical_descriptor_t *cam = NULL;
2098
2099 if (camera_id < 0 || camera_id >= m_nLogicalCameras) {
2100 LOGE("Camera id %d not found!", camera_id);
2101 return -ENODEV;
2102 }
2103
2104 if ( NULL == m_pLogicalCamera) {
2105 LOGE("Hal descriptor table is not initialized!");
2106 return NO_INIT;
2107 }
2108
2109 char prop[PROPERTY_VALUE_MAX];
2110 property_get("persist.camera.dc.frame.sync", prop, "1");
2111 m_bFrameSyncEnabled = atoi(prop);
2112
2113 // Get logical camera
2114 cam = &m_pLogicalCamera[camera_id];
2115
2116 if (m_pLogicalCamera[camera_id].device_version ==
2117 CAMERA_DEVICE_API_VERSION_1_0) {
2118 // HW Dev Holders
2119 hw_device_t *hw_dev[cam->numCameras];
2120
2121 if (m_pPhyCamera[cam->pId[0]].type != CAM_TYPE_MAIN) {
2122 LOGE("Physical camera at index 0 is not main!");
2123 return UNKNOWN_ERROR;
2124 }
2125
2126 // Open all physical cameras
2127 for (uint32_t i = 0; i < cam->numCameras; i++) {
2128 phyId = cam->pId[i];
2129 QCamera2HardwareInterface *hw =
2130 new QCamera2HardwareInterface((uint32_t)phyId);
2131 if (!hw) {
2132 LOGE("Allocation of hardware interface failed");
2133 return NO_MEMORY;
2134 }
2135 hw_dev[i] = NULL;
2136
2137 // Make Camera HWI aware of its mode
2138 cam_sync_related_sensors_event_info_t info;
2139 info.sync_control = CAM_SYNC_RELATED_SENSORS_ON;
2140 info.mode = m_pPhyCamera[phyId].mode;
2141 info.type = m_pPhyCamera[phyId].type;
2142 rc = hw->setRelatedCamSyncInfo(&info);
2143 hw->setFrameSyncEnabled(m_bFrameSyncEnabled);
2144 if (rc != NO_ERROR) {
2145 LOGE("setRelatedCamSyncInfo failed %d", rc);
2146 delete hw;
2147 return rc;
2148 }
2149
2150 rc = hw->openCamera(&hw_dev[i]);
2151 if (rc != NO_ERROR) {
2152 delete hw;
2153 return rc;
2154 }
2155 hw->getCameraSessionId(&m_pPhyCamera[phyId].camera_server_id);
2156 m_pPhyCamera[phyId].dev = reinterpret_cast<camera_device_t*>(hw_dev[i]);
2157 m_pPhyCamera[phyId].hwi = hw;
2158 cam->sId[i] = m_pPhyCamera[phyId].camera_server_id;
2159 LOGH("camera id %d server id : %d hw device %x, hw %x",
2160 phyId, cam->sId[i], hw_dev[i], hw);
2161 }
2162 } else {
2163 LOGE("Device version for camera id %d invalid %d",
2164 camera_id, m_pLogicalCamera[camera_id].device_version);
2165 return BAD_VALUE;
2166 }
2167
2168 cam->dev.common.tag = HARDWARE_DEVICE_TAG;
2169 cam->dev.common.version = HARDWARE_DEVICE_API_VERSION(1, 0);
2170 cam->dev.common.close = close_camera_device;
2171 cam->dev.ops = &mCameraMuxerOps;
2172 cam->dev.priv = (void*)cam;
2173 *hw_device = &cam->dev.common;
2174 return rc;
2175 }
2176
2177
2178 /*===========================================================================
2179 * FUNCTION : getLogicalCamera
2180 *
2181 * DESCRIPTION: Get logical camera descriptor
2182 *
2183 * PARAMETERS :
2184 * @device : camera hardware device info
2185 *
2186 * RETURN : logical camera descriptor or NULL
2187 *==========================================================================*/
getLogicalCamera(struct camera_device * device)2188 qcamera_logical_descriptor_t* QCameraMuxer::getLogicalCamera(
2189 struct camera_device * device)
2190 {
2191 if(device && device->priv){
2192 return (qcamera_logical_descriptor_t*)(device->priv);
2193 }
2194 return NULL;
2195 }
2196
2197 /*===========================================================================
2198 * FUNCTION : getPhysicalCamera
2199 *
2200 * DESCRIPTION: Get physical camera descriptor
2201 *
2202 * PARAMETERS :
2203 * @log_cam : Logical camera descriptor
2204 * @index : physical camera index
2205 *
2206 * RETURN : physical camera descriptor or NULL
2207 *==========================================================================*/
getPhysicalCamera(qcamera_logical_descriptor_t * log_cam,uint32_t index)2208 qcamera_physical_descriptor_t* QCameraMuxer::getPhysicalCamera(
2209 qcamera_logical_descriptor_t* log_cam, uint32_t index)
2210 {
2211 if(!log_cam){
2212 return NULL;
2213 }
2214 return &m_pPhyCamera[log_cam->pId[index]];
2215 }
2216
2217 /*===========================================================================
2218 * FUNCTION : getActiveNumOfPhyCam
2219 *
2220 * DESCRIPTION: Get active physical camera number in Logical Camera
2221 *
2222 * PARAMETERS :
2223 * @log_cam : Logical camera descriptor
2224 * @numOfAcitvePhyCam : number of active physical camera in Logical Camera.
2225 *
2226 * RETURN :
2227 * NO_ERROR : success
2228 * ENODEV : Camera not found
2229 * other: non-zero failure code
2230 *==========================================================================*/
getActiveNumOfPhyCam(qcamera_logical_descriptor_t * log_cam,int & numOfAcitvePhyCam)2231 int32_t QCameraMuxer::getActiveNumOfPhyCam(
2232 qcamera_logical_descriptor_t* log_cam, int& numOfAcitvePhyCam)
2233 {
2234 CHECK_CAMERA_ERROR(log_cam);
2235
2236 numOfAcitvePhyCam = log_cam->numCameras;
2237 return NO_ERROR;
2238 }
2239
2240
2241 /*===========================================================================
2242 * FUNCTION : sendEvtNotify
2243 *
2244 * DESCRIPTION: send event notify to HWI for error callbacks
2245 *
2246 * PARAMETERS :
2247 * @msg_type: msg type to be sent
2248 * @ext1 : optional extension1
2249 * @ext2 : optional extension2
2250 *
2251 * RETURN : int32_t type of status
2252 * NO_ERROR -- success
2253 * none-zero failure code
2254 *==========================================================================*/
sendEvtNotify(int32_t msg_type,int32_t ext1,int32_t ext2)2255 int32_t QCameraMuxer::sendEvtNotify(int32_t msg_type, int32_t ext1,
2256 int32_t ext2)
2257 {
2258 LOGH("E");
2259
2260 CHECK_MUXER_ERROR();
2261
2262 qcamera_physical_descriptor_t *pCam = NULL;
2263 pCam = (qcamera_physical_descriptor_t*)(gMuxer->getMainJpegCallbackCookie());
2264
2265 CHECK_CAMERA_ERROR(pCam);
2266
2267 QCamera2HardwareInterface *hwi = pCam->hwi;
2268 CHECK_HWI_ERROR(hwi);
2269
2270 LOGH("X");
2271 return pCam->hwi->sendEvtNotify(msg_type, ext1, ext2);
2272 }
2273
2274 /*===========================================================================
2275 * FUNCTION : composeMpo
2276 *
2277 * DESCRIPTION: Composition of the 2 MPOs
2278 *
2279 * PARAMETERS : none
2280 * @main_Jpeg: pointer to info to Main Jpeg
2281 * @aux_Jpeg : pointer to info to Aux JPEG
2282 *
2283 * RETURN : none
2284 *==========================================================================*/
composeMpo(cam_compose_jpeg_info_t * main_Jpeg,cam_compose_jpeg_info_t * aux_Jpeg)2285 void QCameraMuxer::composeMpo(cam_compose_jpeg_info_t* main_Jpeg,
2286 cam_compose_jpeg_info_t* aux_Jpeg)
2287 {
2288 LOGH("E Main Jpeg %p Aux Jpeg %p", main_Jpeg, aux_Jpeg);
2289
2290 CHECK_MUXER();
2291 if(main_Jpeg == NULL || aux_Jpeg == NULL) {
2292 LOGE("input buffers invalid, ret = NO_MEMORY");
2293 gMuxer->sendEvtNotify(CAMERA_MSG_ERROR, UNKNOWN_ERROR, 0);
2294 return;
2295 }
2296
2297 pthread_mutex_lock(&m_JpegLock);
2298
2299 m_pRelCamMpoJpeg = mGetMemoryCb(-1, main_Jpeg->buffer->size +
2300 aux_Jpeg->buffer->size, 1, m_pMpoCallbackCookie);
2301 if (NULL == m_pRelCamMpoJpeg) {
2302 LOGE("getMemory for mpo, ret = NO_MEMORY");
2303 gMuxer->sendEvtNotify(CAMERA_MSG_ERROR, UNKNOWN_ERROR, 0);
2304 pthread_mutex_unlock(&m_JpegLock);
2305 return;
2306 }
2307
2308 // fill all structures to send for composition
2309 mm_jpeg_mpo_info_t mpo_compose_info;
2310 mpo_compose_info.num_of_images = 2;
2311 mpo_compose_info.primary_image.buf_filled_len = main_Jpeg->buffer->size;
2312 mpo_compose_info.primary_image.buf_vaddr =
2313 (uint8_t*)(main_Jpeg->buffer->data);
2314 mpo_compose_info.aux_images[0].buf_filled_len = aux_Jpeg->buffer->size;
2315 mpo_compose_info.aux_images[0].buf_vaddr =
2316 (uint8_t*)(aux_Jpeg->buffer->data);
2317 mpo_compose_info.output_buff.buf_vaddr =
2318 (uint8_t*)m_pRelCamMpoJpeg->data;
2319 mpo_compose_info.output_buff.buf_filled_len = 0;
2320 mpo_compose_info.output_buff_size = main_Jpeg->buffer->size +
2321 aux_Jpeg->buffer->size;
2322
2323 LOGD("MPO buffer size %d\n"
2324 "expected size %d, mpo_compose_info.output_buff_size %d",
2325 m_pRelCamMpoJpeg->size,
2326 main_Jpeg->buffer->size + aux_Jpeg->buffer->size,
2327 mpo_compose_info.output_buff_size);
2328
2329 LOGD("MPO primary buffer filled lengths\n"
2330 "mpo_compose_info.primary_image.buf_filled_len %d\n"
2331 "mpo_compose_info.primary_image.buf_vaddr %p",
2332 mpo_compose_info.primary_image.buf_filled_len,
2333 mpo_compose_info.primary_image.buf_vaddr);
2334
2335 LOGD("MPO aux buffer filled lengths\n"
2336 "mpo_compose_info.aux_images[0].buf_filled_len %d"
2337 "mpo_compose_info.aux_images[0].buf_vaddr %p",
2338 mpo_compose_info.aux_images[0].buf_filled_len,
2339 mpo_compose_info.aux_images[0].buf_vaddr);
2340
2341 if(m_bDumpImages) {
2342 LOGD("Dumping Main Image for MPO");
2343 char buf_main[QCAMERA_MAX_FILEPATH_LENGTH];
2344 memset(buf_main, 0, sizeof(buf_main));
2345 snprintf(buf_main, sizeof(buf_main),
2346 QCAMERA_DUMP_FRM_LOCATION "Main.jpg");
2347
2348 int file_fd_main = open(buf_main, O_RDWR | O_CREAT, 0777);
2349 if (file_fd_main >= 0) {
2350 ssize_t written_len = write(file_fd_main,
2351 mpo_compose_info.primary_image.buf_vaddr,
2352 mpo_compose_info.primary_image.buf_filled_len);
2353 fchmod(file_fd_main, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
2354 LOGD("written number of bytes for main Image %zd\n",
2355 written_len);
2356 close(file_fd_main);
2357 }
2358
2359 LOGD("Dumping Aux Image for MPO");
2360 char buf_aux[QCAMERA_MAX_FILEPATH_LENGTH];
2361 memset(buf_aux, 0, sizeof(buf_aux));
2362 snprintf(buf_aux, sizeof(buf_aux),
2363 QCAMERA_DUMP_FRM_LOCATION "Aux.jpg");
2364
2365 int file_fd_aux = open(buf_aux, O_RDWR | O_CREAT, 0777);
2366 if (file_fd_aux >= 0) {
2367 ssize_t written_len = write(file_fd_aux,
2368 mpo_compose_info.aux_images[0].buf_vaddr,
2369 mpo_compose_info.aux_images[0].buf_filled_len);
2370 fchmod(file_fd_aux, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
2371 LOGD("written number of bytes for Aux Image %zd\n",
2372 written_len);
2373 close(file_fd_aux);
2374 }
2375 }
2376
2377 int32_t rc = mJpegMpoOps.compose_mpo(&mpo_compose_info);
2378 LOGD("Compose mpo returned %d", rc);
2379
2380 if(rc != NO_ERROR) {
2381 LOGE("ComposeMpo failed, ret = %d", rc);
2382 gMuxer->sendEvtNotify(CAMERA_MSG_ERROR, UNKNOWN_ERROR, 0);
2383 pthread_mutex_unlock(&m_JpegLock);
2384 return;
2385 }
2386
2387 if(m_bDumpImages) {
2388 char buf_mpo[QCAMERA_MAX_FILEPATH_LENGTH];
2389 memset(buf_mpo, 0, sizeof(buf_mpo));
2390 snprintf(buf_mpo, sizeof(buf_mpo),
2391 QCAMERA_DUMP_FRM_LOCATION "Composed.MPO");
2392
2393 int file_fd_mpo = open(buf_mpo, O_RDWR | O_CREAT, 0777);
2394 if (file_fd_mpo >= 0) {
2395 ssize_t written_len = write(file_fd_mpo,
2396 m_pRelCamMpoJpeg->data,
2397 m_pRelCamMpoJpeg->size);
2398 fchmod(file_fd_mpo, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
2399 LOGD("written number of bytes for MPO Image %zd\n",
2400 written_len);
2401 close(file_fd_mpo);
2402 }
2403 }
2404
2405 mDataCb(main_Jpeg->msg_type,
2406 m_pRelCamMpoJpeg,
2407 main_Jpeg->index,
2408 main_Jpeg->metadata,
2409 m_pMpoCallbackCookie);
2410
2411 if (NULL != m_pRelCamMpoJpeg) {
2412 m_pRelCamMpoJpeg->release(m_pRelCamMpoJpeg);
2413 m_pRelCamMpoJpeg = NULL;
2414 }
2415
2416 pthread_mutex_unlock(&m_JpegLock);
2417 LOGH("X");
2418 return;
2419 }
2420
2421 /*===========================================================================
2422 * FUNCTION : matchFrameId
2423 *
2424 * DESCRIPTION: function to match frame ids within queue nodes
2425 *
2426 * PARAMETERS :
2427 * @data: pointer to queue node to be matched for condition
2428 * @user_data: caller can add more info here
2429 * @match_data : value to be matched against
2430 *
2431 * RETURN : true or false based on whether match was successful or not
2432 *==========================================================================*/
matchFrameId(void * data,__unused void * user_data,void * match_data)2433 bool QCameraMuxer::matchFrameId(void *data, __unused void *user_data,
2434 void *match_data)
2435 {
2436 LOGH("E");
2437
2438 if (!data || !match_data) {
2439 return false;
2440 }
2441
2442 cam_compose_jpeg_info_t * node = (cam_compose_jpeg_info_t *) data;
2443 uint32_t frame_idx = *((uint32_t *) match_data);
2444 LOGH("X");
2445 return node->frame_idx == frame_idx;
2446 }
2447
2448 /*===========================================================================
2449 * FUNCTION : findPreviousJpegs
2450 *
2451 * DESCRIPTION: Finds Jpegs in the queue with index less than delivered one
2452 *
2453 * PARAMETERS :
2454 * @data: pointer to queue node to be matched for condition
2455 * @user_data: caller can add more info here
2456 * @match_data : value to be matched against
2457 *
2458 * RETURN : true or false based on whether match was successful or not
2459 *==========================================================================*/
findPreviousJpegs(void * data,__unused void * user_data,void * match_data)2460 bool QCameraMuxer::findPreviousJpegs(void *data, __unused void *user_data,
2461 void *match_data)
2462 {
2463 LOGH("E");
2464
2465 if (!data || !match_data) {
2466 return false;
2467 }
2468 cam_compose_jpeg_info_t * node = (cam_compose_jpeg_info_t *) data;
2469 uint32_t frame_idx = *((uint32_t *) match_data);
2470 LOGH("X");
2471 return node->frame_idx < frame_idx;
2472 }
2473
2474 /*===========================================================================
2475 * FUNCTION : releaseJpegInfo
2476 *
2477 * DESCRIPTION: callback function for the release of individual nodes
2478 * in the JPEG queues.
2479 *
2480 * PARAMETERS :
2481 * @data : ptr to the data to be released
2482 * @user_data : caller can add more info here
2483 *
2484 * RETURN : None
2485 *==========================================================================*/
releaseJpegInfo(void * data,__unused void * user_data)2486 void QCameraMuxer::releaseJpegInfo(void *data, __unused void *user_data)
2487 {
2488 LOGH("E");
2489
2490 cam_compose_jpeg_info_t *jpegInfo = (cam_compose_jpeg_info_t *)data;
2491 if(jpegInfo && jpegInfo->release_cb) {
2492 if (jpegInfo->release_data != NULL) {
2493 jpegInfo->release_cb(jpegInfo->release_data,
2494 jpegInfo->release_cookie,
2495 NO_ERROR);
2496 }
2497 }
2498 LOGH("X");
2499 }
2500
2501 /*===========================================================================
2502 * FUNCTION : composeMpoRoutine
2503 *
2504 * DESCRIPTION: specialized thread for MPO composition
2505 *
2506 * PARAMETERS :
2507 * @data : pointer to the thread owner
2508 *
2509 * RETURN : void* to thread
2510 *==========================================================================*/
composeMpoRoutine(__unused void * data)2511 void* QCameraMuxer::composeMpoRoutine(__unused void *data)
2512 {
2513 LOGH("E");
2514 if (!gMuxer) {
2515 LOGE("Error getting muxer ");
2516 return NULL;
2517 }
2518
2519 int running = 1;
2520 int ret;
2521 uint8_t is_active = FALSE;
2522 QCameraCmdThread *cmdThread = &gMuxer->m_ComposeMpoTh;
2523 cmdThread->setName("CAM_ComposeMpo");
2524
2525 do {
2526 do {
2527 ret = cam_sem_wait(&cmdThread->cmd_sem);
2528 if (ret != 0 && errno != EINVAL) {
2529 LOGE("cam_sem_wait error (%s)", strerror(errno));
2530 return NULL;
2531 }
2532 } while (ret != 0);
2533
2534 // we got notified about new cmd avail in cmd queue
2535 camera_cmd_type_t cmd = cmdThread->getCmd();
2536 switch (cmd) {
2537 case CAMERA_CMD_TYPE_START_DATA_PROC:
2538 {
2539 LOGH("start ComposeMpo processing");
2540 is_active = TRUE;
2541
2542 // signal cmd is completed
2543 cam_sem_post(&cmdThread->sync_sem);
2544 }
2545 break;
2546 case CAMERA_CMD_TYPE_STOP_DATA_PROC:
2547 {
2548 LOGH("stop ComposeMpo processing");
2549 is_active = FALSE;
2550
2551 // signal cmd is completed
2552 cam_sem_post(&cmdThread->sync_sem);
2553 }
2554 break;
2555 case CAMERA_CMD_TYPE_DO_NEXT_JOB:
2556 {
2557 if (is_active == TRUE) {
2558 LOGH("Mpo Composition Requested");
2559 cam_compose_jpeg_info_t *main_jpeg_node = NULL;
2560 cam_compose_jpeg_info_t *aux_jpeg_node = NULL;
2561 bool foundMatch = false;
2562 while (!gMuxer->m_MainJpegQ.isEmpty() &&
2563 !gMuxer->m_AuxJpegQ.isEmpty()) {
2564 main_jpeg_node = (cam_compose_jpeg_info_t *)
2565 gMuxer->m_MainJpegQ.dequeue();
2566 if (main_jpeg_node != NULL) {
2567 LOGD("main_jpeg_node found frame idx %d"
2568 "ptr %p buffer_ptr %p buffer_size %d",
2569 main_jpeg_node->frame_idx,
2570 main_jpeg_node,
2571 main_jpeg_node->buffer->data,
2572 main_jpeg_node->buffer->size);
2573 // find matching aux node in Aux Jpeg Queue
2574 aux_jpeg_node =
2575 (cam_compose_jpeg_info_t *) gMuxer->
2576 m_AuxJpegQ.dequeue();
2577 if (aux_jpeg_node != NULL) {
2578 LOGD("aux_jpeg_node found frame idx %d"
2579 "ptr %p buffer_ptr %p buffer_size %d",
2580 aux_jpeg_node->frame_idx,
2581 aux_jpeg_node,
2582 aux_jpeg_node->buffer->data,
2583 aux_jpeg_node->buffer->size);
2584 foundMatch = true;
2585 // start MPO composition
2586 gMuxer->composeMpo(main_jpeg_node,
2587 aux_jpeg_node);
2588 }
2589 }
2590 if (main_jpeg_node != NULL) {
2591 if ( main_jpeg_node->release_cb ) {
2592 main_jpeg_node->release_cb(
2593 main_jpeg_node->release_data,
2594 main_jpeg_node->release_cookie,
2595 NO_ERROR);
2596 }
2597 free(main_jpeg_node);
2598 main_jpeg_node = NULL;
2599 } else {
2600 LOGH("Mpo Match not found");
2601 }
2602 if (aux_jpeg_node != NULL) {
2603 if (aux_jpeg_node->release_cb) {
2604 aux_jpeg_node->release_cb(
2605 aux_jpeg_node->release_data,
2606 aux_jpeg_node->release_cookie,
2607 NO_ERROR);
2608 }
2609 free(aux_jpeg_node);
2610 aux_jpeg_node = NULL;
2611 } else {
2612 LOGH("Mpo Match not found");
2613 }
2614 }
2615 }
2616 break;
2617 }
2618 case CAMERA_CMD_TYPE_EXIT:
2619 LOGH("ComposeMpo thread exit");
2620 running = 0;
2621 break;
2622 default:
2623 break;
2624 }
2625 } while (running);
2626 LOGH("X");
2627 return NULL;
2628 }
2629
2630 /*===========================================================================
2631 * FUNCTION : jpeg_data_callback
2632 *
2633 * DESCRIPTION: JPEG data callback for snapshot
2634 *
2635 * PARAMETERS :
2636 * @msg_type : callback msg type
2637 * @data : data ptr of the buffer
2638 * @index : index of the frame
2639 * @metadata : metadata associated with the buffer
2640 * @user : callback cookie returned back to the user
2641 * @frame_idx : frame index for matching frames
2642 * @release_cb : callback function for releasing the data memory
2643 * @release_cookie : cookie for the release callback function
2644 * @release_data :pointer indicating what needs to be released
2645 *
2646 * RETURN : none
2647 *==========================================================================*/
jpeg_data_callback(int32_t msg_type,const camera_memory_t * data,unsigned int index,camera_frame_metadata_t * metadata,void * user,uint32_t frame_idx,camera_release_callback release_cb,void * release_cookie,void * release_data)2648 void QCameraMuxer::jpeg_data_callback(int32_t msg_type,
2649 const camera_memory_t *data, unsigned int index,
2650 camera_frame_metadata_t *metadata, void *user,
2651 uint32_t frame_idx, camera_release_callback release_cb,
2652 void *release_cookie, void *release_data)
2653 {
2654 LOGH("E");
2655 CHECK_MUXER();
2656
2657 if(data != NULL) {
2658 LOGH("jpeg received: data %p size %d data ptr %p frameIdx %d",
2659 data, data->size, data->data, frame_idx);
2660 int rc = gMuxer->storeJpeg(((qcamera_physical_descriptor_t*)(user))->type,
2661 msg_type, data, index, metadata, user, frame_idx, release_cb,
2662 release_cookie, release_data);
2663 if(rc != NO_ERROR) {
2664 gMuxer->sendEvtNotify(CAMERA_MSG_ERROR, UNKNOWN_ERROR, 0);
2665 }
2666 } else {
2667 gMuxer->sendEvtNotify(CAMERA_MSG_ERROR, UNKNOWN_ERROR, 0);
2668 }
2669 LOGH("X");
2670 return;
2671 }
2672
2673 /*===========================================================================
2674 * FUNCTION : storeJpeg
2675 *
2676 * DESCRIPTION: Stores jpegs from multiple related cam instances into a common Queue
2677 *
2678 * PARAMETERS :
2679 * @cam_type : indicates whether main or aux camera sent the Jpeg callback
2680 * @msg_type : callback msg type
2681 * @data : data ptr of the buffer
2682 * @index : index of the frame
2683 * @metadata : metadata associated with the buffer
2684 * @user : callback cookie returned back to the user
2685 * @frame_idx : frame index for matching frames
2686 * @release_cb : callback function for releasing the data memory
2687 * @release_cookie : cookie for the release callback function
2688 * @release_data :pointer indicating what needs to be released
2689 *
2690 * RETURN : int32_t type of status
2691 * NO_ERROR -- success
2692 * none-zero failure code
2693 *==========================================================================*/
storeJpeg(cam_sync_type_t cam_type,int32_t msg_type,const camera_memory_t * data,unsigned int index,camera_frame_metadata_t * metadata,void * user,uint32_t frame_idx,camera_release_callback release_cb,void * release_cookie,void * release_data)2694 int32_t QCameraMuxer::storeJpeg(cam_sync_type_t cam_type,
2695 int32_t msg_type, const camera_memory_t *data, unsigned int index,
2696 camera_frame_metadata_t *metadata, void *user,uint32_t frame_idx,
2697 camera_release_callback release_cb, void *release_cookie,
2698 void *release_data)
2699 {
2700 LOGH("E jpeg received: data %p size %d data ptr %p frameIdx %d",
2701 data, data->size, data->data, frame_idx);
2702
2703 CHECK_MUXER_ERROR();
2704
2705 if (!m_bMpoEnabled) {
2706 if (cam_type == CAM_TYPE_MAIN) {
2707 // send data callback only incase of main camera
2708 // aux image is ignored and released back
2709 mDataCb(msg_type,
2710 data,
2711 index,
2712 metadata,
2713 m_pMpoCallbackCookie);
2714 }
2715 if (release_cb) {
2716 release_cb(release_data, release_cookie, NO_ERROR);
2717 }
2718 LOGH("X");
2719 return NO_ERROR;
2720 }
2721
2722 cam_compose_jpeg_info_t* pJpegFrame =
2723 (cam_compose_jpeg_info_t*)malloc(sizeof(cam_compose_jpeg_info_t));
2724 if (!pJpegFrame) {
2725 LOGE("Allocation failed for MPO nodes");
2726 return NO_MEMORY;
2727 }
2728 memset(pJpegFrame, 0, sizeof(*pJpegFrame));
2729
2730 pJpegFrame->msg_type = msg_type;
2731 pJpegFrame->buffer = const_cast<camera_memory_t*>(data);
2732 pJpegFrame->index = index;
2733 pJpegFrame->metadata = metadata;
2734 pJpegFrame->user = user;
2735 pJpegFrame->valid = true;
2736 pJpegFrame->frame_idx = frame_idx;
2737 pJpegFrame->release_cb = release_cb;
2738 pJpegFrame->release_cookie = release_cookie;
2739 pJpegFrame->release_data = release_data;
2740 if(cam_type == CAM_TYPE_MAIN) {
2741 if (m_MainJpegQ.enqueue((void *)pJpegFrame)) {
2742 LOGD("Main FrameIdx %d", pJpegFrame->frame_idx);
2743 if (m_MainJpegQ.getCurrentSize() > 0) {
2744 LOGD("Trigger Compose");
2745 m_ComposeMpoTh.sendCmd(CAMERA_CMD_TYPE_DO_NEXT_JOB, FALSE, FALSE);
2746 }
2747 } else {
2748 LOGE("Enqueue Failed for Main Jpeg Q");
2749 if ( pJpegFrame->release_cb ) {
2750 // release other buffer also here
2751 pJpegFrame->release_cb(
2752 pJpegFrame->release_data,
2753 pJpegFrame->release_cookie,
2754 NO_ERROR);
2755 }
2756 free(pJpegFrame);
2757 pJpegFrame = NULL;
2758 return NO_MEMORY;
2759 }
2760
2761 } else {
2762 if (m_AuxJpegQ.enqueue((void *)pJpegFrame)) {
2763 LOGD("Aux FrameIdx %d", pJpegFrame->frame_idx);
2764 if (m_AuxJpegQ.getCurrentSize() > 0) {
2765 LOGD("Trigger Compose");
2766 m_ComposeMpoTh.sendCmd(CAMERA_CMD_TYPE_DO_NEXT_JOB, FALSE, FALSE);
2767 }
2768 } else {
2769 LOGE("Enqueue Failed for Aux Jpeg Q");
2770 if ( pJpegFrame->release_cb ) {
2771 // release other buffer also here
2772 pJpegFrame->release_cb(
2773 pJpegFrame->release_data,
2774 pJpegFrame->release_cookie,
2775 NO_ERROR);
2776 }
2777 free(pJpegFrame);
2778 pJpegFrame = NULL;
2779 return NO_MEMORY;
2780 }
2781 }
2782 LOGH("X");
2783
2784 return NO_ERROR;
2785 }
2786
2787
2788 // Muxer Ops
2789 camera_device_ops_t QCameraMuxer::mCameraMuxerOps = {
2790 .set_preview_window = QCameraMuxer::set_preview_window,
2791 .set_callbacks = QCameraMuxer::set_callBacks,
2792 .enable_msg_type = QCameraMuxer::enable_msg_type,
2793 .disable_msg_type = QCameraMuxer::disable_msg_type,
2794 .msg_type_enabled = QCameraMuxer::msg_type_enabled,
2795
2796 .start_preview = QCameraMuxer::start_preview,
2797 .stop_preview = QCameraMuxer::stop_preview,
2798 .preview_enabled = QCameraMuxer::preview_enabled,
2799 .store_meta_data_in_buffers= QCameraMuxer::store_meta_data_in_buffers,
2800
2801 .start_recording = QCameraMuxer::start_recording,
2802 .stop_recording = QCameraMuxer::stop_recording,
2803 .recording_enabled = QCameraMuxer::recording_enabled,
2804 .release_recording_frame = QCameraMuxer::release_recording_frame,
2805
2806 .auto_focus = QCameraMuxer::auto_focus,
2807 .cancel_auto_focus = QCameraMuxer::cancel_auto_focus,
2808
2809 .take_picture = QCameraMuxer::take_picture,
2810 .cancel_picture = QCameraMuxer::cancel_picture,
2811
2812 .set_parameters = QCameraMuxer::set_parameters,
2813 .get_parameters = QCameraMuxer::get_parameters,
2814 .put_parameters = QCameraMuxer::put_parameters,
2815 .send_command = QCameraMuxer::send_command,
2816
2817 .release = QCameraMuxer::release,
2818 .dump = QCameraMuxer::dump,
2819 };
2820
2821
2822 }; // namespace android
2823