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