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