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