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