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