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