1 /* Copyright (c) 2012-2013, The Linux Foundataion. All rights reserved.
2 *
3 * Redistribution and use in source and binary forms, with or without
4 * modification, are permitted provided that the following conditions are
5 * met:
6 *     * Redistributions of source code must retain the above copyright
7 *       notice, this list of conditions and the following disclaimer.
8 *     * Redistributions in binary form must reproduce the above
9 *       copyright notice, this list of conditions and the following
10 *       disclaimer in the documentation and/or other materials provided
11 *       with the distribution.
12 *     * Neither the name of The Linux Foundation nor the names of its
13 *       contributors may be used to endorse or promote products derived
14 *       from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
19 * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
23 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
25 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
26 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 *
28 */
29 
30 #define LOG_TAG "QCameraStream"
31 
32 #include <utils/Errors.h>
33 #include "QCamera2HWI.h"
34 #include "QCameraStream.h"
35 
36 namespace qcamera {
37 
38 /*===========================================================================
39  * FUNCTION   : get_bufs
40  *
41  * DESCRIPTION: static function entry to allocate stream buffers
42  *
43  * PARAMETERS :
44  *   @offset     : offset info of stream buffers
45  *   @num_bufs   : number of buffers allocated
46  *   @initial_reg_flag: flag to indicate if buffer needs to be registered
47  *                      at kernel initially
48  *   @bufs       : output of allocated buffers
49  *   @ops_tbl    : ptr to buf mapping/unmapping ops
50  *   @user_data  : user data ptr of ops_tbl
51  *
52  * RETURN     : int32_t type of status
53  *              NO_ERROR  -- success
54  *              none-zero failure code
55  *==========================================================================*/
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)56 int32_t QCameraStream::get_bufs(
57                      cam_frame_len_offset_t *offset,
58                      uint8_t *num_bufs,
59                      uint8_t **initial_reg_flag,
60                      mm_camera_buf_def_t **bufs,
61                      mm_camera_map_unmap_ops_tbl_t *ops_tbl,
62                      void *user_data)
63 {
64     QCameraStream *stream = reinterpret_cast<QCameraStream *>(user_data);
65     if (!stream) {
66         ALOGE("getBufs invalid stream pointer");
67         return NO_MEMORY;
68     }
69     return stream->getBufs(offset, num_bufs, initial_reg_flag, bufs, ops_tbl);
70 }
71 
72 /*===========================================================================
73  * FUNCTION   : put_bufs
74  *
75  * DESCRIPTION: static function entry to deallocate stream buffers
76  *
77  * PARAMETERS :
78  *   @ops_tbl    : ptr to buf mapping/unmapping ops
79  *   @user_data  : user data ptr of ops_tbl
80  *
81  * RETURN     : int32_t type of status
82  *              NO_ERROR  -- success
83  *              none-zero failure code
84  *==========================================================================*/
put_bufs(mm_camera_map_unmap_ops_tbl_t * ops_tbl,void * user_data)85 int32_t QCameraStream::put_bufs(
86                      mm_camera_map_unmap_ops_tbl_t *ops_tbl,
87                      void *user_data)
88 {
89     QCameraStream *stream = reinterpret_cast<QCameraStream *>(user_data);
90     if (!stream) {
91         ALOGE("putBufs invalid stream pointer");
92         return NO_MEMORY;
93     }
94     return stream->putBufs(ops_tbl);
95 }
96 
97 /*===========================================================================
98  * FUNCTION   : invalidate_buf
99  *
100  * DESCRIPTION: static function entry to invalidate a specific stream buffer
101  *
102  * PARAMETERS :
103  *   @index      : index of the stream buffer to invalidate
104  *   @user_data  : user data ptr of ops_tbl
105  *
106  * RETURN     : int32_t type of status
107  *              NO_ERROR  -- success
108  *              none-zero failure code
109  *==========================================================================*/
invalidate_buf(int index,void * user_data)110 int32_t QCameraStream::invalidate_buf(int index, void *user_data)
111 {
112     QCameraStream *stream = reinterpret_cast<QCameraStream *>(user_data);
113     if (!stream) {
114         ALOGE("invalid stream pointer");
115         return NO_MEMORY;
116     }
117     return stream->invalidateBuf(index);
118 }
119 
120 /*===========================================================================
121  * FUNCTION   : clean_invalidate_buf
122  *
123  * DESCRIPTION: static function entry to clean invalidate a specific stream buffer
124  *
125  * PARAMETERS :
126  *   @index      : index of the stream buffer to clean invalidate
127  *   @user_data  : user data ptr of ops_tbl
128  *
129  * RETURN     : int32_t type of status
130  *              NO_ERROR  -- success
131  *              none-zero failure code
132  *==========================================================================*/
clean_invalidate_buf(int index,void * user_data)133 int32_t QCameraStream::clean_invalidate_buf(int index, void *user_data)
134 {
135     QCameraStream *stream = reinterpret_cast<QCameraStream *>(user_data);
136     if (!stream) {
137         ALOGE("invalid stream pointer");
138         return NO_MEMORY;
139     }
140     return stream->cleanInvalidateBuf(index);
141 }
142 
143 /*===========================================================================
144  * FUNCTION   : QCameraStream
145  *
146  * DESCRIPTION: constructor of QCameraStream
147  *
148  * PARAMETERS :
149  *   @allocator  : memory allocator obj
150  *   @camHandle  : camera handle
151  *   @chId       : channel handle
152  *   @camOps     : ptr to camera ops table
153  *   @paddingInfo: ptr to padding info
154  *
155  * RETURN     : None
156  *==========================================================================*/
QCameraStream(QCameraAllocator & allocator,uint32_t camHandle,uint32_t chId,mm_camera_ops_t * camOps,cam_padding_info_t * paddingInfo)157 QCameraStream::QCameraStream(QCameraAllocator &allocator,
158                              uint32_t camHandle,
159                              uint32_t chId,
160                              mm_camera_ops_t *camOps,
161                              cam_padding_info_t *paddingInfo) :
162         mCamHandle(camHandle),
163         mChannelHandle(chId),
164         mHandle(0),
165         mCamOps(camOps),
166         mStreamInfo(NULL),
167         mNumBufs(0),
168         mDataCB(NULL),
169         mStreamInfoBuf(NULL),
170         mStreamBufs(NULL),
171         mAllocator(allocator),
172         mBufDefs(NULL)
173 {
174     mMemVtbl.user_data = this;
175     mMemVtbl.get_bufs = get_bufs;
176     mMemVtbl.put_bufs = put_bufs;
177     mMemVtbl.invalidate_buf = invalidate_buf;
178     mMemVtbl.clean_invalidate_buf = clean_invalidate_buf;
179     memset(&mFrameLenOffset, 0, sizeof(mFrameLenOffset));
180     memcpy(&mPaddingInfo, paddingInfo, sizeof(cam_padding_info_t));
181     memset(&mCropInfo, 0, sizeof(cam_rect_t));
182     pthread_mutex_init(&mCropLock, NULL);
183 }
184 
185 /*===========================================================================
186  * FUNCTION   : ~QCameraStream
187  *
188  * DESCRIPTION: deconstructor of QCameraStream
189  *
190  * PARAMETERS : None
191  *
192  * RETURN     : None
193  *==========================================================================*/
~QCameraStream()194 QCameraStream::~QCameraStream()
195 {
196     pthread_mutex_destroy(&mCropLock);
197 
198     if (mStreamInfoBuf != NULL) {
199         int rc = mCamOps->unmap_stream_buf(mCamHandle,
200                     mChannelHandle, mHandle, CAM_MAPPING_BUF_TYPE_STREAM_INFO, 0, -1);
201         if (rc < 0) {
202             ALOGE("Failed to map stream info buffer");
203         }
204         mStreamInfoBuf->deallocate();
205         delete mStreamInfoBuf;
206         mStreamInfoBuf = NULL;
207     }
208 
209     // delete stream
210     if (mHandle > 0) {
211         mCamOps->delete_stream(mCamHandle, mChannelHandle, mHandle);
212         mHandle = 0;
213     }
214 }
215 
216 /*===========================================================================
217  * FUNCTION   : init
218  *
219  * DESCRIPTION: initialize stream obj
220  *
221  * PARAMETERS :
222  *   @streamInfoBuf: ptr to buf that contains stream info
223  *   @stream_cb    : stream data notify callback. Can be NULL if not needed
224  *   @userdata     : user data ptr
225  *
226  * RETURN     : int32_t type of status
227  *              NO_ERROR  -- success
228  *              none-zero failure code
229  *==========================================================================*/
init(QCameraHeapMemory * streamInfoBuf,uint8_t minNumBuffers,stream_cb_routine stream_cb,void * userdata)230 int32_t QCameraStream::init(QCameraHeapMemory *streamInfoBuf,
231                             uint8_t minNumBuffers,
232                             stream_cb_routine stream_cb,
233                             void *userdata)
234 {
235     int32_t rc = OK;
236     mm_camera_stream_config_t stream_config;
237 
238     mHandle = mCamOps->add_stream(mCamHandle, mChannelHandle);
239     if (!mHandle) {
240         ALOGE("add_stream failed");
241         rc = UNKNOWN_ERROR;
242         goto done;
243     }
244 
245     // assign and map stream info memory
246     mStreamInfoBuf = streamInfoBuf;
247     mStreamInfo = reinterpret_cast<cam_stream_info_t *>(mStreamInfoBuf->getPtr(0));
248     mNumBufs = minNumBuffers;
249 
250     rc = mCamOps->map_stream_buf(mCamHandle,
251                 mChannelHandle, mHandle, CAM_MAPPING_BUF_TYPE_STREAM_INFO,
252                 0, -1, mStreamInfoBuf->getFd(0), mStreamInfoBuf->getSize(0));
253     if (rc < 0) {
254         ALOGE("Failed to map stream info buffer");
255         goto err1;
256     }
257 
258     // Configure the stream
259     stream_config.stream_info = mStreamInfo;
260     stream_config.mem_vtbl = mMemVtbl;
261     stream_config.stream_cb = dataNotifyCB;
262     stream_config.padding_info = mPaddingInfo;
263     stream_config.userdata = this;
264     rc = mCamOps->config_stream(mCamHandle,
265                 mChannelHandle, mHandle, &stream_config);
266     if (rc < 0) {
267         ALOGE("Failed to config stream, rc = %d", rc);
268         goto err2;
269     }
270 
271     mDataCB = stream_cb;
272     mUserData = userdata;
273     return 0;
274 
275 err2:
276     mCamOps->unmap_stream_buf(mCamHandle,
277                 mChannelHandle, mHandle, CAM_MAPPING_BUF_TYPE_STREAM_INFO, 0, -1);
278 err1:
279     mCamOps->delete_stream(mCamHandle, mChannelHandle, mHandle);
280     mHandle = 0;
281     mStreamInfoBuf = NULL;
282     mStreamInfo = NULL;
283     mNumBufs = 0;
284 done:
285     return rc;
286 }
287 
288 /*===========================================================================
289  * FUNCTION   : start
290  *
291  * DESCRIPTION: start stream. Will start main stream thread to handle stream
292  *              related ops.
293  *
294  * PARAMETERS : none
295  *
296  * RETURN     : int32_t type of status
297  *              NO_ERROR  -- success
298  *              none-zero failure code
299  *==========================================================================*/
start()300 int32_t QCameraStream::start()
301 {
302     int32_t rc = 0;
303     rc = mProcTh.launch(dataProcRoutine, this);
304     return rc;
305 }
306 
307 /*===========================================================================
308  * FUNCTION   : stop
309  *
310  * DESCRIPTION: stop stream. Will stop main stream thread
311  *
312  * PARAMETERS : none
313  *
314  * RETURN     : int32_t type of status
315  *              NO_ERROR  -- success
316  *              none-zero failure code
317  *==========================================================================*/
stop()318 int32_t QCameraStream::stop()
319 {
320     int32_t rc = 0;
321     rc = mProcTh.exit();
322     return rc;
323 }
324 
325 /*===========================================================================
326  * FUNCTION   : processZoomDone
327  *
328  * DESCRIPTION: process zoom done event
329  *
330  * PARAMETERS :
331  *   @previewWindoe : preview window ops table to set preview crop window
332  *   @crop_info     : crop info
333  *
334  * RETURN     : int32_t type of status
335  *              NO_ERROR  -- success
336  *              none-zero failure code
337  *==========================================================================*/
processZoomDone(preview_stream_ops_t * previewWindow,cam_crop_data_t & crop_info)338 int32_t QCameraStream::processZoomDone(preview_stream_ops_t *previewWindow,
339                                        cam_crop_data_t &crop_info)
340 {
341     int32_t rc = 0;
342 
343     // get stream param for crop info
344     for (int i = 0; i < crop_info.num_of_streams; i++) {
345         if (crop_info.crop_info[i].stream_id == mStreamInfo->stream_svr_id) {
346             pthread_mutex_lock(&mCropLock);
347             mCropInfo = crop_info.crop_info[i].crop;
348             pthread_mutex_unlock(&mCropLock);
349 
350             // update preview window crop if it's preview/postview stream
351             if ( (previewWindow != NULL) &&
352                  (mStreamInfo->stream_type == CAM_STREAM_TYPE_PREVIEW ||
353                   mStreamInfo->stream_type == CAM_STREAM_TYPE_POSTVIEW) ) {
354                 rc = previewWindow->set_crop(previewWindow,
355                                              mCropInfo.left,
356                                              mCropInfo.top,
357                                              mCropInfo.width,
358                                              mCropInfo.height);
359             }
360             break;
361         }
362     }
363     return rc;
364 }
365 
366 /*===========================================================================
367  * FUNCTION   : processDataNotify
368  *
369  * DESCRIPTION: process stream data notify
370  *
371  * PARAMETERS :
372  *   @frame   : stream frame received
373  *
374  * RETURN     : int32_t type of status
375  *              NO_ERROR  -- success
376  *              none-zero failure code
377  *==========================================================================*/
processDataNotify(mm_camera_super_buf_t * frame)378 int32_t QCameraStream::processDataNotify(mm_camera_super_buf_t *frame)
379 {
380     ALOGI("%s:\n", __func__);
381     mDataQ.enqueue((void *)frame);
382     return mProcTh.sendCmd(CAMERA_CMD_TYPE_DO_NEXT_JOB, FALSE, FALSE);
383 }
384 
385 /*===========================================================================
386  * FUNCTION   : dataNotifyCB
387  *
388  * DESCRIPTION: callback for data notify. This function is registered with
389  *              mm-camera-interface to handle data notify
390  *
391  * PARAMETERS :
392  *   @recvd_frame   : stream frame received
393  *   userdata       : user data ptr
394  *
395  * RETURN     : none
396  *==========================================================================*/
dataNotifyCB(mm_camera_super_buf_t * recvd_frame,void * userdata)397 void QCameraStream::dataNotifyCB(mm_camera_super_buf_t *recvd_frame,
398                                  void *userdata)
399 {
400     ALOGI("%s:\n", __func__);
401     QCameraStream* stream = (QCameraStream *)userdata;
402     if (stream == NULL ||
403         recvd_frame == NULL ||
404         recvd_frame->bufs[0] == NULL ||
405         recvd_frame->bufs[0]->stream_id != stream->getMyHandle()) {
406         ALOGE("%s: Not a valid stream to handle buf", __func__);
407         return;
408     }
409 
410     mm_camera_super_buf_t *frame =
411         (mm_camera_super_buf_t *)malloc(sizeof(mm_camera_super_buf_t));
412     if (frame == NULL) {
413         ALOGE("%s: No mem for mm_camera_buf_def_t", __func__);
414         stream->bufDone(recvd_frame->bufs[0]->buf_idx);
415         return;
416     }
417     *frame = *recvd_frame;
418     stream->processDataNotify(frame);
419     return;
420 }
421 
422 /*===========================================================================
423  * FUNCTION   : dataProcRoutine
424  *
425  * DESCRIPTION: function to process data in the main stream thread
426  *
427  * PARAMETERS :
428  *   @data    : user data ptr
429  *
430  * RETURN     : none
431  *==========================================================================*/
dataProcRoutine(void * data)432 void *QCameraStream::dataProcRoutine(void *data)
433 {
434     int running = 1;
435     int ret;
436     QCameraStream *pme = (QCameraStream *)data;
437     QCameraCmdThread *cmdThread = &pme->mProcTh;
438 
439     ALOGI("%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                 ALOGD("%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                         free(frame);
465                     }
466                 }
467             }
468             break;
469         case CAMERA_CMD_TYPE_EXIT:
470             ALOGD("%s: Exit", __func__);
471             /* flush data buf queue */
472             pme->mDataQ.flush();
473             running = 0;
474             break;
475         default:
476             break;
477         }
478     } while (running);
479     ALOGD("%s: X", __func__);
480     return NULL;
481 }
482 
483 /*===========================================================================
484  * FUNCTION   : bufDone
485  *
486  * DESCRIPTION: return stream buffer to kernel
487  *
488  * PARAMETERS :
489  *   @index   : index of buffer to be returned
490  *
491  * RETURN     : int32_t type of status
492  *              NO_ERROR  -- success
493  *              none-zero failure code
494  *==========================================================================*/
bufDone(int index)495 int32_t QCameraStream::bufDone(int index)
496 {
497     int32_t rc = NO_ERROR;
498 
499     if (index >= mNumBufs || mBufDefs == NULL)
500         return BAD_INDEX;
501 
502     rc = mCamOps->qbuf(mCamHandle, mChannelHandle, &mBufDefs[index]);
503     if (rc < 0)
504         return rc;
505 
506     return rc;
507 }
508 
509 /*===========================================================================
510  * FUNCTION   : bufDone
511  *
512  * DESCRIPTION: return stream buffer to kernel
513  *
514  * PARAMETERS :
515  *   @opaque    : stream frame/metadata buf to be returned
516  *   @isMetaData: flag if returned opaque is a metadatabuf or the real frame ptr
517  *
518  * RETURN     : int32_t type of status
519  *              NO_ERROR  -- success
520  *              none-zero failure code
521  *==========================================================================*/
bufDone(const void * opaque,bool isMetaData)522 int32_t QCameraStream::bufDone(const void *opaque, bool isMetaData)
523 {
524     int32_t rc = NO_ERROR;
525 
526     int index = mStreamBufs->getMatchBufIndex(opaque, isMetaData);
527     if (index == -1 || index >= mNumBufs || mBufDefs == NULL) {
528         ALOGE("%s: Cannot find buf for opaque data = %p", __func__, opaque);
529         return BAD_INDEX;
530     }
531     ALOGD("%s: Buffer Index = %d, Frame Idx = %d", __func__, index, mBufDefs[index].frame_idx);
532     rc = bufDone(index);
533     return rc;
534 }
535 
536 /*===========================================================================
537  * FUNCTION   : getBufs
538  *
539  * DESCRIPTION: allocate stream buffers
540  *
541  * PARAMETERS :
542  *   @offset     : offset info of stream buffers
543  *   @num_bufs   : number of buffers allocated
544  *   @initial_reg_flag: flag to indicate if buffer needs to be registered
545  *                      at kernel initially
546  *   @bufs       : output of allocated buffers
547  *   @ops_tbl    : ptr to buf mapping/unmapping ops
548  *
549  * RETURN     : int32_t type of status
550  *              NO_ERROR  -- success
551  *              none-zero failure code
552  *==========================================================================*/
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)553 int32_t QCameraStream::getBufs(cam_frame_len_offset_t *offset,
554                      uint8_t *num_bufs,
555                      uint8_t **initial_reg_flag,
556                      mm_camera_buf_def_t **bufs,
557                      mm_camera_map_unmap_ops_tbl_t *ops_tbl)
558 {
559     int rc = NO_ERROR;
560     uint8_t *regFlags;
561 
562     if (!ops_tbl) {
563         ALOGE("%s: ops_tbl is NULL", __func__);
564         return INVALID_OPERATION;
565     }
566 
567     mFrameLenOffset = *offset;
568 
569     //Allocate and map stream info buffer
570     mStreamBufs = mAllocator.allocateStreamBuf(mStreamInfo->stream_type,
571                                                mFrameLenOffset.frame_len,
572                                                mNumBufs);
573     if (!mStreamBufs) {
574         ALOGE("%s: Failed to allocate stream buffers", __func__);
575         return NO_MEMORY;
576     }
577 
578     for (int i = 0; i < mNumBufs; i++) {
579         rc = ops_tbl->map_ops(i, -1, mStreamBufs->getFd(i),
580                 mStreamBufs->getSize(i), ops_tbl->userdata);
581         if (rc < 0) {
582             ALOGE("%s: map_stream_buf failed: %d", __func__, rc);
583             for (int j = 0; j < i; j++) {
584                 ops_tbl->unmap_ops(j, -1, ops_tbl->userdata);
585             }
586             mStreamBufs->deallocate();
587             delete mStreamBufs;
588             mStreamBufs = NULL;
589             return INVALID_OPERATION;
590         }
591     }
592 
593     //regFlags array is allocated by us, but consumed and freed by mm-camera-interface
594     regFlags = (uint8_t *)malloc(sizeof(uint8_t) * mNumBufs);
595     if (!regFlags) {
596         ALOGE("%s: Out of memory", __func__);
597         for (int i = 0; i < mNumBufs; i++) {
598             ops_tbl->unmap_ops(i, -1, ops_tbl->userdata);
599         }
600         mStreamBufs->deallocate();
601         delete mStreamBufs;
602         mStreamBufs = NULL;
603         return NO_MEMORY;
604     }
605 
606     mBufDefs = (mm_camera_buf_def_t *)malloc(mNumBufs * sizeof(mm_camera_buf_def_t));
607     if (mBufDefs == NULL) {
608         ALOGE("%s: getRegFlags failed %d", __func__, rc);
609         for (int i = 0; i < mNumBufs; i++) {
610             ops_tbl->unmap_ops(i, -1, ops_tbl->userdata);
611         }
612         mStreamBufs->deallocate();
613         delete mStreamBufs;
614         mStreamBufs = NULL;
615         free(regFlags);
616         regFlags = NULL;
617         return INVALID_OPERATION;
618     }
619     for (int i = 0; i < mNumBufs; i++) {
620         mStreamBufs->getBufDef(mFrameLenOffset, mBufDefs[i], i);
621     }
622 
623     rc = mStreamBufs->getRegFlags(regFlags);
624     if (rc < 0) {
625         ALOGE("%s: getRegFlags failed %d", __func__, rc);
626         for (int i = 0; i < mNumBufs; i++) {
627             ops_tbl->unmap_ops(i, -1, ops_tbl->userdata);
628         }
629         mStreamBufs->deallocate();
630         delete mStreamBufs;
631         mStreamBufs = NULL;
632         free(mBufDefs);
633         mBufDefs = NULL;
634         free(regFlags);
635         regFlags = NULL;
636         return INVALID_OPERATION;
637     }
638 
639     *num_bufs = mNumBufs;
640     *initial_reg_flag = regFlags;
641     *bufs = mBufDefs;
642     return NO_ERROR;
643 }
644 
645 /*===========================================================================
646  * FUNCTION   : putBufs
647  *
648  * DESCRIPTION: deallocate stream buffers
649  *
650  * PARAMETERS :
651  *   @ops_tbl    : ptr to buf mapping/unmapping ops
652  *
653  * RETURN     : int32_t type of status
654  *              NO_ERROR  -- success
655  *              none-zero failure code
656  *==========================================================================*/
putBufs(mm_camera_map_unmap_ops_tbl_t * ops_tbl)657 int32_t QCameraStream::putBufs(mm_camera_map_unmap_ops_tbl_t *ops_tbl)
658 {
659     int rc = NO_ERROR;
660     for (int i = 0; i < mNumBufs; i++) {
661         rc = ops_tbl->unmap_ops(i, -1, ops_tbl->userdata);
662         if (rc < 0) {
663             ALOGE("%s: map_stream_buf failed: %d", __func__, rc);
664         }
665     }
666     mBufDefs = NULL; // mBufDefs just keep a ptr to the buffer
667                      // mm-camera-interface own the buffer, so no need to free
668     memset(&mFrameLenOffset, 0, sizeof(mFrameLenOffset));
669     mStreamBufs->deallocate();
670     delete mStreamBufs;
671 
672     return rc;
673 }
674 
675 /*===========================================================================
676  * FUNCTION   : invalidateBuf
677  *
678  * DESCRIPTION: invalidate a specific stream buffer
679  *
680  * PARAMETERS :
681  *   @index   : index of the buffer to invalidate
682  *
683  * RETURN     : int32_t type of status
684  *              NO_ERROR  -- success
685  *              none-zero failure code
686  *==========================================================================*/
invalidateBuf(int index)687 int32_t QCameraStream::invalidateBuf(int index)
688 {
689     return mStreamBufs->invalidateCache(index);
690 }
691 
692 /*===========================================================================
693  * FUNCTION   : cleanInvalidateBuf
694  *
695  * DESCRIPTION: clean invalidate a specific stream buffer
696  *
697  * PARAMETERS :
698  *   @index   : index of the buffer to clean invalidate
699  *
700  * RETURN     : int32_t type of status
701  *              NO_ERROR  -- success
702  *              none-zero failure code
703  *==========================================================================*/
cleanInvalidateBuf(int index)704 int32_t QCameraStream::cleanInvalidateBuf(int index)
705 {
706     return mStreamBufs->cleanInvalidateCache(index);
707 }
708 
709 /*===========================================================================
710  * FUNCTION   : isTypeOf
711  *
712  * DESCRIPTION: helper function to determine if the stream is of the queried type
713  *
714  * PARAMETERS :
715  *   @type    : stream type as of queried
716  *
717  * RETURN     : true/false
718  *==========================================================================*/
isTypeOf(cam_stream_type_t type)719 bool QCameraStream::isTypeOf(cam_stream_type_t type)
720 {
721     if (mStreamInfo != NULL && (mStreamInfo->stream_type == type)) {
722         return true;
723     } else {
724         return false;
725     }
726 }
727 
728 /*===========================================================================
729  * FUNCTION   : isOrignalTypeOf
730  *
731  * DESCRIPTION: helper function to determine if the original stream is of the
732  *              queried type if it's reproc stream
733  *
734  * PARAMETERS :
735  *   @type    : stream type as of queried
736  *
737  * RETURN     : true/false
738  *==========================================================================*/
isOrignalTypeOf(cam_stream_type_t type)739 bool QCameraStream::isOrignalTypeOf(cam_stream_type_t type)
740 {
741     if (mStreamInfo != NULL &&
742         mStreamInfo->stream_type == CAM_STREAM_TYPE_OFFLINE_PROC &&
743         mStreamInfo->reprocess_config.pp_type == CAM_ONLINE_REPROCESS_TYPE &&
744         mStreamInfo->reprocess_config.online.input_stream_type == type) {
745         return true;
746     } else {
747         return false;
748     }
749 }
750 
751 /*===========================================================================
752  * FUNCTION   : getMyType
753  *
754  * DESCRIPTION: return stream type
755  *
756  * PARAMETERS : none
757  *
758  * RETURN     : stream type
759  *==========================================================================*/
getMyType()760 cam_stream_type_t QCameraStream::getMyType()
761 {
762     if (mStreamInfo != NULL) {
763         return mStreamInfo->stream_type;
764     } else {
765         return CAM_STREAM_TYPE_DEFAULT;
766     }
767 }
768 
769 /*===========================================================================
770  * FUNCTION   : getFrameOffset
771  *
772  * DESCRIPTION: query stream buffer frame offset info
773  *
774  * PARAMETERS :
775  *   @offset  : reference to struct to store the queried frame offset info
776  *
777  * RETURN     : int32_t type of status
778  *              NO_ERROR  -- success
779  *              none-zero failure code
780  *==========================================================================*/
getFrameOffset(cam_frame_len_offset_t & offset)781 int32_t QCameraStream::getFrameOffset(cam_frame_len_offset_t &offset)
782 {
783     offset = mFrameLenOffset;
784     return 0;
785 }
786 
787 /*===========================================================================
788  * FUNCTION   : getCropInfo
789  *
790  * DESCRIPTION: query crop info of the stream
791  *
792  * PARAMETERS :
793  *   @crop    : reference to struct to store the queried crop info
794  *
795  * RETURN     : int32_t type of status
796  *              NO_ERROR  -- success
797  *              none-zero failure code
798  *==========================================================================*/
getCropInfo(cam_rect_t & crop)799 int32_t QCameraStream::getCropInfo(cam_rect_t &crop)
800 {
801     pthread_mutex_lock(&mCropLock);
802     crop = mCropInfo;
803     pthread_mutex_unlock(&mCropLock);
804     return NO_ERROR;
805 }
806 
807 /*===========================================================================
808  * FUNCTION   : getFrameDimension
809  *
810  * DESCRIPTION: query stream frame dimension info
811  *
812  * PARAMETERS :
813  *   @dim     : reference to struct to store the queried frame dimension
814  *
815  * RETURN     : int32_t type of status
816  *              NO_ERROR  -- success
817  *              none-zero failure code
818  *==========================================================================*/
getFrameDimension(cam_dimension_t & dim)819 int32_t QCameraStream::getFrameDimension(cam_dimension_t &dim)
820 {
821     if (mStreamInfo != NULL) {
822         dim = mStreamInfo->dim;
823         return 0;
824     }
825     return -1;
826 }
827 
828 /*===========================================================================
829  * FUNCTION   : getFormat
830  *
831  * DESCRIPTION: query stream format
832  *
833  * PARAMETERS :
834  *   @fmt     : reference to stream format
835  *
836  * RETURN     : int32_t type of status
837  *              NO_ERROR  -- success
838  *              none-zero failure code
839  *==========================================================================*/
getFormat(cam_format_t & fmt)840 int32_t QCameraStream::getFormat(cam_format_t &fmt)
841 {
842     if (mStreamInfo != NULL) {
843         fmt = mStreamInfo->fmt;
844         return 0;
845     }
846     return -1;
847 }
848 
849 /*===========================================================================
850  * FUNCTION   : getMyServerID
851  *
852  * DESCRIPTION: query server stream ID
853  *
854  * PARAMETERS : None
855  *
856  * RETURN     : stream ID from server
857  *==========================================================================*/
getMyServerID()858 uint32_t QCameraStream::getMyServerID() {
859     if (mStreamInfo != NULL) {
860         return mStreamInfo->stream_svr_id;
861     } else {
862         return 0;
863     }
864 }
865 
866 /*===========================================================================
867  * FUNCTION   : mapBuf
868  *
869  * DESCRIPTION: map stream related buffer to backend server
870  *
871  * PARAMETERS :
872  *   @buf_type : mapping type of buffer
873  *   @buf_idx  : index of buffer
874  *   @plane_idx: plane index
875  *   @fd       : fd of the buffer
876  *   @size     : lenght of the buffer
877  *
878  * RETURN     : int32_t type of status
879  *              NO_ERROR  -- success
880  *              none-zero failure code
881  *==========================================================================*/
mapBuf(uint8_t buf_type,uint32_t buf_idx,int32_t plane_idx,int fd,uint32_t size)882 int32_t QCameraStream::mapBuf(uint8_t buf_type,
883                               uint32_t buf_idx,
884                               int32_t plane_idx,
885                               int fd,
886                               uint32_t size)
887 {
888     return mCamOps->map_stream_buf(mCamHandle, mChannelHandle,
889                                    mHandle, buf_type,
890                                    buf_idx, plane_idx,
891                                    fd, size);
892 
893 }
894 
895 /*===========================================================================
896  * FUNCTION   : unmapBuf
897  *
898  * DESCRIPTION: unmap stream related buffer to backend server
899  *
900  * PARAMETERS :
901  *   @buf_type : mapping type of buffer
902  *   @buf_idx  : index of buffer
903  *   @plane_idx: plane index
904  *
905  * RETURN     : int32_t type of status
906  *              NO_ERROR  -- success
907  *              none-zero failure code
908  *==========================================================================*/
unmapBuf(uint8_t buf_type,uint32_t buf_idx,int32_t plane_idx)909 int32_t QCameraStream::unmapBuf(uint8_t buf_type, uint32_t buf_idx, int32_t plane_idx)
910 {
911     return mCamOps->unmap_stream_buf(mCamHandle, mChannelHandle,
912                                      mHandle, buf_type,
913                                      buf_idx, plane_idx);
914 
915 }
916 
917 /*===========================================================================
918  * FUNCTION   : setParameter
919  *
920  * DESCRIPTION: set stream based parameters
921  *
922  * PARAMETERS :
923  *   @param   : ptr to parameters to be set
924  *
925  * RETURN     : int32_t type of status
926  *              NO_ERROR  -- success
927  *              none-zero failure code
928  *==========================================================================*/
setParameter(cam_stream_parm_buffer_t & param)929 int32_t QCameraStream::setParameter(cam_stream_parm_buffer_t &param)
930 {
931     int32_t rc = NO_ERROR;
932     mStreamInfo->parm_buf = param;
933     rc = mCamOps->set_stream_parms(mCamHandle,
934                                    mChannelHandle,
935                                    mHandle,
936                                    &mStreamInfo->parm_buf);
937     if (rc == NO_ERROR) {
938         param = mStreamInfo->parm_buf;
939     }
940     return rc;
941 }
942 
943 }; // namespace qcamera
944