QCameraStream.cpp revision a1724bc599bec5b2fbe3f4a34d0eca2406ba4c5f
1/* Copyright (c) 2012-2013, 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 "QCamera2HWI.h"
34#include "QCameraStream.h"
35
36namespace qcamera {
37
38/*===========================================================================
39 * FUNCTION   : get_bufs
40 *
41 * DESCRIPTION: static function entry to allocate stream buffers
42 *
43 * PARAMETERS :
44 *   @offset     : offset info of stream buffers
45 *   @num_bufs   : number of buffers allocated
46 *   @initial_reg_flag: flag to indicate if buffer needs to be registered
47 *                      at kernel initially
48 *   @bufs       : output of allocated buffers
49 *   @ops_tbl    : ptr to buf mapping/unmapping ops
50 *   @user_data  : user data ptr of ops_tbl
51 *
52 * RETURN     : int32_t type of status
53 *              NO_ERROR  -- success
54 *              none-zero failure code
55 *==========================================================================*/
56int32_t QCameraStream::get_bufs(
57                     cam_frame_len_offset_t *offset,
58                     uint8_t *num_bufs,
59                     uint8_t **initial_reg_flag,
60                     mm_camera_buf_def_t **bufs,
61                     mm_camera_map_unmap_ops_tbl_t *ops_tbl,
62                     void *user_data)
63{
64    QCameraStream *stream = reinterpret_cast<QCameraStream *>(user_data);
65    if (!stream) {
66        ALOGE("getBufs invalid stream pointer");
67        return NO_MEMORY;
68    }
69    return stream->getBufs(offset, num_bufs, initial_reg_flag, bufs, ops_tbl);
70}
71
72/*===========================================================================
73 * FUNCTION   : put_bufs
74 *
75 * DESCRIPTION: static function entry to deallocate stream buffers
76 *
77 * PARAMETERS :
78 *   @ops_tbl    : ptr to buf mapping/unmapping ops
79 *   @user_data  : user data ptr of ops_tbl
80 *
81 * RETURN     : int32_t type of status
82 *              NO_ERROR  -- success
83 *              none-zero failure code
84 *==========================================================================*/
85int32_t QCameraStream::put_bufs(
86                     mm_camera_map_unmap_ops_tbl_t *ops_tbl,
87                     void *user_data)
88{
89    QCameraStream *stream = reinterpret_cast<QCameraStream *>(user_data);
90    if (!stream) {
91        ALOGE("putBufs invalid stream pointer");
92        return NO_MEMORY;
93    }
94    return stream->putBufs(ops_tbl);
95}
96
97/*===========================================================================
98 * FUNCTION   : invalidate_buf
99 *
100 * DESCRIPTION: static function entry to invalidate a specific stream buffer
101 *
102 * PARAMETERS :
103 *   @index      : index of the stream buffer to invalidate
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 *==========================================================================*/
110int32_t QCameraStream::invalidate_buf(int index, void *user_data)
111{
112    QCameraStream *stream = reinterpret_cast<QCameraStream *>(user_data);
113    if (!stream) {
114        ALOGE("invalid stream pointer");
115        return NO_MEMORY;
116    }
117    return stream->invalidateBuf(index);
118}
119
120/*===========================================================================
121 * FUNCTION   : clean_invalidate_buf
122 *
123 * DESCRIPTION: static function entry to clean invalidate a specific stream buffer
124 *
125 * PARAMETERS :
126 *   @index      : index of the stream buffer to clean invalidate
127 *   @user_data  : user data ptr of ops_tbl
128 *
129 * RETURN     : int32_t type of status
130 *              NO_ERROR  -- success
131 *              none-zero failure code
132 *==========================================================================*/
133int32_t QCameraStream::clean_invalidate_buf(int index, void *user_data)
134{
135    QCameraStream *stream = reinterpret_cast<QCameraStream *>(user_data);
136    if (!stream) {
137        ALOGE("invalid stream pointer");
138        return NO_MEMORY;
139    }
140    return stream->cleanInvalidateBuf(index);
141}
142
143/*===========================================================================
144 * FUNCTION   : QCameraStream
145 *
146 * DESCRIPTION: constructor of QCameraStream
147 *
148 * PARAMETERS :
149 *   @allocator  : memory allocator obj
150 *   @camHandle  : camera handle
151 *   @chId       : channel handle
152 *   @camOps     : ptr to camera ops table
153 *   @paddingInfo: ptr to padding info
154 *
155 * RETURN     : None
156 *==========================================================================*/
157QCameraStream::QCameraStream(QCameraAllocator &allocator,
158                             uint32_t camHandle,
159                             uint32_t chId,
160                             mm_camera_ops_t *camOps,
161                             cam_padding_info_t *paddingInfo) :
162        mCamHandle(camHandle),
163        mChannelHandle(chId),
164        mHandle(0),
165        mCamOps(camOps),
166        mStreamInfo(NULL),
167        mNumBufs(0),
168        mDataCB(NULL),
169        mStreamInfoBuf(NULL),
170        mStreamBufs(NULL),
171        mAllocator(allocator),
172        mBufDefs(NULL)
173{
174    mMemVtbl.user_data = this;
175    mMemVtbl.get_bufs = get_bufs;
176    mMemVtbl.put_bufs = put_bufs;
177    mMemVtbl.invalidate_buf = invalidate_buf;
178    mMemVtbl.clean_invalidate_buf = clean_invalidate_buf;
179    memset(&mFrameLenOffset, 0, sizeof(mFrameLenOffset));
180    memcpy(&mPaddingInfo, paddingInfo, sizeof(cam_padding_info_t));
181    memset(&mCropInfo, 0, sizeof(cam_rect_t));
182    pthread_mutex_init(&mCropLock, NULL);
183}
184
185/*===========================================================================
186 * FUNCTION   : ~QCameraStream
187 *
188 * DESCRIPTION: deconstructor of QCameraStream
189 *
190 * PARAMETERS : None
191 *
192 * RETURN     : None
193 *==========================================================================*/
194QCameraStream::~QCameraStream()
195{
196    pthread_mutex_destroy(&mCropLock);
197
198    if (mStreamInfoBuf != NULL) {
199        int rc = mCamOps->unmap_stream_buf(mCamHandle,
200                    mChannelHandle, mHandle, CAM_MAPPING_BUF_TYPE_STREAM_INFO, 0, -1);
201        if (rc < 0) {
202            ALOGE("Failed to map stream info buffer");
203        }
204        mStreamInfoBuf->deallocate();
205        delete mStreamInfoBuf;
206        mStreamInfoBuf = NULL;
207    }
208
209    // delete stream
210    if (mHandle > 0) {
211        mCamOps->delete_stream(mCamHandle, mChannelHandle, mHandle);
212        mHandle = 0;
213    }
214}
215
216/*===========================================================================
217 * FUNCTION   : init
218 *
219 * DESCRIPTION: initialize stream obj
220 *
221 * PARAMETERS :
222 *   @streamInfoBuf: ptr to buf that contains stream info
223 *   @stream_cb    : stream data notify callback. Can be NULL if not needed
224 *   @userdata     : user data ptr
225 *
226 * RETURN     : int32_t type of status
227 *              NO_ERROR  -- success
228 *              none-zero failure code
229 *==========================================================================*/
230int32_t QCameraStream::init(QCameraHeapMemory *streamInfoBuf,
231                            uint8_t minNumBuffers,
232                            stream_cb_routine stream_cb,
233                            void *userdata)
234{
235    int32_t rc = OK;
236    mm_camera_stream_config_t stream_config;
237
238    mHandle = mCamOps->add_stream(mCamHandle, mChannelHandle);
239    if (!mHandle) {
240        ALOGE("add_stream failed");
241        rc = UNKNOWN_ERROR;
242        goto done;
243    }
244
245    // assign and map stream info memory
246    mStreamInfoBuf = streamInfoBuf;
247    mStreamInfo = reinterpret_cast<cam_stream_info_t *>(mStreamInfoBuf->getPtr(0));
248    mNumBufs = minNumBuffers;
249
250    rc = mCamOps->map_stream_buf(mCamHandle,
251                mChannelHandle, mHandle, CAM_MAPPING_BUF_TYPE_STREAM_INFO,
252                0, -1, mStreamInfoBuf->getFd(0), mStreamInfoBuf->getSize(0));
253    if (rc < 0) {
254        ALOGE("Failed to map stream info buffer");
255        goto err1;
256    }
257
258    // Configure the stream
259    stream_config.stream_info = mStreamInfo;
260    stream_config.mem_vtbl = mMemVtbl;
261    stream_config.stream_cb = dataNotifyCB;
262    stream_config.padding_info = mPaddingInfo;
263    stream_config.userdata = this;
264    rc = mCamOps->config_stream(mCamHandle,
265                mChannelHandle, mHandle, &stream_config);
266    if (rc < 0) {
267        ALOGE("Failed to config stream, rc = %d", rc);
268        goto err2;
269    }
270
271    mDataCB = stream_cb;
272    mUserData = userdata;
273    return 0;
274
275err2:
276    mCamOps->unmap_stream_buf(mCamHandle,
277                mChannelHandle, mHandle, CAM_MAPPING_BUF_TYPE_STREAM_INFO, 0, -1);
278err1:
279    mCamOps->delete_stream(mCamHandle, mChannelHandle, mHandle);
280    mHandle = 0;
281    mStreamInfoBuf = NULL;
282    mStreamInfo = NULL;
283    mNumBufs = 0;
284done:
285    return rc;
286}
287
288/*===========================================================================
289 * FUNCTION   : start
290 *
291 * DESCRIPTION: start stream. Will start main stream thread to handle stream
292 *              related ops.
293 *
294 * PARAMETERS : none
295 *
296 * RETURN     : int32_t type of status
297 *              NO_ERROR  -- success
298 *              none-zero failure code
299 *==========================================================================*/
300int32_t QCameraStream::start()
301{
302    int32_t rc = 0;
303    rc = mProcTh.launch(dataProcRoutine, this);
304    return rc;
305}
306
307/*===========================================================================
308 * FUNCTION   : stop
309 *
310 * DESCRIPTION: stop stream. Will stop main stream thread
311 *
312 * PARAMETERS : none
313 *
314 * RETURN     : int32_t type of status
315 *              NO_ERROR  -- success
316 *              none-zero failure code
317 *==========================================================================*/
318int32_t QCameraStream::stop()
319{
320    int32_t rc = 0;
321    rc = mProcTh.exit();
322    return rc;
323}
324
325/*===========================================================================
326 * FUNCTION   : processZoomDone
327 *
328 * DESCRIPTION: process zoom done event
329 *
330 * PARAMETERS :
331 *   @previewWindoe : preview window ops table to set preview crop window
332 *   @crop_info     : crop info
333 *
334 * RETURN     : int32_t type of status
335 *              NO_ERROR  -- success
336 *              none-zero failure code
337 *==========================================================================*/
338int32_t QCameraStream::processZoomDone(preview_stream_ops_t *previewWindow,
339                                       cam_crop_data_t &crop_info)
340{
341    int32_t rc = 0;
342
343    // get stream param for crop info
344    for (int i = 0; i < crop_info.num_of_streams; i++) {
345        if (crop_info.crop_info[i].stream_id == mStreamInfo->stream_svr_id) {
346            pthread_mutex_lock(&mCropLock);
347            mCropInfo = crop_info.crop_info[i].crop;
348            pthread_mutex_unlock(&mCropLock);
349
350            // update preview window crop if it's preview/postview stream
351            if ( (previewWindow != NULL) &&
352                 (mStreamInfo->stream_type == CAM_STREAM_TYPE_PREVIEW ||
353                  mStreamInfo->stream_type == CAM_STREAM_TYPE_POSTVIEW) ) {
354                rc = previewWindow->set_crop(previewWindow,
355                                             mCropInfo.left,
356                                             mCropInfo.top,
357                                             mCropInfo.width,
358                                             mCropInfo.height);
359            }
360            break;
361        }
362    }
363    return rc;
364}
365
366/*===========================================================================
367 * FUNCTION   : processDataNotify
368 *
369 * DESCRIPTION: process stream data notify
370 *
371 * PARAMETERS :
372 *   @frame   : stream frame received
373 *
374 * RETURN     : int32_t type of status
375 *              NO_ERROR  -- success
376 *              none-zero failure code
377 *==========================================================================*/
378int32_t QCameraStream::processDataNotify(mm_camera_super_buf_t *frame)
379{
380    ALOGI("%s:\n", __func__);
381    mDataQ.enqueue((void *)frame);
382    return mProcTh.sendCmd(CAMERA_CMD_TYPE_DO_NEXT_JOB, FALSE, FALSE);
383}
384
385/*===========================================================================
386 * FUNCTION   : dataNotifyCB
387 *
388 * DESCRIPTION: callback for data notify. This function is registered with
389 *              mm-camera-interface to handle data notify
390 *
391 * PARAMETERS :
392 *   @recvd_frame   : stream frame received
393 *   userdata       : user data ptr
394 *
395 * RETURN     : none
396 *==========================================================================*/
397void QCameraStream::dataNotifyCB(mm_camera_super_buf_t *recvd_frame,
398                                 void *userdata)
399{
400    ALOGI("%s:\n", __func__);
401    QCameraStream* stream = (QCameraStream *)userdata;
402    if (stream == NULL ||
403        recvd_frame == NULL ||
404        recvd_frame->bufs[0] == NULL ||
405        recvd_frame->bufs[0]->stream_id != stream->getMyHandle()) {
406        ALOGE("%s: Not a valid stream to handle buf", __func__);
407        return;
408    }
409
410    mm_camera_super_buf_t *frame =
411        (mm_camera_super_buf_t *)malloc(sizeof(mm_camera_super_buf_t));
412    if (frame == NULL) {
413        ALOGE("%s: No mem for mm_camera_buf_def_t", __func__);
414        stream->bufDone(recvd_frame->bufs[0]->buf_idx);
415        return;
416    }
417    *frame = *recvd_frame;
418    stream->processDataNotify(frame);
419    return;
420}
421
422/*===========================================================================
423 * FUNCTION   : dataProcRoutine
424 *
425 * DESCRIPTION: function to process data in the main stream thread
426 *
427 * PARAMETERS :
428 *   @data    : user data ptr
429 *
430 * RETURN     : none
431 *==========================================================================*/
432void *QCameraStream::dataProcRoutine(void *data)
433{
434    int running = 1;
435    int ret;
436    QCameraStream *pme = (QCameraStream *)data;
437    QCameraCmdThread *cmdThread = &pme->mProcTh;
438
439    ALOGI("%s: E", __func__);
440    do {
441        do {
442            ret = cam_sem_wait(&cmdThread->cmd_sem);
443            if (ret != 0 && errno != EINVAL) {
444                ALOGE("%s: cam_sem_wait error (%s)",
445                      __func__, strerror(errno));
446                return NULL;
447            }
448        } while (ret != 0);
449
450        // we got notified about new cmd avail in cmd queue
451        camera_cmd_type_t cmd = cmdThread->getCmd();
452        switch (cmd) {
453        case CAMERA_CMD_TYPE_DO_NEXT_JOB:
454            {
455                ALOGD("%s: Do next job", __func__);
456                mm_camera_super_buf_t *frame =
457                    (mm_camera_super_buf_t *)pme->mDataQ.dequeue();
458                if (NULL != frame) {
459                    if (pme->mDataCB != NULL) {
460                        pme->mDataCB(frame, pme, pme->mUserData);
461                    } else {
462                        // no data cb routine, return buf here
463                        pme->bufDone(frame->bufs[0]->buf_idx);
464                        free(frame);
465                    }
466                }
467            }
468            break;
469        case CAMERA_CMD_TYPE_EXIT:
470            ALOGD("%s: Exit", __func__);
471            /* flush data buf queue */
472            pme->mDataQ.flush();
473            running = 0;
474            break;
475        default:
476            break;
477        }
478    } while (running);
479    ALOGD("%s: X", __func__);
480    return NULL;
481}
482
483/*===========================================================================
484 * FUNCTION   : bufDone
485 *
486 * DESCRIPTION: return stream buffer to kernel
487 *
488 * PARAMETERS :
489 *   @index   : index of buffer to be returned
490 *
491 * RETURN     : int32_t type of status
492 *              NO_ERROR  -- success
493 *              none-zero failure code
494 *==========================================================================*/
495int32_t QCameraStream::bufDone(int index)
496{
497    int32_t rc = NO_ERROR;
498
499    if (index >= mNumBufs || mBufDefs == NULL)
500        return BAD_INDEX;
501
502    rc = mCamOps->qbuf(mCamHandle, mChannelHandle, &mBufDefs[index]);
503    if (rc < 0)
504        return rc;
505
506    return rc;
507}
508
509/*===========================================================================
510 * FUNCTION   : bufDone
511 *
512 * DESCRIPTION: return stream buffer to kernel
513 *
514 * PARAMETERS :
515 *   @opaque    : stream frame/metadata buf to be returned
516 *   @isMetaData: flag if returned opaque is a metadatabuf or the real frame ptr
517 *
518 * RETURN     : int32_t type of status
519 *              NO_ERROR  -- success
520 *              none-zero failure code
521 *==========================================================================*/
522int32_t QCameraStream::bufDone(const void *opaque, bool isMetaData)
523{
524    int32_t rc = NO_ERROR;
525
526    int index = mStreamBufs->getMatchBufIndex(opaque, isMetaData);
527    if (index == -1 || index >= mNumBufs) {
528        ALOGE("%s: Cannot find buf for opaque data = %p", __func__, opaque);
529        return BAD_INDEX;
530    }
531
532    rc = bufDone(index);
533    return rc;
534}
535
536/*===========================================================================
537 * FUNCTION   : getBufs
538 *
539 * DESCRIPTION: allocate stream buffers
540 *
541 * PARAMETERS :
542 *   @offset     : offset info of stream buffers
543 *   @num_bufs   : number of buffers allocated
544 *   @initial_reg_flag: flag to indicate if buffer needs to be registered
545 *                      at kernel initially
546 *   @bufs       : output of allocated buffers
547 *   @ops_tbl    : ptr to buf mapping/unmapping ops
548 *
549 * RETURN     : int32_t type of status
550 *              NO_ERROR  -- success
551 *              none-zero failure code
552 *==========================================================================*/
553int32_t QCameraStream::getBufs(cam_frame_len_offset_t *offset,
554                     uint8_t *num_bufs,
555                     uint8_t **initial_reg_flag,
556                     mm_camera_buf_def_t **bufs,
557                     mm_camera_map_unmap_ops_tbl_t *ops_tbl)
558{
559    int rc = NO_ERROR;
560    uint8_t *regFlags;
561
562    if (!ops_tbl) {
563        ALOGE("%s: ops_tbl is NULL", __func__);
564        return INVALID_OPERATION;
565    }
566
567    mFrameLenOffset = *offset;
568
569    //Allocate and map stream info buffer
570    mStreamBufs = mAllocator.allocateStreamBuf(mStreamInfo->stream_type,
571                                               mFrameLenOffset.frame_len,
572                                               mNumBufs);
573    if (!mStreamBufs) {
574        ALOGE("%s: Failed to allocate stream buffers", __func__);
575        return NO_MEMORY;
576    }
577
578    for (int i = 0; i < mNumBufs; i++) {
579        rc = ops_tbl->map_ops(i, -1, mStreamBufs->getFd(i),
580                mStreamBufs->getSize(i), ops_tbl->userdata);
581        if (rc < 0) {
582            ALOGE("%s: map_stream_buf failed: %d", __func__, rc);
583            for (int j = 0; j < i; j++) {
584                ops_tbl->unmap_ops(j, -1, ops_tbl->userdata);
585            }
586            mStreamBufs->deallocate();
587            delete mStreamBufs;
588            mStreamBufs = NULL;
589            return INVALID_OPERATION;
590        }
591    }
592
593    //regFlags array is allocated by us, but consumed and freed by mm-camera-interface
594    regFlags = (uint8_t *)malloc(sizeof(uint8_t) * mNumBufs);
595    if (!regFlags) {
596        ALOGE("%s: Out of memory", __func__);
597        for (int i = 0; i < mNumBufs; i++) {
598            ops_tbl->unmap_ops(i, -1, ops_tbl->userdata);
599        }
600        mStreamBufs->deallocate();
601        delete mStreamBufs;
602        mStreamBufs = NULL;
603        return NO_MEMORY;
604    }
605
606    mBufDefs = (mm_camera_buf_def_t *)malloc(mNumBufs * sizeof(mm_camera_buf_def_t));
607    if (mBufDefs == NULL) {
608        ALOGE("%s: getRegFlags failed %d", __func__, rc);
609        for (int i = 0; i < mNumBufs; i++) {
610            ops_tbl->unmap_ops(i, -1, ops_tbl->userdata);
611        }
612        mStreamBufs->deallocate();
613        delete mStreamBufs;
614        mStreamBufs = NULL;
615        free(regFlags);
616        regFlags = NULL;
617        return INVALID_OPERATION;
618    }
619    for (int i = 0; i < mNumBufs; i++) {
620        mStreamBufs->getBufDef(mFrameLenOffset, mBufDefs[i], i);
621    }
622
623    rc = mStreamBufs->getRegFlags(regFlags);
624    if (rc < 0) {
625        ALOGE("%s: getRegFlags failed %d", __func__, rc);
626        for (int i = 0; i < mNumBufs; i++) {
627            ops_tbl->unmap_ops(i, -1, ops_tbl->userdata);
628        }
629        mStreamBufs->deallocate();
630        delete mStreamBufs;
631        mStreamBufs = NULL;
632        free(mBufDefs);
633        mBufDefs = NULL;
634        free(regFlags);
635        regFlags = NULL;
636        return INVALID_OPERATION;
637    }
638
639    *num_bufs = mNumBufs;
640    *initial_reg_flag = regFlags;
641    *bufs = mBufDefs;
642    return NO_ERROR;
643}
644
645/*===========================================================================
646 * FUNCTION   : putBufs
647 *
648 * DESCRIPTION: deallocate stream buffers
649 *
650 * PARAMETERS :
651 *   @ops_tbl    : ptr to buf mapping/unmapping ops
652 *
653 * RETURN     : int32_t type of status
654 *              NO_ERROR  -- success
655 *              none-zero failure code
656 *==========================================================================*/
657int32_t QCameraStream::putBufs(mm_camera_map_unmap_ops_tbl_t *ops_tbl)
658{
659    int rc = NO_ERROR;
660    for (int i = 0; i < mNumBufs; i++) {
661        rc = ops_tbl->unmap_ops(i, -1, ops_tbl->userdata);
662        if (rc < 0) {
663            ALOGE("%s: map_stream_buf failed: %d", __func__, rc);
664        }
665    }
666    mBufDefs = NULL; // mBufDefs just keep a ptr to the buffer
667                     // mm-camera-interface own the buffer, so no need to free
668    memset(&mFrameLenOffset, 0, sizeof(mFrameLenOffset));
669    mStreamBufs->deallocate();
670    delete mStreamBufs;
671
672    return rc;
673}
674
675/*===========================================================================
676 * FUNCTION   : invalidateBuf
677 *
678 * DESCRIPTION: invalidate a specific stream buffer
679 *
680 * PARAMETERS :
681 *   @index   : index of the buffer to invalidate
682 *
683 * RETURN     : int32_t type of status
684 *              NO_ERROR  -- success
685 *              none-zero failure code
686 *==========================================================================*/
687int32_t QCameraStream::invalidateBuf(int index)
688{
689    return mStreamBufs->invalidateCache(index);
690}
691
692/*===========================================================================
693 * FUNCTION   : cleanInvalidateBuf
694 *
695 * DESCRIPTION: clean invalidate a specific stream buffer
696 *
697 * PARAMETERS :
698 *   @index   : index of the buffer to clean invalidate
699 *
700 * RETURN     : int32_t type of status
701 *              NO_ERROR  -- success
702 *              none-zero failure code
703 *==========================================================================*/
704int32_t QCameraStream::cleanInvalidateBuf(int index)
705{
706    return mStreamBufs->cleanInvalidateCache(index);
707}
708
709/*===========================================================================
710 * FUNCTION   : isTypeOf
711 *
712 * DESCRIPTION: helper function to determine if the stream is of the queried type
713 *
714 * PARAMETERS :
715 *   @type    : stream type as of queried
716 *
717 * RETURN     : true/false
718 *==========================================================================*/
719bool QCameraStream::isTypeOf(cam_stream_type_t type)
720{
721    if (mStreamInfo != NULL && (mStreamInfo->stream_type == type)) {
722        return true;
723    } else {
724        return false;
725    }
726}
727
728/*===========================================================================
729 * FUNCTION   : getMyType
730 *
731 * DESCRIPTION: return stream type
732 *
733 * PARAMETERS : none
734 *
735 * RETURN     : stream type
736 *==========================================================================*/
737cam_stream_type_t QCameraStream::getMyType()
738{
739    if (mStreamInfo != NULL) {
740        return mStreamInfo->stream_type;
741    } else {
742        return CAM_STREAM_TYPE_DEFAULT;
743    }
744}
745
746/*===========================================================================
747 * FUNCTION   : getFrameOffset
748 *
749 * DESCRIPTION: query stream buffer frame offset info
750 *
751 * PARAMETERS :
752 *   @offset  : reference to struct to store the queried frame offset info
753 *
754 * RETURN     : int32_t type of status
755 *              NO_ERROR  -- success
756 *              none-zero failure code
757 *==========================================================================*/
758int32_t QCameraStream::getFrameOffset(cam_frame_len_offset_t &offset)
759{
760    offset = mFrameLenOffset;
761    return 0;
762}
763
764/*===========================================================================
765 * FUNCTION   : getCropInfo
766 *
767 * DESCRIPTION: query crop info of the stream
768 *
769 * PARAMETERS :
770 *   @crop    : reference to struct to store the queried crop info
771 *
772 * RETURN     : int32_t type of status
773 *              NO_ERROR  -- success
774 *              none-zero failure code
775 *==========================================================================*/
776int32_t QCameraStream::getCropInfo(cam_rect_t &crop)
777{
778    pthread_mutex_lock(&mCropLock);
779    crop = mCropInfo;
780    pthread_mutex_unlock(&mCropLock);
781    return NO_ERROR;
782}
783
784/*===========================================================================
785 * FUNCTION   : getFrameDimension
786 *
787 * DESCRIPTION: query stream frame dimension info
788 *
789 * PARAMETERS :
790 *   @dim     : reference to struct to store the queried frame dimension
791 *
792 * RETURN     : int32_t type of status
793 *              NO_ERROR  -- success
794 *              none-zero failure code
795 *==========================================================================*/
796int32_t QCameraStream::getFrameDimension(cam_dimension_t &dim)
797{
798    if (mStreamInfo != NULL) {
799        dim = mStreamInfo->dim;
800        return 0;
801    }
802    return -1;
803}
804
805/*===========================================================================
806 * FUNCTION   : getFormat
807 *
808 * DESCRIPTION: query stream format
809 *
810 * PARAMETERS :
811 *   @fmt     : reference to stream format
812 *
813 * RETURN     : int32_t type of status
814 *              NO_ERROR  -- success
815 *              none-zero failure code
816 *==========================================================================*/
817int32_t QCameraStream::getFormat(cam_format_t &fmt)
818{
819    if (mStreamInfo != NULL) {
820        fmt = mStreamInfo->fmt;
821        return 0;
822    }
823    return -1;
824}
825
826/*===========================================================================
827 * FUNCTION   : getMyServerID
828 *
829 * DESCRIPTION: query server stream ID
830 *
831 * PARAMETERS : None
832 *
833 * RETURN     : stream ID from server
834 *==========================================================================*/
835uint32_t QCameraStream::getMyServerID() {
836    if (mStreamInfo != NULL) {
837        return mStreamInfo->stream_svr_id;
838    } else {
839        return 0;
840    }
841}
842
843/*===========================================================================
844 * FUNCTION   : mapBuf
845 *
846 * DESCRIPTION: map stream related buffer to backend server
847 *
848 * PARAMETERS :
849 *   @buf_type : mapping type of buffer
850 *   @buf_idx  : index of buffer
851 *   @plane_idx: plane index
852 *   @fd       : fd of the buffer
853 *   @size     : lenght of the buffer
854 *
855 * RETURN     : int32_t type of status
856 *              NO_ERROR  -- success
857 *              none-zero failure code
858 *==========================================================================*/
859int32_t QCameraStream::mapBuf(uint8_t buf_type,
860                              uint32_t buf_idx,
861                              int32_t plane_idx,
862                              int fd,
863                              uint32_t size)
864{
865    return mCamOps->map_stream_buf(mCamHandle, mChannelHandle,
866                                   mHandle, buf_type,
867                                   buf_idx, plane_idx,
868                                   fd, size);
869
870}
871
872/*===========================================================================
873 * FUNCTION   : unmapBuf
874 *
875 * DESCRIPTION: unmap stream related buffer to backend server
876 *
877 * PARAMETERS :
878 *   @buf_type : mapping type of buffer
879 *   @buf_idx  : index of buffer
880 *   @plane_idx: plane index
881 *
882 * RETURN     : int32_t type of status
883 *              NO_ERROR  -- success
884 *              none-zero failure code
885 *==========================================================================*/
886int32_t QCameraStream::unmapBuf(uint8_t buf_type, uint32_t buf_idx, int32_t plane_idx)
887{
888    return mCamOps->unmap_stream_buf(mCamHandle, mChannelHandle,
889                                     mHandle, buf_type,
890                                     buf_idx, plane_idx);
891
892}
893
894/*===========================================================================
895 * FUNCTION   : setParameter
896 *
897 * DESCRIPTION: set stream based parameters
898 *
899 * PARAMETERS :
900 *   @param   : ptr to parameters to be set
901 *
902 * RETURN     : int32_t type of status
903 *              NO_ERROR  -- success
904 *              none-zero failure code
905 *==========================================================================*/
906int32_t QCameraStream::setParameter(cam_stream_parm_buffer_t &param)
907{
908    int32_t rc = NO_ERROR;
909    mStreamInfo->parm_buf = param;
910    rc = mCamOps->set_stream_parms(mCamHandle,
911                                   mChannelHandle,
912                                   mHandle,
913                                   &mStreamInfo->parm_buf);
914    if (rc == NO_ERROR) {
915        param = mStreamInfo->parm_buf;
916    }
917    return rc;
918}
919
920}; // namespace qcamera
921