Home | History | Annotate | Download | only in HAL3
      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 "QCamera3Stream"
     31 
     32 #include <utils/Log.h>
     33 #include <utils/Errors.h>
     34 #include "QCamera3HWI.h"
     35 #include "QCamera3Stream.h"
     36 #include "QCamera3Channel.h"
     37 
     38 using namespace android;
     39 
     40 namespace qcamera {
     41 
     42 /*===========================================================================
     43  * FUNCTION   : get_bufs
     44  *
     45  * DESCRIPTION: static function entry to allocate stream buffers
     46  *
     47  * PARAMETERS :
     48  *   @offset     : offset info of stream buffers
     49  *   @num_bufs   : number of buffers allocated
     50  *   @initial_reg_flag: flag to indicate if buffer needs to be registered
     51  *                      at kernel initially
     52  *   @bufs       : output of allocated buffers
     53  *   @ops_tbl    : ptr to buf mapping/unmapping ops
     54  *   @user_data  : user data ptr of ops_tbl
     55  *
     56  * RETURN     : int32_t type of status
     57  *              NO_ERROR  -- success
     58  *              none-zero failure code
     59  *==========================================================================*/
     60 int32_t QCamera3Stream::get_bufs(
     61                      cam_frame_len_offset_t *offset,
     62                      uint8_t *num_bufs,
     63                      uint8_t **initial_reg_flag,
     64                      mm_camera_buf_def_t **bufs,
     65                      mm_camera_map_unmap_ops_tbl_t *ops_tbl,
     66                      void *user_data)
     67 {
     68     QCamera3Stream *stream = reinterpret_cast<QCamera3Stream *>(user_data);
     69     if (!stream) {
     70         ALOGE("getBufs invalid stream pointer");
     71         return NO_MEMORY;
     72     }
     73     return stream->getBufs(offset, num_bufs, initial_reg_flag, bufs, ops_tbl);
     74 }
     75 
     76 /*===========================================================================
     77  * FUNCTION   : put_bufs
     78  *
     79  * DESCRIPTION: static function entry to deallocate stream buffers
     80  *
     81  * PARAMETERS :
     82  *   @ops_tbl    : ptr to buf mapping/unmapping ops
     83  *   @user_data  : user data ptr of ops_tbl
     84  *
     85  * RETURN     : int32_t type of status
     86  *              NO_ERROR  -- success
     87  *              none-zero failure code
     88  *==========================================================================*/
     89 int32_t QCamera3Stream::put_bufs(
     90                      mm_camera_map_unmap_ops_tbl_t *ops_tbl,
     91                      void *user_data)
     92 {
     93     QCamera3Stream *stream = reinterpret_cast<QCamera3Stream *>(user_data);
     94     if (!stream) {
     95         ALOGE("putBufs invalid stream pointer");
     96         return NO_MEMORY;
     97     }
     98     return stream->putBufs(ops_tbl);
     99 }
    100 
    101 /*===========================================================================
    102  * FUNCTION   : invalidate_buf
    103  *
    104  * DESCRIPTION: static function entry to invalidate a specific stream buffer
    105  *
    106  * PARAMETERS :
    107  *   @index      : index of the stream buffer to invalidate
    108  *   @user_data  : user data ptr of ops_tbl
    109  *
    110  * RETURN     : int32_t type of status
    111  *              NO_ERROR  -- success
    112  *              none-zero failure code
    113  *==========================================================================*/
    114 int32_t QCamera3Stream::invalidate_buf(int index, void *user_data)
    115 {
    116     QCamera3Stream *stream = reinterpret_cast<QCamera3Stream *>(user_data);
    117     if (!stream) {
    118         ALOGE("invalid stream pointer");
    119         return NO_MEMORY;
    120     }
    121     return stream->invalidateBuf(index);
    122 }
    123 
    124 /*===========================================================================
    125  * FUNCTION   : clean_invalidate_buf
    126  *
    127  * DESCRIPTION: static function entry to clean and invalidate a specific stream buffer
    128  *
    129  * PARAMETERS :
    130  *   @index      : index of the stream buffer to invalidate
    131  *   @user_data  : user data ptr of ops_tbl
    132  *
    133  * RETURN     : int32_t type of status
    134  *              NO_ERROR  -- success
    135  *              none-zero failure code
    136  *==========================================================================*/
    137 int32_t QCamera3Stream::clean_invalidate_buf(int index, void *user_data)
    138 {
    139     QCamera3Stream *stream = reinterpret_cast<QCamera3Stream *>(user_data);
    140     if (!stream) {
    141         ALOGE("invalid stream pointer");
    142         return NO_MEMORY;
    143     }
    144     return stream->cleanInvalidateBuf(index);
    145 }
    146 
    147 /*===========================================================================
    148  * FUNCTION   : QCamera3Stream
    149  *
    150  * DESCRIPTION: constructor of QCamera3Stream
    151  *
    152  * PARAMETERS :
    153  *   @allocator  : memory allocator obj
    154  *   @camHandle  : camera handle
    155  *   @chId       : channel handle
    156  *   @camOps     : ptr to camera ops table
    157  *   @paddingInfo: ptr to padding info
    158  *
    159  * RETURN     : None
    160  *==========================================================================*/
    161 QCamera3Stream::QCamera3Stream(uint32_t camHandle,
    162                              uint32_t chId,
    163                              mm_camera_ops_t *camOps,
    164                              cam_padding_info_t *paddingInfo,
    165                              QCamera3Channel *channel) :
    166         mCamHandle(camHandle),
    167         mChannelHandle(chId),
    168         mHandle(0),
    169         mCamOps(camOps),
    170         mStreamInfo(NULL),
    171         mNumBufs(0),
    172         mDataCB(NULL),
    173         mStreamInfoBuf(NULL),
    174         mStreamBufs(NULL),
    175         mBufDefs(NULL),
    176         mChannel(channel)
    177 {
    178     mMemVtbl.user_data = this;
    179     mMemVtbl.get_bufs = get_bufs;
    180     mMemVtbl.put_bufs = put_bufs;
    181     mMemVtbl.invalidate_buf = invalidate_buf;
    182     mMemVtbl.clean_invalidate_buf = clean_invalidate_buf;
    183     memset(&mFrameLenOffset, 0, sizeof(mFrameLenOffset));
    184     memcpy(&mPaddingInfo, paddingInfo, sizeof(cam_padding_info_t));
    185 }
    186 
    187 /*===========================================================================
    188  * FUNCTION   : ~QCamera3Stream
    189  *
    190  * DESCRIPTION: deconstructor of QCamera3Stream
    191  *
    192  * PARAMETERS : None
    193  *
    194  * RETURN     : None
    195  *==========================================================================*/
    196 QCamera3Stream::~QCamera3Stream()
    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 QCamera3Stream::init(cam_stream_type_t streamType,
    231                             cam_format_t streamFormat,
    232                             cam_dimension_t streamDim,
    233                             cam_stream_reproc_config_t* reprocess_config,
    234                             uint8_t minNumBuffers,
    235                             stream_cb_routine stream_cb,
    236                             void *userdata)
    237 {
    238     int32_t rc = OK;
    239     mm_camera_stream_config_t stream_config;
    240 
    241     mHandle = mCamOps->add_stream(mCamHandle, mChannelHandle);
    242     if (!mHandle) {
    243         ALOGE("add_stream failed");
    244         rc = UNKNOWN_ERROR;
    245         goto done;
    246     }
    247 
    248     // allocate and map stream info memory
    249     mStreamInfoBuf = new QCamera3HeapMemory();
    250     if (mStreamInfoBuf == NULL) {
    251         ALOGE("%s: no memory for stream info buf obj", __func__);
    252         rc = -ENOMEM;
    253         goto err1;
    254     }
    255     rc = mStreamInfoBuf->allocate(1, sizeof(cam_stream_info_t), false);
    256     if (rc < 0) {
    257         ALOGE("%s: no memory for stream info", __func__);
    258         rc = -ENOMEM;
    259         goto err2;
    260     }
    261 
    262     mStreamInfo =
    263         reinterpret_cast<cam_stream_info_t *>(mStreamInfoBuf->getPtr(0));
    264     memset(mStreamInfo, 0, sizeof(cam_stream_info_t));
    265     mStreamInfo->stream_type = streamType;
    266     mStreamInfo->fmt = streamFormat;
    267     mStreamInfo->dim = streamDim;
    268 
    269 
    270 
    271     mNumBufs = minNumBuffers;
    272     if (reprocess_config != NULL) {
    273        mStreamInfo->reprocess_config = *reprocess_config;
    274        mStreamInfo->streaming_mode = CAM_STREAMING_MODE_BURST;
    275        //mStreamInfo->num_of_burst = reprocess_config->offline.num_of_bufs;
    276        mStreamInfo->num_of_burst = 1;
    277        ALOGE("%s: num_of_burst is %d", __func__, mStreamInfo->num_of_burst);
    278     } else {
    279        mStreamInfo->streaming_mode = CAM_STREAMING_MODE_CONTINUOUS;
    280     }
    281 
    282     rc = mCamOps->map_stream_buf(mCamHandle,
    283             mChannelHandle, mHandle, CAM_MAPPING_BUF_TYPE_STREAM_INFO,
    284             0, -1, mStreamInfoBuf->getFd(0), mStreamInfoBuf->getSize(0));
    285     if (rc < 0) {
    286         ALOGE("Failed to map stream info buffer");
    287         goto err3;
    288     }
    289 
    290     // Configure the stream
    291     stream_config.stream_info = mStreamInfo;
    292     stream_config.mem_vtbl = mMemVtbl;
    293     stream_config.padding_info = mPaddingInfo;
    294     stream_config.userdata = this;
    295     stream_config.stream_cb = dataNotifyCB;
    296 
    297     rc = mCamOps->config_stream(mCamHandle,
    298             mChannelHandle, mHandle, &stream_config);
    299     if (rc < 0) {
    300         ALOGE("Failed to config stream, rc = %d", rc);
    301         goto err4;
    302     }
    303 
    304     mDataCB = stream_cb;
    305     mUserData = userdata;
    306     return 0;
    307 
    308 err4:
    309     mCamOps->unmap_stream_buf(mCamHandle,
    310             mChannelHandle, mHandle, CAM_MAPPING_BUF_TYPE_STREAM_INFO, 0, -1);
    311 err3:
    312     mStreamInfoBuf->deallocate();
    313 err2:
    314     delete mStreamInfoBuf;
    315     mStreamInfoBuf = NULL;
    316     mStreamInfo = NULL;
    317 err1:
    318     mCamOps->delete_stream(mCamHandle, mChannelHandle, mHandle);
    319     mHandle = 0;
    320     mNumBufs = 0;
    321 done:
    322     return rc;
    323 }
    324 
    325 /*===========================================================================
    326  * FUNCTION   : start
    327  *
    328  * DESCRIPTION: start stream. Will start main stream thread to handle stream
    329  *              related ops.
    330  *
    331  * PARAMETERS : none
    332  *
    333  * RETURN     : int32_t type of status
    334  *              NO_ERROR  -- success
    335  *              none-zero failure code
    336  *==========================================================================*/
    337 int32_t QCamera3Stream::start()
    338 {
    339     int32_t rc = 0;
    340     rc = mProcTh.launch(dataProcRoutine, this);
    341     return rc;
    342 }
    343 
    344 /*===========================================================================
    345  * FUNCTION   : stop
    346  *
    347  * DESCRIPTION: stop stream. Will stop main stream thread
    348  *
    349  * PARAMETERS : none
    350  *
    351  * RETURN     : int32_t type of status
    352  *              NO_ERROR  -- success
    353  *              none-zero failure code
    354  *==========================================================================*/
    355 int32_t QCamera3Stream::stop()
    356 {
    357     int32_t rc = 0;
    358     rc = mProcTh.exit();
    359     return rc;
    360 }
    361 
    362 /*===========================================================================
    363  * FUNCTION   : processDataNotify
    364  *
    365  * DESCRIPTION: process stream data notify
    366  *
    367  * PARAMETERS :
    368  *   @frame   : stream frame received
    369  *
    370  * RETURN     : int32_t type of status
    371  *              NO_ERROR  -- success
    372  *              none-zero failure code
    373  *==========================================================================*/
    374 int32_t QCamera3Stream::processDataNotify(mm_camera_super_buf_t *frame)
    375 {
    376     ALOGV("%s: E\n", __func__);
    377     mDataQ.enqueue((void *)frame);
    378     int32_t rc = mProcTh.sendCmd(CAMERA_CMD_TYPE_DO_NEXT_JOB, FALSE, FALSE);
    379     ALOGV("%s: X\n", __func__);
    380     return rc;
    381 }
    382 
    383 /*===========================================================================
    384  * FUNCTION   : dataNotifyCB
    385  *
    386  * DESCRIPTION: callback for data notify. This function is registered with
    387  *              mm-camera-interface to handle data notify
    388  *
    389  * PARAMETERS :
    390  *   @recvd_frame   : stream frame received
    391  *   userdata       : user data ptr
    392  *
    393  * RETURN     : none
    394  *==========================================================================*/
    395 void QCamera3Stream::dataNotifyCB(mm_camera_super_buf_t *recvd_frame,
    396                                  void *userdata)
    397 {
    398     ALOGV("%s: E\n", __func__);
    399     QCamera3Stream* stream = (QCamera3Stream *)userdata;
    400     if (stream == NULL ||
    401         recvd_frame == NULL ||
    402         recvd_frame->bufs[0] == NULL ||
    403         recvd_frame->bufs[0]->stream_id != stream->getMyHandle()) {
    404         ALOGE("%s: Not a valid stream to handle buf", __func__);
    405         return;
    406     }
    407 
    408     mm_camera_super_buf_t *frame =
    409         (mm_camera_super_buf_t *)malloc(sizeof(mm_camera_super_buf_t));
    410     if (frame == NULL) {
    411         ALOGE("%s: No mem for mm_camera_buf_def_t", __func__);
    412         stream->bufDone(recvd_frame->bufs[0]->buf_idx);
    413         return;
    414     }
    415     *frame = *recvd_frame;
    416     stream->processDataNotify(frame);
    417     return;
    418 }
    419 
    420 /*===========================================================================
    421  * FUNCTION   : dataProcRoutine
    422  *
    423  * DESCRIPTION: function to process data in the main stream thread
    424  *
    425  * PARAMETERS :
    426  *   @data    : user data ptr
    427  *
    428  * RETURN     : none
    429  *==========================================================================*/
    430 void *QCamera3Stream::dataProcRoutine(void *data)
    431 {
    432     int running = 1;
    433     int ret;
    434     QCamera3Stream *pme = (QCamera3Stream *)data;
    435     QCameraCmdThread *cmdThread = &pme->mProcTh;
    436 
    437     ALOGV("%s: E", __func__);
    438     do {
    439         do {
    440             ret = cam_sem_wait(&cmdThread->cmd_sem);
    441             if (ret != 0 && errno != EINVAL) {
    442                 ALOGE("%s: cam_sem_wait error (%s)",
    443                       __func__, strerror(errno));
    444                 return NULL;
    445             }
    446         } while (ret != 0);
    447 
    448         // we got notified about new cmd avail in cmd queue
    449         camera_cmd_type_t cmd = cmdThread->getCmd();
    450         switch (cmd) {
    451         case CAMERA_CMD_TYPE_DO_NEXT_JOB:
    452             {
    453                 ALOGV("%s: Do next job", __func__);
    454                 mm_camera_super_buf_t *frame =
    455                     (mm_camera_super_buf_t *)pme->mDataQ.dequeue();
    456                 if (NULL != frame) {
    457                     if (pme->mDataCB != NULL) {
    458                         pme->mDataCB(frame, pme, pme->mUserData);
    459                     } else {
    460                         // no data cb routine, return buf here
    461                         pme->bufDone(frame->bufs[0]->buf_idx);
    462                     }
    463                 }
    464             }
    465             break;
    466         case CAMERA_CMD_TYPE_EXIT:
    467             ALOGD("%s: Exit", __func__);
    468             /* flush data buf queue */
    469             pme->mDataQ.flush();
    470             running = 0;
    471             break;
    472         default:
    473             break;
    474         }
    475     } while (running);
    476     ALOGV("%s: X", __func__);
    477     return NULL;
    478 }
    479 
    480 /*===========================================================================
    481  * FUNCTION   : getInternalFormatBuffer
    482  *
    483  * DESCRIPTION: return buffer in the internal format structure
    484  *
    485  * PARAMETERS :
    486  *   @index   : index of buffer to be returned
    487  *
    488  * RETURN     : int32_t type of status
    489  *              NO_ERROR  -- success
    490  *              none-zero failure code
    491  *==========================================================================*/
    492 mm_camera_buf_def_t* QCamera3Stream::getInternalFormatBuffer(int index)
    493 {
    494     mm_camera_buf_def_t *rc = NULL;
    495     if (index >= mNumBufs || mBufDefs == NULL) {
    496         ALOGE("%s:Index out of range/no internal buffers yet", __func__);
    497         return NULL;
    498     }
    499 
    500     rc = (mm_camera_buf_def_t*)malloc(sizeof(mm_camera_buf_def_t));
    501     if(rc) {
    502         memcpy(rc, &mBufDefs[index], sizeof(mm_camera_buf_def_t));
    503     } else {
    504         ALOGE("%s: Failed to allocate memory",__func__);
    505     }
    506     return rc;
    507 }
    508 
    509 /*===========================================================================
    510  * FUNCTION   : bufDone
    511  *
    512  * DESCRIPTION: return stream buffer to kernel
    513  *
    514  * PARAMETERS :
    515  *   @index   : index of buffer to be returned
    516  *
    517  * RETURN     : int32_t type of status
    518  *              NO_ERROR  -- success
    519  *              none-zero failure code
    520  *==========================================================================*/
    521 int32_t QCamera3Stream::bufDone(int index)
    522 {
    523     int32_t rc = NO_ERROR;
    524 
    525     if (index >= mNumBufs || mBufDefs == NULL)
    526         return BAD_INDEX;
    527 
    528     rc = mCamOps->qbuf(mCamHandle, mChannelHandle, &mBufDefs[index]);
    529     if (rc < 0)
    530         return FAILED_TRANSACTION;
    531 
    532     return rc;
    533 }
    534 
    535 /*===========================================================================
    536  * FUNCTION   : getBufs
    537  *
    538  * DESCRIPTION: allocate stream buffers
    539  *
    540  * PARAMETERS :
    541  *   @offset     : offset info of stream buffers
    542  *   @num_bufs   : number of buffers allocated
    543  *   @initial_reg_flag: flag to indicate if buffer needs to be registered
    544  *                      at kernel initially
    545  *   @bufs       : output of allocated buffers
    546  *   @ops_tbl    : ptr to buf mapping/unmapping ops
    547  *
    548  * RETURN     : int32_t type of status
    549  *              NO_ERROR  -- success
    550  *              none-zero failure code
    551  *==========================================================================*/
    552 int32_t QCamera3Stream::getBufs(cam_frame_len_offset_t *offset,
    553                      uint8_t *num_bufs,
    554                      uint8_t **initial_reg_flag,
    555                      mm_camera_buf_def_t **bufs,
    556                      mm_camera_map_unmap_ops_tbl_t *ops_tbl)
    557 {
    558     int rc = NO_ERROR;
    559     uint8_t *regFlags;
    560 
    561     if (!ops_tbl) {
    562         ALOGE("%s: ops_tbl is NULL", __func__);
    563         return INVALID_OPERATION;
    564     }
    565 
    566     mFrameLenOffset = *offset;
    567 
    568     mStreamBufs = mChannel->getStreamBufs(mFrameLenOffset.frame_len);
    569     if (!mStreamBufs) {
    570         ALOGE("%s: Failed to allocate stream buffers", __func__);
    571         return NO_MEMORY;
    572     }
    573 
    574     for (int i = 0; i < mNumBufs; i++) {
    575         rc = ops_tbl->map_ops(i, -1, mStreamBufs->getFd(i),
    576                 mStreamBufs->getSize(i), ops_tbl->userdata);
    577         if (rc < 0) {
    578             ALOGE("%s: map_stream_buf failed: %d", __func__, rc);
    579             for (int j = 0; j < i; j++) {
    580                 ops_tbl->unmap_ops(j, -1, ops_tbl->userdata);
    581             }
    582             return INVALID_OPERATION;
    583         }
    584     }
    585 
    586     //regFlags array is allocated by us, but consumed and freed by mm-camera-interface
    587     regFlags = (uint8_t *)malloc(sizeof(uint8_t) * mNumBufs);
    588     if (!regFlags) {
    589         ALOGE("%s: Out of memory", __func__);
    590         for (int i = 0; i < mNumBufs; i++) {
    591             ops_tbl->unmap_ops(i, -1, ops_tbl->userdata);
    592         }
    593         return NO_MEMORY;
    594     }
    595 
    596     mBufDefs = (mm_camera_buf_def_t *)malloc(mNumBufs * sizeof(mm_camera_buf_def_t));
    597     if (mBufDefs == NULL) {
    598         ALOGE("%s: Failed to allocate mm_camera_buf_def_t %d", __func__, rc);
    599         for (int i = 0; i < mNumBufs; i++) {
    600             ops_tbl->unmap_ops(i, -1, ops_tbl->userdata);
    601         }
    602         free(regFlags);
    603         regFlags = NULL;
    604         return INVALID_OPERATION;
    605     }
    606     for (int i = 0; i < mNumBufs; i++) {
    607         mStreamBufs->getBufDef(mFrameLenOffset, mBufDefs[i], i);
    608     }
    609 
    610     rc = mStreamBufs->getRegFlags(regFlags);
    611     if (rc < 0) {
    612         ALOGE("%s: getRegFlags failed %d", __func__, rc);
    613         for (int i = 0; i < mNumBufs; i++) {
    614             ops_tbl->unmap_ops(i, -1, ops_tbl->userdata);
    615         }
    616         free(mBufDefs);
    617         mBufDefs = NULL;
    618         free(regFlags);
    619         regFlags = NULL;
    620         return INVALID_OPERATION;
    621     }
    622 
    623     *num_bufs = mNumBufs;
    624     *initial_reg_flag = regFlags;
    625     *bufs = mBufDefs;
    626     return NO_ERROR;
    627 }
    628 
    629 /*===========================================================================
    630  * FUNCTION   : putBufs
    631  *
    632  * DESCRIPTION: deallocate stream buffers
    633  *
    634  * PARAMETERS :
    635  *   @ops_tbl    : ptr to buf mapping/unmapping ops
    636  *
    637  * RETURN     : int32_t type of status
    638  *              NO_ERROR  -- success
    639  *              none-zero failure code
    640  *==========================================================================*/
    641 int32_t QCamera3Stream::putBufs(mm_camera_map_unmap_ops_tbl_t *ops_tbl)
    642 {
    643     int rc = NO_ERROR;
    644     for (int i = 0; i < mNumBufs; i++) {
    645         rc = ops_tbl->unmap_ops(i, -1, ops_tbl->userdata);
    646         if (rc < 0) {
    647             ALOGE("%s: map_stream_buf failed: %d", __func__, rc);
    648         }
    649     }
    650     mBufDefs = NULL; // mBufDefs just keep a ptr to the buffer
    651                      // mm-camera-interface own the buffer, so no need to free
    652     memset(&mFrameLenOffset, 0, sizeof(mFrameLenOffset));
    653     mChannel->putStreamBufs();
    654 
    655     return rc;
    656 }
    657 
    658 /*===========================================================================
    659  * FUNCTION   : invalidateBuf
    660  *
    661  * DESCRIPTION: invalidate a specific stream buffer
    662  *
    663  * PARAMETERS :
    664  *   @index   : index of the buffer to invalidate
    665  *
    666  * RETURN     : int32_t type of status
    667  *              NO_ERROR  -- success
    668  *              none-zero failure code
    669  *==========================================================================*/
    670 int32_t QCamera3Stream::invalidateBuf(int index)
    671 {
    672     return mStreamBufs->invalidateCache(index);
    673 }
    674 
    675 /*===========================================================================
    676  * FUNCTION   : cleanInvalidateBuf
    677  *
    678  * DESCRIPTION: clean and 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 QCamera3Stream::cleanInvalidateBuf(int index)
    688 {
    689     return mStreamBufs->cleanInvalidateCache(index);
    690 }
    691 
    692 /*===========================================================================
    693  * FUNCTION   : getFrameOffset
    694  *
    695  * DESCRIPTION: query stream buffer frame offset info
    696  *
    697  * PARAMETERS :
    698  *   @offset  : reference to struct to store the queried frame offset info
    699  *
    700  * RETURN     : int32_t type of status
    701  *              NO_ERROR  -- success
    702  *              none-zero failure code
    703  *==========================================================================*/
    704 int32_t QCamera3Stream::getFrameOffset(cam_frame_len_offset_t &offset)
    705 {
    706     offset = mFrameLenOffset;
    707     return 0;
    708 }
    709 
    710 /*===========================================================================
    711  * FUNCTION   : getFrameDimension
    712  *
    713  * DESCRIPTION: query stream frame dimension info
    714  *
    715  * PARAMETERS :
    716  *   @dim     : reference to struct to store the queried frame dimension
    717  *
    718  * RETURN     : int32_t type of status
    719  *              NO_ERROR  -- success
    720  *              none-zero failure code
    721  *==========================================================================*/
    722 int32_t QCamera3Stream::getFrameDimension(cam_dimension_t &dim)
    723 {
    724     if (mStreamInfo != NULL) {
    725         dim = mStreamInfo->dim;
    726         return 0;
    727     }
    728     return -1;
    729 }
    730 
    731 /*===========================================================================
    732  * FUNCTION   : getFormat
    733  *
    734  * DESCRIPTION: query stream format
    735  *
    736  * PARAMETERS :
    737  *   @fmt     : reference to stream format
    738  *
    739  * RETURN     : int32_t type of status
    740  *              NO_ERROR  -- success
    741  *              none-zero failure code
    742  *==========================================================================*/
    743 int32_t QCamera3Stream::getFormat(cam_format_t &fmt)
    744 {
    745     if (mStreamInfo != NULL) {
    746         fmt = mStreamInfo->fmt;
    747         return 0;
    748     }
    749     return -1;
    750 }
    751 
    752 /*===========================================================================
    753  * FUNCTION   : getMyServerID
    754  *
    755  * DESCRIPTION: query server stream ID
    756  *
    757  * PARAMETERS : None
    758  *
    759  * RETURN     : stream ID from server
    760  *==========================================================================*/
    761 uint32_t QCamera3Stream::getMyServerID() {
    762     if (mStreamInfo != NULL) {
    763         return mStreamInfo->stream_svr_id;
    764     } else {
    765         return 0;
    766     }
    767 }
    768 
    769 /*===========================================================================
    770  * FUNCTION   : getMyType
    771  *
    772  * DESCRIPTION: query stream type
    773  *
    774  * PARAMETERS : None
    775  *
    776  * RETURN     : type of stream
    777  *==========================================================================*/
    778 cam_stream_type_t QCamera3Stream::getMyType() const
    779 {
    780     if (mStreamInfo != NULL) {
    781         return mStreamInfo->stream_type;
    782     } else {
    783         return CAM_STREAM_TYPE_MAX;
    784     }
    785 }
    786 
    787 /*===========================================================================
    788  * FUNCTION   : mapBuf
    789  *
    790  * DESCRIPTION: map stream related buffer to backend server
    791  *
    792  * PARAMETERS :
    793  *   @buf_type : mapping type of buffer
    794  *   @buf_idx  : index of buffer
    795  *   @plane_idx: plane index
    796  *   @fd       : fd of the buffer
    797  *   @size     : lenght of the buffer
    798  *
    799  * RETURN     : int32_t type of status
    800  *              NO_ERROR  -- success
    801  *              none-zero failure code
    802  *==========================================================================*/
    803 int32_t QCamera3Stream::mapBuf(uint8_t buf_type,
    804                               uint32_t buf_idx,
    805                               int32_t plane_idx,
    806                               int fd,
    807                               uint32_t size)
    808 {
    809     return mCamOps->map_stream_buf(mCamHandle, mChannelHandle,
    810                                    mHandle, buf_type,
    811                                    buf_idx, plane_idx,
    812                                    fd, size);
    813 
    814 }
    815 
    816 /*===========================================================================
    817  * FUNCTION   : unmapBuf
    818  *
    819  * DESCRIPTION: unmap stream related buffer to backend server
    820  *
    821  * PARAMETERS :
    822  *   @buf_type : mapping type of buffer
    823  *   @buf_idx  : index of buffer
    824  *   @plane_idx: plane index
    825  *
    826  * RETURN     : int32_t type of status
    827  *              NO_ERROR  -- success
    828  *              none-zero failure code
    829  *==========================================================================*/
    830 int32_t QCamera3Stream::unmapBuf(uint8_t buf_type, uint32_t buf_idx, int32_t plane_idx)
    831 {
    832     return mCamOps->unmap_stream_buf(mCamHandle, mChannelHandle,
    833                                      mHandle, buf_type,
    834                                      buf_idx, plane_idx);
    835 }
    836 
    837 /*===========================================================================
    838  * FUNCTION   : setParameter
    839  *
    840  * DESCRIPTION: set stream based parameters
    841  *
    842  * PARAMETERS :
    843  *   @param   : ptr to parameters to be set
    844  *
    845  * RETURN     : int32_t type of status
    846  *              NO_ERROR  -- success
    847  *              none-zero failure code
    848  *==========================================================================*/
    849 int32_t QCamera3Stream::setParameter(cam_stream_parm_buffer_t &param)
    850 {
    851     int32_t rc = NO_ERROR;
    852     mStreamInfo->parm_buf = param;
    853     rc = mCamOps->set_stream_parms(mCamHandle,
    854                                    mChannelHandle,
    855                                    mHandle,
    856                                    &mStreamInfo->parm_buf);
    857     if (rc == NO_ERROR) {
    858         param = mStreamInfo->parm_buf;
    859     }
    860     return rc;
    861 }
    862 
    863 }; // namespace qcamera
    864