Home | History | Annotate | Download | only in HAL
      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 "QCameraStream"
     31 
     32 #include <utils/Errors.h>
     33 #include "QCamera2HWI.h"
     34 #include "QCameraStream.h"
     35 
     36 #define CAMERA_MIN_ALLOCATED_BUFFERS     3
     37 
     38 namespace qcamera {
     39 
     40 /*===========================================================================
     41  * FUNCTION   : get_bufs
     42  *
     43  * DESCRIPTION: static function entry to allocate stream buffers
     44  *
     45  * PARAMETERS :
     46  *   @offset     : offset info of stream buffers
     47  *   @num_bufs   : number of buffers allocated
     48  *   @initial_reg_flag: flag to indicate if buffer needs to be registered
     49  *                      at kernel initially
     50  *   @bufs       : output of allocated buffers
     51  *   @ops_tbl    : ptr to buf mapping/unmapping ops
     52  *   @user_data  : user data ptr of ops_tbl
     53  *
     54  * RETURN     : int32_t type of status
     55  *              NO_ERROR  -- success
     56  *              none-zero failure code
     57  *==========================================================================*/
     58 int32_t QCameraStream::get_bufs(
     59                      cam_frame_len_offset_t *offset,
     60                      uint8_t *num_bufs,
     61                      uint8_t **initial_reg_flag,
     62                      mm_camera_buf_def_t **bufs,
     63                      mm_camera_map_unmap_ops_tbl_t *ops_tbl,
     64                      void *user_data)
     65 {
     66     QCameraStream *stream = reinterpret_cast<QCameraStream *>(user_data);
     67     if (!stream) {
     68         ALOGE("getBufs invalid stream pointer");
     69         return NO_MEMORY;
     70     }
     71     return stream->getBufs(offset, num_bufs, initial_reg_flag, bufs, ops_tbl);
     72 }
     73 
     74 /*===========================================================================
     75  * FUNCTION   : get_bufs_deffered
     76  *
     77  * DESCRIPTION: static function entry to allocate deffered stream buffers
     78  *
     79  * PARAMETERS :
     80  *   @offset     : offset info of stream buffers
     81  *   @num_bufs   : number of buffers allocated
     82  *   @initial_reg_flag: flag to indicate if buffer needs to be registered
     83  *                      at kernel initially
     84  *   @bufs       : output of allocated buffers
     85  *   @ops_tbl    : ptr to buf mapping/unmapping ops
     86  *   @user_data  : user data ptr of ops_tbl
     87  *
     88  * RETURN     : int32_t type of status
     89  *              NO_ERROR  -- success
     90  *              none-zero failure code
     91  *==========================================================================*/
     92 int32_t QCameraStream::get_bufs_deffered(
     93         cam_frame_len_offset_t * /* offset */,
     94         uint8_t *num_bufs,
     95         uint8_t **initial_reg_flag,
     96         mm_camera_buf_def_t **bufs,
     97         mm_camera_map_unmap_ops_tbl_t * /* ops_tbl */,
     98         void *user_data)
     99 {
    100     QCameraStream *stream = reinterpret_cast<QCameraStream *>(user_data);
    101     if (!stream) {
    102         ALOGE("getBufs invalid stream pointer");
    103         return NO_MEMORY;
    104     }
    105 
    106     *initial_reg_flag   = stream->mRegFlags;
    107     *num_bufs           = stream->mNumBufs;
    108     *bufs               = stream->mBufDefs;
    109     return NO_ERROR;
    110 }
    111 
    112 /*===========================================================================
    113  * FUNCTION   : put_bufs
    114  *
    115  * DESCRIPTION: static function entry to deallocate stream buffers
    116  *
    117  * PARAMETERS :
    118  *   @ops_tbl    : ptr to buf mapping/unmapping ops
    119  *   @user_data  : user data ptr of ops_tbl
    120  *
    121  * RETURN     : int32_t type of status
    122  *              NO_ERROR  -- success
    123  *              none-zero failure code
    124  *==========================================================================*/
    125 int32_t QCameraStream::put_bufs(
    126                      mm_camera_map_unmap_ops_tbl_t *ops_tbl,
    127                      void *user_data)
    128 {
    129     QCameraStream *stream = reinterpret_cast<QCameraStream *>(user_data);
    130     if (!stream) {
    131         ALOGE("putBufs invalid stream pointer");
    132         return NO_MEMORY;
    133     }
    134     return stream->putBufs(ops_tbl);
    135 }
    136 
    137 /*===========================================================================
    138  * FUNCTION   : put_bufs_deffered
    139  *
    140  * DESCRIPTION: static function entry to deallocate deffered stream buffers
    141  *
    142  * PARAMETERS :
    143  *   @ops_tbl    : ptr to buf mapping/unmapping ops
    144  *   @user_data  : user data ptr of ops_tbl
    145  *
    146  * RETURN     : int32_t type of status
    147  *              NO_ERROR  -- success
    148  *              none-zero failure code
    149  *==========================================================================*/
    150 int32_t QCameraStream::put_bufs_deffered(
    151         mm_camera_map_unmap_ops_tbl_t * /*ops_tbl */,
    152         void * /*user_data*/ )
    153 {
    154     // No op
    155     // Used for handling buffers with deffered allocation. They are freed separately.
    156     return NO_ERROR;
    157 }
    158 
    159 /*===========================================================================
    160  * FUNCTION   : invalidate_buf
    161  *
    162  * DESCRIPTION: static function entry to invalidate a specific stream buffer
    163  *
    164  * PARAMETERS :
    165  *   @index      : index of the stream buffer to invalidate
    166  *   @user_data  : user data ptr of ops_tbl
    167  *
    168  * RETURN     : int32_t type of status
    169  *              NO_ERROR  -- success
    170  *              none-zero failure code
    171  *==========================================================================*/
    172 int32_t QCameraStream::invalidate_buf(int index, void *user_data)
    173 {
    174     QCameraStream *stream = reinterpret_cast<QCameraStream *>(user_data);
    175     if (!stream) {
    176         ALOGE("invalid stream pointer");
    177         return NO_MEMORY;
    178     }
    179     if (stream->mStreamInfo->is_secure != SECURE)
    180         return stream->invalidateBuf(index);
    181 
    182     return 0;
    183 }
    184 
    185 /*===========================================================================
    186  * FUNCTION   : clean_invalidate_buf
    187  *
    188  * DESCRIPTION: static function entry to clean invalidate a specific stream buffer
    189  *
    190  * PARAMETERS :
    191  *   @index      : index of the stream buffer to clean invalidate
    192  *   @user_data  : user data ptr of ops_tbl
    193  *
    194  * RETURN     : int32_t type of status
    195  *              NO_ERROR  -- success
    196  *              none-zero failure code
    197  *==========================================================================*/
    198 int32_t QCameraStream::clean_invalidate_buf(int index, void *user_data)
    199 {
    200     QCameraStream *stream = reinterpret_cast<QCameraStream *>(user_data);
    201     if (!stream) {
    202         ALOGE("invalid stream pointer");
    203         return NO_MEMORY;
    204     }
    205 
    206     if (stream->mStreamInfo->is_secure != SECURE)
    207         return stream->cleanInvalidateBuf(index);
    208 
    209     return 0;
    210 }
    211 
    212 /*===========================================================================
    213  * FUNCTION   : QCameraStream
    214  *
    215  * DESCRIPTION: constructor of QCameraStream
    216  *
    217  * PARAMETERS :
    218  *   @allocator  : memory allocator obj
    219  *   @camHandle  : camera handle
    220  *   @chId       : channel handle
    221  *   @camOps     : ptr to camera ops table
    222  *   @paddingInfo: ptr to padding info
    223  *
    224  * RETURN     : None
    225  *==========================================================================*/
    226 QCameraStream::QCameraStream(QCameraAllocator &allocator,
    227                              uint32_t camHandle,
    228                              uint32_t chId,
    229                              mm_camera_ops_t *camOps,
    230                              cam_padding_info_t *paddingInfo,
    231                              bool deffered) :
    232         mDumpFrame(0),
    233         mDumpMetaFrame(0),
    234         mDumpSkipCnt(0),
    235         mCamHandle(camHandle),
    236         mChannelHandle(chId),
    237         mHandle(0),
    238         mCamOps(camOps),
    239         mStreamInfo(NULL),
    240         mNumBufs(0),
    241         mNumBufsNeedAlloc(0),
    242         mDataCB(NULL),
    243         mUserData(NULL),
    244         mDataQ(releaseFrameData, this),
    245         mStreamInfoBuf(NULL),
    246         mStreamBufs(NULL),
    247         mAllocator(allocator),
    248         mBufDefs(NULL),
    249         mStreamBufsAcquired(false),
    250         m_bActive(false),
    251         mDynBufAlloc(false),
    252         mBufAllocPid(0),
    253         mDefferedAllocation(deffered),
    254         wait_for_cond(false)
    255 {
    256     mMemVtbl.user_data = this;
    257     if ( !deffered ) {
    258         mMemVtbl.get_bufs = get_bufs;
    259         mMemVtbl.put_bufs = put_bufs;
    260     } else {
    261         mMemVtbl.get_bufs = get_bufs_deffered;
    262         mMemVtbl.put_bufs = put_bufs_deffered;
    263     }
    264     mMemVtbl.invalidate_buf = invalidate_buf;
    265     mMemVtbl.clean_invalidate_buf = clean_invalidate_buf;
    266     memset(&mFrameLenOffset, 0, sizeof(mFrameLenOffset));
    267     memcpy(&mPaddingInfo, paddingInfo, sizeof(cam_padding_info_t));
    268     memset(&mCropInfo, 0, sizeof(cam_rect_t));
    269     memset(&m_MemOpsTbl, 0, sizeof(mm_camera_map_unmap_ops_tbl_t));
    270     memset(&m_OutputCrop, 0, sizeof(cam_stream_parm_buffer_t));
    271     memset(&m_ImgProp, 0, sizeof(cam_stream_parm_buffer_t));
    272     pthread_mutex_init(&mCropLock, NULL);
    273     pthread_mutex_init(&mParameterLock, NULL);
    274 }
    275 
    276 /*===========================================================================
    277  * FUNCTION   : ~QCameraStream
    278  *
    279  * DESCRIPTION: deconstructor of QCameraStream
    280  *
    281  * PARAMETERS : None
    282  *
    283  * RETURN     : None
    284  *==========================================================================*/
    285 QCameraStream::~QCameraStream()
    286 {
    287     pthread_mutex_destroy(&mCropLock);
    288     pthread_mutex_destroy(&mParameterLock);
    289 
    290     if (mDefferedAllocation) {
    291         mStreamBufsAcquired = false;
    292         releaseBuffs();
    293     }
    294 
    295     unmapStreamInfoBuf();
    296     releaseStreamInfoBuf();
    297 
    298     // delete stream
    299     if (mHandle > 0) {
    300         mCamOps->delete_stream(mCamHandle, mChannelHandle, mHandle);
    301         mHandle = 0;
    302     }
    303 }
    304 
    305 /*===========================================================================
    306  * FUNCTION   : unmapStreamInfoBuf
    307  *
    308  * DESCRIPTION: Unmap stream info buffer
    309  *
    310  * PARAMETERS :
    311  *
    312  * RETURN     : int32_t type of status
    313  *              NO_ERROR  -- success
    314  *              none-zero failure code
    315  *==========================================================================*/
    316 int32_t QCameraStream::unmapStreamInfoBuf()
    317 {
    318     int rc = NO_ERROR;
    319 
    320     if (mStreamInfoBuf != NULL) {
    321         rc = mCamOps->unmap_stream_buf(mCamHandle,
    322             mChannelHandle,
    323             mHandle,
    324             CAM_MAPPING_BUF_TYPE_STREAM_INFO,
    325             0,
    326             -1);
    327 
    328         if (rc < 0) {
    329             ALOGE("Failed to unmap stream info buffer");
    330         }
    331     }
    332 
    333     return rc;
    334 }
    335 
    336 /*===========================================================================
    337  * FUNCTION   : releaseStreamInfoBuf
    338  *
    339  * DESCRIPTION: Release stream info buffer
    340  *
    341  * PARAMETERS :
    342  *
    343  * RETURN     : int32_t type of status
    344  *              NO_ERROR  -- success
    345  *              none-zero failure code
    346  *==========================================================================*/
    347 int32_t QCameraStream::releaseStreamInfoBuf()
    348 {
    349     int rc = NO_ERROR;
    350 
    351     if (mStreamInfoBuf != NULL) {
    352         mStreamInfoBuf->deallocate();
    353         delete mStreamInfoBuf;
    354         mStreamInfoBuf = NULL;
    355     }
    356 
    357     return rc;
    358 }
    359 
    360 /*===========================================================================
    361  * FUNCTION   : deleteStream
    362  *
    363  * DESCRIPTION: Deletes a camera stream
    364  *
    365  * PARAMETERS : None
    366  *
    367  * RETURN     : None
    368  *==========================================================================*/
    369 void QCameraStream::deleteStream()
    370 {
    371     if (mHandle > 0) {
    372         acquireStreamBufs();
    373         releaseBuffs();
    374         unmapStreamInfoBuf();
    375         mCamOps->delete_stream(mCamHandle, mChannelHandle, mHandle);
    376     }
    377 }
    378 
    379 /*===========================================================================
    380  * FUNCTION   : init
    381  *
    382  * DESCRIPTION: initialize stream obj
    383  *
    384  * PARAMETERS :
    385  *   @streamInfoBuf: ptr to buf that contains stream info
    386  *   @stream_cb    : stream data notify callback. Can be NULL if not needed
    387  *   @userdata     : user data ptr
    388  *   @bDynallocBuf : flag to indicate if buffer allocation can be in 2 steps
    389  *
    390  * RETURN     : int32_t type of status
    391  *              NO_ERROR  -- success
    392  *              none-zero failure code
    393  *==========================================================================*/
    394 int32_t QCameraStream::init(QCameraHeapMemory *streamInfoBuf,
    395                             uint8_t minNumBuffers,
    396                             stream_cb_routine stream_cb,
    397                             void *userdata,
    398                             bool bDynallocBuf)
    399 {
    400     int32_t rc = OK;
    401 
    402     mHandle = mCamOps->add_stream(mCamHandle, mChannelHandle);
    403     if (!mHandle) {
    404         ALOGE("add_stream failed");
    405         rc = UNKNOWN_ERROR;
    406         goto done;
    407     }
    408 
    409     // assign and map stream info memory
    410     mStreamInfoBuf = streamInfoBuf;
    411     mStreamInfo = reinterpret_cast<cam_stream_info_t *>(mStreamInfoBuf->getPtr(0));
    412     mNumBufs = minNumBuffers;
    413 
    414     rc = mCamOps->map_stream_buf(mCamHandle,
    415                 mChannelHandle, mHandle, CAM_MAPPING_BUF_TYPE_STREAM_INFO,
    416                 0, -1, mStreamInfoBuf->getFd(0), mStreamInfoBuf->getSize(0));
    417     if (rc < 0) {
    418         ALOGE("Failed to map stream info buffer");
    419         goto err1;
    420     }
    421 
    422     // Calculate buffer size for deffered allocation
    423     if (mDefferedAllocation) {
    424         rc = calcOffset(mStreamInfo);
    425         if (rc < 0) {
    426             ALOGE("%s : Failed to calculate stream offset", __func__);
    427             goto err1;
    428         }
    429     } else {
    430         rc = configStream();
    431         if (rc < 0) {
    432             ALOGE("%s : Failed to config stream ", __func__);
    433             goto err1;
    434         }
    435     }
    436 
    437     mDataCB = stream_cb;
    438     mUserData = userdata;
    439     mDynBufAlloc = bDynallocBuf;
    440     return 0;
    441 
    442 err1:
    443     mCamOps->delete_stream(mCamHandle, mChannelHandle, mHandle);
    444     mHandle = 0;
    445     mStreamInfoBuf = NULL;
    446     mStreamInfo = NULL;
    447     mNumBufs = 0;
    448 done:
    449     return rc;
    450 }
    451 
    452 /*===========================================================================
    453  * FUNCTION   : calcOffset
    454  *
    455  * DESCRIPTION: calculate frame offset based on format and padding information
    456  *
    457  * PARAMETERS :
    458  *   @streamInfo  : stream information
    459  *
    460  * RETURN     : int32_t type of status
    461  *              0  -- success
    462  *              -1 -- failure
    463  *==========================================================================*/
    464 int32_t QCameraStream::calcOffset(cam_stream_info_t *streamInfo)
    465 {
    466     int32_t rc = 0;
    467 
    468     cam_dimension_t dim = streamInfo->dim;
    469     if (streamInfo->pp_config.feature_mask & CAM_QCOM_FEATURE_ROTATION &&
    470             streamInfo->stream_type != CAM_STREAM_TYPE_VIDEO) {
    471         if (streamInfo->pp_config.rotation == ROTATE_90 ||
    472                 streamInfo->pp_config.rotation == ROTATE_270) {
    473             // rotated by 90 or 270, need to switch width and height
    474             dim.width = streamInfo->dim.height;
    475             dim.height = streamInfo->dim.width;
    476         }
    477     }
    478 
    479     switch (streamInfo->stream_type) {
    480     case CAM_STREAM_TYPE_PREVIEW:
    481         rc = mm_stream_calc_offset_preview(streamInfo->fmt,
    482                 &dim,
    483                 &streamInfo->buf_planes);
    484         break;
    485     case CAM_STREAM_TYPE_POSTVIEW:
    486         rc = mm_stream_calc_offset_post_view(streamInfo->fmt,
    487                 &dim,
    488                 &streamInfo->buf_planes);
    489         break;
    490     case CAM_STREAM_TYPE_SNAPSHOT:
    491         rc = mm_stream_calc_offset_snapshot(streamInfo->fmt,
    492                 &dim,
    493                 &mPaddingInfo,
    494                 &streamInfo->buf_planes);
    495         break;
    496     case CAM_STREAM_TYPE_OFFLINE_PROC:
    497         rc = mm_stream_calc_offset_postproc(streamInfo,
    498                 &mPaddingInfo,
    499                 &streamInfo->buf_planes);
    500         break;
    501     case CAM_STREAM_TYPE_VIDEO:
    502         rc = mm_stream_calc_offset_video(&dim,
    503                 &streamInfo->buf_planes);
    504         break;
    505     case CAM_STREAM_TYPE_RAW:
    506         rc = mm_stream_calc_offset_raw(streamInfo->fmt,
    507                 &dim,
    508                 &mPaddingInfo,
    509                 &streamInfo->buf_planes);
    510         break;
    511     case CAM_STREAM_TYPE_METADATA:
    512         rc = mm_stream_calc_offset_metadata(&dim,
    513                 &mPaddingInfo,
    514                 &streamInfo->buf_planes);
    515         break;
    516     default:
    517         ALOGE("%s: not supported for stream type %d",
    518                 __func__, streamInfo->stream_type);
    519         rc = -1;
    520         break;
    521     }
    522     return rc;
    523 }
    524 
    525 /*===========================================================================
    526  * FUNCTION   : start
    527  *
    528  * DESCRIPTION: start stream. Will start main stream thread to handle stream
    529  *              related ops.
    530  *
    531  * PARAMETERS : none
    532  *
    533  * RETURN     : int32_t type of status
    534  *              NO_ERROR  -- success
    535  *              none-zero failure code
    536  *==========================================================================*/
    537 int32_t QCameraStream::start()
    538 {
    539     int32_t rc = 0;
    540     mDataQ.init();
    541     rc = mProcTh.launch(dataProcRoutine, this);
    542     if (rc == NO_ERROR) {
    543         m_bActive = true;
    544     }
    545     pthread_mutex_init(&m_lock, NULL);
    546     pthread_cond_init(&m_cond, NULL);
    547     return rc;
    548 }
    549 
    550 /*===========================================================================
    551  * FUNCTION   : stop
    552  *
    553  * DESCRIPTION: stop stream. Will stop main stream thread
    554  *
    555  * PARAMETERS : none
    556  *
    557  * RETURN     : int32_t type of status
    558  *              NO_ERROR  -- success
    559  *              none-zero failure code
    560  *==========================================================================*/
    561 int32_t QCameraStream::stop()
    562 {
    563     int32_t rc = 0;
    564     m_bActive = false;
    565     rc = mProcTh.exit();
    566     return rc;
    567 }
    568 
    569 /*===========================================================================
    570  * FUNCTION   : syncRuntimeParams
    571  *
    572  * DESCRIPTION: query and sync runtime parameters like output crop
    573  *              buffer info etc.
    574  *
    575  * PARAMETERS : none
    576  *
    577  * RETURN     : int32_t type of status
    578  *              NO_ERROR  -- success
    579  *              none-zero failure code
    580  *==========================================================================*/
    581 int32_t QCameraStream::syncRuntimeParams()
    582 {
    583     int32_t ret = NO_ERROR;
    584 
    585     memset(&m_OutputCrop, 0, sizeof(cam_stream_parm_buffer_t));
    586     m_OutputCrop.type = CAM_STREAM_PARAM_TYPE_GET_OUTPUT_CROP;
    587 
    588     ret = getParameter(m_OutputCrop);
    589     if (ret != NO_ERROR) {
    590         ALOGE("%s: stream getParameter for output crop failed", __func__);
    591         return ret;
    592     }
    593 
    594     memset(&m_ImgProp, 0, sizeof(cam_stream_parm_buffer_t));
    595     m_ImgProp.type = CAM_STREAM_PARAM_TYPE_GET_IMG_PROP;
    596 
    597     ret = getParameter(m_ImgProp);
    598     if (ret != NO_ERROR) {
    599         ALOGE("%s: stream getParameter for image prop failed", __func__);
    600         return ret;
    601     }
    602 
    603     return ret;
    604 }
    605 
    606 /*===========================================================================
    607  * FUNCTION   : processZoomDone
    608  *
    609  * DESCRIPTION: process zoom done event
    610  *
    611  * PARAMETERS :
    612  *   @previewWindoe : preview window ops table to set preview crop window
    613  *   @crop_info     : crop info
    614  *
    615  * RETURN     : int32_t type of status
    616  *              NO_ERROR  -- success
    617  *              none-zero failure code
    618  *==========================================================================*/
    619 int32_t QCameraStream::processZoomDone(preview_stream_ops_t *previewWindow,
    620                                        cam_crop_data_t &crop_info)
    621 {
    622     int32_t rc = 0;
    623 
    624     if (!m_bActive) {
    625         ALOGV("%s : Stream not active", __func__);
    626         return NO_ERROR;
    627     }
    628 
    629     // get stream param for crop info
    630     for (int i = 0; i < crop_info.num_of_streams; i++) {
    631         if (crop_info.crop_info[i].stream_id == mStreamInfo->stream_svr_id) {
    632             pthread_mutex_lock(&mCropLock);
    633             mCropInfo = crop_info.crop_info[i].crop;
    634             pthread_mutex_unlock(&mCropLock);
    635 
    636             // update preview window crop if it's preview/postview stream
    637             if ( (previewWindow != NULL) &&
    638                  (mStreamInfo->stream_type == CAM_STREAM_TYPE_PREVIEW ||
    639                   mStreamInfo->stream_type == CAM_STREAM_TYPE_POSTVIEW) ) {
    640                 rc = previewWindow->set_crop(previewWindow,
    641                                              mCropInfo.left,
    642                                              mCropInfo.top,
    643                                              mCropInfo.width,
    644                                              mCropInfo.height);
    645             }
    646             break;
    647         }
    648     }
    649     return rc;
    650 }
    651 
    652 /*===========================================================================
    653  * FUNCTION   : processDataNotify
    654  *
    655  * DESCRIPTION: process stream data notify
    656  *
    657  * PARAMETERS :
    658  *   @frame   : stream frame received
    659  *
    660  * RETURN     : int32_t type of status
    661  *              NO_ERROR  -- success
    662  *              none-zero failure code
    663  *==========================================================================*/
    664 int32_t QCameraStream::processDataNotify(mm_camera_super_buf_t *frame)
    665 {
    666     CDBG("%s:\n", __func__);
    667     if (mDataQ.enqueue((void *)frame)) {
    668         return mProcTh.sendCmd(CAMERA_CMD_TYPE_DO_NEXT_JOB, FALSE, FALSE);
    669     } else {
    670         CDBG_HIGH("%s: Stream thread is not active, no ops here", __func__);
    671         bufDone(frame->bufs[0]->buf_idx);
    672         free(frame);
    673         return NO_ERROR;
    674     }
    675 }
    676 
    677 /*===========================================================================
    678  * FUNCTION   : dataNotifyCB
    679  *
    680  * DESCRIPTION: callback for data notify. This function is registered with
    681  *              mm-camera-interface to handle data notify
    682  *
    683  * PARAMETERS :
    684  *   @recvd_frame   : stream frame received
    685  *   userdata       : user data ptr
    686  *
    687  * RETURN     : none
    688  *==========================================================================*/
    689 void QCameraStream::dataNotifyCB(mm_camera_super_buf_t *recvd_frame,
    690                                  void *userdata)
    691 {
    692     CDBG("%s:\n", __func__);
    693     QCameraStream* stream = (QCameraStream *)userdata;
    694     if (stream == NULL ||
    695         recvd_frame == NULL ||
    696         recvd_frame->bufs[0] == NULL ||
    697         recvd_frame->bufs[0]->stream_id != stream->getMyHandle()) {
    698         ALOGE("%s: Not a valid stream to handle buf", __func__);
    699         return;
    700     }
    701 
    702     mm_camera_super_buf_t *frame =
    703         (mm_camera_super_buf_t *)malloc(sizeof(mm_camera_super_buf_t));
    704     if (frame == NULL) {
    705         ALOGE("%s: No mem for mm_camera_buf_def_t", __func__);
    706         stream->bufDone(recvd_frame->bufs[0]->buf_idx);
    707         return;
    708     }
    709     *frame = *recvd_frame;
    710     stream->processDataNotify(frame);
    711     return;
    712 }
    713 
    714 /*===========================================================================
    715  * FUNCTION   : dataProcRoutine
    716  *
    717  * DESCRIPTION: function to process data in the main stream thread
    718  *
    719  * PARAMETERS :
    720  *   @data    : user data ptr
    721  *
    722  * RETURN     : none
    723  *==========================================================================*/
    724 void *QCameraStream::dataProcRoutine(void *data)
    725 {
    726     int running = 1;
    727     int ret;
    728     QCameraStream *pme = (QCameraStream *)data;
    729     QCameraCmdThread *cmdThread = &pme->mProcTh;
    730 
    731     CDBG("%s: E", __func__);
    732     do {
    733         do {
    734             ret = cam_sem_wait(&cmdThread->cmd_sem);
    735             if (ret != 0 && errno != EINVAL) {
    736                 ALOGE("%s: cam_sem_wait error (%s)",
    737                       __func__, strerror(errno));
    738                 return NULL;
    739             }
    740         } while (ret != 0);
    741 
    742         // we got notified about new cmd avail in cmd queue
    743         camera_cmd_type_t cmd = cmdThread->getCmd();
    744         switch (cmd) {
    745         case CAMERA_CMD_TYPE_DO_NEXT_JOB:
    746             {
    747                 CDBG_HIGH("%s: Do next job", __func__);
    748                 mm_camera_super_buf_t *frame =
    749                     (mm_camera_super_buf_t *)pme->mDataQ.dequeue();
    750                 if (NULL != frame) {
    751                     if (pme->mDataCB != NULL) {
    752                         pme->mDataCB(frame, pme, pme->mUserData);
    753                     } else {
    754                         // no data cb routine, return buf here
    755                         pme->bufDone(frame->bufs[0]->buf_idx);
    756                         free(frame);
    757                     }
    758                 }
    759             }
    760             break;
    761         case CAMERA_CMD_TYPE_EXIT:
    762             CDBG_HIGH("%s: Exit", __func__);
    763             /* flush data buf queue */
    764             pme->mDataQ.flush();
    765             running = 0;
    766             break;
    767         default:
    768             break;
    769         }
    770     } while (running);
    771     CDBG_HIGH("%s: X", __func__);
    772     return NULL;
    773 }
    774 
    775 /*===========================================================================
    776  * FUNCTION   : bufDone
    777  *
    778  * DESCRIPTION: return stream buffer to kernel
    779  *
    780  * PARAMETERS :
    781  *   @index   : index of buffer to be returned
    782  *
    783  * RETURN     : int32_t type of status
    784  *              NO_ERROR  -- success
    785  *              none-zero failure code
    786  *==========================================================================*/
    787 int32_t QCameraStream::bufDone(int index)
    788 {
    789     int32_t rc = NO_ERROR;
    790 
    791     if (index >= mNumBufs || mBufDefs == NULL)
    792         return BAD_INDEX;
    793 
    794     rc = mCamOps->qbuf(mCamHandle, mChannelHandle, &mBufDefs[index]);
    795     if (rc < 0)
    796         return rc;
    797 
    798     return rc;
    799 }
    800 
    801 /*===========================================================================
    802  * FUNCTION   : bufDone
    803  *
    804  * DESCRIPTION: return stream buffer to kernel
    805  *
    806  * PARAMETERS :
    807  *   @opaque    : stream frame/metadata buf to be returned
    808  *   @isMetaData: flag if returned opaque is a metadatabuf or the real frame ptr
    809  *
    810  * RETURN     : int32_t type of status
    811  *              NO_ERROR  -- success
    812  *              none-zero failure code
    813  *==========================================================================*/
    814 int32_t QCameraStream::bufDone(const void *opaque, bool isMetaData)
    815 {
    816     int32_t rc = NO_ERROR;
    817 
    818     int index = mStreamBufs->getMatchBufIndex(opaque, isMetaData);
    819     if (index == -1 || index >= mNumBufs || mBufDefs == NULL) {
    820         ALOGE("%s: Cannot find buf for opaque data = %p", __func__, opaque);
    821         return BAD_INDEX;
    822     }
    823     CDBG_HIGH("%s: Buffer Index = %d, Frame Idx = %d", __func__, index, mBufDefs[index].frame_idx);
    824     rc = bufDone(index);
    825     return rc;
    826 }
    827 
    828 /*===========================================================================
    829  * FUNCTION   : getBufs
    830  *
    831  * DESCRIPTION: allocate stream buffers
    832  *
    833  * PARAMETERS :
    834  *   @offset     : offset info of stream buffers
    835  *   @num_bufs   : number of buffers allocated
    836  *   @initial_reg_flag: flag to indicate if buffer needs to be registered
    837  *                      at kernel initially
    838  *   @bufs       : output of allocated buffers
    839  *   @ops_tbl    : ptr to buf mapping/unmapping ops
    840  *
    841  * RETURN     : int32_t type of status
    842  *              NO_ERROR  -- success
    843  *              none-zero failure code
    844  *==========================================================================*/
    845 int32_t QCameraStream::getBufs(cam_frame_len_offset_t *offset,
    846         uint8_t *num_bufs,
    847         uint8_t **initial_reg_flag,
    848         mm_camera_buf_def_t **bufs,
    849         mm_camera_map_unmap_ops_tbl_t *ops_tbl)
    850 {
    851     int rc = NO_ERROR;
    852     uint8_t *regFlags;
    853 
    854     if (!ops_tbl) {
    855         ALOGE("%s: ops_tbl is NULL", __func__);
    856         return INVALID_OPERATION;
    857     }
    858 
    859     mFrameLenOffset = *offset;
    860 
    861     uint8_t numBufAlloc = mNumBufs;
    862     mNumBufsNeedAlloc = 0;
    863     if (mDynBufAlloc) {
    864         numBufAlloc = CAMERA_MIN_ALLOCATED_BUFFERS;
    865         if (numBufAlloc > mNumBufs) {
    866             mDynBufAlloc = false;
    867             numBufAlloc = mNumBufs;
    868         } else {
    869             mNumBufsNeedAlloc = mNumBufs - numBufAlloc;
    870         }
    871     }
    872 
    873     //Allocate and map stream info buffer
    874     mStreamBufs = mAllocator.allocateStreamBuf(mStreamInfo->stream_type,
    875                                                mFrameLenOffset.frame_len,
    876                                                mFrameLenOffset.mp[0].stride,
    877                                                mFrameLenOffset.mp[0].scanline,
    878                                                numBufAlloc);
    879     mNumBufs = numBufAlloc + mNumBufsNeedAlloc;
    880 
    881     if (!mStreamBufs) {
    882         ALOGE("%s: Failed to allocate stream buffers", __func__);
    883         return NO_MEMORY;
    884     }
    885 
    886     for (int i = 0; i < numBufAlloc; i++) {
    887         rc = ops_tbl->map_ops(i, -1, mStreamBufs->getFd(i),
    888                 mStreamBufs->getSize(i), ops_tbl->userdata);
    889         if (rc < 0) {
    890             ALOGE("%s: map_stream_buf failed: %d", __func__, rc);
    891             for (int j = 0; j < i; j++) {
    892                 ops_tbl->unmap_ops(j, -1, ops_tbl->userdata);
    893             }
    894             mStreamBufs->deallocate();
    895             delete mStreamBufs;
    896             mStreamBufs = NULL;
    897             return INVALID_OPERATION;
    898         }
    899     }
    900 
    901     //regFlags array is allocated by us, but consumed and freed by mm-camera-interface
    902     regFlags = (uint8_t *)malloc(sizeof(uint8_t) * mNumBufs);
    903     if (!regFlags) {
    904         ALOGE("%s: Out of memory", __func__);
    905         for (int i = 0; i < numBufAlloc; i++) {
    906             ops_tbl->unmap_ops(i, -1, ops_tbl->userdata);
    907         }
    908         mStreamBufs->deallocate();
    909         delete mStreamBufs;
    910         mStreamBufs = NULL;
    911         return NO_MEMORY;
    912     }
    913     memset(regFlags, 0, sizeof(uint8_t) * mNumBufs);
    914 
    915     mBufDefs = (mm_camera_buf_def_t *)malloc(mNumBufs * sizeof(mm_camera_buf_def_t));
    916     if (mBufDefs == NULL) {
    917         ALOGE("%s: getRegFlags failed %d", __func__, rc);
    918         for (int i = 0; i < numBufAlloc; i++) {
    919             ops_tbl->unmap_ops(i, -1, ops_tbl->userdata);
    920         }
    921         mStreamBufs->deallocate();
    922         delete mStreamBufs;
    923         mStreamBufs = NULL;
    924         free(regFlags);
    925         regFlags = NULL;
    926         return INVALID_OPERATION;
    927     }
    928     memset(mBufDefs, 0, mNumBufs * sizeof(mm_camera_buf_def_t));
    929     for (int i = 0; i < numBufAlloc; i++) {
    930         mStreamBufs->getBufDef(mFrameLenOffset, mBufDefs[i], i);
    931     }
    932 
    933     rc = mStreamBufs->getRegFlags(regFlags);
    934     if (rc < 0) {
    935         ALOGE("%s: getRegFlags failed %d", __func__, rc);
    936         for (int i = 0; i < numBufAlloc; i++) {
    937             ops_tbl->unmap_ops(i, -1, ops_tbl->userdata);
    938         }
    939         mStreamBufs->deallocate();
    940         delete mStreamBufs;
    941         mStreamBufs = NULL;
    942         free(mBufDefs);
    943         mBufDefs = NULL;
    944         free(regFlags);
    945         regFlags = NULL;
    946         return INVALID_OPERATION;
    947     }
    948 
    949     *num_bufs = mNumBufs;
    950     *initial_reg_flag = regFlags;
    951     *bufs = mBufDefs;
    952 
    953     if (mNumBufsNeedAlloc > 0) {
    954         pthread_mutex_lock(&m_lock);
    955         wait_for_cond = TRUE;
    956         pthread_mutex_unlock(&m_lock);
    957         CDBG_HIGH("%s: Still need to allocate %d buffers",
    958               __func__, mNumBufsNeedAlloc);
    959         // remember memops table
    960         m_MemOpsTbl = *ops_tbl;
    961         // start another thread to allocate the rest of buffers
    962         pthread_create(&mBufAllocPid,
    963                        NULL,
    964                        BufAllocRoutine,
    965                        this);
    966     }
    967 
    968     return NO_ERROR;
    969 }
    970 
    971 /*===========================================================================
    972  * FUNCTION   : allocateBuffers
    973  *
    974  * DESCRIPTION: allocate stream buffers
    975  *
    976  * PARAMETERS :
    977  *
    978  * RETURN     : int32_t type of status
    979  *              NO_ERROR  -- success
    980  *              none-zero failure code
    981  *==========================================================================*/
    982 int32_t QCameraStream::allocateBuffers()
    983 {
    984     int rc = NO_ERROR;
    985 
    986     mFrameLenOffset = mStreamInfo->buf_planes.plane_info;
    987 
    988     //Allocate and map stream info buffer
    989     mStreamBufs = mAllocator.allocateStreamBuf(mStreamInfo->stream_type,
    990             mFrameLenOffset.frame_len,
    991             mFrameLenOffset.mp[0].stride,
    992             mFrameLenOffset.mp[0].scanline,
    993             mNumBufs);
    994 
    995     if (!mStreamBufs) {
    996         ALOGE("%s: Failed to allocate stream buffers", __func__);
    997         return NO_MEMORY;
    998     }
    999 
   1000     for (int i = 0; i < mNumBufs; i++) {
   1001         rc = mapBuf(CAM_MAPPING_BUF_TYPE_STREAM_BUF,
   1002                 i, -1,
   1003                 mStreamBufs->getFd(i),
   1004                 mStreamBufs->getSize(i));
   1005         if (rc < 0) {
   1006             ALOGE("%s: map_stream_buf failed: %d", __func__, rc);
   1007             for (int j = 0; j < i; j++) {
   1008                 unmapBuf(CAM_MAPPING_BUF_TYPE_STREAM_BUF, i, -1);
   1009             }
   1010             mStreamBufs->deallocate();
   1011             delete mStreamBufs;
   1012             mStreamBufs = NULL;
   1013             return INVALID_OPERATION;
   1014         }
   1015     }
   1016 
   1017     //regFlags array is allocated by us,
   1018     // but consumed and freed by mm-camera-interface
   1019     mRegFlags = (uint8_t *)malloc(sizeof(uint8_t) * mNumBufs);
   1020     if (!mRegFlags) {
   1021         ALOGE("%s: Out of memory", __func__);
   1022         for (int i = 0; i < mNumBufs; i++) {
   1023             unmapBuf(CAM_MAPPING_BUF_TYPE_STREAM_BUF, i, -1);
   1024         }
   1025         mStreamBufs->deallocate();
   1026         delete mStreamBufs;
   1027         mStreamBufs = NULL;
   1028         return NO_MEMORY;
   1029     }
   1030     memset(mRegFlags, 0, sizeof(uint8_t) * mNumBufs);
   1031 
   1032     size_t bufDefsSize = mNumBufs * sizeof(mm_camera_buf_def_t);
   1033     mBufDefs = (mm_camera_buf_def_t *)malloc(bufDefsSize);
   1034     if (mBufDefs == NULL) {
   1035         ALOGE("%s: getRegFlags failed %d", __func__, rc);
   1036         for (int i = 0; i < mNumBufs; i++) {
   1037             unmapBuf(CAM_MAPPING_BUF_TYPE_STREAM_BUF, i, -1);
   1038         }
   1039         mStreamBufs->deallocate();
   1040         delete mStreamBufs;
   1041         mStreamBufs = NULL;
   1042         free(mRegFlags);
   1043         mRegFlags = NULL;
   1044         return INVALID_OPERATION;
   1045     }
   1046     memset(mBufDefs, 0, bufDefsSize);
   1047     for (int i = 0; i < mNumBufs; i++) {
   1048         mStreamBufs->getBufDef(mFrameLenOffset, mBufDefs[i], i);
   1049     }
   1050 
   1051     rc = mStreamBufs->getRegFlags(mRegFlags);
   1052     if (rc < 0) {
   1053         ALOGE("%s: getRegFlags failed %d", __func__, rc);
   1054         for (int i = 0; i < mNumBufs; i++) {
   1055             unmapBuf(CAM_MAPPING_BUF_TYPE_STREAM_BUF, i, -1);
   1056         }
   1057         mStreamBufs->deallocate();
   1058         delete mStreamBufs;
   1059         mStreamBufs = NULL;
   1060         free(mBufDefs);
   1061         mBufDefs = NULL;
   1062         free(mRegFlags);
   1063         mRegFlags = NULL;
   1064         return INVALID_OPERATION;
   1065     }
   1066 
   1067     return NO_ERROR;
   1068 }
   1069 
   1070 
   1071 /*===========================================================================
   1072  * FUNCTION   : releaseBuffs
   1073  *
   1074  * DESCRIPTION: method to deallocate stream buffers
   1075  *
   1076  * PARAMETERS :
   1077  *
   1078  * RETURN     : int32_t type of status
   1079  *              NO_ERROR  -- success
   1080  *              none-zero failure code
   1081  *==========================================================================*/
   1082 int32_t QCameraStream::releaseBuffs()
   1083 {
   1084     int rc = NO_ERROR;
   1085 
   1086     if (NULL != mBufDefs) {
   1087         for (int i = 0; i < mNumBufs; i++) {
   1088             rc = unmapBuf(CAM_MAPPING_BUF_TYPE_STREAM_BUF, i, -1);
   1089             if (rc < 0) {
   1090                 ALOGE("%s: map_stream_buf failed: %d", __func__, rc);
   1091             }
   1092         }
   1093 
   1094         // mBufDefs just keep a ptr to the buffer
   1095         // mm-camera-interface own the buffer, so no need to free
   1096         mBufDefs = NULL;
   1097         memset(&mFrameLenOffset, 0, sizeof(mFrameLenOffset));
   1098     }
   1099     if ( !mStreamBufsAcquired ) {
   1100         mStreamBufs->deallocate();
   1101         delete mStreamBufs;
   1102     }
   1103 
   1104     return rc;
   1105 }
   1106 
   1107 
   1108 /*===========================================================================
   1109  * FUNCTION   : BufAllocRoutine
   1110  *
   1111  * DESCRIPTION: function to allocate additional stream buffers
   1112  *
   1113  * PARAMETERS :
   1114  *   @data    : user data ptr
   1115  *
   1116  * RETURN     : none
   1117  *==========================================================================*/
   1118 void *QCameraStream::BufAllocRoutine(void *data)
   1119 {
   1120     QCameraStream *pme = (QCameraStream *)data;
   1121     int32_t rc = NO_ERROR;
   1122 
   1123     CDBG_HIGH("%s: E", __func__);
   1124     pme->cond_wait();
   1125     if (pme->mNumBufsNeedAlloc > 0) {
   1126         uint8_t numBufAlloc = pme->mNumBufs - pme->mNumBufsNeedAlloc;
   1127         rc = pme->mAllocator.allocateMoreStreamBuf(pme->mStreamBufs,
   1128                                                    pme->mFrameLenOffset.frame_len,
   1129                                                    pme->mNumBufsNeedAlloc);
   1130         if (rc == NO_ERROR){
   1131             for (int i = numBufAlloc; i < pme->mNumBufs; i++) {
   1132                 rc = pme->m_MemOpsTbl.map_ops(i, -1,
   1133                                               pme->mStreamBufs->getFd(i),
   1134                                               pme->mStreamBufs->getSize(i),
   1135                                               pme->m_MemOpsTbl.userdata);
   1136                 if (rc == 0) {
   1137                     pme->mStreamBufs->getBufDef(pme->mFrameLenOffset,
   1138                                                 pme->mBufDefs[i], i);
   1139                     pme->mCamOps->qbuf(pme->mCamHandle,
   1140                                        pme->mChannelHandle,
   1141                                        &pme->mBufDefs[i]);
   1142                 } else {
   1143                     ALOGE("%s: map_stream_buf %d failed: %d", __func__, rc, i);
   1144                 }
   1145             }
   1146 
   1147             pme->mNumBufsNeedAlloc = 0;
   1148         }
   1149     }
   1150     CDBG_HIGH("%s: X", __func__);
   1151     return NULL;
   1152 }
   1153 
   1154 /*===========================================================================
   1155  * FUNCTION   : cond_signal
   1156  *
   1157  * DESCRIPTION: signal if flag "wait_for_cond" is set
   1158  *
   1159  *==========================================================================*/
   1160 void QCameraStream::cond_signal()
   1161 {
   1162     pthread_mutex_lock(&m_lock);
   1163     if(wait_for_cond == TRUE){
   1164         wait_for_cond = FALSE;
   1165         pthread_cond_signal(&m_cond);
   1166     }
   1167     pthread_mutex_unlock(&m_lock);
   1168 }
   1169 
   1170 
   1171 /*===========================================================================
   1172  * FUNCTION   : cond_wait
   1173  *
   1174  * DESCRIPTION: wait on if flag "wait_for_cond" is set
   1175  *
   1176  *==========================================================================*/
   1177 void QCameraStream::cond_wait()
   1178 {
   1179     pthread_mutex_lock(&m_lock);
   1180     while (wait_for_cond == TRUE) {
   1181         pthread_cond_wait(&m_cond, &m_lock);
   1182     }
   1183     pthread_mutex_unlock(&m_lock);
   1184 }
   1185 
   1186 /*===========================================================================
   1187  * FUNCTION   : putBufs
   1188  *
   1189  * DESCRIPTION: deallocate stream buffers
   1190  *
   1191  * PARAMETERS :
   1192  *   @ops_tbl    : ptr to buf mapping/unmapping ops
   1193  *
   1194  * RETURN     : int32_t type of status
   1195  *              NO_ERROR  -- success
   1196  *              none-zero failure code
   1197  *==========================================================================*/
   1198 int32_t QCameraStream::putBufs(mm_camera_map_unmap_ops_tbl_t *ops_tbl)
   1199 {
   1200     int rc = NO_ERROR;
   1201 
   1202     if (mBufAllocPid != 0) {
   1203         CDBG_HIGH("%s: wait for buf allocation thread dead", __func__);
   1204         pthread_join(mBufAllocPid, NULL);
   1205         mBufAllocPid = 0;
   1206         CDBG_HIGH("%s: return from buf allocation thread", __func__);
   1207     }
   1208 
   1209     for (int i = 0; i < mNumBufs; i++) {
   1210         rc = ops_tbl->unmap_ops(i, -1, ops_tbl->userdata);
   1211         if (rc < 0) {
   1212             ALOGE("%s: map_stream_buf failed: %d", __func__, rc);
   1213         }
   1214     }
   1215     mBufDefs = NULL; // mBufDefs just keep a ptr to the buffer
   1216                      // mm-camera-interface own the buffer, so no need to free
   1217     memset(&mFrameLenOffset, 0, sizeof(mFrameLenOffset));
   1218     if ( !mStreamBufsAcquired ) {
   1219         mStreamBufs->deallocate();
   1220         delete mStreamBufs;
   1221     }
   1222 
   1223     return rc;
   1224 }
   1225 
   1226 /*===========================================================================
   1227  * FUNCTION   : invalidateBuf
   1228  *
   1229  * DESCRIPTION: invalidate a specific stream buffer
   1230  *
   1231  * PARAMETERS :
   1232  *   @index   : index of the buffer to invalidate
   1233  *
   1234  * RETURN     : int32_t type of status
   1235  *              NO_ERROR  -- success
   1236  *              none-zero failure code
   1237  *==========================================================================*/
   1238 int32_t QCameraStream::invalidateBuf(int index)
   1239 {
   1240     return mStreamBufs->invalidateCache(index);
   1241 }
   1242 
   1243 /*===========================================================================
   1244  * FUNCTION   : cleanInvalidateBuf
   1245  *
   1246  * DESCRIPTION: clean invalidate a specific stream buffer
   1247  *
   1248  * PARAMETERS :
   1249  *   @index   : index of the buffer to clean invalidate
   1250  *
   1251  * RETURN     : int32_t type of status
   1252  *              NO_ERROR  -- success
   1253  *              none-zero failure code
   1254  *==========================================================================*/
   1255 int32_t QCameraStream::cleanInvalidateBuf(int index)
   1256 {
   1257     return mStreamBufs->cleanInvalidateCache(index);
   1258 }
   1259 
   1260 /*===========================================================================
   1261  * FUNCTION   : isTypeOf
   1262  *
   1263  * DESCRIPTION: helper function to determine if the stream is of the queried type
   1264  *
   1265  * PARAMETERS :
   1266  *   @type    : stream type as of queried
   1267  *
   1268  * RETURN     : true/false
   1269  *==========================================================================*/
   1270 bool QCameraStream::isTypeOf(cam_stream_type_t type)
   1271 {
   1272     if (mStreamInfo != NULL && (mStreamInfo->stream_type == type)) {
   1273         return true;
   1274     } else {
   1275         return false;
   1276     }
   1277 }
   1278 
   1279 /*===========================================================================
   1280  * FUNCTION   : isOrignalTypeOf
   1281  *
   1282  * DESCRIPTION: helper function to determine if the original stream is of the
   1283  *              queried type if it's reproc stream
   1284  *
   1285  * PARAMETERS :
   1286  *   @type    : stream type as of queried
   1287  *
   1288  * RETURN     : true/false
   1289  *==========================================================================*/
   1290 bool QCameraStream::isOrignalTypeOf(cam_stream_type_t type)
   1291 {
   1292     if (mStreamInfo != NULL &&
   1293         mStreamInfo->stream_type == CAM_STREAM_TYPE_OFFLINE_PROC &&
   1294         mStreamInfo->reprocess_config.pp_type == CAM_ONLINE_REPROCESS_TYPE &&
   1295         mStreamInfo->reprocess_config.online.input_stream_type == type) {
   1296         return true;
   1297     } else if (
   1298         mStreamInfo != NULL &&
   1299         mStreamInfo->stream_type == CAM_STREAM_TYPE_OFFLINE_PROC &&
   1300         mStreamInfo->reprocess_config.pp_type == CAM_OFFLINE_REPROCESS_TYPE &&
   1301         mStreamInfo->reprocess_config.offline.input_type == type) {
   1302         return true;
   1303     } else {
   1304         return false;
   1305     }
   1306 }
   1307 
   1308 /*===========================================================================
   1309  * FUNCTION   : getMyType
   1310  *
   1311  * DESCRIPTION: return stream type
   1312  *
   1313  * PARAMETERS : none
   1314  *
   1315  * RETURN     : stream type
   1316  *==========================================================================*/
   1317 cam_stream_type_t QCameraStream::getMyType()
   1318 {
   1319     if (mStreamInfo != NULL) {
   1320         return mStreamInfo->stream_type;
   1321     } else {
   1322         return CAM_STREAM_TYPE_DEFAULT;
   1323     }
   1324 }
   1325 
   1326 /*===========================================================================
   1327  * FUNCTION   : getFrameOffset
   1328  *
   1329  * DESCRIPTION: query stream buffer frame offset info
   1330  *
   1331  * PARAMETERS :
   1332  *   @offset  : reference to struct to store the queried frame offset info
   1333  *
   1334  * RETURN     : int32_t type of status
   1335  *              NO_ERROR  -- success
   1336  *              none-zero failure code
   1337  *==========================================================================*/
   1338 int32_t QCameraStream::getFrameOffset(cam_frame_len_offset_t &offset)
   1339 {
   1340     offset = mFrameLenOffset;
   1341     return 0;
   1342 }
   1343 
   1344 /*===========================================================================
   1345  * FUNCTION   : getCropInfo
   1346  *
   1347  * DESCRIPTION: query crop info of the stream
   1348  *
   1349  * PARAMETERS :
   1350  *   @crop    : reference to struct to store the queried crop info
   1351  *
   1352  * RETURN     : int32_t type of status
   1353  *              NO_ERROR  -- success
   1354  *              none-zero failure code
   1355  *==========================================================================*/
   1356 int32_t QCameraStream::getCropInfo(cam_rect_t &crop)
   1357 {
   1358     pthread_mutex_lock(&mCropLock);
   1359     crop = mCropInfo;
   1360     pthread_mutex_unlock(&mCropLock);
   1361     return NO_ERROR;
   1362 }
   1363 
   1364 /*===========================================================================
   1365  * FUNCTION   : setCropInfo
   1366  *
   1367  * DESCRIPTION: set crop info of the stream
   1368  *
   1369  * PARAMETERS :
   1370  *   @crop    : struct to store new crop info
   1371  *
   1372  * RETURN     : int32_t type of status
   1373  *              NO_ERROR  -- success
   1374  *              none-zero failure code
   1375  *==========================================================================*/
   1376 int32_t QCameraStream::setCropInfo(cam_rect_t crop)
   1377 {
   1378     pthread_mutex_lock(&mCropLock);
   1379     mCropInfo = crop;
   1380     pthread_mutex_unlock(&mCropLock);
   1381     return NO_ERROR;
   1382 }
   1383 
   1384 /*===========================================================================
   1385  * FUNCTION   : getFrameDimension
   1386  *
   1387  * DESCRIPTION: query stream frame dimension info
   1388  *
   1389  * PARAMETERS :
   1390  *   @dim     : reference to struct to store the queried frame dimension
   1391  *
   1392  * RETURN     : int32_t type of status
   1393  *              NO_ERROR  -- success
   1394  *              none-zero failure code
   1395  *==========================================================================*/
   1396 int32_t QCameraStream::getFrameDimension(cam_dimension_t &dim)
   1397 {
   1398     if (mStreamInfo != NULL) {
   1399         dim = mStreamInfo->dim;
   1400         return 0;
   1401     }
   1402     return -1;
   1403 }
   1404 
   1405 /*===========================================================================
   1406  * FUNCTION   : getFormat
   1407  *
   1408  * DESCRIPTION: query stream format
   1409  *
   1410  * PARAMETERS :
   1411  *   @fmt     : reference to stream format
   1412  *
   1413  * RETURN     : int32_t type of status
   1414  *              NO_ERROR  -- success
   1415  *              none-zero failure code
   1416  *==========================================================================*/
   1417 int32_t QCameraStream::getFormat(cam_format_t &fmt)
   1418 {
   1419     if (mStreamInfo != NULL) {
   1420         fmt = mStreamInfo->fmt;
   1421         return 0;
   1422     }
   1423     return -1;
   1424 }
   1425 
   1426 /*===========================================================================
   1427  * FUNCTION   : getMyServerID
   1428  *
   1429  * DESCRIPTION: query server stream ID
   1430  *
   1431  * PARAMETERS : None
   1432  *
   1433  * RETURN     : stream ID from server
   1434  *==========================================================================*/
   1435 uint32_t QCameraStream::getMyServerID() {
   1436     if (mStreamInfo != NULL) {
   1437         return mStreamInfo->stream_svr_id;
   1438     } else {
   1439         return 0;
   1440     }
   1441 }
   1442 
   1443 /*===========================================================================
   1444  * FUNCTION   : acquireStreamBufs
   1445  *
   1446  * DESCRIPTION: acquire stream buffers and postpone their release.
   1447  *
   1448  * PARAMETERS : None
   1449  *
   1450  * RETURN     : int32_t type of status
   1451  *              NO_ERROR  -- success
   1452  *              none-zero failure code
   1453  *==========================================================================*/
   1454 int32_t QCameraStream::acquireStreamBufs()
   1455 {
   1456     mStreamBufsAcquired = true;
   1457 
   1458     return NO_ERROR;
   1459 }
   1460 
   1461 /*===========================================================================
   1462  * FUNCTION   : mapBuf
   1463  *
   1464  * DESCRIPTION: map stream related buffer to backend server
   1465  *
   1466  * PARAMETERS :
   1467  *   @buf_type : mapping type of buffer
   1468  *   @buf_idx  : index of buffer
   1469  *   @plane_idx: plane index
   1470  *   @fd       : fd of the buffer
   1471  *   @size     : lenght of the buffer
   1472  *
   1473  * RETURN     : int32_t type of status
   1474  *              NO_ERROR  -- success
   1475  *              none-zero failure code
   1476  *==========================================================================*/
   1477 int32_t QCameraStream::mapBuf(uint8_t buf_type,
   1478                               uint32_t buf_idx,
   1479                               int32_t plane_idx,
   1480                               int fd,
   1481                               uint32_t size)
   1482 {
   1483     return mCamOps->map_stream_buf(mCamHandle, mChannelHandle,
   1484                                    mHandle, buf_type,
   1485                                    buf_idx, plane_idx,
   1486                                    fd, size);
   1487 
   1488 }
   1489 
   1490 /*===========================================================================
   1491  * FUNCTION   : unmapBuf
   1492  *
   1493  * DESCRIPTION: unmap stream related buffer to backend server
   1494  *
   1495  * PARAMETERS :
   1496  *   @buf_type : mapping type of buffer
   1497  *   @buf_idx  : index of buffer
   1498  *   @plane_idx: plane index
   1499  *
   1500  * RETURN     : int32_t type of status
   1501  *              NO_ERROR  -- success
   1502  *              none-zero failure code
   1503  *==========================================================================*/
   1504 int32_t QCameraStream::unmapBuf(uint8_t buf_type, uint32_t buf_idx, int32_t plane_idx)
   1505 {
   1506     return mCamOps->unmap_stream_buf(mCamHandle, mChannelHandle,
   1507                                      mHandle, buf_type,
   1508                                      buf_idx, plane_idx);
   1509 
   1510 }
   1511 
   1512 /*===========================================================================
   1513  * FUNCTION   : setParameter
   1514  *
   1515  * DESCRIPTION: set stream based parameters
   1516  *
   1517  * PARAMETERS :
   1518  *   @param   : ptr to parameters to be set
   1519  *
   1520  * RETURN     : int32_t type of status
   1521  *              NO_ERROR  -- success
   1522  *              none-zero failure code
   1523  *==========================================================================*/
   1524 int32_t QCameraStream::setParameter(cam_stream_parm_buffer_t &param)
   1525 {
   1526     int32_t rc = NO_ERROR;
   1527     pthread_mutex_lock(&mParameterLock);
   1528     mStreamInfo->parm_buf = param;
   1529     rc = mCamOps->set_stream_parms(mCamHandle,
   1530                                    mChannelHandle,
   1531                                    mHandle,
   1532                                    &mStreamInfo->parm_buf);
   1533     if (rc == NO_ERROR) {
   1534         param = mStreamInfo->parm_buf;
   1535     }
   1536     pthread_mutex_unlock(&mParameterLock);
   1537     return rc;
   1538 }
   1539 
   1540 /*===========================================================================
   1541  * FUNCTION   : getParameter
   1542  *
   1543  * DESCRIPTION: get stream based parameters
   1544  *
   1545  * PARAMETERS :
   1546  *   @param   : ptr to parameters to be red
   1547  *
   1548  * RETURN     : int32_t type of status
   1549  *              NO_ERROR  -- success
   1550  *              none-zero failure code
   1551  *==========================================================================*/
   1552 int32_t QCameraStream::getParameter(cam_stream_parm_buffer_t &param)
   1553 {
   1554     int32_t rc = NO_ERROR;
   1555     pthread_mutex_lock(&mParameterLock);
   1556     mStreamInfo->parm_buf = param;
   1557     rc = mCamOps->get_stream_parms(mCamHandle,
   1558                                    mChannelHandle,
   1559                                    mHandle,
   1560                                    &mStreamInfo->parm_buf);
   1561     if (rc == NO_ERROR) {
   1562         param = mStreamInfo->parm_buf;
   1563     }
   1564     pthread_mutex_unlock(&mParameterLock);
   1565     return rc;
   1566 }
   1567 
   1568 /*===========================================================================
   1569  * FUNCTION   : releaseFrameData
   1570  *
   1571  * DESCRIPTION: callback function to release frame data node
   1572  *
   1573  * PARAMETERS :
   1574  *   @data      : ptr to post process input data
   1575  *   @user_data : user data ptr (QCameraReprocessor)
   1576  *
   1577  * RETURN     : None
   1578  *==========================================================================*/
   1579 void QCameraStream::releaseFrameData(void *data, void *user_data)
   1580 {
   1581     QCameraStream *pme = (QCameraStream *)user_data;
   1582     mm_camera_super_buf_t *frame = (mm_camera_super_buf_t *)data;
   1583     if (NULL != pme) {
   1584         pme->bufDone(frame->bufs[0]->buf_idx);
   1585     }
   1586 }
   1587 
   1588 /*===========================================================================
   1589  * FUNCTION   : configStream
   1590  *
   1591  * DESCRIPTION: send stream configuration to back end
   1592  *
   1593  * PARAMETERS :
   1594  *
   1595  * RETURN     : int32_t type of status
   1596  *              NO_ERROR  -- success
   1597  *              none-zero failure code
   1598  *==========================================================================*/
   1599 int32_t QCameraStream::configStream()
   1600 {
   1601     int rc = NO_ERROR;
   1602 
   1603     // Configure the stream
   1604     mm_camera_stream_config_t stream_config;
   1605     stream_config.stream_info = mStreamInfo;
   1606     stream_config.mem_vtbl = mMemVtbl;
   1607     stream_config.stream_cb = dataNotifyCB;
   1608     stream_config.padding_info = mPaddingInfo;
   1609     stream_config.userdata = this;
   1610     rc = mCamOps->config_stream(mCamHandle,
   1611                 mChannelHandle, mHandle, &stream_config);
   1612     if (rc < 0) {
   1613         ALOGE("Failed to config stream, rc = %d", rc);
   1614         mCamOps->unmap_stream_buf(mCamHandle,
   1615                 mChannelHandle,
   1616                 mHandle,
   1617                 CAM_MAPPING_BUF_TYPE_STREAM_INFO,
   1618                 0,
   1619                 -1);
   1620         return UNKNOWN_ERROR;
   1621     }
   1622 
   1623     return rc;
   1624 }
   1625 
   1626 }; // namespace qcamera
   1627