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 ¶m)
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 ¶m)
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