Home | History | Annotate | Download | only in HAL
      1 /* Copyright (c) 2012-2013, The Linux Foundataion. All rights reserved.
      2 *
      3 * Redistribution and use in source and binary forms, with or without
      4 * modification, are permitted provided that the following conditions are
      5 * met:
      6 *     * Redistributions of source code must retain the above copyright
      7 *       notice, this list of conditions and the following disclaimer.
      8 *     * Redistributions in binary form must reproduce the above
      9 *       copyright notice, this list of conditions and the following
     10 *       disclaimer in the documentation and/or other materials provided
     11 *       with the distribution.
     12 *     * Neither the name of The Linux Foundation nor the names of its
     13 *       contributors may be used to endorse or promote products derived
     14 *       from this software without specific prior written permission.
     15 *
     16 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
     17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
     18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
     19 * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
     20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
     23 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
     24 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
     25 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
     26 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     27 *
     28 */
     29 
     30 #define LOG_TAG "QCameraStream"
     31 
     32 #include <utils/Errors.h>
     33 #include "QCamera2HWI.h"
     34 #include "QCameraStream.h"
     35 
     36 namespace qcamera {
     37 
     38 /*===========================================================================
     39  * FUNCTION   : get_bufs
     40  *
     41  * DESCRIPTION: static function entry to allocate stream buffers
     42  *
     43  * PARAMETERS :
     44  *   @offset     : offset info of stream buffers
     45  *   @num_bufs   : number of buffers allocated
     46  *   @initial_reg_flag: flag to indicate if buffer needs to be registered
     47  *                      at kernel initially
     48  *   @bufs       : output of allocated buffers
     49  *   @ops_tbl    : ptr to buf mapping/unmapping ops
     50  *   @user_data  : user data ptr of ops_tbl
     51  *
     52  * RETURN     : int32_t type of status
     53  *              NO_ERROR  -- success
     54  *              none-zero failure code
     55  *==========================================================================*/
     56 int32_t QCameraStream::get_bufs(
     57                      cam_frame_len_offset_t *offset,
     58                      uint8_t *num_bufs,
     59                      uint8_t **initial_reg_flag,
     60                      mm_camera_buf_def_t **bufs,
     61                      mm_camera_map_unmap_ops_tbl_t *ops_tbl,
     62                      void *user_data)
     63 {
     64     QCameraStream *stream = reinterpret_cast<QCameraStream *>(user_data);
     65     if (!stream) {
     66         ALOGE("getBufs invalid stream pointer");
     67         return NO_MEMORY;
     68     }
     69     return stream->getBufs(offset, num_bufs, initial_reg_flag, bufs, ops_tbl);
     70 }
     71 
     72 /*===========================================================================
     73  * FUNCTION   : put_bufs
     74  *
     75  * DESCRIPTION: static function entry to deallocate stream buffers
     76  *
     77  * PARAMETERS :
     78  *   @ops_tbl    : ptr to buf mapping/unmapping ops
     79  *   @user_data  : user data ptr of ops_tbl
     80  *
     81  * RETURN     : int32_t type of status
     82  *              NO_ERROR  -- success
     83  *              none-zero failure code
     84  *==========================================================================*/
     85 int32_t QCameraStream::put_bufs(
     86                      mm_camera_map_unmap_ops_tbl_t *ops_tbl,
     87                      void *user_data)
     88 {
     89     QCameraStream *stream = reinterpret_cast<QCameraStream *>(user_data);
     90     if (!stream) {
     91         ALOGE("putBufs invalid stream pointer");
     92         return NO_MEMORY;
     93     }
     94     return stream->putBufs(ops_tbl);
     95 }
     96 
     97 /*===========================================================================
     98  * FUNCTION   : invalidate_buf
     99  *
    100  * DESCRIPTION: static function entry to invalidate a specific stream buffer
    101  *
    102  * PARAMETERS :
    103  *   @index      : index of the stream buffer to invalidate
    104  *   @user_data  : user data ptr of ops_tbl
    105  *
    106  * RETURN     : int32_t type of status
    107  *              NO_ERROR  -- success
    108  *              none-zero failure code
    109  *==========================================================================*/
    110 int32_t QCameraStream::invalidate_buf(int index, void *user_data)
    111 {
    112     QCameraStream *stream = reinterpret_cast<QCameraStream *>(user_data);
    113     if (!stream) {
    114         ALOGE("invalid stream pointer");
    115         return NO_MEMORY;
    116     }
    117     return stream->invalidateBuf(index);
    118 }
    119 
    120 /*===========================================================================
    121  * FUNCTION   : clean_invalidate_buf
    122  *
    123  * DESCRIPTION: static function entry to clean invalidate a specific stream buffer
    124  *
    125  * PARAMETERS :
    126  *   @index      : index of the stream buffer to clean invalidate
    127  *   @user_data  : user data ptr of ops_tbl
    128  *
    129  * RETURN     : int32_t type of status
    130  *              NO_ERROR  -- success
    131  *              none-zero failure code
    132  *==========================================================================*/
    133 int32_t QCameraStream::clean_invalidate_buf(int index, void *user_data)
    134 {
    135     QCameraStream *stream = reinterpret_cast<QCameraStream *>(user_data);
    136     if (!stream) {
    137         ALOGE("invalid stream pointer");
    138         return NO_MEMORY;
    139     }
    140     return stream->cleanInvalidateBuf(index);
    141 }
    142 
    143 /*===========================================================================
    144  * FUNCTION   : QCameraStream
    145  *
    146  * DESCRIPTION: constructor of QCameraStream
    147  *
    148  * PARAMETERS :
    149  *   @allocator  : memory allocator obj
    150  *   @camHandle  : camera handle
    151  *   @chId       : channel handle
    152  *   @camOps     : ptr to camera ops table
    153  *   @paddingInfo: ptr to padding info
    154  *
    155  * RETURN     : None
    156  *==========================================================================*/
    157 QCameraStream::QCameraStream(QCameraAllocator &allocator,
    158                              uint32_t camHandle,
    159                              uint32_t chId,
    160                              mm_camera_ops_t *camOps,
    161                              cam_padding_info_t *paddingInfo) :
    162         mCamHandle(camHandle),
    163         mChannelHandle(chId),
    164         mHandle(0),
    165         mCamOps(camOps),
    166         mStreamInfo(NULL),
    167         mNumBufs(0),
    168         mDataCB(NULL),
    169         mStreamInfoBuf(NULL),
    170         mStreamBufs(NULL),
    171         mAllocator(allocator),
    172         mBufDefs(NULL)
    173 {
    174     mMemVtbl.user_data = this;
    175     mMemVtbl.get_bufs = get_bufs;
    176     mMemVtbl.put_bufs = put_bufs;
    177     mMemVtbl.invalidate_buf = invalidate_buf;
    178     mMemVtbl.clean_invalidate_buf = clean_invalidate_buf;
    179     memset(&mFrameLenOffset, 0, sizeof(mFrameLenOffset));
    180     memcpy(&mPaddingInfo, paddingInfo, sizeof(cam_padding_info_t));
    181     memset(&mCropInfo, 0, sizeof(cam_rect_t));
    182     pthread_mutex_init(&mCropLock, NULL);
    183 }
    184 
    185 /*===========================================================================
    186  * FUNCTION   : ~QCameraStream
    187  *
    188  * DESCRIPTION: deconstructor of QCameraStream
    189  *
    190  * PARAMETERS : None
    191  *
    192  * RETURN     : None
    193  *==========================================================================*/
    194 QCameraStream::~QCameraStream()
    195 {
    196     pthread_mutex_destroy(&mCropLock);
    197 
    198     if (mStreamInfoBuf != NULL) {
    199         int rc = mCamOps->unmap_stream_buf(mCamHandle,
    200                     mChannelHandle, mHandle, CAM_MAPPING_BUF_TYPE_STREAM_INFO, 0, -1);
    201         if (rc < 0) {
    202             ALOGE("Failed to map stream info buffer");
    203         }
    204         mStreamInfoBuf->deallocate();
    205         delete mStreamInfoBuf;
    206         mStreamInfoBuf = NULL;
    207     }
    208 
    209     // delete stream
    210     if (mHandle > 0) {
    211         mCamOps->delete_stream(mCamHandle, mChannelHandle, mHandle);
    212         mHandle = 0;
    213     }
    214 }
    215 
    216 /*===========================================================================
    217  * FUNCTION   : init
    218  *
    219  * DESCRIPTION: initialize stream obj
    220  *
    221  * PARAMETERS :
    222  *   @streamInfoBuf: ptr to buf that contains stream info
    223  *   @stream_cb    : stream data notify callback. Can be NULL if not needed
    224  *   @userdata     : user data ptr
    225  *
    226  * RETURN     : int32_t type of status
    227  *              NO_ERROR  -- success
    228  *              none-zero failure code
    229  *==========================================================================*/
    230 int32_t QCameraStream::init(QCameraHeapMemory *streamInfoBuf,
    231                             uint8_t minNumBuffers,
    232                             stream_cb_routine stream_cb,
    233                             void *userdata)
    234 {
    235     int32_t rc = OK;
    236     mm_camera_stream_config_t stream_config;
    237 
    238     mHandle = mCamOps->add_stream(mCamHandle, mChannelHandle);
    239     if (!mHandle) {
    240         ALOGE("add_stream failed");
    241         rc = UNKNOWN_ERROR;
    242         goto done;
    243     }
    244 
    245     // assign and map stream info memory
    246     mStreamInfoBuf = streamInfoBuf;
    247     mStreamInfo = reinterpret_cast<cam_stream_info_t *>(mStreamInfoBuf->getPtr(0));
    248     mNumBufs = minNumBuffers;
    249 
    250     rc = mCamOps->map_stream_buf(mCamHandle,
    251                 mChannelHandle, mHandle, CAM_MAPPING_BUF_TYPE_STREAM_INFO,
    252                 0, -1, mStreamInfoBuf->getFd(0), mStreamInfoBuf->getSize(0));
    253     if (rc < 0) {
    254         ALOGE("Failed to map stream info buffer");
    255         goto err1;
    256     }
    257 
    258     // Configure the stream
    259     stream_config.stream_info = mStreamInfo;
    260     stream_config.mem_vtbl = mMemVtbl;
    261     stream_config.stream_cb = dataNotifyCB;
    262     stream_config.padding_info = mPaddingInfo;
    263     stream_config.userdata = this;
    264     rc = mCamOps->config_stream(mCamHandle,
    265                 mChannelHandle, mHandle, &stream_config);
    266     if (rc < 0) {
    267         ALOGE("Failed to config stream, rc = %d", rc);
    268         goto err2;
    269     }
    270 
    271     mDataCB = stream_cb;
    272     mUserData = userdata;
    273     return 0;
    274 
    275 err2:
    276     mCamOps->unmap_stream_buf(mCamHandle,
    277                 mChannelHandle, mHandle, CAM_MAPPING_BUF_TYPE_STREAM_INFO, 0, -1);
    278 err1:
    279     mCamOps->delete_stream(mCamHandle, mChannelHandle, mHandle);
    280     mHandle = 0;
    281     mStreamInfoBuf = NULL;
    282     mStreamInfo = NULL;
    283     mNumBufs = 0;
    284 done:
    285     return rc;
    286 }
    287 
    288 /*===========================================================================
    289  * FUNCTION   : start
    290  *
    291  * DESCRIPTION: start stream. Will start main stream thread to handle stream
    292  *              related ops.
    293  *
    294  * PARAMETERS : none
    295  *
    296  * RETURN     : int32_t type of status
    297  *              NO_ERROR  -- success
    298  *              none-zero failure code
    299  *==========================================================================*/
    300 int32_t QCameraStream::start()
    301 {
    302     int32_t rc = 0;
    303     rc = mProcTh.launch(dataProcRoutine, this);
    304     return rc;
    305 }
    306 
    307 /*===========================================================================
    308  * FUNCTION   : stop
    309  *
    310  * DESCRIPTION: stop stream. Will stop main stream thread
    311  *
    312  * PARAMETERS : none
    313  *
    314  * RETURN     : int32_t type of status
    315  *              NO_ERROR  -- success
    316  *              none-zero failure code
    317  *==========================================================================*/
    318 int32_t QCameraStream::stop()
    319 {
    320     int32_t rc = 0;
    321     rc = mProcTh.exit();
    322     return rc;
    323 }
    324 
    325 /*===========================================================================
    326  * FUNCTION   : processZoomDone
    327  *
    328  * DESCRIPTION: process zoom done event
    329  *
    330  * PARAMETERS :
    331  *   @previewWindoe : preview window ops table to set preview crop window
    332  *   @crop_info     : crop info
    333  *
    334  * RETURN     : int32_t type of status
    335  *              NO_ERROR  -- success
    336  *              none-zero failure code
    337  *==========================================================================*/
    338 int32_t QCameraStream::processZoomDone(preview_stream_ops_t *previewWindow,
    339                                        cam_crop_data_t &crop_info)
    340 {
    341     int32_t rc = 0;
    342 
    343     // get stream param for crop info
    344     for (int i = 0; i < crop_info.num_of_streams; i++) {
    345         if (crop_info.crop_info[i].stream_id == mStreamInfo->stream_svr_id) {
    346             pthread_mutex_lock(&mCropLock);
    347             mCropInfo = crop_info.crop_info[i].crop;
    348             pthread_mutex_unlock(&mCropLock);
    349 
    350             // update preview window crop if it's preview/postview stream
    351             if ( (previewWindow != NULL) &&
    352                  (mStreamInfo->stream_type == CAM_STREAM_TYPE_PREVIEW ||
    353                   mStreamInfo->stream_type == CAM_STREAM_TYPE_POSTVIEW) ) {
    354                 rc = previewWindow->set_crop(previewWindow,
    355                                              mCropInfo.left,
    356                                              mCropInfo.top,
    357                                              mCropInfo.width,
    358                                              mCropInfo.height);
    359             }
    360             break;
    361         }
    362     }
    363     return rc;
    364 }
    365 
    366 /*===========================================================================
    367  * FUNCTION   : processDataNotify
    368  *
    369  * DESCRIPTION: process stream data notify
    370  *
    371  * PARAMETERS :
    372  *   @frame   : stream frame received
    373  *
    374  * RETURN     : int32_t type of status
    375  *              NO_ERROR  -- success
    376  *              none-zero failure code
    377  *==========================================================================*/
    378 int32_t QCameraStream::processDataNotify(mm_camera_super_buf_t *frame)
    379 {
    380     ALOGI("%s:\n", __func__);
    381     mDataQ.enqueue((void *)frame);
    382     return mProcTh.sendCmd(CAMERA_CMD_TYPE_DO_NEXT_JOB, FALSE, FALSE);
    383 }
    384 
    385 /*===========================================================================
    386  * FUNCTION   : dataNotifyCB
    387  *
    388  * DESCRIPTION: callback for data notify. This function is registered with
    389  *              mm-camera-interface to handle data notify
    390  *
    391  * PARAMETERS :
    392  *   @recvd_frame   : stream frame received
    393  *   userdata       : user data ptr
    394  *
    395  * RETURN     : none
    396  *==========================================================================*/
    397 void QCameraStream::dataNotifyCB(mm_camera_super_buf_t *recvd_frame,
    398                                  void *userdata)
    399 {
    400     ALOGI("%s:\n", __func__);
    401     QCameraStream* stream = (QCameraStream *)userdata;
    402     if (stream == NULL ||
    403         recvd_frame == NULL ||
    404         recvd_frame->bufs[0] == NULL ||
    405         recvd_frame->bufs[0]->stream_id != stream->getMyHandle()) {
    406         ALOGE("%s: Not a valid stream to handle buf", __func__);
    407         return;
    408     }
    409 
    410     mm_camera_super_buf_t *frame =
    411         (mm_camera_super_buf_t *)malloc(sizeof(mm_camera_super_buf_t));
    412     if (frame == NULL) {
    413         ALOGE("%s: No mem for mm_camera_buf_def_t", __func__);
    414         stream->bufDone(recvd_frame->bufs[0]->buf_idx);
    415         return;
    416     }
    417     *frame = *recvd_frame;
    418     stream->processDataNotify(frame);
    419     return;
    420 }
    421 
    422 /*===========================================================================
    423  * FUNCTION   : dataProcRoutine
    424  *
    425  * DESCRIPTION: function to process data in the main stream thread
    426  *
    427  * PARAMETERS :
    428  *   @data    : user data ptr
    429  *
    430  * RETURN     : none
    431  *==========================================================================*/
    432 void *QCameraStream::dataProcRoutine(void *data)
    433 {
    434     int running = 1;
    435     int ret;
    436     QCameraStream *pme = (QCameraStream *)data;
    437     QCameraCmdThread *cmdThread = &pme->mProcTh;
    438 
    439     ALOGI("%s: E", __func__);
    440     do {
    441         do {
    442             ret = cam_sem_wait(&cmdThread->cmd_sem);
    443             if (ret != 0 && errno != EINVAL) {
    444                 ALOGE("%s: cam_sem_wait error (%s)",
    445                       __func__, strerror(errno));
    446                 return NULL;
    447             }
    448         } while (ret != 0);
    449 
    450         // we got notified about new cmd avail in cmd queue
    451         camera_cmd_type_t cmd = cmdThread->getCmd();
    452         switch (cmd) {
    453         case CAMERA_CMD_TYPE_DO_NEXT_JOB:
    454             {
    455                 ALOGD("%s: Do next job", __func__);
    456                 mm_camera_super_buf_t *frame =
    457                     (mm_camera_super_buf_t *)pme->mDataQ.dequeue();
    458                 if (NULL != frame) {
    459                     if (pme->mDataCB != NULL) {
    460                         pme->mDataCB(frame, pme, pme->mUserData);
    461                     } else {
    462                         // no data cb routine, return buf here
    463                         pme->bufDone(frame->bufs[0]->buf_idx);
    464                         free(frame);
    465                     }
    466                 }
    467             }
    468             break;
    469         case CAMERA_CMD_TYPE_EXIT:
    470             ALOGD("%s: Exit", __func__);
    471             /* flush data buf queue */
    472             pme->mDataQ.flush();
    473             running = 0;
    474             break;
    475         default:
    476             break;
    477         }
    478     } while (running);
    479     ALOGD("%s: X", __func__);
    480     return NULL;
    481 }
    482 
    483 /*===========================================================================
    484  * FUNCTION   : bufDone
    485  *
    486  * DESCRIPTION: return stream buffer to kernel
    487  *
    488  * PARAMETERS :
    489  *   @index   : index of buffer to be returned
    490  *
    491  * RETURN     : int32_t type of status
    492  *              NO_ERROR  -- success
    493  *              none-zero failure code
    494  *==========================================================================*/
    495 int32_t QCameraStream::bufDone(int index)
    496 {
    497     int32_t rc = NO_ERROR;
    498 
    499     if (index >= mNumBufs || mBufDefs == NULL)
    500         return BAD_INDEX;
    501 
    502     rc = mCamOps->qbuf(mCamHandle, mChannelHandle, &mBufDefs[index]);
    503     if (rc < 0)
    504         return rc;
    505 
    506     return rc;
    507 }
    508 
    509 /*===========================================================================
    510  * FUNCTION   : bufDone
    511  *
    512  * DESCRIPTION: return stream buffer to kernel
    513  *
    514  * PARAMETERS :
    515  *   @opaque    : stream frame/metadata buf to be returned
    516  *   @isMetaData: flag if returned opaque is a metadatabuf or the real frame ptr
    517  *
    518  * RETURN     : int32_t type of status
    519  *              NO_ERROR  -- success
    520  *              none-zero failure code
    521  *==========================================================================*/
    522 int32_t QCameraStream::bufDone(const void *opaque, bool isMetaData)
    523 {
    524     int32_t rc = NO_ERROR;
    525 
    526     int index = mStreamBufs->getMatchBufIndex(opaque, isMetaData);
    527     if (index == -1 || index >= mNumBufs || mBufDefs == NULL) {
    528         ALOGE("%s: Cannot find buf for opaque data = %p", __func__, opaque);
    529         return BAD_INDEX;
    530     }
    531     ALOGD("%s: Buffer Index = %d, Frame Idx = %d", __func__, index, mBufDefs[index].frame_idx);
    532     rc = bufDone(index);
    533     return rc;
    534 }
    535 
    536 /*===========================================================================
    537  * FUNCTION   : getBufs
    538  *
    539  * DESCRIPTION: allocate stream buffers
    540  *
    541  * PARAMETERS :
    542  *   @offset     : offset info of stream buffers
    543  *   @num_bufs   : number of buffers allocated
    544  *   @initial_reg_flag: flag to indicate if buffer needs to be registered
    545  *                      at kernel initially
    546  *   @bufs       : output of allocated buffers
    547  *   @ops_tbl    : ptr to buf mapping/unmapping ops
    548  *
    549  * RETURN     : int32_t type of status
    550  *              NO_ERROR  -- success
    551  *              none-zero failure code
    552  *==========================================================================*/
    553 int32_t QCameraStream::getBufs(cam_frame_len_offset_t *offset,
    554                      uint8_t *num_bufs,
    555                      uint8_t **initial_reg_flag,
    556                      mm_camera_buf_def_t **bufs,
    557                      mm_camera_map_unmap_ops_tbl_t *ops_tbl)
    558 {
    559     int rc = NO_ERROR;
    560     uint8_t *regFlags;
    561 
    562     if (!ops_tbl) {
    563         ALOGE("%s: ops_tbl is NULL", __func__);
    564         return INVALID_OPERATION;
    565     }
    566 
    567     mFrameLenOffset = *offset;
    568 
    569     //Allocate and map stream info buffer
    570     mStreamBufs = mAllocator.allocateStreamBuf(mStreamInfo->stream_type,
    571                                                mFrameLenOffset.frame_len,
    572                                                mNumBufs);
    573     if (!mStreamBufs) {
    574         ALOGE("%s: Failed to allocate stream buffers", __func__);
    575         return NO_MEMORY;
    576     }
    577 
    578     for (int i = 0; i < mNumBufs; i++) {
    579         rc = ops_tbl->map_ops(i, -1, mStreamBufs->getFd(i),
    580                 mStreamBufs->getSize(i), ops_tbl->userdata);
    581         if (rc < 0) {
    582             ALOGE("%s: map_stream_buf failed: %d", __func__, rc);
    583             for (int j = 0; j < i; j++) {
    584                 ops_tbl->unmap_ops(j, -1, ops_tbl->userdata);
    585             }
    586             mStreamBufs->deallocate();
    587             delete mStreamBufs;
    588             mStreamBufs = NULL;
    589             return INVALID_OPERATION;
    590         }
    591     }
    592 
    593     //regFlags array is allocated by us, but consumed and freed by mm-camera-interface
    594     regFlags = (uint8_t *)malloc(sizeof(uint8_t) * mNumBufs);
    595     if (!regFlags) {
    596         ALOGE("%s: Out of memory", __func__);
    597         for (int i = 0; i < mNumBufs; i++) {
    598             ops_tbl->unmap_ops(i, -1, ops_tbl->userdata);
    599         }
    600         mStreamBufs->deallocate();
    601         delete mStreamBufs;
    602         mStreamBufs = NULL;
    603         return NO_MEMORY;
    604     }
    605 
    606     mBufDefs = (mm_camera_buf_def_t *)malloc(mNumBufs * sizeof(mm_camera_buf_def_t));
    607     if (mBufDefs == NULL) {
    608         ALOGE("%s: getRegFlags failed %d", __func__, rc);
    609         for (int i = 0; i < mNumBufs; i++) {
    610             ops_tbl->unmap_ops(i, -1, ops_tbl->userdata);
    611         }
    612         mStreamBufs->deallocate();
    613         delete mStreamBufs;
    614         mStreamBufs = NULL;
    615         free(regFlags);
    616         regFlags = NULL;
    617         return INVALID_OPERATION;
    618     }
    619     for (int i = 0; i < mNumBufs; i++) {
    620         mStreamBufs->getBufDef(mFrameLenOffset, mBufDefs[i], i);
    621     }
    622 
    623     rc = mStreamBufs->getRegFlags(regFlags);
    624     if (rc < 0) {
    625         ALOGE("%s: getRegFlags failed %d", __func__, rc);
    626         for (int i = 0; i < mNumBufs; i++) {
    627             ops_tbl->unmap_ops(i, -1, ops_tbl->userdata);
    628         }
    629         mStreamBufs->deallocate();
    630         delete mStreamBufs;
    631         mStreamBufs = NULL;
    632         free(mBufDefs);
    633         mBufDefs = NULL;
    634         free(regFlags);
    635         regFlags = NULL;
    636         return INVALID_OPERATION;
    637     }
    638 
    639     *num_bufs = mNumBufs;
    640     *initial_reg_flag = regFlags;
    641     *bufs = mBufDefs;
    642     return NO_ERROR;
    643 }
    644 
    645 /*===========================================================================
    646  * FUNCTION   : putBufs
    647  *
    648  * DESCRIPTION: deallocate stream buffers
    649  *
    650  * PARAMETERS :
    651  *   @ops_tbl    : ptr to buf mapping/unmapping ops
    652  *
    653  * RETURN     : int32_t type of status
    654  *              NO_ERROR  -- success
    655  *              none-zero failure code
    656  *==========================================================================*/
    657 int32_t QCameraStream::putBufs(mm_camera_map_unmap_ops_tbl_t *ops_tbl)
    658 {
    659     int rc = NO_ERROR;
    660     for (int i = 0; i < mNumBufs; i++) {
    661         rc = ops_tbl->unmap_ops(i, -1, ops_tbl->userdata);
    662         if (rc < 0) {
    663             ALOGE("%s: map_stream_buf failed: %d", __func__, rc);
    664         }
    665     }
    666     mBufDefs = NULL; // mBufDefs just keep a ptr to the buffer
    667                      // mm-camera-interface own the buffer, so no need to free
    668     memset(&mFrameLenOffset, 0, sizeof(mFrameLenOffset));
    669     mStreamBufs->deallocate();
    670     delete mStreamBufs;
    671 
    672     return rc;
    673 }
    674 
    675 /*===========================================================================
    676  * FUNCTION   : invalidateBuf
    677  *
    678  * DESCRIPTION: invalidate a specific stream buffer
    679  *
    680  * PARAMETERS :
    681  *   @index   : index of the buffer to invalidate
    682  *
    683  * RETURN     : int32_t type of status
    684  *              NO_ERROR  -- success
    685  *              none-zero failure code
    686  *==========================================================================*/
    687 int32_t QCameraStream::invalidateBuf(int index)
    688 {
    689     return mStreamBufs->invalidateCache(index);
    690 }
    691 
    692 /*===========================================================================
    693  * FUNCTION   : cleanInvalidateBuf
    694  *
    695  * DESCRIPTION: clean invalidate a specific stream buffer
    696  *
    697  * PARAMETERS :
    698  *   @index   : index of the buffer to clean invalidate
    699  *
    700  * RETURN     : int32_t type of status
    701  *              NO_ERROR  -- success
    702  *              none-zero failure code
    703  *==========================================================================*/
    704 int32_t QCameraStream::cleanInvalidateBuf(int index)
    705 {
    706     return mStreamBufs->cleanInvalidateCache(index);
    707 }
    708 
    709 /*===========================================================================
    710  * FUNCTION   : isTypeOf
    711  *
    712  * DESCRIPTION: helper function to determine if the stream is of the queried type
    713  *
    714  * PARAMETERS :
    715  *   @type    : stream type as of queried
    716  *
    717  * RETURN     : true/false
    718  *==========================================================================*/
    719 bool QCameraStream::isTypeOf(cam_stream_type_t type)
    720 {
    721     if (mStreamInfo != NULL && (mStreamInfo->stream_type == type)) {
    722         return true;
    723     } else {
    724         return false;
    725     }
    726 }
    727 
    728 /*===========================================================================
    729  * FUNCTION   : isOrignalTypeOf
    730  *
    731  * DESCRIPTION: helper function to determine if the original stream is of the
    732  *              queried type if it's reproc stream
    733  *
    734  * PARAMETERS :
    735  *   @type    : stream type as of queried
    736  *
    737  * RETURN     : true/false
    738  *==========================================================================*/
    739 bool QCameraStream::isOrignalTypeOf(cam_stream_type_t type)
    740 {
    741     if (mStreamInfo != NULL &&
    742         mStreamInfo->stream_type == CAM_STREAM_TYPE_OFFLINE_PROC &&
    743         mStreamInfo->reprocess_config.pp_type == CAM_ONLINE_REPROCESS_TYPE &&
    744         mStreamInfo->reprocess_config.online.input_stream_type == type) {
    745         return true;
    746     } else {
    747         return false;
    748     }
    749 }
    750 
    751 /*===========================================================================
    752  * FUNCTION   : getMyType
    753  *
    754  * DESCRIPTION: return stream type
    755  *
    756  * PARAMETERS : none
    757  *
    758  * RETURN     : stream type
    759  *==========================================================================*/
    760 cam_stream_type_t QCameraStream::getMyType()
    761 {
    762     if (mStreamInfo != NULL) {
    763         return mStreamInfo->stream_type;
    764     } else {
    765         return CAM_STREAM_TYPE_DEFAULT;
    766     }
    767 }
    768 
    769 /*===========================================================================
    770  * FUNCTION   : getFrameOffset
    771  *
    772  * DESCRIPTION: query stream buffer frame offset info
    773  *
    774  * PARAMETERS :
    775  *   @offset  : reference to struct to store the queried frame offset info
    776  *
    777  * RETURN     : int32_t type of status
    778  *              NO_ERROR  -- success
    779  *              none-zero failure code
    780  *==========================================================================*/
    781 int32_t QCameraStream::getFrameOffset(cam_frame_len_offset_t &offset)
    782 {
    783     offset = mFrameLenOffset;
    784     return 0;
    785 }
    786 
    787 /*===========================================================================
    788  * FUNCTION   : getCropInfo
    789  *
    790  * DESCRIPTION: query crop info of the stream
    791  *
    792  * PARAMETERS :
    793  *   @crop    : reference to struct to store the queried crop info
    794  *
    795  * RETURN     : int32_t type of status
    796  *              NO_ERROR  -- success
    797  *              none-zero failure code
    798  *==========================================================================*/
    799 int32_t QCameraStream::getCropInfo(cam_rect_t &crop)
    800 {
    801     pthread_mutex_lock(&mCropLock);
    802     crop = mCropInfo;
    803     pthread_mutex_unlock(&mCropLock);
    804     return NO_ERROR;
    805 }
    806 
    807 /*===========================================================================
    808  * FUNCTION   : getFrameDimension
    809  *
    810  * DESCRIPTION: query stream frame dimension info
    811  *
    812  * PARAMETERS :
    813  *   @dim     : reference to struct to store the queried frame dimension
    814  *
    815  * RETURN     : int32_t type of status
    816  *              NO_ERROR  -- success
    817  *              none-zero failure code
    818  *==========================================================================*/
    819 int32_t QCameraStream::getFrameDimension(cam_dimension_t &dim)
    820 {
    821     if (mStreamInfo != NULL) {
    822         dim = mStreamInfo->dim;
    823         return 0;
    824     }
    825     return -1;
    826 }
    827 
    828 /*===========================================================================
    829  * FUNCTION   : getFormat
    830  *
    831  * DESCRIPTION: query stream format
    832  *
    833  * PARAMETERS :
    834  *   @fmt     : reference to stream format
    835  *
    836  * RETURN     : int32_t type of status
    837  *              NO_ERROR  -- success
    838  *              none-zero failure code
    839  *==========================================================================*/
    840 int32_t QCameraStream::getFormat(cam_format_t &fmt)
    841 {
    842     if (mStreamInfo != NULL) {
    843         fmt = mStreamInfo->fmt;
    844         return 0;
    845     }
    846     return -1;
    847 }
    848 
    849 /*===========================================================================
    850  * FUNCTION   : getMyServerID
    851  *
    852  * DESCRIPTION: query server stream ID
    853  *
    854  * PARAMETERS : None
    855  *
    856  * RETURN     : stream ID from server
    857  *==========================================================================*/
    858 uint32_t QCameraStream::getMyServerID() {
    859     if (mStreamInfo != NULL) {
    860         return mStreamInfo->stream_svr_id;
    861     } else {
    862         return 0;
    863     }
    864 }
    865 
    866 /*===========================================================================
    867  * FUNCTION   : mapBuf
    868  *
    869  * DESCRIPTION: map stream related buffer to backend server
    870  *
    871  * PARAMETERS :
    872  *   @buf_type : mapping type of buffer
    873  *   @buf_idx  : index of buffer
    874  *   @plane_idx: plane index
    875  *   @fd       : fd of the buffer
    876  *   @size     : lenght of the buffer
    877  *
    878  * RETURN     : int32_t type of status
    879  *              NO_ERROR  -- success
    880  *              none-zero failure code
    881  *==========================================================================*/
    882 int32_t QCameraStream::mapBuf(uint8_t buf_type,
    883                               uint32_t buf_idx,
    884                               int32_t plane_idx,
    885                               int fd,
    886                               uint32_t size)
    887 {
    888     return mCamOps->map_stream_buf(mCamHandle, mChannelHandle,
    889                                    mHandle, buf_type,
    890                                    buf_idx, plane_idx,
    891                                    fd, size);
    892 
    893 }
    894 
    895 /*===========================================================================
    896  * FUNCTION   : unmapBuf
    897  *
    898  * DESCRIPTION: unmap stream related buffer to backend server
    899  *
    900  * PARAMETERS :
    901  *   @buf_type : mapping type of buffer
    902  *   @buf_idx  : index of buffer
    903  *   @plane_idx: plane index
    904  *
    905  * RETURN     : int32_t type of status
    906  *              NO_ERROR  -- success
    907  *              none-zero failure code
    908  *==========================================================================*/
    909 int32_t QCameraStream::unmapBuf(uint8_t buf_type, uint32_t buf_idx, int32_t plane_idx)
    910 {
    911     return mCamOps->unmap_stream_buf(mCamHandle, mChannelHandle,
    912                                      mHandle, buf_type,
    913                                      buf_idx, plane_idx);
    914 
    915 }
    916 
    917 /*===========================================================================
    918  * FUNCTION   : setParameter
    919  *
    920  * DESCRIPTION: set stream based parameters
    921  *
    922  * PARAMETERS :
    923  *   @param   : ptr to parameters to be set
    924  *
    925  * RETURN     : int32_t type of status
    926  *              NO_ERROR  -- success
    927  *              none-zero failure code
    928  *==========================================================================*/
    929 int32_t QCameraStream::setParameter(cam_stream_parm_buffer_t &param)
    930 {
    931     int32_t rc = NO_ERROR;
    932     mStreamInfo->parm_buf = param;
    933     rc = mCamOps->set_stream_parms(mCamHandle,
    934                                    mChannelHandle,
    935                                    mHandle,
    936                                    &mStreamInfo->parm_buf);
    937     if (rc == NO_ERROR) {
    938         param = mStreamInfo->parm_buf;
    939     }
    940     return rc;
    941 }
    942 
    943 }; // namespace qcamera
    944