1 /* Copyright (c) 2012-2014 The Linux Foundataion. 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 #include <utils/Errors.h>
33 #include "QCameraParameters.h"
34 #include "QCamera2HWI.h"
35 #include "QCameraChannel.h"
36 
37 using namespace android;
38 
39 namespace qcamera {
40 
41 /*===========================================================================
42  * FUNCTION   : QCameraChannel
43  *
44  * DESCRIPTION: constrcutor of QCameraChannel
45  *
46  * PARAMETERS :
47  *   @cam_handle : camera handle
48  *   @cam_ops    : ptr to camera ops table
49  *
50  * RETURN     : none
51  *==========================================================================*/
QCameraChannel(uint32_t cam_handle,mm_camera_ops_t * cam_ops)52 QCameraChannel::QCameraChannel(uint32_t cam_handle,
53                                mm_camera_ops_t *cam_ops)
54 {
55     m_camHandle = cam_handle;
56     m_camOps = cam_ops;
57     m_bIsActive = false;
58     m_bAllowDynBufAlloc = false;
59 
60     m_handle = 0;
61     m_numStreams = 0;
62     memset(mStreams, 0, sizeof(mStreams));
63 }
64 
65 /*===========================================================================
66  * FUNCTION   : QCameraChannel
67  *
68  * DESCRIPTION: default constrcutor of QCameraChannel
69  *
70  * PARAMETERS : none
71  *
72  * RETURN     : none
73  *==========================================================================*/
QCameraChannel()74 QCameraChannel::QCameraChannel()
75 {
76     m_camHandle = 0;
77     m_camOps = NULL;
78     m_bIsActive = false;
79 
80     m_handle = 0;
81     m_numStreams = 0;
82     memset(mStreams, 0, sizeof(mStreams));
83 }
84 
85 /*===========================================================================
86  * FUNCTION   : ~QCameraChannel
87  *
88  * DESCRIPTION: destructor of QCameraChannel
89  *
90  * PARAMETERS : none
91  *
92  * RETURN     : none
93  *==========================================================================*/
~QCameraChannel()94 QCameraChannel::~QCameraChannel()
95 {
96     if (m_bIsActive) {
97         stop();
98     }
99 
100     for (int i = 0; i < m_numStreams; i++) {
101         if (mStreams[i] != NULL) {
102             delete mStreams[i];
103             mStreams[i] = 0;
104         }
105     }
106     m_numStreams = 0;
107     m_camOps->delete_channel(m_camHandle, m_handle);
108     m_handle = 0;
109 }
110 
111 /*===========================================================================
112  * FUNCTION   : deleteChannel
113  *
114  * DESCRIPTION: deletes a camera channel
115  *
116  * PARAMETERS : none
117  *
118  * RETURN     : none
119  *==========================================================================*/
deleteChannel()120 void QCameraChannel::deleteChannel()
121 {
122     if (m_bIsActive) {
123         stop();
124     }
125 
126     for (int i = 0; i < m_numStreams; i++) {
127         if (mStreams[i] != NULL) {
128             mStreams[i]->deleteStream();
129         }
130     }
131     m_camOps->delete_channel(m_camHandle, m_handle);
132 }
133 
134 /*===========================================================================
135  * FUNCTION   : init
136  *
137  * DESCRIPTION: initialization of channel
138  *
139  * PARAMETERS :
140  *   @attr    : channel bundle attribute setting
141  *   @dataCB  : data notify callback
142  *   @userData: user data ptr
143  *
144  * RETURN     : int32_t type of status
145  *              NO_ERROR  -- success
146  *              none-zero failure code
147  *==========================================================================*/
init(mm_camera_channel_attr_t * attr,mm_camera_buf_notify_t dataCB,void * userData)148 int32_t QCameraChannel::init(mm_camera_channel_attr_t *attr,
149                              mm_camera_buf_notify_t dataCB,
150                              void *userData)
151 {
152     m_handle = m_camOps->add_channel(m_camHandle,
153                                       attr,
154                                       dataCB,
155                                       userData);
156     if (m_handle == 0) {
157         ALOGE("%s: Add channel failed", __func__);
158         return UNKNOWN_ERROR;
159     }
160     return NO_ERROR;
161 }
162 
163 /*===========================================================================
164  * FUNCTION   : addStream
165  *
166  * DESCRIPTION: add a stream into channel
167  *
168  * PARAMETERS :
169  *   @allocator      : stream related buffer allocator
170  *   @streamInfoBuf  : ptr to buf that constains stream info
171  *   @minStreamBufNum: number of stream buffers needed
172  *   @paddingInfo    : padding information
173  *   @stream_cb      : stream data notify callback
174  *   @userdata       : user data ptr
175  *   @bDynAllocBuf   : flag indicating if allow allocate buffers in 2 steps
176  *
177  * RETURN     : int32_t type of status
178  *              NO_ERROR  -- success
179  *              none-zero failure code
180  *==========================================================================*/
addStream(QCameraAllocator & allocator,QCameraHeapMemory * streamInfoBuf,uint8_t minStreamBufNum,cam_padding_info_t * paddingInfo,stream_cb_routine stream_cb,void * userdata,bool bDynAllocBuf,bool bDeffAlloc)181 int32_t QCameraChannel::addStream(QCameraAllocator &allocator,
182                                   QCameraHeapMemory *streamInfoBuf,
183                                   uint8_t minStreamBufNum,
184                                   cam_padding_info_t *paddingInfo,
185                                   stream_cb_routine stream_cb,
186                                   void *userdata,
187                                   bool bDynAllocBuf,
188                                   bool bDeffAlloc)
189 {
190     int32_t rc = NO_ERROR;
191     if (m_numStreams >= MAX_STREAM_NUM_IN_BUNDLE) {
192         ALOGE("%s: stream number (%d) exceeds max limit (%d)",
193               __func__, m_numStreams, MAX_STREAM_NUM_IN_BUNDLE);
194         return BAD_VALUE;
195     }
196     QCameraStream *pStream = new QCameraStream(allocator,
197                                                m_camHandle,
198                                                m_handle,
199                                                m_camOps,
200                                                paddingInfo,
201                                                bDeffAlloc);
202     if (pStream == NULL) {
203         ALOGE("%s: No mem for Stream", __func__);
204         return NO_MEMORY;
205     }
206 
207     rc = pStream->init(streamInfoBuf, minStreamBufNum,
208                        stream_cb, userdata, bDynAllocBuf);
209     if (rc == 0) {
210         mStreams[m_numStreams] = pStream;
211         m_numStreams++;
212     } else {
213         delete pStream;
214     }
215     return rc;
216 }
217 /*===========================================================================
218  * FUNCTION   : config
219  *
220  * DESCRIPTION: Configure any deffered channel streams
221  *
222  * PARAMETERS : None
223  *
224  * RETURN     : int32_t type of status
225  *              NO_ERROR  -- success
226  *              none-zero failure code
227  *==========================================================================*/
config()228 int32_t QCameraChannel::config()
229 {
230     int32_t rc = NO_ERROR;
231 
232     for (int i = 0; i < m_numStreams; ++i) {
233         if ( mStreams[i]->isDeffered() ) {
234             rc = mStreams[i]->configStream();
235             if (rc != NO_ERROR) {
236                 break;
237             }
238         }
239     }
240 
241     return rc;
242 }
243 
244 /*===========================================================================
245  * FUNCTION   : start
246  *
247  * DESCRIPTION: start channel, which will start all streams belong to this channel
248  *
249  * PARAMETERS : None
250  *
251  * RETURN     : int32_t type of status
252  *              NO_ERROR  -- success
253  *              none-zero failure code
254  *==========================================================================*/
start()255 int32_t QCameraChannel::start()
256 {
257     int32_t rc = NO_ERROR;
258 
259     if (m_numStreams > 1) {
260         // there is more than one stream in the channel
261         // we need to notify mctl that all streams in this channel need to be bundled
262         cam_bundle_config_t bundleInfo;
263         memset(&bundleInfo, 0, sizeof(bundleInfo));
264         rc = m_camOps->get_bundle_info(m_camHandle, m_handle, &bundleInfo);
265         if (rc != NO_ERROR) {
266             ALOGE("%s: get_bundle_info failed", __func__);
267             return rc;
268         }
269         if (bundleInfo.num_of_streams > 1) {
270             for (int i = 0; i < bundleInfo.num_of_streams; i++) {
271                 QCameraStream *pStream = getStreamByServerID(bundleInfo.stream_ids[i]);
272                 if (pStream != NULL) {
273                     if (pStream->isTypeOf(CAM_STREAM_TYPE_METADATA)) {
274                         // Skip metadata for reprocess now because PP module cannot handle meta data
275                         // May need furthur discussion if Imaginglib need meta data
276                         continue;
277                     }
278 
279                     cam_stream_parm_buffer_t param;
280                     memset(&param, 0, sizeof(cam_stream_parm_buffer_t));
281                     param.type = CAM_STREAM_PARAM_TYPE_SET_BUNDLE_INFO;
282                     param.bundleInfo = bundleInfo;
283                     rc = pStream->setParameter(param);
284                     if (rc != NO_ERROR) {
285                         ALOGE("%s: stream setParameter for set bundle failed", __func__);
286                         return rc;
287                     }
288                 }
289             }
290         }
291     }
292 
293     for (int i = 0; i < m_numStreams; i++) {
294         if (mStreams[i] != NULL) {
295             mStreams[i]->start();
296         }
297     }
298     rc = m_camOps->start_channel(m_camHandle, m_handle);
299 
300     if (rc != NO_ERROR) {
301         for (int i = 0; i < m_numStreams; i++) {
302             if (mStreams[i] != NULL) {
303                 mStreams[i]->stop();
304             }
305         }
306     } else {
307         m_bIsActive = true;
308         for (int i = 0; i < m_numStreams; i++) {
309             if (mStreams[i] != NULL) {
310                 mStreams[i]->cond_signal();
311             }
312         }
313     }
314 
315     return rc;
316 }
317 
318 /*===========================================================================
319  * FUNCTION   : stop
320  *
321  * DESCRIPTION: stop a channel, which will stop all streams belong to this channel
322  *
323  * PARAMETERS : none
324  *
325  * RETURN     : int32_t type of status
326  *              NO_ERROR  -- success
327  *              none-zero failure code
328  *==========================================================================*/
stop()329 int32_t QCameraChannel::stop()
330 {
331     int32_t rc = NO_ERROR;
332     for (int i = 0; i < m_numStreams; i++) {
333         if (mStreams[i] != NULL) {
334             mStreams[i]->stop();
335         }
336     }
337 
338     rc = m_camOps->stop_channel(m_camHandle, m_handle);
339 
340     m_bIsActive = false;
341     return rc;
342 }
343 
344 /*===========================================================================
345  * FUNCTION   : bufDone
346  *
347  * DESCRIPTION: return a stream buf back to kernel
348  *
349  * PARAMETERS :
350  *   @recvd_frame  : stream buf frame to be returned
351  *
352  * RETURN     : int32_t type of status
353  *              NO_ERROR  -- success
354  *              none-zero failure code
355  *==========================================================================*/
bufDone(mm_camera_super_buf_t * recvd_frame)356 int32_t QCameraChannel::bufDone(mm_camera_super_buf_t *recvd_frame)
357 {
358     int32_t rc = NO_ERROR;
359     for (int i = 0; i < recvd_frame->num_bufs; i++) {
360          if (recvd_frame->bufs[i] != NULL) {
361              for (int j = 0; j < m_numStreams; j++) {
362                  if (mStreams[j] != NULL &&
363                      mStreams[j]->getMyHandle() == recvd_frame->bufs[i]->stream_id) {
364                      rc = mStreams[j]->bufDone(recvd_frame->bufs[i]->buf_idx);
365                      break; // break loop j
366                  }
367              }
368          }
369     }
370 
371     return rc;
372 }
373 
374 /*===========================================================================
375  * FUNCTION   : processZoomDone
376  *
377  * DESCRIPTION: process zoom done event
378  *
379  * PARAMETERS :
380  *   @previewWindoe : ptr to preview window ops table, needed to set preview
381  *                    crop information
382  *   @crop_info     : crop info as a result of zoom operation
383  *
384  * RETURN     : int32_t type of status
385  *              NO_ERROR  -- success
386  *              none-zero failure code
387  *==========================================================================*/
processZoomDone(preview_stream_ops_t * previewWindow,cam_crop_data_t & crop_info)388 int32_t QCameraChannel::processZoomDone(preview_stream_ops_t *previewWindow,
389                                         cam_crop_data_t &crop_info)
390 {
391     int32_t rc = NO_ERROR;
392     for (int i = 0; i < m_numStreams; i++) {
393         if (mStreams[i] != NULL) {
394             rc = mStreams[i]->processZoomDone(previewWindow, crop_info);
395         }
396     }
397     return rc;
398 }
399 
400 /*===========================================================================
401  * FUNCTION   : getStreamByHandle
402  *
403  * DESCRIPTION: return stream object by stream handle
404  *
405  * PARAMETERS :
406  *   @streamHandle : stream handle
407  *
408  * RETURN     : stream object. NULL if not found
409  *==========================================================================*/
getStreamByHandle(uint32_t streamHandle)410 QCameraStream *QCameraChannel::getStreamByHandle(uint32_t streamHandle)
411 {
412     for (int i = 0; i < m_numStreams; i++) {
413         if (mStreams[i] != NULL && mStreams[i]->getMyHandle() == streamHandle) {
414             return mStreams[i];
415         }
416     }
417     return NULL;
418 }
419 
420 /*===========================================================================
421  * FUNCTION   : getStreamByServerID
422  *
423  * DESCRIPTION: return stream object by stream server ID from daemon
424  *
425  * PARAMETERS :
426  *   @serverID : stream server ID
427  *
428  * RETURN     : stream object. NULL if not found
429  *==========================================================================*/
getStreamByServerID(uint32_t serverID)430 QCameraStream *QCameraChannel::getStreamByServerID(uint32_t serverID)
431 {
432     for (int i = 0; i < m_numStreams; i++) {
433         if (mStreams[i] != NULL && mStreams[i]->getMyServerID() == serverID) {
434             return mStreams[i];
435         }
436     }
437     return NULL;
438 }
439 
440 /*===========================================================================
441  * FUNCTION   : getStreamByIndex
442  *
443  * DESCRIPTION: return stream object by index of streams in the channel
444  *
445  * PARAMETERS :
446  *   @index : index of stream in the channel
447  *
448  * RETURN     : stream object. NULL if not found
449  *==========================================================================*/
getStreamByIndex(uint8_t index)450 QCameraStream *QCameraChannel::getStreamByIndex(uint8_t index)
451 {
452     if (index >= MAX_STREAM_NUM_IN_BUNDLE) {
453         return NULL;
454     }
455 
456     if (index < m_numStreams) {
457         return mStreams[index];
458     }
459     return NULL;
460 }
461 
462 /*===========================================================================
463  * FUNCTION   : UpdateStreamBasedParameters
464  *
465  * DESCRIPTION: update any stream based settings from parameters
466  *
467  * PARAMETERS :
468  *   @param   : reference to parameters object
469  *
470  * RETURN     : int32_t type of status
471  *              NO_ERROR  -- success
472  *              none-zero failure code
473  *==========================================================================*/
UpdateStreamBasedParameters(QCameraParameters & param)474 int32_t QCameraChannel::UpdateStreamBasedParameters(QCameraParameters &param)
475 {
476     int32_t rc = NO_ERROR;
477     if (param.isPreviewFlipChanged()) {
478         // try to find preview stream
479         for (int i = 0; i < MAX_STREAM_NUM_IN_BUNDLE; i++) {
480             if (mStreams[i] != NULL &&
481                 (mStreams[i]->isTypeOf(CAM_STREAM_TYPE_PREVIEW) ||
482                 (mStreams[i]->isOrignalTypeOf(CAM_STREAM_TYPE_PREVIEW))) ) {
483                 cam_stream_parm_buffer_t param_buf;
484                 memset(&param_buf, 0, sizeof(cam_stream_parm_buffer_t));
485                 param_buf.type = CAM_STREAM_PARAM_TYPE_SET_FLIP;
486                 param_buf.flipInfo.flip_mask = param.getFlipMode(CAM_STREAM_TYPE_PREVIEW);
487                 rc = mStreams[i]->setParameter(param_buf);
488                 if (rc != NO_ERROR) {
489                     ALOGE("%s: set preview stream flip failed", __func__);
490                 }
491             }
492         }
493     }
494     if (param.isVideoFlipChanged()) {
495         // try to find video stream
496         for (int i = 0; i < MAX_STREAM_NUM_IN_BUNDLE; i++) {
497             if (mStreams[i] != NULL &&
498                 (mStreams[i]->isTypeOf(CAM_STREAM_TYPE_VIDEO) ||
499                 (mStreams[i]->isOrignalTypeOf(CAM_STREAM_TYPE_VIDEO))) ) {
500                 cam_stream_parm_buffer_t param_buf;
501                 memset(&param_buf, 0, sizeof(cam_stream_parm_buffer_t));
502                 param_buf.type = CAM_STREAM_PARAM_TYPE_SET_FLIP;
503                 param_buf.flipInfo.flip_mask = param.getFlipMode(CAM_STREAM_TYPE_VIDEO);
504                 rc = mStreams[i]->setParameter(param_buf);
505                 if (rc != NO_ERROR) {
506                     ALOGE("%s: set video stream flip failed", __func__);
507                 }
508             }
509         }
510     }
511     if (param.isSnapshotFlipChanged()) {
512         // try to find snapshot/postview stream
513         for (int i = 0; i < MAX_STREAM_NUM_IN_BUNDLE; i++) {
514             if (mStreams[i] != NULL &&
515                 (mStreams[i]->isTypeOf(CAM_STREAM_TYPE_SNAPSHOT) ||
516                  mStreams[i]->isOrignalTypeOf(CAM_STREAM_TYPE_SNAPSHOT) ||
517                  mStreams[i]->isTypeOf(CAM_STREAM_TYPE_POSTVIEW) ||
518                  mStreams[i]->isOrignalTypeOf(CAM_STREAM_TYPE_POSTVIEW) ) ) {
519                 cam_stream_parm_buffer_t param_buf;
520                 memset(&param_buf, 0, sizeof(cam_stream_parm_buffer_t));
521                 param_buf.type = CAM_STREAM_PARAM_TYPE_SET_FLIP;
522                 param_buf.flipInfo.flip_mask = param.getFlipMode(CAM_STREAM_TYPE_SNAPSHOT);
523                 rc = mStreams[i]->setParameter(param_buf);
524                 if (rc != NO_ERROR) {
525                     ALOGE("%s: set snapshot stream flip failed", __func__);
526                 }
527             }
528         }
529     }
530     return rc;
531 }
532 
533 /*===========================================================================
534  * FUNCTION   : QCameraPicChannel
535  *
536  * DESCRIPTION: constructor of QCameraPicChannel
537  *
538  * PARAMETERS :
539  *   @cam_handle : camera handle
540  *   @cam_ops    : ptr to camera ops table
541  *
542  * RETURN     : none
543  *==========================================================================*/
QCameraPicChannel(uint32_t cam_handle,mm_camera_ops_t * cam_ops)544 QCameraPicChannel::QCameraPicChannel(uint32_t cam_handle,
545                                      mm_camera_ops_t *cam_ops) :
546     QCameraChannel(cam_handle, cam_ops)
547 {
548     m_bAllowDynBufAlloc = true;
549 }
550 
551 /*===========================================================================
552  * FUNCTION   : QCameraPicChannel
553  *
554  * DESCRIPTION: default constructor of QCameraPicChannel
555  *
556  * PARAMETERS : none
557  *
558  * RETURN     : none
559  *==========================================================================*/
QCameraPicChannel()560 QCameraPicChannel::QCameraPicChannel()
561 {
562     m_bAllowDynBufAlloc = true;
563 }
564 
565 /*===========================================================================
566  * FUNCTION   : ~QCameraPicChannel
567  *
568  * DESCRIPTION: destructor of QCameraPicChannel
569  *
570  * PARAMETERS : none
571  *
572  * RETURN     : none
573  *==========================================================================*/
~QCameraPicChannel()574 QCameraPicChannel::~QCameraPicChannel()
575 {
576 }
577 
578 /*===========================================================================
579  * FUNCTION   : takePicture
580  *
581  * DESCRIPTION: send request for queued snapshot frames
582  *
583  * PARAMETERS :
584  *   @num_of_snapshot : number of snapshot frames requested
585  *   @num_of_retro_snapshot : number of retro snapshot frames requested
586  *
587  * RETURN     : int32_t type of status
588  *              NO_ERROR  -- success
589  *              none-zero failure code
590  *==========================================================================*/
takePicture(uint8_t num_of_snapshot,uint8_t num_of_retro_snapshot)591 int32_t QCameraPicChannel::takePicture (
592     uint8_t num_of_snapshot,
593     uint8_t num_of_retro_snapshot)
594 {
595     int32_t rc = m_camOps->request_super_buf(m_camHandle,
596                                              m_handle,
597                                              num_of_snapshot,
598                                              num_of_retro_snapshot);
599     return rc;
600 }
601 
602 /*===========================================================================
603  * FUNCTION   : cancelPicture
604  *
605  * DESCRIPTION: cancel request for queued snapshot frames
606  *
607  * PARAMETERS : none
608  *
609  * RETURN     : int32_t type of status
610  *              NO_ERROR  -- success
611  *              none-zero failure code
612  *==========================================================================*/
cancelPicture()613 int32_t QCameraPicChannel::cancelPicture()
614 {
615     int32_t rc = m_camOps->cancel_super_buf_request(m_camHandle, m_handle);
616     return rc;
617 }
618 
619 /*===========================================================================
620  * FUNCTION   : startAdvancedCapture
621  *
622  * DESCRIPTION: start advanced capture based on advanced capture type.
623  *
624  * PARAMETERS :
625  *   @type : advanced capture type.
626  *
627  * RETURN     : int32_t type of status
628  *              NO_ERROR  -- success
629  *              none-zero failure code
630  *==========================================================================*/
startAdvancedCapture(mm_camera_advanced_capture_t type)631 int32_t QCameraPicChannel::startAdvancedCapture(mm_camera_advanced_capture_t type)
632 {
633     int32_t rc = m_camOps->process_advanced_capture(m_camHandle, type,
634                                               m_handle, 1);
635     return rc;
636 }
637 
638 /*===========================================================================
639  * FUNCTION   : QCameraVideoChannel
640  *
641  * DESCRIPTION: constructor of QCameraVideoChannel
642  *
643  * PARAMETERS :
644  *   @cam_handle : camera handle
645  *   @cam_ops    : ptr to camera ops table
646  *
647  * RETURN     : none
648  *==========================================================================*/
QCameraVideoChannel(uint32_t cam_handle,mm_camera_ops_t * cam_ops)649 QCameraVideoChannel::QCameraVideoChannel(uint32_t cam_handle,
650                                          mm_camera_ops_t *cam_ops) :
651     QCameraChannel(cam_handle, cam_ops)
652 {
653 }
654 
655 /*===========================================================================
656  * FUNCTION   : QCameraVideoChannel
657  *
658  * DESCRIPTION: default constructor of QCameraVideoChannel
659  *
660  * PARAMETERS : none
661  *
662  * RETURN     : none
663  *==========================================================================*/
QCameraVideoChannel()664 QCameraVideoChannel::QCameraVideoChannel()
665 {
666 }
667 
668 /*===========================================================================
669  * FUNCTION   : ~QCameraVideoChannel
670  *
671  * DESCRIPTION: destructor of QCameraVideoChannel
672  *
673  * PARAMETERS : none
674  *
675  * RETURN     : none
676  *==========================================================================*/
~QCameraVideoChannel()677 QCameraVideoChannel::~QCameraVideoChannel()
678 {
679 }
680 
681 /*===========================================================================
682  * FUNCTION   : releaseFrame
683  *
684  * DESCRIPTION: return video frame from app
685  *
686  * PARAMETERS :
687  *   @opaque     : ptr to video frame to be returned
688  *   @isMetaData : if frame is a metadata or real frame
689  *
690  * RETURN     : int32_t type of status
691  *              NO_ERROR  -- success
692  *              none-zero failure code
693  *==========================================================================*/
releaseFrame(const void * opaque,bool isMetaData)694 int32_t QCameraVideoChannel::releaseFrame(const void * opaque, bool isMetaData)
695 {
696     QCameraStream *pVideoStream = NULL;
697     for (int i = 0; i < m_numStreams; i++) {
698         if (mStreams[i] != NULL && mStreams[i]->isTypeOf(CAM_STREAM_TYPE_VIDEO)) {
699             pVideoStream = mStreams[i];
700             break;
701         }
702     }
703 
704     if (NULL == pVideoStream) {
705         ALOGE("%s: No video stream in the channel", __func__);
706         return BAD_VALUE;
707     }
708 
709     int32_t rc = pVideoStream->bufDone(opaque, isMetaData);
710     return rc;
711 }
712 
713 /*===========================================================================
714  * FUNCTION   : QCameraReprocessChannel
715  *
716  * DESCRIPTION: constructor of QCameraReprocessChannel
717  *
718  * PARAMETERS :
719  *   @cam_handle : camera handle
720  *   @cam_ops    : ptr to camera ops table
721  *   @pp_mask    : post-proccess feature mask
722  *
723  * RETURN     : none
724  *==========================================================================*/
QCameraReprocessChannel(uint32_t cam_handle,mm_camera_ops_t * cam_ops)725 QCameraReprocessChannel::QCameraReprocessChannel(uint32_t cam_handle,
726                                                  mm_camera_ops_t *cam_ops) :
727     QCameraChannel(cam_handle, cam_ops),
728     m_pSrcChannel(NULL)
729 {
730     memset(mSrcStreamHandles, 0, sizeof(mSrcStreamHandles));
731 }
732 
733 /*===========================================================================
734  * FUNCTION   : QCameraReprocessChannel
735  *
736  * DESCRIPTION: default constructor of QCameraReprocessChannel
737  *
738  * PARAMETERS : none
739  *
740  * RETURN     : none
741  *==========================================================================*/
QCameraReprocessChannel()742 QCameraReprocessChannel::QCameraReprocessChannel() :
743     m_pSrcChannel(NULL)
744 {
745 }
746 
747 /*===========================================================================
748  * FUNCTION   : ~QCameraReprocessChannel
749  *
750  * DESCRIPTION: destructor of QCameraReprocessChannel
751  *
752  * PARAMETERS : none
753  *
754  * RETURN     : none
755  *==========================================================================*/
~QCameraReprocessChannel()756 QCameraReprocessChannel::~QCameraReprocessChannel()
757 {
758 }
759 
760 /*===========================================================================
761  * FUNCTION   : addReprocStreamsFromSource
762  *
763  * DESCRIPTION: add reprocess streams from input source channel
764  *
765  * PARAMETERS :
766  *   @allocator      : stream related buffer allocator
767  *   @config         : pp feature configuration
768  *   @pSrcChannel    : ptr to input source channel that needs reprocess
769  *   @minStreamBufNum: number of stream buffers needed
770  *   @burstNum       : number of burst captures needed
771  *   @paddingInfo    : padding information
772  *   @param          : reference to parameters
773  *   @contStream     : continous streaming mode or burst
774  *   @offline        : configure for offline reprocessing
775  *
776  * RETURN     : int32_t type of status
777  *              NO_ERROR  -- success
778  *              none-zero failure code
779  *==========================================================================*/
addReprocStreamsFromSource(QCameraAllocator & allocator,cam_pp_feature_config_t & config,QCameraChannel * pSrcChannel,uint8_t minStreamBufNum,uint32_t burstNum,cam_padding_info_t * paddingInfo,QCameraParameters & param,bool contStream,bool offline)780 int32_t QCameraReprocessChannel::addReprocStreamsFromSource(QCameraAllocator& allocator,
781                                                             cam_pp_feature_config_t &config,
782                                                             QCameraChannel *pSrcChannel,
783                                                             uint8_t minStreamBufNum,
784                                                             uint32_t burstNum,
785                                                             cam_padding_info_t *paddingInfo,
786                                                             QCameraParameters &param,
787                                                             bool contStream,
788                                                             bool offline)
789 {
790     int32_t rc = 0;
791     QCameraStream *pStream = NULL;
792     QCameraHeapMemory *pStreamInfoBuf = NULL;
793     cam_stream_info_t *streamInfo = NULL;
794 
795     memset(mSrcStreamHandles, 0, sizeof(mSrcStreamHandles));
796 
797     for (int i = 0; i < pSrcChannel->getNumOfStreams(); i++) {
798         pStream = pSrcChannel->getStreamByIndex(i);
799         if (pStream != NULL) {
800             if (pStream->isTypeOf(CAM_STREAM_TYPE_METADATA) ||
801                 pStream->isTypeOf(CAM_STREAM_TYPE_RAW)) {
802                 // Skip metadata&raw for reprocess now because PP module cannot handle
803                 // meta data&raw. May need furthur discussion if Imaginglib need meta data
804                 continue;
805             }
806 
807             if (pStream->isTypeOf(CAM_STREAM_TYPE_POSTVIEW) ||
808                 pStream->isTypeOf(CAM_STREAM_TYPE_PREVIEW)) {
809                 // Skip postview: in non zsl case, dont want to send
810                 // thumbnail through reprocess.
811                 // Skip preview: for same reason for zsl case
812                 continue;
813             }
814 
815             if(pStream->isTypeOf(CAM_STREAM_TYPE_PREVIEW) ||
816                pStream->isTypeOf(CAM_STREAM_TYPE_POSTVIEW) ||
817                pStream->isOrignalTypeOf(CAM_STREAM_TYPE_PREVIEW) ||
818                pStream->isOrignalTypeOf(CAM_STREAM_TYPE_POSTVIEW)) {
819                   uint32_t feature_mask = config.feature_mask;
820 
821                   if ((feature_mask & ~CAM_QCOM_FEATURE_HDR) == 0
822                       && param.isHDREnabled()
823                       && !param.isHDRThumbnailProcessNeeded()) {
824 
825                       // Skip thumbnail stream reprocessing in HDR
826                       // if only hdr is enabled
827                       continue;
828                   }
829 
830                   // skip thumbnail reprocessing if not needed
831                   if (!param.needThumbnailReprocess(&feature_mask)) {
832                       continue;
833                   }
834 
835                   //Don't do WNR for thumbnail
836                   feature_mask &= ~CAM_QCOM_FEATURE_DENOISE2D;
837                   if(!feature_mask) {
838                     // Skip thumbnail stream reprocessing since no other
839                     //reprocessing is enabled.
840                       continue;
841                   }
842             }
843 
844             pStreamInfoBuf = allocator.allocateStreamInfoBuf(CAM_STREAM_TYPE_OFFLINE_PROC);
845             if (pStreamInfoBuf == NULL) {
846                 ALOGE("%s: no mem for stream info buf", __func__);
847                 rc = NO_MEMORY;
848                 break;
849             }
850 
851             streamInfo = (cam_stream_info_t *)pStreamInfoBuf->getPtr(0);
852             memset(streamInfo, 0, sizeof(cam_stream_info_t));
853             streamInfo->stream_type = CAM_STREAM_TYPE_OFFLINE_PROC;
854             rc = pStream->getFormat(streamInfo->fmt);
855             rc = pStream->getFrameDimension(streamInfo->dim);
856             if ( contStream ) {
857                 streamInfo->streaming_mode = CAM_STREAMING_MODE_CONTINUOUS;
858                 streamInfo->num_of_burst = 0;
859             } else {
860                 streamInfo->streaming_mode = CAM_STREAMING_MODE_BURST;
861                 streamInfo->num_of_burst = burstNum;
862             }
863 
864             cam_stream_reproc_config_t rp_cfg;
865             memset(&rp_cfg, 0, sizeof(cam_stream_reproc_config_t));
866             if (offline) {
867                 cam_frame_len_offset_t offset;
868                 memset(&offset, 0, sizeof(cam_frame_len_offset_t));
869 
870                 rp_cfg.pp_type = CAM_OFFLINE_REPROCESS_TYPE;
871                 pStream->getFormat(rp_cfg.offline.input_fmt);
872                 pStream->getFrameDimension(rp_cfg.offline.input_dim);
873                 pStream->getFrameOffset(offset);
874                 rp_cfg.offline.input_buf_planes.plane_info = offset;
875                 rp_cfg.offline.input_type = pStream->getMyType();
876                 //For input metadata + input buffer
877                 rp_cfg.offline.num_of_bufs = 2;
878             } else {
879                 rp_cfg.pp_type = CAM_ONLINE_REPROCESS_TYPE;
880                 rp_cfg.online.input_stream_id = pStream->getMyServerID();
881                 rp_cfg.online.input_stream_type = pStream->getMyType();
882             }
883             streamInfo->reprocess_config = rp_cfg;
884             streamInfo->reprocess_config.pp_feature_config = config;
885 
886             if (!(pStream->isTypeOf(CAM_STREAM_TYPE_SNAPSHOT) ||
887                 pStream->isOrignalTypeOf(CAM_STREAM_TYPE_SNAPSHOT))) {
888                 streamInfo->reprocess_config.pp_feature_config.feature_mask &= ~CAM_QCOM_FEATURE_CAC;
889                 //Don't do WNR for thumbnail
890                 streamInfo->reprocess_config.pp_feature_config.feature_mask &= ~CAM_QCOM_FEATURE_DENOISE2D;
891 
892                 if (param.isHDREnabled()
893                   && !param.isHDRThumbnailProcessNeeded()){
894                     streamInfo->reprocess_config.pp_feature_config.feature_mask
895                       &= ~CAM_QCOM_FEATURE_HDR;
896                 }
897             }
898 
899             if (streamInfo->reprocess_config.pp_feature_config.feature_mask & CAM_QCOM_FEATURE_ROTATION) {
900                 if (streamInfo->reprocess_config.pp_feature_config.rotation == ROTATE_90 ||
901                     streamInfo->reprocess_config.pp_feature_config.rotation == ROTATE_270) {
902                     // rotated by 90 or 270, need to switch width and height
903                     int32_t temp = streamInfo->dim.height;
904                     streamInfo->dim.height = streamInfo->dim.width;
905                     streamInfo->dim.width = temp;
906                 }
907             }
908 
909             if (param.isZSLMode() &&
910                 (streamInfo->reprocess_config.online.input_stream_type == CAM_STREAM_TYPE_SNAPSHOT)) {
911                 // ZSL mode snapshot need reprocess to do the flip
912                 int flipMode =
913                     param.getFlipMode(streamInfo->reprocess_config.online.input_stream_type);
914                 if (flipMode > 0) {
915                     streamInfo->reprocess_config.pp_feature_config.feature_mask |= CAM_QCOM_FEATURE_FLIP;
916                     streamInfo->reprocess_config.pp_feature_config.flip = flipMode;
917                 }
918             }
919 
920             if(streamInfo->reprocess_config.pp_feature_config.feature_mask & CAM_QCOM_FEATURE_SCALE){
921                 //we only Scale Snapshot frame
922                 if(pStream->isTypeOf(CAM_STREAM_TYPE_SNAPSHOT)){
923                     //also check whether rotation is needed
924                     if((streamInfo->reprocess_config.pp_feature_config.feature_mask & CAM_QCOM_FEATURE_ROTATION) &&
925                        (streamInfo->reprocess_config.pp_feature_config.rotation == ROTATE_90 ||
926                         streamInfo->reprocess_config.pp_feature_config.rotation == ROTATE_270)){
927                         //need swap
928                         streamInfo->dim.width = streamInfo->reprocess_config.pp_feature_config.scale_param.output_height;
929                         streamInfo->dim.height = streamInfo->reprocess_config.pp_feature_config.scale_param.output_width;
930                     }else{
931                         streamInfo->dim.width = streamInfo->reprocess_config.pp_feature_config.scale_param.output_width;
932                         streamInfo->dim.height = streamInfo->reprocess_config.pp_feature_config.scale_param.output_height;
933                     }
934                 }
935                 CDBG_HIGH("%s: stream width=%d, height=%d.", __func__, streamInfo->dim.width, streamInfo->dim.height);
936             }
937 
938             // save source stream handler
939             mSrcStreamHandles[m_numStreams] = pStream->getMyHandle();
940 
941             // add reprocess stream
942             rc = addStream(allocator,
943                            pStreamInfoBuf, minStreamBufNum,
944                            paddingInfo,
945                            NULL, NULL, false);
946             if (rc != NO_ERROR) {
947                 ALOGE("%s: add reprocess stream failed, ret = %d", __func__, rc);
948                 break;
949             }
950         }
951     }
952 
953     if (rc == NO_ERROR) {
954         m_pSrcChannel = pSrcChannel;
955     }
956     return rc;
957 }
958 
959 /*===========================================================================
960  * FUNCTION   : getStreamBySrouceHandle
961  *
962  * DESCRIPTION: find reprocess stream by its source stream handle
963  *
964  * PARAMETERS :
965  *   @srcHandle : source stream handle
966  *
967  * RETURN     : ptr to reprocess stream if found. NULL if not found
968  *==========================================================================*/
getStreamBySrouceHandle(uint32_t srcHandle)969 QCameraStream * QCameraReprocessChannel::getStreamBySrouceHandle(uint32_t srcHandle)
970 {
971     QCameraStream *pStream = NULL;
972 
973     for (int i = 0; i < m_numStreams; i++) {
974         if (mSrcStreamHandles[i] == srcHandle) {
975             pStream = mStreams[i];
976             break;
977         }
978     }
979 
980     return pStream;
981 }
982 
983 /*===========================================================================
984  * FUNCTION   : stop
985  *
986  * DESCRIPTION: Unmap offline buffers and stop channel
987  *
988  * PARAMETERS : none
989  *
990  * RETURN     : int32_t type of status
991  *              NO_ERROR  -- success
992  *              none-zero failure code
993  *==========================================================================*/
stop()994 int32_t QCameraReprocessChannel::stop()
995 {
996     if (!mOfflineBuffers.empty()) {
997         QCameraStream *stream = NULL;
998         List<OfflineBuffer>::iterator it = mOfflineBuffers.begin();
999         int error = NO_ERROR;
1000         for( ; it != mOfflineBuffers.end(); it++) {
1001             stream = (*it).stream;
1002             if (NULL != stream) {
1003                 error = stream->unmapBuf((*it).type,
1004                                          (*it).index,
1005                                          -1);
1006                 if (NO_ERROR != error) {
1007                     ALOGE("%s: Error during offline buffer unmap %d",
1008                           __func__, error);
1009                 }
1010             }
1011         }
1012         mOfflineBuffers.clear();
1013     }
1014 
1015     return QCameraChannel::stop();
1016 }
1017 
1018 /*===========================================================================
1019  * FUNCTION   : doReprocessOffline
1020  *
1021  * DESCRIPTION: request to do offline reprocess on the frame
1022  *
1023  * PARAMETERS :
1024  *   @frame   : frame to be performed a reprocess
1025  *
1026  * RETURN     : int32_t type of status
1027  *              NO_ERROR  -- success
1028  *              none-zero failure code
1029  *==========================================================================*/
doReprocessOffline(mm_camera_super_buf_t * frame)1030 int32_t QCameraReprocessChannel::doReprocessOffline(
1031                 mm_camera_super_buf_t *frame)
1032 {
1033     int32_t rc = 0;
1034     OfflineBuffer mappedBuffer;
1035 
1036     if (m_numStreams < 1) {
1037         ALOGE("%s: No reprocess stream is created", __func__);
1038         return -1;
1039     }
1040     if (m_pSrcChannel == NULL) {
1041         ALOGE("%s: No source channel for reprocess", __func__);
1042         return -1;
1043     }
1044 
1045     if (frame == NULL) {
1046         ALOGE("%s: Invalid source frame", __func__);
1047         return BAD_VALUE;
1048     }
1049 
1050     // find meta data stream and index of meta data frame in the superbuf
1051     uint8_t meta_buf_index = -1;
1052     mm_camera_buf_def_t *meta_buf = NULL;
1053     QCameraStream *pStream = NULL;
1054     for (int i = 0; i < frame->num_bufs; i++) {
1055         pStream = m_pSrcChannel->getStreamByHandle(frame->bufs[i]->stream_id);
1056         if (pStream != NULL) {
1057             if (pStream->isTypeOf(CAM_STREAM_TYPE_METADATA)) {
1058                 meta_buf = frame->bufs[i];
1059                 break;
1060             }
1061         }
1062     }
1063 
1064     for (int i = 0; i < frame->num_bufs; i++) {
1065         pStream = getStreamBySrouceHandle(frame->bufs[i]->stream_id);
1066         if (pStream != NULL) {
1067             if (pStream->isTypeOf(CAM_STREAM_TYPE_METADATA)) {
1068                 continue;
1069             }
1070 
1071             meta_buf_index = 0;
1072             if (NULL != meta_buf) {
1073                 rc = pStream->mapBuf(CAM_MAPPING_BUF_TYPE_OFFLINE_META_BUF,
1074                                      meta_buf_index,
1075                                      -1,
1076                                      meta_buf->fd,
1077                                      meta_buf->frame_len);
1078                 if (NO_ERROR != rc ) {
1079                     ALOGE("%s : Error during metadata buffer mapping",
1080                           __func__);
1081                     break;
1082                 }
1083             }
1084             mappedBuffer.index = meta_buf_index;
1085             mappedBuffer.stream = pStream;
1086             mappedBuffer.type = CAM_MAPPING_BUF_TYPE_OFFLINE_META_BUF;
1087             mOfflineBuffers.push_back(mappedBuffer);
1088 
1089             int buf_index = 1;
1090             rc = pStream->mapBuf(CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF,
1091                                  buf_index,
1092                                  -1,
1093                                  frame->bufs[i]->fd,
1094                                  frame->bufs[i]->frame_len);
1095             if (NO_ERROR != rc ) {
1096                 ALOGE("%s : Error during reprocess input buffer mapping",
1097                       __func__);
1098                 break;
1099             }
1100             mappedBuffer.index = buf_index;
1101             mappedBuffer.stream = pStream;
1102             mappedBuffer.type = CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF;
1103             mOfflineBuffers.push_back(mappedBuffer);
1104 
1105             cam_stream_parm_buffer_t param;
1106             memset(&param, 0, sizeof(cam_stream_parm_buffer_t));
1107             param.type = CAM_STREAM_PARAM_TYPE_DO_REPROCESS;
1108             param.reprocess.buf_index = buf_index;
1109             param.reprocess.frame_pp_config.uv_upsample =
1110                             frame->bufs[i]->is_uv_subsampled;
1111             if (NULL != meta_buf) {
1112                 // we have meta data sent together with reprocess frame
1113                 param.reprocess.meta_present = 1;
1114                 param.reprocess.meta_buf_index = meta_buf_index;
1115                 uint32_t stream_id = frame->bufs[i]->stream_id;
1116                 QCameraStream *srcStream =
1117                         m_pSrcChannel->getStreamByHandle(stream_id);
1118                 metadata_buffer_t *pMetaData =
1119                         (metadata_buffer_t *)meta_buf->buffer;
1120                 if (NULL != pMetaData) {
1121                     cam_crop_data_t *crop = NULL;
1122                     if (IS_META_AVAILABLE(CAM_INTF_META_CROP_DATA, pMetaData)) {
1123                         crop = (cam_crop_data_t *)
1124                             POINTER_OF_META(CAM_INTF_META_CROP_DATA, pMetaData);
1125                     }
1126 
1127                     if ((NULL != crop) && (NULL != srcStream)) {
1128                         for (int j = 0; j < MAX_NUM_STREAMS; j++) {
1129                             if (crop->crop_info[j].stream_id ==
1130                                             srcStream->getMyServerID()) {
1131                                 param.reprocess.frame_pp_config.crop.crop_enabled = 1;
1132                                 param.reprocess.frame_pp_config.crop.input_crop =
1133                                         crop->crop_info[j].crop;
1134                                 break;
1135                             }
1136                         }
1137                     }
1138                 }
1139             }
1140             rc = pStream->setParameter(param);
1141             if (rc != NO_ERROR) {
1142                 ALOGE("%s: stream setParameter for reprocess failed",
1143                       __func__);
1144                 break;
1145             }
1146         }
1147     }
1148     return rc;
1149 }
1150 
1151 /*===========================================================================
1152  * FUNCTION   : doReprocess
1153  *
1154  * DESCRIPTION: request to do a reprocess on the frame
1155  *
1156  * PARAMETERS :
1157  *   @frame   : frame to be performed a reprocess
1158  *
1159  * RETURN     : int32_t type of status
1160  *              NO_ERROR  -- success
1161  *              none-zero failure code
1162  *==========================================================================*/
doReprocess(mm_camera_super_buf_t * frame)1163 int32_t QCameraReprocessChannel::doReprocess(mm_camera_super_buf_t *frame)
1164 {
1165     int32_t rc = 0;
1166     if (m_numStreams < 1) {
1167         ALOGE("%s: No reprocess stream is created", __func__);
1168         return -1;
1169     }
1170     if (m_pSrcChannel == NULL) {
1171         ALOGE("%s: No source channel for reprocess", __func__);
1172         return -1;
1173     }
1174 
1175     // find meta data stream and index of meta data frame in the superbuf
1176     QCameraStream *pMetaStream = NULL;
1177     uint8_t meta_buf_index = 0;
1178     for (int i = 0; i < frame->num_bufs; i++) {
1179         QCameraStream *pStream = m_pSrcChannel->getStreamByHandle(frame->bufs[i]->stream_id);
1180         if (pStream != NULL) {
1181             if (pStream->isTypeOf(CAM_STREAM_TYPE_METADATA)) {
1182                 meta_buf_index = frame->bufs[i]->buf_idx;
1183                 pMetaStream = pStream;
1184                 break;
1185             }
1186         }
1187     }
1188 
1189     for (int i = 0; i < frame->num_bufs; i++) {
1190         QCameraStream *pStream = getStreamBySrouceHandle(frame->bufs[i]->stream_id);
1191         if (pStream != NULL) {
1192             if (pStream->isTypeOf(CAM_STREAM_TYPE_METADATA)) {
1193                 // Skip metadata for reprocess now because PP module cannot handle meta data
1194                 // May need furthur discussion if Imaginglib need meta data
1195                 continue;
1196             }
1197 
1198             if (pStream->isTypeOf(CAM_STREAM_TYPE_POSTVIEW) ||
1199                 pStream->isTypeOf(CAM_STREAM_TYPE_PREVIEW)) {
1200                 // Skip postview: In non zsl case, dont want to send
1201                 // thumbnail through reprocess.
1202                 // Skip preview: for same reason in ZSL case
1203                 continue;
1204             }
1205 
1206             cam_stream_parm_buffer_t param;
1207             memset(&param, 0, sizeof(cam_stream_parm_buffer_t));
1208             param.type = CAM_STREAM_PARAM_TYPE_DO_REPROCESS;
1209             param.reprocess.buf_index = frame->bufs[i]->buf_idx;
1210             param.reprocess.frame_idx = frame->bufs[i]->frame_idx;
1211             param.reprocess.frame_pp_config.uv_upsample = frame->bufs[i]->is_uv_subsampled;
1212             if (pMetaStream != NULL) {
1213                 // we have meta data frame bundled, sent together with reprocess frame
1214                 param.reprocess.meta_present = 1;
1215                 param.reprocess.meta_stream_handle = pMetaStream->getMyServerID();
1216                 param.reprocess.meta_buf_index = meta_buf_index;
1217             }
1218             rc = pStream->setParameter(param);
1219             if (rc != NO_ERROR) {
1220                 ALOGE("%s: stream setParameter for reprocess failed", __func__);
1221                 break;
1222             }
1223         }
1224     }
1225     return rc;
1226 }
1227 
1228 /*===========================================================================
1229  * FUNCTION   : doReprocess
1230  *
1231  * DESCRIPTION: request to do a reprocess on the frame
1232  *
1233  * PARAMETERS :
1234  *   @buf_fd     : fd to the input buffer that needs reprocess
1235  *   @buf_lenght : length of the input buffer
1236  *   @ret_val    : result of reprocess.
1237  *                 Example: Could be faceID in case of register face image.
1238  *
1239  * RETURN     : int32_t type of status
1240  *              NO_ERROR  -- success
1241  *              none-zero failure code
1242  *==========================================================================*/
doReprocess(int buf_fd,uint32_t buf_length,int32_t & ret_val)1243 int32_t QCameraReprocessChannel::doReprocess(int buf_fd,
1244                                              uint32_t buf_length,
1245                                              int32_t &ret_val)
1246 {
1247     int32_t rc = 0;
1248     if (m_numStreams < 1) {
1249         ALOGE("%s: No reprocess stream is created", __func__);
1250         return -1;
1251     }
1252 
1253     uint32_t buf_idx = 0;
1254     for (int i = 0; i < m_numStreams; i++) {
1255         rc = mStreams[i]->mapBuf(CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF,
1256                                  buf_idx, -1,
1257                                  buf_fd, buf_length);
1258 
1259         if (rc == NO_ERROR) {
1260             cam_stream_parm_buffer_t param;
1261             memset(&param, 0, sizeof(cam_stream_parm_buffer_t));
1262             param.type = CAM_STREAM_PARAM_TYPE_DO_REPROCESS;
1263             param.reprocess.buf_index = buf_idx;
1264             rc = mStreams[i]->setParameter(param);
1265             if (rc == NO_ERROR) {
1266                 ret_val = param.reprocess.ret_val;
1267             }
1268             mStreams[i]->unmapBuf(CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF,
1269                                   buf_idx, -1);
1270         }
1271     }
1272     return rc;
1273 }
1274 
1275 }; // namespace qcamera
1276