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