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