• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* Copyright (c) 2012-2013, 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 
59     m_handle = 0;
60     m_numStreams = 0;
61     memset(mStreams, 0, sizeof(mStreams));
62 }
63 
64 /*===========================================================================
65  * FUNCTION   : QCameraChannel
66  *
67  * DESCRIPTION: default constrcutor of QCameraChannel
68  *
69  * PARAMETERS : none
70  *
71  * RETURN     : none
72  *==========================================================================*/
QCameraChannel()73 QCameraChannel::QCameraChannel()
74 {
75     m_camHandle = 0;
76     m_camOps = NULL;
77     m_bIsActive = false;
78 
79     m_handle = 0;
80     m_numStreams = 0;
81     memset(mStreams, 0, sizeof(mStreams));
82 }
83 
84 /*===========================================================================
85  * FUNCTION   : ~QCameraChannel
86  *
87  * DESCRIPTION: destructor of QCameraChannel
88  *
89  * PARAMETERS : none
90  *
91  * RETURN     : none
92  *==========================================================================*/
~QCameraChannel()93 QCameraChannel::~QCameraChannel()
94 {
95     if (m_bIsActive) {
96         stop();
97     }
98 
99     for (int i = 0; i < m_numStreams; i++) {
100         if (mStreams[i] != NULL) {
101             delete mStreams[i];
102             mStreams[i] = 0;
103         }
104     }
105     m_numStreams = 0;
106     m_camOps->delete_channel(m_camHandle, m_handle);
107     m_handle = 0;
108 }
109 
110 /*===========================================================================
111  * FUNCTION   : init
112  *
113  * DESCRIPTION: initialization of channel
114  *
115  * PARAMETERS :
116  *   @attr    : channel bundle attribute setting
117  *   @dataCB  : data notify callback
118  *   @userData: user data ptr
119  *
120  * RETURN     : int32_t type of status
121  *              NO_ERROR  -- success
122  *              none-zero failure code
123  *==========================================================================*/
init(mm_camera_channel_attr_t * attr,mm_camera_buf_notify_t dataCB,void * userData)124 int32_t QCameraChannel::init(mm_camera_channel_attr_t *attr,
125                              mm_camera_buf_notify_t dataCB,
126                              void *userData)
127 {
128     m_handle = m_camOps->add_channel(m_camHandle,
129                                       attr,
130                                       dataCB,
131                                       userData);
132     if (m_handle == 0) {
133         ALOGE("%s: Add channel failed", __func__);
134         return UNKNOWN_ERROR;
135     }
136     return NO_ERROR;
137 }
138 
139 /*===========================================================================
140  * FUNCTION   : addStream
141  *
142  * DESCRIPTION: add a stream into channel
143  *
144  * PARAMETERS :
145  *   @allocator      : stream related buffer allocator
146  *   @streamInfoBuf  : ptr to buf that constains stream info
147  *   @minStreamBufNum: number of stream buffers needed
148  *   @paddingInfo    : padding information
149  *   @stream_cb      : stream data notify callback
150  *   @userdata       : user data ptr
151  *
152  * RETURN     : int32_t type of status
153  *              NO_ERROR  -- success
154  *              none-zero failure code
155  *==========================================================================*/
addStream(QCameraAllocator & allocator,QCameraHeapMemory * streamInfoBuf,uint8_t minStreamBufNum,cam_padding_info_t * paddingInfo,stream_cb_routine stream_cb,void * userdata)156 int32_t QCameraChannel::addStream(QCameraAllocator &allocator,
157                                   QCameraHeapMemory *streamInfoBuf,
158                                   uint8_t minStreamBufNum,
159                                   cam_padding_info_t *paddingInfo,
160                                   stream_cb_routine stream_cb,
161                                   void *userdata)
162 {
163     int32_t rc = NO_ERROR;
164     if (m_numStreams >= MAX_STREAM_NUM_IN_BUNDLE) {
165         ALOGE("%s: stream number (%d) exceeds max limit (%d)",
166               __func__, m_numStreams, MAX_STREAM_NUM_IN_BUNDLE);
167         return BAD_VALUE;
168     }
169     QCameraStream *pStream = new QCameraStream(allocator,
170                                                m_camHandle,
171                                                m_handle,
172                                                m_camOps,
173                                                paddingInfo);
174     if (pStream == NULL) {
175         ALOGE("%s: No mem for Stream", __func__);
176         return NO_MEMORY;
177     }
178 
179     rc = pStream->init(streamInfoBuf, minStreamBufNum, stream_cb, userdata);
180     if (rc == 0) {
181         mStreams[m_numStreams] = pStream;
182         m_numStreams++;
183     } else {
184         delete pStream;
185     }
186     return rc;
187 }
188 
189 /*===========================================================================
190  * FUNCTION   : start
191  *
192  * DESCRIPTION: start channel, which will start all streams belong to this channel
193  *
194  * PARAMETERS : None
195  *
196  * RETURN     : int32_t type of status
197  *              NO_ERROR  -- success
198  *              none-zero failure code
199  *==========================================================================*/
start()200 int32_t QCameraChannel::start()
201 {
202     int32_t rc = NO_ERROR;
203 
204     if (m_numStreams > 1) {
205         // there is more than one stream in the channel
206         // we need to notify mctl that all streams in this channel need to be bundled
207         cam_bundle_config_t bundleInfo;
208         memset(&bundleInfo, 0, sizeof(bundleInfo));
209         rc = m_camOps->get_bundle_info(m_camHandle, m_handle, &bundleInfo);
210         if (rc != NO_ERROR) {
211             ALOGE("%s: get_bundle_info failed", __func__);
212             return rc;
213         }
214         if (bundleInfo.num_of_streams > 1) {
215             for (int i = 0; i < bundleInfo.num_of_streams; i++) {
216                 QCameraStream *pStream = getStreamByServerID(bundleInfo.stream_ids[i]);
217                 if (pStream != NULL) {
218                     if (pStream->isTypeOf(CAM_STREAM_TYPE_METADATA)) {
219                         // Skip metadata for reprocess now because PP module cannot handle meta data
220                         // May need furthur discussion if Imaginglib need meta data
221                         continue;
222                     }
223 
224                     cam_stream_parm_buffer_t param;
225                     memset(&param, 0, sizeof(cam_stream_parm_buffer_t));
226                     param.type = CAM_STREAM_PARAM_TYPE_SET_BUNDLE_INFO;
227                     param.bundleInfo = bundleInfo;
228                     rc = pStream->setParameter(param);
229                     if (rc != NO_ERROR) {
230                         ALOGE("%s: stream setParameter for set bundle failed", __func__);
231                         return rc;
232                     }
233                 }
234             }
235         }
236     }
237 
238     for (int i = 0; i < m_numStreams; i++) {
239         if (mStreams[i] != NULL) {
240             mStreams[i]->start();
241         }
242     }
243     rc = m_camOps->start_channel(m_camHandle, m_handle);
244 
245     if (rc != NO_ERROR) {
246         for (int i = 0; i < m_numStreams; i++) {
247             if (mStreams[i] != NULL) {
248                 mStreams[i]->stop();
249             }
250         }
251     } else {
252         m_bIsActive = true;
253     }
254 
255     return rc;
256 }
257 
258 /*===========================================================================
259  * FUNCTION   : stop
260  *
261  * DESCRIPTION: stop a channel, which will stop all streams belong to this channel
262  *
263  * PARAMETERS : none
264  *
265  * RETURN     : int32_t type of status
266  *              NO_ERROR  -- success
267  *              none-zero failure code
268  *==========================================================================*/
stop()269 int32_t QCameraChannel::stop()
270 {
271     int32_t rc = NO_ERROR;
272     rc = m_camOps->stop_channel(m_camHandle, m_handle);
273 
274     for (int i = 0; i < m_numStreams; i++) {
275         if (mStreams[i] != NULL) {
276             mStreams[i]->stop();
277         }
278     }
279 
280     m_bIsActive = false;
281     return rc;
282 }
283 
284 /*===========================================================================
285  * FUNCTION   : bufDone
286  *
287  * DESCRIPTION: return a stream buf back to kernel
288  *
289  * PARAMETERS :
290  *   @recvd_frame  : stream buf frame to be returned
291  *
292  * RETURN     : int32_t type of status
293  *              NO_ERROR  -- success
294  *              none-zero failure code
295  *==========================================================================*/
bufDone(mm_camera_super_buf_t * recvd_frame)296 int32_t QCameraChannel::bufDone(mm_camera_super_buf_t *recvd_frame)
297 {
298     int32_t rc = NO_ERROR;
299     for (int i = 0; i < recvd_frame->num_bufs; i++) {
300          if (recvd_frame->bufs[i] != NULL) {
301              for (int j = 0; j < m_numStreams; j++) {
302                  if (mStreams[j] != NULL &&
303                      mStreams[j]->getMyHandle() == recvd_frame->bufs[i]->stream_id) {
304                      rc = mStreams[j]->bufDone(recvd_frame->bufs[i]->buf_idx);
305                      break; // break loop j
306                  }
307              }
308          }
309     }
310 
311     return rc;
312 }
313 
314 /*===========================================================================
315  * FUNCTION   : processZoomDone
316  *
317  * DESCRIPTION: process zoom done event
318  *
319  * PARAMETERS :
320  *   @previewWindoe : ptr to preview window ops table, needed to set preview
321  *                    crop information
322  *   @crop_info     : crop info as a result of zoom operation
323  *
324  * RETURN     : int32_t type of status
325  *              NO_ERROR  -- success
326  *              none-zero failure code
327  *==========================================================================*/
processZoomDone(preview_stream_ops_t * previewWindow,cam_crop_data_t & crop_info)328 int32_t QCameraChannel::processZoomDone(preview_stream_ops_t *previewWindow,
329                                         cam_crop_data_t &crop_info)
330 {
331     int32_t rc = NO_ERROR;
332     for (int i = 0; i < m_numStreams; i++) {
333         if (mStreams[i] != NULL) {
334             rc = mStreams[i]->processZoomDone(previewWindow, crop_info);
335         }
336     }
337     return rc;
338 }
339 
340 /*===========================================================================
341  * FUNCTION   : getStreamByHandle
342  *
343  * DESCRIPTION: return stream object by stream handle
344  *
345  * PARAMETERS :
346  *   @streamHandle : stream handle
347  *
348  * RETURN     : stream object. NULL if not found
349  *==========================================================================*/
getStreamByHandle(uint32_t streamHandle)350 QCameraStream *QCameraChannel::getStreamByHandle(uint32_t streamHandle)
351 {
352     for (int i = 0; i < m_numStreams; i++) {
353         if (mStreams[i] != NULL && mStreams[i]->getMyHandle() == streamHandle) {
354             return mStreams[i];
355         }
356     }
357     return NULL;
358 }
359 
360 /*===========================================================================
361  * FUNCTION   : getStreamByServerID
362  *
363  * DESCRIPTION: return stream object by stream server ID from daemon
364  *
365  * PARAMETERS :
366  *   @serverID : stream server ID
367  *
368  * RETURN     : stream object. NULL if not found
369  *==========================================================================*/
getStreamByServerID(uint32_t serverID)370 QCameraStream *QCameraChannel::getStreamByServerID(uint32_t serverID)
371 {
372     for (int i = 0; i < m_numStreams; i++) {
373         if (mStreams[i] != NULL && mStreams[i]->getMyServerID() == serverID) {
374             return mStreams[i];
375         }
376     }
377     return NULL;
378 }
379 
380 /*===========================================================================
381  * FUNCTION   : getStreamByIndex
382  *
383  * DESCRIPTION: return stream object by index of streams in the channel
384  *
385  * PARAMETERS :
386  *   @index : index of stream in the channel
387  *
388  * RETURN     : stream object. NULL if not found
389  *==========================================================================*/
getStreamByIndex(uint8_t index)390 QCameraStream *QCameraChannel::getStreamByIndex(uint8_t index)
391 {
392     if (index < m_numStreams) {
393         return mStreams[index];
394     }
395     return NULL;
396 }
397 
398 /*===========================================================================
399  * FUNCTION   : QCameraPicChannel
400  *
401  * DESCRIPTION: constructor of QCameraPicChannel
402  *
403  * PARAMETERS :
404  *   @cam_handle : camera handle
405  *   @cam_ops    : ptr to camera ops table
406  *
407  * RETURN     : none
408  *==========================================================================*/
QCameraPicChannel(uint32_t cam_handle,mm_camera_ops_t * cam_ops)409 QCameraPicChannel::QCameraPicChannel(uint32_t cam_handle,
410                                      mm_camera_ops_t *cam_ops) :
411     QCameraChannel(cam_handle, cam_ops)
412 {
413 }
414 
415 /*===========================================================================
416  * FUNCTION   : QCameraPicChannel
417  *
418  * DESCRIPTION: default constructor of QCameraPicChannel
419  *
420  * PARAMETERS : none
421  *
422  * RETURN     : none
423  *==========================================================================*/
QCameraPicChannel()424 QCameraPicChannel::QCameraPicChannel()
425 {
426 }
427 
428 /*===========================================================================
429  * FUNCTION   : ~QCameraPicChannel
430  *
431  * DESCRIPTION: destructor of QCameraPicChannel
432  *
433  * PARAMETERS : none
434  *
435  * RETURN     : none
436  *==========================================================================*/
~QCameraPicChannel()437 QCameraPicChannel::~QCameraPicChannel()
438 {
439 }
440 
441 /*===========================================================================
442  * FUNCTION   : takePicture
443  *
444  * DESCRIPTION: send request for queued snapshot frames
445  *
446  * PARAMETERS :
447  *   @num_of_snapshot : number of snapshot frames requested
448  *
449  * RETURN     : int32_t type of status
450  *              NO_ERROR  -- success
451  *              none-zero failure code
452  *==========================================================================*/
takePicture(uint8_t num_of_snapshot)453 int32_t QCameraPicChannel::takePicture(uint8_t num_of_snapshot)
454 {
455     int32_t rc = m_camOps->request_super_buf(m_camHandle,
456                                              m_handle,
457                                              num_of_snapshot);
458     return rc;
459 }
460 
461 /*===========================================================================
462  * FUNCTION   : cancelPicture
463  *
464  * DESCRIPTION: cancel request for queued snapshot frames
465  *
466  * PARAMETERS : none
467  *
468  * RETURN     : int32_t type of status
469  *              NO_ERROR  -- success
470  *              none-zero failure code
471  *==========================================================================*/
cancelPicture()472 int32_t QCameraPicChannel::cancelPicture()
473 {
474     int32_t rc = m_camOps->cancel_super_buf_request(m_camHandle, m_handle);
475     return rc;
476 }
477 
478 /*===========================================================================
479  * FUNCTION   : QCameraVideoChannel
480  *
481  * DESCRIPTION: constructor of QCameraVideoChannel
482  *
483  * PARAMETERS :
484  *   @cam_handle : camera handle
485  *   @cam_ops    : ptr to camera ops table
486  *
487  * RETURN     : none
488  *==========================================================================*/
QCameraVideoChannel(uint32_t cam_handle,mm_camera_ops_t * cam_ops)489 QCameraVideoChannel::QCameraVideoChannel(uint32_t cam_handle,
490                                          mm_camera_ops_t *cam_ops) :
491     QCameraChannel(cam_handle, cam_ops)
492 {
493 }
494 
495 /*===========================================================================
496  * FUNCTION   : QCameraVideoChannel
497  *
498  * DESCRIPTION: default constructor of QCameraVideoChannel
499  *
500  * PARAMETERS : none
501  *
502  * RETURN     : none
503  *==========================================================================*/
QCameraVideoChannel()504 QCameraVideoChannel::QCameraVideoChannel()
505 {
506 }
507 
508 /*===========================================================================
509  * FUNCTION   : ~QCameraVideoChannel
510  *
511  * DESCRIPTION: destructor of QCameraVideoChannel
512  *
513  * PARAMETERS : none
514  *
515  * RETURN     : none
516  *==========================================================================*/
~QCameraVideoChannel()517 QCameraVideoChannel::~QCameraVideoChannel()
518 {
519 }
520 
521 /*===========================================================================
522  * FUNCTION   : releaseFrame
523  *
524  * DESCRIPTION: return video frame from app
525  *
526  * PARAMETERS :
527  *   @opaque     : ptr to video frame to be returned
528  *   @isMetaData : if frame is a metadata or real frame
529  *
530  * RETURN     : int32_t type of status
531  *              NO_ERROR  -- success
532  *              none-zero failure code
533  *==========================================================================*/
releaseFrame(const void * opaque,bool isMetaData)534 int32_t QCameraVideoChannel::releaseFrame(const void * opaque, bool isMetaData)
535 {
536     QCameraStream *pVideoStream = NULL;
537     for (int i = 0; i < m_numStreams; i++) {
538         if (mStreams[i] != NULL && mStreams[i]->isTypeOf(CAM_STREAM_TYPE_VIDEO)) {
539             pVideoStream = mStreams[i];
540             break;
541         }
542     }
543 
544     if (NULL == pVideoStream) {
545         ALOGE("%s: No video stream in the channel", __func__);
546         return BAD_VALUE;
547     }
548 
549     int32_t rc = pVideoStream->bufDone(opaque, isMetaData);
550     return rc;
551 }
552 
553 /*===========================================================================
554  * FUNCTION   : QCameraReprocessChannel
555  *
556  * DESCRIPTION: constructor of QCameraReprocessChannel
557  *
558  * PARAMETERS :
559  *   @cam_handle : camera handle
560  *   @cam_ops    : ptr to camera ops table
561  *   @pp_mask    : post-proccess feature mask
562  *
563  * RETURN     : none
564  *==========================================================================*/
QCameraReprocessChannel(uint32_t cam_handle,mm_camera_ops_t * cam_ops)565 QCameraReprocessChannel::QCameraReprocessChannel(uint32_t cam_handle,
566                                                  mm_camera_ops_t *cam_ops) :
567     QCameraChannel(cam_handle, cam_ops),
568     m_pSrcChannel(NULL)
569 {
570     memset(mSrcStreamHandles, 0, sizeof(mSrcStreamHandles));
571 }
572 
573 /*===========================================================================
574  * FUNCTION   : QCameraReprocessChannel
575  *
576  * DESCRIPTION: default constructor of QCameraReprocessChannel
577  *
578  * PARAMETERS : none
579  *
580  * RETURN     : none
581  *==========================================================================*/
QCameraReprocessChannel()582 QCameraReprocessChannel::QCameraReprocessChannel() :
583     m_pSrcChannel(NULL)
584 {
585 }
586 
587 /*===========================================================================
588  * FUNCTION   : ~QCameraReprocessChannel
589  *
590  * DESCRIPTION: destructor of QCameraReprocessChannel
591  *
592  * PARAMETERS : none
593  *
594  * RETURN     : none
595  *==========================================================================*/
~QCameraReprocessChannel()596 QCameraReprocessChannel::~QCameraReprocessChannel()
597 {
598 }
599 
600 /*===========================================================================
601  * FUNCTION   : addReprocStreamsFromSource
602  *
603  * DESCRIPTION: add reprocess streams from input source channel
604  *
605  * PARAMETERS :
606  *   @allocator      : stream related buffer allocator
607  *   @config         : pp feature configuration
608  *   @pSrcChannel    : ptr to input source channel that needs reprocess
609  *   @minStreamBufNum: number of stream buffers needed
610  *   @paddingInfo    : padding information
611  *
612  * RETURN     : int32_t type of status
613  *              NO_ERROR  -- success
614  *              none-zero failure code
615  *==========================================================================*/
addReprocStreamsFromSource(QCameraAllocator & allocator,cam_pp_feature_config_t & config,QCameraChannel * pSrcChannel,uint8_t minStreamBufNum,cam_padding_info_t * paddingInfo)616 int32_t QCameraReprocessChannel::addReprocStreamsFromSource(QCameraAllocator& allocator,
617                                                             cam_pp_feature_config_t &config,
618                                                             QCameraChannel *pSrcChannel,
619                                                             uint8_t minStreamBufNum,
620                                                             cam_padding_info_t *paddingInfo)
621 {
622     int32_t rc = 0;
623     QCameraStream *pStream = NULL;
624     QCameraHeapMemory *pStreamInfoBuf = NULL;
625     cam_stream_info_t *streamInfo = NULL;
626 
627     memset(mSrcStreamHandles, 0, sizeof(mSrcStreamHandles));
628 
629     for (int i = 0; i < pSrcChannel->getNumOfStreams(); i++) {
630         pStream = pSrcChannel->getStreamByIndex(i);
631         if (pStream != NULL) {
632             if (pStream->isTypeOf(CAM_STREAM_TYPE_METADATA)) {
633                 // Skip metadata for reprocess now because PP module cannot handle meta data
634                 // May need furthur discussion if Imaginglib need meta data
635                 continue;
636             }
637 
638             pStreamInfoBuf = allocator.allocateStreamInfoBuf(CAM_STREAM_TYPE_OFFLINE_PROC);
639             if (pStreamInfoBuf == NULL) {
640                 ALOGE("%s: no mem for stream info buf", __func__);
641                 rc = NO_MEMORY;
642                 break;
643             }
644 
645             streamInfo = (cam_stream_info_t *)pStreamInfoBuf->getPtr(0);
646             memset(streamInfo, 0, sizeof(cam_stream_info_t));
647             streamInfo->stream_type = CAM_STREAM_TYPE_OFFLINE_PROC;
648             rc = pStream->getFormat(streamInfo->fmt);
649             rc = pStream->getFrameDimension(streamInfo->dim);
650             streamInfo->streaming_mode = CAM_STREAMING_MODE_BURST;
651             streamInfo->num_of_burst = minStreamBufNum;
652 
653             streamInfo->reprocess_config.pp_type = CAM_ONLINE_REPROCESS_TYPE;
654             streamInfo->reprocess_config.online.input_stream_id = pStream->getMyServerID();
655             streamInfo->reprocess_config.online.input_stream_type = pStream->getMyType();
656             streamInfo->reprocess_config.pp_feature_config = config;
657 
658             if (!(pStream->isTypeOf(CAM_STREAM_TYPE_SNAPSHOT) ||
659                 pStream->isTypeOf(CAM_STREAM_TYPE_NON_ZSL_SNAPSHOT) ||
660                 pStream->isOrignalTypeOf(CAM_STREAM_TYPE_SNAPSHOT) ||
661                 pStream->isOrignalTypeOf(CAM_STREAM_TYPE_NON_ZSL_SNAPSHOT))) {
662                 streamInfo->reprocess_config.pp_feature_config.feature_mask &= ~CAM_QCOM_FEATURE_CAC;
663             }
664             if (streamInfo->reprocess_config.pp_feature_config.feature_mask & CAM_QCOM_FEATURE_ROTATION) {
665                 if (streamInfo->reprocess_config.pp_feature_config.rotation == ROTATE_90 ||
666                     streamInfo->reprocess_config.pp_feature_config.rotation == ROTATE_270) {
667                     // rotated by 90 or 270, need to switch width and height
668                     int32_t temp = streamInfo->dim.height;
669                     streamInfo->dim.height = streamInfo->dim.width;
670                     streamInfo->dim.width = temp;
671                 }
672             }
673 
674             // save source stream handler
675             mSrcStreamHandles[m_numStreams] = pStream->getMyHandle();
676 
677             // add reprocess stream
678             rc = addStream(allocator,
679                            pStreamInfoBuf, minStreamBufNum,
680                            paddingInfo,
681                            NULL, NULL);
682             if (rc != NO_ERROR) {
683                 ALOGE("%s: add reprocess stream failed, ret = %d", __func__, rc);
684                 break;
685             }
686         }
687     }
688 
689     if (rc == NO_ERROR) {
690         m_pSrcChannel = pSrcChannel;
691     }
692     return rc;
693 }
694 
695 /*===========================================================================
696  * FUNCTION   : getStreamBySrouceHandle
697  *
698  * DESCRIPTION: find reprocess stream by its source stream handle
699  *
700  * PARAMETERS :
701  *   @srcHandle : source stream handle
702  *
703  * RETURN     : ptr to reprocess stream if found. NULL if not found
704  *==========================================================================*/
getStreamBySrouceHandle(uint32_t srcHandle)705 QCameraStream * QCameraReprocessChannel::getStreamBySrouceHandle(uint32_t srcHandle)
706 {
707     QCameraStream *pStream = NULL;
708 
709     for (int i = 0; i < m_numStreams; i++) {
710         if (mSrcStreamHandles[i] == srcHandle) {
711             pStream = mStreams[i];
712             break;
713         }
714     }
715 
716     return pStream;
717 }
718 
719 /*===========================================================================
720  * FUNCTION   : doReprocess
721  *
722  * DESCRIPTION: request to do a reprocess on the frame
723  *
724  * PARAMETERS :
725  *   @frame   : frame to be performed a reprocess
726  *
727  * RETURN     : int32_t type of status
728  *              NO_ERROR  -- success
729  *              none-zero failure code
730  *==========================================================================*/
doReprocess(mm_camera_super_buf_t * frame)731 int32_t QCameraReprocessChannel::doReprocess(mm_camera_super_buf_t *frame)
732 {
733     int32_t rc = 0;
734     if (m_numStreams < 1) {
735         ALOGE("%s: No reprocess stream is created", __func__);
736         return -1;
737     }
738     if (m_pSrcChannel == NULL) {
739         ALOGE("%s: No source channel for reprocess", __func__);
740         return -1;
741     }
742 
743     // find meta data stream and index of meta data frame in the superbuf
744     QCameraStream *pMetaStream = NULL;
745     uint8_t meta_buf_index = 0;
746     for (int i = 0; i < frame->num_bufs; i++) {
747         QCameraStream *pStream = m_pSrcChannel->getStreamByHandle(frame->bufs[i]->stream_id);
748         if (pStream != NULL) {
749             if (pStream->isTypeOf(CAM_STREAM_TYPE_METADATA)) {
750                 meta_buf_index = frame->bufs[i]->buf_idx;
751                 pMetaStream = pStream;
752                 break;
753             }
754         }
755     }
756 
757     for (int i = 0; i < frame->num_bufs; i++) {
758         QCameraStream *pStream = getStreamBySrouceHandle(frame->bufs[i]->stream_id);
759         if (pStream != NULL) {
760             if (pStream->isTypeOf(CAM_STREAM_TYPE_METADATA)) {
761                 // Skip metadata for reprocess now because PP module cannot handle meta data
762                 // May need furthur discussion if Imaginglib need meta data
763                 continue;
764             }
765 
766             cam_stream_parm_buffer_t param;
767             memset(&param, 0, sizeof(cam_stream_parm_buffer_t));
768             param.type = CAM_STREAM_PARAM_TYPE_DO_REPROCESS;
769             param.reprocess.buf_index = frame->bufs[i]->buf_idx;
770             param.reprocess.frame_idx = frame->bufs[i]->frame_idx;
771             if (pMetaStream != NULL) {
772                 // we have meta data frame bundled, sent together with reprocess frame
773                 param.reprocess.meta_present = 1;
774                 param.reprocess.meta_stream_handle = pMetaStream->getMyServerID();
775                 param.reprocess.meta_buf_index = meta_buf_index;
776             }
777             rc = pStream->setParameter(param);
778             if (rc != NO_ERROR) {
779                 ALOGE("%s: stream setParameter for reprocess failed", __func__);
780                 break;
781             }
782         }
783     }
784     return rc;
785 }
786 
787 /*===========================================================================
788  * FUNCTION   : doReprocess
789  *
790  * DESCRIPTION: request to do a reprocess on the frame
791  *
792  * PARAMETERS :
793  *   @buf_fd     : fd to the input buffer that needs reprocess
794  *   @buf_lenght : length of the input buffer
795  *   @ret_val    : result of reprocess.
796  *                 Example: Could be faceID in case of register face image.
797  *
798  * RETURN     : int32_t type of status
799  *              NO_ERROR  -- success
800  *              none-zero failure code
801  *==========================================================================*/
doReprocess(int buf_fd,uint32_t buf_length,int32_t & ret_val)802 int32_t QCameraReprocessChannel::doReprocess(int buf_fd,
803                                              uint32_t buf_length,
804                                              int32_t &ret_val)
805 {
806     int32_t rc = 0;
807     if (m_numStreams < 1) {
808         ALOGE("%s: No reprocess stream is created", __func__);
809         return -1;
810     }
811 
812     uint32_t buf_idx = 0;
813     for (int i = 0; i < m_numStreams; i++) {
814         rc = mStreams[i]->mapBuf(CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF,
815                                  buf_idx, -1,
816                                  buf_fd, buf_length);
817 
818         if (rc == NO_ERROR) {
819             cam_stream_parm_buffer_t param;
820             memset(&param, 0, sizeof(cam_stream_parm_buffer_t));
821             param.type = CAM_STREAM_PARAM_TYPE_DO_REPROCESS;
822             param.reprocess.buf_index = buf_idx;
823             rc = mStreams[i]->setParameter(param);
824             if (rc == NO_ERROR) {
825                 ret_val = param.reprocess.ret_val;
826             }
827             mStreams[i]->unmapBuf(CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF,
828                                   buf_idx, -1);
829         }
830     }
831     return rc;
832 }
833 
834 }; // namespace qcamera
835