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);
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);
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);
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);
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].sync_3a[0] = CAM_3A_SYNC_FOLLOW;
1836 m_pLogicalCamera[index].facing = m_pPhyCamera[i].cam_info.facing;
1837 m_pLogicalCamera[index].numCameras++;
1838 LOGH("Logical Main Camera ID: %d, facing: %d,"
1839 "Phy Id: %d type: %d mode: %d",
1840 m_pLogicalCamera[index].id,
1841 m_pLogicalCamera[index].facing,
1842 m_pLogicalCamera[index].pId[0],
1843 m_pLogicalCamera[index].type[0],
1844 m_pLogicalCamera[index].mode[0]);
1845
1846 index++;
1847 }
1848 }
1849 //Now assign AUX cameras to logical camera
1850 for (i = 0; i < m_nPhyCameras ; i++) {
1851 if (m_pPhyCamera[i].mode == CAM_MODE_SECONDARY) {
1852 for (int j = 0; j < m_nLogicalCameras; j++) {
1853 int n = m_pLogicalCamera[j].numCameras;
1854 ///@note n can only be 1 at this point
1855 if ((n < MAX_NUM_CAMERA_PER_BUNDLE) &&
1856 (m_pLogicalCamera[j].facing ==
1857 m_pPhyCamera[i].cam_info.facing)) {
1858 m_pLogicalCamera[j].pId[n] = i;
1859 m_pLogicalCamera[j].type[n] = CAM_TYPE_AUX;
1860 m_pLogicalCamera[j].mode[n] = CAM_MODE_SECONDARY;
1861 m_pLogicalCamera[j].sync_3a[n] = CAM_3A_SYNC_FOLLOW;
1862 m_pLogicalCamera[j].numCameras++;
1863 LOGH("Aux %d for Logical Camera ID: %d,"
1864 "aux phy id:%d, type: %d mode: %d",
1865 n, j, m_pLogicalCamera[j].pId[n],
1866 m_pLogicalCamera[j].type[n], m_pLogicalCamera[j].mode[n]);
1867 }
1868 }
1869 }
1870 }
1871 //Print logical and physical camera tables
1872 for (i = 0; i < m_nLogicalCameras ; i++) {
1873 for (uint8_t j = 0; j < m_pLogicalCamera[i].numCameras; j++) {
1874 LOGH("Logical Camera ID: %d, index: %d, "
1875 "facing: %d, Phy Id: %d type: %d mode: %d",
1876 i, j, m_pLogicalCamera[i].facing,
1877 m_pLogicalCamera[i].pId[j], m_pLogicalCamera[i].type[j],
1878 m_pLogicalCamera[i].mode[j]);
1879 }
1880 }
1881 LOGH("[%d] X: rc = %d", rc);
1882 return rc;
1883 }
1884
1885 /*===========================================================================
1886 * FUNCTION : getNumberOfCameras
1887 *
1888 * DESCRIPTION: query number of logical cameras detected
1889 *
1890 * RETURN : number of cameras detected
1891 *==========================================================================*/
getNumberOfCameras()1892 int QCameraMuxer::getNumberOfCameras()
1893 {
1894 return m_nLogicalCameras;
1895 }
1896
1897 /*===========================================================================
1898 * FUNCTION : getCameraInfo
1899 *
1900 * DESCRIPTION: query camera information with its ID
1901 *
1902 * PARAMETERS :
1903 * @camera_id : camera ID
1904 * @info : ptr to camera info struct
1905 *
1906 * RETURN : int32_t type of status
1907 * NO_ERROR -- success
1908 * none-zero failure code
1909 *==========================================================================*/
getCameraInfo(int camera_id,struct camera_info * info,__unused cam_sync_type_t * p_cam_type)1910 int QCameraMuxer::getCameraInfo(int camera_id,
1911 struct camera_info *info, __unused cam_sync_type_t *p_cam_type)
1912 {
1913 int rc = NO_ERROR;
1914 LOGH("E, camera_id = %d", camera_id);
1915
1916 if (!m_nLogicalCameras || (camera_id >= m_nLogicalCameras) ||
1917 !info || (camera_id < 0)) {
1918 LOGE("m_nLogicalCameras: %d, camera id: %d",
1919 m_nLogicalCameras, camera_id);
1920 return -ENODEV;
1921 }
1922
1923 if (!m_pLogicalCamera || !m_pPhyCamera) {
1924 LOGE("Error! Cameras not initialized!");
1925 return NO_INIT;
1926 }
1927 uint32_t phy_id =
1928 m_pLogicalCamera[camera_id].pId[
1929 m_pLogicalCamera[camera_id].nPrimaryPhyCamIndex];
1930 // Call HAL3 getCamInfo to get the flash light info through static metatdata
1931 // regardless of HAL version
1932 rc = QCamera3HardwareInterface::getCamInfo(phy_id, info);
1933 info->device_version = CAMERA_DEVICE_API_VERSION_1_0; // Hardcode the HAL to HAL1
1934 LOGH("X");
1935 return rc;
1936 }
1937
1938 /*===========================================================================
1939 * FUNCTION : setCallbacks
1940 *
1941 * DESCRIPTION: set callback functions to send asynchronous notifications to
1942 * frameworks.
1943 *
1944 * PARAMETERS :
1945 * @callbacks : callback function pointer
1946 *
1947 * RETURN : int32_t type of status
1948 * NO_ERROR -- success
1949 * none-zero failure code
1950 *==========================================================================*/
setCallbacks(const camera_module_callbacks_t * callbacks)1951 int32_t QCameraMuxer::setCallbacks(const camera_module_callbacks_t *callbacks)
1952 {
1953 if(callbacks) {
1954 m_pCallbacks = callbacks;
1955 return NO_ERROR;
1956 } else {
1957 return BAD_TYPE;
1958 }
1959 }
1960
1961 /*===========================================================================
1962 * FUNCTION : setDataCallback
1963 *
1964 * DESCRIPTION: set data callback function for snapshots
1965 *
1966 * PARAMETERS :
1967 * @data_cb : callback function pointer
1968 *
1969 * RETURN : int32_t type of status
1970 * NO_ERROR -- success
1971 * none-zero failure code
1972 *==========================================================================*/
setDataCallback(camera_data_callback data_cb)1973 int32_t QCameraMuxer::setDataCallback(camera_data_callback data_cb)
1974 {
1975 if(data_cb) {
1976 mDataCb = data_cb;
1977 return NO_ERROR;
1978 } else {
1979 return BAD_TYPE;
1980 }
1981 }
1982
1983 /*===========================================================================
1984 * FUNCTION : setMemoryCallback
1985 *
1986 * DESCRIPTION: set get memory callback for memory allocations
1987 *
1988 * PARAMETERS :
1989 * @get_memory : callback function pointer
1990 *
1991 * RETURN : int32_t type of status
1992 * NO_ERROR -- success
1993 * none-zero failure code
1994 *==========================================================================*/
setMemoryCallback(camera_request_memory get_memory)1995 int32_t QCameraMuxer::setMemoryCallback(camera_request_memory get_memory)
1996 {
1997 if(get_memory) {
1998 mGetMemoryCb = get_memory;
1999 return NO_ERROR;
2000 } else {
2001 return BAD_TYPE;
2002 }
2003 }
2004
2005 /*===========================================================================
2006 * FUNCTION : setMpoCallbackCookie
2007 *
2008 * DESCRIPTION: set mpo callback cookie. will be used for sending final MPO callbacks
2009 * to framework
2010 *
2011 * PARAMETERS :
2012 * @mpoCbCookie : callback function pointer
2013 *
2014 * RETURN : int32_t type of status
2015 * NO_ERROR -- success
2016 * none-zero failure code
2017 *==========================================================================*/
setMpoCallbackCookie(void * mpoCbCookie)2018 int32_t QCameraMuxer::setMpoCallbackCookie(void* mpoCbCookie)
2019 {
2020 if(mpoCbCookie) {
2021 m_pMpoCallbackCookie = mpoCbCookie;
2022 return NO_ERROR;
2023 } else {
2024 return BAD_TYPE;
2025 }
2026 }
2027
2028 /*===========================================================================
2029 * FUNCTION : getMpoCallbackCookie
2030 *
2031 * DESCRIPTION: gets the mpo callback cookie. will be used for sending final MPO callbacks
2032 * to framework
2033 *
2034 * PARAMETERS :none
2035 *
2036 * RETURN :void ptr to the mpo callback cookie
2037 *==========================================================================*/
getMpoCallbackCookie(void)2038 void* QCameraMuxer::getMpoCallbackCookie(void)
2039 {
2040 return m_pMpoCallbackCookie;
2041 }
2042
2043 /*===========================================================================
2044 * FUNCTION : setMainJpegCallbackCookie
2045 *
2046 * DESCRIPTION: set jpeg callback cookie.
2047 * set to phy cam instance of the primary related cam instance
2048 *
2049 * PARAMETERS :
2050 * @jpegCbCookie : ptr to jpeg cookie
2051 *
2052 * RETURN : int32_t type of status
2053 * NO_ERROR -- success
2054 * none-zero failure code
2055 *==========================================================================*/
setMainJpegCallbackCookie(void * jpegCbCookie)2056 int32_t QCameraMuxer::setMainJpegCallbackCookie(void* jpegCbCookie)
2057 {
2058 if(jpegCbCookie) {
2059 m_pJpegCallbackCookie = jpegCbCookie;
2060 return NO_ERROR;
2061 } else {
2062 return BAD_TYPE;
2063 }
2064 }
2065
2066 /*===========================================================================
2067 * FUNCTION : getMainJpegCallbackCookie
2068 *
2069 * DESCRIPTION: gets the jpeg callback cookie for primary related cam instance
2070 * set to phy cam instance of the primary related cam instance
2071 *
2072 * PARAMETERS :none
2073 *
2074 * RETURN :void ptr to the jpeg callback cookie
2075 *==========================================================================*/
getMainJpegCallbackCookie(void)2076 void* QCameraMuxer::getMainJpegCallbackCookie(void)
2077 {
2078 return m_pJpegCallbackCookie;
2079 }
2080
2081 /*===========================================================================
2082 * FUNCTION : cameraDeviceOpen
2083 *
2084 * DESCRIPTION: open a camera device with its ID
2085 *
2086 * PARAMETERS :
2087 * @camera_id : camera ID
2088 * @hw_device : ptr to struct storing camera hardware device info
2089 *
2090 * RETURN : int32_t type of status
2091 * NO_ERROR -- success
2092 * none-zero failure code
2093 *==========================================================================*/
cameraDeviceOpen(int camera_id,struct hw_device_t ** hw_device)2094 int QCameraMuxer::cameraDeviceOpen(int camera_id,
2095 struct hw_device_t **hw_device)
2096 {
2097 int rc = NO_ERROR;
2098 uint32_t phyId = 0;
2099 qcamera_logical_descriptor_t *cam = NULL;
2100
2101 if (camera_id < 0 || camera_id >= m_nLogicalCameras) {
2102 LOGE("Camera id %d not found!", camera_id);
2103 return -ENODEV;
2104 }
2105
2106 if ( NULL == m_pLogicalCamera) {
2107 LOGE("Hal descriptor table is not initialized!");
2108 return NO_INIT;
2109 }
2110
2111 char prop[PROPERTY_VALUE_MAX];
2112 property_get("persist.camera.dc.frame.sync", prop, "1");
2113 m_bFrameSyncEnabled = atoi(prop);
2114
2115 // Get logical camera
2116 cam = &m_pLogicalCamera[camera_id];
2117
2118 if (m_pLogicalCamera[camera_id].device_version ==
2119 CAMERA_DEVICE_API_VERSION_1_0) {
2120 // HW Dev Holders
2121 hw_device_t *hw_dev[cam->numCameras];
2122
2123 if (m_pPhyCamera[cam->pId[0]].type != CAM_TYPE_MAIN) {
2124 LOGE("Physical camera at index 0 is not main!");
2125 return UNKNOWN_ERROR;
2126 }
2127
2128 // Open all physical cameras
2129 for (uint32_t i = 0; i < cam->numCameras; i++) {
2130 phyId = cam->pId[i];
2131 QCamera2HardwareInterface *hw =
2132 new QCamera2HardwareInterface((uint32_t)phyId);
2133 if (!hw) {
2134 LOGE("Allocation of hardware interface failed");
2135 return NO_MEMORY;
2136 }
2137 hw_dev[i] = NULL;
2138
2139 // Make Camera HWI aware of its mode
2140 cam_sync_related_sensors_event_info_t info;
2141 info.sync_control = CAM_SYNC_RELATED_SENSORS_ON;
2142 info.mode = m_pPhyCamera[phyId].mode;
2143 info.type = m_pPhyCamera[phyId].type;
2144 rc = hw->setRelatedCamSyncInfo(&info);
2145 hw->setFrameSyncEnabled(m_bFrameSyncEnabled);
2146 if (rc != NO_ERROR) {
2147 LOGE("setRelatedCamSyncInfo failed %d", rc);
2148 delete hw;
2149 return rc;
2150 }
2151
2152 rc = hw->openCamera(&hw_dev[i]);
2153 if (rc != NO_ERROR) {
2154 delete hw;
2155 return rc;
2156 }
2157 hw->getCameraSessionId(&m_pPhyCamera[phyId].camera_server_id);
2158 m_pPhyCamera[phyId].dev = reinterpret_cast<camera_device_t*>(hw_dev[i]);
2159 m_pPhyCamera[phyId].hwi = hw;
2160 cam->sId[i] = m_pPhyCamera[phyId].camera_server_id;
2161 LOGH("camera id %d server id : %d hw device %x, hw %x",
2162 phyId, cam->sId[i], hw_dev[i], hw);
2163 }
2164 } else {
2165 LOGE("Device version for camera id %d invalid %d",
2166 camera_id, m_pLogicalCamera[camera_id].device_version);
2167 return BAD_VALUE;
2168 }
2169
2170 cam->dev.common.tag = HARDWARE_DEVICE_TAG;
2171 cam->dev.common.version = HARDWARE_DEVICE_API_VERSION(1, 0);
2172 cam->dev.common.close = close_camera_device;
2173 cam->dev.ops = &mCameraMuxerOps;
2174 cam->dev.priv = (void*)cam;
2175 *hw_device = &cam->dev.common;
2176 return rc;
2177 }
2178
2179
2180 /*===========================================================================
2181 * FUNCTION : getLogicalCamera
2182 *
2183 * DESCRIPTION: Get logical camera descriptor
2184 *
2185 * PARAMETERS :
2186 * @device : camera hardware device info
2187 *
2188 * RETURN : logical camera descriptor or NULL
2189 *==========================================================================*/
getLogicalCamera(struct camera_device * device)2190 qcamera_logical_descriptor_t* QCameraMuxer::getLogicalCamera(
2191 struct camera_device * device)
2192 {
2193 if(device && device->priv){
2194 return (qcamera_logical_descriptor_t*)(device->priv);
2195 }
2196 return NULL;
2197 }
2198
2199 /*===========================================================================
2200 * FUNCTION : getPhysicalCamera
2201 *
2202 * DESCRIPTION: Get physical camera descriptor
2203 *
2204 * PARAMETERS :
2205 * @log_cam : Logical camera descriptor
2206 * @index : physical camera index
2207 *
2208 * RETURN : physical camera descriptor or NULL
2209 *==========================================================================*/
getPhysicalCamera(qcamera_logical_descriptor_t * log_cam,uint32_t index)2210 qcamera_physical_descriptor_t* QCameraMuxer::getPhysicalCamera(
2211 qcamera_logical_descriptor_t* log_cam, uint32_t index)
2212 {
2213 if(!log_cam){
2214 return NULL;
2215 }
2216 return &m_pPhyCamera[log_cam->pId[index]];
2217 }
2218
2219 /*===========================================================================
2220 * FUNCTION : getActiveNumOfPhyCam
2221 *
2222 * DESCRIPTION: Get active physical camera number in Logical Camera
2223 *
2224 * PARAMETERS :
2225 * @log_cam : Logical camera descriptor
2226 * @numOfAcitvePhyCam : number of active physical camera in Logical Camera.
2227 *
2228 * RETURN :
2229 * NO_ERROR : success
2230 * ENODEV : Camera not found
2231 * other: non-zero failure code
2232 *==========================================================================*/
getActiveNumOfPhyCam(qcamera_logical_descriptor_t * log_cam,int & numOfAcitvePhyCam)2233 int32_t QCameraMuxer::getActiveNumOfPhyCam(
2234 qcamera_logical_descriptor_t* log_cam, int& numOfAcitvePhyCam)
2235 {
2236 CHECK_CAMERA_ERROR(log_cam);
2237
2238 numOfAcitvePhyCam = log_cam->numCameras;
2239 return NO_ERROR;
2240 }
2241
2242
2243 /*===========================================================================
2244 * FUNCTION : sendEvtNotify
2245 *
2246 * DESCRIPTION: send event notify to HWI for error callbacks
2247 *
2248 * PARAMETERS :
2249 * @msg_type: msg type to be sent
2250 * @ext1 : optional extension1
2251 * @ext2 : optional extension2
2252 *
2253 * RETURN : int32_t type of status
2254 * NO_ERROR -- success
2255 * none-zero failure code
2256 *==========================================================================*/
sendEvtNotify(int32_t msg_type,int32_t ext1,int32_t ext2)2257 int32_t QCameraMuxer::sendEvtNotify(int32_t msg_type, int32_t ext1,
2258 int32_t ext2)
2259 {
2260 LOGH("E");
2261
2262 CHECK_MUXER_ERROR();
2263
2264 qcamera_physical_descriptor_t *pCam = NULL;
2265 pCam = (qcamera_physical_descriptor_t*)(gMuxer->getMainJpegCallbackCookie());
2266
2267 CHECK_CAMERA_ERROR(pCam);
2268
2269 QCamera2HardwareInterface *hwi = pCam->hwi;
2270 CHECK_HWI_ERROR(hwi);
2271
2272 LOGH("X");
2273 return pCam->hwi->sendEvtNotify(msg_type, ext1, ext2);
2274 }
2275
2276 /*===========================================================================
2277 * FUNCTION : composeMpo
2278 *
2279 * DESCRIPTION: Composition of the 2 MPOs
2280 *
2281 * PARAMETERS : none
2282 * @main_Jpeg: pointer to info to Main Jpeg
2283 * @aux_Jpeg : pointer to info to Aux JPEG
2284 *
2285 * RETURN : none
2286 *==========================================================================*/
composeMpo(cam_compose_jpeg_info_t * main_Jpeg,cam_compose_jpeg_info_t * aux_Jpeg)2287 void QCameraMuxer::composeMpo(cam_compose_jpeg_info_t* main_Jpeg,
2288 cam_compose_jpeg_info_t* aux_Jpeg)
2289 {
2290 LOGH("E Main Jpeg %p Aux Jpeg %p", main_Jpeg, aux_Jpeg);
2291
2292 CHECK_MUXER();
2293 if(main_Jpeg == NULL || aux_Jpeg == NULL) {
2294 LOGE("input buffers invalid, ret = NO_MEMORY");
2295 gMuxer->sendEvtNotify(CAMERA_MSG_ERROR, UNKNOWN_ERROR, 0);
2296 return;
2297 }
2298
2299 pthread_mutex_lock(&m_JpegLock);
2300
2301 m_pRelCamMpoJpeg = mGetMemoryCb(-1, main_Jpeg->buffer->size +
2302 aux_Jpeg->buffer->size, 1, m_pMpoCallbackCookie);
2303 if (NULL == m_pRelCamMpoJpeg) {
2304 LOGE("getMemory for mpo, ret = NO_MEMORY");
2305 gMuxer->sendEvtNotify(CAMERA_MSG_ERROR, UNKNOWN_ERROR, 0);
2306 pthread_mutex_unlock(&m_JpegLock);
2307 return;
2308 }
2309
2310 // fill all structures to send for composition
2311 mm_jpeg_mpo_info_t mpo_compose_info;
2312 mpo_compose_info.num_of_images = 2;
2313 mpo_compose_info.primary_image.buf_filled_len = main_Jpeg->buffer->size;
2314 mpo_compose_info.primary_image.buf_vaddr =
2315 (uint8_t*)(main_Jpeg->buffer->data);
2316 mpo_compose_info.aux_images[0].buf_filled_len = aux_Jpeg->buffer->size;
2317 mpo_compose_info.aux_images[0].buf_vaddr =
2318 (uint8_t*)(aux_Jpeg->buffer->data);
2319 mpo_compose_info.output_buff.buf_vaddr =
2320 (uint8_t*)m_pRelCamMpoJpeg->data;
2321 mpo_compose_info.output_buff.buf_filled_len = 0;
2322 mpo_compose_info.output_buff_size = main_Jpeg->buffer->size +
2323 aux_Jpeg->buffer->size;
2324
2325 LOGD("MPO buffer size %d\n"
2326 "expected size %d, mpo_compose_info.output_buff_size %d",
2327 m_pRelCamMpoJpeg->size,
2328 main_Jpeg->buffer->size + aux_Jpeg->buffer->size,
2329 mpo_compose_info.output_buff_size);
2330
2331 LOGD("MPO primary buffer filled lengths\n"
2332 "mpo_compose_info.primary_image.buf_filled_len %d\n"
2333 "mpo_compose_info.primary_image.buf_vaddr %p",
2334 mpo_compose_info.primary_image.buf_filled_len,
2335 mpo_compose_info.primary_image.buf_vaddr);
2336
2337 LOGD("MPO aux buffer filled lengths\n"
2338 "mpo_compose_info.aux_images[0].buf_filled_len %d"
2339 "mpo_compose_info.aux_images[0].buf_vaddr %p",
2340 mpo_compose_info.aux_images[0].buf_filled_len,
2341 mpo_compose_info.aux_images[0].buf_vaddr);
2342
2343 if(m_bDumpImages) {
2344 LOGD("Dumping Main Image for MPO");
2345 char buf_main[QCAMERA_MAX_FILEPATH_LENGTH];
2346 memset(buf_main, 0, sizeof(buf_main));
2347 snprintf(buf_main, sizeof(buf_main),
2348 QCAMERA_DUMP_FRM_LOCATION "Main.jpg");
2349
2350 int file_fd_main = open(buf_main, O_RDWR | O_CREAT, 0777);
2351 if (file_fd_main >= 0) {
2352 ssize_t written_len = write(file_fd_main,
2353 mpo_compose_info.primary_image.buf_vaddr,
2354 mpo_compose_info.primary_image.buf_filled_len);
2355 fchmod(file_fd_main, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
2356 LOGD("written number of bytes for main Image %zd\n",
2357 written_len);
2358 close(file_fd_main);
2359 }
2360
2361 LOGD("Dumping Aux Image for MPO");
2362 char buf_aux[QCAMERA_MAX_FILEPATH_LENGTH];
2363 memset(buf_aux, 0, sizeof(buf_aux));
2364 snprintf(buf_aux, sizeof(buf_aux),
2365 QCAMERA_DUMP_FRM_LOCATION "Aux.jpg");
2366
2367 int file_fd_aux = open(buf_aux, O_RDWR | O_CREAT, 0777);
2368 if (file_fd_aux >= 0) {
2369 ssize_t written_len = write(file_fd_aux,
2370 mpo_compose_info.aux_images[0].buf_vaddr,
2371 mpo_compose_info.aux_images[0].buf_filled_len);
2372 fchmod(file_fd_aux, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
2373 LOGD("written number of bytes for Aux Image %zd\n",
2374 written_len);
2375 close(file_fd_aux);
2376 }
2377 }
2378
2379 int32_t rc = mJpegMpoOps.compose_mpo(&mpo_compose_info);
2380 LOGD("Compose mpo returned %d", rc);
2381
2382 if(rc != NO_ERROR) {
2383 LOGE("ComposeMpo failed, ret = %d", rc);
2384 gMuxer->sendEvtNotify(CAMERA_MSG_ERROR, UNKNOWN_ERROR, 0);
2385 pthread_mutex_unlock(&m_JpegLock);
2386 return;
2387 }
2388
2389 if(m_bDumpImages) {
2390 char buf_mpo[QCAMERA_MAX_FILEPATH_LENGTH];
2391 memset(buf_mpo, 0, sizeof(buf_mpo));
2392 snprintf(buf_mpo, sizeof(buf_mpo),
2393 QCAMERA_DUMP_FRM_LOCATION "Composed.MPO");
2394
2395 int file_fd_mpo = open(buf_mpo, O_RDWR | O_CREAT, 0777);
2396 if (file_fd_mpo >= 0) {
2397 ssize_t written_len = write(file_fd_mpo,
2398 m_pRelCamMpoJpeg->data,
2399 m_pRelCamMpoJpeg->size);
2400 fchmod(file_fd_mpo, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
2401 LOGD("written number of bytes for MPO Image %zd\n",
2402 written_len);
2403 close(file_fd_mpo);
2404 }
2405 }
2406
2407 mDataCb(main_Jpeg->msg_type,
2408 m_pRelCamMpoJpeg,
2409 main_Jpeg->index,
2410 main_Jpeg->metadata,
2411 m_pMpoCallbackCookie);
2412
2413 if (NULL != m_pRelCamMpoJpeg) {
2414 m_pRelCamMpoJpeg->release(m_pRelCamMpoJpeg);
2415 m_pRelCamMpoJpeg = NULL;
2416 }
2417
2418 pthread_mutex_unlock(&m_JpegLock);
2419 LOGH("X");
2420 return;
2421 }
2422
2423 /*===========================================================================
2424 * FUNCTION : matchFrameId
2425 *
2426 * DESCRIPTION: function to match frame ids within queue nodes
2427 *
2428 * PARAMETERS :
2429 * @data: pointer to queue node to be matched for condition
2430 * @user_data: caller can add more info here
2431 * @match_data : value to be matched against
2432 *
2433 * RETURN : true or false based on whether match was successful or not
2434 *==========================================================================*/
matchFrameId(void * data,__unused void * user_data,void * match_data)2435 bool QCameraMuxer::matchFrameId(void *data, __unused void *user_data,
2436 void *match_data)
2437 {
2438 LOGH("E");
2439
2440 if (!data || !match_data) {
2441 return false;
2442 }
2443
2444 cam_compose_jpeg_info_t * node = (cam_compose_jpeg_info_t *) data;
2445 uint32_t frame_idx = *((uint32_t *) match_data);
2446 LOGH("X");
2447 return node->frame_idx == frame_idx;
2448 }
2449
2450 /*===========================================================================
2451 * FUNCTION : findPreviousJpegs
2452 *
2453 * DESCRIPTION: Finds Jpegs in the queue with index less than delivered one
2454 *
2455 * PARAMETERS :
2456 * @data: pointer to queue node to be matched for condition
2457 * @user_data: caller can add more info here
2458 * @match_data : value to be matched against
2459 *
2460 * RETURN : true or false based on whether match was successful or not
2461 *==========================================================================*/
findPreviousJpegs(void * data,__unused void * user_data,void * match_data)2462 bool QCameraMuxer::findPreviousJpegs(void *data, __unused void *user_data,
2463 void *match_data)
2464 {
2465 LOGH("E");
2466
2467 if (!data || !match_data) {
2468 return false;
2469 }
2470 cam_compose_jpeg_info_t * node = (cam_compose_jpeg_info_t *) data;
2471 uint32_t frame_idx = *((uint32_t *) match_data);
2472 LOGH("X");
2473 return node->frame_idx < frame_idx;
2474 }
2475
2476 /*===========================================================================
2477 * FUNCTION : releaseJpegInfo
2478 *
2479 * DESCRIPTION: callback function for the release of individual nodes
2480 * in the JPEG queues.
2481 *
2482 * PARAMETERS :
2483 * @data : ptr to the data to be released
2484 * @user_data : caller can add more info here
2485 *
2486 * RETURN : None
2487 *==========================================================================*/
releaseJpegInfo(void * data,__unused void * user_data)2488 void QCameraMuxer::releaseJpegInfo(void *data, __unused void *user_data)
2489 {
2490 LOGH("E");
2491
2492 cam_compose_jpeg_info_t *jpegInfo = (cam_compose_jpeg_info_t *)data;
2493 if(jpegInfo && jpegInfo->release_cb) {
2494 if (jpegInfo->release_data != NULL) {
2495 jpegInfo->release_cb(jpegInfo->release_data,
2496 jpegInfo->release_cookie,
2497 NO_ERROR);
2498 }
2499 }
2500 LOGH("X");
2501 }
2502
2503 /*===========================================================================
2504 * FUNCTION : composeMpoRoutine
2505 *
2506 * DESCRIPTION: specialized thread for MPO composition
2507 *
2508 * PARAMETERS :
2509 * @data : pointer to the thread owner
2510 *
2511 * RETURN : void* to thread
2512 *==========================================================================*/
composeMpoRoutine(__unused void * data)2513 void* QCameraMuxer::composeMpoRoutine(__unused void *data)
2514 {
2515 LOGH("E");
2516 if (!gMuxer) {
2517 LOGE("Error getting muxer ");
2518 return NULL;
2519 }
2520
2521 int running = 1;
2522 int ret;
2523 uint8_t is_active = FALSE;
2524 QCameraCmdThread *cmdThread = &gMuxer->m_ComposeMpoTh;
2525 cmdThread->setName("CAM_ComposeMpo");
2526
2527 do {
2528 do {
2529 ret = cam_sem_wait(&cmdThread->cmd_sem);
2530 if (ret != 0 && errno != EINVAL) {
2531 LOGE("cam_sem_wait error (%s)", strerror(errno));
2532 return NULL;
2533 }
2534 } while (ret != 0);
2535
2536 // we got notified about new cmd avail in cmd queue
2537 camera_cmd_type_t cmd = cmdThread->getCmd();
2538 switch (cmd) {
2539 case CAMERA_CMD_TYPE_START_DATA_PROC:
2540 {
2541 LOGH("start ComposeMpo processing");
2542 is_active = TRUE;
2543
2544 // signal cmd is completed
2545 cam_sem_post(&cmdThread->sync_sem);
2546 }
2547 break;
2548 case CAMERA_CMD_TYPE_STOP_DATA_PROC:
2549 {
2550 LOGH("stop ComposeMpo processing");
2551 is_active = FALSE;
2552
2553 // signal cmd is completed
2554 cam_sem_post(&cmdThread->sync_sem);
2555 }
2556 break;
2557 case CAMERA_CMD_TYPE_DO_NEXT_JOB:
2558 {
2559 if (is_active == TRUE) {
2560 LOGH("Mpo Composition Requested");
2561 cam_compose_jpeg_info_t *main_jpeg_node = NULL;
2562 cam_compose_jpeg_info_t *aux_jpeg_node = NULL;
2563 bool foundMatch = false;
2564 while (!gMuxer->m_MainJpegQ.isEmpty() &&
2565 !gMuxer->m_AuxJpegQ.isEmpty()) {
2566 main_jpeg_node = (cam_compose_jpeg_info_t *)
2567 gMuxer->m_MainJpegQ.dequeue();
2568 if (main_jpeg_node != NULL) {
2569 LOGD("main_jpeg_node found frame idx %d"
2570 "ptr %p buffer_ptr %p buffer_size %d",
2571 main_jpeg_node->frame_idx,
2572 main_jpeg_node,
2573 main_jpeg_node->buffer->data,
2574 main_jpeg_node->buffer->size);
2575 // find matching aux node in Aux Jpeg Queue
2576 aux_jpeg_node =
2577 (cam_compose_jpeg_info_t *) gMuxer->
2578 m_AuxJpegQ.dequeue();
2579 if (aux_jpeg_node != NULL) {
2580 LOGD("aux_jpeg_node found frame idx %d"
2581 "ptr %p buffer_ptr %p buffer_size %d",
2582 aux_jpeg_node->frame_idx,
2583 aux_jpeg_node,
2584 aux_jpeg_node->buffer->data,
2585 aux_jpeg_node->buffer->size);
2586 foundMatch = true;
2587 // start MPO composition
2588 gMuxer->composeMpo(main_jpeg_node,
2589 aux_jpeg_node);
2590 }
2591 }
2592 if (main_jpeg_node != NULL) {
2593 if ( main_jpeg_node->release_cb ) {
2594 main_jpeg_node->release_cb(
2595 main_jpeg_node->release_data,
2596 main_jpeg_node->release_cookie,
2597 NO_ERROR);
2598 }
2599 free(main_jpeg_node);
2600 main_jpeg_node = NULL;
2601 } else {
2602 LOGH("Mpo Match not found");
2603 }
2604 if (aux_jpeg_node != NULL) {
2605 if (aux_jpeg_node->release_cb) {
2606 aux_jpeg_node->release_cb(
2607 aux_jpeg_node->release_data,
2608 aux_jpeg_node->release_cookie,
2609 NO_ERROR);
2610 }
2611 free(aux_jpeg_node);
2612 aux_jpeg_node = NULL;
2613 } else {
2614 LOGH("Mpo Match not found");
2615 }
2616 }
2617 }
2618 break;
2619 }
2620 case CAMERA_CMD_TYPE_EXIT:
2621 LOGH("ComposeMpo thread exit");
2622 running = 0;
2623 break;
2624 default:
2625 break;
2626 }
2627 } while (running);
2628 LOGH("X");
2629 return NULL;
2630 }
2631
2632 /*===========================================================================
2633 * FUNCTION : jpeg_data_callback
2634 *
2635 * DESCRIPTION: JPEG data callback for snapshot
2636 *
2637 * PARAMETERS :
2638 * @msg_type : callback msg type
2639 * @data : data ptr of the buffer
2640 * @index : index of the frame
2641 * @metadata : metadata associated with the buffer
2642 * @user : callback cookie returned back to the user
2643 * @frame_idx : frame index for matching frames
2644 * @release_cb : callback function for releasing the data memory
2645 * @release_cookie : cookie for the release callback function
2646 * @release_data :pointer indicating what needs to be released
2647 *
2648 * RETURN : none
2649 *==========================================================================*/
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)2650 void QCameraMuxer::jpeg_data_callback(int32_t msg_type,
2651 const camera_memory_t *data, unsigned int index,
2652 camera_frame_metadata_t *metadata, void *user,
2653 uint32_t frame_idx, camera_release_callback release_cb,
2654 void *release_cookie, void *release_data)
2655 {
2656 LOGH("E");
2657 CHECK_MUXER();
2658
2659 if(data != NULL) {
2660 LOGH("jpeg received: data %p size %d data ptr %p frameIdx %d",
2661 data, data->size, data->data, frame_idx);
2662 int rc = gMuxer->storeJpeg(((qcamera_physical_descriptor_t*)(user))->type,
2663 msg_type, data, index, metadata, user, frame_idx, release_cb,
2664 release_cookie, release_data);
2665 if(rc != NO_ERROR) {
2666 gMuxer->sendEvtNotify(CAMERA_MSG_ERROR, UNKNOWN_ERROR, 0);
2667 }
2668 } else {
2669 gMuxer->sendEvtNotify(CAMERA_MSG_ERROR, UNKNOWN_ERROR, 0);
2670 }
2671 LOGH("X");
2672 return;
2673 }
2674
2675 /*===========================================================================
2676 * FUNCTION : storeJpeg
2677 *
2678 * DESCRIPTION: Stores jpegs from multiple related cam instances into a common Queue
2679 *
2680 * PARAMETERS :
2681 * @cam_type : indicates whether main or aux camera sent the Jpeg callback
2682 * @msg_type : callback msg type
2683 * @data : data ptr of the buffer
2684 * @index : index of the frame
2685 * @metadata : metadata associated with the buffer
2686 * @user : callback cookie returned back to the user
2687 * @frame_idx : frame index for matching frames
2688 * @release_cb : callback function for releasing the data memory
2689 * @release_cookie : cookie for the release callback function
2690 * @release_data :pointer indicating what needs to be released
2691 *
2692 * RETURN : int32_t type of status
2693 * NO_ERROR -- success
2694 * none-zero failure code
2695 *==========================================================================*/
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)2696 int32_t QCameraMuxer::storeJpeg(cam_sync_type_t cam_type,
2697 int32_t msg_type, const camera_memory_t *data, unsigned int index,
2698 camera_frame_metadata_t *metadata, void *user,uint32_t frame_idx,
2699 camera_release_callback release_cb, void *release_cookie,
2700 void *release_data)
2701 {
2702 LOGH("E jpeg received: data %p size %d data ptr %p frameIdx %d",
2703 data, data->size, data->data, frame_idx);
2704
2705 CHECK_MUXER_ERROR();
2706
2707 if (!m_bMpoEnabled) {
2708 if (cam_type == CAM_TYPE_MAIN) {
2709 // send data callback only incase of main camera
2710 // aux image is ignored and released back
2711 mDataCb(msg_type,
2712 data,
2713 index,
2714 metadata,
2715 m_pMpoCallbackCookie);
2716 }
2717 if (release_cb) {
2718 release_cb(release_data, release_cookie, NO_ERROR);
2719 }
2720 LOGH("X");
2721 return NO_ERROR;
2722 }
2723
2724 cam_compose_jpeg_info_t* pJpegFrame =
2725 (cam_compose_jpeg_info_t*)malloc(sizeof(cam_compose_jpeg_info_t));
2726 if (!pJpegFrame) {
2727 LOGE("Allocation failed for MPO nodes");
2728 return NO_MEMORY;
2729 }
2730 memset(pJpegFrame, 0, sizeof(*pJpegFrame));
2731
2732 pJpegFrame->msg_type = msg_type;
2733 pJpegFrame->buffer = const_cast<camera_memory_t*>(data);
2734 pJpegFrame->index = index;
2735 pJpegFrame->metadata = metadata;
2736 pJpegFrame->user = user;
2737 pJpegFrame->valid = true;
2738 pJpegFrame->frame_idx = frame_idx;
2739 pJpegFrame->release_cb = release_cb;
2740 pJpegFrame->release_cookie = release_cookie;
2741 pJpegFrame->release_data = release_data;
2742 if(cam_type == CAM_TYPE_MAIN) {
2743 if (m_MainJpegQ.enqueue((void *)pJpegFrame)) {
2744 LOGD("Main FrameIdx %d", pJpegFrame->frame_idx);
2745 if (m_MainJpegQ.getCurrentSize() > 0) {
2746 LOGD("Trigger Compose");
2747 m_ComposeMpoTh.sendCmd(CAMERA_CMD_TYPE_DO_NEXT_JOB, FALSE, FALSE);
2748 }
2749 } else {
2750 LOGE("Enqueue Failed for Main Jpeg Q");
2751 if ( pJpegFrame->release_cb ) {
2752 // release other buffer also here
2753 pJpegFrame->release_cb(
2754 pJpegFrame->release_data,
2755 pJpegFrame->release_cookie,
2756 NO_ERROR);
2757 }
2758 free(pJpegFrame);
2759 pJpegFrame = NULL;
2760 return NO_MEMORY;
2761 }
2762
2763 } else {
2764 if (m_AuxJpegQ.enqueue((void *)pJpegFrame)) {
2765 LOGD("Aux FrameIdx %d", pJpegFrame->frame_idx);
2766 if (m_AuxJpegQ.getCurrentSize() > 0) {
2767 LOGD("Trigger Compose");
2768 m_ComposeMpoTh.sendCmd(CAMERA_CMD_TYPE_DO_NEXT_JOB, FALSE, FALSE);
2769 }
2770 } else {
2771 LOGE("Enqueue Failed for Aux Jpeg Q");
2772 if ( pJpegFrame->release_cb ) {
2773 // release other buffer also here
2774 pJpegFrame->release_cb(
2775 pJpegFrame->release_data,
2776 pJpegFrame->release_cookie,
2777 NO_ERROR);
2778 }
2779 free(pJpegFrame);
2780 pJpegFrame = NULL;
2781 return NO_MEMORY;
2782 }
2783 }
2784 LOGH("X");
2785
2786 return NO_ERROR;
2787 }
2788
2789
2790 // Muxer Ops
2791 camera_device_ops_t QCameraMuxer::mCameraMuxerOps = {
2792 .set_preview_window = QCameraMuxer::set_preview_window,
2793 .set_callbacks = QCameraMuxer::set_callBacks,
2794 .enable_msg_type = QCameraMuxer::enable_msg_type,
2795 .disable_msg_type = QCameraMuxer::disable_msg_type,
2796 .msg_type_enabled = QCameraMuxer::msg_type_enabled,
2797
2798 .start_preview = QCameraMuxer::start_preview,
2799 .stop_preview = QCameraMuxer::stop_preview,
2800 .preview_enabled = QCameraMuxer::preview_enabled,
2801 .store_meta_data_in_buffers= QCameraMuxer::store_meta_data_in_buffers,
2802
2803 .start_recording = QCameraMuxer::start_recording,
2804 .stop_recording = QCameraMuxer::stop_recording,
2805 .recording_enabled = QCameraMuxer::recording_enabled,
2806 .release_recording_frame = QCameraMuxer::release_recording_frame,
2807
2808 .auto_focus = QCameraMuxer::auto_focus,
2809 .cancel_auto_focus = QCameraMuxer::cancel_auto_focus,
2810
2811 .take_picture = QCameraMuxer::take_picture,
2812 .cancel_picture = QCameraMuxer::cancel_picture,
2813
2814 .set_parameters = QCameraMuxer::set_parameters,
2815 .get_parameters = QCameraMuxer::get_parameters,
2816 .put_parameters = QCameraMuxer::put_parameters,
2817 .send_command = QCameraMuxer::send_command,
2818
2819 .release = QCameraMuxer::release,
2820 .dump = QCameraMuxer::dump,
2821 };
2822
2823
2824 }; // namespace android
2825