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         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  *==========================================================================*/
~QCamera3Stream()200 QCamera3Stream::~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  *==========================================================================*/
init(cam_stream_type_t streamType,cam_format_t streamFormat,cam_dimension_t streamDim,cam_stream_reproc_config_t * reprocess_config,uint8_t minNumBuffers,uint32_t postprocess_mask,cam_is_type_t is_type,hal3_stream_cb_routine stream_cb,void * userdata)234 int32_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 
316 err4:
317     mCamOps->unmap_stream_buf(mCamHandle,
318             mChannelHandle, mHandle, CAM_MAPPING_BUF_TYPE_STREAM_INFO, 0, -1);
319 err3:
320     mStreamInfoBuf->deallocate();
321 err2:
322     delete mStreamInfoBuf;
323     mStreamInfoBuf = NULL;
324     mStreamInfo = NULL;
325 err1:
326     mCamOps->delete_stream(mCamHandle, mChannelHandle, mHandle);
327     mHandle = 0;
328     mNumBufs = 0;
329 done:
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  *==========================================================================*/
start()345 int32_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  *==========================================================================*/
stop()365 int32_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  *==========================================================================*/
processDataNotify(mm_camera_super_buf_t * frame)384 int32_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  *==========================================================================*/
dataNotifyCB(mm_camera_super_buf_t * recvd_frame,void * userdata)412 void 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  *==========================================================================*/
dataProcRoutine(void * data)447 void *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  *==========================================================================*/
getInternalFormatBuffer(int index)510 mm_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  *==========================================================================*/
bufDone(int index)540 int32_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  *==========================================================================*/
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)592 int32_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  *==========================================================================*/
putBufs(mm_camera_map_unmap_ops_tbl_t * ops_tbl)685 int32_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  *==========================================================================*/
invalidateBuf(int index)716 int32_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  *==========================================================================*/
cleanInvalidateBuf(int index)733 int32_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  *==========================================================================*/
getFrameOffset(cam_frame_len_offset_t & offset)750 int32_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  *==========================================================================*/
getFrameDimension(cam_dimension_t & dim)768 int32_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  *==========================================================================*/
getFormat(cam_format_t & fmt)789 int32_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  *==========================================================================*/
getMyServerID()807 uint32_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  *==========================================================================*/
getMyType() const824 cam_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  *==========================================================================*/
mapBuf(uint8_t buf_type,uint32_t buf_idx,int32_t plane_idx,int fd,uint32_t size)849 int32_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  *==========================================================================*/
unmapBuf(uint8_t buf_type,uint32_t buf_idx,int32_t plane_idx)876 int32_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  *==========================================================================*/
setParameter(cam_stream_parm_buffer_t & param)895 int32_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  *==========================================================================*/
releaseFrameData(void * data,void * user_data)920 void 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