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, Buf->getPtr(i));
    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                 mStreamBufs->getPtr(i));
   1308 
   1309         if (rc < 0) {
   1310             LOGE("Failed to map buffers");
   1311             return BAD_INDEX;
   1312         }
   1313     }
   1314 
   1315     cam_buf_map_type_list bufMapList;
   1316     rc = bufferMaps.getCamBufMapList(bufMapList);
   1317     if (rc == NO_ERROR) {
   1318         rc = ops_tbl->bundled_map_ops(&bufMapList, ops_tbl->userdata);
   1319     }
   1320     if (rc < 0) {
   1321         LOGE("map_stream_buf failed: %d", rc);
   1322         mStreamBufs->deallocate();
   1323         delete mStreamBufs;
   1324         mStreamBufs = NULL;
   1325         return INVALID_OPERATION;
   1326     }
   1327 
   1328     //regFlags array is allocated by us, but consumed and freed by mm-camera-interface
   1329     regFlags = (uint8_t *)malloc(sizeof(uint8_t) * mNumBufs);
   1330     if (!regFlags) {
   1331         LOGE("Out of memory");
   1332         for (uint32_t i = 0; i < numBufsToMap; i++) {
   1333             ops_tbl->unmap_ops(i, -1, CAM_MAPPING_BUF_TYPE_STREAM_BUF, ops_tbl->userdata);
   1334         }
   1335         mStreamBufs->deallocate();
   1336         delete mStreamBufs;
   1337         mStreamBufs = NULL;
   1338         return NO_MEMORY;
   1339     }
   1340     memset(regFlags, 0, sizeof(uint8_t) * mNumBufs);
   1341 
   1342     mBufDefs = (mm_camera_buf_def_t *)malloc(mNumBufs * sizeof(mm_camera_buf_def_t));
   1343     if (mBufDefs == NULL) {
   1344         LOGE("getRegFlags failed %d", rc);
   1345         for (uint32_t i = 0; i < numBufsToMap; i++) {
   1346             ops_tbl->unmap_ops(i, -1, CAM_MAPPING_BUF_TYPE_STREAM_BUF, ops_tbl->userdata);
   1347         }
   1348         mStreamBufs->deallocate();
   1349         delete mStreamBufs;
   1350         mStreamBufs = NULL;
   1351         free(regFlags);
   1352         regFlags = NULL;
   1353         return INVALID_OPERATION;
   1354     }
   1355     memset(mBufDefs, 0, mNumBufs * sizeof(mm_camera_buf_def_t));
   1356     for (uint32_t i = 0; i < numBufsToMap; i++) {
   1357         mStreamBufs->getBufDef(mFrameLenOffset, mBufDefs[i], i);
   1358     }
   1359 
   1360     rc = mStreamBufs->getRegFlags(regFlags);
   1361     if (rc < 0) {
   1362         LOGE("getRegFlags failed %d", rc);
   1363         for (uint32_t i = 0; i < numBufsToMap; i++) {
   1364             ops_tbl->unmap_ops(i, -1, CAM_MAPPING_BUF_TYPE_STREAM_BUF, ops_tbl->userdata);
   1365         }
   1366         mStreamBufs->deallocate();
   1367         delete mStreamBufs;
   1368         mStreamBufs = NULL;
   1369         free(mBufDefs);
   1370         mBufDefs = NULL;
   1371         free(regFlags);
   1372         regFlags = NULL;
   1373         return INVALID_OPERATION;
   1374     }
   1375 
   1376     *num_bufs = mNumBufs;
   1377     *initial_reg_flag = regFlags;
   1378     *bufs = mBufDefs;
   1379     LOGH("stream type: %d, mRegFlags: %p, numBufs: %d",
   1380              mStreamInfo->stream_type, regFlags, mNumBufs);
   1381 
   1382     if (mNumBufsNeedAlloc > 0) {
   1383         pthread_mutex_lock(&m_lock);
   1384         wait_for_cond = TRUE;
   1385         pthread_mutex_unlock(&m_lock);
   1386         LOGH("Still need to allocate %d buffers",
   1387                mNumBufsNeedAlloc);
   1388         // start another thread to allocate the rest of buffers
   1389         pthread_create(&mBufAllocPid,
   1390                        NULL,
   1391                        BufAllocRoutine,
   1392                        this);
   1393         pthread_setname_np(mBufAllocPid, "CAM_strmBuf");
   1394     }
   1395 
   1396     return NO_ERROR;
   1397 }
   1398 
   1399 /*===========================================================================
   1400  * FUNCTION   : getBufsDeferred
   1401  *
   1402  * DESCRIPTION: allocate deferred stream buffers
   1403  *
   1404  * PARAMETERS :
   1405  *   @offset     : offset info of stream buffers
   1406  *   @num_bufs   : number of buffers allocated
   1407  *   @initial_reg_flag: flag to indicate if buffer needs to be registered
   1408  *                      at kernel initially
   1409  *   @bufs       : output of allocated buffers
   1410  *   @ops_tbl    : ptr to buf mapping/unmapping ops
   1411  *
   1412  * RETURN     : int32_t type of status
   1413  *              NO_ERROR  -- success
   1414  *              none-zero failure code
   1415  *==========================================================================*/
   1416 int32_t QCameraStream::getBufsDeferred(__unused cam_frame_len_offset_t *offset,
   1417         uint8_t *num_bufs,
   1418         uint8_t **initial_reg_flag,
   1419         mm_camera_buf_def_t **bufs,
   1420         __unused mm_camera_map_unmap_ops_tbl_t *ops_tbl)
   1421 {
   1422     int32_t rc = NO_ERROR;
   1423     // wait for allocation
   1424     rc = mAllocator.waitForBackgroundTask(mAllocTaskId);
   1425     if (rc != NO_ERROR) {
   1426         LOGE("Allocation Failed");
   1427         return NO_MEMORY;
   1428     }
   1429 
   1430     if (!mRegFlags || !mBufDefs) {
   1431         LOGE("reg flags or buf defs uninitialized");
   1432         return NO_MEMORY;
   1433     }
   1434 
   1435     *initial_reg_flag   = mRegFlags;
   1436     *num_bufs           = mNumBufs;
   1437     *bufs               = mBufDefs;
   1438 
   1439     LOGH("stream type: %d, mRegFlags: 0x%x, numBufs: %d",
   1440              getMyType(), mRegFlags, mNumBufs);
   1441 
   1442     return NO_ERROR;
   1443 }
   1444 /*===========================================================================
   1445  * FUNCTION   : mapNewBuffer
   1446  *
   1447  * DESCRIPTION: map a new stream buffer
   1448  *
   1449  * PARAMETERS :
   1450  *
   1451  * RETURN     : int32_t type of status
   1452  *              NO_ERROR  -- success
   1453  *              none-zero failure code
   1454  *==========================================================================*/
   1455 int32_t QCameraStream::mapNewBuffer(uint32_t index)
   1456 {
   1457     LOGH("E - index = %d", index);
   1458 
   1459     int rc = NO_ERROR;
   1460 
   1461     if (mStreamBufs == NULL) {
   1462         LOGE("Invalid Operation");
   1463         return INVALID_OPERATION;
   1464     }
   1465 
   1466     ssize_t bufSize = mStreamBufs->getSize(index);
   1467     if (BAD_INDEX == bufSize) {
   1468         LOGE("Failed to retrieve buffer size (bad index)");
   1469         return INVALID_OPERATION;
   1470     }
   1471 
   1472     cam_buf_map_type_list bufMapList;
   1473     rc = QCameraBufferMaps::makeSingletonBufMapList(
   1474             CAM_MAPPING_BUF_TYPE_STREAM_BUF, 0 /*stream id*/, index,
   1475             -1 /*plane index*/, 0 /*cookie*/, mStreamBufs->getFd(index),
   1476             bufSize, bufMapList, mStreamBufs->getPtr(index));
   1477 
   1478     if (rc == NO_ERROR) {
   1479         rc = m_MemOpsTbl.bundled_map_ops(&bufMapList, m_MemOpsTbl.userdata);
   1480     }
   1481     if (rc < 0) {
   1482         LOGE("map_stream_buf failed: %d", rc);
   1483         rc = INVALID_OPERATION;
   1484     } else {
   1485         mStreamBufs->getBufDef(mFrameLenOffset, mBufDefs[index], index);
   1486     }
   1487 
   1488     LOGH("X - rc = %d", rc);
   1489     return rc;
   1490 }
   1491 
   1492 /*===========================================================================
   1493  * FUNCTION   : allocateBuffers
   1494  *
   1495  * DESCRIPTION: allocate stream buffers
   1496  *
   1497  * PARAMETERS :
   1498  *
   1499  * RETURN     : int32_t type of status
   1500  *              NO_ERROR  -- success
   1501  *              none-zero failure code
   1502  *==========================================================================*/
   1503 int32_t QCameraStream::allocateBuffers()
   1504 {
   1505     int32_t rc = NO_ERROR;
   1506 
   1507     mFrameLenOffset = mStreamInfo->buf_planes.plane_info;
   1508 
   1509     if (mStreamInfo->streaming_mode == CAM_STREAMING_MODE_BATCH) {
   1510         return allocateBatchBufs(&mFrameLenOffset,
   1511                 &mNumBufs, &mRegFlags,
   1512                 &mBufDefs, NULL);
   1513     }
   1514 
   1515     /* This allocation is running in the deferred context, so it
   1516      * is safe (and necessary) to assume any preemptive allocation
   1517      * is already complete. Therefore, no need to wait here. */
   1518 
   1519     uint8_t numBufAlloc = mNumBufs;
   1520     mNumBufsNeedAlloc = 0;
   1521     if (mDynBufAlloc) {
   1522         numBufAlloc = CAMERA_MIN_ALLOCATED_BUFFERS;
   1523         if (numBufAlloc > mNumBufs) {
   1524             mDynBufAlloc = false;
   1525             numBufAlloc = mNumBufs;
   1526         } else {
   1527             mNumBufsNeedAlloc = (uint8_t)(mNumBufs - numBufAlloc);
   1528         }
   1529     }
   1530 
   1531     //Allocate and map stream info buffer
   1532     mStreamBufs = mAllocator.allocateStreamBuf(mStreamInfo->stream_type,
   1533             mFrameLenOffset.frame_len,
   1534             mFrameLenOffset.mp[0].stride,
   1535             mFrameLenOffset.mp[0].scanline,
   1536             numBufAlloc);
   1537 
   1538     if (!mStreamBufs) {
   1539         LOGE("Failed to allocate stream buffers");
   1540         return NO_MEMORY;
   1541     }
   1542 
   1543     mNumBufs = (uint8_t)(numBufAlloc + mNumBufsNeedAlloc);
   1544     uint8_t numBufsToMap = mStreamBufs->getMappable();
   1545 
   1546     //regFlags array is allocated by us,
   1547     // but consumed and freed by mm-camera-interface
   1548     mRegFlags = (uint8_t *)malloc(sizeof(uint8_t) * mNumBufs);
   1549     if (!mRegFlags) {
   1550         LOGE("Out of memory");
   1551         for (uint32_t i = 0; i < numBufsToMap; i++) {
   1552             unmapBuf(CAM_MAPPING_BUF_TYPE_STREAM_BUF, i, -1, NULL);
   1553         }
   1554         mStreamBufs->deallocate();
   1555         delete mStreamBufs;
   1556         mStreamBufs = NULL;
   1557         return NO_MEMORY;
   1558     }
   1559     memset(mRegFlags, 0, sizeof(uint8_t) * mNumBufs);
   1560 
   1561     size_t bufDefsSize = mNumBufs * sizeof(mm_camera_buf_def_t);
   1562     mBufDefs = (mm_camera_buf_def_t *)malloc(bufDefsSize);
   1563     if (mBufDefs == NULL) {
   1564         LOGE("getRegFlags failed %d", rc);
   1565         for (uint32_t i = 0; i < numBufsToMap; i++) {
   1566             unmapBuf(CAM_MAPPING_BUF_TYPE_STREAM_BUF, i, -1, NULL);
   1567         }
   1568         mStreamBufs->deallocate();
   1569         delete mStreamBufs;
   1570         mStreamBufs = NULL;
   1571         free(mRegFlags);
   1572         mRegFlags = NULL;
   1573         return INVALID_OPERATION;
   1574     }
   1575     memset(mBufDefs, 0, bufDefsSize);
   1576     for (uint32_t i = 0; i < numBufsToMap; i++) {
   1577         mStreamBufs->getBufDef(mFrameLenOffset, mBufDefs[i], i);
   1578     }
   1579 
   1580     rc = mStreamBufs->getRegFlags(mRegFlags);
   1581     if (rc < 0) {
   1582         LOGE("getRegFlags failed %d", rc);
   1583         for (uint32_t i = 0; i < numBufsToMap; i++) {
   1584             unmapBuf(CAM_MAPPING_BUF_TYPE_STREAM_BUF, i, -1, NULL);
   1585         }
   1586         mStreamBufs->deallocate();
   1587         delete mStreamBufs;
   1588         mStreamBufs = NULL;
   1589         free(mBufDefs);
   1590         mBufDefs = NULL;
   1591         free(mRegFlags);
   1592         mRegFlags = NULL;
   1593         return INVALID_OPERATION;
   1594     }
   1595 
   1596     if (mNumBufsNeedAlloc > 0) {
   1597         pthread_mutex_lock(&m_lock);
   1598         wait_for_cond = TRUE;
   1599         pthread_mutex_unlock(&m_lock);
   1600         LOGH("Still need to allocate %d buffers",
   1601                mNumBufsNeedAlloc);
   1602         // start another thread to allocate the rest of buffers
   1603         pthread_create(&mBufAllocPid,
   1604                        NULL,
   1605                        BufAllocRoutine,
   1606                        this);
   1607         pthread_setname_np(mBufAllocPid, "CAM_strmBufAlloc");
   1608     }
   1609     return rc;
   1610 }
   1611 
   1612 /*===========================================================================
   1613  * FUNCTION   : mapBuffers
   1614  *
   1615  * DESCRIPTION: map stream buffers
   1616  *
   1617  * PARAMETERS :
   1618  *
   1619  * RETURN     : int32_t type of status
   1620  *              NO_ERROR  -- success
   1621  *              none-zero failure code
   1622  *==========================================================================*/
   1623 int32_t QCameraStream::mapBuffers()
   1624 {
   1625     int32_t rc = NO_ERROR;
   1626     QCameraBufferMaps bufferMaps;
   1627 
   1628     rc = mAllocator.waitForBackgroundTask(mAllocTaskId);
   1629     if (rc != NO_ERROR) {
   1630         LOGE("Allocation Failed");
   1631         return NO_MEMORY;
   1632     }
   1633 
   1634     if (mStreamBufs == NULL) {
   1635         LOGE("Stream buffers not allocated");
   1636         return UNKNOWN_ERROR;
   1637     }
   1638 
   1639     uint8_t numBufsToMap = mStreamBufs->getMappable();
   1640     for (uint32_t i = 0; i < numBufsToMap; i++) {
   1641         ssize_t bufSize = mStreamBufs->getSize(i);
   1642         if (BAD_INDEX != bufSize) {
   1643             rc = bufferMaps.enqueue(CAM_MAPPING_BUF_TYPE_STREAM_BUF, mHandle,
   1644                     i /*buf index*/, -1 /*plane index*/, 0 /*cookie*/,
   1645                     mStreamBufs->getFd(i), bufSize,
   1646                     mStreamBufs->getPtr(i));
   1647 
   1648             if (rc < 0) {
   1649                 LOGE("Failed to map buffers");
   1650                 rc = BAD_INDEX;
   1651                 break;
   1652             }
   1653         } else {
   1654             LOGE("Bad index %u", i);
   1655             rc = BAD_INDEX;
   1656             break;
   1657         }
   1658     }
   1659 
   1660     cam_buf_map_type_list bufMapList;
   1661     if (rc == NO_ERROR) {
   1662         rc = bufferMaps.getCamBufMapList(bufMapList);
   1663     }
   1664     if (rc == NO_ERROR) {
   1665         rc = mapBufs(bufMapList, NULL);
   1666     }
   1667     return rc;
   1668 }
   1669 
   1670 /*===========================================================================
   1671  * FUNCTION   : allocateBatchBufs
   1672  *
   1673  * DESCRIPTION: allocate stream batch buffers and stream buffers
   1674  *
   1675  * PARAMETERS :
   1676  *   @offset     : offset info of stream buffers
   1677  *   @num_bufs   : number of buffers allocated
   1678  *   @initial_reg_flag: flag to indicate if buffer needs to be registered
   1679  *                      at kernel initially
   1680  *   @bufs       : output of allocated buffers
   1681  *   @plane_bufs    : output of allocated plane buffers
   1682   *   @ops_tbl    : ptr to buf mapping/unmapping ops
   1683  *
   1684  * RETURN     : int32_t type of status
   1685  *              NO_ERROR  -- success
   1686  *              none-zero failure code
   1687  *==========================================================================*/
   1688 int32_t QCameraStream::allocateBatchBufs(cam_frame_len_offset_t *offset,
   1689         uint8_t *num_bufs, uint8_t **initial_reg_flag,
   1690         mm_camera_buf_def_t **bufs, mm_camera_map_unmap_ops_tbl_t *ops_tbl)
   1691 {
   1692     int rc = NO_ERROR;
   1693     uint8_t *regFlags;
   1694     QCameraBufferMaps bufferMaps;
   1695     QCameraBufferMaps planeBufferMaps;
   1696 
   1697     mFrameLenOffset = *offset;
   1698 
   1699     LOGH("Batch Buffer allocation stream type = %d", getMyType());
   1700 
   1701     //Allocate stream batch buffer
   1702     mStreamBatchBufs = mAllocator.allocateStreamUserBuf (mStreamInfo);
   1703     if (!mStreamBatchBufs) {
   1704         LOGE("Failed to allocate stream batch buffers");
   1705         return NO_MEMORY;
   1706     }
   1707 
   1708     uint8_t numBufsToMap = mStreamBatchBufs->getMappable();
   1709 
   1710     //map batch buffers
   1711     for (uint32_t i = 0; i < numBufsToMap; i++) {
   1712         rc = bufferMaps.enqueue(CAM_MAPPING_BUF_TYPE_STREAM_USER_BUF,
   1713                 0 /*stream id*/, i /*buf index*/, -1 /*plane index*/,
   1714                 0 /*cookie*/, mStreamBatchBufs->getFd(i),
   1715                 mNumBufs, mStreamBatchBufs->getPtr(i));
   1716 
   1717         if (rc < 0) {
   1718             LOGE("Failed to map buffers");
   1719             rc = BAD_INDEX;
   1720             break;
   1721         }
   1722     }
   1723 
   1724     cam_buf_map_type_list bufMapList;
   1725     if (rc == NO_ERROR) {
   1726         rc = bufferMaps.getCamBufMapList(bufMapList);
   1727     }
   1728     if (rc == NO_ERROR) {
   1729         rc = mapBufs(bufMapList, ops_tbl);
   1730     }
   1731     if (rc < 0) {
   1732         LOGE("Failed to map stream batch buffers");
   1733         mStreamBatchBufs->deallocate();
   1734         delete mStreamBatchBufs;
   1735         mStreamBatchBufs = NULL;
   1736         return NO_MEMORY;
   1737     }
   1738 
   1739     /*calculate stream Buffer count*/
   1740     mNumPlaneBufs =
   1741             (mNumBufs * mStreamInfo->user_buf_info.frame_buf_cnt);
   1742 
   1743     /* For some stream types, buffer allocation may have already begun
   1744      * preemptively. If this is the case, we need to wait for the
   1745      * preemptive allocation to complete before proceeding. */
   1746     mAllocator.waitForDeferredAlloc(mStreamInfo->stream_type);
   1747 
   1748     //Allocate stream buffer
   1749     mStreamBufs = mAllocator.allocateStreamBuf(mStreamInfo->stream_type,
   1750             mFrameLenOffset.frame_len,mFrameLenOffset.mp[0].stride,
   1751             mFrameLenOffset.mp[0].scanline,mNumPlaneBufs);
   1752     if (!mStreamBufs) {
   1753         LOGE("Failed to allocate stream buffers");
   1754         rc = NO_MEMORY;
   1755         goto err1;
   1756     }
   1757 
   1758     //Map plane stream buffers
   1759     for (uint32_t i = 0; i < mNumPlaneBufs; i++) {
   1760         ssize_t bufSize = mStreamBufs->getSize(i);
   1761         if (BAD_INDEX != bufSize) {
   1762             rc = planeBufferMaps.enqueue(CAM_MAPPING_BUF_TYPE_STREAM_BUF,
   1763                     0 /*stream id*/, i /*buf index*/, -1 /*plane index*/,
   1764                     0 /*cookie*/, mStreamBufs->getFd(i), bufSize,
   1765                     mStreamBufs->getPtr(i));
   1766 
   1767             if (rc < 0) {
   1768                 LOGE("Failed to map buffers");
   1769                 mStreamBufs->deallocate();
   1770                 delete mStreamBufs;
   1771                 mStreamBufs = NULL;
   1772                 rc = INVALID_OPERATION;
   1773                 goto err1;
   1774             }
   1775         } else {
   1776             LOGE("Failed to retrieve buffer size (bad index)");
   1777             mStreamBufs->deallocate();
   1778             delete mStreamBufs;
   1779             mStreamBufs = NULL;
   1780             rc = INVALID_OPERATION;
   1781             goto err1;
   1782         }
   1783     }
   1784 
   1785     cam_buf_map_type_list planeBufMapList;
   1786     rc = planeBufferMaps.getCamBufMapList(planeBufMapList);
   1787     if (rc == NO_ERROR) {
   1788         rc = mapBufs(planeBufMapList, ops_tbl);
   1789     }
   1790 
   1791     if (rc < 0) {
   1792         LOGE("map_stream_buf failed: %d", rc);
   1793         mStreamBufs->deallocate();
   1794         delete mStreamBufs;
   1795         mStreamBufs = NULL;
   1796         rc = INVALID_OPERATION;
   1797         goto err1;
   1798     }
   1799 
   1800     LOGD("BATCH Buf Count = %d, Plane Buf Cnt = %d",
   1801             mNumBufs, mNumPlaneBufs);
   1802 
   1803     //regFlags array is allocated by us, but consumed and freed by mm-camera-interface
   1804     regFlags = (uint8_t *)malloc(sizeof(uint8_t) * mNumBufs);
   1805     if (!regFlags) {
   1806         LOGE("Out of memory");
   1807         for (uint32_t i = 0; i < mNumPlaneBufs; i++) {
   1808             unmapBuf(CAM_MAPPING_BUF_TYPE_STREAM_BUF, i, -1, ops_tbl);
   1809         }
   1810         mStreamBufs->deallocate();
   1811         delete mStreamBufs;
   1812         mStreamBufs = NULL;
   1813         rc = NO_MEMORY;
   1814         goto err1;
   1815     }
   1816     memset(regFlags, 0, sizeof(uint8_t) * mNumBufs);
   1817     for (uint32_t i = 0; i < mNumBufs; i++) {
   1818         regFlags[i] = 1;
   1819     }
   1820 
   1821     mBufDefs = (mm_camera_buf_def_t *)malloc(mNumBufs * sizeof(mm_camera_buf_def_t));
   1822     if (mBufDefs == NULL) {
   1823         LOGE("getRegFlags failed %d", rc);
   1824         for (uint32_t i = 0; i < mNumPlaneBufs; i++) {
   1825             unmapBuf(CAM_MAPPING_BUF_TYPE_STREAM_BUF, i, -1, ops_tbl);
   1826         }
   1827         mStreamBufs->deallocate();
   1828         delete mStreamBufs;
   1829         mStreamBufs = NULL;
   1830         free(regFlags);
   1831         regFlags = NULL;
   1832         rc = INVALID_OPERATION;
   1833         goto err1;
   1834     }
   1835     memset(mBufDefs, 0, mNumBufs * sizeof(mm_camera_buf_def_t));
   1836 
   1837     mPlaneBufDefs = (mm_camera_buf_def_t *)
   1838             malloc(mNumPlaneBufs * (sizeof(mm_camera_buf_def_t)));
   1839     if (mPlaneBufDefs == NULL) {
   1840         LOGE("No Memory");
   1841         free(regFlags);
   1842         regFlags = NULL;
   1843         free(mBufDefs);
   1844         mBufDefs = NULL;
   1845         for (uint32_t i = 0; i < mNumPlaneBufs; i++) {
   1846             unmapBuf(CAM_MAPPING_BUF_TYPE_STREAM_BUF, i, -1, ops_tbl);
   1847         }
   1848         mStreamBufs->deallocate();
   1849         delete mStreamBufs;
   1850         mStreamBufs = NULL;
   1851         free(regFlags);
   1852         regFlags = NULL;
   1853         rc = INVALID_OPERATION;
   1854         goto err1;
   1855     }
   1856     memset(mPlaneBufDefs, 0,
   1857              mNumPlaneBufs * (sizeof(mm_camera_buf_def_t)));
   1858 
   1859     for (uint32_t i = 0; i < mStreamInfo->num_bufs; i++) {
   1860         mStreamBatchBufs->getUserBufDef(mStreamInfo->user_buf_info,
   1861                 mBufDefs[i], i, mFrameLenOffset, mPlaneBufDefs,
   1862                 mStreamBufs);
   1863     }
   1864 
   1865     *num_bufs = mNumBufs;
   1866     *initial_reg_flag = regFlags;
   1867     *bufs = mBufDefs;
   1868     LOGH("stream type: %d, numBufs: %d mNumPlaneBufs: %d",
   1869              mStreamInfo->stream_type, mNumBufs, mNumPlaneBufs);
   1870 
   1871     return NO_ERROR;
   1872 
   1873 err1:
   1874     mStreamBatchBufs->deallocate();
   1875     delete mStreamBatchBufs;
   1876     mStreamBatchBufs = NULL;
   1877     return rc;
   1878 }
   1879 
   1880 
   1881 /*===========================================================================
   1882  * FUNCTION   : releaseBuffs
   1883  *
   1884  * DESCRIPTION: method to deallocate stream buffers
   1885  *
   1886  * PARAMETERS :
   1887  *
   1888  * RETURN     : int32_t type of status
   1889  *              NO_ERROR  -- success
   1890  *              none-zero failure code
   1891  *==========================================================================*/
   1892 int32_t QCameraStream::releaseBuffs()
   1893 {
   1894     int rc = NO_ERROR;
   1895 
   1896     if (mStreamInfo->streaming_mode == CAM_STREAMING_MODE_BATCH) {
   1897         return releaseBatchBufs(NULL);
   1898     }
   1899 
   1900     if ((NULL != mBufDefs) && (mStreamBufs != NULL)) {
   1901         uint8_t numBufsToUnmap = mStreamBufs->getMappable();
   1902         for (uint32_t i = 0; i < numBufsToUnmap; i++) {
   1903             rc = unmapBuf(CAM_MAPPING_BUF_TYPE_STREAM_BUF, i, -1, NULL);
   1904             if (rc < 0) {
   1905                 LOGE("map_stream_buf failed: %d", rc);
   1906             }
   1907         }
   1908 
   1909         // mBufDefs just keep a ptr to the buffer
   1910         // mm-camera-interface own the buffer, so no need to free
   1911         mBufDefs = NULL;
   1912         memset(&mFrameLenOffset, 0, sizeof(mFrameLenOffset));
   1913     }
   1914     if (!mStreamBufsAcquired && (mStreamBufs != NULL)) {
   1915         mStreamBufs->deallocate();
   1916         delete mStreamBufs;
   1917         mStreamBufs = NULL;
   1918     }
   1919     return rc;
   1920 }
   1921 
   1922 /*===========================================================================
   1923  * FUNCTION   : releaseBatchBufs
   1924  *
   1925  * DESCRIPTION: method to deallocate stream buffers and batch buffers
   1926  *
   1927  * PARAMETERS :
   1928  *   @ops_tbl    : ptr to buf mapping/unmapping ops
   1929  *
   1930  * RETURN     : int32_t type of status
   1931  *              NO_ERROR  -- success
   1932  *              none-zero failure code
   1933 
   1934  *==========================================================================*/
   1935 int32_t QCameraStream::releaseBatchBufs(mm_camera_map_unmap_ops_tbl_t *ops_tbl)
   1936 {
   1937     int rc = NO_ERROR;
   1938 
   1939     if (NULL != mPlaneBufDefs) {
   1940         for (uint32_t i = 0; i < mNumPlaneBufs; i++) {
   1941             rc = unmapBuf(CAM_MAPPING_BUF_TYPE_STREAM_BUF, i, -1, ops_tbl);
   1942             if (rc < 0) {
   1943                 LOGE("map_stream_buf failed: %d", rc);
   1944             }
   1945         }
   1946 
   1947         // mBufDefs just keep a ptr to the buffer
   1948         // mm-camera-interface own the buffer, so no need to free
   1949         mPlaneBufDefs = NULL;
   1950         memset(&mFrameLenOffset, 0, sizeof(mFrameLenOffset));
   1951         mNumPlaneBufs = 0;
   1952     }
   1953 
   1954     if (mStreamBufs != NULL) {
   1955         mStreamBufs->deallocate();
   1956         delete mStreamBufs;
   1957     }
   1958 
   1959     mBufDefs = NULL;
   1960 
   1961     if (mStreamBatchBufs != NULL) {
   1962         for (uint8_t i = 0; i < mStreamBatchBufs->getCnt(); i++) {
   1963             unmapBuf(CAM_MAPPING_BUF_TYPE_STREAM_USER_BUF, i, -1, ops_tbl);
   1964         }
   1965         mStreamBatchBufs->deallocate();
   1966         delete mStreamBatchBufs;
   1967         mStreamBatchBufs = NULL;
   1968     }
   1969     return rc;
   1970 
   1971 }
   1972 
   1973 /*===========================================================================
   1974  * FUNCTION   : BufAllocRoutine
   1975  *
   1976  * DESCRIPTION: function to allocate additional stream buffers
   1977  *
   1978  * PARAMETERS :
   1979  *   @data    : user data ptr
   1980  *
   1981  * RETURN     : none
   1982  *==========================================================================*/
   1983 void *QCameraStream::BufAllocRoutine(void *data)
   1984 {
   1985     QCameraStream *pme = (QCameraStream *)data;
   1986     int32_t rc = NO_ERROR;
   1987 
   1988     LOGH("E");
   1989     pme->cond_wait();
   1990     if (pme->mNumBufsNeedAlloc > 0) {
   1991         uint8_t numBufAlloc = (uint8_t)(pme->mNumBufs - pme->mNumBufsNeedAlloc);
   1992         rc = pme->mAllocator.allocateMoreStreamBuf(pme->mStreamBufs,
   1993                                                    pme->mFrameLenOffset.frame_len,
   1994                                                    pme->mNumBufsNeedAlloc);
   1995         if (rc != NO_ERROR) {
   1996             LOGE("Failed to allocate buffers");
   1997             pme->mNumBufsNeedAlloc = 0;
   1998             return NULL;
   1999         }
   2000 
   2001         pme->mNumBufsNeedAlloc = 0;
   2002         QCameraBufferMaps bufferMaps;
   2003         for (uint32_t i = numBufAlloc; i < pme->mNumBufs; i++) {
   2004             ssize_t bufSize = pme->mStreamBufs->getSize(i);
   2005             if (BAD_INDEX == bufSize) {
   2006                 LOGE("Failed to retrieve buffer size (bad index)");
   2007                 return NULL;
   2008             }
   2009 
   2010             rc = bufferMaps.enqueue(CAM_MAPPING_BUF_TYPE_STREAM_BUF,
   2011                     pme->mHandle, i /*buf index*/, -1 /*plane index*/,
   2012                     0 /*cookie*/, pme->mStreamBufs->getFd(i), bufSize,
   2013                     pme->mStreamBufs->getPtr(i));
   2014 
   2015             if (rc < 0) {
   2016                 LOGE("Failed to map buffers");
   2017                 return NULL;
   2018             }
   2019         }
   2020 
   2021         cam_buf_map_type_list bufMapList;
   2022         rc = bufferMaps.getCamBufMapList(bufMapList);
   2023         if (rc == NO_ERROR) {
   2024             rc = pme->m_MemOpsTbl.bundled_map_ops(&bufMapList, pme->m_MemOpsTbl.userdata);
   2025         }
   2026         if (rc != 0) {
   2027             LOGE("Failed to map buffers with return code %d", rc);
   2028             return NULL;
   2029         }
   2030 
   2031         for (uint32_t i = numBufAlloc; i < pme->mNumBufs; i++) {
   2032             pme->mStreamBufs->getBufDef(pme->mFrameLenOffset, pme->mBufDefs[i], i);
   2033             pme->mCamOps->qbuf(pme->mCamHandle, pme->mChannelHandle,
   2034                     &pme->mBufDefs[i]);
   2035         }
   2036     }
   2037     LOGH("X");
   2038     return NULL;
   2039 }
   2040 
   2041 /*===========================================================================
   2042  * FUNCTION   : cond_signal
   2043  *
   2044  * DESCRIPTION: signal if flag "wait_for_cond" is set
   2045  *
   2046  *==========================================================================*/
   2047 void QCameraStream::cond_signal(bool forceExit)
   2048 {
   2049     pthread_mutex_lock(&m_lock);
   2050     if(wait_for_cond == TRUE){
   2051         wait_for_cond = FALSE;
   2052         if (forceExit) {
   2053             mNumBufsNeedAlloc = 0;
   2054         }
   2055         pthread_cond_signal(&m_cond);
   2056     }
   2057     pthread_mutex_unlock(&m_lock);
   2058 }
   2059 
   2060 
   2061 /*===========================================================================
   2062  * FUNCTION   : cond_wait
   2063  *
   2064  * DESCRIPTION: wait on if flag "wait_for_cond" is set
   2065  *
   2066  *==========================================================================*/
   2067 void QCameraStream::cond_wait()
   2068 {
   2069     pthread_mutex_lock(&m_lock);
   2070     while (wait_for_cond == TRUE) {
   2071         pthread_cond_wait(&m_cond, &m_lock);
   2072     }
   2073     pthread_mutex_unlock(&m_lock);
   2074 }
   2075 
   2076 /*===========================================================================
   2077  * FUNCTION   : putBufs
   2078  *
   2079  * DESCRIPTION: deallocate stream buffers
   2080  *
   2081  * PARAMETERS :
   2082  *   @ops_tbl    : ptr to buf mapping/unmapping ops
   2083  *
   2084  * RETURN     : int32_t type of status
   2085  *              NO_ERROR  -- success
   2086  *              none-zero failure code
   2087  *==========================================================================*/
   2088 int32_t QCameraStream::putBufs(mm_camera_map_unmap_ops_tbl_t *ops_tbl)
   2089 {
   2090     int rc = NO_ERROR;
   2091 
   2092     if (mBufAllocPid != 0) {
   2093         cond_signal(true);
   2094         LOGL("wait for buf allocation thread dead");
   2095         pthread_join(mBufAllocPid, NULL);
   2096         mBufAllocPid = 0;
   2097         LOGL("return from buf allocation thread");
   2098     }
   2099 
   2100     uint8_t numBufsToUnmap = mStreamBufs->getMappable();
   2101     for (uint32_t i = 0; i < numBufsToUnmap; i++) {
   2102         rc = ops_tbl->unmap_ops(i, -1, CAM_MAPPING_BUF_TYPE_STREAM_BUF, ops_tbl->userdata);
   2103         if (rc < 0) {
   2104             LOGE("map_stream_buf failed: %d", rc);
   2105         }
   2106     }
   2107     mBufDefs = NULL; // mBufDefs just keep a ptr to the buffer
   2108                      // mm-camera-interface own the buffer, so no need to free
   2109     memset(&mFrameLenOffset, 0, sizeof(mFrameLenOffset));
   2110     if ( !mStreamBufsAcquired ) {
   2111         mStreamBufs->deallocate();
   2112         delete mStreamBufs;
   2113         mStreamBufs = NULL;
   2114     }
   2115 
   2116     return rc;
   2117 }
   2118 
   2119 /*===========================================================================
   2120  * FUNCTION   : putBufsDeffered
   2121  *
   2122  * DESCRIPTION: function to deallocate deffered stream buffers
   2123  *
   2124  * PARAMETERS : none
   2125  *
   2126  * RETURN     : int32_t type of status
   2127  *              NO_ERROR  -- success
   2128  *              none-zero failure code
   2129  *==========================================================================*/
   2130 int32_t QCameraStream::putBufsDeffered()
   2131 {
   2132     if (mBufAllocPid != 0) {
   2133         cond_signal(true);
   2134         LOGH("%s: wait for buf allocation thread dead", __func__);
   2135         // Wait for the allocation of additional stream buffers
   2136         pthread_join(mBufAllocPid, NULL);
   2137         mBufAllocPid = 0;
   2138         LOGH("%s: return from buf allocation thread", __func__);
   2139     }
   2140     // Deallocation of the deffered stream buffers handled separately
   2141     return NO_ERROR;
   2142 }
   2143 
   2144 /*===========================================================================
   2145  * FUNCTION   : invalidateBuf
   2146  *
   2147  * DESCRIPTION: invalidate a specific stream buffer
   2148  *
   2149  * PARAMETERS :
   2150  *   @index   : index of the buffer to invalidate
   2151  *
   2152  * RETURN     : int32_t type of status
   2153  *              NO_ERROR  -- success
   2154  *              none-zero failure code
   2155  *==========================================================================*/
   2156 int32_t QCameraStream::invalidateBuf(uint32_t index)
   2157 {
   2158     if (mStreamBufs == NULL) {
   2159         LOGE("Invalid Operation");
   2160         return INVALID_OPERATION;
   2161     }
   2162     return mStreamBufs->invalidateCache(index);
   2163 }
   2164 
   2165 /*===========================================================================
   2166  * FUNCTION   : cleanInvalidateBuf
   2167  *
   2168  * DESCRIPTION: clean invalidate a specific stream buffer
   2169  *
   2170  * PARAMETERS :
   2171  *   @index   : index of the buffer to clean invalidate
   2172  *
   2173  * RETURN     : int32_t type of status
   2174  *              NO_ERROR  -- success
   2175  *              none-zero failure code
   2176  *==========================================================================*/
   2177 int32_t QCameraStream::cleanInvalidateBuf(uint32_t index)
   2178 {
   2179     if (mStreamBufs == NULL) {
   2180         LOGE("Invalid Operation");
   2181         return INVALID_OPERATION;
   2182     }
   2183     return mStreamBufs->cleanInvalidateCache(index);
   2184 }
   2185 
   2186 /*===========================================================================
   2187  * FUNCTION   : isTypeOf
   2188  *
   2189  * DESCRIPTION: helper function to determine if the stream is of the queried type
   2190  *
   2191  * PARAMETERS :
   2192  *   @type    : stream type as of queried
   2193  *
   2194  * RETURN     : true/false
   2195  *==========================================================================*/
   2196 bool QCameraStream::isTypeOf(cam_stream_type_t type)
   2197 {
   2198     if (mStreamInfo != NULL && (mStreamInfo->stream_type == type)) {
   2199         return true;
   2200     } else {
   2201         return false;
   2202     }
   2203 }
   2204 
   2205 /*===========================================================================
   2206  * FUNCTION   : isOrignalTypeOf
   2207  *
   2208  * DESCRIPTION: helper function to determine if the original stream is of the
   2209  *              queried type if it's reproc stream
   2210  *
   2211  * PARAMETERS :
   2212  *   @type    : stream type as of queried
   2213  *
   2214  * RETURN     : true/false
   2215  *==========================================================================*/
   2216 bool QCameraStream::isOrignalTypeOf(cam_stream_type_t type)
   2217 {
   2218     if (mStreamInfo != NULL &&
   2219         mStreamInfo->stream_type == CAM_STREAM_TYPE_OFFLINE_PROC &&
   2220         mStreamInfo->reprocess_config.pp_type == CAM_ONLINE_REPROCESS_TYPE &&
   2221         mStreamInfo->reprocess_config.online.input_stream_type == type) {
   2222         return true;
   2223     } else if (
   2224         mStreamInfo != NULL &&
   2225         mStreamInfo->stream_type == CAM_STREAM_TYPE_OFFLINE_PROC &&
   2226         mStreamInfo->reprocess_config.pp_type == CAM_OFFLINE_REPROCESS_TYPE &&
   2227         mStreamInfo->reprocess_config.offline.input_type == type) {
   2228         return true;
   2229     } else {
   2230         return false;
   2231     }
   2232 }
   2233 
   2234 /*===========================================================================
   2235  * FUNCTION   : getMyType
   2236  *
   2237  * DESCRIPTION: return stream type
   2238  *
   2239  * PARAMETERS : none
   2240  *
   2241  * RETURN     : stream type
   2242  *==========================================================================*/
   2243 cam_stream_type_t QCameraStream::getMyType()
   2244 {
   2245     if (mStreamInfo != NULL) {
   2246         return mStreamInfo->stream_type;
   2247     } else {
   2248         return CAM_STREAM_TYPE_DEFAULT;
   2249     }
   2250 }
   2251 
   2252 /*===========================================================================
   2253  * FUNCTION   : getMyOriginalType
   2254  *
   2255  * DESCRIPTION: return stream type
   2256  *
   2257  * PARAMETERS : none
   2258  *
   2259  * RETURN     : stream type
   2260  *==========================================================================*/
   2261 cam_stream_type_t QCameraStream::getMyOriginalType()
   2262 {
   2263     if (mStreamInfo != NULL) {
   2264         if (mStreamInfo->stream_type == CAM_STREAM_TYPE_OFFLINE_PROC &&
   2265                 mStreamInfo->reprocess_config.pp_type == CAM_ONLINE_REPROCESS_TYPE) {
   2266             return mStreamInfo->reprocess_config.online.input_stream_type;
   2267         } else if (mStreamInfo->stream_type == CAM_STREAM_TYPE_OFFLINE_PROC &&
   2268                 mStreamInfo->reprocess_config.pp_type == CAM_OFFLINE_REPROCESS_TYPE) {
   2269             return mStreamInfo->reprocess_config.offline.input_type;
   2270         } else {
   2271             return mStreamInfo->stream_type;
   2272         }
   2273     } else {
   2274         return CAM_STREAM_TYPE_DEFAULT;
   2275     }
   2276 }
   2277 
   2278 /*===========================================================================
   2279  * FUNCTION   : getFrameOffset
   2280  *
   2281  * DESCRIPTION: query stream buffer frame offset info
   2282  *
   2283  * PARAMETERS :
   2284  *   @offset  : reference to struct to store the queried frame offset info
   2285  *
   2286  * RETURN     : int32_t type of status
   2287  *              NO_ERROR  -- success
   2288  *              none-zero failure code
   2289  *==========================================================================*/
   2290 int32_t QCameraStream::getFrameOffset(cam_frame_len_offset_t &offset)
   2291 {
   2292     if (NULL == mStreamInfo) {
   2293         return NO_INIT;
   2294     }
   2295 
   2296     offset = mFrameLenOffset;
   2297     if ((ROTATE_90 == mOnlineRotation) || (ROTATE_270 == mOnlineRotation)
   2298             || (offset.frame_len == 0) || (offset.num_planes == 0)) {
   2299         // Re-calculate frame offset in case of online rotation
   2300         cam_stream_info_t streamInfo = *mStreamInfo;
   2301         getFrameDimension(streamInfo.dim);
   2302         calcOffset(&streamInfo);
   2303         offset = streamInfo.buf_planes.plane_info;
   2304     }
   2305 
   2306     return 0;
   2307 }
   2308 
   2309 /*===========================================================================
   2310  * FUNCTION   : getCropInfo
   2311  *
   2312  * DESCRIPTION: query crop info of the stream
   2313  *
   2314  * PARAMETERS :
   2315  *   @crop    : reference to struct to store the queried crop info
   2316  *
   2317  * RETURN     : int32_t type of status
   2318  *              NO_ERROR  -- success
   2319  *              none-zero failure code
   2320  *==========================================================================*/
   2321 int32_t QCameraStream::getCropInfo(cam_rect_t &crop)
   2322 {
   2323     pthread_mutex_lock(&mCropLock);
   2324     crop = mCropInfo;
   2325     pthread_mutex_unlock(&mCropLock);
   2326     return NO_ERROR;
   2327 }
   2328 
   2329 /*===========================================================================
   2330  * FUNCTION   : setCropInfo
   2331  *
   2332  * DESCRIPTION: set crop info of the stream
   2333  *
   2334  * PARAMETERS :
   2335  *   @crop    : struct to store new crop info
   2336  *
   2337  * RETURN     : int32_t type of status
   2338  *              NO_ERROR  -- success
   2339  *              none-zero failure code
   2340  *==========================================================================*/
   2341 int32_t QCameraStream::setCropInfo(cam_rect_t crop)
   2342 {
   2343     pthread_mutex_lock(&mCropLock);
   2344     mCropInfo = crop;
   2345     pthread_mutex_unlock(&mCropLock);
   2346     return NO_ERROR;
   2347 }
   2348 
   2349 /*===========================================================================
   2350  * FUNCTION   : getFrameDimension
   2351  *
   2352  * DESCRIPTION: query stream frame dimension info
   2353  *
   2354  * PARAMETERS :
   2355  *   @dim     : reference to struct to store the queried frame dimension
   2356  *
   2357  * RETURN     : int32_t type of status
   2358  *              NO_ERROR  -- success
   2359  *              none-zero failure code
   2360  *==========================================================================*/
   2361 int32_t QCameraStream::getFrameDimension(cam_dimension_t &dim)
   2362 {
   2363     if (mStreamInfo != NULL) {
   2364         if ((ROTATE_90 == mOnlineRotation) || (ROTATE_270 == mOnlineRotation)) {
   2365             dim.width = mStreamInfo->dim.height;
   2366             dim.height = mStreamInfo->dim.width;
   2367         } else {
   2368             dim = mStreamInfo->dim;
   2369         }
   2370         return 0;
   2371     }
   2372     return -1;
   2373 }
   2374 
   2375 /*===========================================================================
   2376  * FUNCTION   : getFormat
   2377  *
   2378  * DESCRIPTION: query stream format
   2379  *
   2380  * PARAMETERS :
   2381  *   @fmt     : reference to stream format
   2382  *
   2383  * RETURN     : int32_t type of status
   2384  *              NO_ERROR  -- success
   2385  *              none-zero failure code
   2386  *==========================================================================*/
   2387 int32_t QCameraStream::getFormat(cam_format_t &fmt)
   2388 {
   2389     if (mStreamInfo != NULL) {
   2390         fmt = mStreamInfo->fmt;
   2391         return 0;
   2392     }
   2393     return -1;
   2394 }
   2395 
   2396 /*===========================================================================
   2397  * FUNCTION   : getMyServerID
   2398  *
   2399  * DESCRIPTION: query server stream ID
   2400  *
   2401  * PARAMETERS : None
   2402  *
   2403  * RETURN     : stream ID from server
   2404  *==========================================================================*/
   2405 uint32_t QCameraStream::getMyServerID() {
   2406     if (mStreamInfo != NULL) {
   2407         return mStreamInfo->stream_svr_id;
   2408     } else {
   2409         return 0;
   2410     }
   2411 }
   2412 
   2413 /*===========================================================================
   2414  * FUNCTION   : acquireStreamBufs
   2415  *
   2416  * DESCRIPTION: acquire stream buffers and postpone their release.
   2417  *
   2418  * PARAMETERS : None
   2419  *
   2420  * RETURN     : int32_t type of status
   2421  *              NO_ERROR  -- success
   2422  *              none-zero failure code
   2423  *==========================================================================*/
   2424 int32_t QCameraStream::acquireStreamBufs()
   2425 {
   2426     mStreamBufsAcquired = true;
   2427 
   2428     return NO_ERROR;
   2429 }
   2430 
   2431 /*===========================================================================
   2432  * FUNCTION   : mapBuf
   2433  *
   2434  * DESCRIPTION: map stream related buffer to backend server
   2435  *
   2436  * PARAMETERS :
   2437  *   @buf_type : mapping type of buffer
   2438  *   @buf_idx  : index of buffer
   2439  *   @plane_idx: plane index
   2440  *   @fd       : fd of the buffer
   2441  *   @buffer   : buffer address
   2442  *   @size     : lenght of the buffer
   2443  *   @ops_tbl  : ptr to buf mapping/unmapping ops
   2444  *
   2445  * RETURN     : int32_t type of status
   2446  *              NO_ERROR  -- success
   2447  *              none-zero failure code
   2448  *==========================================================================*/
   2449 int32_t QCameraStream::mapBuf(uint8_t buf_type, uint32_t buf_idx,
   2450         int32_t plane_idx, int fd, void *buffer, size_t size,
   2451         mm_camera_map_unmap_ops_tbl_t *ops_tbl)
   2452 {
   2453     cam_buf_map_type_list bufMapList;
   2454     int32_t rc = QCameraBufferMaps::makeSingletonBufMapList(
   2455            (cam_mapping_buf_type)buf_type, mHandle, buf_idx, plane_idx,
   2456            0 /*cookie*/, fd, size, bufMapList, buffer);
   2457 
   2458     if (rc != NO_ERROR) {
   2459         return rc;
   2460     }
   2461 
   2462     return mapBufs(bufMapList, ops_tbl);
   2463 }
   2464 
   2465 /*===========================================================================
   2466  * FUNCTION   : mapBufs
   2467  *
   2468  * DESCRIPTION: map stream related buffers to backend server
   2469  *
   2470  * PARAMETERS :
   2471  *   @bufMapList : buffer mapping information
   2472  *   @ops_tbl    : ptr to buf mapping/unmapping ops
   2473  *
   2474  * RETURN     : int32_t type of status
   2475  *              NO_ERROR  -- success
   2476  *              none-zero failure code
   2477  *==========================================================================*/
   2478 
   2479 int32_t QCameraStream::mapBufs(cam_buf_map_type_list bufMapList,
   2480         __unused mm_camera_map_unmap_ops_tbl_t *ops_tbl)
   2481 {
   2482     if (m_MemOpsTbl.bundled_map_ops != NULL) {
   2483         return m_MemOpsTbl.bundled_map_ops(&bufMapList, m_MemOpsTbl.userdata);
   2484     } else {
   2485         return mCamOps->map_stream_bufs(mCamHandle, mChannelHandle,
   2486                 &bufMapList);
   2487     }
   2488 
   2489 }
   2490 
   2491 /*===========================================================================
   2492  * FUNCTION   : unmapBuf
   2493  *
   2494  * DESCRIPTION: unmap stream related buffer to backend server
   2495  *
   2496  * PARAMETERS :
   2497  *   @buf_type : mapping type of buffer
   2498  *   @buf_idx  : index of buffer
   2499  *   @plane_idx: plane index
   2500  *   @ops_tbl    : ptr to buf mapping/unmapping ops
   2501  *
   2502  * RETURN     : int32_t type of status
   2503  *              NO_ERROR  -- success
   2504  *              none-zero failure code
   2505  *==========================================================================*/
   2506 int32_t QCameraStream::unmapBuf(uint8_t buf_type, uint32_t buf_idx, int32_t plane_idx,
   2507         mm_camera_map_unmap_ops_tbl_t *ops_tbl)
   2508 {
   2509     if (ops_tbl != NULL) {
   2510         return ops_tbl->unmap_ops(buf_idx, plane_idx,
   2511                 (cam_mapping_buf_type)buf_type, ops_tbl->userdata);
   2512     } else {
   2513         return mCamOps->unmap_stream_buf(mCamHandle, mChannelHandle,
   2514                 mHandle, buf_type, buf_idx, plane_idx);
   2515     }
   2516 }
   2517 
   2518 /*===========================================================================
   2519  * FUNCTION   : setParameter
   2520  *
   2521  * DESCRIPTION: set stream based parameters
   2522  *
   2523  * PARAMETERS :
   2524  *   @param   : ptr to parameters to be set
   2525  *
   2526  * RETURN     : int32_t type of status
   2527  *              NO_ERROR  -- success
   2528  *              none-zero failure code
   2529  *==========================================================================*/
   2530 int32_t QCameraStream::setParameter(cam_stream_parm_buffer_t &param)
   2531 {
   2532     int32_t rc = NO_ERROR;
   2533     pthread_mutex_lock(&mParameterLock);
   2534     mStreamInfo->parm_buf = param;
   2535     rc = mCamOps->set_stream_parms(mCamHandle,
   2536                                    mChannelHandle,
   2537                                    mHandle,
   2538                                    &mStreamInfo->parm_buf);
   2539     if (rc == NO_ERROR) {
   2540         param = mStreamInfo->parm_buf;
   2541     }
   2542     pthread_mutex_unlock(&mParameterLock);
   2543     return rc;
   2544 }
   2545 
   2546 /*===========================================================================
   2547  * FUNCTION   : getParameter
   2548  *
   2549  * DESCRIPTION: get stream based parameters
   2550  *
   2551  * PARAMETERS :
   2552  *   @param   : ptr to parameters to be red
   2553  *
   2554  * RETURN     : int32_t type of status
   2555  *              NO_ERROR  -- success
   2556  *              none-zero failure code
   2557  *==========================================================================*/
   2558 int32_t QCameraStream::getParameter(cam_stream_parm_buffer_t &param)
   2559 {
   2560     int32_t rc = NO_ERROR;
   2561     pthread_mutex_lock(&mParameterLock);
   2562     mStreamInfo->parm_buf = param;
   2563     rc = mCamOps->get_stream_parms(mCamHandle,
   2564                                    mChannelHandle,
   2565                                    mHandle,
   2566                                    &mStreamInfo->parm_buf);
   2567     if (rc == NO_ERROR) {
   2568         param = mStreamInfo->parm_buf;
   2569     }
   2570     pthread_mutex_unlock(&mParameterLock);
   2571     return rc;
   2572 }
   2573 
   2574 /*===========================================================================
   2575  * FUNCTION   : releaseFrameData
   2576  *
   2577  * DESCRIPTION: callback function to release frame data node
   2578  *
   2579  * PARAMETERS :
   2580  *   @data      : ptr to post process input data
   2581  *   @user_data : user data ptr (QCameraReprocessor)
   2582  *
   2583  * RETURN     : None
   2584  *==========================================================================*/
   2585 void QCameraStream::releaseFrameData(void *data, void *user_data)
   2586 {
   2587     QCameraStream *pme = (QCameraStream *)user_data;
   2588     mm_camera_super_buf_t *frame = (mm_camera_super_buf_t *)data;
   2589     if (NULL != pme) {
   2590         pme->bufDone(frame->bufs[0]->buf_idx);
   2591     }
   2592 }
   2593 
   2594 /*===========================================================================
   2595  * FUNCTION   : configStream
   2596  *
   2597  * DESCRIPTION: send stream configuration to back end
   2598  *
   2599  * PARAMETERS :
   2600  *
   2601  * RETURN     : int32_t type of status
   2602  *              NO_ERROR  -- success
   2603  *              none-zero failure code
   2604  *==========================================================================*/
   2605 int32_t QCameraStream::configStream()
   2606 {
   2607     int rc = NO_ERROR;
   2608 
   2609     // Configure the stream
   2610     mm_camera_stream_config_t stream_config;
   2611     stream_config.stream_info = mStreamInfo;
   2612     stream_config.mem_vtbl = mMemVtbl;
   2613     stream_config.stream_cb_sync = NULL;
   2614     stream_config.stream_cb = dataNotifyCB;
   2615     stream_config.padding_info = mPaddingInfo;
   2616     stream_config.userdata = this;
   2617     rc = mCamOps->config_stream(mCamHandle,
   2618                 mChannelHandle, mHandle, &stream_config);
   2619     if (rc < 0) {
   2620         LOGE("Failed to config stream, rc = %d", rc);
   2621         mCamOps->unmap_stream_buf(mCamHandle,
   2622                 mChannelHandle,
   2623                 mHandle,
   2624                 CAM_MAPPING_BUF_TYPE_STREAM_INFO,
   2625                 0,
   2626                 -1);
   2627         return UNKNOWN_ERROR;
   2628     }
   2629 
   2630     return rc;
   2631 }
   2632 
   2633 /*===========================================================================
   2634  * FUNCTION   : setSyncDataCB
   2635  *
   2636  * DESCRIPTION: register callback with mm-interface for this stream
   2637  *
   2638  * PARAMETERS :
   2639        @stream_cb   : Callback function
   2640  *
   2641  * RETURN     : int32_t type of status
   2642  *              NO_ERROR  -- success
   2643  *              non-zero failure code
   2644  *==========================================================================*/
   2645 int32_t QCameraStream::setSyncDataCB(stream_cb_routine data_cb)
   2646 {
   2647     int32_t rc = NO_ERROR;
   2648 
   2649     if (mCamOps != NULL) {
   2650         mSYNCDataCB = data_cb;
   2651         rc = mCamOps->register_stream_buf_cb(mCamHandle,
   2652                 mChannelHandle, mHandle, dataNotifySYNCCB, MM_CAMERA_STREAM_CB_TYPE_SYNC,
   2653                 this);
   2654         if (rc == NO_ERROR) {
   2655             mSyncCBEnabled = TRUE;
   2656             return rc;
   2657         }
   2658     }
   2659     LOGE("Interface handle is NULL");
   2660     return UNKNOWN_ERROR;
   2661 }
   2662 
   2663 }; // namespace qcamera
   2664