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