Home | History | Annotate | Download | only in HAL3
      1 /* Copyright (c) 2012-2014, The Linux Foundataion. All rights reserved.
      2 *
      3 * Redistribution and use in source and binary forms, with or without
      4 * modification, are permitted provided that the following conditions are
      5 * met:
      6 *     * Redistributions of source code must retain the above copyright
      7 *       notice, this list of conditions and the following disclaimer.
      8 *     * Redistributions in binary form must reproduce the above
      9 *       copyright notice, this list of conditions and the following
     10 *       disclaimer in the documentation and/or other materials provided
     11 *       with the distribution.
     12 *     * Neither the name of The Linux Foundation nor the names of its
     13 *       contributors may be used to endorse or promote products derived
     14 *       from this software without specific prior written permission.
     15 *
     16 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
     17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
     18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
     19 * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
     20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
     23 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
     24 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
     25 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
     26 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     27 *
     28 */
     29 
     30 #define LOG_TAG "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 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  *   @streamInfoBuf: ptr to buf that contains stream info
    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_stream_reproc_config_t* reprocess_config,
    238                             uint8_t minNumBuffers,
    239                             stream_cb_routine stream_cb,
    240                             void *userdata)
    241 {
    242     int32_t rc = OK;
    243     mm_camera_stream_config_t stream_config;
    244 
    245     mHandle = mCamOps->add_stream(mCamHandle, mChannelHandle);
    246     if (!mHandle) {
    247         ALOGE("add_stream failed");
    248         rc = UNKNOWN_ERROR;
    249         goto done;
    250     }
    251 
    252     // allocate and map stream info memory
    253     mStreamInfoBuf = new QCamera3HeapMemory();
    254     if (mStreamInfoBuf == NULL) {
    255         ALOGE("%s: no memory for stream info buf obj", __func__);
    256         rc = -ENOMEM;
    257         goto err1;
    258     }
    259     rc = mStreamInfoBuf->allocate(1, sizeof(cam_stream_info_t), false);
    260     if (rc < 0) {
    261         ALOGE("%s: no memory for stream info", __func__);
    262         rc = -ENOMEM;
    263         goto err2;
    264     }
    265 
    266     mStreamInfo =
    267         reinterpret_cast<cam_stream_info_t *>(mStreamInfoBuf->getPtr(0));
    268     memset(mStreamInfo, 0, sizeof(cam_stream_info_t));
    269     mStreamInfo->stream_type = streamType;
    270     mStreamInfo->fmt = streamFormat;
    271     mStreamInfo->dim = streamDim;
    272     mStreamInfo->num_bufs = minNumBuffers;
    273 
    274     rc = mCamOps->map_stream_buf(mCamHandle,
    275             mChannelHandle, mHandle, CAM_MAPPING_BUF_TYPE_STREAM_INFO,
    276             0, -1, mStreamInfoBuf->getFd(0), mStreamInfoBuf->getSize(0));
    277     if (rc < 0) {
    278         ALOGE("Failed to map stream info buffer");
    279         goto err3;
    280     }
    281 
    282     mNumBufs = minNumBuffers;
    283     if (reprocess_config != NULL) {
    284        mStreamInfo->reprocess_config = *reprocess_config;
    285        mStreamInfo->streaming_mode = CAM_STREAMING_MODE_BURST;
    286        //mStreamInfo->num_of_burst = reprocess_config->offline.num_of_bufs;
    287        mStreamInfo->num_of_burst = 1;
    288        ALOGI("%s: num_of_burst is %d", __func__, mStreamInfo->num_of_burst);
    289     } else {
    290        mStreamInfo->streaming_mode = CAM_STREAMING_MODE_CONTINUOUS;
    291     }
    292 
    293     // Configure the stream
    294     stream_config.stream_info = mStreamInfo;
    295     stream_config.mem_vtbl = mMemVtbl;
    296     stream_config.padding_info = mPaddingInfo;
    297     stream_config.userdata = this;
    298     stream_config.stream_cb = dataNotifyCB;
    299 
    300     rc = mCamOps->config_stream(mCamHandle,
    301             mChannelHandle, mHandle, &stream_config);
    302     if (rc < 0) {
    303         ALOGE("Failed to config stream, rc = %d", rc);
    304         goto err4;
    305     }
    306 
    307     mDataCB = stream_cb;
    308     mUserData = userdata;
    309     return 0;
    310 
    311 err4:
    312     mCamOps->unmap_stream_buf(mCamHandle,
    313             mChannelHandle, mHandle, CAM_MAPPING_BUF_TYPE_STREAM_INFO, 0, -1);
    314 err3:
    315     mStreamInfoBuf->deallocate();
    316 err2:
    317     delete mStreamInfoBuf;
    318     mStreamInfoBuf = NULL;
    319     mStreamInfo = NULL;
    320 err1:
    321     mCamOps->delete_stream(mCamHandle, mChannelHandle, mHandle);
    322     mHandle = 0;
    323     mNumBufs = 0;
    324 done:
    325     return rc;
    326 }
    327 
    328 /*===========================================================================
    329  * FUNCTION   : start
    330  *
    331  * DESCRIPTION: start stream. Will start main stream thread to handle stream
    332  *              related ops.
    333  *
    334  * PARAMETERS : none
    335  *
    336  * RETURN     : int32_t type of status
    337  *              NO_ERROR  -- success
    338  *              none-zero failure code
    339  *==========================================================================*/
    340 int32_t QCamera3Stream::start()
    341 {
    342     int32_t rc = 0;
    343 
    344     mDataQ.init();
    345     rc = mProcTh.launch(dataProcRoutine, this);
    346     return rc;
    347 }
    348 
    349 /*===========================================================================
    350  * FUNCTION   : stop
    351  *
    352  * DESCRIPTION: stop stream. Will stop main stream thread
    353  *
    354  * PARAMETERS : none
    355  *
    356  * RETURN     : int32_t type of status
    357  *              NO_ERROR  -- success
    358  *              none-zero failure code
    359  *==========================================================================*/
    360 int32_t QCamera3Stream::stop()
    361 {
    362     int32_t rc = 0;
    363     rc = mProcTh.exit();
    364     return rc;
    365 }
    366 
    367 /*===========================================================================
    368  * FUNCTION   : processDataNotify
    369  *
    370  * DESCRIPTION: process stream data notify
    371  *
    372  * PARAMETERS :
    373  *   @frame   : stream frame received
    374  *
    375  * RETURN     : int32_t type of status
    376  *              NO_ERROR  -- success
    377  *              none-zero failure code
    378  *==========================================================================*/
    379 int32_t QCamera3Stream::processDataNotify(mm_camera_super_buf_t *frame)
    380 {
    381     ALOGV("%s: E\n", __func__);
    382     int32_t rc;
    383     if (mDataQ.enqueue((void *)frame)) {
    384         rc = mProcTh.sendCmd(CAMERA_CMD_TYPE_DO_NEXT_JOB, FALSE, FALSE);
    385     } else {
    386         ALOGD("%s: Stream thread is not active, no ops here", __func__);
    387         bufDone(frame->bufs[0]->buf_idx);
    388         free(frame);
    389         rc = NO_ERROR;
    390     }
    391     ALOGV("%s: X\n", __func__);
    392     return rc;
    393 }
    394 
    395 /*===========================================================================
    396  * FUNCTION   : dataNotifyCB
    397  *
    398  * DESCRIPTION: callback for data notify. This function is registered with
    399  *              mm-camera-interface to handle data notify
    400  *
    401  * PARAMETERS :
    402  *   @recvd_frame   : stream frame received
    403  *   userdata       : user data ptr
    404  *
    405  * RETURN     : none
    406  *==========================================================================*/
    407 void QCamera3Stream::dataNotifyCB(mm_camera_super_buf_t *recvd_frame,
    408                                  void *userdata)
    409 {
    410     ALOGV("%s: E\n", __func__);
    411     QCamera3Stream* stream = (QCamera3Stream *)userdata;
    412     if (stream == NULL ||
    413         recvd_frame == NULL ||
    414         recvd_frame->bufs[0] == NULL ||
    415         recvd_frame->bufs[0]->stream_id != stream->getMyHandle()) {
    416         ALOGE("%s: Not a valid stream to handle buf", __func__);
    417         return;
    418     }
    419 
    420     mm_camera_super_buf_t *frame =
    421         (mm_camera_super_buf_t *)malloc(sizeof(mm_camera_super_buf_t));
    422     if (frame == NULL) {
    423         ALOGE("%s: No mem for mm_camera_buf_def_t", __func__);
    424         stream->bufDone(recvd_frame->bufs[0]->buf_idx);
    425         return;
    426     }
    427     *frame = *recvd_frame;
    428     stream->processDataNotify(frame);
    429     return;
    430 }
    431 
    432 /*===========================================================================
    433  * FUNCTION   : dataProcRoutine
    434  *
    435  * DESCRIPTION: function to process data in the main stream thread
    436  *
    437  * PARAMETERS :
    438  *   @data    : user data ptr
    439  *
    440  * RETURN     : none
    441  *==========================================================================*/
    442 void *QCamera3Stream::dataProcRoutine(void *data)
    443 {
    444     int running = 1;
    445     int ret;
    446     QCamera3Stream *pme = (QCamera3Stream *)data;
    447     QCameraCmdThread *cmdThread = &pme->mProcTh;
    448     cmdThread->setName("cam_stream_proc");
    449 
    450     ALOGV("%s: E", __func__);
    451     do {
    452         do {
    453             ret = cam_sem_wait(&cmdThread->cmd_sem);
    454             if (ret != 0 && errno != EINVAL) {
    455                 ALOGE("%s: cam_sem_wait error (%s)",
    456                       __func__, strerror(errno));
    457                 return NULL;
    458             }
    459         } while (ret != 0);
    460 
    461         // we got notified about new cmd avail in cmd queue
    462         camera_cmd_type_t cmd = cmdThread->getCmd();
    463         switch (cmd) {
    464         case CAMERA_CMD_TYPE_DO_NEXT_JOB:
    465             {
    466                 ALOGV("%s: Do next job", __func__);
    467                 mm_camera_super_buf_t *frame =
    468                     (mm_camera_super_buf_t *)pme->mDataQ.dequeue();
    469                 if (NULL != frame) {
    470                     if (pme->mDataCB != NULL) {
    471                         pme->mDataCB(frame, pme, pme->mUserData);
    472                     } else {
    473                         // no data cb routine, return buf here
    474                         pme->bufDone(frame->bufs[0]->buf_idx);
    475                     }
    476                 }
    477             }
    478             break;
    479         case CAMERA_CMD_TYPE_EXIT:
    480             ALOGD("%s: Exit", __func__);
    481             /* flush data buf queue */
    482             pme->mDataQ.flush();
    483             running = 0;
    484             break;
    485         default:
    486             break;
    487         }
    488     } while (running);
    489     ALOGV("%s: X", __func__);
    490     return NULL;
    491 }
    492 
    493 /*===========================================================================
    494  * FUNCTION   : getInternalFormatBuffer
    495  *
    496  * DESCRIPTION: return buffer in the internal format structure
    497  *
    498  * PARAMETERS :
    499  *   @index   : index of buffer to be returned
    500  *
    501  * RETURN     : int32_t type of status
    502  *              NO_ERROR  -- success
    503  *              none-zero failure code
    504  *==========================================================================*/
    505 mm_camera_buf_def_t* QCamera3Stream::getInternalFormatBuffer(int index)
    506 {
    507     mm_camera_buf_def_t *rc = NULL;
    508     if ((index >= mNumBufs) || (mBufDefs == NULL) ||
    509             (NULL == mBufDefs[index].mem_info)) {
    510         ALOGE("%s:Index out of range/no internal buffers yet", __func__);
    511         return NULL;
    512     }
    513 
    514     rc = (mm_camera_buf_def_t*)malloc(sizeof(mm_camera_buf_def_t));
    515     if(rc) {
    516         memcpy(rc, &mBufDefs[index], sizeof(mm_camera_buf_def_t));
    517     } else {
    518         ALOGE("%s: Failed to allocate memory",__func__);
    519     }
    520     return rc;
    521 }
    522 
    523 /*===========================================================================
    524  * FUNCTION   : bufDone
    525  *
    526  * DESCRIPTION: return stream buffer to kernel
    527  *
    528  * PARAMETERS :
    529  *   @index   : index of buffer to be returned
    530  *
    531  * RETURN     : int32_t type of status
    532  *              NO_ERROR  -- success
    533  *              none-zero failure code
    534  *==========================================================================*/
    535 int32_t QCamera3Stream::bufDone(int index)
    536 {
    537     int32_t rc = NO_ERROR;
    538 
    539     if (index >= mNumBufs || mBufDefs == NULL)
    540         return BAD_INDEX;
    541 
    542     if( NULL == mBufDefs[index].mem_info) {
    543         if (NULL == mMemOps) {
    544             ALOGE("%s: Camera operations not initialized", __func__);
    545             return NO_INIT;
    546         }
    547 
    548         rc = mMemOps->map_ops(index, -1, mStreamBufs->getFd(index),
    549                 mStreamBufs->getSize(index), mMemOps->userdata);
    550         if (rc < 0) {
    551             ALOGE("%s: Failed to map camera buffer %d", __func__, index);
    552             return rc;
    553         }
    554 
    555         rc = mStreamBufs->getBufDef(mFrameLenOffset, mBufDefs[index], index);
    556         if (NO_ERROR != rc) {
    557             ALOGE("%s: Couldn't find camera buffer definition", __func__);
    558             mMemOps->unmap_ops(index, -1, mMemOps->userdata);
    559             return rc;
    560         }
    561     }
    562 
    563     rc = mCamOps->qbuf(mCamHandle, mChannelHandle, &mBufDefs[index]);
    564     if (rc < 0)
    565         return FAILED_TRANSACTION;
    566 
    567     return rc;
    568 }
    569 
    570 /*===========================================================================
    571  * FUNCTION   : getBufs
    572  *
    573  * DESCRIPTION: allocate stream buffers
    574  *
    575  * PARAMETERS :
    576  *   @offset     : offset info of stream buffers
    577  *   @num_bufs   : number of buffers allocated
    578  *   @initial_reg_flag: flag to indicate if buffer needs to be registered
    579  *                      at kernel initially
    580  *   @bufs       : output of allocated buffers
    581  *   @ops_tbl    : ptr to buf mapping/unmapping ops
    582  *
    583  * RETURN     : int32_t type of status
    584  *              NO_ERROR  -- success
    585  *              none-zero failure code
    586  *==========================================================================*/
    587 int32_t QCamera3Stream::getBufs(cam_frame_len_offset_t *offset,
    588                      uint8_t *num_bufs,
    589                      uint8_t **initial_reg_flag,
    590                      mm_camera_buf_def_t **bufs,
    591                      mm_camera_map_unmap_ops_tbl_t *ops_tbl)
    592 {
    593     int rc = NO_ERROR;
    594     uint8_t *regFlags;
    595 
    596     if (!ops_tbl) {
    597         ALOGE("%s: ops_tbl is NULL", __func__);
    598         return INVALID_OPERATION;
    599     }
    600 
    601     mFrameLenOffset = *offset;
    602     mMemOps = ops_tbl;
    603 
    604     mStreamBufs = mChannel->getStreamBufs(mFrameLenOffset.frame_len);
    605     if (!mStreamBufs) {
    606         ALOGE("%s: Failed to allocate stream buffers", __func__);
    607         return NO_MEMORY;
    608     }
    609 
    610     int registeredBuffers = mStreamBufs->getCnt();
    611     for (int i = 0; i < registeredBuffers; i++) {
    612         rc = ops_tbl->map_ops(i, -1, mStreamBufs->getFd(i),
    613                 mStreamBufs->getSize(i), ops_tbl->userdata);
    614         if (rc < 0) {
    615             ALOGE("%s: map_stream_buf failed: %d", __func__, rc);
    616             for (int j = 0; j < i; j++) {
    617                 ops_tbl->unmap_ops(j, -1, ops_tbl->userdata);
    618             }
    619             return INVALID_OPERATION;
    620         }
    621     }
    622 
    623     //regFlags array is allocated by us, but consumed and freed by mm-camera-interface
    624     regFlags = (uint8_t *)malloc(sizeof(uint8_t) * mNumBufs);
    625     if (!regFlags) {
    626         ALOGE("%s: Out of memory", __func__);
    627         for (int i = 0; i < registeredBuffers; i++) {
    628             ops_tbl->unmap_ops(i, -1, ops_tbl->userdata);
    629         }
    630         return NO_MEMORY;
    631     }
    632     memset(regFlags, 0, sizeof(uint8_t) * mNumBufs);
    633 
    634     mBufDefs = (mm_camera_buf_def_t *)malloc(mNumBufs * sizeof(mm_camera_buf_def_t));
    635     if (mBufDefs == NULL) {
    636         ALOGE("%s: Failed to allocate mm_camera_buf_def_t %d", __func__, rc);
    637         for (int i = 0; i < registeredBuffers; i++) {
    638             ops_tbl->unmap_ops(i, -1, ops_tbl->userdata);
    639         }
    640         free(regFlags);
    641         regFlags = NULL;
    642         return INVALID_OPERATION;
    643     }
    644     memset(mBufDefs, 0, mNumBufs * sizeof(mm_camera_buf_def_t));
    645     for (int i = 0; i < registeredBuffers; i++) {
    646         mStreamBufs->getBufDef(mFrameLenOffset, mBufDefs[i], i);
    647     }
    648 
    649     rc = mStreamBufs->getRegFlags(regFlags);
    650     if (rc < 0) {
    651         ALOGE("%s: getRegFlags failed %d", __func__, rc);
    652         for (int i = 0; i < registeredBuffers; i++) {
    653             ops_tbl->unmap_ops(i, -1, ops_tbl->userdata);
    654         }
    655         free(mBufDefs);
    656         mBufDefs = NULL;
    657         free(regFlags);
    658         regFlags = NULL;
    659         return INVALID_OPERATION;
    660     }
    661 
    662     *num_bufs = mNumBufs;
    663     *initial_reg_flag = regFlags;
    664     *bufs = mBufDefs;
    665     return NO_ERROR;
    666 }
    667 
    668 /*===========================================================================
    669  * FUNCTION   : putBufs
    670  *
    671  * DESCRIPTION: deallocate stream buffers
    672  *
    673  * PARAMETERS :
    674  *   @ops_tbl    : ptr to buf mapping/unmapping ops
    675  *
    676  * RETURN     : int32_t type of status
    677  *              NO_ERROR  -- success
    678  *              none-zero failure code
    679  *==========================================================================*/
    680 int32_t QCamera3Stream::putBufs(mm_camera_map_unmap_ops_tbl_t *ops_tbl)
    681 {
    682     int rc = NO_ERROR;
    683     for (int i = 0; i < mNumBufs; i++) {
    684         if (NULL != mBufDefs[i].mem_info) {
    685             rc = ops_tbl->unmap_ops(i, -1, ops_tbl->userdata);
    686             if (rc < 0) {
    687                 ALOGE("%s: map_stream_buf failed: %d", __func__, rc);
    688             }
    689         }
    690     }
    691     mBufDefs = NULL; // mBufDefs just keep a ptr to the buffer
    692                      // mm-camera-interface own the buffer, so no need to free
    693     memset(&mFrameLenOffset, 0, sizeof(mFrameLenOffset));
    694     mChannel->putStreamBufs();
    695 
    696     return rc;
    697 }
    698 
    699 /*===========================================================================
    700  * FUNCTION   : invalidateBuf
    701  *
    702  * DESCRIPTION: invalidate a specific stream buffer
    703  *
    704  * PARAMETERS :
    705  *   @index   : index of the buffer to invalidate
    706  *
    707  * RETURN     : int32_t type of status
    708  *              NO_ERROR  -- success
    709  *              none-zero failure code
    710  *==========================================================================*/
    711 int32_t QCamera3Stream::invalidateBuf(int index)
    712 {
    713     return mStreamBufs->invalidateCache(index);
    714 }
    715 
    716 /*===========================================================================
    717  * FUNCTION   : cleanInvalidateBuf
    718  *
    719  * DESCRIPTION: clean and invalidate a specific stream buffer
    720  *
    721  * PARAMETERS :
    722  *   @index   : index of the buffer to invalidate
    723  *
    724  * RETURN     : int32_t type of status
    725  *              NO_ERROR  -- success
    726  *              none-zero failure code
    727  *==========================================================================*/
    728 int32_t QCamera3Stream::cleanInvalidateBuf(int index)
    729 {
    730     return mStreamBufs->cleanInvalidateCache(index);
    731 }
    732 
    733 /*===========================================================================
    734  * FUNCTION   : getFrameOffset
    735  *
    736  * DESCRIPTION: query stream buffer frame offset info
    737  *
    738  * PARAMETERS :
    739  *   @offset  : reference to struct to store the queried frame offset info
    740  *
    741  * RETURN     : int32_t type of status
    742  *              NO_ERROR  -- success
    743  *              none-zero failure code
    744  *==========================================================================*/
    745 int32_t QCamera3Stream::getFrameOffset(cam_frame_len_offset_t &offset)
    746 {
    747     offset = mFrameLenOffset;
    748     return 0;
    749 }
    750 
    751 /*===========================================================================
    752  * FUNCTION   : getFrameDimension
    753  *
    754  * DESCRIPTION: query stream frame dimension info
    755  *
    756  * PARAMETERS :
    757  *   @dim     : reference to struct to store the queried frame dimension
    758  *
    759  * RETURN     : int32_t type of status
    760  *              NO_ERROR  -- success
    761  *              none-zero failure code
    762  *==========================================================================*/
    763 int32_t QCamera3Stream::getFrameDimension(cam_dimension_t &dim)
    764 {
    765     if (mStreamInfo != NULL) {
    766         dim = mStreamInfo->dim;
    767         return 0;
    768     }
    769     return -1;
    770 }
    771 
    772 /*===========================================================================
    773  * FUNCTION   : getFormat
    774  *
    775  * DESCRIPTION: query stream format
    776  *
    777  * PARAMETERS :
    778  *   @fmt     : reference to stream format
    779  *
    780  * RETURN     : int32_t type of status
    781  *              NO_ERROR  -- success
    782  *              none-zero failure code
    783  *==========================================================================*/
    784 int32_t QCamera3Stream::getFormat(cam_format_t &fmt)
    785 {
    786     if (mStreamInfo != NULL) {
    787         fmt = mStreamInfo->fmt;
    788         return 0;
    789     }
    790     return -1;
    791 }
    792 
    793 /*===========================================================================
    794  * FUNCTION   : getMyServerID
    795  *
    796  * DESCRIPTION: query server stream ID
    797  *
    798  * PARAMETERS : None
    799  *
    800  * RETURN     : stream ID from server
    801  *==========================================================================*/
    802 uint32_t QCamera3Stream::getMyServerID() {
    803     if (mStreamInfo != NULL) {
    804         return mStreamInfo->stream_svr_id;
    805     } else {
    806         return 0;
    807     }
    808 }
    809 
    810 /*===========================================================================
    811  * FUNCTION   : getMyType
    812  *
    813  * DESCRIPTION: query stream type
    814  *
    815  * PARAMETERS : None
    816  *
    817  * RETURN     : type of stream
    818  *==========================================================================*/
    819 cam_stream_type_t QCamera3Stream::getMyType() const
    820 {
    821     if (mStreamInfo != NULL) {
    822         return mStreamInfo->stream_type;
    823     } else {
    824         return CAM_STREAM_TYPE_MAX;
    825     }
    826 }
    827 
    828 /*===========================================================================
    829  * FUNCTION   : mapBuf
    830  *
    831  * DESCRIPTION: map stream related buffer to backend server
    832  *
    833  * PARAMETERS :
    834  *   @buf_type : mapping type of buffer
    835  *   @buf_idx  : index of buffer
    836  *   @plane_idx: plane index
    837  *   @fd       : fd of the buffer
    838  *   @size     : lenght of the buffer
    839  *
    840  * RETURN     : int32_t type of status
    841  *              NO_ERROR  -- success
    842  *              none-zero failure code
    843  *==========================================================================*/
    844 int32_t QCamera3Stream::mapBuf(uint8_t buf_type,
    845                               uint32_t buf_idx,
    846                               int32_t plane_idx,
    847                               int fd,
    848                               uint32_t size)
    849 {
    850     return mCamOps->map_stream_buf(mCamHandle, mChannelHandle,
    851                                    mHandle, buf_type,
    852                                    buf_idx, plane_idx,
    853                                    fd, size);
    854 
    855 }
    856 
    857 /*===========================================================================
    858  * FUNCTION   : unmapBuf
    859  *
    860  * DESCRIPTION: unmap stream related buffer to backend server
    861  *
    862  * PARAMETERS :
    863  *   @buf_type : mapping type of buffer
    864  *   @buf_idx  : index of buffer
    865  *   @plane_idx: plane index
    866  *
    867  * RETURN     : int32_t type of status
    868  *              NO_ERROR  -- success
    869  *              none-zero failure code
    870  *==========================================================================*/
    871 int32_t QCamera3Stream::unmapBuf(uint8_t buf_type, uint32_t buf_idx, int32_t plane_idx)
    872 {
    873     return mCamOps->unmap_stream_buf(mCamHandle, mChannelHandle,
    874                                      mHandle, buf_type,
    875                                      buf_idx, plane_idx);
    876 }
    877 
    878 /*===========================================================================
    879  * FUNCTION   : setParameter
    880  *
    881  * DESCRIPTION: set stream based parameters
    882  *
    883  * PARAMETERS :
    884  *   @param   : ptr to parameters to be set
    885  *
    886  * RETURN     : int32_t type of status
    887  *              NO_ERROR  -- success
    888  *              none-zero failure code
    889  *==========================================================================*/
    890 int32_t QCamera3Stream::setParameter(cam_stream_parm_buffer_t &param)
    891 {
    892     int32_t rc = NO_ERROR;
    893     mStreamInfo->parm_buf = param;
    894     rc = mCamOps->set_stream_parms(mCamHandle,
    895                                    mChannelHandle,
    896                                    mHandle,
    897                                    &mStreamInfo->parm_buf);
    898     if (rc == NO_ERROR) {
    899         param = mStreamInfo->parm_buf;
    900     }
    901     return rc;
    902 }
    903 
    904 /*===========================================================================
    905  * FUNCTION   : releaseFrameData
    906  *
    907  * DESCRIPTION: callback function to release frame data node
    908  *
    909  * PARAMETERS :
    910  *   @data      : ptr to post process input data
    911  *   @user_data : user data ptr (QCameraReprocessor)
    912  *
    913  * RETURN     : None
    914  *==========================================================================*/
    915 void QCamera3Stream::releaseFrameData(void *data, void *user_data)
    916 {
    917     QCamera3Stream *pme = (QCamera3Stream *)user_data;
    918     mm_camera_super_buf_t *frame = (mm_camera_super_buf_t *)data;
    919     if (NULL != pme) {
    920         pme->bufDone(frame->bufs[0]->buf_idx);
    921     }
    922 }
    923 
    924 }; // namespace qcamera
    925