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