Home | History | Annotate | Download | only in HAL
      1 /* Copyright (c) 2012-2016, The Linux Foundation. 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 // System dependencies
     33 #include <utils/Errors.h>
     34 
     35 // Camera dependencies
     36 #include "QCameraBufferMaps.h"
     37 #include "QCamera2HWI.h"
     38 #include "QCameraStream.h"
     39 
     40 extern "C" {
     41 #include "mm_camera_dbg.h"
     42 }
     43 
     44 #define CAMERA_MIN_ALLOCATED_BUFFERS     3
     45 
     46 namespace qcamera {
     47 
     48 /*===========================================================================
     49  * FUNCTION   : get_bufs
     50  *
     51  * DESCRIPTION: static function entry to allocate stream buffers
     52  *
     53  * PARAMETERS :
     54  *   @offset     : offset info of stream buffers
     55  *   @num_bufs   : number of buffers allocated
     56  *   @initial_reg_flag: flag to indicate if buffer needs to be registered
     57  *                      at kernel initially
     58  *   @bufs       : output of allocated buffers
     59  *   @ops_tbl    : ptr to buf mapping/unmapping ops
     60  *   @user_data  : user data ptr of ops_tbl
     61  *
     62  * RETURN     : int32_t type of status
     63  *              NO_ERROR  -- success
     64  *              none-zero failure code
     65  *==========================================================================*/
     66 int32_t QCameraStream::get_bufs(
     67                      cam_frame_len_offset_t *offset,
     68                      uint8_t *num_bufs,
     69                      uint8_t **initial_reg_flag,
     70                      mm_camera_buf_def_t **bufs,
     71                      mm_camera_map_unmap_ops_tbl_t *ops_tbl,
     72                      void *user_data)
     73 {
     74     QCameraStream *stream = reinterpret_cast<QCameraStream *>(user_data);
     75     if (!stream) {
     76         LOGE("getBufs invalid stream pointer");
     77         return NO_MEMORY;
     78     }
     79 
     80     if (stream->mStreamInfo != NULL
     81             && stream->mStreamInfo->streaming_mode == CAM_STREAMING_MODE_BATCH) {
     82         //Batch Mode. Allocate Butch buffers
     83         return stream->allocateBatchBufs(offset, num_bufs,
     84                 initial_reg_flag, bufs, ops_tbl);
     85     } else {
     86         // Plane Buffer. Allocate plane buffer
     87         return stream->getBufs(offset, num_bufs,
     88                 initial_reg_flag, bufs, ops_tbl);
     89     }
     90 }
     91 
     92 /*===========================================================================
     93  * FUNCTION   : get_bufs_deffered
     94  *
     95  * DESCRIPTION: static function entry to allocate deffered stream buffers
     96  *
     97  * PARAMETERS :
     98  *   @offset     : offset info of stream buffers
     99  *   @num_bufs   : number of buffers allocated
    100  *   @initial_reg_flag: flag to indicate if buffer needs to be registered
    101  *                      at kernel initially
    102  *   @bufs       : output of allocated buffers
    103  *   @ops_tbl    : ptr to buf mapping/unmapping ops
    104  *   @user_data  : user data ptr of ops_tbl
    105  *
    106  * RETURN     : int32_t type of status
    107  *              NO_ERROR  -- success
    108  *              none-zero failure code
    109  *==========================================================================*/
    110 int32_t QCameraStream::get_bufs_deffered(
    111         cam_frame_len_offset_t * /* offset */,
    112         uint8_t *num_bufs,
    113         uint8_t **initial_reg_flag,
    114         mm_camera_buf_def_t **bufs,
    115         mm_camera_map_unmap_ops_tbl_t * ops_tbl,
    116         void *user_data)
    117 {
    118     QCameraStream *stream = reinterpret_cast<QCameraStream *>(user_data);
    119 
    120     if (!stream) {
    121         LOGE("getBufs invalid stream pointer");
    122         return NO_MEMORY;
    123     }
    124 
    125     return stream->getBufsDeferred(NULL /*offset*/, num_bufs, initial_reg_flag, bufs,
    126             ops_tbl);
    127 }
    128 
    129 /*===========================================================================
    130  * FUNCTION   : put_bufs
    131  *
    132  * DESCRIPTION: static function entry to deallocate stream buffers
    133  *
    134  * PARAMETERS :
    135  *   @ops_tbl    : ptr to buf mapping/unmapping ops
    136  *   @user_data  : user data ptr of ops_tbl
    137  *
    138  * RETURN     : int32_t type of status
    139  *              NO_ERROR  -- success
    140  *              none-zero failure code
    141  *==========================================================================*/
    142 int32_t QCameraStream::put_bufs(
    143         mm_camera_map_unmap_ops_tbl_t *ops_tbl,
    144         void *user_data)
    145 {
    146     QCameraStream *stream = reinterpret_cast<QCameraStream *>(user_data);
    147     if (!stream) {
    148         LOGE("putBufs invalid stream pointer");
    149         return NO_MEMORY;
    150     }
    151 
    152     if (stream->mStreamInfo != NULL
    153             && stream->mStreamInfo->streaming_mode == CAM_STREAMING_MODE_BATCH) {
    154         //Batch Mode. release  Butch buffers
    155         return stream->releaseBatchBufs(ops_tbl);
    156     } else {
    157         // Plane Buffer. release  plane buffer
    158         return stream->putBufs(ops_tbl);
    159     }
    160 
    161 }
    162 
    163 /*===========================================================================
    164  * FUNCTION   : put_bufs_deffered
    165  *
    166  * DESCRIPTION: static function entry to deallocate deffered stream buffers
    167  *
    168  * PARAMETERS :
    169  *   @ops_tbl    : ptr to buf mapping/unmapping ops
    170  *   @user_data  : user data ptr of ops_tbl
    171  *
    172  * RETURN     : int32_t type of status
    173  *              NO_ERROR  -- success
    174  *              none-zero failure code
    175  *==========================================================================*/
    176 int32_t QCameraStream::put_bufs_deffered(
    177         mm_camera_map_unmap_ops_tbl_t * /*ops_tbl */,
    178         void * user_data )
    179 {
    180     QCameraStream *stream = reinterpret_cast<QCameraStream *>(user_data);
    181 
    182     if (!stream) {
    183         LOGE("put_bufs_deffered invalid stream pointer");
    184         return NO_MEMORY;
    185     }
    186 
    187     return stream->putBufsDeffered();
    188 }
    189 
    190 /*===========================================================================
    191  * FUNCTION   : invalidate_buf
    192  *
    193  * DESCRIPTION: static function entry to invalidate a specific stream buffer
    194  *
    195  * PARAMETERS :
    196  *   @index      : index of the stream buffer to invalidate
    197  *   @user_data  : user data ptr of ops_tbl
    198  *
    199  * RETURN     : int32_t type of status
    200  *              NO_ERROR  -- success
    201  *              none-zero failure code
    202  *==========================================================================*/
    203 int32_t QCameraStream::invalidate_buf(uint32_t index, void *user_data)
    204 {
    205     QCameraStream *stream = reinterpret_cast<QCameraStream *>(user_data);
    206     if (!stream) {
    207         LOGE("invalid stream pointer");
    208         return NO_MEMORY;
    209     }
    210 
    211     if (stream->mStreamInfo->is_secure == SECURE){
    212         return 0;
    213     }
    214 
    215     if (stream->mStreamInfo->streaming_mode == CAM_STREAMING_MODE_BATCH) {
    216         for (int i = 0; i < stream->mBufDefs[index].user_buf.bufs_used; i++) {
    217             uint32_t buf_idx = stream->mBufDefs[index].user_buf.buf_idx[i];
    218             stream->invalidateBuf(buf_idx);
    219         }
    220     } else {
    221         return stream->invalidateBuf(index);
    222     }
    223 
    224     return 0;
    225 }
    226 
    227 /*===========================================================================
    228  * FUNCTION   : clean_invalidate_buf
    229  *
    230  * DESCRIPTION: static function entry to clean invalidate a specific stream buffer
    231  *
    232  * PARAMETERS :
    233  *   @index      : index of the stream buffer to clean invalidate
    234  *   @user_data  : user data ptr of ops_tbl
    235  *
    236  * RETURN     : int32_t type of status
    237  *              NO_ERROR  -- success
    238  *              none-zero failure code
    239  *==========================================================================*/
    240 int32_t QCameraStream::clean_invalidate_buf(uint32_t index, void *user_data)
    241 {
    242     QCameraStream *stream = reinterpret_cast<QCameraStream *>(user_data);
    243     if (!stream) {
    244         LOGE("invalid stream pointer");
    245         return NO_MEMORY;
    246     }
    247 
    248     if (stream->mStreamInfo->is_secure == SECURE){
    249         return 0;
    250     }
    251 
    252     if (stream->mStreamInfo->streaming_mode == CAM_STREAMING_MODE_BATCH) {
    253         for (int i = 0; i < stream->mBufDefs[index].user_buf.bufs_used; i++) {
    254             uint32_t buf_idx = stream->mBufDefs[index].user_buf.buf_idx[i];
    255             stream->cleanInvalidateBuf(buf_idx);
    256         }
    257     } else {
    258         return stream->cleanInvalidateBuf(index);
    259     }
    260 
    261     return 0;
    262 }
    263 
    264 /*===========================================================================
    265  * FUNCTION   : set_config_ops
    266  *
    267  * DESCRIPTION: static function update mm-interface ops functions
    268  *
    269  * PARAMETERS :
    270  *   @ops_tbl    : ptr to buf mapping/unmapping ops
    271  *   @user_data  : user data ptr of ops_tbl
    272  *
    273  * RETURN     : int32_t type of status
    274  *              NO_ERROR  -- success
    275  *              none-zero failure code
    276  *==========================================================================*/
    277 int32_t QCameraStream::set_config_ops(mm_camera_map_unmap_ops_tbl_t *ops_tbl,
    278         void *user_data)
    279 {
    280     QCameraStream *stream = reinterpret_cast<QCameraStream *>(user_data);
    281     if (!stream) {
    282         LOGE("Stream invalid");
    283         return NO_MEMORY;
    284     }
    285 
    286     stream->m_MemOpsTbl = *ops_tbl;
    287     return 0;
    288 }
    289 
    290 /*===========================================================================
    291  * FUNCTION   : QCameraStream
    292  *
    293  * DESCRIPTION: constructor of QCameraStream
    294  *
    295  * PARAMETERS :
    296  *   @allocator  : memory allocator obj
    297  *   @camHandle  : camera handle
    298  *   @chId       : channel handle
    299  *   @camOps     : ptr to camera ops table
    300  *   @paddingInfo: ptr to padding info
    301  *   @deffered   : deferred stream
    302  *   @online_rotation: rotation applied online
    303  *
    304  * RETURN     : None
    305  *==========================================================================*/
    306 QCameraStream::QCameraStream(QCameraAllocator &allocator,
    307         uint32_t camHandle, uint32_t chId,
    308         mm_camera_ops_t *camOps, cam_padding_info_t *paddingInfo,
    309         bool deffered, cam_rotation_t online_rotation):
    310         mDumpFrame(0),
    311         mDumpMetaFrame(0),
    312         mDumpSkipCnt(0),
    313         mStreamTimestamp(0),
    314         mCamHandle(camHandle),
    315         mChannelHandle(chId),
    316         mHandle(0),
    317         mCamOps(camOps),
    318         mStreamInfo(NULL),
    319         mNumBufs(0),
    320         mNumPlaneBufs(0),
    321         mNumBufsNeedAlloc(0),
    322         mRegFlags(NULL),
    323         mDataCB(NULL),
    324         mSYNCDataCB(NULL),
    325         mUserData(NULL),
    326         mDataQ(releaseFrameData, this),
    327         mStreamInfoBuf(NULL),
    328         mMiscBuf(NULL),
    329         mStreamBufs(NULL),
    330         mStreamBatchBufs(NULL),
    331         mAllocator(allocator),
    332         mBufDefs(NULL),
    333         mPlaneBufDefs(NULL),
    334         mOnlineRotation(online_rotation),
    335         mStreamBufsAcquired(false),
    336         m_bActive(false),
    337         mDynBufAlloc(false),
    338         mBufAllocPid(0),
    339         mDefferedAllocation(deffered),
    340         wait_for_cond(false),
    341         mAllocTaskId(0),
    342         mMapTaskId(0),
    343         mSyncCBEnabled(false)
    344 {
    345     mMemVtbl.user_data = this;
    346     if ( !deffered ) {
    347         mMemVtbl.get_bufs = get_bufs;
    348         mMemVtbl.put_bufs = put_bufs;
    349     } else {
    350         mMemVtbl.get_bufs = get_bufs_deffered;
    351         mMemVtbl.put_bufs = put_bufs_deffered;
    352     }
    353     mMemVtbl.invalidate_buf = invalidate_buf;
    354     mMemVtbl.clean_invalidate_buf = clean_invalidate_buf;
    355     mMemVtbl.set_config_ops = set_config_ops;
    356     memset(&mFrameLenOffset, 0, sizeof(mFrameLenOffset));
    357     memcpy(&mPaddingInfo, paddingInfo, sizeof(cam_padding_info_t));
    358     memset(&mCropInfo, 0, sizeof(cam_rect_t));
    359     memset(&m_MemOpsTbl, 0, sizeof(mm_camera_map_unmap_ops_tbl_t));
    360     memset(&m_OutputCrop, 0, sizeof(cam_stream_parm_buffer_t));
    361     memset(&m_ImgProp, 0, sizeof(cam_stream_parm_buffer_t));
    362     memset(&mAllocTask, 0, sizeof(mAllocTask));
    363     memset(&mMapTask, 0, sizeof(mMapTask));
    364     pthread_mutex_init(&mCropLock, NULL);
    365     pthread_mutex_init(&mParameterLock, NULL);
    366     mCurMetaMemory = NULL;
    367     mCurBufIndex = -1;
    368     mCurMetaIndex = -1;
    369     mFirstTimeStamp = 0;
    370     memset (&mStreamMetaMemory, 0,
    371             (sizeof(MetaMemory) * CAMERA_MIN_VIDEO_BATCH_BUFFERS));
    372     pthread_mutex_init(&m_lock, NULL);
    373     pthread_cond_init(&m_cond, NULL);
    374 }
    375 
    376 /*===========================================================================
    377  * FUNCTION   : ~QCameraStream
    378  *
    379  * DESCRIPTION: deconstructor of QCameraStream
    380  *
    381  * PARAMETERS : None
    382  *
    383  * RETURN     : None
    384  *==========================================================================*/
    385 QCameraStream::~QCameraStream()
    386 {
    387     pthread_mutex_destroy(&mCropLock);
    388     pthread_mutex_destroy(&mParameterLock);
    389 
    390     mAllocator.waitForBackgroundTask(mAllocTaskId);
    391     mAllocator.waitForBackgroundTask(mMapTaskId);
    392     if (mBufAllocPid != 0) {
    393         cond_signal(true);
    394         LOGL("Wait for buf allocation thread dead");
    395         // Wait for the allocation of additional stream buffers
    396         pthread_join(mBufAllocPid, NULL);
    397         mBufAllocPid = 0;
    398     }
    399 
    400     if (mDefferedAllocation) {
    401         mStreamBufsAcquired = false;
    402         releaseBuffs();
    403     }
    404 
    405     unmapStreamInfoBuf();
    406     releaseStreamInfoBuf();
    407 
    408     if (mMiscBuf) {
    409         unMapBuf(mMiscBuf, CAM_MAPPING_BUF_TYPE_MISC_BUF, NULL);
    410         releaseMiscBuf();
    411     }
    412 
    413     // delete stream
    414     if (mHandle > 0) {
    415         mCamOps->delete_stream(mCamHandle, mChannelHandle, mHandle);
    416         mHandle = 0;
    417     }
    418     pthread_mutex_destroy(&m_lock);
    419     pthread_cond_destroy(&m_cond);
    420 }
    421 
    422 /*===========================================================================
    423  * FUNCTION   : unmapStreamInfoBuf
    424  *
    425  * DESCRIPTION: Unmap stream info buffer
    426  *
    427  * PARAMETERS :
    428  *
    429  * RETURN     : int32_t type of status
    430  *              NO_ERROR  -- success
    431  *              none-zero failure code
    432  *==========================================================================*/
    433 int32_t QCameraStream::unmapStreamInfoBuf()
    434 {
    435     int rc = NO_ERROR;
    436 
    437     if (mStreamInfoBuf != NULL) {
    438         rc = mCamOps->unmap_stream_buf(mCamHandle,
    439             mChannelHandle,
    440             mHandle,
    441             CAM_MAPPING_BUF_TYPE_STREAM_INFO,
    442             0,
    443             -1);
    444 
    445         if (rc < 0) {
    446             LOGE("Failed to unmap stream info buffer");
    447         }
    448     }
    449 
    450     return rc;
    451 }
    452 
    453 /*===========================================================================
    454  * FUNCTION   : releaseMiscBuf
    455  *
    456  * DESCRIPTION: Release misc buffers
    457  *
    458  * PARAMETERS :
    459  *
    460  * RETURN     : int32_t type of status
    461  *              NO_ERROR  -- success
    462  *              none-zero failure code
    463  *==========================================================================*/
    464 int32_t QCameraStream::releaseMiscBuf()
    465 {
    466     int rc = NO_ERROR;
    467 
    468     if (mMiscBuf != NULL) {
    469         mMiscBuf->deallocate();
    470         delete mMiscBuf;
    471         mMiscBuf = NULL;
    472     }
    473 
    474     return rc;
    475 }
    476 
    477 /*===========================================================================
    478  * FUNCTION   : releaseStreamInfoBuf
    479  *
    480  * DESCRIPTION: Release stream info buffer
    481  *
    482  * PARAMETERS :
    483  *
    484  * RETURN     : int32_t type of status
    485  *              NO_ERROR  -- success
    486  *              none-zero failure code
    487  *==========================================================================*/
    488 int32_t QCameraStream::releaseStreamInfoBuf()
    489 {
    490     int rc = NO_ERROR;
    491 
    492     if (mStreamInfoBuf != NULL) {
    493         mStreamInfoBuf->deallocate();
    494         delete mStreamInfoBuf;
    495         mStreamInfoBuf = NULL;
    496         mStreamInfo = NULL;
    497     }
    498 
    499     return rc;
    500 }
    501 
    502 /*===========================================================================
    503  * FUNCTION   : deleteStream
    504  *
    505  * DESCRIPTION: Deletes a camera stream
    506  *
    507  * PARAMETERS : None
    508  *
    509  * RETURN     : None
    510  *==========================================================================*/
    511 void QCameraStream::deleteStream()
    512 {
    513     if (mHandle > 0) {
    514         acquireStreamBufs();
    515         releaseBuffs();
    516         unmapStreamInfoBuf();
    517         mCamOps->delete_stream(mCamHandle, mChannelHandle, mHandle);
    518     }
    519 }
    520 
    521 /*===========================================================================
    522  * FUNCTION   : unMapBuf
    523  *
    524  * DESCRIPTION: unmaps buffers
    525  *
    526  * PARAMETERS :
    527  *   @heapBuf      : heap buffer handler
    528  *   @bufType      : buffer type
    529  *   @ops_tbl    : ptr to buf mapping/unmapping ops
    530  *
    531  * RETURN     : int32_t type of status
    532  *              NO_ERROR  -- success
    533  *              none-zero failure code
    534  *==========================================================================*/
    535 int32_t QCameraStream::unMapBuf(QCameraMemory *Buf,
    536         cam_mapping_buf_type bufType, __unused mm_camera_map_unmap_ops_tbl_t *ops_tbl)
    537 {
    538     int32_t rc = NO_ERROR;
    539     uint8_t cnt;
    540     ssize_t bufSize = BAD_INDEX;
    541     uint32_t i;
    542 
    543     cnt = Buf->getCnt();
    544     for (i = 0; i < cnt; i++) {
    545         bufSize = Buf->getSize(i);
    546         if (BAD_INDEX != bufSize) {
    547             if (m_MemOpsTbl.unmap_ops == NULL ) {
    548                 rc = mCamOps->unmap_stream_buf(mCamHandle, mChannelHandle, mHandle,
    549                         bufType, i, -1);
    550             } else {
    551                 rc = m_MemOpsTbl.unmap_ops(i, -1, bufType, m_MemOpsTbl.userdata);
    552             }
    553             if (rc < 0) {
    554                 LOGE("Failed to unmap buffer");
    555                 break;
    556             }
    557         } else {
    558             LOGE("Failed to retrieve buffer size (bad index)");
    559             rc = BAD_INDEX;
    560             break;
    561         }
    562     }
    563 
    564     return rc;
    565 }
    566 
    567 /*===========================================================================
    568  * FUNCTION   : mapBufs
    569  *
    570  * DESCRIPTION: maps buffers
    571  *
    572  * PARAMETERS :
    573  *   @heapBuf      : heap buffer handler
    574  *   @bufType      : buffer type
    575  *   @ops_tbl    : ptr to buf mapping/unmapping ops
    576  *
    577  * RETURN     : int32_t type of status
    578  *              NO_ERROR  -- success
    579  *              none-zero failure code
    580  *==========================================================================*/
    581 int32_t QCameraStream::mapBufs(QCameraMemory *Buf,
    582         cam_mapping_buf_type bufType, __unused mm_camera_map_unmap_ops_tbl_t *ops_tbl)
    583 {
    584     int32_t rc = NO_ERROR;
    585     uint32_t i = 0;
    586 
    587     QCameraBufferMaps bufferMaps;
    588     for (i = 0; i < Buf->getCnt(); i++) {
    589         ssize_t bufSize = Buf->getSize(i);
    590         if (BAD_INDEX == bufSize) {
    591             LOGE("Failed to retrieve buffer size (bad index)");
    592             return BAD_INDEX;
    593         }
    594 
    595         rc = bufferMaps.enqueue(bufType, mHandle, i /*buf index*/, -1 /*plane index*/,
    596                 0 /*cookie*/, Buf->getFd(i), bufSize);
    597 
    598         if (rc < 0) {
    599             LOGE("Failed to map buffers");
    600             return BAD_INDEX;
    601         }
    602     }
    603 
    604     cam_buf_map_type_list bufMapList;
    605     rc = bufferMaps.getCamBufMapList(bufMapList);
    606     if (rc < 0) {
    607         LOGE("Failed to map buffers");
    608         return BAD_INDEX;
    609     }
    610 
    611     if (m_MemOpsTbl.bundled_map_ops == NULL) {
    612         rc = mCamOps->map_stream_bufs(mCamHandle, mChannelHandle, &bufMapList);
    613     } else {
    614         rc = m_MemOpsTbl.bundled_map_ops(&bufMapList, m_MemOpsTbl.userdata);
    615     }
    616 
    617     if (rc < 0) {
    618         LOGE("Failed to map buffer");
    619         rc = BAD_INDEX;
    620     }
    621     return rc;
    622 }
    623 
    624 /*===========================================================================
    625  * FUNCTION   : backgroundAllocate
    626  *
    627  * DESCRIPTION: schedule buffers to be allocated in the background
    628  *
    629  * PARAMETERS :
    630  *
    631  * RETURN     : int32_t type of status
    632  *              NO_ERROR  -- success
    633  *              none-zero failure code
    634  *==========================================================================*/
    635 int32_t QCameraStream::backgroundAllocate(void *data) {
    636     QCameraStream *stream = (QCameraStream*)data;
    637     int32_t rc = stream->allocateBuffers();
    638     if (rc != NO_ERROR) {
    639         LOGE("Error allocating buffers !!!");
    640     }
    641     return rc;
    642 }
    643 
    644 /*===========================================================================
    645  * FUNCTION   : backgroundMap
    646  *
    647  * DESCRIPTION: map buffers in the background
    648  *
    649  * PARAMETERS :
    650  *
    651  * RETURN     : int32_t type of status
    652  *              NO_ERROR  -- success
    653  *              none-zero failure code
    654  *==========================================================================*/
    655 int32_t QCameraStream::backgroundMap(void *data) {
    656     QCameraStream *stream = (QCameraStream*)data;
    657     int32_t rc = stream->mapBuffers();
    658     if (rc != NO_ERROR) {
    659         LOGE("Error mapping buffers !!!");
    660     }
    661     return rc;
    662 }
    663 
    664 /*===========================================================================
    665  * FUNCTION   : init
    666  *
    667  * DESCRIPTION: initialize stream obj
    668  *
    669  * PARAMETERS :
    670  *   @streamInfoBuf: ptr to buf that contains stream info
    671  *   @miscBuf      : ptr to buf that contains misc bufs
    672  *   @stream_cb    : stream data notify callback. Can be NULL if not needed
    673  *   @userdata     : user data ptr
    674  *   @bDynallocBuf : flag to indicate if buffer allocation can be in 2 steps
    675  *
    676  * RETURN     : int32_t type of status
    677  *              NO_ERROR  -- success
    678  *              none-zero failure code
    679  *==========================================================================*/
    680 int32_t QCameraStream::init(QCameraHeapMemory *streamInfoBuf,
    681         QCameraHeapMemory *miscBuf,
    682         uint8_t minNumBuffers,
    683         stream_cb_routine stream_cb,
    684         void *userdata,
    685         bool bDynallocBuf)
    686 {
    687     int32_t rc = OK;
    688 
    689     // assign and map stream info memory
    690     mStreamInfoBuf = streamInfoBuf;
    691     mStreamInfo = reinterpret_cast<cam_stream_info_t *>(mStreamInfoBuf->getPtr(0));
    692     mNumBufs = minNumBuffers;
    693     mDynBufAlloc = bDynallocBuf;
    694 
    695     // Calculate buffer size for deffered allocation
    696     if (mDefferedAllocation) {
    697         rc = calcOffset(mStreamInfo);
    698         if (rc < 0) {
    699             LOGE("Failed to calculate stream offset");
    700             goto done;
    701         }
    702 
    703         mAllocTask.bgFunction = backgroundAllocate;
    704         mAllocTask.bgArgs = this;
    705         mAllocTaskId = mAllocator.scheduleBackgroundTask(&mAllocTask);
    706         if (mAllocTaskId == 0) {
    707             LOGE("Failed to schedule buffer alloction");
    708             rc = -ENOMEM;
    709             goto done;
    710         }
    711     }
    712 
    713     mHandle = mCamOps->add_stream(mCamHandle, mChannelHandle);
    714     if (!mHandle) {
    715         LOGE("add_stream failed");
    716         rc = UNKNOWN_ERROR;
    717         goto done;
    718     }
    719 
    720     rc = mapBufs(mStreamInfoBuf, CAM_MAPPING_BUF_TYPE_STREAM_INFO, NULL);
    721     if (rc < 0) {
    722         LOGE("Failed to map stream info buffer");
    723         goto err1;
    724     }
    725 
    726     mMiscBuf = miscBuf;
    727     if (miscBuf) {
    728         rc = mapBufs(mMiscBuf, CAM_MAPPING_BUF_TYPE_MISC_BUF, NULL);
    729         if (rc < 0) {
    730             LOGE("Failed to map miscellaneous buffer");
    731             releaseMiscBuf();
    732             goto err1;
    733         }
    734     }
    735 
    736     rc = configStream();
    737     if (rc < 0) {
    738         LOGE("Failed to config stream ");
    739         goto err1;
    740     }
    741 
    742     if (mDefferedAllocation) {
    743         mMapTask.bgFunction = backgroundMap;
    744         mMapTask.bgArgs = this;
    745         mMapTaskId = mAllocator.scheduleBackgroundTask(&mMapTask);
    746         if (mMapTaskId == 0) {
    747             LOGE("Failed to schedule buffer alloction");
    748             rc = -ENOMEM;
    749             goto err1;
    750         }
    751     }
    752 
    753     mDataCB = stream_cb;
    754     mUserData = userdata;
    755     return 0;
    756 
    757 err1:
    758     mCamOps->delete_stream(mCamHandle, mChannelHandle, mHandle);
    759     mHandle = 0;
    760     mNumBufs = 0;
    761 done:
    762     return rc;
    763 }
    764 
    765 /*===========================================================================
    766  * FUNCTION   : calcOffset
    767  *
    768  * DESCRIPTION: calculate frame offset based on format and padding information
    769  *
    770  * PARAMETERS :
    771  *   @streamInfo  : stream information
    772  *
    773  * RETURN     : int32_t type of status
    774  *              0  -- success
    775  *              -1 -- failure
    776  *==========================================================================*/
    777 int32_t QCameraStream::calcOffset(cam_stream_info_t *streamInfo)
    778 {
    779     int32_t rc = 0;
    780 
    781     cam_dimension_t dim = streamInfo->dim;
    782     if (streamInfo->pp_config.feature_mask & CAM_QCOM_FEATURE_ROTATION &&
    783             streamInfo->stream_type != CAM_STREAM_TYPE_VIDEO) {
    784         if (streamInfo->pp_config.rotation == ROTATE_90 ||
    785                 streamInfo->pp_config.rotation == ROTATE_270) {
    786             // rotated by 90 or 270, need to switch width and height
    787             dim.width = streamInfo->dim.height;
    788             dim.height = streamInfo->dim.width;
    789         }
    790     }
    791 
    792     switch (streamInfo->stream_type) {
    793     case CAM_STREAM_TYPE_PREVIEW:
    794     case CAM_STREAM_TYPE_CALLBACK:
    795         rc = mm_stream_calc_offset_preview(streamInfo,
    796                 &dim,
    797                 &mPaddingInfo,
    798                 &streamInfo->buf_planes);
    799         break;
    800     case CAM_STREAM_TYPE_POSTVIEW:
    801         rc = mm_stream_calc_offset_post_view(streamInfo->fmt,
    802                 &dim,
    803                 &streamInfo->buf_planes);
    804         break;
    805     case CAM_STREAM_TYPE_SNAPSHOT:
    806         rc = mm_stream_calc_offset_snapshot(streamInfo->fmt,
    807                 &dim,
    808                 &mPaddingInfo,
    809                 &streamInfo->buf_planes);
    810         break;
    811     case CAM_STREAM_TYPE_OFFLINE_PROC:
    812         rc = mm_stream_calc_offset_postproc(streamInfo,
    813                 &mPaddingInfo,
    814                 &streamInfo->buf_planes);
    815         break;
    816     case CAM_STREAM_TYPE_VIDEO:
    817         rc = mm_stream_calc_offset_video(streamInfo->fmt,
    818                 &dim, &streamInfo->buf_planes);
    819         break;
    820     case CAM_STREAM_TYPE_RAW:
    821         rc = mm_stream_calc_offset_raw(streamInfo->fmt,
    822                 &dim,
    823                 &mPaddingInfo,
    824                 &streamInfo->buf_planes);
    825         break;
    826     case CAM_STREAM_TYPE_ANALYSIS:
    827         rc = mm_stream_calc_offset_analysis(streamInfo->fmt,
    828                 &dim,
    829                 &mPaddingInfo,
    830                 &streamInfo->buf_planes);
    831         break;
    832     case CAM_STREAM_TYPE_METADATA:
    833         rc = mm_stream_calc_offset_metadata(&dim,
    834                 &mPaddingInfo,
    835                 &streamInfo->buf_planes);
    836         break;
    837     default:
    838         LOGE("not supported for stream type %d",
    839                  streamInfo->stream_type);
    840         rc = -1;
    841         break;
    842     }
    843     return rc;
    844 }
    845 
    846 /*===========================================================================
    847  * FUNCTION   : start
    848  *
    849  * DESCRIPTION: start stream. Will start main stream thread to handle stream
    850  *              related ops.
    851  *
    852  * PARAMETERS : none
    853  *
    854  * RETURN     : int32_t type of status
    855  *              NO_ERROR  -- success
    856  *              none-zero failure code
    857  *==========================================================================*/
    858 int32_t QCameraStream::start()
    859 {
    860     int32_t rc = 0;
    861     mDataQ.init();
    862     rc = mProcTh.launch(dataProcRoutine, this);
    863     if (rc == NO_ERROR) {
    864         m_bActive = true;
    865     }
    866 
    867     mCurMetaMemory = NULL;
    868     mCurBufIndex = -1;
    869     mCurMetaIndex = -1;
    870     mFirstTimeStamp = 0;
    871     memset (&mStreamMetaMemory, 0,
    872             (sizeof(MetaMemory) * CAMERA_MIN_VIDEO_BATCH_BUFFERS));
    873     return rc;
    874 }
    875 
    876 /*===========================================================================
    877  * FUNCTION   : stop
    878  *
    879  * DESCRIPTION: stop stream. Will stop main stream thread
    880  *
    881  * PARAMETERS : none
    882  *
    883  * RETURN     : int32_t type of status
    884  *              NO_ERROR  -- success
    885  *              none-zero failure code
    886  *==========================================================================*/
    887 int32_t QCameraStream::stop()
    888 {
    889     int32_t rc = 0;
    890     m_bActive = false;
    891     mAllocator.waitForBackgroundTask(mAllocTaskId);
    892     mAllocator.waitForBackgroundTask(mMapTaskId);
    893     rc = mProcTh.exit();
    894     return rc;
    895 }
    896 
    897 /*===========================================================================
    898  * FUNCTION   : syncRuntimeParams
    899  *
    900  * DESCRIPTION: query and sync runtime parameters like output crop
    901  *              buffer info etc.
    902  *
    903  * PARAMETERS : none
    904  *
    905  * RETURN     : int32_t type of status
    906  *              NO_ERROR  -- success
    907  *              none-zero failure code
    908  *==========================================================================*/
    909 int32_t QCameraStream::syncRuntimeParams()
    910 {
    911     int32_t ret = NO_ERROR;
    912 
    913     memset(&m_OutputCrop, 0, sizeof(cam_stream_parm_buffer_t));
    914     m_OutputCrop.type = CAM_STREAM_PARAM_TYPE_GET_OUTPUT_CROP;
    915 
    916     ret = getParameter(m_OutputCrop);
    917     if (ret != NO_ERROR) {
    918         LOGE("stream getParameter for output crop failed");
    919         return ret;
    920     }
    921 
    922     memset(&m_ImgProp, 0, sizeof(cam_stream_parm_buffer_t));
    923     m_ImgProp.type = CAM_STREAM_PARAM_TYPE_GET_IMG_PROP;
    924 
    925     ret = getParameter(m_ImgProp);
    926     if (ret != NO_ERROR) {
    927         LOGE("stream getParameter for image prop failed");
    928         return ret;
    929     }
    930 
    931     return ret;
    932 }
    933 
    934 /*===========================================================================
    935  * FUNCTION   : processZoomDone
    936  *
    937  * DESCRIPTION: process zoom done event
    938  *
    939  * PARAMETERS :
    940  *   @previewWindoe : preview window ops table to set preview crop window
    941  *   @crop_info     : crop info
    942  *
    943  * RETURN     : int32_t type of status
    944  *              NO_ERROR  -- success
    945  *              none-zero failure code
    946  *==========================================================================*/
    947 int32_t QCameraStream::processZoomDone(preview_stream_ops_t *previewWindow,
    948                                        cam_crop_data_t &crop_info)
    949 {
    950     int32_t rc = 0;
    951 
    952     if (!m_bActive) {
    953         LOGL("Stream not active");
    954         return NO_ERROR;
    955     }
    956 
    957     // get stream param for crop info
    958     for (int i = 0; i < crop_info.num_of_streams; i++) {
    959         if (crop_info.crop_info[i].stream_id == mStreamInfo->stream_svr_id) {
    960             pthread_mutex_lock(&mCropLock);
    961             mCropInfo = crop_info.crop_info[i].crop;
    962             pthread_mutex_unlock(&mCropLock);
    963 
    964             // update preview window crop if it's preview/postview stream
    965             if ( (previewWindow != NULL) &&
    966                  (mStreamInfo->stream_type == CAM_STREAM_TYPE_PREVIEW ||
    967                   mStreamInfo->stream_type == CAM_STREAM_TYPE_POSTVIEW) ) {
    968                 rc = previewWindow->set_crop(previewWindow,
    969                                              mCropInfo.left,
    970                                              mCropInfo.top,
    971                                              mCropInfo.width,
    972                                              mCropInfo.height);
    973             }
    974             break;
    975         }
    976     }
    977     return rc;
    978 }
    979 
    980 /*===========================================================================
    981  * FUNCTION   : processDataNotify
    982  *
    983  * DESCRIPTION: process stream data notify
    984  *
    985  * PARAMETERS :
    986  *   @frame   : stream frame received
    987  *
    988  * RETURN     : int32_t type of status
    989  *              NO_ERROR  -- success
    990  *              none-zero failure code
    991  *==========================================================================*/
    992 int32_t QCameraStream::processDataNotify(mm_camera_super_buf_t *frame)
    993 {
    994     LOGD("\n");
    995 
    996     if (mDataQ.enqueue((void *)frame)) {
    997         return mProcTh.sendCmd(CAMERA_CMD_TYPE_DO_NEXT_JOB, FALSE, FALSE);
    998     } else {
    999         if (!m_bActive) {
   1000             LOGW("Stream thread is not active, no ops here %d", getMyType());
   1001         } else {
   1002             bufDone(frame->bufs[0]->buf_idx);
   1003         }
   1004         free(frame);
   1005         return NO_ERROR;
   1006     }
   1007 }
   1008 
   1009 /*===========================================================================
   1010  * FUNCTION   : dataNotifySYNCCB
   1011  *
   1012  * DESCRIPTION: This function registered with interface for
   1013  *                        SYNC callback if SYNC callback registered.
   1014  *
   1015  * PARAMETERS :
   1016  *   @recvd_frame   : stream frame received
   1017  *   @userdata      : user data ptr
   1018  *
   1019  * RETURN     : none
   1020  *==========================================================================*/
   1021 void QCameraStream::dataNotifySYNCCB(mm_camera_super_buf_t *recvd_frame,
   1022         void *userdata)
   1023 {
   1024     LOGD("\n");
   1025     QCameraStream* stream = (QCameraStream *)userdata;
   1026     if (stream == NULL ||
   1027         recvd_frame == NULL ||
   1028         recvd_frame->bufs[0] == NULL ||
   1029         recvd_frame->bufs[0]->stream_id != stream->getMyHandle()) {
   1030         LOGE("Not a valid stream to handle buf");
   1031         return;
   1032     }
   1033     if ((stream->mSyncCBEnabled) && (stream->mSYNCDataCB != NULL))
   1034         stream->mSYNCDataCB(recvd_frame, stream, stream->mUserData);
   1035     return;
   1036 }
   1037 
   1038 
   1039 /*===========================================================================
   1040  * FUNCTION   : dataNotifyCB
   1041  *
   1042  * DESCRIPTION: callback for data notify. This function is registered with
   1043  *              mm-camera-interface to handle data notify
   1044  *
   1045  * PARAMETERS :
   1046  *   @recvd_frame   : stream frame received
   1047  *   userdata       : user data ptr
   1048  *
   1049  * RETURN     : none
   1050  *==========================================================================*/
   1051 void QCameraStream::dataNotifyCB(mm_camera_super_buf_t *recvd_frame,
   1052                                  void *userdata)
   1053 {
   1054     LOGD("\n");
   1055     QCameraStream* stream = (QCameraStream *)userdata;
   1056     if (stream == NULL ||
   1057         recvd_frame == NULL ||
   1058         recvd_frame->bufs[0] == NULL ||
   1059         recvd_frame->bufs[0]->stream_id != stream->getMyHandle()) {
   1060         LOGE("Not a valid stream to handle buf");
   1061         return;
   1062     }
   1063 
   1064     mm_camera_super_buf_t *frame =
   1065         (mm_camera_super_buf_t *)malloc(sizeof(mm_camera_super_buf_t));
   1066     if (frame == NULL) {
   1067         LOGE("No mem for mm_camera_buf_def_t");
   1068         stream->bufDone(recvd_frame->bufs[0]->buf_idx);
   1069         return;
   1070     }
   1071     *frame = *recvd_frame;
   1072     stream->processDataNotify(frame);
   1073     return;
   1074 }
   1075 
   1076 /*===========================================================================
   1077  * FUNCTION   : dataProcRoutine
   1078  *
   1079  * DESCRIPTION: function to process data in the main stream thread
   1080  *
   1081  * PARAMETERS :
   1082  *   @data    : user data ptr
   1083  *
   1084  * RETURN     : none
   1085  *==========================================================================*/
   1086 void *QCameraStream::dataProcRoutine(void *data)
   1087 {
   1088     int running = 1;
   1089     int ret;
   1090     QCameraStream *pme = (QCameraStream *)data;
   1091     QCameraCmdThread *cmdThread = &pme->mProcTh;
   1092     cmdThread->setName("CAM_strmDatProc");
   1093 
   1094     LOGD("E");
   1095     do {
   1096         do {
   1097             ret = cam_sem_wait(&cmdThread->cmd_sem);
   1098             if (ret != 0 && errno != EINVAL) {
   1099                 LOGE("cam_sem_wait error (%s)",
   1100                        strerror(errno));
   1101                 return NULL;
   1102             }
   1103         } while (ret != 0);
   1104 
   1105         // we got notified about new cmd avail in cmd queue
   1106         camera_cmd_type_t cmd = cmdThread->getCmd();
   1107         switch (cmd) {
   1108         case CAMERA_CMD_TYPE_DO_NEXT_JOB:
   1109             {
   1110                 LOGH("Do next job");
   1111                 mm_camera_super_buf_t *frame =
   1112                     (mm_camera_super_buf_t *)pme->mDataQ.dequeue();
   1113                 if (NULL != frame) {
   1114                     if (pme->mDataCB != NULL) {
   1115                         pme->mDataCB(frame, pme, pme->mUserData);
   1116                     } else {
   1117                         // no data cb routine, return buf here
   1118                         pme->bufDone(frame->bufs[0]->buf_idx);
   1119                         free(frame);
   1120                     }
   1121                 }
   1122             }
   1123             break;
   1124         case CAMERA_CMD_TYPE_EXIT:
   1125             LOGH("Exit");
   1126             /* flush data buf queue */
   1127             pme->mDataQ.flush();
   1128             running = 0;
   1129             break;
   1130         default:
   1131             break;
   1132         }
   1133     } while (running);
   1134     LOGH("X");
   1135     return NULL;
   1136 }
   1137 
   1138 /*===========================================================================
   1139  * FUNCTION   : bufDone
   1140  *
   1141  * DESCRIPTION: return stream buffer to kernel
   1142  *
   1143  * PARAMETERS :
   1144  *   @index   : index of buffer to be returned
   1145  *
   1146  * RETURN     : int32_t type of status
   1147  *              NO_ERROR  -- success
   1148  *              none-zero failure code
   1149  *==========================================================================*/
   1150 int32_t QCameraStream::bufDone(uint32_t index)
   1151 {
   1152     int32_t rc = NO_ERROR;
   1153 
   1154     if (index >= mNumBufs || mBufDefs == NULL)
   1155         return BAD_INDEX;
   1156 
   1157     rc = mCamOps->qbuf(mCamHandle, mChannelHandle, &mBufDefs[index]);
   1158 
   1159     if (rc < 0)
   1160         return rc;
   1161 
   1162     return rc;
   1163 }
   1164 
   1165 /*===========================================================================
   1166  * FUNCTION   : bufDone
   1167  *
   1168  * DESCRIPTION: return stream buffer to kernel
   1169  *
   1170  * PARAMETERS :
   1171  *   @opaque    : stream frame/metadata buf to be returned
   1172  *   @isMetaData: flag if returned opaque is a metadatabuf or the real frame ptr
   1173  *
   1174  * RETURN     : int32_t type of status
   1175  *              NO_ERROR  -- success
   1176  *              none-zero failure code
   1177  *==========================================================================*/
   1178 int32_t QCameraStream::bufDone(const void *opaque, bool isMetaData)
   1179 {
   1180     int32_t rc = NO_ERROR;
   1181     int index = -1;
   1182 
   1183     if ((mStreamInfo != NULL)
   1184             && (mStreamInfo->streaming_mode == CAM_STREAMING_MODE_BATCH)
   1185             && (mStreamBatchBufs != NULL)) {
   1186         index = mStreamBatchBufs->getMatchBufIndex(opaque, isMetaData);
   1187     } else if (mStreamBufs != NULL){
   1188         index = mStreamBufs->getMatchBufIndex(opaque, isMetaData);
   1189     }
   1190 
   1191     if (index == -1 || index >= mNumBufs || mBufDefs == NULL) {
   1192         LOGE("Cannot find buf for opaque data = %p", opaque);
   1193         return BAD_INDEX;
   1194     }
   1195 
   1196     if ((CAMERA_MIN_VIDEO_BATCH_BUFFERS > index)
   1197             && mStreamMetaMemory[index].numBuffers > 0) {
   1198         for (int i= 0; i < mStreamMetaMemory[index].numBuffers; i++) {
   1199             uint8_t buf_idx = mStreamMetaMemory[index].buf_index[i];
   1200             bufDone((uint32_t)buf_idx);
   1201         }
   1202         mStreamMetaMemory[index].consumerOwned = FALSE;
   1203         mStreamMetaMemory[index].numBuffers = 0;
   1204     } else {
   1205         LOGH("Buffer Index = %d, Frame Idx = %d", index,
   1206                 mBufDefs[index].frame_idx);
   1207         rc = bufDone((uint32_t)index);
   1208     }
   1209 
   1210     return rc;
   1211 }
   1212 
   1213 /*===========================================================================
   1214  * FUNCTION   : getNumQueuedBuf
   1215  *
   1216  * DESCRIPTION: return queued buffer count
   1217  *
   1218  * PARAMETERS : None
   1219  *
   1220  * RETURN     : queued buffer count
   1221  *==========================================================================*/
   1222 int32_t QCameraStream::getNumQueuedBuf()
   1223 {
   1224     int32_t rc = -1;
   1225     if (mHandle > 0) {
   1226         rc = mCamOps->get_queued_buf_count(mCamHandle, mChannelHandle, mHandle);
   1227     }
   1228     if (rc == -1) {
   1229         LOGE("stream is not in active state. Invalid operation");
   1230     }
   1231     return rc;
   1232 }
   1233 
   1234 /*===========================================================================
   1235  * FUNCTION   : getBufs
   1236  *
   1237  * DESCRIPTION: allocate stream buffers
   1238  *
   1239  * PARAMETERS :
   1240  *   @offset     : offset info of stream buffers
   1241  *   @num_bufs   : number of buffers allocated
   1242  *   @initial_reg_flag: flag to indicate if buffer needs to be registered
   1243  *                      at kernel initially
   1244  *   @bufs       : output of allocated buffers
   1245  *   @ops_tbl    : ptr to buf mapping/unmapping ops
   1246  *
   1247  * RETURN     : int32_t type of status
   1248  *              NO_ERROR  -- success
   1249  *              none-zero failure code
   1250  *==========================================================================*/
   1251 int32_t QCameraStream::getBufs(cam_frame_len_offset_t *offset,
   1252         uint8_t *num_bufs,
   1253         uint8_t **initial_reg_flag,
   1254         mm_camera_buf_def_t **bufs,
   1255         mm_camera_map_unmap_ops_tbl_t *ops_tbl)
   1256 {
   1257     int rc = NO_ERROR;
   1258     uint8_t *regFlags;
   1259 
   1260     if (!ops_tbl) {
   1261         LOGE("ops_tbl is NULL");
   1262         return INVALID_OPERATION;
   1263     }
   1264 
   1265     mFrameLenOffset = *offset;
   1266 
   1267     uint8_t numBufAlloc = mNumBufs;
   1268     mNumBufsNeedAlloc = 0;
   1269     if (mDynBufAlloc) {
   1270         numBufAlloc = CAMERA_MIN_ALLOCATED_BUFFERS;
   1271         if (numBufAlloc > mNumBufs) {
   1272             mDynBufAlloc = false;
   1273             numBufAlloc = mNumBufs;
   1274         } else {
   1275             mNumBufsNeedAlloc = (uint8_t)(mNumBufs - numBufAlloc);
   1276         }
   1277     }
   1278 
   1279     /* For some stream types, buffer allocation may have already begun
   1280      * preemptively. If this is the case, we need to wait for the
   1281      * preemptive allocation to complete before proceeding. */
   1282     mAllocator.waitForDeferredAlloc(mStreamInfo->stream_type);
   1283 
   1284     //Allocate stream buffer
   1285     mStreamBufs = mAllocator.allocateStreamBuf(mStreamInfo->stream_type,
   1286             mFrameLenOffset.frame_len, mFrameLenOffset.mp[0].stride,
   1287             mFrameLenOffset.mp[0].scanline, numBufAlloc);
   1288     if (!mStreamBufs) {
   1289         LOGE("Failed to allocate stream buffers");
   1290         return NO_MEMORY;
   1291     }
   1292 
   1293     mNumBufs = (uint8_t)(numBufAlloc + mNumBufsNeedAlloc);
   1294     uint8_t numBufsToMap = mStreamBufs->getMappable();
   1295 
   1296     QCameraBufferMaps bufferMaps;
   1297     for (uint32_t i = 0; i < numBufsToMap; i++) {
   1298         ssize_t bufSize = mStreamBufs->getSize(i);
   1299         if (BAD_INDEX == bufSize) {
   1300             LOGE("Failed to retrieve buffer size (bad index)");
   1301             return INVALID_OPERATION;
   1302         }
   1303 
   1304         rc = bufferMaps.enqueue(CAM_MAPPING_BUF_TYPE_STREAM_BUF,
   1305                 0 /*stream id*/, i /*buf index*/, -1 /*plane index*/,
   1306                 0 /*cookie*/, mStreamBufs->getFd(i), bufSize);
   1307 
   1308         if (rc < 0) {
   1309             LOGE("Failed to map buffers");
   1310             return BAD_INDEX;
   1311         }
   1312     }
   1313 
   1314     cam_buf_map_type_list bufMapList;
   1315     rc = bufferMaps.getCamBufMapList(bufMapList);
   1316     if (rc == NO_ERROR) {
   1317         rc = ops_tbl->bundled_map_ops(&bufMapList, ops_tbl->userdata);
   1318     }
   1319     if (rc < 0) {
   1320         LOGE("map_stream_buf failed: %d", rc);
   1321         mStreamBufs->deallocate();
   1322         delete mStreamBufs;
   1323         mStreamBufs = NULL;
   1324         return INVALID_OPERATION;
   1325     }
   1326 
   1327     //regFlags array is allocated by us, but consumed and freed by mm-camera-interface
   1328     regFlags = (uint8_t *)malloc(sizeof(uint8_t) * mNumBufs);
   1329     if (!regFlags) {
   1330         LOGE("Out of memory");
   1331         for (uint32_t i = 0; i < numBufsToMap; i++) {
   1332             ops_tbl->unmap_ops(i, -1, CAM_MAPPING_BUF_TYPE_STREAM_BUF, ops_tbl->userdata);
   1333         }
   1334         mStreamBufs->deallocate();
   1335         delete mStreamBufs;
   1336         mStreamBufs = NULL;
   1337         return NO_MEMORY;
   1338     }
   1339     memset(regFlags, 0, sizeof(uint8_t) * mNumBufs);
   1340 
   1341     mBufDefs = (mm_camera_buf_def_t *)malloc(mNumBufs * sizeof(mm_camera_buf_def_t));
   1342     if (mBufDefs == NULL) {
   1343         LOGE("getRegFlags failed %d", rc);
   1344         for (uint32_t i = 0; i < numBufsToMap; i++) {
   1345             ops_tbl->unmap_ops(i, -1, CAM_MAPPING_BUF_TYPE_STREAM_BUF, ops_tbl->userdata);
   1346         }
   1347         mStreamBufs->deallocate();
   1348         delete mStreamBufs;
   1349         mStreamBufs = NULL;
   1350         free(regFlags);
   1351         regFlags = NULL;
   1352         return INVALID_OPERATION;
   1353     }
   1354     memset(mBufDefs, 0, mNumBufs * sizeof(mm_camera_buf_def_t));
   1355     for (uint32_t i = 0; i < numBufsToMap; i++) {
   1356         mStreamBufs->getBufDef(mFrameLenOffset, mBufDefs[i], i);
   1357     }
   1358 
   1359     rc = mStreamBufs->getRegFlags(regFlags);
   1360     if (rc < 0) {
   1361         LOGE("getRegFlags failed %d", rc);
   1362         for (uint32_t i = 0; i < numBufsToMap; i++) {
   1363             ops_tbl->unmap_ops(i, -1, CAM_MAPPING_BUF_TYPE_STREAM_BUF, ops_tbl->userdata);
   1364         }
   1365         mStreamBufs->deallocate();
   1366         delete mStreamBufs;
   1367         mStreamBufs = NULL;
   1368         free(mBufDefs);
   1369         mBufDefs = NULL;
   1370         free(regFlags);
   1371         regFlags = NULL;
   1372         return INVALID_OPERATION;
   1373     }
   1374 
   1375     *num_bufs = mNumBufs;
   1376     *initial_reg_flag = regFlags;
   1377     *bufs = mBufDefs;
   1378     LOGH("stream type: %d, mRegFlags: 0x%x, numBufs: %d",
   1379              mStreamInfo->stream_type, regFlags, mNumBufs);
   1380 
   1381     if (mNumBufsNeedAlloc > 0) {
   1382         pthread_mutex_lock(&m_lock);
   1383         wait_for_cond = TRUE;
   1384         pthread_mutex_unlock(&m_lock);
   1385         LOGH("Still need to allocate %d buffers",
   1386                mNumBufsNeedAlloc);
   1387         // start another thread to allocate the rest of buffers
   1388         pthread_create(&mBufAllocPid,
   1389                        NULL,
   1390                        BufAllocRoutine,
   1391                        this);
   1392         pthread_setname_np(mBufAllocPid, "CAM_strmBuf");
   1393     }
   1394 
   1395     return NO_ERROR;
   1396 }
   1397 
   1398 /*===========================================================================
   1399  * FUNCTION   : getBufsDeferred
   1400  *
   1401  * DESCRIPTION: allocate deferred stream buffers
   1402  *
   1403  * PARAMETERS :
   1404  *   @offset     : offset info of stream buffers
   1405  *   @num_bufs   : number of buffers allocated
   1406  *   @initial_reg_flag: flag to indicate if buffer needs to be registered
   1407  *                      at kernel initially
   1408  *   @bufs       : output of allocated buffers
   1409  *   @ops_tbl    : ptr to buf mapping/unmapping ops
   1410  *
   1411  * RETURN     : int32_t type of status
   1412  *              NO_ERROR  -- success
   1413  *              none-zero failure code
   1414  *==========================================================================*/
   1415 int32_t QCameraStream::getBufsDeferred(__unused cam_frame_len_offset_t *offset,
   1416         uint8_t *num_bufs,
   1417         uint8_t **initial_reg_flag,
   1418         mm_camera_buf_def_t **bufs,
   1419         __unused mm_camera_map_unmap_ops_tbl_t *ops_tbl)
   1420 {
   1421     int32_t rc = NO_ERROR;
   1422     // wait for allocation
   1423     rc = mAllocator.waitForBackgroundTask(mAllocTaskId);
   1424     if (rc != NO_ERROR) {
   1425         LOGE("Allocation Failed");
   1426         return NO_MEMORY;
   1427     }
   1428 
   1429     if (!mRegFlags || !mBufDefs) {
   1430         LOGE("reg flags or buf defs uninitialized");
   1431         return NO_MEMORY;
   1432     }
   1433 
   1434     *initial_reg_flag   = mRegFlags;
   1435     *num_bufs           = mNumBufs;
   1436     *bufs               = mBufDefs;
   1437 
   1438     LOGH("stream type: %d, mRegFlags: 0x%x, numBufs: %d",
   1439              getMyType(), mRegFlags, mNumBufs);
   1440 
   1441     return NO_ERROR;
   1442 }
   1443 /*===========================================================================
   1444  * FUNCTION   : mapNewBuffer
   1445  *
   1446  * DESCRIPTION: map a new stream buffer
   1447  *
   1448  * PARAMETERS :
   1449  *
   1450  * RETURN     : int32_t type of status
   1451  *              NO_ERROR  -- success
   1452  *              none-zero failure code
   1453  *==========================================================================*/
   1454 int32_t QCameraStream::mapNewBuffer(uint32_t index)
   1455 {
   1456     LOGH("E - index = %d", index);
   1457 
   1458     int rc = NO_ERROR;
   1459 
   1460     if (mStreamBufs == NULL) {
   1461         LOGE("Invalid Operation");
   1462         return INVALID_OPERATION;
   1463     }
   1464 
   1465     ssize_t bufSize = mStreamBufs->getSize(index);
   1466     if (BAD_INDEX == bufSize) {
   1467         LOGE("Failed to retrieve buffer size (bad index)");
   1468         return INVALID_OPERATION;
   1469     }
   1470 
   1471     cam_buf_map_type_list bufMapList;
   1472     rc = QCameraBufferMaps::makeSingletonBufMapList(
   1473             CAM_MAPPING_BUF_TYPE_STREAM_BUF, 0 /*stream id*/, index,
   1474             -1 /*plane index*/, 0 /*cookie*/, mStreamBufs->getFd(index),
   1475             bufSize, bufMapList);
   1476 
   1477     if (rc == NO_ERROR) {
   1478         rc = m_MemOpsTbl.bundled_map_ops(&bufMapList, m_MemOpsTbl.userdata);
   1479     }
   1480     if (rc < 0) {
   1481         LOGE("map_stream_buf failed: %d", rc);
   1482         rc = INVALID_OPERATION;
   1483     } else {
   1484         mStreamBufs->getBufDef(mFrameLenOffset, mBufDefs[index], index);
   1485     }
   1486 
   1487     LOGH("X - rc = %d", rc);
   1488     return rc;
   1489 }
   1490 
   1491 /*===========================================================================
   1492  * FUNCTION   : allocateBuffers
   1493  *
   1494  * DESCRIPTION: allocate stream buffers
   1495  *
   1496  * PARAMETERS :
   1497  *
   1498  * RETURN     : int32_t type of status
   1499  *              NO_ERROR  -- success
   1500  *              none-zero failure code
   1501  *==========================================================================*/
   1502 int32_t QCameraStream::allocateBuffers()
   1503 {
   1504     int32_t rc = NO_ERROR;
   1505 
   1506     mFrameLenOffset = mStreamInfo->buf_planes.plane_info;
   1507 
   1508     if (mStreamInfo->streaming_mode == CAM_STREAMING_MODE_BATCH) {
   1509         return allocateBatchBufs(&mFrameLenOffset,
   1510                 &mNumBufs, &mRegFlags,
   1511                 &mBufDefs, NULL);
   1512     }
   1513 
   1514     /* This allocation is running in the deferred context, so it
   1515      * is safe (and necessary) to assume any preemptive allocation
   1516      * is already complete. Therefore, no need to wait here. */
   1517 
   1518     uint8_t numBufAlloc = mNumBufs;
   1519     mNumBufsNeedAlloc = 0;
   1520     if (mDynBufAlloc) {
   1521         numBufAlloc = CAMERA_MIN_ALLOCATED_BUFFERS;
   1522         if (numBufAlloc > mNumBufs) {
   1523             mDynBufAlloc = false;
   1524             numBufAlloc = mNumBufs;
   1525         } else {
   1526             mNumBufsNeedAlloc = (uint8_t)(mNumBufs - numBufAlloc);
   1527         }
   1528     }
   1529 
   1530     //Allocate and map stream info buffer
   1531     mStreamBufs = mAllocator.allocateStreamBuf(mStreamInfo->stream_type,
   1532             mFrameLenOffset.frame_len,
   1533             mFrameLenOffset.mp[0].stride,
   1534             mFrameLenOffset.mp[0].scanline,
   1535             numBufAlloc);
   1536 
   1537     if (!mStreamBufs) {
   1538         LOGE("Failed to allocate stream buffers");
   1539         return NO_MEMORY;
   1540     }
   1541 
   1542     mNumBufs = (uint8_t)(numBufAlloc + mNumBufsNeedAlloc);
   1543     uint8_t numBufsToMap = mStreamBufs->getMappable();
   1544 
   1545     //regFlags array is allocated by us,
   1546     // but consumed and freed by mm-camera-interface
   1547     mRegFlags = (uint8_t *)malloc(sizeof(uint8_t) * mNumBufs);
   1548     if (!mRegFlags) {
   1549         LOGE("Out of memory");
   1550         for (uint32_t i = 0; i < numBufsToMap; i++) {
   1551             unmapBuf(CAM_MAPPING_BUF_TYPE_STREAM_BUF, i, -1, NULL);
   1552         }
   1553         mStreamBufs->deallocate();
   1554         delete mStreamBufs;
   1555         mStreamBufs = NULL;
   1556         return NO_MEMORY;
   1557     }
   1558     memset(mRegFlags, 0, sizeof(uint8_t) * mNumBufs);
   1559 
   1560     size_t bufDefsSize = mNumBufs * sizeof(mm_camera_buf_def_t);
   1561     mBufDefs = (mm_camera_buf_def_t *)malloc(bufDefsSize);
   1562     if (mBufDefs == NULL) {
   1563         LOGE("getRegFlags failed %d", rc);
   1564         for (uint32_t i = 0; i < numBufsToMap; i++) {
   1565             unmapBuf(CAM_MAPPING_BUF_TYPE_STREAM_BUF, i, -1, NULL);
   1566         }
   1567         mStreamBufs->deallocate();
   1568         delete mStreamBufs;
   1569         mStreamBufs = NULL;
   1570         free(mRegFlags);
   1571         mRegFlags = NULL;
   1572         return INVALID_OPERATION;
   1573     }
   1574     memset(mBufDefs, 0, bufDefsSize);
   1575     for (uint32_t i = 0; i < numBufsToMap; i++) {
   1576         mStreamBufs->getBufDef(mFrameLenOffset, mBufDefs[i], i);
   1577     }
   1578 
   1579     rc = mStreamBufs->getRegFlags(mRegFlags);
   1580     if (rc < 0) {
   1581         LOGE("getRegFlags failed %d", rc);
   1582         for (uint32_t i = 0; i < numBufsToMap; i++) {
   1583             unmapBuf(CAM_MAPPING_BUF_TYPE_STREAM_BUF, i, -1, NULL);
   1584         }
   1585         mStreamBufs->deallocate();
   1586         delete mStreamBufs;
   1587         mStreamBufs = NULL;
   1588         free(mBufDefs);
   1589         mBufDefs = NULL;
   1590         free(mRegFlags);
   1591         mRegFlags = NULL;
   1592         return INVALID_OPERATION;
   1593     }
   1594 
   1595     if (mNumBufsNeedAlloc > 0) {
   1596         pthread_mutex_lock(&m_lock);
   1597         wait_for_cond = TRUE;
   1598         pthread_mutex_unlock(&m_lock);
   1599         LOGH("Still need to allocate %d buffers",
   1600                mNumBufsNeedAlloc);
   1601         // start another thread to allocate the rest of buffers
   1602         pthread_create(&mBufAllocPid,
   1603                        NULL,
   1604                        BufAllocRoutine,
   1605                        this);
   1606         pthread_setname_np(mBufAllocPid, "CAM_strmBufAlloc");
   1607     }
   1608     return rc;
   1609 }
   1610 
   1611 /*===========================================================================
   1612  * FUNCTION   : mapBuffers
   1613  *
   1614  * DESCRIPTION: map stream buffers
   1615  *
   1616  * PARAMETERS :
   1617  *
   1618  * RETURN     : int32_t type of status
   1619  *              NO_ERROR  -- success
   1620  *              none-zero failure code
   1621  *==========================================================================*/
   1622 int32_t QCameraStream::mapBuffers()
   1623 {
   1624     int32_t rc = NO_ERROR;
   1625     QCameraBufferMaps bufferMaps;
   1626 
   1627     rc = mAllocator.waitForBackgroundTask(mAllocTaskId);
   1628     if (rc != NO_ERROR) {
   1629         LOGE("Allocation Failed");
   1630         return NO_MEMORY;
   1631     }
   1632 
   1633     if (mStreamBufs == NULL) {
   1634         LOGE("Stream buffers not allocated");
   1635         return UNKNOWN_ERROR;
   1636     }
   1637 
   1638     uint8_t numBufsToMap = mStreamBufs->getMappable();
   1639     for (uint32_t i = 0; i < numBufsToMap; i++) {
   1640         ssize_t bufSize = mStreamBufs->getSize(i);
   1641         if (BAD_INDEX != bufSize) {
   1642             rc = bufferMaps.enqueue(CAM_MAPPING_BUF_TYPE_STREAM_BUF, mHandle,
   1643                     i /*buf index*/, -1 /*plane index*/, 0 /*cookie*/,
   1644                     mStreamBufs->getFd(i), bufSize);
   1645 
   1646             if (rc < 0) {
   1647                 LOGE("Failed to map buffers");
   1648                 rc = BAD_INDEX;
   1649                 break;
   1650             }
   1651         } else {
   1652             LOGE("Bad index %u", i);
   1653             rc = BAD_INDEX;
   1654             break;
   1655         }
   1656     }
   1657 
   1658     cam_buf_map_type_list bufMapList;
   1659     if (rc == NO_ERROR) {
   1660         rc = bufferMaps.getCamBufMapList(bufMapList);
   1661     }
   1662     if (rc == NO_ERROR) {
   1663         rc = mapBufs(bufMapList, NULL);
   1664     }
   1665     return rc;
   1666 }
   1667 
   1668 /*===========================================================================
   1669  * FUNCTION   : allocateBatchBufs
   1670  *
   1671  * DESCRIPTION: allocate stream batch buffers and stream buffers
   1672  *
   1673  * PARAMETERS :
   1674  *   @offset     : offset info of stream buffers
   1675  *   @num_bufs   : number of buffers allocated
   1676  *   @initial_reg_flag: flag to indicate if buffer needs to be registered
   1677  *                      at kernel initially
   1678  *   @bufs       : output of allocated buffers
   1679  *   @plane_bufs    : output of allocated plane buffers
   1680   *   @ops_tbl    : ptr to buf mapping/unmapping ops
   1681  *
   1682  * RETURN     : int32_t type of status
   1683  *              NO_ERROR  -- success
   1684  *              none-zero failure code
   1685  *==========================================================================*/
   1686 int32_t QCameraStream::allocateBatchBufs(cam_frame_len_offset_t *offset,
   1687         uint8_t *num_bufs, uint8_t **initial_reg_flag,
   1688         mm_camera_buf_def_t **bufs, mm_camera_map_unmap_ops_tbl_t *ops_tbl)
   1689 {
   1690     int rc = NO_ERROR;
   1691     uint8_t *regFlags;
   1692     QCameraBufferMaps bufferMaps;
   1693     QCameraBufferMaps planeBufferMaps;
   1694 
   1695     mFrameLenOffset = *offset;
   1696 
   1697     LOGH("Batch Buffer allocation stream type = %d", getMyType());
   1698 
   1699     //Allocate stream batch buffer
   1700     mStreamBatchBufs = mAllocator.allocateStreamUserBuf (mStreamInfo);
   1701     if (!mStreamBatchBufs) {
   1702         LOGE("Failed to allocate stream batch buffers");
   1703         return NO_MEMORY;
   1704     }
   1705 
   1706     uint8_t numBufsToMap = mStreamBatchBufs->getMappable();
   1707 
   1708     //map batch buffers
   1709     for (uint32_t i = 0; i < numBufsToMap; i++) {
   1710         rc = bufferMaps.enqueue(CAM_MAPPING_BUF_TYPE_STREAM_USER_BUF,
   1711                 0 /*stream id*/, i /*buf index*/, -1 /*plane index*/,
   1712                 0 /*cookie*/, mStreamBatchBufs->getFd(i), mNumBufs);
   1713 
   1714         if (rc < 0) {
   1715             LOGE("Failed to map buffers");
   1716             rc = BAD_INDEX;
   1717             break;
   1718         }
   1719     }
   1720 
   1721     cam_buf_map_type_list bufMapList;
   1722     if (rc == NO_ERROR) {
   1723         rc = bufferMaps.getCamBufMapList(bufMapList);
   1724     }
   1725     if (rc == NO_ERROR) {
   1726         rc = mapBufs(bufMapList, ops_tbl);
   1727     }
   1728     if (rc < 0) {
   1729         LOGE("Failed to map stream batch buffers");
   1730         mStreamBatchBufs->deallocate();
   1731         delete mStreamBatchBufs;
   1732         mStreamBatchBufs = NULL;
   1733         return NO_MEMORY;
   1734     }
   1735 
   1736     /*calculate stream Buffer count*/
   1737     mNumPlaneBufs =
   1738             (mNumBufs * mStreamInfo->user_buf_info.frame_buf_cnt);
   1739 
   1740     /* For some stream types, buffer allocation may have already begun
   1741      * preemptively. If this is the case, we need to wait for the
   1742      * preemptive allocation to complete before proceeding. */
   1743     mAllocator.waitForDeferredAlloc(mStreamInfo->stream_type);
   1744 
   1745     //Allocate stream buffer
   1746     mStreamBufs = mAllocator.allocateStreamBuf(mStreamInfo->stream_type,
   1747             mFrameLenOffset.frame_len,mFrameLenOffset.mp[0].stride,
   1748             mFrameLenOffset.mp[0].scanline,mNumPlaneBufs);
   1749     if (!mStreamBufs) {
   1750         LOGE("Failed to allocate stream buffers");
   1751         rc = NO_MEMORY;
   1752         goto err1;
   1753     }
   1754 
   1755     //Map plane stream buffers
   1756     for (uint32_t i = 0; i < mNumPlaneBufs; i++) {
   1757         ssize_t bufSize = mStreamBufs->getSize(i);
   1758         if (BAD_INDEX != bufSize) {
   1759             rc = planeBufferMaps.enqueue(CAM_MAPPING_BUF_TYPE_STREAM_BUF,
   1760                     0 /*stream id*/, i /*buf index*/, -1 /*plane index*/,
   1761                     0 /*cookie*/, mStreamBufs->getFd(i), bufSize);
   1762 
   1763             if (rc < 0) {
   1764                 LOGE("Failed to map buffers");
   1765                 mStreamBufs->deallocate();
   1766                 delete mStreamBufs;
   1767                 mStreamBufs = NULL;
   1768                 rc = INVALID_OPERATION;
   1769                 goto err1;
   1770             }
   1771         } else {
   1772             LOGE("Failed to retrieve buffer size (bad index)");
   1773             mStreamBufs->deallocate();
   1774             delete mStreamBufs;
   1775             mStreamBufs = NULL;
   1776             rc = INVALID_OPERATION;
   1777             goto err1;
   1778         }
   1779     }
   1780 
   1781     cam_buf_map_type_list planeBufMapList;
   1782     rc = planeBufferMaps.getCamBufMapList(planeBufMapList);
   1783     if (rc == NO_ERROR) {
   1784         rc = mapBufs(planeBufMapList, ops_tbl);
   1785     }
   1786 
   1787     if (rc < 0) {
   1788         LOGE("map_stream_buf failed: %d", rc);
   1789         mStreamBufs->deallocate();
   1790         delete mStreamBufs;
   1791         mStreamBufs = NULL;
   1792         rc = INVALID_OPERATION;
   1793         goto err1;
   1794     }
   1795 
   1796     LOGD("BATCH Buf Count = %d, Plane Buf Cnt = %d",
   1797             mNumBufs, mNumPlaneBufs);
   1798 
   1799     //regFlags array is allocated by us, but consumed and freed by mm-camera-interface
   1800     regFlags = (uint8_t *)malloc(sizeof(uint8_t) * mNumBufs);
   1801     if (!regFlags) {
   1802         LOGE("Out of memory");
   1803         for (uint32_t i = 0; i < mNumPlaneBufs; i++) {
   1804             unmapBuf(CAM_MAPPING_BUF_TYPE_STREAM_BUF, i, -1, ops_tbl);
   1805         }
   1806         mStreamBufs->deallocate();
   1807         delete mStreamBufs;
   1808         mStreamBufs = NULL;
   1809         rc = NO_MEMORY;
   1810         goto err1;
   1811     }
   1812     memset(regFlags, 0, sizeof(uint8_t) * mNumBufs);
   1813     for (uint32_t i = 0; i < mNumBufs; i++) {
   1814         regFlags[i] = 1;
   1815     }
   1816 
   1817     mBufDefs = (mm_camera_buf_def_t *)malloc(mNumBufs * sizeof(mm_camera_buf_def_t));
   1818     if (mBufDefs == NULL) {
   1819         LOGE("getRegFlags failed %d", rc);
   1820         for (uint32_t i = 0; i < mNumPlaneBufs; i++) {
   1821             unmapBuf(CAM_MAPPING_BUF_TYPE_STREAM_BUF, i, -1, ops_tbl);
   1822         }
   1823         mStreamBufs->deallocate();
   1824         delete mStreamBufs;
   1825         mStreamBufs = NULL;
   1826         free(regFlags);
   1827         regFlags = NULL;
   1828         rc = INVALID_OPERATION;
   1829         goto err1;
   1830     }
   1831     memset(mBufDefs, 0, mNumBufs * sizeof(mm_camera_buf_def_t));
   1832 
   1833     mPlaneBufDefs = (mm_camera_buf_def_t *)
   1834             malloc(mNumPlaneBufs * (sizeof(mm_camera_buf_def_t)));
   1835     if (mPlaneBufDefs == NULL) {
   1836         LOGE("No Memory");
   1837         free(regFlags);
   1838         regFlags = NULL;
   1839         free(mBufDefs);
   1840         mBufDefs = NULL;
   1841         for (uint32_t i = 0; i < mNumPlaneBufs; i++) {
   1842             unmapBuf(CAM_MAPPING_BUF_TYPE_STREAM_BUF, i, -1, ops_tbl);
   1843         }
   1844         mStreamBufs->deallocate();
   1845         delete mStreamBufs;
   1846         mStreamBufs = NULL;
   1847         free(regFlags);
   1848         regFlags = NULL;
   1849         rc = INVALID_OPERATION;
   1850         goto err1;
   1851     }
   1852     memset(mPlaneBufDefs, 0,
   1853              mNumPlaneBufs * (sizeof(mm_camera_buf_def_t)));
   1854 
   1855     for (uint32_t i = 0; i < mStreamInfo->num_bufs; i++) {
   1856         mStreamBatchBufs->getUserBufDef(mStreamInfo->user_buf_info,
   1857                 mBufDefs[i], i, mFrameLenOffset, mPlaneBufDefs,
   1858                 mStreamBufs);
   1859     }
   1860 
   1861     *num_bufs = mNumBufs;
   1862     *initial_reg_flag = regFlags;
   1863     *bufs = mBufDefs;
   1864     LOGH("stream type: %d, numBufs: %d mNumPlaneBufs: %d",
   1865              mStreamInfo->stream_type, mNumBufs, mNumPlaneBufs);
   1866 
   1867     return NO_ERROR;
   1868 
   1869 err1:
   1870     mStreamBatchBufs->deallocate();
   1871     delete mStreamBatchBufs;
   1872     mStreamBatchBufs = NULL;
   1873     return rc;
   1874 }
   1875 
   1876 
   1877 /*===========================================================================
   1878  * FUNCTION   : releaseBuffs
   1879  *
   1880  * DESCRIPTION: method to deallocate stream buffers
   1881  *
   1882  * PARAMETERS :
   1883  *
   1884  * RETURN     : int32_t type of status
   1885  *              NO_ERROR  -- success
   1886  *              none-zero failure code
   1887  *==========================================================================*/
   1888 int32_t QCameraStream::releaseBuffs()
   1889 {
   1890     int rc = NO_ERROR;
   1891 
   1892     if (mStreamInfo->streaming_mode == CAM_STREAMING_MODE_BATCH) {
   1893         return releaseBatchBufs(NULL);
   1894     }
   1895 
   1896     if ((NULL != mBufDefs) && (mStreamBufs != NULL)) {
   1897         uint8_t numBufsToUnmap = mStreamBufs->getMappable();
   1898         for (uint32_t i = 0; i < numBufsToUnmap; i++) {
   1899             rc = unmapBuf(CAM_MAPPING_BUF_TYPE_STREAM_BUF, i, -1, NULL);
   1900             if (rc < 0) {
   1901                 LOGE("map_stream_buf failed: %d", rc);
   1902             }
   1903         }
   1904 
   1905         // mBufDefs just keep a ptr to the buffer
   1906         // mm-camera-interface own the buffer, so no need to free
   1907         mBufDefs = NULL;
   1908         memset(&mFrameLenOffset, 0, sizeof(mFrameLenOffset));
   1909     }
   1910     if (!mStreamBufsAcquired && (mStreamBufs != NULL)) {
   1911         mStreamBufs->deallocate();
   1912         delete mStreamBufs;
   1913         mStreamBufs = NULL;
   1914     }
   1915     return rc;
   1916 }
   1917 
   1918 /*===========================================================================
   1919  * FUNCTION   : releaseBatchBufs
   1920  *
   1921  * DESCRIPTION: method to deallocate stream buffers and batch buffers
   1922  *
   1923  * PARAMETERS :
   1924  *   @ops_tbl    : ptr to buf mapping/unmapping ops
   1925  *
   1926  * RETURN     : int32_t type of status
   1927  *              NO_ERROR  -- success
   1928  *              none-zero failure code
   1929 
   1930  *==========================================================================*/
   1931 int32_t QCameraStream::releaseBatchBufs(mm_camera_map_unmap_ops_tbl_t *ops_tbl)
   1932 {
   1933     int rc = NO_ERROR;
   1934 
   1935     if (NULL != mPlaneBufDefs) {
   1936         for (uint32_t i = 0; i < mNumPlaneBufs; i++) {
   1937             rc = unmapBuf(CAM_MAPPING_BUF_TYPE_STREAM_BUF, i, -1, ops_tbl);
   1938             if (rc < 0) {
   1939                 LOGE("map_stream_buf failed: %d", rc);
   1940             }
   1941         }
   1942 
   1943         // mBufDefs just keep a ptr to the buffer
   1944         // mm-camera-interface own the buffer, so no need to free
   1945         mPlaneBufDefs = NULL;
   1946         memset(&mFrameLenOffset, 0, sizeof(mFrameLenOffset));
   1947         mNumPlaneBufs = 0;
   1948     }
   1949 
   1950     if (mStreamBufs != NULL) {
   1951         mStreamBufs->deallocate();
   1952         delete mStreamBufs;
   1953     }
   1954 
   1955     mBufDefs = NULL;
   1956 
   1957     if (mStreamBatchBufs != NULL) {
   1958         for (uint8_t i = 0; i < mStreamBatchBufs->getCnt(); i++) {
   1959             unmapBuf(CAM_MAPPING_BUF_TYPE_STREAM_USER_BUF, i, -1, ops_tbl);
   1960         }
   1961         mStreamBatchBufs->deallocate();
   1962         delete mStreamBatchBufs;
   1963         mStreamBatchBufs = NULL;
   1964     }
   1965     return rc;
   1966 
   1967 }
   1968 
   1969 /*===========================================================================
   1970  * FUNCTION   : BufAllocRoutine
   1971  *
   1972  * DESCRIPTION: function to allocate additional stream buffers
   1973  *
   1974  * PARAMETERS :
   1975  *   @data    : user data ptr
   1976  *
   1977  * RETURN     : none
   1978  *==========================================================================*/
   1979 void *QCameraStream::BufAllocRoutine(void *data)
   1980 {
   1981     QCameraStream *pme = (QCameraStream *)data;
   1982     int32_t rc = NO_ERROR;
   1983 
   1984     LOGH("E");
   1985     pme->cond_wait();
   1986     if (pme->mNumBufsNeedAlloc > 0) {
   1987         uint8_t numBufAlloc = (uint8_t)(pme->mNumBufs - pme->mNumBufsNeedAlloc);
   1988         rc = pme->mAllocator.allocateMoreStreamBuf(pme->mStreamBufs,
   1989                                                    pme->mFrameLenOffset.frame_len,
   1990                                                    pme->mNumBufsNeedAlloc);
   1991         if (rc != NO_ERROR) {
   1992             LOGE("Failed to allocate buffers");
   1993             pme->mNumBufsNeedAlloc = 0;
   1994             return NULL;
   1995         }
   1996 
   1997         pme->mNumBufsNeedAlloc = 0;
   1998         QCameraBufferMaps bufferMaps;
   1999         for (uint32_t i = numBufAlloc; i < pme->mNumBufs; i++) {
   2000             ssize_t bufSize = pme->mStreamBufs->getSize(i);
   2001             if (BAD_INDEX == bufSize) {
   2002                 LOGE("Failed to retrieve buffer size (bad index)");
   2003                 return NULL;
   2004             }
   2005 
   2006             rc = bufferMaps.enqueue(CAM_MAPPING_BUF_TYPE_STREAM_BUF,
   2007                     pme->mHandle, i /*buf index*/, -1 /*plane index*/,
   2008                     0 /*cookie*/, pme->mStreamBufs->getFd(i), bufSize);
   2009 
   2010             if (rc < 0) {
   2011                 LOGE("Failed to map buffers");
   2012                 return NULL;
   2013             }
   2014         }
   2015 
   2016         cam_buf_map_type_list bufMapList;
   2017         rc = bufferMaps.getCamBufMapList(bufMapList);
   2018         if (rc == NO_ERROR) {
   2019             rc = pme->m_MemOpsTbl.bundled_map_ops(&bufMapList, pme->m_MemOpsTbl.userdata);
   2020         }
   2021         if (rc != 0) {
   2022             LOGE("Failed to map buffers with return code %d", rc);
   2023             return NULL;
   2024         }
   2025 
   2026         for (uint32_t i = numBufAlloc; i < pme->mNumBufs; i++) {
   2027             pme->mStreamBufs->getBufDef(pme->mFrameLenOffset, pme->mBufDefs[i], i);
   2028             pme->mCamOps->qbuf(pme->mCamHandle, pme->mChannelHandle,
   2029                     &pme->mBufDefs[i]);
   2030         }
   2031     }
   2032     LOGH("X");
   2033     return NULL;
   2034 }
   2035 
   2036 /*===========================================================================
   2037  * FUNCTION   : cond_signal
   2038  *
   2039  * DESCRIPTION: signal if flag "wait_for_cond" is set
   2040  *
   2041  *==========================================================================*/
   2042 void QCameraStream::cond_signal(bool forceExit)
   2043 {
   2044     pthread_mutex_lock(&m_lock);
   2045     if(wait_for_cond == TRUE){
   2046         wait_for_cond = FALSE;
   2047         if (forceExit) {
   2048             mNumBufsNeedAlloc = 0;
   2049         }
   2050         pthread_cond_signal(&m_cond);
   2051     }
   2052     pthread_mutex_unlock(&m_lock);
   2053 }
   2054 
   2055 
   2056 /*===========================================================================
   2057  * FUNCTION   : cond_wait
   2058  *
   2059  * DESCRIPTION: wait on if flag "wait_for_cond" is set
   2060  *
   2061  *==========================================================================*/
   2062 void QCameraStream::cond_wait()
   2063 {
   2064     pthread_mutex_lock(&m_lock);
   2065     while (wait_for_cond == TRUE) {
   2066         pthread_cond_wait(&m_cond, &m_lock);
   2067     }
   2068     pthread_mutex_unlock(&m_lock);
   2069 }
   2070 
   2071 /*===========================================================================
   2072  * FUNCTION   : putBufs
   2073  *
   2074  * DESCRIPTION: deallocate stream buffers
   2075  *
   2076  * PARAMETERS :
   2077  *   @ops_tbl    : ptr to buf mapping/unmapping ops
   2078  *
   2079  * RETURN     : int32_t type of status
   2080  *              NO_ERROR  -- success
   2081  *              none-zero failure code
   2082  *==========================================================================*/
   2083 int32_t QCameraStream::putBufs(mm_camera_map_unmap_ops_tbl_t *ops_tbl)
   2084 {
   2085     int rc = NO_ERROR;
   2086 
   2087     if (mBufAllocPid != 0) {
   2088         cond_signal(true);
   2089         LOGL("wait for buf allocation thread dead");
   2090         pthread_join(mBufAllocPid, NULL);
   2091         mBufAllocPid = 0;
   2092         LOGL("return from buf allocation thread");
   2093     }
   2094 
   2095     uint8_t numBufsToUnmap = mStreamBufs->getMappable();
   2096     for (uint32_t i = 0; i < numBufsToUnmap; i++) {
   2097         rc = ops_tbl->unmap_ops(i, -1, CAM_MAPPING_BUF_TYPE_STREAM_BUF, ops_tbl->userdata);
   2098         if (rc < 0) {
   2099             LOGE("map_stream_buf failed: %d", rc);
   2100         }
   2101     }
   2102     mBufDefs = NULL; // mBufDefs just keep a ptr to the buffer
   2103                      // mm-camera-interface own the buffer, so no need to free
   2104     memset(&mFrameLenOffset, 0, sizeof(mFrameLenOffset));
   2105     if ( !mStreamBufsAcquired ) {
   2106         mStreamBufs->deallocate();
   2107         delete mStreamBufs;
   2108         mStreamBufs = NULL;
   2109     }
   2110 
   2111     return rc;
   2112 }
   2113 
   2114 /*===========================================================================
   2115  * FUNCTION   : putBufsDeffered
   2116  *
   2117  * DESCRIPTION: function to deallocate deffered stream buffers
   2118  *
   2119  * PARAMETERS : none
   2120  *
   2121  * RETURN     : int32_t type of status
   2122  *              NO_ERROR  -- success
   2123  *              none-zero failure code
   2124  *==========================================================================*/
   2125 int32_t QCameraStream::putBufsDeffered()
   2126 {
   2127     if (mBufAllocPid != 0) {
   2128         cond_signal(true);
   2129         LOGH("%s: wait for buf allocation thread dead", __func__);
   2130         // Wait for the allocation of additional stream buffers
   2131         pthread_join(mBufAllocPid, NULL);
   2132         mBufAllocPid = 0;
   2133         LOGH("%s: return from buf allocation thread", __func__);
   2134     }
   2135     // Deallocation of the deffered stream buffers handled separately
   2136     return NO_ERROR;
   2137 }
   2138 
   2139 /*===========================================================================
   2140  * FUNCTION   : invalidateBuf
   2141  *
   2142  * DESCRIPTION: invalidate a specific stream buffer
   2143  *
   2144  * PARAMETERS :
   2145  *   @index   : index of the buffer to invalidate
   2146  *
   2147  * RETURN     : int32_t type of status
   2148  *              NO_ERROR  -- success
   2149  *              none-zero failure code
   2150  *==========================================================================*/
   2151 int32_t QCameraStream::invalidateBuf(uint32_t index)
   2152 {
   2153     if (mStreamBufs == NULL) {
   2154         LOGE("Invalid Operation");
   2155         return INVALID_OPERATION;
   2156     }
   2157     return mStreamBufs->invalidateCache(index);
   2158 }
   2159 
   2160 /*===========================================================================
   2161  * FUNCTION   : cleanInvalidateBuf
   2162  *
   2163  * DESCRIPTION: clean invalidate a specific stream buffer
   2164  *
   2165  * PARAMETERS :
   2166  *   @index   : index of the buffer to clean invalidate
   2167  *
   2168  * RETURN     : int32_t type of status
   2169  *              NO_ERROR  -- success
   2170  *              none-zero failure code
   2171  *==========================================================================*/
   2172 int32_t QCameraStream::cleanInvalidateBuf(uint32_t index)
   2173 {
   2174     if (mStreamBufs == NULL) {
   2175         LOGE("Invalid Operation");
   2176         return INVALID_OPERATION;
   2177     }
   2178     return mStreamBufs->cleanInvalidateCache(index);
   2179 }
   2180 
   2181 /*===========================================================================
   2182  * FUNCTION   : isTypeOf
   2183  *
   2184  * DESCRIPTION: helper function to determine if the stream is of the queried type
   2185  *
   2186  * PARAMETERS :
   2187  *   @type    : stream type as of queried
   2188  *
   2189  * RETURN     : true/false
   2190  *==========================================================================*/
   2191 bool QCameraStream::isTypeOf(cam_stream_type_t type)
   2192 {
   2193     if (mStreamInfo != NULL && (mStreamInfo->stream_type == type)) {
   2194         return true;
   2195     } else {
   2196         return false;
   2197     }
   2198 }
   2199 
   2200 /*===========================================================================
   2201  * FUNCTION   : isOrignalTypeOf
   2202  *
   2203  * DESCRIPTION: helper function to determine if the original stream is of the
   2204  *              queried type if it's reproc stream
   2205  *
   2206  * PARAMETERS :
   2207  *   @type    : stream type as of queried
   2208  *
   2209  * RETURN     : true/false
   2210  *==========================================================================*/
   2211 bool QCameraStream::isOrignalTypeOf(cam_stream_type_t type)
   2212 {
   2213     if (mStreamInfo != NULL &&
   2214         mStreamInfo->stream_type == CAM_STREAM_TYPE_OFFLINE_PROC &&
   2215         mStreamInfo->reprocess_config.pp_type == CAM_ONLINE_REPROCESS_TYPE &&
   2216         mStreamInfo->reprocess_config.online.input_stream_type == type) {
   2217         return true;
   2218     } else if (
   2219         mStreamInfo != NULL &&
   2220         mStreamInfo->stream_type == CAM_STREAM_TYPE_OFFLINE_PROC &&
   2221         mStreamInfo->reprocess_config.pp_type == CAM_OFFLINE_REPROCESS_TYPE &&
   2222         mStreamInfo->reprocess_config.offline.input_type == type) {
   2223         return true;
   2224     } else {
   2225         return false;
   2226     }
   2227 }
   2228 
   2229 /*===========================================================================
   2230  * FUNCTION   : getMyType
   2231  *
   2232  * DESCRIPTION: return stream type
   2233  *
   2234  * PARAMETERS : none
   2235  *
   2236  * RETURN     : stream type
   2237  *==========================================================================*/
   2238 cam_stream_type_t QCameraStream::getMyType()
   2239 {
   2240     if (mStreamInfo != NULL) {
   2241         return mStreamInfo->stream_type;
   2242     } else {
   2243         return CAM_STREAM_TYPE_DEFAULT;
   2244     }
   2245 }
   2246 
   2247 /*===========================================================================
   2248  * FUNCTION   : getMyOriginalType
   2249  *
   2250  * DESCRIPTION: return stream type
   2251  *
   2252  * PARAMETERS : none
   2253  *
   2254  * RETURN     : stream type
   2255  *==========================================================================*/
   2256 cam_stream_type_t QCameraStream::getMyOriginalType()
   2257 {
   2258     if (mStreamInfo != NULL) {
   2259         if (mStreamInfo->stream_type == CAM_STREAM_TYPE_OFFLINE_PROC &&
   2260                 mStreamInfo->reprocess_config.pp_type == CAM_ONLINE_REPROCESS_TYPE) {
   2261             return mStreamInfo->reprocess_config.online.input_stream_type;
   2262         } else if (mStreamInfo->stream_type == CAM_STREAM_TYPE_OFFLINE_PROC &&
   2263                 mStreamInfo->reprocess_config.pp_type == CAM_OFFLINE_REPROCESS_TYPE) {
   2264             return mStreamInfo->reprocess_config.offline.input_type;
   2265         } else {
   2266             return mStreamInfo->stream_type;
   2267         }
   2268     } else {
   2269         return CAM_STREAM_TYPE_DEFAULT;
   2270     }
   2271 }
   2272 
   2273 /*===========================================================================
   2274  * FUNCTION   : getFrameOffset
   2275  *
   2276  * DESCRIPTION: query stream buffer frame offset info
   2277  *
   2278  * PARAMETERS :
   2279  *   @offset  : reference to struct to store the queried frame offset info
   2280  *
   2281  * RETURN     : int32_t type of status
   2282  *              NO_ERROR  -- success
   2283  *              none-zero failure code
   2284  *==========================================================================*/
   2285 int32_t QCameraStream::getFrameOffset(cam_frame_len_offset_t &offset)
   2286 {
   2287     if (NULL == mStreamInfo) {
   2288         return NO_INIT;
   2289     }
   2290 
   2291     offset = mFrameLenOffset;
   2292     if ((ROTATE_90 == mOnlineRotation) || (ROTATE_270 == mOnlineRotation)
   2293             || (offset.frame_len == 0) || (offset.num_planes == 0)) {
   2294         // Re-calculate frame offset in case of online rotation
   2295         cam_stream_info_t streamInfo = *mStreamInfo;
   2296         getFrameDimension(streamInfo.dim);
   2297         calcOffset(&streamInfo);
   2298         offset = streamInfo.buf_planes.plane_info;
   2299     }
   2300 
   2301     return 0;
   2302 }
   2303 
   2304 /*===========================================================================
   2305  * FUNCTION   : getCropInfo
   2306  *
   2307  * DESCRIPTION: query crop info of the stream
   2308  *
   2309  * PARAMETERS :
   2310  *   @crop    : reference to struct to store the queried crop info
   2311  *
   2312  * RETURN     : int32_t type of status
   2313  *              NO_ERROR  -- success
   2314  *              none-zero failure code
   2315  *==========================================================================*/
   2316 int32_t QCameraStream::getCropInfo(cam_rect_t &crop)
   2317 {
   2318     pthread_mutex_lock(&mCropLock);
   2319     crop = mCropInfo;
   2320     pthread_mutex_unlock(&mCropLock);
   2321     return NO_ERROR;
   2322 }
   2323 
   2324 /*===========================================================================
   2325  * FUNCTION   : setCropInfo
   2326  *
   2327  * DESCRIPTION: set crop info of the stream
   2328  *
   2329  * PARAMETERS :
   2330  *   @crop    : struct to store new crop info
   2331  *
   2332  * RETURN     : int32_t type of status
   2333  *              NO_ERROR  -- success
   2334  *              none-zero failure code
   2335  *==========================================================================*/
   2336 int32_t QCameraStream::setCropInfo(cam_rect_t crop)
   2337 {
   2338     pthread_mutex_lock(&mCropLock);
   2339     mCropInfo = crop;
   2340     pthread_mutex_unlock(&mCropLock);
   2341     return NO_ERROR;
   2342 }
   2343 
   2344 /*===========================================================================
   2345  * FUNCTION   : getFrameDimension
   2346  *
   2347  * DESCRIPTION: query stream frame dimension info
   2348  *
   2349  * PARAMETERS :
   2350  *   @dim     : reference to struct to store the queried frame dimension
   2351  *
   2352  * RETURN     : int32_t type of status
   2353  *              NO_ERROR  -- success
   2354  *              none-zero failure code
   2355  *==========================================================================*/
   2356 int32_t QCameraStream::getFrameDimension(cam_dimension_t &dim)
   2357 {
   2358     if (mStreamInfo != NULL) {
   2359         if ((ROTATE_90 == mOnlineRotation) || (ROTATE_270 == mOnlineRotation)) {
   2360             dim.width = mStreamInfo->dim.height;
   2361             dim.height = mStreamInfo->dim.width;
   2362         } else {
   2363             dim = mStreamInfo->dim;
   2364         }
   2365         return 0;
   2366     }
   2367     return -1;
   2368 }
   2369 
   2370 /*===========================================================================
   2371  * FUNCTION   : getFormat
   2372  *
   2373  * DESCRIPTION: query stream format
   2374  *
   2375  * PARAMETERS :
   2376  *   @fmt     : reference to stream format
   2377  *
   2378  * RETURN     : int32_t type of status
   2379  *              NO_ERROR  -- success
   2380  *              none-zero failure code
   2381  *==========================================================================*/
   2382 int32_t QCameraStream::getFormat(cam_format_t &fmt)
   2383 {
   2384     if (mStreamInfo != NULL) {
   2385         fmt = mStreamInfo->fmt;
   2386         return 0;
   2387     }
   2388     return -1;
   2389 }
   2390 
   2391 /*===========================================================================
   2392  * FUNCTION   : getMyServerID
   2393  *
   2394  * DESCRIPTION: query server stream ID
   2395  *
   2396  * PARAMETERS : None
   2397  *
   2398  * RETURN     : stream ID from server
   2399  *==========================================================================*/
   2400 uint32_t QCameraStream::getMyServerID() {
   2401     if (mStreamInfo != NULL) {
   2402         return mStreamInfo->stream_svr_id;
   2403     } else {
   2404         return 0;
   2405     }
   2406 }
   2407 
   2408 /*===========================================================================
   2409  * FUNCTION   : acquireStreamBufs
   2410  *
   2411  * DESCRIPTION: acquire stream buffers and postpone their release.
   2412  *
   2413  * PARAMETERS : None
   2414  *
   2415  * RETURN     : int32_t type of status
   2416  *              NO_ERROR  -- success
   2417  *              none-zero failure code
   2418  *==========================================================================*/
   2419 int32_t QCameraStream::acquireStreamBufs()
   2420 {
   2421     mStreamBufsAcquired = true;
   2422 
   2423     return NO_ERROR;
   2424 }
   2425 
   2426 /*===========================================================================
   2427  * FUNCTION   : mapBuf
   2428  *
   2429  * DESCRIPTION: map stream related buffer to backend server
   2430  *
   2431  * PARAMETERS :
   2432  *   @buf_type : mapping type of buffer
   2433  *   @buf_idx  : index of buffer
   2434  *   @plane_idx: plane index
   2435  *   @fd       : fd of the buffer
   2436  *   @size     : lenght of the buffer
   2437  *   @ops_tbl    : ptr to buf mapping/unmapping ops
   2438  *
   2439  * RETURN     : int32_t type of status
   2440  *              NO_ERROR  -- success
   2441  *              none-zero failure code
   2442  *==========================================================================*/
   2443 int32_t QCameraStream::mapBuf(uint8_t buf_type, uint32_t buf_idx,
   2444         int32_t plane_idx, int fd, size_t size, mm_camera_map_unmap_ops_tbl_t *ops_tbl)
   2445 {
   2446     cam_buf_map_type_list bufMapList;
   2447     int32_t rc = QCameraBufferMaps::makeSingletonBufMapList(
   2448            (cam_mapping_buf_type)buf_type, mHandle, buf_idx, plane_idx,
   2449            0 /*cookie*/, fd, size, bufMapList);
   2450 
   2451     if (rc != NO_ERROR) {
   2452         return rc;
   2453     }
   2454 
   2455     return mapBufs(bufMapList, ops_tbl);
   2456 }
   2457 
   2458 /*===========================================================================
   2459  * FUNCTION   : mapBufs
   2460  *
   2461  * DESCRIPTION: map stream related buffers to backend server
   2462  *
   2463  * PARAMETERS :
   2464  *   @bufMapList : buffer mapping information
   2465  *   @ops_tbl    : ptr to buf mapping/unmapping ops
   2466  *
   2467  * RETURN     : int32_t type of status
   2468  *              NO_ERROR  -- success
   2469  *              none-zero failure code
   2470  *==========================================================================*/
   2471 
   2472 int32_t QCameraStream::mapBufs(cam_buf_map_type_list bufMapList,
   2473         __unused mm_camera_map_unmap_ops_tbl_t *ops_tbl)
   2474 {
   2475     if (m_MemOpsTbl.bundled_map_ops != NULL) {
   2476         return m_MemOpsTbl.bundled_map_ops(&bufMapList, m_MemOpsTbl.userdata);
   2477     } else {
   2478         return mCamOps->map_stream_bufs(mCamHandle, mChannelHandle,
   2479                 &bufMapList);
   2480     }
   2481 
   2482 }
   2483 
   2484 /*===========================================================================
   2485  * FUNCTION   : unmapBuf
   2486  *
   2487  * DESCRIPTION: unmap stream related buffer to backend server
   2488  *
   2489  * PARAMETERS :
   2490  *   @buf_type : mapping type of buffer
   2491  *   @buf_idx  : index of buffer
   2492  *   @plane_idx: plane index
   2493  *   @ops_tbl    : ptr to buf mapping/unmapping ops
   2494  *
   2495  * RETURN     : int32_t type of status
   2496  *              NO_ERROR  -- success
   2497  *              none-zero failure code
   2498  *==========================================================================*/
   2499 int32_t QCameraStream::unmapBuf(uint8_t buf_type, uint32_t buf_idx, int32_t plane_idx,
   2500         mm_camera_map_unmap_ops_tbl_t *ops_tbl)
   2501 {
   2502     if (ops_tbl != NULL) {
   2503         return ops_tbl->unmap_ops(buf_idx, plane_idx,
   2504                 (cam_mapping_buf_type)buf_type, ops_tbl->userdata);
   2505     } else {
   2506         return mCamOps->unmap_stream_buf(mCamHandle, mChannelHandle,
   2507                 mHandle, buf_type, buf_idx, plane_idx);
   2508     }
   2509 }
   2510 
   2511 /*===========================================================================
   2512  * FUNCTION   : setParameter
   2513  *
   2514  * DESCRIPTION: set stream based parameters
   2515  *
   2516  * PARAMETERS :
   2517  *   @param   : ptr to parameters to be set
   2518  *
   2519  * RETURN     : int32_t type of status
   2520  *              NO_ERROR  -- success
   2521  *              none-zero failure code
   2522  *==========================================================================*/
   2523 int32_t QCameraStream::setParameter(cam_stream_parm_buffer_t &param)
   2524 {
   2525     int32_t rc = NO_ERROR;
   2526     pthread_mutex_lock(&mParameterLock);
   2527     mStreamInfo->parm_buf = param;
   2528     rc = mCamOps->set_stream_parms(mCamHandle,
   2529                                    mChannelHandle,
   2530                                    mHandle,
   2531                                    &mStreamInfo->parm_buf);
   2532     if (rc == NO_ERROR) {
   2533         param = mStreamInfo->parm_buf;
   2534     }
   2535     pthread_mutex_unlock(&mParameterLock);
   2536     return rc;
   2537 }
   2538 
   2539 /*===========================================================================
   2540  * FUNCTION   : getParameter
   2541  *
   2542  * DESCRIPTION: get stream based parameters
   2543  *
   2544  * PARAMETERS :
   2545  *   @param   : ptr to parameters to be red
   2546  *
   2547  * RETURN     : int32_t type of status
   2548  *              NO_ERROR  -- success
   2549  *              none-zero failure code
   2550  *==========================================================================*/
   2551 int32_t QCameraStream::getParameter(cam_stream_parm_buffer_t &param)
   2552 {
   2553     int32_t rc = NO_ERROR;
   2554     pthread_mutex_lock(&mParameterLock);
   2555     mStreamInfo->parm_buf = param;
   2556     rc = mCamOps->get_stream_parms(mCamHandle,
   2557                                    mChannelHandle,
   2558                                    mHandle,
   2559                                    &mStreamInfo->parm_buf);
   2560     if (rc == NO_ERROR) {
   2561         param = mStreamInfo->parm_buf;
   2562     }
   2563     pthread_mutex_unlock(&mParameterLock);
   2564     return rc;
   2565 }
   2566 
   2567 /*===========================================================================
   2568  * FUNCTION   : releaseFrameData
   2569  *
   2570  * DESCRIPTION: callback function to release frame data node
   2571  *
   2572  * PARAMETERS :
   2573  *   @data      : ptr to post process input data
   2574  *   @user_data : user data ptr (QCameraReprocessor)
   2575  *
   2576  * RETURN     : None
   2577  *==========================================================================*/
   2578 void QCameraStream::releaseFrameData(void *data, void *user_data)
   2579 {
   2580     QCameraStream *pme = (QCameraStream *)user_data;
   2581     mm_camera_super_buf_t *frame = (mm_camera_super_buf_t *)data;
   2582     if (NULL != pme) {
   2583         pme->bufDone(frame->bufs[0]->buf_idx);
   2584     }
   2585 }
   2586 
   2587 /*===========================================================================
   2588  * FUNCTION   : configStream
   2589  *
   2590  * DESCRIPTION: send stream configuration to back end
   2591  *
   2592  * PARAMETERS :
   2593  *
   2594  * RETURN     : int32_t type of status
   2595  *              NO_ERROR  -- success
   2596  *              none-zero failure code
   2597  *==========================================================================*/
   2598 int32_t QCameraStream::configStream()
   2599 {
   2600     int rc = NO_ERROR;
   2601 
   2602     // Configure the stream
   2603     mm_camera_stream_config_t stream_config;
   2604     stream_config.stream_info = mStreamInfo;
   2605     stream_config.mem_vtbl = mMemVtbl;
   2606     stream_config.stream_cb_sync = NULL;
   2607     stream_config.stream_cb = dataNotifyCB;
   2608     stream_config.padding_info = mPaddingInfo;
   2609     stream_config.userdata = this;
   2610     rc = mCamOps->config_stream(mCamHandle,
   2611                 mChannelHandle, mHandle, &stream_config);
   2612     if (rc < 0) {
   2613         LOGE("Failed to config stream, rc = %d", rc);
   2614         mCamOps->unmap_stream_buf(mCamHandle,
   2615                 mChannelHandle,
   2616                 mHandle,
   2617                 CAM_MAPPING_BUF_TYPE_STREAM_INFO,
   2618                 0,
   2619                 -1);
   2620         return UNKNOWN_ERROR;
   2621     }
   2622 
   2623     return rc;
   2624 }
   2625 
   2626 /*===========================================================================
   2627  * FUNCTION   : setSyncDataCB
   2628  *
   2629  * DESCRIPTION: register callback with mm-interface for this stream
   2630  *
   2631  * PARAMETERS :
   2632        @stream_cb   : Callback function
   2633  *
   2634  * RETURN     : int32_t type of status
   2635  *              NO_ERROR  -- success
   2636  *              non-zero failure code
   2637  *==========================================================================*/
   2638 int32_t QCameraStream::setSyncDataCB(stream_cb_routine data_cb)
   2639 {
   2640     int32_t rc = NO_ERROR;
   2641 
   2642     if (mCamOps != NULL) {
   2643         mSYNCDataCB = data_cb;
   2644         rc = mCamOps->register_stream_buf_cb(mCamHandle,
   2645                 mChannelHandle, mHandle, dataNotifySYNCCB, MM_CAMERA_STREAM_CB_TYPE_SYNC,
   2646                 this);
   2647         if (rc == NO_ERROR) {
   2648             mSyncCBEnabled = TRUE;
   2649             return rc;
   2650         }
   2651     }
   2652     LOGE("Interface handle is NULL");
   2653     return UNKNOWN_ERROR;
   2654 }
   2655 
   2656 }; // namespace qcamera
   2657