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