1 /* Copyright (c) 2012-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 "QCameraChannel"
31 
32 // System dependencies
33 #include <utils/Errors.h>
34 
35 // Camera dependencies
36 #include "QCamera2HWI.h"
37 
38 extern "C" {
39 #include "mm_camera_dbg.h"
40 }
41 
42 using namespace android;
43 
44 namespace qcamera {
45 
46 /*===========================================================================
47  * FUNCTION   : QCameraChannel
48  *
49  * DESCRIPTION: constrcutor of QCameraChannel
50  *
51  * PARAMETERS :
52  *   @cam_handle : camera handle
53  *   @cam_ops    : ptr to camera ops table
54  *
55  * RETURN     : none
56  *==========================================================================*/
QCameraChannel(uint32_t cam_handle,mm_camera_ops_t * cam_ops)57 QCameraChannel::QCameraChannel(uint32_t cam_handle,
58                                mm_camera_ops_t *cam_ops)
59 {
60     m_camHandle = cam_handle;
61     m_camOps = cam_ops;
62     m_bIsActive = false;
63     m_bAllowDynBufAlloc = false;
64     mDualChannel = is_dual_camera_by_handle(cam_handle);
65     m_handle = 0;
66 }
67 
68 /*===========================================================================
69  * FUNCTION   : QCameraChannel
70  *
71  * DESCRIPTION: default constrcutor of QCameraChannel
72  *
73  * PARAMETERS : none
74  *
75  * RETURN     : none
76  *==========================================================================*/
QCameraChannel()77 QCameraChannel::QCameraChannel()
78 {
79     m_camHandle = 0;
80     m_camOps = NULL;
81     m_bIsActive = false;
82     mDualChannel = 0;
83     m_handle = 0;
84 }
85 
86 /*===========================================================================
87  * FUNCTION   : ~QCameraChannel
88  *
89  * DESCRIPTION: destructor of QCameraChannel
90  *
91  * PARAMETERS : none
92  *
93  * RETURN     : none
94  *==========================================================================*/
~QCameraChannel()95 QCameraChannel::~QCameraChannel()
96 {
97     if (m_bIsActive) {
98         stop();
99     }
100     for (size_t i = 0; i < mStreams.size(); i++) {
101         if (mStreams[i] != NULL) {
102             if (validate_handle(m_handle, mStreams[i]->getChannelHandle())) {
103                 delete mStreams[i];
104             }
105         }
106     }
107     mStreams.clear();
108     m_camOps->delete_channel(m_camHandle, m_handle);
109     m_handle = 0;
110 }
111 
112 /*===========================================================================
113  * FUNCTION   : deleteChannel
114  *
115  * DESCRIPTION: deletes a camera channel
116  *
117  * PARAMETERS : none
118  *
119  * RETURN     : none
120  *==========================================================================*/
deleteChannel()121 void QCameraChannel::deleteChannel()
122 {
123     if (m_bIsActive) {
124         stop();
125     }
126     for (size_t i = 0; i < mStreams.size(); i++) {
127         if ((mStreams[i] != NULL) &&
128                 (validate_handle(m_handle, mStreams[i]->getChannelHandle()))) {
129             mStreams[i]->deleteStream();
130         }
131     }
132     m_camOps->delete_channel(m_camHandle, m_handle);
133 }
134 
135 /*===========================================================================
136  * FUNCTION   : setStreamSyncCB
137  *
138  * DESCRIPTION: reg callback function to stream of stream type
139  *
140  * PARAMETERS :
141  *    @stream_type : Stream type for which callback needs to be registered.
142  *    @stream_cb   : Callback function
143 
144  * RETURN     : int32_t type of status
145  *              NO_ERROR  -- success
146  *              non-zero failure code
147  *==========================================================================*/
setStreamSyncCB(cam_stream_type_t stream_type,stream_cb_routine stream_cb)148 int32_t QCameraChannel::setStreamSyncCB (cam_stream_type_t stream_type,
149         stream_cb_routine stream_cb)
150 {
151     int32_t rc = UNKNOWN_ERROR;
152     for (size_t i = 0; i < mStreams.size(); i++) {
153         if ((mStreams[i] != NULL) && (stream_type == mStreams[i]->getMyType())) {
154             rc = mStreams[i]->setSyncDataCB(stream_cb);
155             break;
156         }
157     }
158     return rc;
159 }
160 
161 /*===========================================================================
162  * FUNCTION   : init
163  *
164  * DESCRIPTION: initialization of channel
165  *
166  * PARAMETERS :
167  *   @attr    : channel bundle attribute setting
168  *   @dataCB  : data notify callback
169  *   @userData: user data ptr
170  *
171  * RETURN     : int32_t type of status
172  *              NO_ERROR  -- success
173  *              none-zero failure code
174  *==========================================================================*/
init(mm_camera_channel_attr_t * attr,mm_camera_buf_notify_t dataCB,void * userData)175 int32_t QCameraChannel::init(mm_camera_channel_attr_t *attr,
176                              mm_camera_buf_notify_t dataCB,
177                              void *userData)
178 {
179     m_handle = m_camOps->add_channel(m_camHandle,
180                                       attr,
181                                       dataCB,
182                                       userData);
183     if (m_handle == 0) {
184         LOGE("Add channel failed");
185         return UNKNOWN_ERROR;
186     }
187 
188     mActiveCameras = MM_CAMERA_TYPE_MAIN;
189     if (isDualChannel()) {
190         mActiveCameras |= MM_CAMERA_TYPE_AUX;
191     }
192     mMasterCamera = MM_CAMERA_TYPE_MAIN;
193     mBundledSnapshot = false;
194     return NO_ERROR;
195 }
196 
197 /*===========================================================================
198  * FUNCTION   : getChHandleForStream
199  *
200  * DESCRIPTION: return actual channel handle based on use case per stream
201  *
202  * PARAMETERS :
203  *   @ch_type  : type of channel
204  *
205  * RETURN     : number of buffers needed
206  * NOTE :  Based on the use cases and auxillary camera type,
207            we can decide channel handle for streams.
208            Incase, we want to avoid any stream for auxillary camera,
209            we can decide here.
210  *==========================================================================*/
getChHandleForStream(cam_stream_type_t stream_type)211 uint32_t QCameraChannel::getChHandleForStream(cam_stream_type_t stream_type)
212 {
213     uint32_t handle = m_handle;
214     if (!mDualChannel) {
215         return m_handle;
216     }
217 
218     /*Based on the use case, decide channel handle for channel*/
219     switch (stream_type) {
220     case CAM_STREAM_TYPE_PREVIEW:
221     case CAM_STREAM_TYPE_SNAPSHOT:
222     case CAM_STREAM_TYPE_VIDEO:
223     case CAM_STREAM_TYPE_METADATA:
224     case CAM_STREAM_TYPE_ANALYSIS:
225     case CAM_STREAM_TYPE_CALLBACK:
226         handle = m_handle;
227         break;
228     case CAM_STREAM_TYPE_POSTVIEW:
229     case CAM_STREAM_TYPE_RAW:
230     case CAM_STREAM_TYPE_OFFLINE_PROC:
231     case CAM_STREAM_TYPE_DEFAULT:
232     case CAM_STREAM_TYPE_MAX:
233     default:
234         handle = get_main_camera_handle(m_handle);
235         break;
236     }
237     return handle;
238 }
239 
240 /*===========================================================================
241  * FUNCTION   : addStream
242  *
243  * DESCRIPTION: add a stream into channel
244  *
245  * PARAMETERS :
246  *   @allocator      : stream related buffer allocator
247  *   @streamInfoBuf  : ptr to buf that contains stream info
248  *   @miscBuf        : ptr to buf that contains misc buffers
249  *   @minStreamBufNum: number of stream buffers needed
250  *   @paddingInfo    : padding information
251  *   @stream_cb      : stream data notify callback
252  *   @userdata       : user data ptr
253  *   @bDynAllocBuf   : flag indicating if allow allocate buffers in 2 steps
254  *   @online_rotation: rotation applied online
255  *   @cam_type       : Camera type in case of dual camera
256  *
257  * RETURN     : int32_t type of status
258  *              NO_ERROR  -- success
259  *              none-zero failure code
260  *==========================================================================*/
addStream(QCameraAllocator & allocator,QCameraHeapMemory * streamInfoBuf,QCameraHeapMemory * miscBuf,cam_padding_info_t * paddingInfo,stream_cb_routine stream_cb,void * userdata,bool bDynAllocBuf,bool bDeffAlloc,cam_rotation_t online_rotation,uint32_t cam_type)261 int32_t QCameraChannel::addStream(QCameraAllocator &allocator,
262         QCameraHeapMemory *streamInfoBuf, QCameraHeapMemory *miscBuf,
263         cam_padding_info_t *paddingInfo, stream_cb_routine stream_cb,
264         void *userdata, bool bDynAllocBuf, bool bDeffAlloc,
265         cam_rotation_t online_rotation,
266         uint32_t cam_type)
267 {
268     int32_t rc = NO_ERROR;
269     uint32_t ch_handle = m_handle;
270 
271     if (mStreams.size() >= MAX_STREAM_NUM_IN_BUNDLE) {
272         LOGE("stream number (%zu) exceeds max limit (%d)",
273                mStreams.size(), MAX_STREAM_NUM_IN_BUNDLE);
274         if (streamInfoBuf != NULL) {
275             streamInfoBuf->deallocate();
276             delete streamInfoBuf;
277             streamInfoBuf = NULL;
278         }
279         return BAD_VALUE;
280     }
281 
282     if (cam_type == MM_CAMERA_TYPE_MAIN) {
283         ch_handle = get_main_camera_handle(m_handle);
284     } else if (cam_type == MM_CAMERA_TYPE_AUX) {
285         ch_handle = get_aux_camera_handle(m_handle);
286     }
287 
288     QCameraStream *pStream = new QCameraStream(allocator,
289             m_camHandle, ch_handle, m_camOps, paddingInfo, bDeffAlloc,
290             online_rotation);
291     if (pStream == NULL) {
292         LOGE("No mem for Stream");
293         if (streamInfoBuf != NULL) {
294             streamInfoBuf->deallocate();
295             delete streamInfoBuf;
296             streamInfoBuf = NULL;
297         }
298         return NO_MEMORY;
299     }
300 
301     rc = pStream->init(streamInfoBuf, miscBuf,
302                        stream_cb, userdata, bDynAllocBuf);
303     if (rc == 0) {
304         Mutex::Autolock lock(mStreamLock);
305         mStreams.add(pStream);
306     } else {
307         delete pStream;
308     }
309     return rc;
310 }
311 
312 /*===========================================================================
313  * FUNCTION   : linkStream
314  *
315  * DESCRIPTION: link a stream into channel
316  *
317  * PARAMETERS :
318  *   @ch      : Channel which the stream belongs to
319  *   @stream  : Stream which needs to be linked
320  *
321  * RETURN     : int32_t type of status
322  *              NO_ERROR  -- success
323  *              none-zero failure code
324  *==========================================================================*/
linkStream(QCameraChannel * ch,QCameraStream * stream)325 int32_t QCameraChannel::linkStream(QCameraChannel *ch, QCameraStream *stream)
326 {
327     int32_t rc = NO_ERROR;
328 
329     if ((0 == m_handle) || (NULL == ch) || (NULL == stream)) {
330         return NO_INIT;
331     }
332 
333     int32_t handle = m_camOps->link_stream(m_camHandle,
334             ch->getMyHandle(),
335             stream->getMyHandle(),
336             m_handle);
337     if (0 == handle) {
338         LOGE("Linking of stream failed");
339         rc = INVALID_OPERATION;
340     } else {
341         Mutex::Autolock lock(mStreamLock);
342         mStreams.add(stream);
343     }
344 
345     return rc;
346 }
347 
348 /*===========================================================================
349  * FUNCTION   : start
350  *
351  * DESCRIPTION: start channel, which will start all streams belong to this channel
352  *
353  * PARAMETERS : None
354  *
355  * RETURN     : int32_t type of status
356  *              NO_ERROR  -- success
357  *              none-zero failure code
358  *==========================================================================*/
start()359 int32_t QCameraChannel::start()
360 {
361     int32_t rc = NO_ERROR;
362 
363     if(m_bIsActive) {
364         LOGW("Attempt to start active channel");
365         return rc;
366     }
367 
368     // there is more than one stream in the channel
369     // we need to notify mctl that all streams in this channel need to be bundled
370     for (size_t i = 0; i < mStreams.size(); i++) {
371         if ((mStreams[i] != NULL) &&
372                 (validate_handle(m_handle, mStreams[i]->getChannelHandle()))) {
373             mStreams[i]->setBundleInfo();
374         }
375     }
376 
377 
378     for (size_t i = 0; i < mStreams.size(); i++) {
379         if ((mStreams[i] != NULL) &&
380                 (validate_handle(m_handle, mStreams[i]->getChannelHandle()))) {
381             mStreams[i]->start();
382         }
383     }
384     rc = m_camOps->start_channel(m_camHandle, m_handle, /*start_sensor_streaming*/true);
385 
386     if (rc != NO_ERROR) {
387         for (size_t i = 0; i < mStreams.size(); i++) {
388             if ((mStreams[i] != NULL) &&
389                 (validate_handle(m_handle, mStreams[i]->getChannelHandle()))) {
390                 mStreams[i]->stop();
391             }
392         }
393     } else {
394         m_bIsActive = true;
395         for (size_t i = 0; i < mStreams.size(); i++) {
396             if (mStreams[i] != NULL) {
397                 mStreams[i]->cond_signal();
398             }
399         }
400     }
401 
402     return rc;
403 }
404 
405 /*===========================================================================
406  * FUNCTION   : stop
407  *
408  * DESCRIPTION: stop a channel, which will stop all streams belong to this channel
409  *
410  * PARAMETERS : none
411  *
412  * RETURN     : int32_t type of status
413  *              NO_ERROR  -- success
414  *              none-zero failure code
415  *==========================================================================*/
stop()416 int32_t QCameraChannel::stop()
417 {
418     int32_t rc = NO_ERROR;
419     size_t i = 0;
420 
421     if (!m_bIsActive) {
422         return NO_INIT;
423     }
424 
425     {
426         Mutex::Autolock lock(mStreamLock);
427         while(i < mStreams.size()) {
428             if (mStreams[i] != NULL) {
429                 if (validate_handle(m_handle, mStreams[i]->getChannelHandle())) {
430                     mStreams[i]->stop();
431                     i++;
432                 } else {
433                     // Remove linked stream from stream list
434                     mStreams.removeAt(i);
435                 }
436             }
437         }
438     }
439 
440     rc = m_camOps->stop_channel(m_camHandle, m_handle, /*stop_immediately*/false);
441 
442     m_bIsActive = false;
443     return rc;
444 }
445 
446 /*===========================================================================
447  * FUNCTION   : bufDone
448  *
449  * DESCRIPTION: return a stream buf back to kernel
450  *
451  * PARAMETERS :
452  *   @recvd_frame  : stream buf frame to be returned
453  *
454  * RETURN     : int32_t type of status
455  *              NO_ERROR  -- success
456  *              none-zero failure code
457  *==========================================================================*/
bufDone(mm_camera_super_buf_t * recvd_frame)458 int32_t QCameraChannel::bufDone(mm_camera_super_buf_t *recvd_frame)
459 {
460     int32_t rc = NO_ERROR;
461     for (uint32_t i = 0; i < recvd_frame->num_bufs; i++) {
462         if (recvd_frame->bufs[i] != NULL) {
463             for (uint32_t j = 0; j < mStreams.size(); j++) {
464                 if (mStreams[j] != NULL &&
465                          (validate_handle(mStreams[j]->getMyHandle(),
466                          recvd_frame->bufs[i]->stream_id))) {
467                     rc = mStreams[j]->bufDone(recvd_frame->bufs[i]->buf_idx);
468                     break; // break loop j
469                 }
470             }
471         }
472     }
473 
474     return rc;
475 }
476 
477 /*===========================================================================
478  * FUNCTION   : bufDone
479  *
480  * DESCRIPTION: return specified buffer from super buffer to kernel
481  *
482  * PARAMETERS :
483  *   @recvd_frame  : stream buf frame to be returned
484  *   @stream_id      : stream ID of the buffer to be released
485  *
486  * RETURN     : int32_t type of status
487  *              NO_ERROR  -- success
488  *              none-zero failure code
489  *==========================================================================*/
bufDone(mm_camera_super_buf_t * recvd_frame,uint32_t stream_id)490 int32_t QCameraChannel::bufDone(mm_camera_super_buf_t *recvd_frame, uint32_t stream_id)
491 {
492     int32_t rc = NO_ERROR;
493     int32_t index;
494     for (int32_t i = 0; i < (int32_t)recvd_frame->num_bufs; i++) {
495         index = -1;
496         if ((recvd_frame->bufs[i] != NULL) &&
497                 (recvd_frame->bufs[i]->stream_id == stream_id)) {
498             for (uint32_t j = 0; j < mStreams.size(); j++) {
499                 if ((mStreams[j] != NULL) &&
500                         (validate_handle(mStreams[j]->getMyHandle(),
501                         recvd_frame->bufs[i]->stream_id))) {
502                     rc = mStreams[j]->bufDone(recvd_frame->bufs[i]->buf_idx);
503                     index = i;
504                     break; // break loop j
505                 }
506             }
507             if ((index >= 0) && (index < (int32_t)recvd_frame->num_bufs)) {
508                 for (int32_t j = index; j < (int32_t)(recvd_frame->num_bufs - 1); j++) {
509                     recvd_frame->bufs[j] = recvd_frame->bufs[j + 1];
510                 }
511                 recvd_frame->num_bufs--;
512                 i--;
513             }
514         }
515     }
516 
517     return rc;
518 }
519 
520 /*===========================================================================
521  * FUNCTION   : processZoomDone
522  *
523  * DESCRIPTION: process zoom done event
524  *
525  * PARAMETERS :
526  *   @previewWindoe : ptr to preview window ops table, needed to set preview
527  *                    crop information
528  *   @crop_info     : crop info as a result of zoom operation
529  *
530  * RETURN     : int32_t type of status
531  *              NO_ERROR  -- success
532  *              none-zero failure code
533  *==========================================================================*/
processZoomDone(preview_stream_ops_t * previewWindow,cam_crop_data_t & crop_info)534 int32_t QCameraChannel::processZoomDone(preview_stream_ops_t *previewWindow,
535                                         cam_crop_data_t &crop_info)
536 {
537     int32_t rc = NO_ERROR;
538     Mutex::Autolock lock(mStreamLock);
539     for (size_t i = 0; i < mStreams.size(); i++) {
540         if ((mStreams[i] != NULL) &&
541                 (validate_handle(m_handle, mStreams[i]->getChannelHandle()))) {
542             rc = mStreams[i]->processZoomDone(previewWindow, crop_info);
543         }
544     }
545     return rc;
546 }
547 
548 /*===========================================================================
549  * FUNCTION   : getStreamByHandle
550  *
551  * DESCRIPTION: return stream object by stream handle
552  *
553  * PARAMETERS :
554  *   @streamHandle : stream handle
555  *
556  * RETURN     : stream object. NULL if not found
557  *==========================================================================*/
getStreamByHandle(uint32_t streamHandle)558 QCameraStream *QCameraChannel::getStreamByHandle(uint32_t streamHandle)
559 {
560     for (size_t i = 0; i < mStreams.size(); i++) {
561         if (mStreams[i] != NULL &&
562                 (validate_handle(mStreams[i]->getMyHandle(), streamHandle))) {
563             return mStreams[i];
564         }
565     }
566     return NULL;
567 }
568 
569 /*===========================================================================
570  * FUNCTION   : getStreamByServerID
571  *
572  * DESCRIPTION: return stream object by stream server ID from daemon
573  *
574  * PARAMETERS :
575  *   @serverID : stream server ID
576  *
577  * RETURN     : stream object. NULL if not found
578  *==========================================================================*/
getStreamByServerID(uint32_t serverID)579 QCameraStream *QCameraChannel::getStreamByServerID(uint32_t serverID)
580 {
581     for (size_t i = 0; i < mStreams.size(); i++) {
582         if (mStreams[i] != NULL && mStreams[i]->getMyServerID() == serverID) {
583             return mStreams[i];
584         }
585     }
586     return NULL;
587 }
588 
589 /*===========================================================================
590  * FUNCTION   : getStreamByIndex
591  *
592  * DESCRIPTION: return stream object by index of streams in the channel
593  *
594  * PARAMETERS :
595  *   @index : index of stream in the channel
596  *
597  * RETURN     : stream object. NULL if not found
598  *==========================================================================*/
getStreamByIndex(uint32_t index)599 QCameraStream *QCameraChannel::getStreamByIndex(uint32_t index)
600 {
601     if (index >= MAX_STREAM_NUM_IN_BUNDLE) {
602         return NULL;
603     }
604 
605     if (index < mStreams.size()) {
606         return mStreams[index];
607     }
608     return NULL;
609 }
610 
611 /*===========================================================================
612  * FUNCTION   : UpdateStreamBasedParameters
613  *
614  * DESCRIPTION: update any stream based settings from parameters
615  *
616  * PARAMETERS :
617  *   @param   : reference to parameters object
618  *
619  * RETURN     : int32_t type of status
620  *              NO_ERROR  -- success
621  *              none-zero failure code
622  *==========================================================================*/
UpdateStreamBasedParameters(QCameraParametersIntf & param)623 int32_t QCameraChannel::UpdateStreamBasedParameters(QCameraParametersIntf &param)
624 {
625     int32_t rc = NO_ERROR;
626     Mutex::Autolock lock(mStreamLock);
627     if (param.isPreviewFlipChanged()) {
628         // try to find preview stream
629         for (size_t i = 0; i < mStreams.size(); i++) {
630             if ((mStreams[i] != NULL) &&
631                     (validate_handle(m_handle, mStreams[i]->getChannelHandle())) &&
632                     (mStreams[i]->isTypeOf(CAM_STREAM_TYPE_PREVIEW) ||
633                     (mStreams[i]->isOrignalTypeOf(CAM_STREAM_TYPE_PREVIEW))) ) {
634                 cam_stream_parm_buffer_t param_buf;
635                 memset(&param_buf, 0, sizeof(cam_stream_parm_buffer_t));
636                 param_buf.type = CAM_STREAM_PARAM_TYPE_SET_FLIP;
637                 param_buf.flipInfo.flip_mask =
638                         (uint32_t)param.getFlipMode(CAM_STREAM_TYPE_PREVIEW);
639                 rc = mStreams[i]->setParameter(param_buf);
640                 if (rc != NO_ERROR) {
641                     LOGW("set preview stream flip failed");
642                 }
643             }
644         }
645     }
646     if (param.isVideoFlipChanged()) {
647         // try to find video stream
648         for (size_t i = 0; i < mStreams.size(); i++) {
649             if ((mStreams[i] != NULL) &&
650                     (validate_handle(m_handle, mStreams[i]->getChannelHandle())) &&
651                     (mStreams[i]->isTypeOf(CAM_STREAM_TYPE_VIDEO) ||
652                     (mStreams[i]->isOrignalTypeOf(CAM_STREAM_TYPE_VIDEO))) ) {
653                 cam_stream_parm_buffer_t param_buf;
654                 memset(&param_buf, 0, sizeof(cam_stream_parm_buffer_t));
655                 param_buf.type = CAM_STREAM_PARAM_TYPE_SET_FLIP;
656                 param_buf.flipInfo.flip_mask =
657                         (uint32_t)param.getFlipMode(CAM_STREAM_TYPE_VIDEO);
658                 rc = mStreams[i]->setParameter(param_buf);
659                 if (rc != NO_ERROR) {
660                     LOGW("set video stream flip failed");
661                 }
662             }
663         }
664     }
665     if (param.isSnapshotFlipChanged()) {
666         // try to find snapshot/postview stream
667         for (size_t i = 0; i < mStreams.size(); i++) {
668             if (mStreams[i] != NULL &&
669                     (validate_handle(m_handle, mStreams[i]->getChannelHandle())) &&
670                     (mStreams[i]->isTypeOf(CAM_STREAM_TYPE_SNAPSHOT) ||
671                      mStreams[i]->isOrignalTypeOf(CAM_STREAM_TYPE_SNAPSHOT) ||
672                      mStreams[i]->isTypeOf(CAM_STREAM_TYPE_POSTVIEW) ||
673                  mStreams[i]->isOrignalTypeOf(CAM_STREAM_TYPE_POSTVIEW) ) ) {
674                 cam_stream_parm_buffer_t param_buf;
675                 memset(&param_buf, 0, sizeof(cam_stream_parm_buffer_t));
676                 param_buf.type = CAM_STREAM_PARAM_TYPE_SET_FLIP;
677                 param_buf.flipInfo.flip_mask =
678                         (uint32_t)param.getFlipMode(CAM_STREAM_TYPE_SNAPSHOT);
679                 rc = mStreams[i]->setParameter(param_buf);
680                 if (rc != NO_ERROR) {
681                     LOGW("set snapshot stream flip failed");
682                 }
683             }
684         }
685     }
686     return rc;
687 }
688 
689 /*===========================================================================
690  * FUNCTION   : processCameraControl
691  *
692  * DESCRIPTION:  Suspend and resume camera
693  *
694  * PARAMETERS :
695  *   @camState   : Camera start. MAIN/AUX/MAIN&AUX
696  *
697  * RETURN     : int32_t type of status
698  *              NO_ERROR  -- success
699  *              none-zero failure code
700  *==========================================================================*/
processCameraControl(uint32_t camState,bool bundledSnapshot)701 int32_t QCameraChannel::processCameraControl(
702         uint32_t camState,
703         bool     bundledSnapshot)
704 {
705     int32_t ret = NO_ERROR;
706 
707     for (size_t i = 0; i < mStreams.size(); i++) {
708         if (mStreams[i] != NULL && mStreams[i]->isDualStream()) {
709             ret = mStreams[i]->processCameraControl(camState);
710             if (ret != NO_ERROR) {
711                 LOGE("Stream handle failed");
712                 break;
713             }
714         }
715     }
716 
717     mActiveCameras   = camState;
718     mBundledSnapshot = bundledSnapshot;
719     return ret;
720 }
721 
722 /*===========================================================================
723  * FUNCTION   : switchChannelCb
724  *
725  * DESCRIPTION: switch channel's in case of dual camera
726  *
727  * PARAMETERS :
728  * @camMaster : Master camera
729  *
730  * RETURN     : int32_t type of status
731  *              NO_ERROR  -- success
732  *              none-zero failure code
733  *==========================================================================*/
switchChannelCb(uint32_t camMaster)734 int32_t QCameraChannel::switchChannelCb(uint32_t camMaster)
735 {
736     int32_t ret = NO_ERROR;
737 
738     for (size_t i = 0; i < mStreams.size(); i++) {
739         if (mStreams[i] != NULL && mStreams[i]->isDualStream()) {
740             ret = mStreams[i]->switchStreamCb(camMaster);
741             if (ret != NO_ERROR) {
742                 LOGE("Stream Switch Failed");
743                 break;
744             }
745         }
746     }
747 
748     // Update master camera
749     mMasterCamera = camMaster;
750     return ret;
751 }
752 
753 /*===========================================================================
754  * FUNCTION   : getSnapshotHandle
755  *
756  * DESCRIPTION: Get the camera handle for snapshot based on the bundlesnapshot
757  *              flag and active camera state
758  *
759  * PARAMETERS : None
760  *
761  * RETURN     : camera handle for snapshot
762  *
763  *==========================================================================*/
getSnapshotHandle()764 uint32_t QCameraChannel::getSnapshotHandle()
765 {
766     uint32_t snapshotHandle = 0;
767 
768     if ((mActiveCameras == MM_CAMERA_DUAL_CAM) && mBundledSnapshot) {
769         snapshotHandle = m_handle;
770     } else {
771         snapshotHandle = (mMasterCamera == MM_CAMERA_TYPE_MAIN) ?
772                 get_main_camera_handle(m_handle) : get_aux_camera_handle(m_handle);
773     }
774 
775     return snapshotHandle;
776 }
777 
778 /*===========================================================================
779  * FUNCTION   : QCameraPicChannel
780  *
781  * DESCRIPTION: constructor of QCameraPicChannel
782  *
783  * PARAMETERS :
784  *   @cam_handle : camera handle
785  *   @cam_ops    : ptr to camera ops table
786  *
787  * RETURN     : none
788  *==========================================================================*/
QCameraPicChannel(uint32_t cam_handle,mm_camera_ops_t * cam_ops)789 QCameraPicChannel::QCameraPicChannel(uint32_t cam_handle,
790                                      mm_camera_ops_t *cam_ops) :
791     QCameraChannel(cam_handle, cam_ops)
792 {
793     m_bAllowDynBufAlloc = true;
794 }
795 
796 /*===========================================================================
797  * FUNCTION   : QCameraPicChannel
798  *
799  * DESCRIPTION: default constructor of QCameraPicChannel
800  *
801  * PARAMETERS : none
802  *
803  * RETURN     : none
804  *==========================================================================*/
QCameraPicChannel()805 QCameraPicChannel::QCameraPicChannel()
806 {
807     m_bAllowDynBufAlloc = true;
808 }
809 
810 /*===========================================================================
811  * FUNCTION   : ~QCameraPicChannel
812  *
813  * DESCRIPTION: destructor of QCameraPicChannel
814  *
815  * PARAMETERS : none
816  *
817  * RETURN     : none
818  *==========================================================================*/
~QCameraPicChannel()819 QCameraPicChannel::~QCameraPicChannel()
820 {
821 }
822 
823 /*===========================================================================
824  * FUNCTION   : takePicture
825  *
826  * DESCRIPTION: send request for queued snapshot frames
827  *
828  * PARAMETERS :
829  *   @buf : request buf info
830  *
831  * RETURN     : int32_t type of status
832  *              NO_ERROR  -- success
833  *              none-zero failure code
834  *==========================================================================*/
takePicture(mm_camera_req_buf_t * buf)835 int32_t QCameraPicChannel::takePicture (mm_camera_req_buf_t *buf)
836 {
837     uint32_t snapshotHandle = getSnapshotHandle();
838     LOGD("mSnapshotHandle = 0x%x", snapshotHandle);
839     int32_t rc = m_camOps->request_super_buf(m_camHandle, snapshotHandle, buf);
840     return rc;
841 }
842 
843 /*===========================================================================
844  * FUNCTION   : cancelPicture
845  *
846  * DESCRIPTION: cancel request for queued snapshot frames
847  *
848  * PARAMETERS : none
849  *
850  * RETURN     : int32_t type of status
851  *              NO_ERROR  -- success
852  *              none-zero failure code
853  *==========================================================================*/
cancelPicture()854 int32_t QCameraPicChannel::cancelPicture()
855 {
856     int32_t rc = m_camOps->cancel_super_buf_request(m_camHandle, m_handle);
857     return rc;
858 }
859 
860 /*===========================================================================
861  * FUNCTION   : stopAdvancedCapture
862  *
863  * DESCRIPTION: stop advanced capture based on advanced capture type.
864  *
865  * PARAMETERS :
866  *   @type : advanced capture type.
867  *
868  * RETURN     : int32_t type of status
869  *              NO_ERROR  -- success
870  *              none-zero failure code
871  *==========================================================================*/
stopAdvancedCapture(mm_camera_advanced_capture_t type)872 int32_t QCameraPicChannel::stopAdvancedCapture(mm_camera_advanced_capture_t type)
873 {
874     int32_t rc = m_camOps->process_advanced_capture(m_camHandle,
875             m_handle, type, 0, NULL);
876     return rc;
877 }
878 
879 /*===========================================================================
880  * FUNCTION   : startAdvancedCapture
881  *
882  * DESCRIPTION: start advanced capture based on advanced capture type.
883  *
884  * PARAMETERS :
885  *   @type : advanced capture type.
886  *   @config: advance capture config
887  *
888  * RETURN     : int32_t type of status
889  *              NO_ERROR  -- success
890  *              none-zero failure code
891  *==========================================================================*/
startAdvancedCapture(mm_camera_advanced_capture_t type,cam_capture_frame_config_t * config)892 int32_t QCameraPicChannel::startAdvancedCapture(mm_camera_advanced_capture_t type,
893         cam_capture_frame_config_t *config)
894 {
895     int32_t rc = NO_ERROR;
896 
897     rc = m_camOps->process_advanced_capture(m_camHandle, getSnapshotHandle(), type,
898             1, config);
899     return rc;
900 }
901 
902 /*===========================================================================
903 * FUNCTION   : flushSuperbuffer
904  *
905  * DESCRIPTION: flush the all superbuffer frames.
906  *
907  * PARAMETERS :
908  *   @frame_idx : frame index of focused frame
909  *
910  * RETURN     : int32_t type of status
911  *              NO_ERROR  -- success
912  *              none-zero failure code
913  *==========================================================================*/
flushSuperbuffer(uint32_t frame_idx)914 int32_t QCameraPicChannel::flushSuperbuffer(uint32_t frame_idx)
915 {
916     int32_t rc = m_camOps->flush_super_buf_queue(m_camHandle, m_handle, frame_idx);
917     return rc;
918 }
919 
920 /*===========================================================================
921  * FUNCTION   : QCameraVideoChannel
922  *
923  * DESCRIPTION: constructor of QCameraVideoChannel
924  *
925  * PARAMETERS :
926  *   @cam_handle : camera handle
927  *   @cam_ops    : ptr to camera ops table
928  *
929  * RETURN     : none
930  *==========================================================================*/
QCameraVideoChannel(uint32_t cam_handle,mm_camera_ops_t * cam_ops)931 QCameraVideoChannel::QCameraVideoChannel(uint32_t cam_handle,
932                                          mm_camera_ops_t *cam_ops) :
933     QCameraChannel(cam_handle, cam_ops)
934 {
935 }
936 
937 /*===========================================================================
938  * FUNCTION   : QCameraVideoChannel
939  *
940  * DESCRIPTION: default constructor of QCameraVideoChannel
941  *
942  * PARAMETERS : none
943  *
944  * RETURN     : none
945  *==========================================================================*/
QCameraVideoChannel()946 QCameraVideoChannel::QCameraVideoChannel()
947 {
948 }
949 
950 /*===========================================================================
951  * FUNCTION   : ~QCameraVideoChannel
952  *
953  * DESCRIPTION: destructor of QCameraVideoChannel
954  *
955  * PARAMETERS : none
956  *
957  * RETURN     : none
958  *==========================================================================*/
~QCameraVideoChannel()959 QCameraVideoChannel::~QCameraVideoChannel()
960 {
961 }
962 
963 /*===========================================================================
964  * FUNCTION   : takePicture
965  *
966  * DESCRIPTION: send request for queued snapshot frames
967  *
968  * PARAMETERS :
969  *   @mm_camera_req_buf_t : request buf info
970  *
971  * RETURN     : int32_t type of status
972  *              NO_ERROR  -- success
973  *              none-zero failure code
974  *==========================================================================*/
takePicture(mm_camera_req_buf_t * buf)975 int32_t QCameraVideoChannel::takePicture(mm_camera_req_buf_t *buf)
976 {
977     uint32_t snapshotHandle = getSnapshotHandle();
978     LOGD("mSnapshotHandle = 0x%x", snapshotHandle);
979     int32_t rc = m_camOps->request_super_buf(m_camHandle, snapshotHandle, buf);
980     return rc;
981 }
982 
983 /*===========================================================================
984  * FUNCTION   : cancelPicture
985  *
986  * DESCRIPTION: cancel request for queued snapshot frames
987  *
988  * PARAMETERS : none
989  *
990  * RETURN     : int32_t type of status
991  *              NO_ERROR  -- success
992  *              none-zero failure code
993  *==========================================================================*/
cancelPicture()994 int32_t QCameraVideoChannel::cancelPicture()
995 {
996     int32_t rc = m_camOps->cancel_super_buf_request(m_camHandle, m_handle);
997     return rc;
998 }
999 
1000 /*===========================================================================
1001  * FUNCTION   : releaseFrame
1002  *
1003  * DESCRIPTION: return video frame from app
1004  *
1005  * PARAMETERS :
1006  *   @opaque     : ptr to video frame to be returned
1007  *   @isMetaData : if frame is a metadata or real frame
1008  *
1009  * RETURN     : int32_t type of status
1010  *              NO_ERROR  -- success
1011  *              none-zero failure code
1012  *==========================================================================*/
releaseFrame(const void * opaque,bool isMetaData)1013 int32_t QCameraVideoChannel::releaseFrame(const void * opaque, bool isMetaData)
1014 {
1015     QCameraStream *pVideoStream = NULL;
1016     for (size_t i = 0; i < mStreams.size(); i++) {
1017         if (mStreams[i] != NULL && mStreams[i]->isTypeOf(CAM_STREAM_TYPE_VIDEO)) {
1018             pVideoStream = mStreams[i];
1019             break;
1020         }
1021     }
1022 
1023     if (NULL == pVideoStream) {
1024         LOGE("No video stream in the channel");
1025         return BAD_VALUE;
1026     }
1027 
1028     int32_t rc = pVideoStream->bufDone(opaque, isMetaData);
1029     return rc;
1030 }
1031 
1032 /*===========================================================================
1033  * FUNCTION   : QCameraReprocessChannel
1034  *
1035  * DESCRIPTION: constructor of QCameraReprocessChannel
1036  *
1037  * PARAMETERS :
1038  *   @cam_handle : camera handle
1039  *   @cam_ops    : ptr to camera ops table
1040  *
1041  * RETURN     : none
1042  *==========================================================================*/
QCameraReprocessChannel(uint32_t cam_handle,mm_camera_ops_t * cam_ops)1043 QCameraReprocessChannel::QCameraReprocessChannel(uint32_t cam_handle,
1044                                                  mm_camera_ops_t *cam_ops) :
1045     QCameraChannel(cam_handle, cam_ops),
1046     m_pSrcChannel(NULL),
1047     mPassCount(0)
1048 {
1049     memset(mSrcStreamHandles, 0, sizeof(mSrcStreamHandles));
1050 }
1051 
1052 /*===========================================================================
1053  * FUNCTION   : QCameraReprocessChannel
1054  *
1055  * DESCRIPTION: default constructor of QCameraReprocessChannel
1056  *
1057  * PARAMETERS : none
1058  *
1059  * RETURN     : none
1060  *==========================================================================*/
QCameraReprocessChannel()1061 QCameraReprocessChannel::QCameraReprocessChannel() :
1062     m_pSrcChannel(NULL),
1063     mPassCount(0)
1064 {
1065 }
1066 
1067 /*===========================================================================
1068  * FUNCTION   : ~QCameraReprocessChannel
1069  *
1070  * DESCRIPTION: destructor of QCameraReprocessChannel
1071  *
1072  * PARAMETERS : none
1073  *
1074  * RETURN     : none
1075  *==========================================================================*/
~QCameraReprocessChannel()1076 QCameraReprocessChannel::~QCameraReprocessChannel()
1077 {
1078 }
1079 
1080 /*===========================================================================
1081  * FUNCTION   : addReprocStreamsFromSource
1082  *
1083  * DESCRIPTION: add reprocess streams from input source channel
1084  *
1085  * PARAMETERS :
1086  *   @allocator      : stream related buffer allocator
1087  *   @featureConfig  : pp feature configuration
1088  *   @pSrcChannel    : ptr to input source channel that needs reprocess
1089  *   @minStreamBufNum: number of stream buffers needed
1090  *   @burstNum       : number of burst captures needed
1091  *   @paddingInfo    : padding information
1092  *   @param          : reference to parameters
1093  *   @contStream     : continous streaming mode or burst
1094  *   @offline        : configure for offline reprocessing
1095  *
1096  * RETURN     : int32_t type of status
1097  *              NO_ERROR  -- success
1098  *              none-zero failure code
1099  *==========================================================================*/
addReprocStreamsFromSource(QCameraAllocator & allocator,cam_pp_feature_config_t & featureConfig,QCameraChannel * pSrcChannel,uint8_t minStreamBufNum,uint8_t burstNum,cam_padding_info_t * paddingInfo,QCameraParametersIntf & param,bool contStream,bool offline)1100 int32_t QCameraReprocessChannel::addReprocStreamsFromSource(
1101         QCameraAllocator& allocator, cam_pp_feature_config_t &featureConfig,
1102         QCameraChannel *pSrcChannel, uint8_t minStreamBufNum, uint8_t burstNum,
1103         cam_padding_info_t *paddingInfo, QCameraParametersIntf &param, bool contStream,
1104         bool offline)
1105 {
1106     int32_t rc = 0;
1107     QCameraStream *pStream = NULL;
1108     QCameraHeapMemory *pStreamInfoBuf = NULL;
1109     QCameraHeapMemory *pMiscBuf = NULL;
1110     cam_stream_info_t *streamInfo = NULL;
1111     cam_padding_info_t padding;
1112 
1113     memset(mSrcStreamHandles, 0, sizeof(mSrcStreamHandles));
1114     if (NULL == paddingInfo) {
1115         return BAD_VALUE;
1116     }
1117     padding = *paddingInfo;
1118     //Use maximum padding so that the buffer
1119     //can be rotated
1120     padding.width_padding = MAX(padding.width_padding, padding.height_padding);
1121     padding.height_padding = padding.width_padding;
1122     padding.offset_info.offset_x = 0;
1123     padding.offset_info.offset_y = 0;
1124 
1125     LOGD("num of src stream = %d", pSrcChannel->getNumOfStreams());
1126     for (uint32_t i = 0; i < pSrcChannel->getNumOfStreams(); i++) {
1127         cam_pp_feature_config_t pp_featuremask = featureConfig;
1128         pStream = pSrcChannel->getStreamByIndex(i);
1129         if (pStream != NULL) {
1130             if (param.getofflineRAW() && !((pStream->isTypeOf(CAM_STREAM_TYPE_RAW))
1131                     || (pStream->isTypeOf(CAM_STREAM_TYPE_POSTVIEW))
1132                     || (pStream->isTypeOf(CAM_STREAM_TYPE_METADATA))
1133                     || (pStream->isOrignalTypeOf(CAM_STREAM_TYPE_RAW))
1134                     || (pStream->isOrignalTypeOf(CAM_STREAM_TYPE_METADATA)))) {
1135                 //Skip all the stream other than RAW and POSTVIEW incase of offline of RAW
1136                 continue;
1137             }
1138 
1139             if (pStream->isTypeOf(CAM_STREAM_TYPE_RAW)
1140                     && (!param.getofflineRAW())) {
1141                 // Skip raw for reprocess now because PP module cannot handle
1142                 // meta data&raw. May need furthur discussion if Imaginglib need meta data
1143                 continue;
1144             }
1145 
1146             if (((pStream->isTypeOf(CAM_STREAM_TYPE_METADATA))
1147                     && !((param.getManualCaptureMode() >=
1148                     CAM_MANUAL_CAPTURE_TYPE_3) || (param.getQuadraCfa())))
1149                     || (pStream->isTypeOf(CAM_STREAM_TYPE_ANALYSIS))) {
1150                 // Skip metadata, if not manual capture or quadra cfa
1151                 continue;
1152             }
1153 
1154             if (pStream->isTypeOf(CAM_STREAM_TYPE_PREVIEW) ||
1155                     pStream->isTypeOf(CAM_STREAM_TYPE_POSTVIEW) ||
1156                     pStream->isOrignalTypeOf(CAM_STREAM_TYPE_PREVIEW) ||
1157                     pStream->isOrignalTypeOf(CAM_STREAM_TYPE_POSTVIEW)) {
1158                 cam_feature_mask_t feature_mask = featureConfig.feature_mask;
1159 
1160                 // skip thumbnail reprocessing if not needed
1161                 if (!param.needThumbnailReprocess(&feature_mask)) {
1162                     continue;
1163                 }
1164                 // CAC, SHARPNESS, FLIP and WNR would have been already applied -
1165                 // on preview/postview stream in realtime.
1166                 // So, need not apply again.
1167                 feature_mask &= ~(CAM_QCOM_FEATURE_DENOISE2D |
1168                         CAM_QCOM_FEATURE_CAC |
1169                         CAM_QCOM_FEATURE_SHARPNESS |
1170                         CAM_QCOM_FEATURE_FLIP |
1171                         CAM_QCOM_FEATURE_RAW_PROCESSING);
1172                 if (!feature_mask) {
1173                     // Skip thumbnail stream reprocessing since no other
1174                     //reprocessing is enabled.
1175                     continue;
1176                 }
1177             }
1178 
1179             // For quadra CFA, assign metada_bypass for first pass feature mask.
1180             // For second pass in quadra CFA mode, assign metadata_processing.
1181             // For normal reprocess(no quadra CFA), assign metadata_processing.
1182             if (!param.getQuadraCfa()) {
1183                 if (pStream->isTypeOf(CAM_STREAM_TYPE_METADATA)) {
1184                     pp_featuremask.feature_mask = 0;
1185                     pp_featuremask.feature_mask |= CAM_QCOM_FEATURE_METADATA_PROCESSING;
1186                 }
1187             } else {
1188                 if (pStream->isTypeOf(CAM_STREAM_TYPE_METADATA)) {
1189                     // First reprocess pass in quadra CFA mode
1190                     // Skip processing of the offline metadata for first pass,
1191                     pp_featuremask.feature_mask = 0;
1192                     pp_featuremask.feature_mask |= CAM_QCOM_FEATURE_METADATA_BYPASS;
1193                 } else if (pStream->isOrignalTypeOf(CAM_STREAM_TYPE_METADATA)) {
1194                     // Second reprocess pass in quadra CFA mode
1195                     // offline Metadata processing needed for second pass.
1196                     // offline meta data will be copied from backend.
1197                     pp_featuremask.feature_mask = 0;
1198                     pp_featuremask.feature_mask |= CAM_QCOM_FEATURE_METADATA_PROCESSING;
1199                 }
1200             }
1201 
1202             pStreamInfoBuf = allocator.allocateStreamInfoBuf(CAM_STREAM_TYPE_OFFLINE_PROC);
1203             if (pStreamInfoBuf == NULL) {
1204                 LOGE("no mem for stream info buf");
1205                 rc = NO_MEMORY;
1206                 break;
1207             }
1208 
1209             streamInfo = (cam_stream_info_t *)pStreamInfoBuf->getPtr(0);
1210             memset(streamInfo, 0, sizeof(cam_stream_info_t));
1211             streamInfo->stream_type = CAM_STREAM_TYPE_OFFLINE_PROC;
1212             // Enable CPP high performance mode to put it in turbo frequency mode for
1213             // burst/longshot/HDR snapshot cases
1214             streamInfo->perf_mode = CAM_PERF_HIGH_PERFORMANCE;
1215             if (param.getofflineRAW() && (pStream->isTypeOf(CAM_STREAM_TYPE_RAW)
1216                     || pStream->isOrignalTypeOf(CAM_STREAM_TYPE_RAW))) {
1217                 if (pp_featuremask.feature_mask & CAM_QCOM_FEATURE_QUADRA_CFA) {
1218                     param.getStreamFormat(CAM_STREAM_TYPE_OFFLINE_PROC, streamInfo->fmt);
1219                 } else {
1220                     streamInfo->fmt = CAM_FORMAT_YUV_420_NV21;
1221                 }
1222             } else {
1223                 rc = pStream->getFormat(streamInfo->fmt);
1224             }
1225 
1226             if (pStream->isTypeOf(CAM_STREAM_TYPE_PREVIEW) ||
1227                     pStream->isTypeOf(CAM_STREAM_TYPE_POSTVIEW) ||
1228                     pStream->isOrignalTypeOf(CAM_STREAM_TYPE_PREVIEW) ||
1229                     pStream->isOrignalTypeOf(CAM_STREAM_TYPE_POSTVIEW)) {
1230                 if (pp_featuremask.feature_mask & CAM_QCOM_FEATURE_SCALE) {
1231                     param.getThumbnailSize(&(streamInfo->dim.width),
1232                             &(streamInfo->dim.height));
1233                 } else {
1234                     pStream->getFrameDimension(streamInfo->dim);
1235                 }
1236             } else {
1237                 if ((param.isPostProcScaling() || param.isDCmAsymmetricSnapMode()) &&
1238                         (pp_featuremask.feature_mask & CAM_QCOM_FEATURE_SCALE)) {
1239                     rc = param.getStreamDimension(CAM_STREAM_TYPE_OFFLINE_PROC,
1240                             streamInfo->dim);
1241                 } else if ((param.getofflineRAW()) &&
1242                         ((pStream->isTypeOf(CAM_STREAM_TYPE_RAW)) ||
1243                         (pStream->isOrignalTypeOf(CAM_STREAM_TYPE_RAW)))) {
1244                          if ((param.getQuadraCfa()) &&
1245                              (pp_featuremask.feature_mask & CAM_QCOM_FEATURE_QUADRA_CFA)) {
1246                              rc = pStream->getFrameDimension(streamInfo->dim);
1247                          } else {
1248                              param.getStreamDimension(CAM_STREAM_TYPE_SNAPSHOT,streamInfo->dim);
1249                          }
1250                 } else {
1251                     rc = pStream->getFrameDimension(streamInfo->dim);
1252                 }
1253             }
1254 
1255             if ( contStream ) {
1256                 streamInfo->streaming_mode = CAM_STREAMING_MODE_CONTINUOUS;
1257                 streamInfo->num_of_burst = 0;
1258             } else {
1259                 streamInfo->streaming_mode = CAM_STREAMING_MODE_BURST;
1260                 streamInfo->num_of_burst = burstNum;
1261             }
1262             streamInfo->num_bufs = minStreamBufNum;
1263             streamInfo->buf_cnt = streamInfo->num_bufs;
1264 
1265             cam_stream_reproc_config_t rp_cfg;
1266             memset(&rp_cfg, 0, sizeof(cam_stream_reproc_config_t));
1267             if (offline) {
1268                 cam_frame_len_offset_t offset;
1269                 memset(&offset, 0, sizeof(cam_frame_len_offset_t));
1270 
1271                 rp_cfg.pp_type = CAM_OFFLINE_REPROCESS_TYPE;
1272                 pStream->getFormat(rp_cfg.offline.input_fmt);
1273                 pStream->getFrameDimension(rp_cfg.offline.input_dim);
1274                 pStream->getFrameOffset(offset);
1275                 rp_cfg.offline.input_buf_planes.plane_info = offset;
1276                 rp_cfg.offline.input_type = pStream->getMyOriginalType();
1277                 //For input metadata + input buffer
1278                 rp_cfg.offline.num_of_bufs = 2;
1279             } else {
1280                 rp_cfg.pp_type = CAM_ONLINE_REPROCESS_TYPE;
1281                 rp_cfg.online.input_stream_id = pStream->getMyServerID();
1282                 rp_cfg.online.input_stream_type = pStream->getMyOriginalType();
1283             }
1284             param.getStreamRotation(streamInfo->stream_type,
1285                     streamInfo->pp_config, streamInfo->dim);
1286             streamInfo->reprocess_config = rp_cfg;
1287             streamInfo->reprocess_config.pp_feature_config = pp_featuremask;
1288 
1289             if (!(pStream->isTypeOf(CAM_STREAM_TYPE_SNAPSHOT)
1290                 || pStream->isOrignalTypeOf(CAM_STREAM_TYPE_SNAPSHOT)
1291                 || pStream->isTypeOf(CAM_STREAM_TYPE_RAW)
1292                 || pStream->isOrignalTypeOf(CAM_STREAM_TYPE_RAW))) {
1293                 // CAC, SHARPNESS, FLIP and WNR would have been already applied -
1294                 // on preview/postview stream in realtime. Need not apply again.
1295                 streamInfo->reprocess_config.pp_feature_config.feature_mask &=
1296                         ~CAM_QCOM_FEATURE_CAC;
1297                 streamInfo->reprocess_config.pp_feature_config.feature_mask &=
1298                         ~CAM_QCOM_FEATURE_SHARPNESS;
1299                 streamInfo->reprocess_config.pp_feature_config.feature_mask &=
1300                         ~CAM_QCOM_FEATURE_FLIP;
1301                 //Don't do WNR for thumbnail
1302                 streamInfo->reprocess_config.pp_feature_config.feature_mask &=
1303                         ~CAM_QCOM_FEATURE_DENOISE2D;
1304                 streamInfo->reprocess_config.pp_feature_config.feature_mask &=
1305                         ~CAM_QCOM_FEATURE_CDS;
1306                 streamInfo->reprocess_config.pp_feature_config.feature_mask &=
1307                         ~CAM_QCOM_FEATURE_DSDN;
1308                 //No need of RAW processing for other than RAW streams
1309                 streamInfo->reprocess_config.pp_feature_config.feature_mask &=
1310                         ~CAM_QCOM_FEATURE_RAW_PROCESSING;
1311 
1312                 if (param.isHDREnabled()
1313                   && !param.isHDRThumbnailProcessNeeded()){
1314                     streamInfo->reprocess_config.pp_feature_config.feature_mask
1315                       &= ~CAM_QCOM_FEATURE_HDR;
1316                 }
1317             }
1318 
1319             cam_stream_type_t type = CAM_STREAM_TYPE_DEFAULT;
1320             if (offline) {
1321                 type = streamInfo->reprocess_config.offline.input_type;
1322             } else {
1323                 type = streamInfo->reprocess_config.online.input_stream_type;
1324             }
1325             if (type == CAM_STREAM_TYPE_SNAPSHOT) {
1326                 int flipMode = param.getFlipMode(type);
1327                 if (flipMode > 0) {
1328                     streamInfo->reprocess_config.pp_feature_config.feature_mask |=
1329                             CAM_QCOM_FEATURE_FLIP;
1330                     streamInfo->reprocess_config.pp_feature_config.flip = (uint32_t)flipMode;
1331                 }
1332             }
1333 
1334             if ((streamInfo->reprocess_config.pp_feature_config.feature_mask
1335                     & CAM_QCOM_FEATURE_SCALE)
1336                     && param.isReprocScaleEnabled()
1337                     && param.isUnderReprocScaling()) {
1338                 //we only Scale Snapshot frame
1339                 if (pStream->isTypeOf(CAM_STREAM_TYPE_SNAPSHOT)) {
1340                     streamInfo->dim.width =
1341                             streamInfo->reprocess_config.pp_feature_config.scale_param.output_width;
1342                     streamInfo->dim.height =
1343                             streamInfo->reprocess_config.pp_feature_config.scale_param.output_height;
1344                 }
1345                 LOGH("stream width=%d, height=%d.",
1346                          streamInfo->dim.width, streamInfo->dim.height);
1347             }
1348 
1349             // save source stream handler
1350             if (mDualChannel) {
1351                 mSrcStreamHandles[mStreams.size()] = pStream->getMyHandle();
1352             } else if (get_main_camera_handle(pStream->getMyHandle())) {
1353                 mSrcStreamHandles[mStreams.size()] =
1354                         get_main_camera_handle(pStream->getMyHandle());
1355             } else if (get_aux_camera_handle(pStream->getMyHandle())) {
1356                 mSrcStreamHandles[mStreams.size()] =
1357                         get_aux_camera_handle(pStream->getMyHandle());
1358             } else {
1359                 LOGE("Invalid Handle. ");
1360                 rc = BAD_VALUE;
1361                 break;
1362             }
1363 
1364             mSrcStreamHandles[mStreams.size()] = pStream->getMyHandle();
1365             pMiscBuf = allocator.allocateMiscBuf(streamInfo);
1366 
1367             if (offline) {
1368                 LOGH("Configure Reprocessing Input stream = %d Input: res = %dX%d,"
1369                         "fmt = %d, buf_cnt = %d",
1370                         streamInfo->reprocess_config.offline.input_type,
1371                         rp_cfg.offline.input_dim.width,
1372                         rp_cfg.offline.input_dim.height,
1373                         rp_cfg.offline.input_fmt, rp_cfg.offline.num_of_bufs);
1374             }
1375 
1376             LOGH("Configure Reprocessing Output: stream = %d, res = %dX%d, fmt = %d,"
1377                     "type = %d buf_cnt = %d",
1378                     pStream->getMyOriginalType(), streamInfo->dim.width,
1379                     streamInfo->dim.height, streamInfo->fmt, type, minStreamBufNum);
1380 
1381             // add reprocess stream
1382             if (streamInfo->reprocess_config.pp_feature_config.feature_mask
1383                     & CAM_QCOM_FEATURE_ROTATION) {
1384                 rc = addStream(allocator, pStreamInfoBuf, pMiscBuf,
1385                         &padding, NULL, NULL, false, false,
1386                         streamInfo->reprocess_config.pp_feature_config.rotation,
1387                         pStream->getMyCamType());
1388             } else {
1389                 rc = addStream(allocator, pStreamInfoBuf, pMiscBuf,
1390                         &padding, NULL, NULL, false, false, ROTATE_0,
1391                         pStream->getMyCamType());
1392             }
1393             if (rc != NO_ERROR) {
1394                 LOGE("add reprocess stream failed, ret = %d", rc);
1395                 break;
1396             }
1397         }
1398     }
1399 
1400     if (rc == NO_ERROR) {
1401         m_pSrcChannel = pSrcChannel;
1402     }
1403     return rc;
1404 }
1405 
1406 /*===========================================================================
1407  * FUNCTION   : getStreamBySrouceHandle
1408  *
1409  * DESCRIPTION: find reprocess stream by its source stream handle
1410  *
1411  * PARAMETERS :
1412  *   @srcHandle : source stream handle
1413  *
1414  * RETURN     : ptr to reprocess stream if found. NULL if not found
1415  *==========================================================================*/
getStreamBySrouceHandle(uint32_t srcHandle)1416 QCameraStream * QCameraReprocessChannel::getStreamBySrouceHandle(uint32_t srcHandle)
1417 {
1418     QCameraStream *pStream = NULL;
1419 
1420     for (size_t i = 0; i < mStreams.size(); i++) {
1421         if (validate_handle(mSrcStreamHandles[i], srcHandle)) {
1422             pStream = mStreams[i];
1423             break;
1424         }
1425     }
1426 
1427     return pStream;
1428 }
1429 
1430 /*===========================================================================
1431  * FUNCTION   : stop
1432  *
1433  * DESCRIPTION: stop channel and unmap offline buffers
1434  *
1435  * PARAMETERS : none
1436  *
1437  * RETURN     : int32_t type of status
1438  *              NO_ERROR  -- success
1439  *              none-zero failure code
1440  *==========================================================================*/
stop()1441 int32_t QCameraReprocessChannel::stop()
1442 {
1443     int32_t rc = QCameraChannel::stop();
1444 
1445     if (!mOfflineBuffers.empty()) {
1446         QCameraStream *stream = NULL;
1447         List<OfflineBuffer>::iterator it = mOfflineBuffers.begin();
1448         int error = NO_ERROR;
1449         for( ; it != mOfflineBuffers.end(); it++) {
1450             stream = (*it).stream;
1451             if (NULL != stream) {
1452                 error = stream->unmapBuf((*it).type,
1453                                          (*it).index,
1454                                          -1);
1455                 if (NO_ERROR != error) {
1456                     LOGE("Error during offline buffer unmap %d",
1457                            error);
1458                 }
1459             }
1460         }
1461         mOfflineBuffers.clear();
1462     }
1463     return rc;
1464 }
1465 
1466 /*===========================================================================
1467  * FUNCTION   : doReprocessOffline
1468  *
1469  * DESCRIPTION: request to do offline reprocess on the frame
1470  *
1471  * PARAMETERS :
1472  *   @frame   : frame to be performed a reprocess
1473  *   @meta_buf : Metadata buffer for reprocessing
1474  *   @pStream  : Actual reprocess stream
1475  *
1476  * RETURN     : int32_t type of status
1477  *              NO_ERROR  -- success
1478  *              none-zero failure code
1479  *==========================================================================*/
doReprocessOffline(mm_camera_buf_def_t * frame,mm_camera_buf_def_t * meta_buf,QCameraStream * pStream)1480 int32_t QCameraReprocessChannel::doReprocessOffline(mm_camera_buf_def_t *frame,
1481         mm_camera_buf_def_t *meta_buf, QCameraStream *pStream)
1482 {
1483     int32_t rc = 0;
1484     OfflineBuffer mappedBuffer;
1485     uint32_t buf_index = 0;
1486     uint32_t meta_buf_index = 0;
1487 
1488     if ((frame == NULL) || (meta_buf == NULL)) {
1489         LOGE("Invalid Input Paramters");
1490         return INVALID_OPERATION;
1491     }
1492 
1493     if (pStream == NULL) {
1494         pStream = getStreamBySrouceHandle(frame->stream_id);
1495         if (pStream == NULL) {
1496             LOGE("Input validation failed.");
1497             return INVALID_OPERATION;
1498         }
1499     }
1500 
1501     if (!mOfflineBuffers.empty()) {
1502         List<OfflineBuffer>::iterator it = mOfflineBuffers.begin();
1503         for( ; it != mOfflineBuffers.end(); it++) {
1504             buf_index = (buf_index < ((*it).index)) ? ((*it).index) : buf_index;
1505         }
1506         buf_index += 1;
1507     }
1508 
1509     meta_buf_index = buf_index;
1510     if (meta_buf != NULL) {
1511         rc = pStream->mapBuf(CAM_MAPPING_BUF_TYPE_OFFLINE_META_BUF,
1512                 meta_buf_index,
1513                 -1,
1514                 meta_buf->fd,
1515                 meta_buf->buffer,
1516                 meta_buf->frame_len);
1517         if (NO_ERROR != rc ) {
1518             LOGE("Error during metadata buffer mapping");
1519             rc = -1;
1520             return rc;
1521         }
1522 
1523         mappedBuffer.index = meta_buf_index;
1524         mappedBuffer.stream = pStream;
1525         mappedBuffer.type = CAM_MAPPING_BUF_TYPE_OFFLINE_META_BUF;
1526         mOfflineBuffers.push_back(mappedBuffer);
1527         buf_index += 1;
1528     }
1529 
1530     rc = pStream->mapBuf(CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF,
1531              buf_index,
1532              -1,
1533              frame->fd,
1534              frame->buffer,
1535              frame->frame_len);
1536     if (NO_ERROR != rc ) {
1537         LOGE("Error during reprocess input buffer mapping");
1538         rc = -1;
1539         return rc;
1540     }
1541     mappedBuffer.index = buf_index;
1542     mappedBuffer.stream = pStream;
1543     mappedBuffer.type = CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF;
1544     mOfflineBuffers.push_back(mappedBuffer);
1545 
1546     cam_stream_parm_buffer_t param;
1547     memset(&param, 0, sizeof(cam_stream_parm_buffer_t));
1548 
1549     param.type = CAM_STREAM_PARAM_TYPE_DO_REPROCESS;
1550     param.reprocess.buf_index = buf_index;
1551     param.reprocess.frame_idx = frame->frame_idx;
1552     param.reprocess.is_uv_subsampled = frame->is_uv_subsampled;
1553     cam_stream_info_t *streamInfo =
1554             reinterpret_cast<cam_stream_info_t *>(pStream->getStreamInfoBuf()->getPtr(0));
1555 
1556     if ((pStream->isOrignalTypeOf(CAM_STREAM_TYPE_METADATA)) && streamInfo &&
1557              (streamInfo->reprocess_config.pp_feature_config.feature_mask &
1558              CAM_QCOM_FEATURE_METADATA_BYPASS)) {
1559         LOGH("set meta bypass for quadra cfa first pass");
1560         // Backend will skip processing of metadata for first pass
1561         param.reprocess.is_offline_meta_bypass = 1;
1562     }
1563     if (meta_buf != NULL) {
1564         param.reprocess.meta_present = 1;
1565         param.reprocess.meta_buf_index = meta_buf_index;
1566     }
1567 
1568     LOGI("Offline reprocessing id = %d buf Id = %d meta index = %d type = %d",
1569              param.reprocess.frame_idx, param.reprocess.buf_index,
1570             param.reprocess.meta_buf_index, pStream->getMyOriginalType());
1571 
1572     rc = pStream->setParameter(param);
1573     if (rc != NO_ERROR) {
1574         LOGE("stream setParameter for reprocess failed");
1575         return rc;
1576     }
1577     return rc;
1578 }
1579 
1580 /*===========================================================================
1581  * FUNCTION   : doReprocessOffline
1582  *
1583  * DESCRIPTION: request to do offline reprocess on the frame
1584  *
1585  * PARAMETERS :
1586  *   @frame   : frame to be performed a reprocess
1587  *   @meta_buf : Metadata buffer for reprocessing
1588  *   @mParameter : camera parameters
1589  *
1590  * RETURN     : int32_t type of status
1591  *              NO_ERROR  -- success
1592  *              none-zero failure code
1593  *==========================================================================*/
doReprocessOffline(mm_camera_super_buf_t * frame,mm_camera_buf_def_t * meta_buf,QCameraParametersIntf & mParameter)1594 int32_t QCameraReprocessChannel::doReprocessOffline(mm_camera_super_buf_t *frame,
1595         mm_camera_buf_def_t *meta_buf, QCameraParametersIntf &mParameter)
1596 {
1597     int32_t rc = 0;
1598     QCameraStream *pStream = NULL;
1599 
1600     if (mStreams.size() < 1) {
1601         LOGE("No reprocess streams");
1602         return -1;
1603     }
1604     if (m_pSrcChannel == NULL) {
1605         LOGE("No source channel for reprocess");
1606         return -1;
1607     }
1608 
1609     if (frame == NULL) {
1610         LOGE("Invalid source frame");
1611         return BAD_VALUE;
1612     }
1613 
1614     for (uint32_t i = 0; i < frame->num_bufs; i++) {
1615         pStream = getStreamBySrouceHandle(frame->bufs[i]->stream_id);
1616         if ((pStream != NULL) &&
1617                 (validate_handle(m_handle,pStream->getChannelHandle()))) {
1618             if (mParameter.getofflineRAW() &&
1619                     !((pStream->isOrignalTypeOf(CAM_STREAM_TYPE_RAW))
1620                     || (pStream->isOrignalTypeOf(CAM_STREAM_TYPE_METADATA)))) {
1621                 continue;
1622             }
1623 
1624             if ((pStream->isOrignalTypeOf(CAM_STREAM_TYPE_METADATA)
1625                      && ((mParameter.getManualCaptureMode()
1626                      < CAM_MANUAL_CAPTURE_TYPE_3) && (!mParameter.getQuadraCfa())))
1627                      || (pStream->isTypeOf(CAM_STREAM_TYPE_ANALYSIS))) {
1628                 // Skip metadata for reprocess now because PP module cannot handle meta data
1629                 // May need furthur discussion if Imaginglib need meta data
1630                 // Do not skip metadata for manual capture or quadra CFA mode.
1631                 continue;
1632             }
1633 
1634             // Update Metadata
1635             if (meta_buf != NULL) {
1636                 uint32_t stream_id = frame->bufs[i]->stream_id;
1637                 QCameraStream *srcStream =
1638                         m_pSrcChannel->getStreamByHandle(stream_id);
1639                 metadata_buffer_t *pMetaData =
1640                         (metadata_buffer_t *)meta_buf->buffer;
1641                 if ((NULL != pMetaData) && (NULL != srcStream)) {
1642                     IF_META_AVAILABLE(cam_crop_data_t, crop,
1643                             CAM_INTF_META_CROP_DATA, pMetaData) {
1644                         if (MAX_NUM_STREAMS > crop->num_of_streams) {
1645                             for (int j = 0; j < MAX_NUM_STREAMS; j++) {
1646                                 if (crop->crop_info[j].stream_id ==
1647                                             srcStream->getMyServerID()) {
1648                                     // Store crop/roi information for offline reprocess
1649                                     // in the reprocess stream slot
1650                                     crop->crop_info[crop->num_of_streams].crop =
1651                                             crop->crop_info[j].crop;
1652                                     crop->crop_info[crop->num_of_streams].roi_map =
1653                                             crop->crop_info[j].roi_map;
1654                                     for (uint8_t k = 0; k < mStreams.size(); k++) {
1655                                         if (srcStream->getMyType() ==
1656                                                 mStreams[k]->getMyOriginalType()) {
1657                                             crop->crop_info[crop->num_of_streams].stream_id =
1658                                                     mStreams[k]->getMyServerID();
1659                                             break;
1660                                         }
1661                                     }
1662                                     crop->num_of_streams++;
1663                                     break;
1664                                 }
1665                             }
1666                         } else {
1667                             LOGE("No space to add reprocess stream crop/roi information");
1668                         }
1669                     }
1670                 }
1671             } else {
1672                 LOGE("Metadata NULL");
1673             }
1674 
1675             if (mParameter.getofflineRAW()) {
1676                 //For offline RAW reprocessing, make sure cache is clean & invalidated
1677                 frame->bufs[i]->cache_flags |= CPU_HAS_READ_WRITTEN;
1678             }
1679             //Do Cache ops before sending to reprocess
1680             if (frame->bufs[i] != NULL) {
1681                 pStream->handleCacheOps(frame->bufs[i]);
1682             }
1683             rc = doReprocessOffline (frame->bufs[i], meta_buf, pStream);
1684         }
1685     }
1686     return rc;
1687 }
1688 
1689 /*===========================================================================
1690  * FUNCTION   : doReprocess
1691  *
1692  * DESCRIPTION: request to do a reprocess on the frame
1693  *
1694  * PARAMETERS :
1695  *   @frame   : frame to be performed a reprocess
1696  *   @mParameter : camera parameters
1697  *   @pMetaStream: Metadata stream handle
1698  *   @meta_buf_index : Metadata buffer index
1699  *
1700  * RETURN     : int32_t type of status
1701  *              NO_ERROR  -- success
1702  *              none-zero failure code
1703  *==========================================================================*/
doReprocess(mm_camera_super_buf_t * frame,QCameraParametersIntf & mParameter,QCameraStream * pMetaStream,uint8_t meta_buf_index)1704 int32_t QCameraReprocessChannel::doReprocess(mm_camera_super_buf_t *frame,
1705         QCameraParametersIntf &mParameter, QCameraStream *pMetaStream,
1706         uint8_t meta_buf_index)
1707 {
1708     int32_t rc = 0;
1709     if (mStreams.size() < 1) {
1710         LOGE("No reprocess streams");
1711         return -1;
1712     }
1713     if (m_pSrcChannel == NULL) {
1714         LOGE("No source channel for reprocess");
1715         return -1;
1716     }
1717 
1718     if (pMetaStream == NULL) {
1719         LOGW("Null Metadata buffer for processing");
1720     }
1721 
1722     for (uint32_t i = 0; i < frame->num_bufs; i++) {
1723         QCameraStream *pStream = getStreamBySrouceHandle(frame->bufs[i]->stream_id);
1724         if ((pStream != NULL) &&
1725                 (validate_handle(m_handle, pStream->getChannelHandle()))) {
1726             if (mParameter.getofflineRAW() && !((pStream->isOrignalTypeOf(CAM_STREAM_TYPE_RAW))
1727                     || (pStream->isOrignalTypeOf(CAM_STREAM_TYPE_POSTVIEW))
1728                     || (pStream->isOrignalTypeOf(CAM_STREAM_TYPE_METADATA)))) {
1729                 //Skip all the stream other than RAW and POSTVIEW incase of offline of RAW
1730                 continue;
1731             }
1732             if ((pStream->isOrignalTypeOf(CAM_STREAM_TYPE_METADATA)
1733                      && ((mParameter.getManualCaptureMode()
1734                      < CAM_MANUAL_CAPTURE_TYPE_3) && (!mParameter.getQuadraCfa())))
1735                      || (pStream->isTypeOf(CAM_STREAM_TYPE_ANALYSIS))) {
1736                 // Skip metadata for reprocess now because PP module cannot handle meta data
1737                 // May need furthur discussion if Imaginglib need meta data
1738                 // Do not skip metadata for manual capture or quadra CFA mode.
1739                 continue;
1740             }
1741 
1742             //Do Cache ops before sending to reprocess
1743             if (frame->bufs[i] != NULL) {
1744                 pStream->handleCacheOps(frame->bufs[i]);
1745             }
1746 
1747             cam_stream_parm_buffer_t param;
1748             memset(&param, 0, sizeof(cam_stream_parm_buffer_t));
1749             param.type = CAM_STREAM_PARAM_TYPE_DO_REPROCESS;
1750             param.reprocess.buf_index = frame->bufs[i]->buf_idx;
1751             param.reprocess.frame_idx = frame->bufs[i]->frame_idx;
1752             param.reprocess.is_uv_subsampled = frame->bufs[i]->is_uv_subsampled;
1753             if (pMetaStream != NULL) {
1754                 // we have meta data frame bundled, sent together with reprocess frame
1755                 param.reprocess.meta_present = 1;
1756                 param.reprocess.meta_stream_handle = pMetaStream->getMyServerID();
1757                 param.reprocess.meta_buf_index = meta_buf_index;
1758             }
1759 
1760             LOGI("Online reprocessing id = %d buf Id = %d meta index = %d type = %d",
1761                      param.reprocess.frame_idx, param.reprocess.buf_index,
1762                     param.reprocess.meta_buf_index, pStream->getMyOriginalType());
1763 
1764             rc = pStream->setParameter(param);
1765             if (rc != NO_ERROR) {
1766                 LOGE("stream setParameter for reprocess failed");
1767                 break;
1768             }
1769         }
1770     }
1771     return rc;
1772 }
1773 
1774 /*===========================================================================
1775  * FUNCTION   : doReprocess
1776  *
1777  * DESCRIPTION: request to do a reprocess on the frame
1778  *
1779  * PARAMETERS :
1780  *   @buf_fd     : fd to the input buffer that needs reprocess
1781  *   @buffer     : buffer pointer of actual buffer
1782  *   @buf_lenght : length of the input buffer
1783  *   @ret_val    : result of reprocess.
1784  *                 Example: Could be faceID in case of register face image.
1785  *
1786  * RETURN     : int32_t type of status
1787  *              NO_ERROR  -- success
1788  *              none-zero failure code
1789  *==========================================================================*/
doReprocess(int buf_fd,void * buffer,size_t buf_length,int32_t & ret_val)1790 int32_t QCameraReprocessChannel::doReprocess(int buf_fd, void *buffer,
1791         size_t buf_length, int32_t &ret_val)
1792 {
1793     int32_t rc = 0;
1794     if (mStreams.size() < 1) {
1795         LOGE("No reprocess streams");
1796         return -1;
1797     }
1798 
1799     uint32_t buf_idx = 0;
1800     for (size_t i = 0; i < mStreams.size(); i++) {
1801         if ((mStreams[i] != NULL) &&
1802                 (validate_handle(m_handle, mStreams[i]->getChannelHandle()))) {
1803             continue;
1804         }
1805         rc = mStreams[i]->mapBuf(CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF,
1806                                  buf_idx, -1,
1807                                  buf_fd, buffer, buf_length);
1808 
1809         if (rc == NO_ERROR) {
1810             cam_stream_parm_buffer_t param;
1811             memset(&param, 0, sizeof(cam_stream_parm_buffer_t));
1812             param.type = CAM_STREAM_PARAM_TYPE_DO_REPROCESS;
1813             param.reprocess.buf_index = buf_idx;
1814             rc = mStreams[i]->setParameter(param);
1815             if (rc == NO_ERROR) {
1816                 ret_val = param.reprocess.ret_val;
1817             }
1818             mStreams[i]->unmapBuf(CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF,
1819                                   buf_idx, -1);
1820         }
1821     }
1822     return rc;
1823 }
1824 
1825 }; // namespace qcamera
1826