Home | History | Annotate | Download | only in HAL
      1 /* Copyright (c) 2012-2015, The Linux Foundataion. All rights reserved.
      2 *
      3 * Redistribution and use in source and binary forms, with or without
      4 * modification, are permitted provided that the following conditions are
      5 * met:
      6 *     * Redistributions of source code must retain the above copyright
      7 *       notice, this list of conditions and the following disclaimer.
      8 *     * Redistributions in binary form must reproduce the above
      9 *       copyright notice, this list of conditions and the following
     10 *       disclaimer in the documentation and/or other materials provided
     11 *       with the distribution.
     12 *     * Neither the name of The Linux Foundation nor the names of its
     13 *       contributors may be used to endorse or promote products derived
     14 *       from this software without specific prior written permission.
     15 *
     16 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
     17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
     18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
     19 * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
     20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
     23 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
     24 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
     25 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
     26 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     27 *
     28 */
     29 
     30 #define LOG_TAG "QCameraStream"
     31 
     32 #include <utils/Errors.h>
     33 #include <QComOMXMetadata.h>
     34 #include "QCamera2HWI.h"
     35 #include "QCameraStream.h"
     36 
     37 #define CAMERA_MIN_ALLOCATED_BUFFERS     3
     38 
     39 namespace qcamera {
     40 
     41 /*===========================================================================
     42  * FUNCTION   : get_bufs
     43  *
     44  * DESCRIPTION: static function entry to allocate stream buffers
     45  *
     46  * PARAMETERS :
     47  *   @offset     : offset info of stream buffers
     48  *   @num_bufs   : number of buffers allocated
     49  *   @initial_reg_flag: flag to indicate if buffer needs to be registered
     50  *                      at kernel initially
     51  *   @bufs       : output of allocated buffers
     52  *   @ops_tbl    : ptr to buf mapping/unmapping ops
     53  *   @user_data  : user data ptr of ops_tbl
     54  *
     55  * RETURN     : int32_t type of status
     56  *              NO_ERROR  -- success
     57  *              none-zero failure code
     58  *==========================================================================*/
     59 int32_t QCameraStream::get_bufs(
     60                      cam_frame_len_offset_t *offset,
     61                      uint8_t *num_bufs,
     62                      uint8_t **initial_reg_flag,
     63                      mm_camera_buf_def_t **bufs,
     64                      mm_camera_map_unmap_ops_tbl_t *ops_tbl,
     65                      void *user_data)
     66 {
     67     QCameraStream *stream = reinterpret_cast<QCameraStream *>(user_data);
     68     if (!stream) {
     69         ALOGE("getBufs invalid stream pointer");
     70         return NO_MEMORY;
     71     }
     72 
     73     if (stream->mStreamInfo != NULL
     74             && stream->mStreamInfo->streaming_mode == CAM_STREAMING_MODE_BATCH) {
     75         //Batch Mode. Allocate Butch buffers
     76         return stream->allocateBatchBufs(offset, num_bufs,
     77                 initial_reg_flag, bufs, ops_tbl);
     78     } else {
     79         // Plane Buffer. Allocate plane buffer
     80         return stream->getBufs(offset, num_bufs,
     81                 initial_reg_flag, bufs, ops_tbl);
     82     }
     83 }
     84 
     85 /*===========================================================================
     86  * FUNCTION   : get_bufs_deffered
     87  *
     88  * DESCRIPTION: static function entry to allocate deffered stream buffers
     89  *
     90  * PARAMETERS :
     91  *   @offset     : offset info of stream buffers
     92  *   @num_bufs   : number of buffers allocated
     93  *   @initial_reg_flag: flag to indicate if buffer needs to be registered
     94  *                      at kernel initially
     95  *   @bufs       : output of allocated buffers
     96  *   @ops_tbl    : ptr to buf mapping/unmapping ops
     97  *   @user_data  : user data ptr of ops_tbl
     98  *
     99  * RETURN     : int32_t type of status
    100  *              NO_ERROR  -- success
    101  *              none-zero failure code
    102  *==========================================================================*/
    103 int32_t QCameraStream::get_bufs_deffered(
    104         cam_frame_len_offset_t * /* offset */,
    105         uint8_t *num_bufs,
    106         uint8_t **initial_reg_flag,
    107         mm_camera_buf_def_t **bufs,
    108         mm_camera_map_unmap_ops_tbl_t * /* ops_tbl */,
    109         void *user_data)
    110 {
    111     QCameraStream *stream = reinterpret_cast<QCameraStream *>(user_data);
    112     if (!stream) {
    113         ALOGE("getBufs invalid stream pointer");
    114         return NO_MEMORY;
    115     }
    116 
    117     *initial_reg_flag   = stream->mRegFlags;
    118     *num_bufs           = stream->mNumBufs;
    119     *bufs               = stream->mBufDefs;
    120     CDBG_HIGH("%s: stream type: %d, mRegFlags: 0x%x, numBufs: %d",
    121             __func__, stream->getMyType(), stream->mRegFlags, stream->mNumBufs);
    122     return NO_ERROR;
    123 }
    124 
    125 /*===========================================================================
    126  * FUNCTION   : put_bufs
    127  *
    128  * DESCRIPTION: static function entry to deallocate stream buffers
    129  *
    130  * PARAMETERS :
    131  *   @ops_tbl    : ptr to buf mapping/unmapping ops
    132  *   @user_data  : user data ptr of ops_tbl
    133  *
    134  * RETURN     : int32_t type of status
    135  *              NO_ERROR  -- success
    136  *              none-zero failure code
    137  *==========================================================================*/
    138 int32_t QCameraStream::put_bufs(
    139         mm_camera_map_unmap_ops_tbl_t *ops_tbl,
    140         void *user_data)
    141 {
    142     QCameraStream *stream = reinterpret_cast<QCameraStream *>(user_data);
    143     if (!stream) {
    144         ALOGE("putBufs invalid stream pointer");
    145         return NO_MEMORY;
    146     }
    147 
    148     if (stream->mStreamInfo != NULL
    149             && stream->mStreamInfo->streaming_mode == CAM_STREAMING_MODE_BATCH) {
    150         //Batch Mode. release  Butch buffers
    151         return stream->releaseBatchBufs(ops_tbl);
    152     } else {
    153         // Plane Buffer. release  plane buffer
    154         return stream->putBufs(ops_tbl);
    155     }
    156 
    157 }
    158 
    159 /*===========================================================================
    160  * FUNCTION   : put_bufs_deffered
    161  *
    162  * DESCRIPTION: static function entry to deallocate deffered stream buffers
    163  *
    164  * PARAMETERS :
    165  *   @ops_tbl    : ptr to buf mapping/unmapping ops
    166  *   @user_data  : user data ptr of ops_tbl
    167  *
    168  * RETURN     : int32_t type of status
    169  *              NO_ERROR  -- success
    170  *              none-zero failure code
    171  *==========================================================================*/
    172 int32_t QCameraStream::put_bufs_deffered(
    173         mm_camera_map_unmap_ops_tbl_t * /*ops_tbl */,
    174         void * /*user_data*/ )
    175 {
    176     // No op
    177     // Used for handling buffers with deffered allocation. They are freed separately.
    178     return NO_ERROR;
    179 }
    180 
    181 /*===========================================================================
    182  * FUNCTION   : invalidate_buf
    183  *
    184  * DESCRIPTION: static function entry to invalidate a specific stream buffer
    185  *
    186  * PARAMETERS :
    187  *   @index      : index of the stream buffer to invalidate
    188  *   @user_data  : user data ptr of ops_tbl
    189  *
    190  * RETURN     : int32_t type of status
    191  *              NO_ERROR  -- success
    192  *              none-zero failure code
    193  *==========================================================================*/
    194 int32_t QCameraStream::invalidate_buf(uint32_t index, void *user_data)
    195 {
    196     QCameraStream *stream = reinterpret_cast<QCameraStream *>(user_data);
    197     if (!stream) {
    198         ALOGE("invalid stream pointer");
    199         return NO_MEMORY;
    200     }
    201 
    202     if (stream->mStreamInfo->is_secure == SECURE){
    203         return 0;
    204     }
    205 
    206     if (stream->mStreamInfo->streaming_mode == CAM_STREAMING_MODE_BATCH) {
    207         for (int i = 0; i < stream->mBufDefs[index].user_buf.bufs_used; i++) {
    208             uint32_t buf_idx = stream->mBufDefs[index].user_buf.buf_idx[i];
    209             stream->invalidateBuf(buf_idx);
    210         }
    211     } else {
    212         return stream->invalidateBuf(index);
    213     }
    214 
    215     return 0;
    216 }
    217 
    218 /*===========================================================================
    219  * FUNCTION   : clean_invalidate_buf
    220  *
    221  * DESCRIPTION: static function entry to clean invalidate a specific stream buffer
    222  *
    223  * PARAMETERS :
    224  *   @index      : index of the stream buffer to clean invalidate
    225  *   @user_data  : user data ptr of ops_tbl
    226  *
    227  * RETURN     : int32_t type of status
    228  *              NO_ERROR  -- success
    229  *              none-zero failure code
    230  *==========================================================================*/
    231 int32_t QCameraStream::clean_invalidate_buf(uint32_t index, void *user_data)
    232 {
    233     QCameraStream *stream = reinterpret_cast<QCameraStream *>(user_data);
    234     if (!stream) {
    235         ALOGE("invalid stream pointer");
    236         return NO_MEMORY;
    237     }
    238 
    239     if (stream->mStreamInfo->is_secure == SECURE){
    240         return 0;
    241     }
    242 
    243     if (stream->mStreamInfo->streaming_mode == CAM_STREAMING_MODE_BATCH) {
    244         for (int i = 0; i < stream->mBufDefs[index].user_buf.bufs_used; i++) {
    245             uint32_t buf_idx = stream->mBufDefs[index].user_buf.buf_idx[i];
    246             stream->cleanInvalidateBuf(buf_idx);
    247         }
    248     } else {
    249         return stream->cleanInvalidateBuf(index);
    250     }
    251 
    252     return 0;
    253 }
    254 
    255 /*===========================================================================
    256  * FUNCTION   : QCameraStream
    257  *
    258  * DESCRIPTION: constructor of QCameraStream
    259  *
    260  * PARAMETERS :
    261  *   @allocator  : memory allocator obj
    262  *   @camHandle  : camera handle
    263  *   @chId       : channel handle
    264  *   @camOps     : ptr to camera ops table
    265  *   @paddingInfo: ptr to padding info
    266  *   @deffered   : deferred stream
    267  *   @online_rotation: rotation applied online
    268  *
    269  * RETURN     : None
    270  *==========================================================================*/
    271 QCameraStream::QCameraStream(QCameraAllocator &allocator,
    272         uint32_t camHandle, uint32_t chId,
    273         mm_camera_ops_t *camOps, cam_padding_info_t *paddingInfo,
    274         bool deffered, cam_rotation_t online_rotation):
    275         mDumpFrame(0),
    276         mDumpMetaFrame(0),
    277         mDumpSkipCnt(0),
    278         mCamHandle(camHandle),
    279         mChannelHandle(chId),
    280         mHandle(0),
    281         mCamOps(camOps),
    282         mStreamInfo(NULL),
    283         mNumBufs(0),
    284         mNumPlaneBufs(0),
    285         mNumBufsNeedAlloc(0),
    286         mDataCB(NULL),
    287         mUserData(NULL),
    288         mDataQ(releaseFrameData, this),
    289         mStreamInfoBuf(NULL),
    290         mMiscBuf(NULL),
    291         mStreamBufs(NULL),
    292         mStreamBatchBufs(NULL),
    293         mAllocator(allocator),
    294         mBufDefs(NULL),
    295         mPlaneBufDefs(NULL),
    296         mOnlineRotation(online_rotation),
    297         mStreamBufsAcquired(false),
    298         m_bActive(false),
    299         mDynBufAlloc(false),
    300         mBufAllocPid(0),
    301         mDefferedAllocation(deffered),
    302         wait_for_cond(false)
    303 {
    304     mMemVtbl.user_data = this;
    305     if ( !deffered ) {
    306         mMemVtbl.get_bufs = get_bufs;
    307         mMemVtbl.put_bufs = put_bufs;
    308     } else {
    309         mMemVtbl.get_bufs = get_bufs_deffered;
    310         mMemVtbl.put_bufs = put_bufs_deffered;
    311     }
    312     mMemVtbl.invalidate_buf = invalidate_buf;
    313     mMemVtbl.clean_invalidate_buf = clean_invalidate_buf;
    314     memset(&mFrameLenOffset, 0, sizeof(mFrameLenOffset));
    315     memcpy(&mPaddingInfo, paddingInfo, sizeof(cam_padding_info_t));
    316     memset(&mCropInfo, 0, sizeof(cam_rect_t));
    317     memset(&m_MemOpsTbl, 0, sizeof(mm_camera_map_unmap_ops_tbl_t));
    318     memset(&m_OutputCrop, 0, sizeof(cam_stream_parm_buffer_t));
    319     memset(&m_ImgProp, 0, sizeof(cam_stream_parm_buffer_t));
    320     pthread_mutex_init(&mCropLock, NULL);
    321     pthread_mutex_init(&mParameterLock, NULL);
    322 }
    323 
    324 /*===========================================================================
    325  * FUNCTION   : ~QCameraStream
    326  *
    327  * DESCRIPTION: deconstructor of QCameraStream
    328  *
    329  * PARAMETERS : None
    330  *
    331  * RETURN     : None
    332  *==========================================================================*/
    333 QCameraStream::~QCameraStream()
    334 {
    335     pthread_mutex_destroy(&mCropLock);
    336     pthread_mutex_destroy(&mParameterLock);
    337 
    338     if (mDefferedAllocation) {
    339         mStreamBufsAcquired = false;
    340         releaseBuffs();
    341     }
    342 
    343     unmapStreamInfoBuf();
    344     releaseStreamInfoBuf();
    345 
    346     if (mMiscBuf) {
    347         unMapBuf(mMiscBuf, CAM_MAPPING_BUF_TYPE_MISC_BUF, NULL);
    348         releaseMiscBuf();
    349     }
    350 
    351     // delete stream
    352     if (mHandle > 0) {
    353         mCamOps->delete_stream(mCamHandle, mChannelHandle, mHandle);
    354         mHandle = 0;
    355     }
    356 }
    357 
    358 /*===========================================================================
    359  * FUNCTION   : unmapStreamInfoBuf
    360  *
    361  * DESCRIPTION: Unmap stream info buffer
    362  *
    363  * PARAMETERS :
    364  *
    365  * RETURN     : int32_t type of status
    366  *              NO_ERROR  -- success
    367  *              none-zero failure code
    368  *==========================================================================*/
    369 int32_t QCameraStream::unmapStreamInfoBuf()
    370 {
    371     int rc = NO_ERROR;
    372 
    373     if (mStreamInfoBuf != NULL) {
    374         rc = mCamOps->unmap_stream_buf(mCamHandle,
    375             mChannelHandle,
    376             mHandle,
    377             CAM_MAPPING_BUF_TYPE_STREAM_INFO,
    378             0,
    379             -1);
    380 
    381         if (rc < 0) {
    382             ALOGE("Failed to unmap stream info buffer");
    383         }
    384     }
    385 
    386     return rc;
    387 }
    388 
    389 /*===========================================================================
    390  * FUNCTION   : releaseMiscBuf
    391  *
    392  * DESCRIPTION: Release misc buffers
    393  *
    394  * PARAMETERS :
    395  *
    396  * RETURN     : int32_t type of status
    397  *              NO_ERROR  -- success
    398  *              none-zero failure code
    399  *==========================================================================*/
    400 int32_t QCameraStream::releaseMiscBuf()
    401 {
    402     int rc = NO_ERROR;
    403 
    404     if (mMiscBuf != NULL) {
    405         mMiscBuf->deallocate();
    406         delete mMiscBuf;
    407         mMiscBuf = NULL;
    408     }
    409 
    410     return rc;
    411 }
    412 
    413 /*===========================================================================
    414  * FUNCTION   : releaseStreamInfoBuf
    415  *
    416  * DESCRIPTION: Release stream info buffer
    417  *
    418  * PARAMETERS :
    419  *
    420  * RETURN     : int32_t type of status
    421  *              NO_ERROR  -- success
    422  *              none-zero failure code
    423  *==========================================================================*/
    424 int32_t QCameraStream::releaseStreamInfoBuf()
    425 {
    426     int rc = NO_ERROR;
    427 
    428     if (mStreamInfoBuf != NULL) {
    429         mStreamInfoBuf->deallocate();
    430         delete mStreamInfoBuf;
    431         mStreamInfoBuf = NULL;
    432     }
    433 
    434     return rc;
    435 }
    436 
    437 /*===========================================================================
    438  * FUNCTION   : deleteStream
    439  *
    440  * DESCRIPTION: Deletes a camera stream
    441  *
    442  * PARAMETERS : None
    443  *
    444  * RETURN     : None
    445  *==========================================================================*/
    446 void QCameraStream::deleteStream()
    447 {
    448     if (mHandle > 0) {
    449         acquireStreamBufs();
    450         releaseBuffs();
    451         unmapStreamInfoBuf();
    452         mCamOps->delete_stream(mCamHandle, mChannelHandle, mHandle);
    453     }
    454 }
    455 
    456 /*===========================================================================
    457  * FUNCTION   : unMapBuf
    458  *
    459  * DESCRIPTION: unmaps buffers
    460  *
    461  * PARAMETERS :
    462  *   @heapBuf      : heap buffer handler
    463  *   @bufType      : buffer type
    464  *   @ops_tbl    : ptr to buf mapping/unmapping ops
    465  *
    466  * RETURN     : int32_t type of status
    467  *              NO_ERROR  -- success
    468  *              none-zero failure code
    469  *==========================================================================*/
    470 int32_t QCameraStream::unMapBuf(QCameraMemory *Buf,
    471         cam_mapping_buf_type bufType, mm_camera_map_unmap_ops_tbl_t *ops_tbl)
    472 {
    473     int32_t rc = NO_ERROR;
    474     uint8_t cnt;
    475     ssize_t bufSize = BAD_INDEX;
    476     uint32_t i;
    477 
    478     cnt = Buf->getCnt();
    479     for (i = 0; i < cnt; i++) {
    480         bufSize = Buf->getSize(i);
    481         if (BAD_INDEX != bufSize) {
    482             if (ops_tbl == NULL ) {
    483                 rc = mCamOps->unmap_stream_buf(mCamHandle, mChannelHandle, mHandle,
    484                         bufType, i, -1);
    485             } else {
    486                 rc = ops_tbl->unmap_ops(i, -1, bufType, ops_tbl->userdata);
    487             }
    488             if (rc < 0) {
    489                 ALOGE("Failed to unmap buffer");
    490                 break;
    491             }
    492         } else {
    493             ALOGE("Failed to retrieve buffer size (bad index)");
    494             rc = BAD_INDEX;
    495             break;
    496         }
    497     }
    498 
    499     return rc;
    500 }
    501 
    502 /*===========================================================================
    503  * FUNCTION   : mapBuf
    504  *
    505  * DESCRIPTION: maps buffers
    506  *
    507  * PARAMETERS :
    508  *   @heapBuf      : heap buffer handler
    509  *   @bufType      : buffer type
    510  *   @ops_tbl    : ptr to buf mapping/unmapping ops
    511  *
    512  * RETURN     : int32_t type of status
    513  *              NO_ERROR  -- success
    514  *              none-zero failure code
    515  *==========================================================================*/
    516 int32_t QCameraStream::mapBuf(QCameraMemory *Buf,
    517         cam_mapping_buf_type bufType, mm_camera_map_unmap_ops_tbl_t *ops_tbl)
    518 {
    519     int32_t rc = NO_ERROR;
    520     uint8_t cnt;
    521     ssize_t bufSize = BAD_INDEX;
    522     int32_t i = 0;
    523 
    524     cnt = Buf->getCnt();
    525     for (i = 0; i < cnt; i++) {
    526         bufSize = Buf->getSize((uint32_t)i);
    527         if (BAD_INDEX != bufSize) {
    528             if (ops_tbl == NULL) {
    529                 rc = mCamOps->map_stream_buf(mCamHandle, mChannelHandle, mHandle,
    530                         (uint8_t)bufType, (uint32_t)i, -1,
    531                         Buf->getFd((uint32_t)i), (uint32_t)bufSize);
    532             } else {
    533                 rc = ops_tbl->map_ops((uint32_t)i, -1, Buf->getFd((uint32_t)i),
    534                         (uint32_t)bufSize, bufType, ops_tbl->userdata);
    535             }
    536             if (rc < 0) {
    537                 ALOGE("Failed to map buffer");
    538                 goto err1;
    539             }
    540         } else {
    541             ALOGE("Failed to retrieve buffer size (bad index)");
    542             rc = BAD_INDEX;
    543             goto err1;
    544         }
    545     }
    546 
    547     return rc;
    548 err1:
    549     i -= 1;
    550     for (; i >= 0; i--) {
    551         bufSize = Buf->getSize((uint32_t)i);
    552         if (BAD_INDEX != bufSize) {
    553             if (ops_tbl == NULL) {
    554                 rc = mCamOps->unmap_stream_buf(mCamHandle, mChannelHandle, mHandle,
    555                         (uint8_t)bufType, (uint32_t)i, -1);
    556             } else {
    557                 rc = ops_tbl->unmap_ops((uint32_t)i, -1, bufType, ops_tbl->userdata);
    558             }
    559             if (rc < 0) {
    560                 ALOGE("Failed to unmap buffer");
    561             }
    562         } else {
    563             ALOGE("Failed to retrieve buffer size (bad index)");
    564             rc = BAD_INDEX;
    565         }
    566     }
    567     return rc;
    568 }
    569 
    570 /*===========================================================================
    571  * FUNCTION   : init
    572  *
    573  * DESCRIPTION: initialize stream obj
    574  *
    575  * PARAMETERS :
    576  *   @streamInfoBuf: ptr to buf that contains stream info
    577  *   @miscBuf      : ptr to buf that contains misc bufs
    578  *   @stream_cb    : stream data notify callback. Can be NULL if not needed
    579  *   @userdata     : user data ptr
    580  *   @bDynallocBuf : flag to indicate if buffer allocation can be in 2 steps
    581  *
    582  * RETURN     : int32_t type of status
    583  *              NO_ERROR  -- success
    584  *              none-zero failure code
    585  *==========================================================================*/
    586 int32_t QCameraStream::init(QCameraHeapMemory *streamInfoBuf,
    587         QCameraHeapMemory *miscBuf,
    588         uint8_t minNumBuffers,
    589         stream_cb_routine stream_cb,
    590         void *userdata,
    591         bool bDynallocBuf)
    592 {
    593     int32_t rc = OK;
    594 
    595     mHandle = mCamOps->add_stream(mCamHandle, mChannelHandle);
    596     if (!mHandle) {
    597         ALOGE("add_stream failed");
    598         rc = UNKNOWN_ERROR;
    599         if (streamInfoBuf != NULL) {
    600             streamInfoBuf->deallocate();
    601             delete streamInfoBuf;
    602             streamInfoBuf = NULL;
    603         }
    604         goto done;
    605     }
    606 
    607     // assign and map stream info memory
    608     mStreamInfoBuf = streamInfoBuf;
    609     mStreamInfo = reinterpret_cast<cam_stream_info_t *>(mStreamInfoBuf->getPtr(0));
    610     mNumBufs = minNumBuffers;
    611 
    612     rc = mapBuf(mStreamInfoBuf, CAM_MAPPING_BUF_TYPE_STREAM_INFO, NULL);
    613     if (rc < 0) {
    614         ALOGE("Failed to map stream info buffer");
    615         releaseStreamInfoBuf();
    616         mStreamInfo = 0;
    617         goto err1;
    618     }
    619 
    620     mMiscBuf = miscBuf;
    621     if (miscBuf) {
    622         rc = mapBuf(mMiscBuf, CAM_MAPPING_BUF_TYPE_MISC_BUF, NULL);
    623         if (rc < 0) {
    624             ALOGE("Failed to map miscellaneous buffer");
    625             releaseMiscBuf();
    626             goto err1;
    627         }
    628     }
    629 
    630     // Calculate buffer size for deffered allocation
    631     if (mDefferedAllocation) {
    632         rc = calcOffset(mStreamInfo);
    633         if (rc < 0) {
    634             ALOGE("%s : Failed to calculate stream offset", __func__);
    635             goto err1;
    636         }
    637     } else {
    638         rc = configStream();
    639         if (rc < 0) {
    640             ALOGE("%s : Failed to config stream ", __func__);
    641             goto err1;
    642         }
    643     }
    644 
    645     mDataCB = stream_cb;
    646     mUserData = userdata;
    647     mDynBufAlloc = bDynallocBuf;
    648     return 0;
    649 
    650 err1:
    651     mCamOps->delete_stream(mCamHandle, mChannelHandle, mHandle);
    652     mHandle = 0;
    653     mNumBufs = 0;
    654 done:
    655     return rc;
    656 }
    657 
    658 /*===========================================================================
    659  * FUNCTION   : calcOffset
    660  *
    661  * DESCRIPTION: calculate frame offset based on format and padding information
    662  *
    663  * PARAMETERS :
    664  *   @streamInfo  : stream information
    665  *
    666  * RETURN     : int32_t type of status
    667  *              0  -- success
    668  *              -1 -- failure
    669  *==========================================================================*/
    670 int32_t QCameraStream::calcOffset(cam_stream_info_t *streamInfo)
    671 {
    672     int32_t rc = 0;
    673 
    674     cam_dimension_t dim = streamInfo->dim;
    675     if (streamInfo->pp_config.feature_mask & CAM_QCOM_FEATURE_ROTATION &&
    676             streamInfo->stream_type != CAM_STREAM_TYPE_VIDEO) {
    677         if (streamInfo->pp_config.rotation == ROTATE_90 ||
    678                 streamInfo->pp_config.rotation == ROTATE_270) {
    679             // rotated by 90 or 270, need to switch width and height
    680             dim.width = streamInfo->dim.height;
    681             dim.height = streamInfo->dim.width;
    682         }
    683     }
    684 
    685     switch (streamInfo->stream_type) {
    686     case CAM_STREAM_TYPE_PREVIEW:
    687         rc = mm_stream_calc_offset_preview(streamInfo->fmt,
    688                 &dim,
    689                 &streamInfo->buf_planes);
    690         break;
    691     case CAM_STREAM_TYPE_POSTVIEW:
    692         rc = mm_stream_calc_offset_post_view(streamInfo->fmt,
    693                 &dim,
    694                 &streamInfo->buf_planes);
    695         break;
    696     case CAM_STREAM_TYPE_SNAPSHOT:
    697         rc = mm_stream_calc_offset_snapshot(streamInfo->fmt,
    698                 &dim,
    699                 &mPaddingInfo,
    700                 &streamInfo->buf_planes);
    701         break;
    702     case CAM_STREAM_TYPE_OFFLINE_PROC:
    703         rc = mm_stream_calc_offset_postproc(streamInfo,
    704                 &mPaddingInfo,
    705                 &streamInfo->buf_planes);
    706         break;
    707     case CAM_STREAM_TYPE_VIDEO:
    708         rc = mm_stream_calc_offset_video(&dim,
    709                 &streamInfo->buf_planes);
    710         break;
    711     case CAM_STREAM_TYPE_RAW:
    712         rc = mm_stream_calc_offset_raw(streamInfo->fmt,
    713                 &dim,
    714                 &mPaddingInfo,
    715                 &streamInfo->buf_planes);
    716         break;
    717     case CAM_STREAM_TYPE_ANALYSIS:
    718         rc = mm_stream_calc_offset_analysis(streamInfo->fmt,
    719                 &dim,
    720                 &mPaddingInfo,
    721                 &streamInfo->buf_planes);
    722         break;
    723     case CAM_STREAM_TYPE_METADATA:
    724         rc = mm_stream_calc_offset_metadata(&dim,
    725                 &mPaddingInfo,
    726                 &streamInfo->buf_planes);
    727         break;
    728     default:
    729         ALOGE("%s: not supported for stream type %d",
    730                 __func__, streamInfo->stream_type);
    731         rc = -1;
    732         break;
    733     }
    734     return rc;
    735 }
    736 
    737 /*===========================================================================
    738  * FUNCTION   : start
    739  *
    740  * DESCRIPTION: start stream. Will start main stream thread to handle stream
    741  *              related ops.
    742  *
    743  * PARAMETERS : none
    744  *
    745  * RETURN     : int32_t type of status
    746  *              NO_ERROR  -- success
    747  *              none-zero failure code
    748  *==========================================================================*/
    749 int32_t QCameraStream::start()
    750 {
    751     int32_t rc = 0;
    752     mDataQ.init();
    753     rc = mProcTh.launch(dataProcRoutine, this);
    754     if (rc == NO_ERROR) {
    755         m_bActive = true;
    756     }
    757     pthread_mutex_init(&m_lock, NULL);
    758     pthread_cond_init(&m_cond, NULL);
    759     return rc;
    760 }
    761 
    762 /*===========================================================================
    763  * FUNCTION   : stop
    764  *
    765  * DESCRIPTION: stop stream. Will stop main stream thread
    766  *
    767  * PARAMETERS : none
    768  *
    769  * RETURN     : int32_t type of status
    770  *              NO_ERROR  -- success
    771  *              none-zero failure code
    772  *==========================================================================*/
    773 int32_t QCameraStream::stop()
    774 {
    775     int32_t rc = 0;
    776     m_bActive = false;
    777     rc = mProcTh.exit();
    778     return rc;
    779 }
    780 
    781 /*===========================================================================
    782  * FUNCTION   : syncRuntimeParams
    783  *
    784  * DESCRIPTION: query and sync runtime parameters like output crop
    785  *              buffer info etc.
    786  *
    787  * PARAMETERS : none
    788  *
    789  * RETURN     : int32_t type of status
    790  *              NO_ERROR  -- success
    791  *              none-zero failure code
    792  *==========================================================================*/
    793 int32_t QCameraStream::syncRuntimeParams()
    794 {
    795     int32_t ret = NO_ERROR;
    796 
    797     memset(&m_OutputCrop, 0, sizeof(cam_stream_parm_buffer_t));
    798     m_OutputCrop.type = CAM_STREAM_PARAM_TYPE_GET_OUTPUT_CROP;
    799 
    800     ret = getParameter(m_OutputCrop);
    801     if (ret != NO_ERROR) {
    802         ALOGE("%s: stream getParameter for output crop failed", __func__);
    803         return ret;
    804     }
    805 
    806     memset(&m_ImgProp, 0, sizeof(cam_stream_parm_buffer_t));
    807     m_ImgProp.type = CAM_STREAM_PARAM_TYPE_GET_IMG_PROP;
    808 
    809     ret = getParameter(m_ImgProp);
    810     if (ret != NO_ERROR) {
    811         ALOGE("%s: stream getParameter for image prop failed", __func__);
    812         return ret;
    813     }
    814 
    815     return ret;
    816 }
    817 
    818 /*===========================================================================
    819  * FUNCTION   : processZoomDone
    820  *
    821  * DESCRIPTION: process zoom done event
    822  *
    823  * PARAMETERS :
    824  *   @previewWindoe : preview window ops table to set preview crop window
    825  *   @crop_info     : crop info
    826  *
    827  * RETURN     : int32_t type of status
    828  *              NO_ERROR  -- success
    829  *              none-zero failure code
    830  *==========================================================================*/
    831 int32_t QCameraStream::processZoomDone(preview_stream_ops_t *previewWindow,
    832                                        cam_crop_data_t &crop_info)
    833 {
    834     int32_t rc = 0;
    835 
    836     if (!m_bActive) {
    837         ALOGV("%s : Stream not active", __func__);
    838         return NO_ERROR;
    839     }
    840 
    841     // get stream param for crop info
    842     for (int i = 0; i < crop_info.num_of_streams; i++) {
    843         if (crop_info.crop_info[i].stream_id == mStreamInfo->stream_svr_id) {
    844             pthread_mutex_lock(&mCropLock);
    845             mCropInfo = crop_info.crop_info[i].crop;
    846             pthread_mutex_unlock(&mCropLock);
    847 
    848             // update preview window crop if it's preview/postview stream
    849             if ( (previewWindow != NULL) &&
    850                  (mStreamInfo->stream_type == CAM_STREAM_TYPE_PREVIEW ||
    851                   mStreamInfo->stream_type == CAM_STREAM_TYPE_POSTVIEW) ) {
    852                 rc = previewWindow->set_crop(previewWindow,
    853                                              mCropInfo.left,
    854                                              mCropInfo.top,
    855                                              mCropInfo.width,
    856                                              mCropInfo.height);
    857             }
    858             break;
    859         }
    860     }
    861     return rc;
    862 }
    863 
    864 /*===========================================================================
    865  * FUNCTION   : processDataNotify
    866  *
    867  * DESCRIPTION: process stream data notify
    868  *
    869  * PARAMETERS :
    870  *   @frame   : stream frame received
    871  *
    872  * RETURN     : int32_t type of status
    873  *              NO_ERROR  -- success
    874  *              none-zero failure code
    875  *==========================================================================*/
    876 int32_t QCameraStream::processDataNotify(mm_camera_super_buf_t *frame)
    877 {
    878     CDBG("%s:\n", __func__);
    879     if (mDataQ.enqueue((void *)frame)) {
    880         return mProcTh.sendCmd(CAMERA_CMD_TYPE_DO_NEXT_JOB, FALSE, FALSE);
    881     } else {
    882         CDBG_HIGH("%s: Stream thread is not active, no ops here", __func__);
    883         bufDone(frame->bufs[0]->buf_idx);
    884         free(frame);
    885         return NO_ERROR;
    886     }
    887 }
    888 
    889 /*===========================================================================
    890  * FUNCTION   : dataNotifyCB
    891  *
    892  * DESCRIPTION: callback for data notify. This function is registered with
    893  *              mm-camera-interface to handle data notify
    894  *
    895  * PARAMETERS :
    896  *   @recvd_frame   : stream frame received
    897  *   userdata       : user data ptr
    898  *
    899  * RETURN     : none
    900  *==========================================================================*/
    901 void QCameraStream::dataNotifyCB(mm_camera_super_buf_t *recvd_frame,
    902                                  void *userdata)
    903 {
    904     CDBG("%s:\n", __func__);
    905     QCameraStream* stream = (QCameraStream *)userdata;
    906     if (stream == NULL ||
    907         recvd_frame == NULL ||
    908         recvd_frame->bufs[0] == NULL ||
    909         recvd_frame->bufs[0]->stream_id != stream->getMyHandle()) {
    910         ALOGE("%s: Not a valid stream to handle buf", __func__);
    911         return;
    912     }
    913 
    914     mm_camera_super_buf_t *frame =
    915         (mm_camera_super_buf_t *)malloc(sizeof(mm_camera_super_buf_t));
    916     if (frame == NULL) {
    917         ALOGE("%s: No mem for mm_camera_buf_def_t", __func__);
    918         stream->bufDone(recvd_frame->bufs[0]->buf_idx);
    919         return;
    920     }
    921     *frame = *recvd_frame;
    922     stream->processDataNotify(frame);
    923     return;
    924 }
    925 
    926 /*===========================================================================
    927  * FUNCTION   : dataProcRoutine
    928  *
    929  * DESCRIPTION: function to process data in the main stream thread
    930  *
    931  * PARAMETERS :
    932  *   @data    : user data ptr
    933  *
    934  * RETURN     : none
    935  *==========================================================================*/
    936 void *QCameraStream::dataProcRoutine(void *data)
    937 {
    938     int running = 1;
    939     int ret;
    940     QCameraStream *pme = (QCameraStream *)data;
    941     QCameraCmdThread *cmdThread = &pme->mProcTh;
    942     cmdThread->setName("CAM_strmDatProc");
    943 
    944     CDBG("%s: E", __func__);
    945     do {
    946         do {
    947             ret = cam_sem_wait(&cmdThread->cmd_sem);
    948             if (ret != 0 && errno != EINVAL) {
    949                 ALOGE("%s: cam_sem_wait error (%s)",
    950                       __func__, strerror(errno));
    951                 return NULL;
    952             }
    953         } while (ret != 0);
    954 
    955         // we got notified about new cmd avail in cmd queue
    956         camera_cmd_type_t cmd = cmdThread->getCmd();
    957         switch (cmd) {
    958         case CAMERA_CMD_TYPE_DO_NEXT_JOB:
    959             {
    960                 CDBG_HIGH("%s: Do next job", __func__);
    961                 mm_camera_super_buf_t *frame =
    962                     (mm_camera_super_buf_t *)pme->mDataQ.dequeue();
    963                 if (NULL != frame) {
    964                     if (pme->mDataCB != NULL) {
    965                         pme->mDataCB(frame, pme, pme->mUserData);
    966                     } else {
    967                         // no data cb routine, return buf here
    968                         pme->bufDone(frame->bufs[0]->buf_idx);
    969                         free(frame);
    970                     }
    971                 }
    972             }
    973             break;
    974         case CAMERA_CMD_TYPE_EXIT:
    975             CDBG_HIGH("%s: Exit", __func__);
    976             /* flush data buf queue */
    977             pme->mDataQ.flush();
    978             running = 0;
    979             break;
    980         default:
    981             break;
    982         }
    983     } while (running);
    984     CDBG_HIGH("%s: X", __func__);
    985     return NULL;
    986 }
    987 
    988 /*===========================================================================
    989  * FUNCTION   : bufDone
    990  *
    991  * DESCRIPTION: return stream buffer to kernel
    992  *
    993  * PARAMETERS :
    994  *   @index   : index of buffer to be returned
    995  *
    996  * RETURN     : int32_t type of status
    997  *              NO_ERROR  -- success
    998  *              none-zero failure code
    999  *==========================================================================*/
   1000 int32_t QCameraStream::bufDone(uint32_t index)
   1001 {
   1002     int32_t rc = NO_ERROR;
   1003 
   1004     if (index >= mNumBufs || mBufDefs == NULL)
   1005         return BAD_INDEX;
   1006 
   1007     rc = mCamOps->qbuf(mCamHandle, mChannelHandle, &mBufDefs[index]);
   1008     if (rc < 0)
   1009         return rc;
   1010 
   1011     return rc;
   1012 }
   1013 
   1014 /*===========================================================================
   1015  * FUNCTION   : bufDone
   1016  *
   1017  * DESCRIPTION: return stream buffer to kernel
   1018  *
   1019  * PARAMETERS :
   1020  *   @opaque    : stream frame/metadata buf to be returned
   1021  *   @isMetaData: flag if returned opaque is a metadatabuf or the real frame ptr
   1022  *
   1023  * RETURN     : int32_t type of status
   1024  *              NO_ERROR  -- success
   1025  *              none-zero failure code
   1026  *==========================================================================*/
   1027 int32_t QCameraStream::bufDone(const void *opaque, bool isMetaData)
   1028 {
   1029     int32_t rc = NO_ERROR;
   1030     int index;
   1031 
   1032     if (mStreamInfo != NULL
   1033             && mStreamInfo->streaming_mode == CAM_STREAMING_MODE_BATCH) {
   1034         index = mStreamBatchBufs->getMatchBufIndex(opaque, TRUE);
   1035         if (index == -1 || index >= mNumBufs || mBufDefs == NULL) {
   1036             ALOGE("%s: Cannot find buf for opaque data = %p", __func__, opaque);
   1037             return BAD_INDEX;
   1038         }
   1039         camera_memory_t *video_mem = mStreamBatchBufs->getMemory(index, true);
   1040         if (video_mem != NULL) {
   1041             struct encoder_media_buffer_type * packet =
   1042                     (struct encoder_media_buffer_type *)video_mem->data;
   1043             native_handle_t *nh = const_cast<native_handle_t *>(packet->meta_handle);
   1044             if (NULL != nh) {
   1045                if (native_handle_delete(nh)) {
   1046                    ALOGE("%s: Unable to delete native handle", __func__);
   1047                }
   1048             } else {
   1049                ALOGE("%s : native handle not available", __func__);
   1050             }
   1051         }
   1052     } else {
   1053         index = mStreamBufs->getMatchBufIndex(opaque, isMetaData);
   1054         if (index == -1 || index >= mNumBufs || mBufDefs == NULL) {
   1055             ALOGE("%s: Cannot find buf for opaque data = %p", __func__, opaque);
   1056             return BAD_INDEX;
   1057         }
   1058         CDBG_HIGH("%s: Buffer Index = %d, Frame Idx = %d", __func__, index,
   1059                 mBufDefs[index].frame_idx);
   1060     }
   1061     rc = bufDone((uint32_t)index);
   1062     return rc;
   1063 }
   1064 
   1065 /*===========================================================================
   1066  * FUNCTION   : getNumQueuedBuf
   1067  *
   1068  * DESCRIPTION: return queued buffer count
   1069  *
   1070  * PARAMETERS : None
   1071  *
   1072  * RETURN     : queued buffer count
   1073  *==========================================================================*/
   1074 int32_t QCameraStream::getNumQueuedBuf()
   1075 {
   1076     int32_t rc = -1;
   1077     if (mHandle > 0) {
   1078         rc = mCamOps->get_queued_buf_count(mCamHandle, mChannelHandle, mHandle);
   1079     }
   1080     if (rc == -1) {
   1081         ALOGE("%s: stream is not in active state. Invalid operation", __func__);
   1082     }
   1083     return rc;
   1084 }
   1085 
   1086 /*===========================================================================
   1087  * FUNCTION   : getBufs
   1088  *
   1089  * DESCRIPTION: allocate stream buffers
   1090  *
   1091  * PARAMETERS :
   1092  *   @offset     : offset info of stream buffers
   1093  *   @num_bufs   : number of buffers allocated
   1094  *   @initial_reg_flag: flag to indicate if buffer needs to be registered
   1095  *                      at kernel initially
   1096  *   @bufs       : output of allocated buffers
   1097  *   @ops_tbl    : ptr to buf mapping/unmapping ops
   1098  *
   1099  * RETURN     : int32_t type of status
   1100  *              NO_ERROR  -- success
   1101  *              none-zero failure code
   1102  *==========================================================================*/
   1103 int32_t QCameraStream::getBufs(cam_frame_len_offset_t *offset,
   1104         uint8_t *num_bufs,
   1105         uint8_t **initial_reg_flag,
   1106         mm_camera_buf_def_t **bufs,
   1107         mm_camera_map_unmap_ops_tbl_t *ops_tbl)
   1108 {
   1109     int rc = NO_ERROR;
   1110     uint8_t *regFlags;
   1111 
   1112     if (!ops_tbl) {
   1113         ALOGE("%s: ops_tbl is NULL", __func__);
   1114         return INVALID_OPERATION;
   1115     }
   1116 
   1117     mFrameLenOffset = *offset;
   1118 
   1119     uint8_t numBufAlloc = mNumBufs;
   1120     mNumBufsNeedAlloc = 0;
   1121     if (mDynBufAlloc) {
   1122         numBufAlloc = CAMERA_MIN_ALLOCATED_BUFFERS;
   1123         if (numBufAlloc > mNumBufs) {
   1124             mDynBufAlloc = false;
   1125             numBufAlloc = mNumBufs;
   1126         } else {
   1127             mNumBufsNeedAlloc = (uint8_t)(mNumBufs - numBufAlloc);
   1128         }
   1129     }
   1130 
   1131     //Allocate stream buffer
   1132     mStreamBufs = mAllocator.allocateStreamBuf(mStreamInfo->stream_type,
   1133             mFrameLenOffset.frame_len, mFrameLenOffset.mp[0].stride,
   1134             mFrameLenOffset.mp[0].scanline, numBufAlloc);
   1135     if (!mStreamBufs) {
   1136         ALOGE("%s: Failed to allocate stream buffers", __func__);
   1137         return NO_MEMORY;
   1138     }
   1139 
   1140     mNumBufs = (uint8_t)(numBufAlloc + mNumBufsNeedAlloc);
   1141 
   1142     for (uint32_t i = 0; i < numBufAlloc; i++) {
   1143         ssize_t bufSize = mStreamBufs->getSize(i);
   1144         if (BAD_INDEX != bufSize) {
   1145             rc = ops_tbl->map_ops(i, -1, mStreamBufs->getFd(i),
   1146                     (uint32_t)bufSize, CAM_MAPPING_BUF_TYPE_STREAM_BUF, ops_tbl->userdata);
   1147             if (rc < 0) {
   1148                 ALOGE("%s: map_stream_buf failed: %d", __func__, rc);
   1149                 for (uint32_t j = 0; j < i; j++) {
   1150                     ops_tbl->unmap_ops(j, -1, CAM_MAPPING_BUF_TYPE_STREAM_BUF, ops_tbl->userdata);
   1151                 }
   1152                 mStreamBufs->deallocate();
   1153                 delete mStreamBufs;
   1154                 mStreamBufs = NULL;
   1155                 return INVALID_OPERATION;
   1156             }
   1157         } else {
   1158             ALOGE("Failed to retrieve buffer size (bad index)");
   1159             return INVALID_OPERATION;
   1160         }
   1161     }
   1162 
   1163     //regFlags array is allocated by us, but consumed and freed by mm-camera-interface
   1164     regFlags = (uint8_t *)malloc(sizeof(uint8_t) * mNumBufs);
   1165     if (!regFlags) {
   1166         ALOGE("%s: Out of memory", __func__);
   1167         for (uint32_t i = 0; i < numBufAlloc; i++) {
   1168             ops_tbl->unmap_ops(i, -1, CAM_MAPPING_BUF_TYPE_STREAM_BUF, ops_tbl->userdata);
   1169         }
   1170         mStreamBufs->deallocate();
   1171         delete mStreamBufs;
   1172         mStreamBufs = NULL;
   1173         return NO_MEMORY;
   1174     }
   1175     memset(regFlags, 0, sizeof(uint8_t) * mNumBufs);
   1176 
   1177     mBufDefs = (mm_camera_buf_def_t *)malloc(mNumBufs * sizeof(mm_camera_buf_def_t));
   1178     if (mBufDefs == NULL) {
   1179         ALOGE("%s: getRegFlags failed %d", __func__, rc);
   1180         for (uint32_t i = 0; i < numBufAlloc; i++) {
   1181             ops_tbl->unmap_ops(i, -1, CAM_MAPPING_BUF_TYPE_STREAM_BUF, ops_tbl->userdata);
   1182         }
   1183         mStreamBufs->deallocate();
   1184         delete mStreamBufs;
   1185         mStreamBufs = NULL;
   1186         free(regFlags);
   1187         regFlags = NULL;
   1188         return INVALID_OPERATION;
   1189     }
   1190     memset(mBufDefs, 0, mNumBufs * sizeof(mm_camera_buf_def_t));
   1191     for (uint32_t i = 0; i < numBufAlloc; i++) {
   1192         mStreamBufs->getBufDef(mFrameLenOffset, mBufDefs[i], i);
   1193     }
   1194 
   1195     rc = mStreamBufs->getRegFlags(regFlags);
   1196     if (rc < 0) {
   1197         ALOGE("%s: getRegFlags failed %d", __func__, rc);
   1198         for (uint32_t i = 0; i < numBufAlloc; i++) {
   1199             ops_tbl->unmap_ops(i, -1, CAM_MAPPING_BUF_TYPE_STREAM_BUF, ops_tbl->userdata);
   1200         }
   1201         mStreamBufs->deallocate();
   1202         delete mStreamBufs;
   1203         mStreamBufs = NULL;
   1204         free(mBufDefs);
   1205         mBufDefs = NULL;
   1206         free(regFlags);
   1207         regFlags = NULL;
   1208         return INVALID_OPERATION;
   1209     }
   1210 
   1211     *num_bufs = mNumBufs;
   1212     *initial_reg_flag = regFlags;
   1213     *bufs = mBufDefs;
   1214     CDBG_HIGH("%s: stream type: %d, mRegFlags: 0x%x, numBufs: %d",
   1215             __func__, mStreamInfo->stream_type, regFlags, mBufDefs);
   1216 
   1217     if (mNumBufsNeedAlloc > 0) {
   1218         pthread_mutex_lock(&m_lock);
   1219         wait_for_cond = TRUE;
   1220         pthread_mutex_unlock(&m_lock);
   1221         CDBG_HIGH("%s: Still need to allocate %d buffers",
   1222               __func__, mNumBufsNeedAlloc);
   1223         // remember memops table
   1224         m_MemOpsTbl = *ops_tbl;
   1225         // start another thread to allocate the rest of buffers
   1226         pthread_create(&mBufAllocPid,
   1227                        NULL,
   1228                        BufAllocRoutine,
   1229                        this);
   1230         pthread_setname_np(mBufAllocPid, "CAM_strmBufAlloc");
   1231     }
   1232 
   1233     return NO_ERROR;
   1234 }
   1235 
   1236 /*===========================================================================
   1237  * FUNCTION   : allocateBuffers
   1238  *
   1239  * DESCRIPTION: allocate stream buffers
   1240  *
   1241  * PARAMETERS :
   1242  *
   1243  * RETURN     : int32_t type of status
   1244  *              NO_ERROR  -- success
   1245  *              none-zero failure code
   1246  *==========================================================================*/
   1247 int32_t QCameraStream::allocateBuffers()
   1248 {
   1249     int rc = NO_ERROR;
   1250 
   1251     mFrameLenOffset = mStreamInfo->buf_planes.plane_info;
   1252 
   1253     if (mStreamInfo->streaming_mode == CAM_STREAMING_MODE_BATCH) {
   1254         return allocateBatchBufs(&mFrameLenOffset,
   1255                 &mNumBufs, &mRegFlags,
   1256                 &mBufDefs, NULL);
   1257     }
   1258 
   1259     //Allocate and map stream info buffer
   1260     mStreamBufs = mAllocator.allocateStreamBuf(mStreamInfo->stream_type,
   1261             mFrameLenOffset.frame_len,
   1262             mFrameLenOffset.mp[0].stride,
   1263             mFrameLenOffset.mp[0].scanline,
   1264             mNumBufs);
   1265 
   1266     if (!mStreamBufs) {
   1267         ALOGE("%s: Failed to allocate stream buffers", __func__);
   1268         return NO_MEMORY;
   1269     }
   1270 
   1271     for (uint32_t i = 0; i < mNumBufs; i++) {
   1272         ssize_t bufSize = mStreamBufs->getSize(i);
   1273         if (BAD_INDEX != bufSize) {
   1274             rc = mapBuf(CAM_MAPPING_BUF_TYPE_STREAM_BUF, i, -1,
   1275                     mStreamBufs->getFd(i), (size_t)bufSize, NULL);
   1276             ALOGE_IF((rc < 0), "%s: map_stream_buf failed: %d", __func__, rc);
   1277         } else {
   1278             ALOGE("%s: Bad index %u", __func__, i);
   1279             rc = BAD_INDEX;
   1280         }
   1281         if (rc < 0) {
   1282             ALOGE("%s: Cleanup after error: %d", __func__, rc);
   1283             for (uint32_t j = 0; j < i; j++) {
   1284                 unmapBuf(CAM_MAPPING_BUF_TYPE_STREAM_BUF, j, -1, NULL);
   1285             }
   1286             mStreamBufs->deallocate();
   1287             delete mStreamBufs;
   1288             mStreamBufs = NULL;
   1289             return INVALID_OPERATION;
   1290         }
   1291     }
   1292 
   1293     //regFlags array is allocated by us,
   1294     // but consumed and freed by mm-camera-interface
   1295     mRegFlags = (uint8_t *)malloc(sizeof(uint8_t) * mNumBufs);
   1296     if (!mRegFlags) {
   1297         ALOGE("%s: Out of memory", __func__);
   1298         for (uint32_t i = 0; i < mNumBufs; i++) {
   1299             unmapBuf(CAM_MAPPING_BUF_TYPE_STREAM_BUF, i, -1, NULL);
   1300         }
   1301         mStreamBufs->deallocate();
   1302         delete mStreamBufs;
   1303         mStreamBufs = NULL;
   1304         return NO_MEMORY;
   1305     }
   1306     memset(mRegFlags, 0, sizeof(uint8_t) * mNumBufs);
   1307 
   1308     size_t bufDefsSize = mNumBufs * sizeof(mm_camera_buf_def_t);
   1309     mBufDefs = (mm_camera_buf_def_t *)malloc(bufDefsSize);
   1310     if (mBufDefs == NULL) {
   1311         ALOGE("%s: getRegFlags failed %d", __func__, rc);
   1312         for (uint32_t i = 0; i < mNumBufs; i++) {
   1313             unmapBuf(CAM_MAPPING_BUF_TYPE_STREAM_BUF, i, -1, NULL);
   1314         }
   1315         mStreamBufs->deallocate();
   1316         delete mStreamBufs;
   1317         mStreamBufs = NULL;
   1318         free(mRegFlags);
   1319         mRegFlags = NULL;
   1320         return INVALID_OPERATION;
   1321     }
   1322     memset(mBufDefs, 0, bufDefsSize);
   1323     for (uint32_t i = 0; i < mNumBufs; i++) {
   1324         mStreamBufs->getBufDef(mFrameLenOffset, mBufDefs[i], i);
   1325     }
   1326 
   1327     rc = mStreamBufs->getRegFlags(mRegFlags);
   1328     if (rc < 0) {
   1329         ALOGE("%s: getRegFlags failed %d", __func__, rc);
   1330         for (uint32_t i = 0; i < mNumBufs; i++) {
   1331             unmapBuf(CAM_MAPPING_BUF_TYPE_STREAM_BUF, i, -1, NULL);
   1332         }
   1333         mStreamBufs->deallocate();
   1334         delete mStreamBufs;
   1335         mStreamBufs = NULL;
   1336         free(mBufDefs);
   1337         mBufDefs = NULL;
   1338         free(mRegFlags);
   1339         mRegFlags = NULL;
   1340         return INVALID_OPERATION;
   1341     }
   1342 
   1343     return NO_ERROR;
   1344 }
   1345 
   1346 /*===========================================================================
   1347  * FUNCTION   : allocateBatchBufs
   1348  *
   1349  * DESCRIPTION: allocate stream batch buffers and stream buffers
   1350  *
   1351  * PARAMETERS :
   1352  *   @offset     : offset info of stream buffers
   1353  *   @num_bufs   : number of buffers allocated
   1354  *   @initial_reg_flag: flag to indicate if buffer needs to be registered
   1355  *                      at kernel initially
   1356  *   @bufs       : output of allocated buffers
   1357  *   @plane_bufs    : output of allocated plane buffers
   1358   *   @ops_tbl    : ptr to buf mapping/unmapping ops
   1359  *
   1360  * RETURN     : int32_t type of status
   1361  *              NO_ERROR  -- success
   1362  *              none-zero failure code
   1363  *==========================================================================*/
   1364 int32_t QCameraStream::allocateBatchBufs(cam_frame_len_offset_t *offset,
   1365         uint8_t *num_bufs, uint8_t **initial_reg_flag,
   1366         mm_camera_buf_def_t **bufs, mm_camera_map_unmap_ops_tbl_t *ops_tbl)
   1367 {
   1368     int rc = NO_ERROR;
   1369     uint8_t *regFlags;
   1370 
   1371     mFrameLenOffset = *offset;
   1372 
   1373     CDBG_HIGH("%s : Batch Buffer allocation stream type = %d", __func__, getMyType());
   1374 
   1375     //Allocate stream batch buffer
   1376     mStreamBatchBufs = mAllocator.allocateStreamUserBuf (mStreamInfo);
   1377     if (!mStreamBatchBufs) {
   1378         ALOGE("%s: Failed to allocate stream batch buffers", __func__);
   1379         return NO_MEMORY;
   1380     }
   1381 
   1382     //map batch buffers
   1383     for (uint32_t i = 0; i < mStreamBatchBufs->getCnt(); i++) {
   1384         rc = mapBuf(CAM_MAPPING_BUF_TYPE_STREAM_USER_BUF, i, -1,
   1385                     mStreamBatchBufs->getFd(i), (size_t)mNumBufs, ops_tbl);
   1386         if (rc < 0) {
   1387             ALOGE("Failed to map stream batch buffer");
   1388             for (uint32_t j = 0; j < i; j++) {
   1389                 unmapBuf(CAM_MAPPING_BUF_TYPE_STREAM_USER_BUF, j, -1, ops_tbl);
   1390             }
   1391             mStreamBatchBufs->deallocate();
   1392             delete mStreamBatchBufs;
   1393             mStreamBatchBufs = NULL;
   1394             return NO_MEMORY;
   1395         }
   1396     }
   1397 
   1398     /*calculate stream Buffer count*/
   1399     mNumPlaneBufs =
   1400             (mNumBufs * mStreamInfo->user_buf_info.frame_buf_cnt);
   1401 
   1402     //Allocate stream buffer
   1403     mStreamBufs = mAllocator.allocateStreamBuf(mStreamInfo->stream_type,
   1404             mFrameLenOffset.frame_len,mFrameLenOffset.mp[0].stride,
   1405             mFrameLenOffset.mp[0].scanline,mNumPlaneBufs);
   1406     if (!mStreamBufs) {
   1407         ALOGE("%s: Failed to allocate stream buffers", __func__);
   1408         rc = NO_MEMORY;
   1409         goto err1;
   1410     }
   1411 
   1412     //Map plane stream buffers
   1413     for (uint32_t i = 0; i < mNumPlaneBufs; i++) {
   1414         ssize_t bufSize = mStreamBufs->getSize(i);
   1415         if (BAD_INDEX != bufSize) {
   1416             rc = mapBuf(CAM_MAPPING_BUF_TYPE_STREAM_BUF, i, -1,
   1417                     mStreamBufs->getFd(i), (size_t)bufSize, ops_tbl);
   1418             if (rc < 0) {
   1419                 ALOGE("%s: map_stream_buf failed: %d", __func__, rc);
   1420                 for (uint32_t j = 0; j < i; j++) {
   1421                     unmapBuf(CAM_MAPPING_BUF_TYPE_STREAM_BUF, j, -1, ops_tbl);
   1422                 }
   1423                 mStreamBufs->deallocate();
   1424                 delete mStreamBufs;
   1425                 mStreamBufs = NULL;
   1426                 rc = INVALID_OPERATION;
   1427                 goto err1;
   1428             }
   1429         } else {
   1430             ALOGE("Failed to retrieve buffer size (bad index)");
   1431             mStreamBufs->deallocate();
   1432             delete mStreamBufs;
   1433             mStreamBufs = NULL;
   1434             rc = INVALID_OPERATION;
   1435             goto err1;
   1436         }
   1437     }
   1438 
   1439     CDBG ("%s: BATCH Buf Count = %d, Plane Buf Cnt = %d", __func__,
   1440             mNumBufs, mNumPlaneBufs);
   1441 
   1442     //regFlags array is allocated by us, but consumed and freed by mm-camera-interface
   1443     regFlags = (uint8_t *)malloc(sizeof(uint8_t) * mNumBufs);
   1444     if (!regFlags) {
   1445         ALOGE("%s: Out of memory", __func__);
   1446         for (uint32_t i = 0; i < mNumPlaneBufs; i++) {
   1447             unmapBuf(CAM_MAPPING_BUF_TYPE_STREAM_BUF, i, -1, ops_tbl);
   1448         }
   1449         mStreamBufs->deallocate();
   1450         delete mStreamBufs;
   1451         mStreamBufs = NULL;
   1452         rc = NO_MEMORY;
   1453         goto err1;
   1454     }
   1455     memset(regFlags, 0, sizeof(uint8_t) * mNumBufs);
   1456     for (uint32_t i = 0; i < mNumBufs; i++) {
   1457         regFlags[i] = 1;
   1458     }
   1459 
   1460     mBufDefs = (mm_camera_buf_def_t *)malloc(mNumBufs * sizeof(mm_camera_buf_def_t));
   1461     if (mBufDefs == NULL) {
   1462         ALOGE("%s: getRegFlags failed %d", __func__, rc);
   1463         for (uint32_t i = 0; i < mNumPlaneBufs; i++) {
   1464             unmapBuf(CAM_MAPPING_BUF_TYPE_STREAM_BUF, i, -1, ops_tbl);
   1465         }
   1466         mStreamBufs->deallocate();
   1467         delete mStreamBufs;
   1468         mStreamBufs = NULL;
   1469         free(regFlags);
   1470         regFlags = NULL;
   1471         rc = INVALID_OPERATION;
   1472         goto err1;
   1473     }
   1474     memset(mBufDefs, 0, mNumBufs * sizeof(mm_camera_buf_def_t));
   1475 
   1476     mPlaneBufDefs = (mm_camera_buf_def_t *)
   1477             malloc(mNumPlaneBufs * (sizeof(mm_camera_buf_def_t)));
   1478     if (mPlaneBufDefs == NULL) {
   1479         ALOGE("%s : No Memory", __func__);
   1480         free(regFlags);
   1481         regFlags = NULL;
   1482         free(mBufDefs);
   1483         mBufDefs = NULL;
   1484         for (uint32_t i = 0; i < mNumPlaneBufs; i++) {
   1485             unmapBuf(CAM_MAPPING_BUF_TYPE_STREAM_BUF, i, -1, ops_tbl);
   1486         }
   1487         mStreamBufs->deallocate();
   1488         delete mStreamBufs;
   1489         mStreamBufs = NULL;
   1490         free(regFlags);
   1491         regFlags = NULL;
   1492         rc = INVALID_OPERATION;
   1493         goto err1;
   1494     }
   1495     memset(mPlaneBufDefs, 0,
   1496              mNumPlaneBufs * (sizeof(mm_camera_buf_def_t)));
   1497 
   1498     for (uint32_t i = 0; i < mStreamInfo->num_bufs; i++) {
   1499         mStreamBatchBufs->getUserBufDef(mStreamInfo->user_buf_info,
   1500                 mBufDefs[i], i, mFrameLenOffset, mPlaneBufDefs,
   1501                 mStreamBufs);
   1502     }
   1503 
   1504     *num_bufs = mNumBufs;
   1505     *initial_reg_flag = regFlags;
   1506     *bufs = mBufDefs;
   1507     CDBG_HIGH("%s: stream type: %d, numBufs: %d mNumPlaneBufs: %d",
   1508             __func__, mStreamInfo->stream_type, mNumBufs, mNumPlaneBufs);
   1509 
   1510     return NO_ERROR;
   1511 
   1512 err1:
   1513     for (uint8_t i = 0; i < mStreamBatchBufs->getCnt(); i++) {
   1514         unmapBuf(CAM_MAPPING_BUF_TYPE_STREAM_USER_BUF, i, -1, ops_tbl);
   1515     }
   1516     mStreamBatchBufs->deallocate();
   1517     delete mStreamBatchBufs;
   1518     mStreamBatchBufs = NULL;
   1519     return rc;
   1520 }
   1521 
   1522 
   1523 /*===========================================================================
   1524  * FUNCTION   : releaseBuffs
   1525  *
   1526  * DESCRIPTION: method to deallocate stream buffers
   1527  *
   1528  * PARAMETERS :
   1529  *
   1530  * RETURN     : int32_t type of status
   1531  *              NO_ERROR  -- success
   1532  *              none-zero failure code
   1533  *==========================================================================*/
   1534 int32_t QCameraStream::releaseBuffs()
   1535 {
   1536     int rc = NO_ERROR;
   1537 
   1538     if (mStreamInfo->streaming_mode == CAM_STREAMING_MODE_BATCH) {
   1539         return releaseBatchBufs(NULL);
   1540     }
   1541 
   1542     if (NULL != mBufDefs) {
   1543         for (uint32_t i = 0; i < mNumBufs; i++) {
   1544             rc = unmapBuf(CAM_MAPPING_BUF_TYPE_STREAM_BUF, i, -1, NULL);
   1545             if (rc < 0) {
   1546                 ALOGE("%s: map_stream_buf failed: %d", __func__, rc);
   1547             }
   1548         }
   1549 
   1550         // mBufDefs just keep a ptr to the buffer
   1551         // mm-camera-interface own the buffer, so no need to free
   1552         mBufDefs = NULL;
   1553         memset(&mFrameLenOffset, 0, sizeof(mFrameLenOffset));
   1554     }
   1555     if (!mStreamBufsAcquired && mStreamBufs != NULL) {
   1556         mStreamBufs->deallocate();
   1557         delete mStreamBufs;
   1558     }
   1559 
   1560     return rc;
   1561 }
   1562 
   1563 /*===========================================================================
   1564  * FUNCTION   : releaseBatchBufs
   1565  *
   1566  * DESCRIPTION: method to deallocate stream buffers and batch buffers
   1567  *
   1568  * PARAMETERS :
   1569  *   @ops_tbl    : ptr to buf mapping/unmapping ops
   1570  *
   1571  * RETURN     : int32_t type of status
   1572  *              NO_ERROR  -- success
   1573  *              none-zero failure code
   1574 
   1575  *==========================================================================*/
   1576 int32_t QCameraStream::releaseBatchBufs(mm_camera_map_unmap_ops_tbl_t *ops_tbl)
   1577 {
   1578     int rc = NO_ERROR;
   1579 
   1580     if (NULL != mPlaneBufDefs) {
   1581         for (uint32_t i = 0; i < mNumPlaneBufs; i++) {
   1582             rc = unmapBuf(CAM_MAPPING_BUF_TYPE_STREAM_BUF, i, -1, ops_tbl);
   1583             if (rc < 0) {
   1584                 ALOGE("%s: map_stream_buf failed: %d", __func__, rc);
   1585             }
   1586         }
   1587 
   1588         // mBufDefs just keep a ptr to the buffer
   1589         // mm-camera-interface own the buffer, so no need to free
   1590         mPlaneBufDefs = NULL;
   1591         memset(&mFrameLenOffset, 0, sizeof(mFrameLenOffset));
   1592         mNumPlaneBufs = 0;
   1593     }
   1594 
   1595     if ( mStreamBufs != NULL) {
   1596         mStreamBufs->deallocate();
   1597         delete mStreamBufs;
   1598     }
   1599 
   1600     mBufDefs = NULL;
   1601 
   1602     if (mStreamBatchBufs != NULL) {
   1603         for (uint8_t i = 0; i < mStreamBatchBufs->getCnt(); i++) {
   1604             unmapBuf(CAM_MAPPING_BUF_TYPE_STREAM_USER_BUF, i, -1, ops_tbl);
   1605         }
   1606         mStreamBatchBufs->deallocate();
   1607         delete mStreamBatchBufs;
   1608         mStreamBatchBufs = NULL;
   1609     }
   1610     return rc;
   1611 
   1612 }
   1613 
   1614 /*===========================================================================
   1615  * FUNCTION   : BufAllocRoutine
   1616  *
   1617  * DESCRIPTION: function to allocate additional stream buffers
   1618  *
   1619  * PARAMETERS :
   1620  *   @data    : user data ptr
   1621  *
   1622  * RETURN     : none
   1623  *==========================================================================*/
   1624 void *QCameraStream::BufAllocRoutine(void *data)
   1625 {
   1626     QCameraStream *pme = (QCameraStream *)data;
   1627     int32_t rc = NO_ERROR;
   1628 
   1629     CDBG_HIGH("%s: E", __func__);
   1630     pme->cond_wait();
   1631     if (pme->mNumBufsNeedAlloc > 0) {
   1632         uint8_t numBufAlloc = (uint8_t)(pme->mNumBufs - pme->mNumBufsNeedAlloc);
   1633         rc = pme->mAllocator.allocateMoreStreamBuf(pme->mStreamBufs,
   1634                                                    pme->mFrameLenOffset.frame_len,
   1635                                                    pme->mNumBufsNeedAlloc);
   1636         if (rc == NO_ERROR){
   1637             for (uint32_t i = numBufAlloc; i < pme->mNumBufs; i++) {
   1638                 ssize_t bufSize = pme->mStreamBufs->getSize(i);
   1639                 if (BAD_INDEX != bufSize) {
   1640                     rc = pme->m_MemOpsTbl.map_ops(i, -1, pme->mStreamBufs->getFd(i),
   1641                             (uint32_t)bufSize, CAM_MAPPING_BUF_TYPE_STREAM_BUF,
   1642                             pme->m_MemOpsTbl.userdata);
   1643                     if (rc == 0) {
   1644                         pme->mStreamBufs->getBufDef(pme->mFrameLenOffset, pme->mBufDefs[i], i);
   1645                         pme->mCamOps->qbuf(pme->mCamHandle, pme->mChannelHandle,
   1646                                 &pme->mBufDefs[i]);
   1647                     } else {
   1648                         ALOGE("%s: map_stream_buf %d failed: %d", __func__, rc, i);
   1649                     }
   1650                 } else {
   1651                     ALOGE("Failed to retrieve buffer size (bad index)");
   1652                 }
   1653             }
   1654 
   1655             pme->mNumBufsNeedAlloc = 0;
   1656         }
   1657     }
   1658     CDBG_HIGH("%s: X", __func__);
   1659     return NULL;
   1660 }
   1661 
   1662 /*===========================================================================
   1663  * FUNCTION   : cond_signal
   1664  *
   1665  * DESCRIPTION: signal if flag "wait_for_cond" is set
   1666  *
   1667  *==========================================================================*/
   1668 void QCameraStream::cond_signal()
   1669 {
   1670     pthread_mutex_lock(&m_lock);
   1671     if(wait_for_cond == TRUE){
   1672         wait_for_cond = FALSE;
   1673         pthread_cond_signal(&m_cond);
   1674     }
   1675     pthread_mutex_unlock(&m_lock);
   1676 }
   1677 
   1678 
   1679 /*===========================================================================
   1680  * FUNCTION   : cond_wait
   1681  *
   1682  * DESCRIPTION: wait on if flag "wait_for_cond" is set
   1683  *
   1684  *==========================================================================*/
   1685 void QCameraStream::cond_wait()
   1686 {
   1687     pthread_mutex_lock(&m_lock);
   1688     while (wait_for_cond == TRUE) {
   1689         pthread_cond_wait(&m_cond, &m_lock);
   1690     }
   1691     pthread_mutex_unlock(&m_lock);
   1692 }
   1693 
   1694 /*===========================================================================
   1695  * FUNCTION   : putBufs
   1696  *
   1697  * DESCRIPTION: deallocate stream buffers
   1698  *
   1699  * PARAMETERS :
   1700  *   @ops_tbl    : ptr to buf mapping/unmapping ops
   1701  *
   1702  * RETURN     : int32_t type of status
   1703  *              NO_ERROR  -- success
   1704  *              none-zero failure code
   1705  *==========================================================================*/
   1706 int32_t QCameraStream::putBufs(mm_camera_map_unmap_ops_tbl_t *ops_tbl)
   1707 {
   1708     int rc = NO_ERROR;
   1709 
   1710     if (mBufAllocPid != 0) {
   1711         CDBG_HIGH("%s: wait for buf allocation thread dead", __func__);
   1712         pthread_join(mBufAllocPid, NULL);
   1713         mBufAllocPid = 0;
   1714         CDBG_HIGH("%s: return from buf allocation thread", __func__);
   1715     }
   1716 
   1717     for (uint32_t i = 0; i < mNumBufs; i++) {
   1718         rc = ops_tbl->unmap_ops(i, -1, CAM_MAPPING_BUF_TYPE_STREAM_BUF, ops_tbl->userdata);
   1719         if (rc < 0) {
   1720             ALOGE("%s: map_stream_buf failed: %d", __func__, rc);
   1721         }
   1722     }
   1723     mBufDefs = NULL; // mBufDefs just keep a ptr to the buffer
   1724                      // mm-camera-interface own the buffer, so no need to free
   1725     memset(&mFrameLenOffset, 0, sizeof(mFrameLenOffset));
   1726     if ( !mStreamBufsAcquired ) {
   1727         mStreamBufs->deallocate();
   1728         delete mStreamBufs;
   1729     }
   1730 
   1731     return rc;
   1732 }
   1733 
   1734 /*===========================================================================
   1735  * FUNCTION   : invalidateBuf
   1736  *
   1737  * DESCRIPTION: invalidate a specific stream buffer
   1738  *
   1739  * PARAMETERS :
   1740  *   @index   : index of the buffer to invalidate
   1741  *
   1742  * RETURN     : int32_t type of status
   1743  *              NO_ERROR  -- success
   1744  *              none-zero failure code
   1745  *==========================================================================*/
   1746 int32_t QCameraStream::invalidateBuf(uint32_t index)
   1747 {
   1748     return mStreamBufs->invalidateCache(index);
   1749 }
   1750 
   1751 /*===========================================================================
   1752  * FUNCTION   : cleanInvalidateBuf
   1753  *
   1754  * DESCRIPTION: clean invalidate a specific stream buffer
   1755  *
   1756  * PARAMETERS :
   1757  *   @index   : index of the buffer to clean invalidate
   1758  *
   1759  * RETURN     : int32_t type of status
   1760  *              NO_ERROR  -- success
   1761  *              none-zero failure code
   1762  *==========================================================================*/
   1763 int32_t QCameraStream::cleanInvalidateBuf(uint32_t index)
   1764 {
   1765     return mStreamBufs->cleanInvalidateCache(index);
   1766 }
   1767 
   1768 /*===========================================================================
   1769  * FUNCTION   : isTypeOf
   1770  *
   1771  * DESCRIPTION: helper function to determine if the stream is of the queried type
   1772  *
   1773  * PARAMETERS :
   1774  *   @type    : stream type as of queried
   1775  *
   1776  * RETURN     : true/false
   1777  *==========================================================================*/
   1778 bool QCameraStream::isTypeOf(cam_stream_type_t type)
   1779 {
   1780     if (mStreamInfo != NULL && (mStreamInfo->stream_type == type)) {
   1781         return true;
   1782     } else {
   1783         return false;
   1784     }
   1785 }
   1786 
   1787 /*===========================================================================
   1788  * FUNCTION   : isOrignalTypeOf
   1789  *
   1790  * DESCRIPTION: helper function to determine if the original stream is of the
   1791  *              queried type if it's reproc stream
   1792  *
   1793  * PARAMETERS :
   1794  *   @type    : stream type as of queried
   1795  *
   1796  * RETURN     : true/false
   1797  *==========================================================================*/
   1798 bool QCameraStream::isOrignalTypeOf(cam_stream_type_t type)
   1799 {
   1800     if (mStreamInfo != NULL &&
   1801         mStreamInfo->stream_type == CAM_STREAM_TYPE_OFFLINE_PROC &&
   1802         mStreamInfo->reprocess_config.pp_type == CAM_ONLINE_REPROCESS_TYPE &&
   1803         mStreamInfo->reprocess_config.online.input_stream_type == type) {
   1804         return true;
   1805     } else if (
   1806         mStreamInfo != NULL &&
   1807         mStreamInfo->stream_type == CAM_STREAM_TYPE_OFFLINE_PROC &&
   1808         mStreamInfo->reprocess_config.pp_type == CAM_OFFLINE_REPROCESS_TYPE &&
   1809         mStreamInfo->reprocess_config.offline.input_type == type) {
   1810         return true;
   1811     } else {
   1812         return false;
   1813     }
   1814 }
   1815 
   1816 /*===========================================================================
   1817  * FUNCTION   : getMyType
   1818  *
   1819  * DESCRIPTION: return stream type
   1820  *
   1821  * PARAMETERS : none
   1822  *
   1823  * RETURN     : stream type
   1824  *==========================================================================*/
   1825 cam_stream_type_t QCameraStream::getMyType()
   1826 {
   1827     if (mStreamInfo != NULL) {
   1828         return mStreamInfo->stream_type;
   1829     } else {
   1830         return CAM_STREAM_TYPE_DEFAULT;
   1831     }
   1832 }
   1833 
   1834 /*===========================================================================
   1835  * FUNCTION   : getMyOriginalType
   1836  *
   1837  * DESCRIPTION: return stream type
   1838  *
   1839  * PARAMETERS : none
   1840  *
   1841  * RETURN     : stream type
   1842  *==========================================================================*/
   1843 cam_stream_type_t QCameraStream::getMyOriginalType()
   1844 {
   1845     if (mStreamInfo != NULL) {
   1846         if (mStreamInfo->stream_type == CAM_STREAM_TYPE_OFFLINE_PROC &&
   1847                 mStreamInfo->reprocess_config.pp_type == CAM_ONLINE_REPROCESS_TYPE) {
   1848             return mStreamInfo->reprocess_config.online.input_stream_type;
   1849         } else if (mStreamInfo->stream_type == CAM_STREAM_TYPE_OFFLINE_PROC &&
   1850                 mStreamInfo->reprocess_config.pp_type == CAM_OFFLINE_REPROCESS_TYPE) {
   1851             return mStreamInfo->reprocess_config.offline.input_type;
   1852         } else {
   1853             return mStreamInfo->stream_type;
   1854         }
   1855     } else {
   1856         return CAM_STREAM_TYPE_DEFAULT;
   1857     }
   1858 }
   1859 
   1860 /*===========================================================================
   1861  * FUNCTION   : getFrameOffset
   1862  *
   1863  * DESCRIPTION: query stream buffer frame offset info
   1864  *
   1865  * PARAMETERS :
   1866  *   @offset  : reference to struct to store the queried frame offset info
   1867  *
   1868  * RETURN     : int32_t type of status
   1869  *              NO_ERROR  -- success
   1870  *              none-zero failure code
   1871  *==========================================================================*/
   1872 int32_t QCameraStream::getFrameOffset(cam_frame_len_offset_t &offset)
   1873 {
   1874     if (NULL == mStreamInfo) {
   1875         return NO_INIT;
   1876     }
   1877 
   1878     offset = mFrameLenOffset;
   1879     if ((ROTATE_90 == mOnlineRotation) || (ROTATE_270 == mOnlineRotation)) {
   1880         // Re-calculate frame offset in case of online rotation
   1881         cam_stream_info_t streamInfo = *mStreamInfo;
   1882         getFrameDimension(streamInfo.dim);
   1883         calcOffset(&streamInfo);
   1884         offset = streamInfo.buf_planes.plane_info;
   1885     }
   1886 
   1887     return 0;
   1888 }
   1889 
   1890 /*===========================================================================
   1891  * FUNCTION   : getCropInfo
   1892  *
   1893  * DESCRIPTION: query crop info of the stream
   1894  *
   1895  * PARAMETERS :
   1896  *   @crop    : reference to struct to store the queried crop info
   1897  *
   1898  * RETURN     : int32_t type of status
   1899  *              NO_ERROR  -- success
   1900  *              none-zero failure code
   1901  *==========================================================================*/
   1902 int32_t QCameraStream::getCropInfo(cam_rect_t &crop)
   1903 {
   1904     pthread_mutex_lock(&mCropLock);
   1905     crop = mCropInfo;
   1906     pthread_mutex_unlock(&mCropLock);
   1907     return NO_ERROR;
   1908 }
   1909 
   1910 /*===========================================================================
   1911  * FUNCTION   : setCropInfo
   1912  *
   1913  * DESCRIPTION: set crop info of the stream
   1914  *
   1915  * PARAMETERS :
   1916  *   @crop    : struct to store new crop info
   1917  *
   1918  * RETURN     : int32_t type of status
   1919  *              NO_ERROR  -- success
   1920  *              none-zero failure code
   1921  *==========================================================================*/
   1922 int32_t QCameraStream::setCropInfo(cam_rect_t crop)
   1923 {
   1924     pthread_mutex_lock(&mCropLock);
   1925     mCropInfo = crop;
   1926     pthread_mutex_unlock(&mCropLock);
   1927     return NO_ERROR;
   1928 }
   1929 
   1930 /*===========================================================================
   1931  * FUNCTION   : getFrameDimension
   1932  *
   1933  * DESCRIPTION: query stream frame dimension info
   1934  *
   1935  * PARAMETERS :
   1936  *   @dim     : reference to struct to store the queried frame dimension
   1937  *
   1938  * RETURN     : int32_t type of status
   1939  *              NO_ERROR  -- success
   1940  *              none-zero failure code
   1941  *==========================================================================*/
   1942 int32_t QCameraStream::getFrameDimension(cam_dimension_t &dim)
   1943 {
   1944     if (mStreamInfo != NULL) {
   1945         if ((ROTATE_90 == mOnlineRotation) || (ROTATE_270 == mOnlineRotation)) {
   1946             dim.width = mStreamInfo->dim.height;
   1947             dim.height = mStreamInfo->dim.width;
   1948         } else {
   1949             dim = mStreamInfo->dim;
   1950         }
   1951         return 0;
   1952     }
   1953     return -1;
   1954 }
   1955 
   1956 /*===========================================================================
   1957  * FUNCTION   : getFormat
   1958  *
   1959  * DESCRIPTION: query stream format
   1960  *
   1961  * PARAMETERS :
   1962  *   @fmt     : reference to stream format
   1963  *
   1964  * RETURN     : int32_t type of status
   1965  *              NO_ERROR  -- success
   1966  *              none-zero failure code
   1967  *==========================================================================*/
   1968 int32_t QCameraStream::getFormat(cam_format_t &fmt)
   1969 {
   1970     if (mStreamInfo != NULL) {
   1971         fmt = mStreamInfo->fmt;
   1972         return 0;
   1973     }
   1974     return -1;
   1975 }
   1976 
   1977 /*===========================================================================
   1978  * FUNCTION   : getMyServerID
   1979  *
   1980  * DESCRIPTION: query server stream ID
   1981  *
   1982  * PARAMETERS : None
   1983  *
   1984  * RETURN     : stream ID from server
   1985  *==========================================================================*/
   1986 uint32_t QCameraStream::getMyServerID() {
   1987     if (mStreamInfo != NULL) {
   1988         return mStreamInfo->stream_svr_id;
   1989     } else {
   1990         return 0;
   1991     }
   1992 }
   1993 
   1994 /*===========================================================================
   1995  * FUNCTION   : acquireStreamBufs
   1996  *
   1997  * DESCRIPTION: acquire stream buffers and postpone their release.
   1998  *
   1999  * PARAMETERS : None
   2000  *
   2001  * RETURN     : int32_t type of status
   2002  *              NO_ERROR  -- success
   2003  *              none-zero failure code
   2004  *==========================================================================*/
   2005 int32_t QCameraStream::acquireStreamBufs()
   2006 {
   2007     mStreamBufsAcquired = true;
   2008 
   2009     return NO_ERROR;
   2010 }
   2011 
   2012 /*===========================================================================
   2013  * FUNCTION   : mapBuf
   2014  *
   2015  * DESCRIPTION: map stream related buffer to backend server
   2016  *
   2017  * PARAMETERS :
   2018  *   @buf_type : mapping type of buffer
   2019  *   @buf_idx  : index of buffer
   2020  *   @plane_idx: plane index
   2021  *   @fd       : fd of the buffer
   2022  *   @size     : lenght of the buffer
   2023  *   @ops_tbl    : ptr to buf mapping/unmapping ops
   2024  *
   2025  * RETURN     : int32_t type of status
   2026  *              NO_ERROR  -- success
   2027  *              none-zero failure code
   2028  *==========================================================================*/
   2029 int32_t QCameraStream::mapBuf(uint8_t buf_type, uint32_t buf_idx,
   2030         int32_t plane_idx, int fd, size_t size, mm_camera_map_unmap_ops_tbl_t *ops_tbl)
   2031 {
   2032     if (ops_tbl != NULL) {
   2033         return ops_tbl->map_ops(buf_idx, plane_idx, fd,
   2034                 (uint32_t)size, (cam_mapping_buf_type)buf_type, ops_tbl->userdata);
   2035     } else {
   2036         return mCamOps->map_stream_buf(mCamHandle, mChannelHandle,
   2037                 mHandle, buf_type, buf_idx, plane_idx,
   2038                 fd, size);
   2039     }
   2040 
   2041 }
   2042 
   2043 /*===========================================================================
   2044  * FUNCTION   : unmapBuf
   2045  *
   2046  * DESCRIPTION: unmap stream related buffer to backend server
   2047  *
   2048  * PARAMETERS :
   2049  *   @buf_type : mapping type of buffer
   2050  *   @buf_idx  : index of buffer
   2051  *   @plane_idx: plane index
   2052  *   @ops_tbl    : ptr to buf mapping/unmapping ops
   2053  *
   2054  * RETURN     : int32_t type of status
   2055  *              NO_ERROR  -- success
   2056  *              none-zero failure code
   2057  *==========================================================================*/
   2058 int32_t QCameraStream::unmapBuf(uint8_t buf_type, uint32_t buf_idx, int32_t plane_idx,
   2059         mm_camera_map_unmap_ops_tbl_t *ops_tbl)
   2060 {
   2061     if (ops_tbl != NULL) {
   2062         return ops_tbl->unmap_ops(buf_idx, plane_idx,
   2063                 (cam_mapping_buf_type)buf_type, ops_tbl->userdata);
   2064     } else {
   2065         return mCamOps->unmap_stream_buf(mCamHandle, mChannelHandle,
   2066                 mHandle, buf_type, buf_idx, plane_idx);
   2067     }
   2068 }
   2069 
   2070 /*===========================================================================
   2071  * FUNCTION   : setParameter
   2072  *
   2073  * DESCRIPTION: set stream based parameters
   2074  *
   2075  * PARAMETERS :
   2076  *   @param   : ptr to parameters to be set
   2077  *
   2078  * RETURN     : int32_t type of status
   2079  *              NO_ERROR  -- success
   2080  *              none-zero failure code
   2081  *==========================================================================*/
   2082 int32_t QCameraStream::setParameter(cam_stream_parm_buffer_t &param)
   2083 {
   2084     int32_t rc = NO_ERROR;
   2085     pthread_mutex_lock(&mParameterLock);
   2086     mStreamInfo->parm_buf = param;
   2087     rc = mCamOps->set_stream_parms(mCamHandle,
   2088                                    mChannelHandle,
   2089                                    mHandle,
   2090                                    &mStreamInfo->parm_buf);
   2091     if (rc == NO_ERROR) {
   2092         param = mStreamInfo->parm_buf;
   2093     }
   2094     pthread_mutex_unlock(&mParameterLock);
   2095     return rc;
   2096 }
   2097 
   2098 /*===========================================================================
   2099  * FUNCTION   : getParameter
   2100  *
   2101  * DESCRIPTION: get stream based parameters
   2102  *
   2103  * PARAMETERS :
   2104  *   @param   : ptr to parameters to be red
   2105  *
   2106  * RETURN     : int32_t type of status
   2107  *              NO_ERROR  -- success
   2108  *              none-zero failure code
   2109  *==========================================================================*/
   2110 int32_t QCameraStream::getParameter(cam_stream_parm_buffer_t &param)
   2111 {
   2112     int32_t rc = NO_ERROR;
   2113     pthread_mutex_lock(&mParameterLock);
   2114     mStreamInfo->parm_buf = param;
   2115     rc = mCamOps->get_stream_parms(mCamHandle,
   2116                                    mChannelHandle,
   2117                                    mHandle,
   2118                                    &mStreamInfo->parm_buf);
   2119     if (rc == NO_ERROR) {
   2120         param = mStreamInfo->parm_buf;
   2121     }
   2122     pthread_mutex_unlock(&mParameterLock);
   2123     return rc;
   2124 }
   2125 
   2126 /*===========================================================================
   2127  * FUNCTION   : releaseFrameData
   2128  *
   2129  * DESCRIPTION: callback function to release frame data node
   2130  *
   2131  * PARAMETERS :
   2132  *   @data      : ptr to post process input data
   2133  *   @user_data : user data ptr (QCameraReprocessor)
   2134  *
   2135  * RETURN     : None
   2136  *==========================================================================*/
   2137 void QCameraStream::releaseFrameData(void *data, void *user_data)
   2138 {
   2139     QCameraStream *pme = (QCameraStream *)user_data;
   2140     mm_camera_super_buf_t *frame = (mm_camera_super_buf_t *)data;
   2141     if (NULL != pme) {
   2142         pme->bufDone(frame->bufs[0]->buf_idx);
   2143     }
   2144 }
   2145 
   2146 /*===========================================================================
   2147  * FUNCTION   : configStream
   2148  *
   2149  * DESCRIPTION: send stream configuration to back end
   2150  *
   2151  * PARAMETERS :
   2152  *
   2153  * RETURN     : int32_t type of status
   2154  *              NO_ERROR  -- success
   2155  *              none-zero failure code
   2156  *==========================================================================*/
   2157 int32_t QCameraStream::configStream()
   2158 {
   2159     int rc = NO_ERROR;
   2160 
   2161     // Configure the stream
   2162     mm_camera_stream_config_t stream_config;
   2163     stream_config.stream_info = mStreamInfo;
   2164     stream_config.mem_vtbl = mMemVtbl;
   2165     stream_config.stream_cb = dataNotifyCB;
   2166     stream_config.padding_info = mPaddingInfo;
   2167     stream_config.userdata = this;
   2168     rc = mCamOps->config_stream(mCamHandle,
   2169                 mChannelHandle, mHandle, &stream_config);
   2170     if (rc < 0) {
   2171         ALOGE("Failed to config stream, rc = %d", rc);
   2172         mCamOps->unmap_stream_buf(mCamHandle,
   2173                 mChannelHandle,
   2174                 mHandle,
   2175                 CAM_MAPPING_BUF_TYPE_STREAM_INFO,
   2176                 0,
   2177                 -1);
   2178         return UNKNOWN_ERROR;
   2179     }
   2180 
   2181     return rc;
   2182 }
   2183 
   2184 }; // namespace qcamera
   2185