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 "QCameraStream"
31 
32 #include <utils/Errors.h>
33 #include "QCamera2HWI.h"
34 #include "QCameraStream.h"
35 
36 #define CAMERA_MIN_ALLOCATED_BUFFERS     3
37 
38 namespace qcamera {
39 
40 /*===========================================================================
41  * FUNCTION   : get_bufs
42  *
43  * DESCRIPTION: static function entry to allocate stream buffers
44  *
45  * PARAMETERS :
46  *   @offset     : offset info of stream buffers
47  *   @num_bufs   : number of buffers allocated
48  *   @initial_reg_flag: flag to indicate if buffer needs to be registered
49  *                      at kernel initially
50  *   @bufs       : output of allocated buffers
51  *   @ops_tbl    : ptr to buf mapping/unmapping ops
52  *   @user_data  : user data ptr of ops_tbl
53  *
54  * RETURN     : int32_t type of status
55  *              NO_ERROR  -- success
56  *              none-zero failure code
57  *==========================================================================*/
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)58 int32_t QCameraStream::get_bufs(
59                      cam_frame_len_offset_t *offset,
60                      uint8_t *num_bufs,
61                      uint8_t **initial_reg_flag,
62                      mm_camera_buf_def_t **bufs,
63                      mm_camera_map_unmap_ops_tbl_t *ops_tbl,
64                      void *user_data)
65 {
66     QCameraStream *stream = reinterpret_cast<QCameraStream *>(user_data);
67     if (!stream) {
68         ALOGE("getBufs invalid stream pointer");
69         return NO_MEMORY;
70     }
71     return stream->getBufs(offset, num_bufs, initial_reg_flag, bufs, ops_tbl);
72 }
73 
74 /*===========================================================================
75  * FUNCTION   : get_bufs_deffered
76  *
77  * DESCRIPTION: static function entry to allocate deffered stream buffers
78  *
79  * PARAMETERS :
80  *   @offset     : offset info of stream buffers
81  *   @num_bufs   : number of buffers allocated
82  *   @initial_reg_flag: flag to indicate if buffer needs to be registered
83  *                      at kernel initially
84  *   @bufs       : output of allocated buffers
85  *   @ops_tbl    : ptr to buf mapping/unmapping ops
86  *   @user_data  : user data ptr of ops_tbl
87  *
88  * RETURN     : int32_t type of status
89  *              NO_ERROR  -- success
90  *              none-zero failure code
91  *==========================================================================*/
get_bufs_deffered(cam_frame_len_offset_t *,uint8_t * num_bufs,uint8_t ** initial_reg_flag,mm_camera_buf_def_t ** bufs,mm_camera_map_unmap_ops_tbl_t *,void * user_data)92 int32_t QCameraStream::get_bufs_deffered(
93         cam_frame_len_offset_t * /* offset */,
94         uint8_t *num_bufs,
95         uint8_t **initial_reg_flag,
96         mm_camera_buf_def_t **bufs,
97         mm_camera_map_unmap_ops_tbl_t * /* ops_tbl */,
98         void *user_data)
99 {
100     QCameraStream *stream = reinterpret_cast<QCameraStream *>(user_data);
101     if (!stream) {
102         ALOGE("getBufs invalid stream pointer");
103         return NO_MEMORY;
104     }
105 
106     *initial_reg_flag   = stream->mRegFlags;
107     *num_bufs           = stream->mNumBufs;
108     *bufs               = stream->mBufDefs;
109     return NO_ERROR;
110 }
111 
112 /*===========================================================================
113  * FUNCTION   : put_bufs
114  *
115  * DESCRIPTION: static function entry to deallocate stream buffers
116  *
117  * PARAMETERS :
118  *   @ops_tbl    : ptr to buf mapping/unmapping ops
119  *   @user_data  : user data ptr of ops_tbl
120  *
121  * RETURN     : int32_t type of status
122  *              NO_ERROR  -- success
123  *              none-zero failure code
124  *==========================================================================*/
put_bufs(mm_camera_map_unmap_ops_tbl_t * ops_tbl,void * user_data)125 int32_t QCameraStream::put_bufs(
126                      mm_camera_map_unmap_ops_tbl_t *ops_tbl,
127                      void *user_data)
128 {
129     QCameraStream *stream = reinterpret_cast<QCameraStream *>(user_data);
130     if (!stream) {
131         ALOGE("putBufs invalid stream pointer");
132         return NO_MEMORY;
133     }
134     return stream->putBufs(ops_tbl);
135 }
136 
137 /*===========================================================================
138  * FUNCTION   : put_bufs_deffered
139  *
140  * DESCRIPTION: static function entry to deallocate deffered stream buffers
141  *
142  * PARAMETERS :
143  *   @ops_tbl    : ptr to buf mapping/unmapping ops
144  *   @user_data  : user data ptr of ops_tbl
145  *
146  * RETURN     : int32_t type of status
147  *              NO_ERROR  -- success
148  *              none-zero failure code
149  *==========================================================================*/
put_bufs_deffered(mm_camera_map_unmap_ops_tbl_t *,void *)150 int32_t QCameraStream::put_bufs_deffered(
151         mm_camera_map_unmap_ops_tbl_t * /*ops_tbl */,
152         void * /*user_data*/ )
153 {
154     // No op
155     // Used for handling buffers with deffered allocation. They are freed separately.
156     return NO_ERROR;
157 }
158 
159 /*===========================================================================
160  * FUNCTION   : invalidate_buf
161  *
162  * DESCRIPTION: static function entry to invalidate a specific stream buffer
163  *
164  * PARAMETERS :
165  *   @index      : index of the stream buffer to invalidate
166  *   @user_data  : user data ptr of ops_tbl
167  *
168  * RETURN     : int32_t type of status
169  *              NO_ERROR  -- success
170  *              none-zero failure code
171  *==========================================================================*/
invalidate_buf(int index,void * user_data)172 int32_t QCameraStream::invalidate_buf(int index, void *user_data)
173 {
174     QCameraStream *stream = reinterpret_cast<QCameraStream *>(user_data);
175     if (!stream) {
176         ALOGE("invalid stream pointer");
177         return NO_MEMORY;
178     }
179     if (stream->mStreamInfo->is_secure != SECURE)
180         return stream->invalidateBuf(index);
181 
182     return 0;
183 }
184 
185 /*===========================================================================
186  * FUNCTION   : clean_invalidate_buf
187  *
188  * DESCRIPTION: static function entry to clean invalidate a specific stream buffer
189  *
190  * PARAMETERS :
191  *   @index      : index of the stream buffer to clean invalidate
192  *   @user_data  : user data ptr of ops_tbl
193  *
194  * RETURN     : int32_t type of status
195  *              NO_ERROR  -- success
196  *              none-zero failure code
197  *==========================================================================*/
clean_invalidate_buf(int index,void * user_data)198 int32_t QCameraStream::clean_invalidate_buf(int index, void *user_data)
199 {
200     QCameraStream *stream = reinterpret_cast<QCameraStream *>(user_data);
201     if (!stream) {
202         ALOGE("invalid stream pointer");
203         return NO_MEMORY;
204     }
205 
206     if (stream->mStreamInfo->is_secure != SECURE)
207         return stream->cleanInvalidateBuf(index);
208 
209     return 0;
210 }
211 
212 /*===========================================================================
213  * FUNCTION   : QCameraStream
214  *
215  * DESCRIPTION: constructor of QCameraStream
216  *
217  * PARAMETERS :
218  *   @allocator  : memory allocator obj
219  *   @camHandle  : camera handle
220  *   @chId       : channel handle
221  *   @camOps     : ptr to camera ops table
222  *   @paddingInfo: ptr to padding info
223  *
224  * RETURN     : None
225  *==========================================================================*/
QCameraStream(QCameraAllocator & allocator,uint32_t camHandle,uint32_t chId,mm_camera_ops_t * camOps,cam_padding_info_t * paddingInfo,bool deffered)226 QCameraStream::QCameraStream(QCameraAllocator &allocator,
227                              uint32_t camHandle,
228                              uint32_t chId,
229                              mm_camera_ops_t *camOps,
230                              cam_padding_info_t *paddingInfo,
231                              bool deffered) :
232         mDumpFrame(0),
233         mDumpMetaFrame(0),
234         mDumpSkipCnt(0),
235         mCamHandle(camHandle),
236         mChannelHandle(chId),
237         mHandle(0),
238         mCamOps(camOps),
239         mStreamInfo(NULL),
240         mNumBufs(0),
241         mNumBufsNeedAlloc(0),
242         mDataCB(NULL),
243         mUserData(NULL),
244         mDataQ(releaseFrameData, this),
245         mStreamInfoBuf(NULL),
246         mStreamBufs(NULL),
247         mAllocator(allocator),
248         mBufDefs(NULL),
249         mStreamBufsAcquired(false),
250         m_bActive(false),
251         mDynBufAlloc(false),
252         mBufAllocPid(0),
253         mDefferedAllocation(deffered),
254         wait_for_cond(false)
255 {
256     mMemVtbl.user_data = this;
257     if ( !deffered ) {
258         mMemVtbl.get_bufs = get_bufs;
259         mMemVtbl.put_bufs = put_bufs;
260     } else {
261         mMemVtbl.get_bufs = get_bufs_deffered;
262         mMemVtbl.put_bufs = put_bufs_deffered;
263     }
264     mMemVtbl.invalidate_buf = invalidate_buf;
265     mMemVtbl.clean_invalidate_buf = clean_invalidate_buf;
266     memset(&mFrameLenOffset, 0, sizeof(mFrameLenOffset));
267     memcpy(&mPaddingInfo, paddingInfo, sizeof(cam_padding_info_t));
268     memset(&mCropInfo, 0, sizeof(cam_rect_t));
269     memset(&m_MemOpsTbl, 0, sizeof(mm_camera_map_unmap_ops_tbl_t));
270     memset(&m_OutputCrop, 0, sizeof(cam_stream_parm_buffer_t));
271     memset(&m_ImgProp, 0, sizeof(cam_stream_parm_buffer_t));
272     pthread_mutex_init(&mCropLock, NULL);
273     pthread_mutex_init(&mParameterLock, NULL);
274 }
275 
276 /*===========================================================================
277  * FUNCTION   : ~QCameraStream
278  *
279  * DESCRIPTION: deconstructor of QCameraStream
280  *
281  * PARAMETERS : None
282  *
283  * RETURN     : None
284  *==========================================================================*/
~QCameraStream()285 QCameraStream::~QCameraStream()
286 {
287     pthread_mutex_destroy(&mCropLock);
288     pthread_mutex_destroy(&mParameterLock);
289 
290     if (mDefferedAllocation) {
291         mStreamBufsAcquired = false;
292         releaseBuffs();
293     }
294 
295     unmapStreamInfoBuf();
296     releaseStreamInfoBuf();
297 
298     // delete stream
299     if (mHandle > 0) {
300         mCamOps->delete_stream(mCamHandle, mChannelHandle, mHandle);
301         mHandle = 0;
302     }
303 }
304 
305 /*===========================================================================
306  * FUNCTION   : unmapStreamInfoBuf
307  *
308  * DESCRIPTION: Unmap stream info buffer
309  *
310  * PARAMETERS :
311  *
312  * RETURN     : int32_t type of status
313  *              NO_ERROR  -- success
314  *              none-zero failure code
315  *==========================================================================*/
unmapStreamInfoBuf()316 int32_t QCameraStream::unmapStreamInfoBuf()
317 {
318     int rc = NO_ERROR;
319 
320     if (mStreamInfoBuf != NULL) {
321         rc = mCamOps->unmap_stream_buf(mCamHandle,
322             mChannelHandle,
323             mHandle,
324             CAM_MAPPING_BUF_TYPE_STREAM_INFO,
325             0,
326             -1);
327 
328         if (rc < 0) {
329             ALOGE("Failed to unmap stream info buffer");
330         }
331     }
332 
333     return rc;
334 }
335 
336 /*===========================================================================
337  * FUNCTION   : releaseStreamInfoBuf
338  *
339  * DESCRIPTION: Release stream info buffer
340  *
341  * PARAMETERS :
342  *
343  * RETURN     : int32_t type of status
344  *              NO_ERROR  -- success
345  *              none-zero failure code
346  *==========================================================================*/
releaseStreamInfoBuf()347 int32_t QCameraStream::releaseStreamInfoBuf()
348 {
349     int rc = NO_ERROR;
350 
351     if (mStreamInfoBuf != NULL) {
352         mStreamInfoBuf->deallocate();
353         delete mStreamInfoBuf;
354         mStreamInfoBuf = NULL;
355     }
356 
357     return rc;
358 }
359 
360 /*===========================================================================
361  * FUNCTION   : deleteStream
362  *
363  * DESCRIPTION: Deletes a camera stream
364  *
365  * PARAMETERS : None
366  *
367  * RETURN     : None
368  *==========================================================================*/
deleteStream()369 void QCameraStream::deleteStream()
370 {
371     if (mHandle > 0) {
372         acquireStreamBufs();
373         releaseBuffs();
374         unmapStreamInfoBuf();
375         mCamOps->delete_stream(mCamHandle, mChannelHandle, mHandle);
376     }
377 }
378 
379 /*===========================================================================
380  * FUNCTION   : init
381  *
382  * DESCRIPTION: initialize stream obj
383  *
384  * PARAMETERS :
385  *   @streamInfoBuf: ptr to buf that contains stream info
386  *   @stream_cb    : stream data notify callback. Can be NULL if not needed
387  *   @userdata     : user data ptr
388  *   @bDynallocBuf : flag to indicate if buffer allocation can be in 2 steps
389  *
390  * RETURN     : int32_t type of status
391  *              NO_ERROR  -- success
392  *              none-zero failure code
393  *==========================================================================*/
init(QCameraHeapMemory * streamInfoBuf,uint8_t minNumBuffers,stream_cb_routine stream_cb,void * userdata,bool bDynallocBuf)394 int32_t QCameraStream::init(QCameraHeapMemory *streamInfoBuf,
395                             uint8_t minNumBuffers,
396                             stream_cb_routine stream_cb,
397                             void *userdata,
398                             bool bDynallocBuf)
399 {
400     int32_t rc = OK;
401 
402     mHandle = mCamOps->add_stream(mCamHandle, mChannelHandle);
403     if (!mHandle) {
404         ALOGE("add_stream failed");
405         rc = UNKNOWN_ERROR;
406         goto done;
407     }
408 
409     // assign and map stream info memory
410     mStreamInfoBuf = streamInfoBuf;
411     mStreamInfo = reinterpret_cast<cam_stream_info_t *>(mStreamInfoBuf->getPtr(0));
412     mNumBufs = minNumBuffers;
413 
414     rc = mCamOps->map_stream_buf(mCamHandle,
415                 mChannelHandle, mHandle, CAM_MAPPING_BUF_TYPE_STREAM_INFO,
416                 0, -1, mStreamInfoBuf->getFd(0), mStreamInfoBuf->getSize(0));
417     if (rc < 0) {
418         ALOGE("Failed to map stream info buffer");
419         goto err1;
420     }
421 
422     // Calculate buffer size for deffered allocation
423     if (mDefferedAllocation) {
424         rc = calcOffset(mStreamInfo);
425         if (rc < 0) {
426             ALOGE("%s : Failed to calculate stream offset", __func__);
427             goto err1;
428         }
429     } else {
430         rc = configStream();
431         if (rc < 0) {
432             ALOGE("%s : Failed to config stream ", __func__);
433             goto err1;
434         }
435     }
436 
437     mDataCB = stream_cb;
438     mUserData = userdata;
439     mDynBufAlloc = bDynallocBuf;
440     return 0;
441 
442 err1:
443     mCamOps->delete_stream(mCamHandle, mChannelHandle, mHandle);
444     mHandle = 0;
445     mStreamInfoBuf = NULL;
446     mStreamInfo = NULL;
447     mNumBufs = 0;
448 done:
449     return rc;
450 }
451 
452 /*===========================================================================
453  * FUNCTION   : calcOffset
454  *
455  * DESCRIPTION: calculate frame offset based on format and padding information
456  *
457  * PARAMETERS :
458  *   @streamInfo  : stream information
459  *
460  * RETURN     : int32_t type of status
461  *              0  -- success
462  *              -1 -- failure
463  *==========================================================================*/
calcOffset(cam_stream_info_t * streamInfo)464 int32_t QCameraStream::calcOffset(cam_stream_info_t *streamInfo)
465 {
466     int32_t rc = 0;
467 
468     cam_dimension_t dim = streamInfo->dim;
469     if (streamInfo->pp_config.feature_mask & CAM_QCOM_FEATURE_ROTATION &&
470             streamInfo->stream_type != CAM_STREAM_TYPE_VIDEO) {
471         if (streamInfo->pp_config.rotation == ROTATE_90 ||
472                 streamInfo->pp_config.rotation == ROTATE_270) {
473             // rotated by 90 or 270, need to switch width and height
474             dim.width = streamInfo->dim.height;
475             dim.height = streamInfo->dim.width;
476         }
477     }
478 
479     switch (streamInfo->stream_type) {
480     case CAM_STREAM_TYPE_PREVIEW:
481         rc = mm_stream_calc_offset_preview(streamInfo->fmt,
482                 &dim,
483                 &streamInfo->buf_planes);
484         break;
485     case CAM_STREAM_TYPE_POSTVIEW:
486         rc = mm_stream_calc_offset_post_view(streamInfo->fmt,
487                 &dim,
488                 &streamInfo->buf_planes);
489         break;
490     case CAM_STREAM_TYPE_SNAPSHOT:
491         rc = mm_stream_calc_offset_snapshot(streamInfo->fmt,
492                 &dim,
493                 &mPaddingInfo,
494                 &streamInfo->buf_planes);
495         break;
496     case CAM_STREAM_TYPE_OFFLINE_PROC:
497         rc = mm_stream_calc_offset_postproc(streamInfo,
498                 &mPaddingInfo,
499                 &streamInfo->buf_planes);
500         break;
501     case CAM_STREAM_TYPE_VIDEO:
502         rc = mm_stream_calc_offset_video(&dim,
503                 &streamInfo->buf_planes);
504         break;
505     case CAM_STREAM_TYPE_RAW:
506         rc = mm_stream_calc_offset_raw(streamInfo->fmt,
507                 &dim,
508                 &mPaddingInfo,
509                 &streamInfo->buf_planes);
510         break;
511     case CAM_STREAM_TYPE_METADATA:
512         rc = mm_stream_calc_offset_metadata(&dim,
513                 &mPaddingInfo,
514                 &streamInfo->buf_planes);
515         break;
516     default:
517         ALOGE("%s: not supported for stream type %d",
518                 __func__, streamInfo->stream_type);
519         rc = -1;
520         break;
521     }
522     return rc;
523 }
524 
525 /*===========================================================================
526  * FUNCTION   : start
527  *
528  * DESCRIPTION: start stream. Will start main stream thread to handle stream
529  *              related ops.
530  *
531  * PARAMETERS : none
532  *
533  * RETURN     : int32_t type of status
534  *              NO_ERROR  -- success
535  *              none-zero failure code
536  *==========================================================================*/
start()537 int32_t QCameraStream::start()
538 {
539     int32_t rc = 0;
540     mDataQ.init();
541     rc = mProcTh.launch(dataProcRoutine, this);
542     if (rc == NO_ERROR) {
543         m_bActive = true;
544     }
545     pthread_mutex_init(&m_lock, NULL);
546     pthread_cond_init(&m_cond, NULL);
547     return rc;
548 }
549 
550 /*===========================================================================
551  * FUNCTION   : stop
552  *
553  * DESCRIPTION: stop stream. Will stop main stream thread
554  *
555  * PARAMETERS : none
556  *
557  * RETURN     : int32_t type of status
558  *              NO_ERROR  -- success
559  *              none-zero failure code
560  *==========================================================================*/
stop()561 int32_t QCameraStream::stop()
562 {
563     int32_t rc = 0;
564     m_bActive = false;
565     rc = mProcTh.exit();
566     return rc;
567 }
568 
569 /*===========================================================================
570  * FUNCTION   : syncRuntimeParams
571  *
572  * DESCRIPTION: query and sync runtime parameters like output crop
573  *              buffer info etc.
574  *
575  * PARAMETERS : none
576  *
577  * RETURN     : int32_t type of status
578  *              NO_ERROR  -- success
579  *              none-zero failure code
580  *==========================================================================*/
syncRuntimeParams()581 int32_t QCameraStream::syncRuntimeParams()
582 {
583     int32_t ret = NO_ERROR;
584 
585     memset(&m_OutputCrop, 0, sizeof(cam_stream_parm_buffer_t));
586     m_OutputCrop.type = CAM_STREAM_PARAM_TYPE_GET_OUTPUT_CROP;
587 
588     ret = getParameter(m_OutputCrop);
589     if (ret != NO_ERROR) {
590         ALOGE("%s: stream getParameter for output crop failed", __func__);
591         return ret;
592     }
593 
594     memset(&m_ImgProp, 0, sizeof(cam_stream_parm_buffer_t));
595     m_ImgProp.type = CAM_STREAM_PARAM_TYPE_GET_IMG_PROP;
596 
597     ret = getParameter(m_ImgProp);
598     if (ret != NO_ERROR) {
599         ALOGE("%s: stream getParameter for image prop failed", __func__);
600         return ret;
601     }
602 
603     return ret;
604 }
605 
606 /*===========================================================================
607  * FUNCTION   : processZoomDone
608  *
609  * DESCRIPTION: process zoom done event
610  *
611  * PARAMETERS :
612  *   @previewWindoe : preview window ops table to set preview crop window
613  *   @crop_info     : crop info
614  *
615  * RETURN     : int32_t type of status
616  *              NO_ERROR  -- success
617  *              none-zero failure code
618  *==========================================================================*/
processZoomDone(preview_stream_ops_t * previewWindow,cam_crop_data_t & crop_info)619 int32_t QCameraStream::processZoomDone(preview_stream_ops_t *previewWindow,
620                                        cam_crop_data_t &crop_info)
621 {
622     int32_t rc = 0;
623 
624     if (!m_bActive) {
625         ALOGV("%s : Stream not active", __func__);
626         return NO_ERROR;
627     }
628 
629     // get stream param for crop info
630     for (int i = 0; i < crop_info.num_of_streams; i++) {
631         if (crop_info.crop_info[i].stream_id == mStreamInfo->stream_svr_id) {
632             pthread_mutex_lock(&mCropLock);
633             mCropInfo = crop_info.crop_info[i].crop;
634             pthread_mutex_unlock(&mCropLock);
635 
636             // update preview window crop if it's preview/postview stream
637             if ( (previewWindow != NULL) &&
638                  (mStreamInfo->stream_type == CAM_STREAM_TYPE_PREVIEW ||
639                   mStreamInfo->stream_type == CAM_STREAM_TYPE_POSTVIEW) ) {
640                 rc = previewWindow->set_crop(previewWindow,
641                                              mCropInfo.left,
642                                              mCropInfo.top,
643                                              mCropInfo.width,
644                                              mCropInfo.height);
645             }
646             break;
647         }
648     }
649     return rc;
650 }
651 
652 /*===========================================================================
653  * FUNCTION   : processDataNotify
654  *
655  * DESCRIPTION: process stream data notify
656  *
657  * PARAMETERS :
658  *   @frame   : stream frame received
659  *
660  * RETURN     : int32_t type of status
661  *              NO_ERROR  -- success
662  *              none-zero failure code
663  *==========================================================================*/
processDataNotify(mm_camera_super_buf_t * frame)664 int32_t QCameraStream::processDataNotify(mm_camera_super_buf_t *frame)
665 {
666     CDBG("%s:\n", __func__);
667     if (mDataQ.enqueue((void *)frame)) {
668         return mProcTh.sendCmd(CAMERA_CMD_TYPE_DO_NEXT_JOB, FALSE, FALSE);
669     } else {
670         CDBG_HIGH("%s: Stream thread is not active, no ops here", __func__);
671         bufDone(frame->bufs[0]->buf_idx);
672         free(frame);
673         return NO_ERROR;
674     }
675 }
676 
677 /*===========================================================================
678  * FUNCTION   : dataNotifyCB
679  *
680  * DESCRIPTION: callback for data notify. This function is registered with
681  *              mm-camera-interface to handle data notify
682  *
683  * PARAMETERS :
684  *   @recvd_frame   : stream frame received
685  *   userdata       : user data ptr
686  *
687  * RETURN     : none
688  *==========================================================================*/
dataNotifyCB(mm_camera_super_buf_t * recvd_frame,void * userdata)689 void QCameraStream::dataNotifyCB(mm_camera_super_buf_t *recvd_frame,
690                                  void *userdata)
691 {
692     CDBG("%s:\n", __func__);
693     QCameraStream* stream = (QCameraStream *)userdata;
694     if (stream == NULL ||
695         recvd_frame == NULL ||
696         recvd_frame->bufs[0] == NULL ||
697         recvd_frame->bufs[0]->stream_id != stream->getMyHandle()) {
698         ALOGE("%s: Not a valid stream to handle buf", __func__);
699         return;
700     }
701 
702     mm_camera_super_buf_t *frame =
703         (mm_camera_super_buf_t *)malloc(sizeof(mm_camera_super_buf_t));
704     if (frame == NULL) {
705         ALOGE("%s: No mem for mm_camera_buf_def_t", __func__);
706         stream->bufDone(recvd_frame->bufs[0]->buf_idx);
707         return;
708     }
709     *frame = *recvd_frame;
710     stream->processDataNotify(frame);
711     return;
712 }
713 
714 /*===========================================================================
715  * FUNCTION   : dataProcRoutine
716  *
717  * DESCRIPTION: function to process data in the main stream thread
718  *
719  * PARAMETERS :
720  *   @data    : user data ptr
721  *
722  * RETURN     : none
723  *==========================================================================*/
dataProcRoutine(void * data)724 void *QCameraStream::dataProcRoutine(void *data)
725 {
726     int running = 1;
727     int ret;
728     QCameraStream *pme = (QCameraStream *)data;
729     QCameraCmdThread *cmdThread = &pme->mProcTh;
730 
731     CDBG("%s: E", __func__);
732     do {
733         do {
734             ret = cam_sem_wait(&cmdThread->cmd_sem);
735             if (ret != 0 && errno != EINVAL) {
736                 ALOGE("%s: cam_sem_wait error (%s)",
737                       __func__, strerror(errno));
738                 return NULL;
739             }
740         } while (ret != 0);
741 
742         // we got notified about new cmd avail in cmd queue
743         camera_cmd_type_t cmd = cmdThread->getCmd();
744         switch (cmd) {
745         case CAMERA_CMD_TYPE_DO_NEXT_JOB:
746             {
747                 CDBG_HIGH("%s: Do next job", __func__);
748                 mm_camera_super_buf_t *frame =
749                     (mm_camera_super_buf_t *)pme->mDataQ.dequeue();
750                 if (NULL != frame) {
751                     if (pme->mDataCB != NULL) {
752                         pme->mDataCB(frame, pme, pme->mUserData);
753                     } else {
754                         // no data cb routine, return buf here
755                         pme->bufDone(frame->bufs[0]->buf_idx);
756                         free(frame);
757                     }
758                 }
759             }
760             break;
761         case CAMERA_CMD_TYPE_EXIT:
762             CDBG_HIGH("%s: Exit", __func__);
763             /* flush data buf queue */
764             pme->mDataQ.flush();
765             running = 0;
766             break;
767         default:
768             break;
769         }
770     } while (running);
771     CDBG_HIGH("%s: X", __func__);
772     return NULL;
773 }
774 
775 /*===========================================================================
776  * FUNCTION   : bufDone
777  *
778  * DESCRIPTION: return stream buffer to kernel
779  *
780  * PARAMETERS :
781  *   @index   : index of buffer to be returned
782  *
783  * RETURN     : int32_t type of status
784  *              NO_ERROR  -- success
785  *              none-zero failure code
786  *==========================================================================*/
bufDone(int index)787 int32_t QCameraStream::bufDone(int index)
788 {
789     int32_t rc = NO_ERROR;
790 
791     if (index >= mNumBufs || mBufDefs == NULL)
792         return BAD_INDEX;
793 
794     rc = mCamOps->qbuf(mCamHandle, mChannelHandle, &mBufDefs[index]);
795     if (rc < 0)
796         return rc;
797 
798     return rc;
799 }
800 
801 /*===========================================================================
802  * FUNCTION   : bufDone
803  *
804  * DESCRIPTION: return stream buffer to kernel
805  *
806  * PARAMETERS :
807  *   @opaque    : stream frame/metadata buf to be returned
808  *   @isMetaData: flag if returned opaque is a metadatabuf or the real frame ptr
809  *
810  * RETURN     : int32_t type of status
811  *              NO_ERROR  -- success
812  *              none-zero failure code
813  *==========================================================================*/
bufDone(const void * opaque,bool isMetaData)814 int32_t QCameraStream::bufDone(const void *opaque, bool isMetaData)
815 {
816     int32_t rc = NO_ERROR;
817 
818     int index = mStreamBufs->getMatchBufIndex(opaque, isMetaData);
819     if (index == -1 || index >= mNumBufs || mBufDefs == NULL) {
820         ALOGE("%s: Cannot find buf for opaque data = %p", __func__, opaque);
821         return BAD_INDEX;
822     }
823     CDBG_HIGH("%s: Buffer Index = %d, Frame Idx = %d", __func__, index, mBufDefs[index].frame_idx);
824     rc = bufDone(index);
825     return rc;
826 }
827 
828 /*===========================================================================
829  * FUNCTION   : getBufs
830  *
831  * DESCRIPTION: allocate stream buffers
832  *
833  * PARAMETERS :
834  *   @offset     : offset info of stream buffers
835  *   @num_bufs   : number of buffers allocated
836  *   @initial_reg_flag: flag to indicate if buffer needs to be registered
837  *                      at kernel initially
838  *   @bufs       : output of allocated buffers
839  *   @ops_tbl    : ptr to buf mapping/unmapping ops
840  *
841  * RETURN     : int32_t type of status
842  *              NO_ERROR  -- success
843  *              none-zero failure code
844  *==========================================================================*/
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)845 int32_t QCameraStream::getBufs(cam_frame_len_offset_t *offset,
846         uint8_t *num_bufs,
847         uint8_t **initial_reg_flag,
848         mm_camera_buf_def_t **bufs,
849         mm_camera_map_unmap_ops_tbl_t *ops_tbl)
850 {
851     int rc = NO_ERROR;
852     uint8_t *regFlags;
853 
854     if (!ops_tbl) {
855         ALOGE("%s: ops_tbl is NULL", __func__);
856         return INVALID_OPERATION;
857     }
858 
859     mFrameLenOffset = *offset;
860 
861     uint8_t numBufAlloc = mNumBufs;
862     mNumBufsNeedAlloc = 0;
863     if (mDynBufAlloc) {
864         numBufAlloc = CAMERA_MIN_ALLOCATED_BUFFERS;
865         if (numBufAlloc > mNumBufs) {
866             mDynBufAlloc = false;
867             numBufAlloc = mNumBufs;
868         } else {
869             mNumBufsNeedAlloc = mNumBufs - numBufAlloc;
870         }
871     }
872 
873     //Allocate and map stream info buffer
874     mStreamBufs = mAllocator.allocateStreamBuf(mStreamInfo->stream_type,
875                                                mFrameLenOffset.frame_len,
876                                                mFrameLenOffset.mp[0].stride,
877                                                mFrameLenOffset.mp[0].scanline,
878                                                numBufAlloc);
879     mNumBufs = numBufAlloc + mNumBufsNeedAlloc;
880 
881     if (!mStreamBufs) {
882         ALOGE("%s: Failed to allocate stream buffers", __func__);
883         return NO_MEMORY;
884     }
885 
886     for (int i = 0; i < numBufAlloc; i++) {
887         rc = ops_tbl->map_ops(i, -1, mStreamBufs->getFd(i),
888                 mStreamBufs->getSize(i), ops_tbl->userdata);
889         if (rc < 0) {
890             ALOGE("%s: map_stream_buf failed: %d", __func__, rc);
891             for (int j = 0; j < i; j++) {
892                 ops_tbl->unmap_ops(j, -1, ops_tbl->userdata);
893             }
894             mStreamBufs->deallocate();
895             delete mStreamBufs;
896             mStreamBufs = NULL;
897             return INVALID_OPERATION;
898         }
899     }
900 
901     //regFlags array is allocated by us, but consumed and freed by mm-camera-interface
902     regFlags = (uint8_t *)malloc(sizeof(uint8_t) * mNumBufs);
903     if (!regFlags) {
904         ALOGE("%s: Out of memory", __func__);
905         for (int i = 0; i < numBufAlloc; i++) {
906             ops_tbl->unmap_ops(i, -1, ops_tbl->userdata);
907         }
908         mStreamBufs->deallocate();
909         delete mStreamBufs;
910         mStreamBufs = NULL;
911         return NO_MEMORY;
912     }
913     memset(regFlags, 0, sizeof(uint8_t) * mNumBufs);
914 
915     mBufDefs = (mm_camera_buf_def_t *)malloc(mNumBufs * sizeof(mm_camera_buf_def_t));
916     if (mBufDefs == NULL) {
917         ALOGE("%s: getRegFlags failed %d", __func__, rc);
918         for (int i = 0; i < numBufAlloc; i++) {
919             ops_tbl->unmap_ops(i, -1, ops_tbl->userdata);
920         }
921         mStreamBufs->deallocate();
922         delete mStreamBufs;
923         mStreamBufs = NULL;
924         free(regFlags);
925         regFlags = NULL;
926         return INVALID_OPERATION;
927     }
928     memset(mBufDefs, 0, mNumBufs * sizeof(mm_camera_buf_def_t));
929     for (int i = 0; i < numBufAlloc; i++) {
930         mStreamBufs->getBufDef(mFrameLenOffset, mBufDefs[i], i);
931     }
932 
933     rc = mStreamBufs->getRegFlags(regFlags);
934     if (rc < 0) {
935         ALOGE("%s: getRegFlags failed %d", __func__, rc);
936         for (int i = 0; i < numBufAlloc; i++) {
937             ops_tbl->unmap_ops(i, -1, ops_tbl->userdata);
938         }
939         mStreamBufs->deallocate();
940         delete mStreamBufs;
941         mStreamBufs = NULL;
942         free(mBufDefs);
943         mBufDefs = NULL;
944         free(regFlags);
945         regFlags = NULL;
946         return INVALID_OPERATION;
947     }
948 
949     *num_bufs = mNumBufs;
950     *initial_reg_flag = regFlags;
951     *bufs = mBufDefs;
952 
953     if (mNumBufsNeedAlloc > 0) {
954         pthread_mutex_lock(&m_lock);
955         wait_for_cond = TRUE;
956         pthread_mutex_unlock(&m_lock);
957         CDBG_HIGH("%s: Still need to allocate %d buffers",
958               __func__, mNumBufsNeedAlloc);
959         // remember memops table
960         m_MemOpsTbl = *ops_tbl;
961         // start another thread to allocate the rest of buffers
962         pthread_create(&mBufAllocPid,
963                        NULL,
964                        BufAllocRoutine,
965                        this);
966     }
967 
968     return NO_ERROR;
969 }
970 
971 /*===========================================================================
972  * FUNCTION   : allocateBuffers
973  *
974  * DESCRIPTION: allocate stream buffers
975  *
976  * PARAMETERS :
977  *
978  * RETURN     : int32_t type of status
979  *              NO_ERROR  -- success
980  *              none-zero failure code
981  *==========================================================================*/
allocateBuffers()982 int32_t QCameraStream::allocateBuffers()
983 {
984     int rc = NO_ERROR;
985 
986     mFrameLenOffset = mStreamInfo->buf_planes.plane_info;
987 
988     //Allocate and map stream info buffer
989     mStreamBufs = mAllocator.allocateStreamBuf(mStreamInfo->stream_type,
990             mFrameLenOffset.frame_len,
991             mFrameLenOffset.mp[0].stride,
992             mFrameLenOffset.mp[0].scanline,
993             mNumBufs);
994 
995     if (!mStreamBufs) {
996         ALOGE("%s: Failed to allocate stream buffers", __func__);
997         return NO_MEMORY;
998     }
999 
1000     for (int i = 0; i < mNumBufs; i++) {
1001         rc = mapBuf(CAM_MAPPING_BUF_TYPE_STREAM_BUF,
1002                 i, -1,
1003                 mStreamBufs->getFd(i),
1004                 mStreamBufs->getSize(i));
1005         if (rc < 0) {
1006             ALOGE("%s: map_stream_buf failed: %d", __func__, rc);
1007             for (int j = 0; j < i; j++) {
1008                 unmapBuf(CAM_MAPPING_BUF_TYPE_STREAM_BUF, i, -1);
1009             }
1010             mStreamBufs->deallocate();
1011             delete mStreamBufs;
1012             mStreamBufs = NULL;
1013             return INVALID_OPERATION;
1014         }
1015     }
1016 
1017     //regFlags array is allocated by us,
1018     // but consumed and freed by mm-camera-interface
1019     mRegFlags = (uint8_t *)malloc(sizeof(uint8_t) * mNumBufs);
1020     if (!mRegFlags) {
1021         ALOGE("%s: Out of memory", __func__);
1022         for (int i = 0; i < mNumBufs; i++) {
1023             unmapBuf(CAM_MAPPING_BUF_TYPE_STREAM_BUF, i, -1);
1024         }
1025         mStreamBufs->deallocate();
1026         delete mStreamBufs;
1027         mStreamBufs = NULL;
1028         return NO_MEMORY;
1029     }
1030     memset(mRegFlags, 0, sizeof(uint8_t) * mNumBufs);
1031 
1032     size_t bufDefsSize = mNumBufs * sizeof(mm_camera_buf_def_t);
1033     mBufDefs = (mm_camera_buf_def_t *)malloc(bufDefsSize);
1034     if (mBufDefs == NULL) {
1035         ALOGE("%s: getRegFlags failed %d", __func__, rc);
1036         for (int i = 0; i < mNumBufs; i++) {
1037             unmapBuf(CAM_MAPPING_BUF_TYPE_STREAM_BUF, i, -1);
1038         }
1039         mStreamBufs->deallocate();
1040         delete mStreamBufs;
1041         mStreamBufs = NULL;
1042         free(mRegFlags);
1043         mRegFlags = NULL;
1044         return INVALID_OPERATION;
1045     }
1046     memset(mBufDefs, 0, bufDefsSize);
1047     for (int i = 0; i < mNumBufs; i++) {
1048         mStreamBufs->getBufDef(mFrameLenOffset, mBufDefs[i], i);
1049     }
1050 
1051     rc = mStreamBufs->getRegFlags(mRegFlags);
1052     if (rc < 0) {
1053         ALOGE("%s: getRegFlags failed %d", __func__, rc);
1054         for (int i = 0; i < mNumBufs; i++) {
1055             unmapBuf(CAM_MAPPING_BUF_TYPE_STREAM_BUF, i, -1);
1056         }
1057         mStreamBufs->deallocate();
1058         delete mStreamBufs;
1059         mStreamBufs = NULL;
1060         free(mBufDefs);
1061         mBufDefs = NULL;
1062         free(mRegFlags);
1063         mRegFlags = NULL;
1064         return INVALID_OPERATION;
1065     }
1066 
1067     return NO_ERROR;
1068 }
1069 
1070 
1071 /*===========================================================================
1072  * FUNCTION   : releaseBuffs
1073  *
1074  * DESCRIPTION: method to deallocate stream buffers
1075  *
1076  * PARAMETERS :
1077  *
1078  * RETURN     : int32_t type of status
1079  *              NO_ERROR  -- success
1080  *              none-zero failure code
1081  *==========================================================================*/
releaseBuffs()1082 int32_t QCameraStream::releaseBuffs()
1083 {
1084     int rc = NO_ERROR;
1085 
1086     if (NULL != mBufDefs) {
1087         for (int i = 0; i < mNumBufs; i++) {
1088             rc = unmapBuf(CAM_MAPPING_BUF_TYPE_STREAM_BUF, i, -1);
1089             if (rc < 0) {
1090                 ALOGE("%s: map_stream_buf failed: %d", __func__, rc);
1091             }
1092         }
1093 
1094         // mBufDefs just keep a ptr to the buffer
1095         // mm-camera-interface own the buffer, so no need to free
1096         mBufDefs = NULL;
1097         memset(&mFrameLenOffset, 0, sizeof(mFrameLenOffset));
1098     }
1099     if ( !mStreamBufsAcquired ) {
1100         mStreamBufs->deallocate();
1101         delete mStreamBufs;
1102     }
1103 
1104     return rc;
1105 }
1106 
1107 
1108 /*===========================================================================
1109  * FUNCTION   : BufAllocRoutine
1110  *
1111  * DESCRIPTION: function to allocate additional stream buffers
1112  *
1113  * PARAMETERS :
1114  *   @data    : user data ptr
1115  *
1116  * RETURN     : none
1117  *==========================================================================*/
BufAllocRoutine(void * data)1118 void *QCameraStream::BufAllocRoutine(void *data)
1119 {
1120     QCameraStream *pme = (QCameraStream *)data;
1121     int32_t rc = NO_ERROR;
1122 
1123     CDBG_HIGH("%s: E", __func__);
1124     pme->cond_wait();
1125     if (pme->mNumBufsNeedAlloc > 0) {
1126         uint8_t numBufAlloc = pme->mNumBufs - pme->mNumBufsNeedAlloc;
1127         rc = pme->mAllocator.allocateMoreStreamBuf(pme->mStreamBufs,
1128                                                    pme->mFrameLenOffset.frame_len,
1129                                                    pme->mNumBufsNeedAlloc);
1130         if (rc == NO_ERROR){
1131             for (int i = numBufAlloc; i < pme->mNumBufs; i++) {
1132                 rc = pme->m_MemOpsTbl.map_ops(i, -1,
1133                                               pme->mStreamBufs->getFd(i),
1134                                               pme->mStreamBufs->getSize(i),
1135                                               pme->m_MemOpsTbl.userdata);
1136                 if (rc == 0) {
1137                     pme->mStreamBufs->getBufDef(pme->mFrameLenOffset,
1138                                                 pme->mBufDefs[i], i);
1139                     pme->mCamOps->qbuf(pme->mCamHandle,
1140                                        pme->mChannelHandle,
1141                                        &pme->mBufDefs[i]);
1142                 } else {
1143                     ALOGE("%s: map_stream_buf %d failed: %d", __func__, rc, i);
1144                 }
1145             }
1146 
1147             pme->mNumBufsNeedAlloc = 0;
1148         }
1149     }
1150     CDBG_HIGH("%s: X", __func__);
1151     return NULL;
1152 }
1153 
1154 /*===========================================================================
1155  * FUNCTION   : cond_signal
1156  *
1157  * DESCRIPTION: signal if flag "wait_for_cond" is set
1158  *
1159  *==========================================================================*/
cond_signal()1160 void QCameraStream::cond_signal()
1161 {
1162     pthread_mutex_lock(&m_lock);
1163     if(wait_for_cond == TRUE){
1164         wait_for_cond = FALSE;
1165         pthread_cond_signal(&m_cond);
1166     }
1167     pthread_mutex_unlock(&m_lock);
1168 }
1169 
1170 
1171 /*===========================================================================
1172  * FUNCTION   : cond_wait
1173  *
1174  * DESCRIPTION: wait on if flag "wait_for_cond" is set
1175  *
1176  *==========================================================================*/
cond_wait()1177 void QCameraStream::cond_wait()
1178 {
1179     pthread_mutex_lock(&m_lock);
1180     while (wait_for_cond == TRUE) {
1181         pthread_cond_wait(&m_cond, &m_lock);
1182     }
1183     pthread_mutex_unlock(&m_lock);
1184 }
1185 
1186 /*===========================================================================
1187  * FUNCTION   : putBufs
1188  *
1189  * DESCRIPTION: deallocate stream buffers
1190  *
1191  * PARAMETERS :
1192  *   @ops_tbl    : ptr to buf mapping/unmapping ops
1193  *
1194  * RETURN     : int32_t type of status
1195  *              NO_ERROR  -- success
1196  *              none-zero failure code
1197  *==========================================================================*/
putBufs(mm_camera_map_unmap_ops_tbl_t * ops_tbl)1198 int32_t QCameraStream::putBufs(mm_camera_map_unmap_ops_tbl_t *ops_tbl)
1199 {
1200     int rc = NO_ERROR;
1201 
1202     if (mBufAllocPid != 0) {
1203         CDBG_HIGH("%s: wait for buf allocation thread dead", __func__);
1204         pthread_join(mBufAllocPid, NULL);
1205         mBufAllocPid = 0;
1206         CDBG_HIGH("%s: return from buf allocation thread", __func__);
1207     }
1208 
1209     for (int i = 0; i < mNumBufs; i++) {
1210         rc = ops_tbl->unmap_ops(i, -1, ops_tbl->userdata);
1211         if (rc < 0) {
1212             ALOGE("%s: map_stream_buf failed: %d", __func__, rc);
1213         }
1214     }
1215     mBufDefs = NULL; // mBufDefs just keep a ptr to the buffer
1216                      // mm-camera-interface own the buffer, so no need to free
1217     memset(&mFrameLenOffset, 0, sizeof(mFrameLenOffset));
1218     if ( !mStreamBufsAcquired ) {
1219         mStreamBufs->deallocate();
1220         delete mStreamBufs;
1221     }
1222 
1223     return rc;
1224 }
1225 
1226 /*===========================================================================
1227  * FUNCTION   : invalidateBuf
1228  *
1229  * DESCRIPTION: invalidate a specific stream buffer
1230  *
1231  * PARAMETERS :
1232  *   @index   : index of the buffer to invalidate
1233  *
1234  * RETURN     : int32_t type of status
1235  *              NO_ERROR  -- success
1236  *              none-zero failure code
1237  *==========================================================================*/
invalidateBuf(int index)1238 int32_t QCameraStream::invalidateBuf(int index)
1239 {
1240     return mStreamBufs->invalidateCache(index);
1241 }
1242 
1243 /*===========================================================================
1244  * FUNCTION   : cleanInvalidateBuf
1245  *
1246  * DESCRIPTION: clean invalidate a specific stream buffer
1247  *
1248  * PARAMETERS :
1249  *   @index   : index of the buffer to clean invalidate
1250  *
1251  * RETURN     : int32_t type of status
1252  *              NO_ERROR  -- success
1253  *              none-zero failure code
1254  *==========================================================================*/
cleanInvalidateBuf(int index)1255 int32_t QCameraStream::cleanInvalidateBuf(int index)
1256 {
1257     return mStreamBufs->cleanInvalidateCache(index);
1258 }
1259 
1260 /*===========================================================================
1261  * FUNCTION   : isTypeOf
1262  *
1263  * DESCRIPTION: helper function to determine if the stream is of the queried type
1264  *
1265  * PARAMETERS :
1266  *   @type    : stream type as of queried
1267  *
1268  * RETURN     : true/false
1269  *==========================================================================*/
isTypeOf(cam_stream_type_t type)1270 bool QCameraStream::isTypeOf(cam_stream_type_t type)
1271 {
1272     if (mStreamInfo != NULL && (mStreamInfo->stream_type == type)) {
1273         return true;
1274     } else {
1275         return false;
1276     }
1277 }
1278 
1279 /*===========================================================================
1280  * FUNCTION   : isOrignalTypeOf
1281  *
1282  * DESCRIPTION: helper function to determine if the original stream is of the
1283  *              queried type if it's reproc stream
1284  *
1285  * PARAMETERS :
1286  *   @type    : stream type as of queried
1287  *
1288  * RETURN     : true/false
1289  *==========================================================================*/
isOrignalTypeOf(cam_stream_type_t type)1290 bool QCameraStream::isOrignalTypeOf(cam_stream_type_t type)
1291 {
1292     if (mStreamInfo != NULL &&
1293         mStreamInfo->stream_type == CAM_STREAM_TYPE_OFFLINE_PROC &&
1294         mStreamInfo->reprocess_config.pp_type == CAM_ONLINE_REPROCESS_TYPE &&
1295         mStreamInfo->reprocess_config.online.input_stream_type == type) {
1296         return true;
1297     } else if (
1298         mStreamInfo != NULL &&
1299         mStreamInfo->stream_type == CAM_STREAM_TYPE_OFFLINE_PROC &&
1300         mStreamInfo->reprocess_config.pp_type == CAM_OFFLINE_REPROCESS_TYPE &&
1301         mStreamInfo->reprocess_config.offline.input_type == type) {
1302         return true;
1303     } else {
1304         return false;
1305     }
1306 }
1307 
1308 /*===========================================================================
1309  * FUNCTION   : getMyType
1310  *
1311  * DESCRIPTION: return stream type
1312  *
1313  * PARAMETERS : none
1314  *
1315  * RETURN     : stream type
1316  *==========================================================================*/
getMyType()1317 cam_stream_type_t QCameraStream::getMyType()
1318 {
1319     if (mStreamInfo != NULL) {
1320         return mStreamInfo->stream_type;
1321     } else {
1322         return CAM_STREAM_TYPE_DEFAULT;
1323     }
1324 }
1325 
1326 /*===========================================================================
1327  * FUNCTION   : getFrameOffset
1328  *
1329  * DESCRIPTION: query stream buffer frame offset info
1330  *
1331  * PARAMETERS :
1332  *   @offset  : reference to struct to store the queried frame offset info
1333  *
1334  * RETURN     : int32_t type of status
1335  *              NO_ERROR  -- success
1336  *              none-zero failure code
1337  *==========================================================================*/
getFrameOffset(cam_frame_len_offset_t & offset)1338 int32_t QCameraStream::getFrameOffset(cam_frame_len_offset_t &offset)
1339 {
1340     offset = mFrameLenOffset;
1341     return 0;
1342 }
1343 
1344 /*===========================================================================
1345  * FUNCTION   : getCropInfo
1346  *
1347  * DESCRIPTION: query crop info of the stream
1348  *
1349  * PARAMETERS :
1350  *   @crop    : reference to struct to store the queried crop info
1351  *
1352  * RETURN     : int32_t type of status
1353  *              NO_ERROR  -- success
1354  *              none-zero failure code
1355  *==========================================================================*/
getCropInfo(cam_rect_t & crop)1356 int32_t QCameraStream::getCropInfo(cam_rect_t &crop)
1357 {
1358     pthread_mutex_lock(&mCropLock);
1359     crop = mCropInfo;
1360     pthread_mutex_unlock(&mCropLock);
1361     return NO_ERROR;
1362 }
1363 
1364 /*===========================================================================
1365  * FUNCTION   : setCropInfo
1366  *
1367  * DESCRIPTION: set crop info of the stream
1368  *
1369  * PARAMETERS :
1370  *   @crop    : struct to store new crop info
1371  *
1372  * RETURN     : int32_t type of status
1373  *              NO_ERROR  -- success
1374  *              none-zero failure code
1375  *==========================================================================*/
setCropInfo(cam_rect_t crop)1376 int32_t QCameraStream::setCropInfo(cam_rect_t crop)
1377 {
1378     pthread_mutex_lock(&mCropLock);
1379     mCropInfo = crop;
1380     pthread_mutex_unlock(&mCropLock);
1381     return NO_ERROR;
1382 }
1383 
1384 /*===========================================================================
1385  * FUNCTION   : getFrameDimension
1386  *
1387  * DESCRIPTION: query stream frame dimension info
1388  *
1389  * PARAMETERS :
1390  *   @dim     : reference to struct to store the queried frame dimension
1391  *
1392  * RETURN     : int32_t type of status
1393  *              NO_ERROR  -- success
1394  *              none-zero failure code
1395  *==========================================================================*/
getFrameDimension(cam_dimension_t & dim)1396 int32_t QCameraStream::getFrameDimension(cam_dimension_t &dim)
1397 {
1398     if (mStreamInfo != NULL) {
1399         dim = mStreamInfo->dim;
1400         return 0;
1401     }
1402     return -1;
1403 }
1404 
1405 /*===========================================================================
1406  * FUNCTION   : getFormat
1407  *
1408  * DESCRIPTION: query stream format
1409  *
1410  * PARAMETERS :
1411  *   @fmt     : reference to stream format
1412  *
1413  * RETURN     : int32_t type of status
1414  *              NO_ERROR  -- success
1415  *              none-zero failure code
1416  *==========================================================================*/
getFormat(cam_format_t & fmt)1417 int32_t QCameraStream::getFormat(cam_format_t &fmt)
1418 {
1419     if (mStreamInfo != NULL) {
1420         fmt = mStreamInfo->fmt;
1421         return 0;
1422     }
1423     return -1;
1424 }
1425 
1426 /*===========================================================================
1427  * FUNCTION   : getMyServerID
1428  *
1429  * DESCRIPTION: query server stream ID
1430  *
1431  * PARAMETERS : None
1432  *
1433  * RETURN     : stream ID from server
1434  *==========================================================================*/
getMyServerID()1435 uint32_t QCameraStream::getMyServerID() {
1436     if (mStreamInfo != NULL) {
1437         return mStreamInfo->stream_svr_id;
1438     } else {
1439         return 0;
1440     }
1441 }
1442 
1443 /*===========================================================================
1444  * FUNCTION   : acquireStreamBufs
1445  *
1446  * DESCRIPTION: acquire stream buffers and postpone their release.
1447  *
1448  * PARAMETERS : None
1449  *
1450  * RETURN     : int32_t type of status
1451  *              NO_ERROR  -- success
1452  *              none-zero failure code
1453  *==========================================================================*/
acquireStreamBufs()1454 int32_t QCameraStream::acquireStreamBufs()
1455 {
1456     mStreamBufsAcquired = true;
1457 
1458     return NO_ERROR;
1459 }
1460 
1461 /*===========================================================================
1462  * FUNCTION   : mapBuf
1463  *
1464  * DESCRIPTION: map stream related buffer to backend server
1465  *
1466  * PARAMETERS :
1467  *   @buf_type : mapping type of buffer
1468  *   @buf_idx  : index of buffer
1469  *   @plane_idx: plane index
1470  *   @fd       : fd of the buffer
1471  *   @size     : lenght of the buffer
1472  *
1473  * RETURN     : int32_t type of status
1474  *              NO_ERROR  -- success
1475  *              none-zero failure code
1476  *==========================================================================*/
mapBuf(uint8_t buf_type,uint32_t buf_idx,int32_t plane_idx,int fd,uint32_t size)1477 int32_t QCameraStream::mapBuf(uint8_t buf_type,
1478                               uint32_t buf_idx,
1479                               int32_t plane_idx,
1480                               int fd,
1481                               uint32_t size)
1482 {
1483     return mCamOps->map_stream_buf(mCamHandle, mChannelHandle,
1484                                    mHandle, buf_type,
1485                                    buf_idx, plane_idx,
1486                                    fd, size);
1487 
1488 }
1489 
1490 /*===========================================================================
1491  * FUNCTION   : unmapBuf
1492  *
1493  * DESCRIPTION: unmap stream related buffer to backend server
1494  *
1495  * PARAMETERS :
1496  *   @buf_type : mapping type of buffer
1497  *   @buf_idx  : index of buffer
1498  *   @plane_idx: plane index
1499  *
1500  * RETURN     : int32_t type of status
1501  *              NO_ERROR  -- success
1502  *              none-zero failure code
1503  *==========================================================================*/
unmapBuf(uint8_t buf_type,uint32_t buf_idx,int32_t plane_idx)1504 int32_t QCameraStream::unmapBuf(uint8_t buf_type, uint32_t buf_idx, int32_t plane_idx)
1505 {
1506     return mCamOps->unmap_stream_buf(mCamHandle, mChannelHandle,
1507                                      mHandle, buf_type,
1508                                      buf_idx, plane_idx);
1509 
1510 }
1511 
1512 /*===========================================================================
1513  * FUNCTION   : setParameter
1514  *
1515  * DESCRIPTION: set stream based parameters
1516  *
1517  * PARAMETERS :
1518  *   @param   : ptr to parameters to be set
1519  *
1520  * RETURN     : int32_t type of status
1521  *              NO_ERROR  -- success
1522  *              none-zero failure code
1523  *==========================================================================*/
setParameter(cam_stream_parm_buffer_t & param)1524 int32_t QCameraStream::setParameter(cam_stream_parm_buffer_t &param)
1525 {
1526     int32_t rc = NO_ERROR;
1527     pthread_mutex_lock(&mParameterLock);
1528     mStreamInfo->parm_buf = param;
1529     rc = mCamOps->set_stream_parms(mCamHandle,
1530                                    mChannelHandle,
1531                                    mHandle,
1532                                    &mStreamInfo->parm_buf);
1533     if (rc == NO_ERROR) {
1534         param = mStreamInfo->parm_buf;
1535     }
1536     pthread_mutex_unlock(&mParameterLock);
1537     return rc;
1538 }
1539 
1540 /*===========================================================================
1541  * FUNCTION   : getParameter
1542  *
1543  * DESCRIPTION: get stream based parameters
1544  *
1545  * PARAMETERS :
1546  *   @param   : ptr to parameters to be red
1547  *
1548  * RETURN     : int32_t type of status
1549  *              NO_ERROR  -- success
1550  *              none-zero failure code
1551  *==========================================================================*/
getParameter(cam_stream_parm_buffer_t & param)1552 int32_t QCameraStream::getParameter(cam_stream_parm_buffer_t &param)
1553 {
1554     int32_t rc = NO_ERROR;
1555     pthread_mutex_lock(&mParameterLock);
1556     mStreamInfo->parm_buf = param;
1557     rc = mCamOps->get_stream_parms(mCamHandle,
1558                                    mChannelHandle,
1559                                    mHandle,
1560                                    &mStreamInfo->parm_buf);
1561     if (rc == NO_ERROR) {
1562         param = mStreamInfo->parm_buf;
1563     }
1564     pthread_mutex_unlock(&mParameterLock);
1565     return rc;
1566 }
1567 
1568 /*===========================================================================
1569  * FUNCTION   : releaseFrameData
1570  *
1571  * DESCRIPTION: callback function to release frame data node
1572  *
1573  * PARAMETERS :
1574  *   @data      : ptr to post process input data
1575  *   @user_data : user data ptr (QCameraReprocessor)
1576  *
1577  * RETURN     : None
1578  *==========================================================================*/
releaseFrameData(void * data,void * user_data)1579 void QCameraStream::releaseFrameData(void *data, void *user_data)
1580 {
1581     QCameraStream *pme = (QCameraStream *)user_data;
1582     mm_camera_super_buf_t *frame = (mm_camera_super_buf_t *)data;
1583     if (NULL != pme) {
1584         pme->bufDone(frame->bufs[0]->buf_idx);
1585     }
1586 }
1587 
1588 /*===========================================================================
1589  * FUNCTION   : configStream
1590  *
1591  * DESCRIPTION: send stream configuration to back end
1592  *
1593  * PARAMETERS :
1594  *
1595  * RETURN     : int32_t type of status
1596  *              NO_ERROR  -- success
1597  *              none-zero failure code
1598  *==========================================================================*/
configStream()1599 int32_t QCameraStream::configStream()
1600 {
1601     int rc = NO_ERROR;
1602 
1603     // Configure the stream
1604     mm_camera_stream_config_t stream_config;
1605     stream_config.stream_info = mStreamInfo;
1606     stream_config.mem_vtbl = mMemVtbl;
1607     stream_config.stream_cb = dataNotifyCB;
1608     stream_config.padding_info = mPaddingInfo;
1609     stream_config.userdata = this;
1610     rc = mCamOps->config_stream(mCamHandle,
1611                 mChannelHandle, mHandle, &stream_config);
1612     if (rc < 0) {
1613         ALOGE("Failed to config stream, rc = %d", rc);
1614         mCamOps->unmap_stream_buf(mCamHandle,
1615                 mChannelHandle,
1616                 mHandle,
1617                 CAM_MAPPING_BUF_TYPE_STREAM_INFO,
1618                 0,
1619                 -1);
1620         return UNKNOWN_ERROR;
1621     }
1622 
1623     return rc;
1624 }
1625 
1626 }; // namespace qcamera
1627