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