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