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