Home | History | Annotate | Download | only in HAL
      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  *==========================================================================*/
     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  *==========================================================================*/
     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  *==========================================================================*/
     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  *==========================================================================*/
    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  *==========================================================================*/
    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  *==========================================================================*/
    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  *==========================================================================*/
    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  *==========================================================================*/
    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  *==========================================================================*/
    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  *==========================================================================*/
    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  *==========================================================================*/
    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  *==========================================================================*/
    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  *==========================================================================*/
    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  *==========================================================================*/
    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  *==========================================================================*/
    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  *==========================================================================*/
    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  *==========================================================================*/
    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  *==========================================================================*/
    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  *==========================================================================*/
    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  *==========================================================================*/
    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  *==========================================================================*/
    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  *==========================================================================*/
    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  *==========================================================================*/
    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  *==========================================================================*/
    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  *==========================================================================*/
    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  *==========================================================================*/
    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  *==========================================================================*/
    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  *==========================================================================*/
    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