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