1 /* Copyright (c) 2012-2015, 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 <QComOMXMetadata.h>
34 #include "QCamera2HWI.h"
35 #include "QCameraStream.h"
36
37 #define CAMERA_MIN_ALLOCATED_BUFFERS 3
38
39 namespace qcamera {
40
41 /*===========================================================================
42 * FUNCTION : get_bufs
43 *
44 * DESCRIPTION: static function entry to allocate stream buffers
45 *
46 * PARAMETERS :
47 * @offset : offset info of stream buffers
48 * @num_bufs : number of buffers allocated
49 * @initial_reg_flag: flag to indicate if buffer needs to be registered
50 * at kernel initially
51 * @bufs : output of allocated buffers
52 * @ops_tbl : ptr to buf mapping/unmapping ops
53 * @user_data : user data ptr of ops_tbl
54 *
55 * RETURN : int32_t type of status
56 * NO_ERROR -- success
57 * none-zero failure code
58 *==========================================================================*/
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)59 int32_t QCameraStream::get_bufs(
60 cam_frame_len_offset_t *offset,
61 uint8_t *num_bufs,
62 uint8_t **initial_reg_flag,
63 mm_camera_buf_def_t **bufs,
64 mm_camera_map_unmap_ops_tbl_t *ops_tbl,
65 void *user_data)
66 {
67 QCameraStream *stream = reinterpret_cast<QCameraStream *>(user_data);
68 if (!stream) {
69 ALOGE("getBufs invalid stream pointer");
70 return NO_MEMORY;
71 }
72
73 if (stream->mStreamInfo != NULL
74 && stream->mStreamInfo->streaming_mode == CAM_STREAMING_MODE_BATCH) {
75 //Batch Mode. Allocate Butch buffers
76 return stream->allocateBatchBufs(offset, num_bufs,
77 initial_reg_flag, bufs, ops_tbl);
78 } else {
79 // Plane Buffer. Allocate plane buffer
80 return stream->getBufs(offset, num_bufs,
81 initial_reg_flag, bufs, ops_tbl);
82 }
83 }
84
85 /*===========================================================================
86 * FUNCTION : get_bufs_deffered
87 *
88 * DESCRIPTION: static function entry to allocate deffered stream buffers
89 *
90 * PARAMETERS :
91 * @offset : offset info of stream buffers
92 * @num_bufs : number of buffers allocated
93 * @initial_reg_flag: flag to indicate if buffer needs to be registered
94 * at kernel initially
95 * @bufs : output of allocated buffers
96 * @ops_tbl : ptr to buf mapping/unmapping ops
97 * @user_data : user data ptr of ops_tbl
98 *
99 * RETURN : int32_t type of status
100 * NO_ERROR -- success
101 * none-zero failure code
102 *==========================================================================*/
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)103 int32_t QCameraStream::get_bufs_deffered(
104 cam_frame_len_offset_t * /* offset */,
105 uint8_t *num_bufs,
106 uint8_t **initial_reg_flag,
107 mm_camera_buf_def_t **bufs,
108 mm_camera_map_unmap_ops_tbl_t * /* ops_tbl */,
109 void *user_data)
110 {
111 QCameraStream *stream = reinterpret_cast<QCameraStream *>(user_data);
112 if (!stream) {
113 ALOGE("getBufs invalid stream pointer");
114 return NO_MEMORY;
115 }
116
117 *initial_reg_flag = stream->mRegFlags;
118 *num_bufs = stream->mNumBufs;
119 *bufs = stream->mBufDefs;
120 CDBG_HIGH("%s: stream type: %d, mRegFlags: %p, numBufs: %d",
121 __func__, stream->getMyType(), stream->mRegFlags, stream->mNumBufs);
122 return NO_ERROR;
123 }
124
125 /*===========================================================================
126 * FUNCTION : put_bufs
127 *
128 * DESCRIPTION: static function entry to deallocate stream buffers
129 *
130 * PARAMETERS :
131 * @ops_tbl : ptr to buf mapping/unmapping ops
132 * @user_data : user data ptr of ops_tbl
133 *
134 * RETURN : int32_t type of status
135 * NO_ERROR -- success
136 * none-zero failure code
137 *==========================================================================*/
put_bufs(mm_camera_map_unmap_ops_tbl_t * ops_tbl,void * user_data)138 int32_t QCameraStream::put_bufs(
139 mm_camera_map_unmap_ops_tbl_t *ops_tbl,
140 void *user_data)
141 {
142 QCameraStream *stream = reinterpret_cast<QCameraStream *>(user_data);
143 if (!stream) {
144 ALOGE("putBufs invalid stream pointer");
145 return NO_MEMORY;
146 }
147
148 if (stream->mStreamInfo != NULL
149 && stream->mStreamInfo->streaming_mode == CAM_STREAMING_MODE_BATCH) {
150 //Batch Mode. release Butch buffers
151 return stream->releaseBatchBufs(ops_tbl);
152 } else {
153 // Plane Buffer. release plane buffer
154 return stream->putBufs(ops_tbl);
155 }
156
157 }
158
159 /*===========================================================================
160 * FUNCTION : put_bufs_deffered
161 *
162 * DESCRIPTION: static function entry to deallocate deffered stream buffers
163 *
164 * PARAMETERS :
165 * @ops_tbl : ptr to buf mapping/unmapping ops
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 *==========================================================================*/
put_bufs_deffered(mm_camera_map_unmap_ops_tbl_t *,void *)172 int32_t QCameraStream::put_bufs_deffered(
173 mm_camera_map_unmap_ops_tbl_t * /*ops_tbl */,
174 void * /*user_data*/ )
175 {
176 // No op
177 // Used for handling buffers with deffered allocation. They are freed separately.
178 return NO_ERROR;
179 }
180
181 /*===========================================================================
182 * FUNCTION : invalidate_buf
183 *
184 * DESCRIPTION: static function entry to invalidate a specific stream buffer
185 *
186 * PARAMETERS :
187 * @index : index of the stream buffer to invalidate
188 * @user_data : user data ptr of ops_tbl
189 *
190 * RETURN : int32_t type of status
191 * NO_ERROR -- success
192 * none-zero failure code
193 *==========================================================================*/
invalidate_buf(uint32_t index,void * user_data)194 int32_t QCameraStream::invalidate_buf(uint32_t index, void *user_data)
195 {
196 QCameraStream *stream = reinterpret_cast<QCameraStream *>(user_data);
197 if (!stream) {
198 ALOGE("invalid stream pointer");
199 return NO_MEMORY;
200 }
201
202 if (stream->mStreamInfo->is_secure == SECURE){
203 return 0;
204 }
205
206 if (stream->mStreamInfo->streaming_mode == CAM_STREAMING_MODE_BATCH) {
207 for (int i = 0; i < stream->mBufDefs[index].user_buf.bufs_used; i++) {
208 uint32_t buf_idx = stream->mBufDefs[index].user_buf.buf_idx[i];
209 stream->invalidateBuf(buf_idx);
210 }
211 } else {
212 return stream->invalidateBuf(index);
213 }
214
215 return 0;
216 }
217
218 /*===========================================================================
219 * FUNCTION : clean_invalidate_buf
220 *
221 * DESCRIPTION: static function entry to clean invalidate a specific stream buffer
222 *
223 * PARAMETERS :
224 * @index : index of the stream buffer to clean invalidate
225 * @user_data : user data ptr of ops_tbl
226 *
227 * RETURN : int32_t type of status
228 * NO_ERROR -- success
229 * none-zero failure code
230 *==========================================================================*/
clean_invalidate_buf(uint32_t index,void * user_data)231 int32_t QCameraStream::clean_invalidate_buf(uint32_t index, void *user_data)
232 {
233 QCameraStream *stream = reinterpret_cast<QCameraStream *>(user_data);
234 if (!stream) {
235 ALOGE("invalid stream pointer");
236 return NO_MEMORY;
237 }
238
239 if (stream->mStreamInfo->is_secure == SECURE){
240 return 0;
241 }
242
243 if (stream->mStreamInfo->streaming_mode == CAM_STREAMING_MODE_BATCH) {
244 for (int i = 0; i < stream->mBufDefs[index].user_buf.bufs_used; i++) {
245 uint32_t buf_idx = stream->mBufDefs[index].user_buf.buf_idx[i];
246 stream->cleanInvalidateBuf(buf_idx);
247 }
248 } else {
249 return stream->cleanInvalidateBuf(index);
250 }
251
252 return 0;
253 }
254
255 /*===========================================================================
256 * FUNCTION : QCameraStream
257 *
258 * DESCRIPTION: constructor of QCameraStream
259 *
260 * PARAMETERS :
261 * @allocator : memory allocator obj
262 * @camHandle : camera handle
263 * @chId : channel handle
264 * @camOps : ptr to camera ops table
265 * @paddingInfo: ptr to padding info
266 * @deffered : deferred stream
267 * @online_rotation: rotation applied online
268 *
269 * RETURN : None
270 *==========================================================================*/
QCameraStream(QCameraAllocator & allocator,uint32_t camHandle,uint32_t chId,mm_camera_ops_t * camOps,cam_padding_info_t * paddingInfo,bool deffered,cam_rotation_t online_rotation)271 QCameraStream::QCameraStream(QCameraAllocator &allocator,
272 uint32_t camHandle, uint32_t chId,
273 mm_camera_ops_t *camOps, cam_padding_info_t *paddingInfo,
274 bool deffered, cam_rotation_t online_rotation):
275 mDumpFrame(0),
276 mDumpMetaFrame(0),
277 mDumpSkipCnt(0),
278 mCamHandle(camHandle),
279 mChannelHandle(chId),
280 mHandle(0),
281 mCamOps(camOps),
282 mStreamInfo(NULL),
283 mNumBufs(0),
284 mNumPlaneBufs(0),
285 mNumBufsNeedAlloc(0),
286 mDataCB(NULL),
287 mUserData(NULL),
288 mDataQ(releaseFrameData, this),
289 mStreamInfoBuf(NULL),
290 mMiscBuf(NULL),
291 mStreamBufs(NULL),
292 mStreamBatchBufs(NULL),
293 mAllocator(allocator),
294 mBufDefs(NULL),
295 mPlaneBufDefs(NULL),
296 mOnlineRotation(online_rotation),
297 mStreamBufsAcquired(false),
298 m_bActive(false),
299 mDynBufAlloc(false),
300 mBufAllocPid(0),
301 mDefferedAllocation(deffered),
302 wait_for_cond(false)
303 {
304 mMemVtbl.user_data = this;
305 if ( !deffered ) {
306 mMemVtbl.get_bufs = get_bufs;
307 mMemVtbl.put_bufs = put_bufs;
308 } else {
309 mMemVtbl.get_bufs = get_bufs_deffered;
310 mMemVtbl.put_bufs = put_bufs_deffered;
311 }
312 mMemVtbl.invalidate_buf = invalidate_buf;
313 mMemVtbl.clean_invalidate_buf = clean_invalidate_buf;
314 memset(&mFrameLenOffset, 0, sizeof(mFrameLenOffset));
315 memcpy(&mPaddingInfo, paddingInfo, sizeof(cam_padding_info_t));
316 memset(&mCropInfo, 0, sizeof(cam_rect_t));
317 memset(&m_MemOpsTbl, 0, sizeof(mm_camera_map_unmap_ops_tbl_t));
318 memset(&m_OutputCrop, 0, sizeof(cam_stream_parm_buffer_t));
319 memset(&m_ImgProp, 0, sizeof(cam_stream_parm_buffer_t));
320 pthread_mutex_init(&mCropLock, NULL);
321 pthread_mutex_init(&mParameterLock, NULL);
322 }
323
324 /*===========================================================================
325 * FUNCTION : ~QCameraStream
326 *
327 * DESCRIPTION: deconstructor of QCameraStream
328 *
329 * PARAMETERS : None
330 *
331 * RETURN : None
332 *==========================================================================*/
~QCameraStream()333 QCameraStream::~QCameraStream()
334 {
335 pthread_mutex_destroy(&mCropLock);
336 pthread_mutex_destroy(&mParameterLock);
337
338 if (mDefferedAllocation) {
339 mStreamBufsAcquired = false;
340 releaseBuffs();
341 }
342
343 unmapStreamInfoBuf();
344 releaseStreamInfoBuf();
345
346 if (mMiscBuf) {
347 unMapBuf(mMiscBuf, CAM_MAPPING_BUF_TYPE_MISC_BUF, NULL);
348 releaseMiscBuf();
349 }
350
351 // delete stream
352 if (mHandle > 0) {
353 mCamOps->delete_stream(mCamHandle, mChannelHandle, mHandle);
354 mHandle = 0;
355 }
356 }
357
358 /*===========================================================================
359 * FUNCTION : unmapStreamInfoBuf
360 *
361 * DESCRIPTION: Unmap stream info buffer
362 *
363 * PARAMETERS :
364 *
365 * RETURN : int32_t type of status
366 * NO_ERROR -- success
367 * none-zero failure code
368 *==========================================================================*/
unmapStreamInfoBuf()369 int32_t QCameraStream::unmapStreamInfoBuf()
370 {
371 int rc = NO_ERROR;
372
373 if (mStreamInfoBuf != NULL) {
374 rc = mCamOps->unmap_stream_buf(mCamHandle,
375 mChannelHandle,
376 mHandle,
377 CAM_MAPPING_BUF_TYPE_STREAM_INFO,
378 0,
379 -1);
380
381 if (rc < 0) {
382 ALOGE("Failed to unmap stream info buffer");
383 }
384 }
385
386 return rc;
387 }
388
389 /*===========================================================================
390 * FUNCTION : releaseMiscBuf
391 *
392 * DESCRIPTION: Release misc buffers
393 *
394 * PARAMETERS :
395 *
396 * RETURN : int32_t type of status
397 * NO_ERROR -- success
398 * none-zero failure code
399 *==========================================================================*/
releaseMiscBuf()400 int32_t QCameraStream::releaseMiscBuf()
401 {
402 int rc = NO_ERROR;
403
404 if (mMiscBuf != NULL) {
405 mMiscBuf->deallocate();
406 delete mMiscBuf;
407 mMiscBuf = NULL;
408 }
409
410 return rc;
411 }
412
413 /*===========================================================================
414 * FUNCTION : releaseStreamInfoBuf
415 *
416 * DESCRIPTION: Release stream info buffer
417 *
418 * PARAMETERS :
419 *
420 * RETURN : int32_t type of status
421 * NO_ERROR -- success
422 * none-zero failure code
423 *==========================================================================*/
releaseStreamInfoBuf()424 int32_t QCameraStream::releaseStreamInfoBuf()
425 {
426 int rc = NO_ERROR;
427
428 if (mStreamInfoBuf != NULL) {
429 mStreamInfoBuf->deallocate();
430 delete mStreamInfoBuf;
431 mStreamInfoBuf = NULL;
432 }
433
434 return rc;
435 }
436
437 /*===========================================================================
438 * FUNCTION : deleteStream
439 *
440 * DESCRIPTION: Deletes a camera stream
441 *
442 * PARAMETERS : None
443 *
444 * RETURN : None
445 *==========================================================================*/
deleteStream()446 void QCameraStream::deleteStream()
447 {
448 if (mHandle > 0) {
449 acquireStreamBufs();
450 releaseBuffs();
451 unmapStreamInfoBuf();
452 mCamOps->delete_stream(mCamHandle, mChannelHandle, mHandle);
453 }
454 }
455
456 /*===========================================================================
457 * FUNCTION : unMapBuf
458 *
459 * DESCRIPTION: unmaps buffers
460 *
461 * PARAMETERS :
462 * @heapBuf : heap buffer handler
463 * @bufType : buffer type
464 * @ops_tbl : ptr to buf mapping/unmapping ops
465 *
466 * RETURN : int32_t type of status
467 * NO_ERROR -- success
468 * none-zero failure code
469 *==========================================================================*/
unMapBuf(QCameraMemory * Buf,cam_mapping_buf_type bufType,mm_camera_map_unmap_ops_tbl_t * ops_tbl)470 int32_t QCameraStream::unMapBuf(QCameraMemory *Buf,
471 cam_mapping_buf_type bufType, mm_camera_map_unmap_ops_tbl_t *ops_tbl)
472 {
473 int32_t rc = NO_ERROR;
474 uint8_t cnt;
475 ssize_t bufSize = BAD_INDEX;
476 uint32_t i;
477
478 cnt = Buf->getCnt();
479 for (i = 0; i < cnt; i++) {
480 bufSize = Buf->getSize(i);
481 if (BAD_INDEX != bufSize) {
482 if (ops_tbl == NULL ) {
483 rc = mCamOps->unmap_stream_buf(mCamHandle, mChannelHandle, mHandle,
484 bufType, i, -1);
485 } else {
486 rc = ops_tbl->unmap_ops(i, -1, bufType, ops_tbl->userdata);
487 }
488 if (rc < 0) {
489 ALOGE("Failed to unmap buffer");
490 break;
491 }
492 } else {
493 ALOGE("Failed to retrieve buffer size (bad index)");
494 rc = BAD_INDEX;
495 break;
496 }
497 }
498
499 return rc;
500 }
501
502 /*===========================================================================
503 * FUNCTION : mapBuf
504 *
505 * DESCRIPTION: maps buffers
506 *
507 * PARAMETERS :
508 * @heapBuf : heap buffer handler
509 * @bufType : buffer type
510 * @ops_tbl : ptr to buf mapping/unmapping ops
511 *
512 * RETURN : int32_t type of status
513 * NO_ERROR -- success
514 * none-zero failure code
515 *==========================================================================*/
mapBuf(QCameraMemory * Buf,cam_mapping_buf_type bufType,mm_camera_map_unmap_ops_tbl_t * ops_tbl)516 int32_t QCameraStream::mapBuf(QCameraMemory *Buf,
517 cam_mapping_buf_type bufType, mm_camera_map_unmap_ops_tbl_t *ops_tbl)
518 {
519 int32_t rc = NO_ERROR;
520 uint8_t cnt;
521 ssize_t bufSize = BAD_INDEX;
522 int32_t i = 0;
523
524 cnt = Buf->getCnt();
525 for (i = 0; i < cnt; i++) {
526 bufSize = Buf->getSize((uint32_t)i);
527 if (BAD_INDEX != bufSize) {
528 if (ops_tbl == NULL) {
529 rc = mCamOps->map_stream_buf(mCamHandle, mChannelHandle, mHandle,
530 (uint8_t)bufType, (uint32_t)i, -1,
531 Buf->getFd((uint32_t)i), (uint32_t)bufSize);
532 } else {
533 rc = ops_tbl->map_ops((uint32_t)i, -1, Buf->getFd((uint32_t)i),
534 (uint32_t)bufSize, bufType, ops_tbl->userdata);
535 }
536 if (rc < 0) {
537 ALOGE("Failed to map buffer");
538 goto err1;
539 }
540 } else {
541 ALOGE("Failed to retrieve buffer size (bad index)");
542 rc = BAD_INDEX;
543 goto err1;
544 }
545 }
546
547 return rc;
548 err1:
549 i -= 1;
550 for (; i >= 0; i--) {
551 bufSize = Buf->getSize((uint32_t)i);
552 if (BAD_INDEX != bufSize) {
553 if (ops_tbl == NULL) {
554 rc = mCamOps->unmap_stream_buf(mCamHandle, mChannelHandle, mHandle,
555 (uint8_t)bufType, (uint32_t)i, -1);
556 } else {
557 rc = ops_tbl->unmap_ops((uint32_t)i, -1, bufType, ops_tbl->userdata);
558 }
559 if (rc < 0) {
560 ALOGE("Failed to unmap buffer");
561 }
562 } else {
563 ALOGE("Failed to retrieve buffer size (bad index)");
564 rc = BAD_INDEX;
565 }
566 }
567 return rc;
568 }
569
570 /*===========================================================================
571 * FUNCTION : init
572 *
573 * DESCRIPTION: initialize stream obj
574 *
575 * PARAMETERS :
576 * @streamInfoBuf: ptr to buf that contains stream info
577 * @miscBuf : ptr to buf that contains misc bufs
578 * @stream_cb : stream data notify callback. Can be NULL if not needed
579 * @userdata : user data ptr
580 * @bDynallocBuf : flag to indicate if buffer allocation can be in 2 steps
581 *
582 * RETURN : int32_t type of status
583 * NO_ERROR -- success
584 * none-zero failure code
585 *==========================================================================*/
init(QCameraHeapMemory * streamInfoBuf,QCameraHeapMemory * miscBuf,uint8_t minNumBuffers,stream_cb_routine stream_cb,void * userdata,bool bDynallocBuf)586 int32_t QCameraStream::init(QCameraHeapMemory *streamInfoBuf,
587 QCameraHeapMemory *miscBuf,
588 uint8_t minNumBuffers,
589 stream_cb_routine stream_cb,
590 void *userdata,
591 bool bDynallocBuf)
592 {
593 int32_t rc = OK;
594
595 mHandle = mCamOps->add_stream(mCamHandle, mChannelHandle);
596 if (!mHandle) {
597 ALOGE("add_stream failed");
598 rc = UNKNOWN_ERROR;
599 if (streamInfoBuf != NULL) {
600 streamInfoBuf->deallocate();
601 delete streamInfoBuf;
602 streamInfoBuf = NULL;
603 }
604 goto done;
605 }
606
607 // assign and map stream info memory
608 mStreamInfoBuf = streamInfoBuf;
609 mStreamInfo = reinterpret_cast<cam_stream_info_t *>(mStreamInfoBuf->getPtr(0));
610 mNumBufs = minNumBuffers;
611
612 rc = mapBuf(mStreamInfoBuf, CAM_MAPPING_BUF_TYPE_STREAM_INFO, NULL);
613 if (rc < 0) {
614 ALOGE("Failed to map stream info buffer");
615 releaseStreamInfoBuf();
616 mStreamInfo = 0;
617 goto err1;
618 }
619
620 mMiscBuf = miscBuf;
621 if (miscBuf) {
622 rc = mapBuf(mMiscBuf, CAM_MAPPING_BUF_TYPE_MISC_BUF, NULL);
623 if (rc < 0) {
624 ALOGE("Failed to map miscellaneous buffer");
625 releaseMiscBuf();
626 goto err1;
627 }
628 }
629
630 // Calculate buffer size for deffered allocation
631 if (mDefferedAllocation) {
632 rc = calcOffset(mStreamInfo);
633 if (rc < 0) {
634 ALOGE("%s : Failed to calculate stream offset", __func__);
635 goto err1;
636 }
637 } else {
638 rc = configStream();
639 if (rc < 0) {
640 ALOGE("%s : Failed to config stream ", __func__);
641 goto err1;
642 }
643 }
644
645 mDataCB = stream_cb;
646 mUserData = userdata;
647 mDynBufAlloc = bDynallocBuf;
648 return 0;
649
650 err1:
651 mCamOps->delete_stream(mCamHandle, mChannelHandle, mHandle);
652 mHandle = 0;
653 mNumBufs = 0;
654 done:
655 return rc;
656 }
657
658 /*===========================================================================
659 * FUNCTION : calcOffset
660 *
661 * DESCRIPTION: calculate frame offset based on format and padding information
662 *
663 * PARAMETERS :
664 * @streamInfo : stream information
665 *
666 * RETURN : int32_t type of status
667 * 0 -- success
668 * -1 -- failure
669 *==========================================================================*/
calcOffset(cam_stream_info_t * streamInfo)670 int32_t QCameraStream::calcOffset(cam_stream_info_t *streamInfo)
671 {
672 int32_t rc = 0;
673
674 cam_dimension_t dim = streamInfo->dim;
675 if (streamInfo->pp_config.feature_mask & CAM_QCOM_FEATURE_ROTATION &&
676 streamInfo->stream_type != CAM_STREAM_TYPE_VIDEO) {
677 if (streamInfo->pp_config.rotation == ROTATE_90 ||
678 streamInfo->pp_config.rotation == ROTATE_270) {
679 // rotated by 90 or 270, need to switch width and height
680 dim.width = streamInfo->dim.height;
681 dim.height = streamInfo->dim.width;
682 }
683 }
684
685 switch (streamInfo->stream_type) {
686 case CAM_STREAM_TYPE_PREVIEW:
687 rc = mm_stream_calc_offset_preview(streamInfo->fmt,
688 &dim,
689 &streamInfo->buf_planes);
690 break;
691 case CAM_STREAM_TYPE_POSTVIEW:
692 rc = mm_stream_calc_offset_post_view(streamInfo->fmt,
693 &dim,
694 &streamInfo->buf_planes);
695 break;
696 case CAM_STREAM_TYPE_SNAPSHOT:
697 rc = mm_stream_calc_offset_snapshot(streamInfo->fmt,
698 &dim,
699 &mPaddingInfo,
700 &streamInfo->buf_planes);
701 break;
702 case CAM_STREAM_TYPE_OFFLINE_PROC:
703 rc = mm_stream_calc_offset_postproc(streamInfo,
704 &mPaddingInfo,
705 &streamInfo->buf_planes);
706 break;
707 case CAM_STREAM_TYPE_VIDEO:
708 rc = mm_stream_calc_offset_video(&dim,
709 &streamInfo->buf_planes);
710 break;
711 case CAM_STREAM_TYPE_RAW:
712 rc = mm_stream_calc_offset_raw(streamInfo->fmt,
713 &dim,
714 &mPaddingInfo,
715 &streamInfo->buf_planes);
716 break;
717 case CAM_STREAM_TYPE_ANALYSIS:
718 rc = mm_stream_calc_offset_analysis(streamInfo->fmt,
719 &dim,
720 &mPaddingInfo,
721 &streamInfo->buf_planes);
722 break;
723 case CAM_STREAM_TYPE_METADATA:
724 rc = mm_stream_calc_offset_metadata(&dim,
725 &mPaddingInfo,
726 &streamInfo->buf_planes);
727 break;
728 default:
729 ALOGE("%s: not supported for stream type %d",
730 __func__, streamInfo->stream_type);
731 rc = -1;
732 break;
733 }
734 return rc;
735 }
736
737 /*===========================================================================
738 * FUNCTION : start
739 *
740 * DESCRIPTION: start stream. Will start main stream thread to handle stream
741 * related ops.
742 *
743 * PARAMETERS : none
744 *
745 * RETURN : int32_t type of status
746 * NO_ERROR -- success
747 * none-zero failure code
748 *==========================================================================*/
start()749 int32_t QCameraStream::start()
750 {
751 int32_t rc = 0;
752 mDataQ.init();
753 rc = mProcTh.launch(dataProcRoutine, this);
754 if (rc == NO_ERROR) {
755 m_bActive = true;
756 }
757 pthread_mutex_init(&m_lock, NULL);
758 pthread_cond_init(&m_cond, NULL);
759 return rc;
760 }
761
762 /*===========================================================================
763 * FUNCTION : stop
764 *
765 * DESCRIPTION: stop stream. Will stop main stream thread
766 *
767 * PARAMETERS : none
768 *
769 * RETURN : int32_t type of status
770 * NO_ERROR -- success
771 * none-zero failure code
772 *==========================================================================*/
stop()773 int32_t QCameraStream::stop()
774 {
775 int32_t rc = 0;
776 m_bActive = false;
777 rc = mProcTh.exit();
778 return rc;
779 }
780
781 /*===========================================================================
782 * FUNCTION : syncRuntimeParams
783 *
784 * DESCRIPTION: query and sync runtime parameters like output crop
785 * buffer info etc.
786 *
787 * PARAMETERS : none
788 *
789 * RETURN : int32_t type of status
790 * NO_ERROR -- success
791 * none-zero failure code
792 *==========================================================================*/
syncRuntimeParams()793 int32_t QCameraStream::syncRuntimeParams()
794 {
795 int32_t ret = NO_ERROR;
796
797 memset(&m_OutputCrop, 0, sizeof(cam_stream_parm_buffer_t));
798 m_OutputCrop.type = CAM_STREAM_PARAM_TYPE_GET_OUTPUT_CROP;
799
800 ret = getParameter(m_OutputCrop);
801 if (ret != NO_ERROR) {
802 ALOGE("%s: stream getParameter for output crop failed", __func__);
803 return ret;
804 }
805
806 memset(&m_ImgProp, 0, sizeof(cam_stream_parm_buffer_t));
807 m_ImgProp.type = CAM_STREAM_PARAM_TYPE_GET_IMG_PROP;
808
809 ret = getParameter(m_ImgProp);
810 if (ret != NO_ERROR) {
811 ALOGE("%s: stream getParameter for image prop failed", __func__);
812 return ret;
813 }
814
815 return ret;
816 }
817
818 /*===========================================================================
819 * FUNCTION : processZoomDone
820 *
821 * DESCRIPTION: process zoom done event
822 *
823 * PARAMETERS :
824 * @previewWindoe : preview window ops table to set preview crop window
825 * @crop_info : crop info
826 *
827 * RETURN : int32_t type of status
828 * NO_ERROR -- success
829 * none-zero failure code
830 *==========================================================================*/
processZoomDone(preview_stream_ops_t * previewWindow,cam_crop_data_t & crop_info)831 int32_t QCameraStream::processZoomDone(preview_stream_ops_t *previewWindow,
832 cam_crop_data_t &crop_info)
833 {
834 int32_t rc = 0;
835
836 if (!m_bActive) {
837 ALOGV("%s : Stream not active", __func__);
838 return NO_ERROR;
839 }
840
841 // get stream param for crop info
842 for (int i = 0; i < crop_info.num_of_streams; i++) {
843 if (crop_info.crop_info[i].stream_id == mStreamInfo->stream_svr_id) {
844 pthread_mutex_lock(&mCropLock);
845 mCropInfo = crop_info.crop_info[i].crop;
846 pthread_mutex_unlock(&mCropLock);
847
848 // update preview window crop if it's preview/postview stream
849 if ( (previewWindow != NULL) &&
850 (mStreamInfo->stream_type == CAM_STREAM_TYPE_PREVIEW ||
851 mStreamInfo->stream_type == CAM_STREAM_TYPE_POSTVIEW) ) {
852 rc = previewWindow->set_crop(previewWindow,
853 mCropInfo.left,
854 mCropInfo.top,
855 mCropInfo.width,
856 mCropInfo.height);
857 }
858 break;
859 }
860 }
861 return rc;
862 }
863
864 /*===========================================================================
865 * FUNCTION : processDataNotify
866 *
867 * DESCRIPTION: process stream data notify
868 *
869 * PARAMETERS :
870 * @frame : stream frame received
871 *
872 * RETURN : int32_t type of status
873 * NO_ERROR -- success
874 * none-zero failure code
875 *==========================================================================*/
processDataNotify(mm_camera_super_buf_t * frame)876 int32_t QCameraStream::processDataNotify(mm_camera_super_buf_t *frame)
877 {
878 CDBG("%s:\n", __func__);
879 if (mDataQ.enqueue((void *)frame)) {
880 return mProcTh.sendCmd(CAMERA_CMD_TYPE_DO_NEXT_JOB, FALSE, FALSE);
881 } else {
882 CDBG_HIGH("%s: Stream thread is not active, no ops here", __func__);
883 bufDone(frame->bufs[0]->buf_idx);
884 free(frame);
885 return NO_ERROR;
886 }
887 }
888
889 /*===========================================================================
890 * FUNCTION : dataNotifyCB
891 *
892 * DESCRIPTION: callback for data notify. This function is registered with
893 * mm-camera-interface to handle data notify
894 *
895 * PARAMETERS :
896 * @recvd_frame : stream frame received
897 * userdata : user data ptr
898 *
899 * RETURN : none
900 *==========================================================================*/
dataNotifyCB(mm_camera_super_buf_t * recvd_frame,void * userdata)901 void QCameraStream::dataNotifyCB(mm_camera_super_buf_t *recvd_frame,
902 void *userdata)
903 {
904 CDBG("%s:\n", __func__);
905 QCameraStream* stream = (QCameraStream *)userdata;
906 if (stream == NULL ||
907 recvd_frame == NULL ||
908 recvd_frame->bufs[0] == NULL ||
909 recvd_frame->bufs[0]->stream_id != stream->getMyHandle()) {
910 ALOGE("%s: Not a valid stream to handle buf", __func__);
911 return;
912 }
913
914 mm_camera_super_buf_t *frame =
915 (mm_camera_super_buf_t *)malloc(sizeof(mm_camera_super_buf_t));
916 if (frame == NULL) {
917 ALOGE("%s: No mem for mm_camera_buf_def_t", __func__);
918 stream->bufDone(recvd_frame->bufs[0]->buf_idx);
919 return;
920 }
921 *frame = *recvd_frame;
922 stream->processDataNotify(frame);
923 return;
924 }
925
926 /*===========================================================================
927 * FUNCTION : dataProcRoutine
928 *
929 * DESCRIPTION: function to process data in the main stream thread
930 *
931 * PARAMETERS :
932 * @data : user data ptr
933 *
934 * RETURN : none
935 *==========================================================================*/
dataProcRoutine(void * data)936 void *QCameraStream::dataProcRoutine(void *data)
937 {
938 int running = 1;
939 int ret;
940 QCameraStream *pme = (QCameraStream *)data;
941 QCameraCmdThread *cmdThread = &pme->mProcTh;
942 cmdThread->setName("CAM_strmDatProc");
943
944 CDBG("%s: E", __func__);
945 do {
946 do {
947 ret = cam_sem_wait(&cmdThread->cmd_sem);
948 if (ret != 0 && errno != EINVAL) {
949 ALOGE("%s: cam_sem_wait error (%s)",
950 __func__, strerror(errno));
951 return NULL;
952 }
953 } while (ret != 0);
954
955 // we got notified about new cmd avail in cmd queue
956 camera_cmd_type_t cmd = cmdThread->getCmd();
957 switch (cmd) {
958 case CAMERA_CMD_TYPE_DO_NEXT_JOB:
959 {
960 CDBG_HIGH("%s: Do next job", __func__);
961 mm_camera_super_buf_t *frame =
962 (mm_camera_super_buf_t *)pme->mDataQ.dequeue();
963 if (NULL != frame) {
964 if (pme->mDataCB != NULL) {
965 pme->mDataCB(frame, pme, pme->mUserData);
966 } else {
967 // no data cb routine, return buf here
968 pme->bufDone(frame->bufs[0]->buf_idx);
969 free(frame);
970 }
971 }
972 }
973 break;
974 case CAMERA_CMD_TYPE_EXIT:
975 CDBG_HIGH("%s: Exit", __func__);
976 /* flush data buf queue */
977 pme->mDataQ.flush();
978 running = 0;
979 break;
980 default:
981 break;
982 }
983 } while (running);
984 CDBG_HIGH("%s: X", __func__);
985 return NULL;
986 }
987
988 /*===========================================================================
989 * FUNCTION : bufDone
990 *
991 * DESCRIPTION: return stream buffer to kernel
992 *
993 * PARAMETERS :
994 * @index : index of buffer to be returned
995 *
996 * RETURN : int32_t type of status
997 * NO_ERROR -- success
998 * none-zero failure code
999 *==========================================================================*/
bufDone(uint32_t index)1000 int32_t QCameraStream::bufDone(uint32_t index)
1001 {
1002 int32_t rc = NO_ERROR;
1003
1004 if (index >= mNumBufs || mBufDefs == NULL)
1005 return BAD_INDEX;
1006
1007 rc = mCamOps->qbuf(mCamHandle, mChannelHandle, &mBufDefs[index]);
1008 if (rc < 0)
1009 return rc;
1010
1011 return rc;
1012 }
1013
1014 /*===========================================================================
1015 * FUNCTION : bufDone
1016 *
1017 * DESCRIPTION: return stream buffer to kernel
1018 *
1019 * PARAMETERS :
1020 * @opaque : stream frame/metadata buf to be returned
1021 * @isMetaData: flag if returned opaque is a metadatabuf or the real frame ptr
1022 *
1023 * RETURN : int32_t type of status
1024 * NO_ERROR -- success
1025 * none-zero failure code
1026 *==========================================================================*/
bufDone(const void * opaque,bool isMetaData)1027 int32_t QCameraStream::bufDone(const void *opaque, bool isMetaData)
1028 {
1029 int32_t rc = NO_ERROR;
1030 int index;
1031
1032 if (mStreamInfo != NULL
1033 && mStreamInfo->streaming_mode == CAM_STREAMING_MODE_BATCH) {
1034 index = mStreamBatchBufs->getMatchBufIndex(opaque, TRUE);
1035 if (index == -1 || index >= mNumBufs || mBufDefs == NULL) {
1036 ALOGE("%s: Cannot find buf for opaque data = %p", __func__, opaque);
1037 return BAD_INDEX;
1038 }
1039 camera_memory_t *video_mem = mStreamBatchBufs->getMemory(index, true);
1040 if (video_mem != NULL) {
1041 struct encoder_media_buffer_type * packet =
1042 (struct encoder_media_buffer_type *)video_mem->data;
1043 native_handle_t *nh = const_cast<native_handle_t *>(packet->meta_handle);
1044 if (NULL != nh) {
1045 if (native_handle_delete(nh)) {
1046 ALOGE("%s: Unable to delete native handle", __func__);
1047 }
1048 } else {
1049 ALOGE("%s : native handle not available", __func__);
1050 }
1051 }
1052 } else {
1053 index = mStreamBufs->getMatchBufIndex(opaque, isMetaData);
1054 if (index == -1 || index >= mNumBufs || mBufDefs == NULL) {
1055 ALOGE("%s: Cannot find buf for opaque data = %p", __func__, opaque);
1056 return BAD_INDEX;
1057 }
1058 CDBG_HIGH("%s: Buffer Index = %d, Frame Idx = %d", __func__, index,
1059 mBufDefs[index].frame_idx);
1060 }
1061 rc = bufDone((uint32_t)index);
1062 return rc;
1063 }
1064
1065 /*===========================================================================
1066 * FUNCTION : getNumQueuedBuf
1067 *
1068 * DESCRIPTION: return queued buffer count
1069 *
1070 * PARAMETERS : None
1071 *
1072 * RETURN : queued buffer count
1073 *==========================================================================*/
getNumQueuedBuf()1074 int32_t QCameraStream::getNumQueuedBuf()
1075 {
1076 int32_t rc = -1;
1077 if (mHandle > 0) {
1078 rc = mCamOps->get_queued_buf_count(mCamHandle, mChannelHandle, mHandle);
1079 }
1080 if (rc == -1) {
1081 ALOGE("%s: stream is not in active state. Invalid operation", __func__);
1082 }
1083 return rc;
1084 }
1085
1086 /*===========================================================================
1087 * FUNCTION : getBufs
1088 *
1089 * DESCRIPTION: allocate stream buffers
1090 *
1091 * PARAMETERS :
1092 * @offset : offset info of stream buffers
1093 * @num_bufs : number of buffers allocated
1094 * @initial_reg_flag: flag to indicate if buffer needs to be registered
1095 * at kernel initially
1096 * @bufs : output of allocated buffers
1097 * @ops_tbl : ptr to buf mapping/unmapping ops
1098 *
1099 * RETURN : int32_t type of status
1100 * NO_ERROR -- success
1101 * none-zero failure code
1102 *==========================================================================*/
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)1103 int32_t QCameraStream::getBufs(cam_frame_len_offset_t *offset,
1104 uint8_t *num_bufs,
1105 uint8_t **initial_reg_flag,
1106 mm_camera_buf_def_t **bufs,
1107 mm_camera_map_unmap_ops_tbl_t *ops_tbl)
1108 {
1109 int rc = NO_ERROR;
1110 uint8_t *regFlags;
1111
1112 if (!ops_tbl) {
1113 ALOGE("%s: ops_tbl is NULL", __func__);
1114 return INVALID_OPERATION;
1115 }
1116
1117 mFrameLenOffset = *offset;
1118
1119 uint8_t numBufAlloc = mNumBufs;
1120 mNumBufsNeedAlloc = 0;
1121 if (mDynBufAlloc) {
1122 numBufAlloc = CAMERA_MIN_ALLOCATED_BUFFERS;
1123 if (numBufAlloc > mNumBufs) {
1124 mDynBufAlloc = false;
1125 numBufAlloc = mNumBufs;
1126 } else {
1127 mNumBufsNeedAlloc = (uint8_t)(mNumBufs - numBufAlloc);
1128 }
1129 }
1130
1131 //Allocate stream buffer
1132 mStreamBufs = mAllocator.allocateStreamBuf(mStreamInfo->stream_type,
1133 mFrameLenOffset.frame_len, mFrameLenOffset.mp[0].stride,
1134 mFrameLenOffset.mp[0].scanline, numBufAlloc);
1135 if (!mStreamBufs) {
1136 ALOGE("%s: Failed to allocate stream buffers", __func__);
1137 return NO_MEMORY;
1138 }
1139
1140 mNumBufs = (uint8_t)(numBufAlloc + mNumBufsNeedAlloc);
1141
1142 for (uint32_t i = 0; i < numBufAlloc; i++) {
1143 ssize_t bufSize = mStreamBufs->getSize(i);
1144 if (BAD_INDEX != bufSize) {
1145 rc = ops_tbl->map_ops(i, -1, mStreamBufs->getFd(i),
1146 (uint32_t)bufSize, CAM_MAPPING_BUF_TYPE_STREAM_BUF, ops_tbl->userdata);
1147 if (rc < 0) {
1148 ALOGE("%s: map_stream_buf failed: %d", __func__, rc);
1149 for (uint32_t j = 0; j < i; j++) {
1150 ops_tbl->unmap_ops(j, -1, CAM_MAPPING_BUF_TYPE_STREAM_BUF, ops_tbl->userdata);
1151 }
1152 mStreamBufs->deallocate();
1153 delete mStreamBufs;
1154 mStreamBufs = NULL;
1155 return INVALID_OPERATION;
1156 }
1157 } else {
1158 ALOGE("Failed to retrieve buffer size (bad index)");
1159 return INVALID_OPERATION;
1160 }
1161 }
1162
1163 //regFlags array is allocated by us, but consumed and freed by mm-camera-interface
1164 regFlags = (uint8_t *)malloc(sizeof(uint8_t) * mNumBufs);
1165 if (!regFlags) {
1166 ALOGE("%s: Out of memory", __func__);
1167 for (uint32_t i = 0; i < numBufAlloc; i++) {
1168 ops_tbl->unmap_ops(i, -1, CAM_MAPPING_BUF_TYPE_STREAM_BUF, ops_tbl->userdata);
1169 }
1170 mStreamBufs->deallocate();
1171 delete mStreamBufs;
1172 mStreamBufs = NULL;
1173 return NO_MEMORY;
1174 }
1175 memset(regFlags, 0, sizeof(uint8_t) * mNumBufs);
1176
1177 mBufDefs = (mm_camera_buf_def_t *)malloc(mNumBufs * sizeof(mm_camera_buf_def_t));
1178 if (mBufDefs == NULL) {
1179 ALOGE("%s: getRegFlags failed %d", __func__, rc);
1180 for (uint32_t i = 0; i < numBufAlloc; i++) {
1181 ops_tbl->unmap_ops(i, -1, CAM_MAPPING_BUF_TYPE_STREAM_BUF, ops_tbl->userdata);
1182 }
1183 mStreamBufs->deallocate();
1184 delete mStreamBufs;
1185 mStreamBufs = NULL;
1186 free(regFlags);
1187 regFlags = NULL;
1188 return INVALID_OPERATION;
1189 }
1190 memset(mBufDefs, 0, mNumBufs * sizeof(mm_camera_buf_def_t));
1191 for (uint32_t i = 0; i < numBufAlloc; i++) {
1192 mStreamBufs->getBufDef(mFrameLenOffset, mBufDefs[i], i);
1193 }
1194
1195 rc = mStreamBufs->getRegFlags(regFlags);
1196 if (rc < 0) {
1197 ALOGE("%s: getRegFlags failed %d", __func__, rc);
1198 for (uint32_t i = 0; i < numBufAlloc; i++) {
1199 ops_tbl->unmap_ops(i, -1, CAM_MAPPING_BUF_TYPE_STREAM_BUF, ops_tbl->userdata);
1200 }
1201 mStreamBufs->deallocate();
1202 delete mStreamBufs;
1203 mStreamBufs = NULL;
1204 free(mBufDefs);
1205 mBufDefs = NULL;
1206 free(regFlags);
1207 regFlags = NULL;
1208 return INVALID_OPERATION;
1209 }
1210
1211 *num_bufs = mNumBufs;
1212 *initial_reg_flag = regFlags;
1213 *bufs = mBufDefs;
1214 CDBG_HIGH("%s: stream type: %d, mRegFlags: %p, numBufs: %d",
1215 __func__, mStreamInfo->stream_type, regFlags, mNumBufs);
1216
1217 if (mNumBufsNeedAlloc > 0) {
1218 pthread_mutex_lock(&m_lock);
1219 wait_for_cond = TRUE;
1220 pthread_mutex_unlock(&m_lock);
1221 CDBG_HIGH("%s: Still need to allocate %d buffers",
1222 __func__, mNumBufsNeedAlloc);
1223 // remember memops table
1224 m_MemOpsTbl = *ops_tbl;
1225 // start another thread to allocate the rest of buffers
1226 pthread_create(&mBufAllocPid,
1227 NULL,
1228 BufAllocRoutine,
1229 this);
1230 pthread_setname_np(mBufAllocPid, "CAM_strmBufAlloc");
1231 }
1232
1233 return NO_ERROR;
1234 }
1235
1236 /*===========================================================================
1237 * FUNCTION : allocateBuffers
1238 *
1239 * DESCRIPTION: allocate stream buffers
1240 *
1241 * PARAMETERS :
1242 *
1243 * RETURN : int32_t type of status
1244 * NO_ERROR -- success
1245 * none-zero failure code
1246 *==========================================================================*/
allocateBuffers()1247 int32_t QCameraStream::allocateBuffers()
1248 {
1249 int rc = NO_ERROR;
1250
1251 mFrameLenOffset = mStreamInfo->buf_planes.plane_info;
1252
1253 if (mStreamInfo->streaming_mode == CAM_STREAMING_MODE_BATCH) {
1254 return allocateBatchBufs(&mFrameLenOffset,
1255 &mNumBufs, &mRegFlags,
1256 &mBufDefs, NULL);
1257 }
1258
1259 //Allocate and map stream info buffer
1260 mStreamBufs = mAllocator.allocateStreamBuf(mStreamInfo->stream_type,
1261 mFrameLenOffset.frame_len,
1262 mFrameLenOffset.mp[0].stride,
1263 mFrameLenOffset.mp[0].scanline,
1264 mNumBufs);
1265
1266 if (!mStreamBufs) {
1267 ALOGE("%s: Failed to allocate stream buffers", __func__);
1268 return NO_MEMORY;
1269 }
1270
1271 for (uint32_t i = 0; i < mNumBufs; i++) {
1272 ssize_t bufSize = mStreamBufs->getSize(i);
1273 if (BAD_INDEX != bufSize) {
1274 rc = mapBuf(CAM_MAPPING_BUF_TYPE_STREAM_BUF, i, -1,
1275 mStreamBufs->getFd(i), (size_t)bufSize, NULL);
1276 ALOGE_IF((rc < 0), "%s: map_stream_buf failed: %d", __func__, rc);
1277 } else {
1278 ALOGE("%s: Bad index %u", __func__, i);
1279 rc = BAD_INDEX;
1280 }
1281 if (rc < 0) {
1282 ALOGE("%s: Cleanup after error: %d", __func__, rc);
1283 for (uint32_t j = 0; j < i; j++) {
1284 unmapBuf(CAM_MAPPING_BUF_TYPE_STREAM_BUF, j, -1, NULL);
1285 }
1286 mStreamBufs->deallocate();
1287 delete mStreamBufs;
1288 mStreamBufs = NULL;
1289 return INVALID_OPERATION;
1290 }
1291 }
1292
1293 //regFlags array is allocated by us,
1294 // but consumed and freed by mm-camera-interface
1295 mRegFlags = (uint8_t *)malloc(sizeof(uint8_t) * mNumBufs);
1296 if (!mRegFlags) {
1297 ALOGE("%s: Out of memory", __func__);
1298 for (uint32_t i = 0; i < mNumBufs; i++) {
1299 unmapBuf(CAM_MAPPING_BUF_TYPE_STREAM_BUF, i, -1, NULL);
1300 }
1301 mStreamBufs->deallocate();
1302 delete mStreamBufs;
1303 mStreamBufs = NULL;
1304 return NO_MEMORY;
1305 }
1306 memset(mRegFlags, 0, sizeof(uint8_t) * mNumBufs);
1307
1308 size_t bufDefsSize = mNumBufs * sizeof(mm_camera_buf_def_t);
1309 mBufDefs = (mm_camera_buf_def_t *)malloc(bufDefsSize);
1310 if (mBufDefs == NULL) {
1311 ALOGE("%s: getRegFlags failed %d", __func__, rc);
1312 for (uint32_t i = 0; i < mNumBufs; i++) {
1313 unmapBuf(CAM_MAPPING_BUF_TYPE_STREAM_BUF, i, -1, NULL);
1314 }
1315 mStreamBufs->deallocate();
1316 delete mStreamBufs;
1317 mStreamBufs = NULL;
1318 free(mRegFlags);
1319 mRegFlags = NULL;
1320 return INVALID_OPERATION;
1321 }
1322 memset(mBufDefs, 0, bufDefsSize);
1323 for (uint32_t i = 0; i < mNumBufs; i++) {
1324 mStreamBufs->getBufDef(mFrameLenOffset, mBufDefs[i], i);
1325 }
1326
1327 rc = mStreamBufs->getRegFlags(mRegFlags);
1328 if (rc < 0) {
1329 ALOGE("%s: getRegFlags failed %d", __func__, rc);
1330 for (uint32_t i = 0; i < mNumBufs; i++) {
1331 unmapBuf(CAM_MAPPING_BUF_TYPE_STREAM_BUF, i, -1, NULL);
1332 }
1333 mStreamBufs->deallocate();
1334 delete mStreamBufs;
1335 mStreamBufs = NULL;
1336 free(mBufDefs);
1337 mBufDefs = NULL;
1338 free(mRegFlags);
1339 mRegFlags = NULL;
1340 return INVALID_OPERATION;
1341 }
1342
1343 return NO_ERROR;
1344 }
1345
1346 /*===========================================================================
1347 * FUNCTION : allocateBatchBufs
1348 *
1349 * DESCRIPTION: allocate stream batch buffers and stream buffers
1350 *
1351 * PARAMETERS :
1352 * @offset : offset info of stream buffers
1353 * @num_bufs : number of buffers allocated
1354 * @initial_reg_flag: flag to indicate if buffer needs to be registered
1355 * at kernel initially
1356 * @bufs : output of allocated buffers
1357 * @plane_bufs : output of allocated plane buffers
1358 * @ops_tbl : ptr to buf mapping/unmapping ops
1359 *
1360 * RETURN : int32_t type of status
1361 * NO_ERROR -- success
1362 * none-zero failure code
1363 *==========================================================================*/
allocateBatchBufs(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)1364 int32_t QCameraStream::allocateBatchBufs(cam_frame_len_offset_t *offset,
1365 uint8_t *num_bufs, uint8_t **initial_reg_flag,
1366 mm_camera_buf_def_t **bufs, mm_camera_map_unmap_ops_tbl_t *ops_tbl)
1367 {
1368 int rc = NO_ERROR;
1369 uint8_t *regFlags;
1370
1371 mFrameLenOffset = *offset;
1372
1373 CDBG_HIGH("%s : Batch Buffer allocation stream type = %d", __func__, getMyType());
1374
1375 //Allocate stream batch buffer
1376 mStreamBatchBufs = mAllocator.allocateStreamUserBuf (mStreamInfo);
1377 if (!mStreamBatchBufs) {
1378 ALOGE("%s: Failed to allocate stream batch buffers", __func__);
1379 return NO_MEMORY;
1380 }
1381
1382 //map batch buffers
1383 for (uint32_t i = 0; i < mStreamBatchBufs->getCnt(); i++) {
1384 rc = mapBuf(CAM_MAPPING_BUF_TYPE_STREAM_USER_BUF, i, -1,
1385 mStreamBatchBufs->getFd(i), (size_t)mNumBufs, ops_tbl);
1386 if (rc < 0) {
1387 ALOGE("Failed to map stream batch buffer");
1388 for (uint32_t j = 0; j < i; j++) {
1389 unmapBuf(CAM_MAPPING_BUF_TYPE_STREAM_USER_BUF, j, -1, ops_tbl);
1390 }
1391 mStreamBatchBufs->deallocate();
1392 delete mStreamBatchBufs;
1393 mStreamBatchBufs = NULL;
1394 return NO_MEMORY;
1395 }
1396 }
1397
1398 /*calculate stream Buffer count*/
1399 mNumPlaneBufs =
1400 (mNumBufs * mStreamInfo->user_buf_info.frame_buf_cnt);
1401
1402 //Allocate stream buffer
1403 mStreamBufs = mAllocator.allocateStreamBuf(mStreamInfo->stream_type,
1404 mFrameLenOffset.frame_len,mFrameLenOffset.mp[0].stride,
1405 mFrameLenOffset.mp[0].scanline,mNumPlaneBufs);
1406 if (!mStreamBufs) {
1407 ALOGE("%s: Failed to allocate stream buffers", __func__);
1408 rc = NO_MEMORY;
1409 goto err1;
1410 }
1411
1412 //Map plane stream buffers
1413 for (uint32_t i = 0; i < mNumPlaneBufs; i++) {
1414 ssize_t bufSize = mStreamBufs->getSize(i);
1415 if (BAD_INDEX != bufSize) {
1416 rc = mapBuf(CAM_MAPPING_BUF_TYPE_STREAM_BUF, i, -1,
1417 mStreamBufs->getFd(i), (size_t)bufSize, ops_tbl);
1418 if (rc < 0) {
1419 ALOGE("%s: map_stream_buf failed: %d", __func__, rc);
1420 for (uint32_t j = 0; j < i; j++) {
1421 unmapBuf(CAM_MAPPING_BUF_TYPE_STREAM_BUF, j, -1, ops_tbl);
1422 }
1423 mStreamBufs->deallocate();
1424 delete mStreamBufs;
1425 mStreamBufs = NULL;
1426 rc = INVALID_OPERATION;
1427 goto err1;
1428 }
1429 } else {
1430 ALOGE("Failed to retrieve buffer size (bad index)");
1431 mStreamBufs->deallocate();
1432 delete mStreamBufs;
1433 mStreamBufs = NULL;
1434 rc = INVALID_OPERATION;
1435 goto err1;
1436 }
1437 }
1438
1439 CDBG ("%s: BATCH Buf Count = %d, Plane Buf Cnt = %d", __func__,
1440 mNumBufs, mNumPlaneBufs);
1441
1442 //regFlags array is allocated by us, but consumed and freed by mm-camera-interface
1443 regFlags = (uint8_t *)malloc(sizeof(uint8_t) * mNumBufs);
1444 if (!regFlags) {
1445 ALOGE("%s: Out of memory", __func__);
1446 for (uint32_t i = 0; i < mNumPlaneBufs; i++) {
1447 unmapBuf(CAM_MAPPING_BUF_TYPE_STREAM_BUF, i, -1, ops_tbl);
1448 }
1449 mStreamBufs->deallocate();
1450 delete mStreamBufs;
1451 mStreamBufs = NULL;
1452 rc = NO_MEMORY;
1453 goto err1;
1454 }
1455 memset(regFlags, 0, sizeof(uint8_t) * mNumBufs);
1456 for (uint32_t i = 0; i < mNumBufs; i++) {
1457 regFlags[i] = 1;
1458 }
1459
1460 mBufDefs = (mm_camera_buf_def_t *)malloc(mNumBufs * sizeof(mm_camera_buf_def_t));
1461 if (mBufDefs == NULL) {
1462 ALOGE("%s: getRegFlags failed %d", __func__, rc);
1463 for (uint32_t i = 0; i < mNumPlaneBufs; i++) {
1464 unmapBuf(CAM_MAPPING_BUF_TYPE_STREAM_BUF, i, -1, ops_tbl);
1465 }
1466 mStreamBufs->deallocate();
1467 delete mStreamBufs;
1468 mStreamBufs = NULL;
1469 free(regFlags);
1470 regFlags = NULL;
1471 rc = INVALID_OPERATION;
1472 goto err1;
1473 }
1474 memset(mBufDefs, 0, mNumBufs * sizeof(mm_camera_buf_def_t));
1475
1476 mPlaneBufDefs = (mm_camera_buf_def_t *)
1477 malloc(mNumPlaneBufs * (sizeof(mm_camera_buf_def_t)));
1478 if (mPlaneBufDefs == NULL) {
1479 ALOGE("%s : No Memory", __func__);
1480 free(regFlags);
1481 regFlags = NULL;
1482 free(mBufDefs);
1483 mBufDefs = NULL;
1484 for (uint32_t i = 0; i < mNumPlaneBufs; i++) {
1485 unmapBuf(CAM_MAPPING_BUF_TYPE_STREAM_BUF, i, -1, ops_tbl);
1486 }
1487 mStreamBufs->deallocate();
1488 delete mStreamBufs;
1489 mStreamBufs = NULL;
1490 free(regFlags);
1491 regFlags = NULL;
1492 rc = INVALID_OPERATION;
1493 goto err1;
1494 }
1495 memset(mPlaneBufDefs, 0,
1496 mNumPlaneBufs * (sizeof(mm_camera_buf_def_t)));
1497
1498 for (uint32_t i = 0; i < mStreamInfo->num_bufs; i++) {
1499 mStreamBatchBufs->getUserBufDef(mStreamInfo->user_buf_info,
1500 mBufDefs[i], i, mFrameLenOffset, mPlaneBufDefs,
1501 mStreamBufs);
1502 }
1503
1504 *num_bufs = mNumBufs;
1505 *initial_reg_flag = regFlags;
1506 *bufs = mBufDefs;
1507 CDBG_HIGH("%s: stream type: %d, numBufs: %d mNumPlaneBufs: %d",
1508 __func__, mStreamInfo->stream_type, mNumBufs, mNumPlaneBufs);
1509
1510 return NO_ERROR;
1511
1512 err1:
1513 for (uint8_t i = 0; i < mStreamBatchBufs->getCnt(); i++) {
1514 unmapBuf(CAM_MAPPING_BUF_TYPE_STREAM_USER_BUF, i, -1, ops_tbl);
1515 }
1516 mStreamBatchBufs->deallocate();
1517 delete mStreamBatchBufs;
1518 mStreamBatchBufs = NULL;
1519 return rc;
1520 }
1521
1522
1523 /*===========================================================================
1524 * FUNCTION : releaseBuffs
1525 *
1526 * DESCRIPTION: method to deallocate stream buffers
1527 *
1528 * PARAMETERS :
1529 *
1530 * RETURN : int32_t type of status
1531 * NO_ERROR -- success
1532 * none-zero failure code
1533 *==========================================================================*/
releaseBuffs()1534 int32_t QCameraStream::releaseBuffs()
1535 {
1536 int rc = NO_ERROR;
1537
1538 if (mStreamInfo->streaming_mode == CAM_STREAMING_MODE_BATCH) {
1539 return releaseBatchBufs(NULL);
1540 }
1541
1542 if (NULL != mBufDefs) {
1543 for (uint32_t i = 0; i < mNumBufs; i++) {
1544 rc = unmapBuf(CAM_MAPPING_BUF_TYPE_STREAM_BUF, i, -1, NULL);
1545 if (rc < 0) {
1546 ALOGE("%s: map_stream_buf failed: %d", __func__, rc);
1547 }
1548 }
1549
1550 // mBufDefs just keep a ptr to the buffer
1551 // mm-camera-interface own the buffer, so no need to free
1552 mBufDefs = NULL;
1553 memset(&mFrameLenOffset, 0, sizeof(mFrameLenOffset));
1554 }
1555 if (!mStreamBufsAcquired && mStreamBufs != NULL) {
1556 mStreamBufs->deallocate();
1557 delete mStreamBufs;
1558 }
1559
1560 return rc;
1561 }
1562
1563 /*===========================================================================
1564 * FUNCTION : releaseBatchBufs
1565 *
1566 * DESCRIPTION: method to deallocate stream buffers and batch buffers
1567 *
1568 * PARAMETERS :
1569 * @ops_tbl : ptr to buf mapping/unmapping ops
1570 *
1571 * RETURN : int32_t type of status
1572 * NO_ERROR -- success
1573 * none-zero failure code
1574
1575 *==========================================================================*/
releaseBatchBufs(mm_camera_map_unmap_ops_tbl_t * ops_tbl)1576 int32_t QCameraStream::releaseBatchBufs(mm_camera_map_unmap_ops_tbl_t *ops_tbl)
1577 {
1578 int rc = NO_ERROR;
1579
1580 if (NULL != mPlaneBufDefs) {
1581 for (uint32_t i = 0; i < mNumPlaneBufs; i++) {
1582 rc = unmapBuf(CAM_MAPPING_BUF_TYPE_STREAM_BUF, i, -1, ops_tbl);
1583 if (rc < 0) {
1584 ALOGE("%s: map_stream_buf failed: %d", __func__, rc);
1585 }
1586 }
1587
1588 // mBufDefs just keep a ptr to the buffer
1589 // mm-camera-interface own the buffer, so no need to free
1590 mPlaneBufDefs = NULL;
1591 memset(&mFrameLenOffset, 0, sizeof(mFrameLenOffset));
1592 mNumPlaneBufs = 0;
1593 }
1594
1595 if ( mStreamBufs != NULL) {
1596 mStreamBufs->deallocate();
1597 delete mStreamBufs;
1598 }
1599
1600 mBufDefs = NULL;
1601
1602 if (mStreamBatchBufs != NULL) {
1603 for (uint8_t i = 0; i < mStreamBatchBufs->getCnt(); i++) {
1604 unmapBuf(CAM_MAPPING_BUF_TYPE_STREAM_USER_BUF, i, -1, ops_tbl);
1605 }
1606 mStreamBatchBufs->deallocate();
1607 delete mStreamBatchBufs;
1608 mStreamBatchBufs = NULL;
1609 }
1610 return rc;
1611
1612 }
1613
1614 /*===========================================================================
1615 * FUNCTION : BufAllocRoutine
1616 *
1617 * DESCRIPTION: function to allocate additional stream buffers
1618 *
1619 * PARAMETERS :
1620 * @data : user data ptr
1621 *
1622 * RETURN : none
1623 *==========================================================================*/
BufAllocRoutine(void * data)1624 void *QCameraStream::BufAllocRoutine(void *data)
1625 {
1626 QCameraStream *pme = (QCameraStream *)data;
1627 int32_t rc = NO_ERROR;
1628
1629 CDBG_HIGH("%s: E", __func__);
1630 pme->cond_wait();
1631 if (pme->mNumBufsNeedAlloc > 0) {
1632 uint8_t numBufAlloc = (uint8_t)(pme->mNumBufs - pme->mNumBufsNeedAlloc);
1633 rc = pme->mAllocator.allocateMoreStreamBuf(pme->mStreamBufs,
1634 pme->mFrameLenOffset.frame_len,
1635 pme->mNumBufsNeedAlloc);
1636 if (rc == NO_ERROR){
1637 for (uint32_t i = numBufAlloc; i < pme->mNumBufs; i++) {
1638 ssize_t bufSize = pme->mStreamBufs->getSize(i);
1639 if (BAD_INDEX != bufSize) {
1640 rc = pme->m_MemOpsTbl.map_ops(i, -1, pme->mStreamBufs->getFd(i),
1641 (uint32_t)bufSize, CAM_MAPPING_BUF_TYPE_STREAM_BUF,
1642 pme->m_MemOpsTbl.userdata);
1643 if (rc == 0) {
1644 pme->mStreamBufs->getBufDef(pme->mFrameLenOffset, pme->mBufDefs[i], i);
1645 pme->mCamOps->qbuf(pme->mCamHandle, pme->mChannelHandle,
1646 &pme->mBufDefs[i]);
1647 } else {
1648 ALOGE("%s: map_stream_buf %d failed: %d", __func__, rc, i);
1649 }
1650 } else {
1651 ALOGE("Failed to retrieve buffer size (bad index)");
1652 }
1653 }
1654
1655 pme->mNumBufsNeedAlloc = 0;
1656 }
1657 }
1658 CDBG_HIGH("%s: X", __func__);
1659 return NULL;
1660 }
1661
1662 /*===========================================================================
1663 * FUNCTION : cond_signal
1664 *
1665 * DESCRIPTION: signal if flag "wait_for_cond" is set
1666 *
1667 *==========================================================================*/
cond_signal()1668 void QCameraStream::cond_signal()
1669 {
1670 pthread_mutex_lock(&m_lock);
1671 if(wait_for_cond == TRUE){
1672 wait_for_cond = FALSE;
1673 pthread_cond_signal(&m_cond);
1674 }
1675 pthread_mutex_unlock(&m_lock);
1676 }
1677
1678
1679 /*===========================================================================
1680 * FUNCTION : cond_wait
1681 *
1682 * DESCRIPTION: wait on if flag "wait_for_cond" is set
1683 *
1684 *==========================================================================*/
cond_wait()1685 void QCameraStream::cond_wait()
1686 {
1687 pthread_mutex_lock(&m_lock);
1688 while (wait_for_cond == TRUE) {
1689 pthread_cond_wait(&m_cond, &m_lock);
1690 }
1691 pthread_mutex_unlock(&m_lock);
1692 }
1693
1694 /*===========================================================================
1695 * FUNCTION : putBufs
1696 *
1697 * DESCRIPTION: deallocate stream buffers
1698 *
1699 * PARAMETERS :
1700 * @ops_tbl : ptr to buf mapping/unmapping ops
1701 *
1702 * RETURN : int32_t type of status
1703 * NO_ERROR -- success
1704 * none-zero failure code
1705 *==========================================================================*/
putBufs(mm_camera_map_unmap_ops_tbl_t * ops_tbl)1706 int32_t QCameraStream::putBufs(mm_camera_map_unmap_ops_tbl_t *ops_tbl)
1707 {
1708 int rc = NO_ERROR;
1709
1710 if (mBufAllocPid != 0) {
1711 CDBG_HIGH("%s: wait for buf allocation thread dead", __func__);
1712 pthread_join(mBufAllocPid, NULL);
1713 mBufAllocPid = 0;
1714 CDBG_HIGH("%s: return from buf allocation thread", __func__);
1715 }
1716
1717 for (uint32_t i = 0; i < mNumBufs; i++) {
1718 rc = ops_tbl->unmap_ops(i, -1, CAM_MAPPING_BUF_TYPE_STREAM_BUF, ops_tbl->userdata);
1719 if (rc < 0) {
1720 ALOGE("%s: map_stream_buf failed: %d", __func__, rc);
1721 }
1722 }
1723 mBufDefs = NULL; // mBufDefs just keep a ptr to the buffer
1724 // mm-camera-interface own the buffer, so no need to free
1725 memset(&mFrameLenOffset, 0, sizeof(mFrameLenOffset));
1726 if ( !mStreamBufsAcquired ) {
1727 mStreamBufs->deallocate();
1728 delete mStreamBufs;
1729 }
1730
1731 return rc;
1732 }
1733
1734 /*===========================================================================
1735 * FUNCTION : invalidateBuf
1736 *
1737 * DESCRIPTION: invalidate a specific stream buffer
1738 *
1739 * PARAMETERS :
1740 * @index : index of the buffer to invalidate
1741 *
1742 * RETURN : int32_t type of status
1743 * NO_ERROR -- success
1744 * none-zero failure code
1745 *==========================================================================*/
invalidateBuf(uint32_t index)1746 int32_t QCameraStream::invalidateBuf(uint32_t index)
1747 {
1748 return mStreamBufs->invalidateCache(index);
1749 }
1750
1751 /*===========================================================================
1752 * FUNCTION : cleanInvalidateBuf
1753 *
1754 * DESCRIPTION: clean invalidate a specific stream buffer
1755 *
1756 * PARAMETERS :
1757 * @index : index of the buffer to clean invalidate
1758 *
1759 * RETURN : int32_t type of status
1760 * NO_ERROR -- success
1761 * none-zero failure code
1762 *==========================================================================*/
cleanInvalidateBuf(uint32_t index)1763 int32_t QCameraStream::cleanInvalidateBuf(uint32_t index)
1764 {
1765 return mStreamBufs->cleanInvalidateCache(index);
1766 }
1767
1768 /*===========================================================================
1769 * FUNCTION : isTypeOf
1770 *
1771 * DESCRIPTION: helper function to determine if the stream is of the queried type
1772 *
1773 * PARAMETERS :
1774 * @type : stream type as of queried
1775 *
1776 * RETURN : true/false
1777 *==========================================================================*/
isTypeOf(cam_stream_type_t type)1778 bool QCameraStream::isTypeOf(cam_stream_type_t type)
1779 {
1780 if (mStreamInfo != NULL && (mStreamInfo->stream_type == type)) {
1781 return true;
1782 } else {
1783 return false;
1784 }
1785 }
1786
1787 /*===========================================================================
1788 * FUNCTION : isOrignalTypeOf
1789 *
1790 * DESCRIPTION: helper function to determine if the original stream is of the
1791 * queried type if it's reproc stream
1792 *
1793 * PARAMETERS :
1794 * @type : stream type as of queried
1795 *
1796 * RETURN : true/false
1797 *==========================================================================*/
isOrignalTypeOf(cam_stream_type_t type)1798 bool QCameraStream::isOrignalTypeOf(cam_stream_type_t type)
1799 {
1800 if (mStreamInfo != NULL &&
1801 mStreamInfo->stream_type == CAM_STREAM_TYPE_OFFLINE_PROC &&
1802 mStreamInfo->reprocess_config.pp_type == CAM_ONLINE_REPROCESS_TYPE &&
1803 mStreamInfo->reprocess_config.online.input_stream_type == type) {
1804 return true;
1805 } else if (
1806 mStreamInfo != NULL &&
1807 mStreamInfo->stream_type == CAM_STREAM_TYPE_OFFLINE_PROC &&
1808 mStreamInfo->reprocess_config.pp_type == CAM_OFFLINE_REPROCESS_TYPE &&
1809 mStreamInfo->reprocess_config.offline.input_type == type) {
1810 return true;
1811 } else {
1812 return false;
1813 }
1814 }
1815
1816 /*===========================================================================
1817 * FUNCTION : getMyType
1818 *
1819 * DESCRIPTION: return stream type
1820 *
1821 * PARAMETERS : none
1822 *
1823 * RETURN : stream type
1824 *==========================================================================*/
getMyType()1825 cam_stream_type_t QCameraStream::getMyType()
1826 {
1827 if (mStreamInfo != NULL) {
1828 return mStreamInfo->stream_type;
1829 } else {
1830 return CAM_STREAM_TYPE_DEFAULT;
1831 }
1832 }
1833
1834 /*===========================================================================
1835 * FUNCTION : getMyOriginalType
1836 *
1837 * DESCRIPTION: return stream type
1838 *
1839 * PARAMETERS : none
1840 *
1841 * RETURN : stream type
1842 *==========================================================================*/
getMyOriginalType()1843 cam_stream_type_t QCameraStream::getMyOriginalType()
1844 {
1845 if (mStreamInfo != NULL) {
1846 if (mStreamInfo->stream_type == CAM_STREAM_TYPE_OFFLINE_PROC &&
1847 mStreamInfo->reprocess_config.pp_type == CAM_ONLINE_REPROCESS_TYPE) {
1848 return mStreamInfo->reprocess_config.online.input_stream_type;
1849 } else if (mStreamInfo->stream_type == CAM_STREAM_TYPE_OFFLINE_PROC &&
1850 mStreamInfo->reprocess_config.pp_type == CAM_OFFLINE_REPROCESS_TYPE) {
1851 return mStreamInfo->reprocess_config.offline.input_type;
1852 } else {
1853 return mStreamInfo->stream_type;
1854 }
1855 } else {
1856 return CAM_STREAM_TYPE_DEFAULT;
1857 }
1858 }
1859
1860 /*===========================================================================
1861 * FUNCTION : getFrameOffset
1862 *
1863 * DESCRIPTION: query stream buffer frame offset info
1864 *
1865 * PARAMETERS :
1866 * @offset : reference to struct to store the queried frame offset info
1867 *
1868 * RETURN : int32_t type of status
1869 * NO_ERROR -- success
1870 * none-zero failure code
1871 *==========================================================================*/
getFrameOffset(cam_frame_len_offset_t & offset)1872 int32_t QCameraStream::getFrameOffset(cam_frame_len_offset_t &offset)
1873 {
1874 if (NULL == mStreamInfo) {
1875 return NO_INIT;
1876 }
1877
1878 offset = mFrameLenOffset;
1879 if ((ROTATE_90 == mOnlineRotation) || (ROTATE_270 == mOnlineRotation)) {
1880 // Re-calculate frame offset in case of online rotation
1881 cam_stream_info_t streamInfo = *mStreamInfo;
1882 getFrameDimension(streamInfo.dim);
1883 calcOffset(&streamInfo);
1884 offset = streamInfo.buf_planes.plane_info;
1885 }
1886
1887 return 0;
1888 }
1889
1890 /*===========================================================================
1891 * FUNCTION : getCropInfo
1892 *
1893 * DESCRIPTION: query crop info of the stream
1894 *
1895 * PARAMETERS :
1896 * @crop : reference to struct to store the queried crop info
1897 *
1898 * RETURN : int32_t type of status
1899 * NO_ERROR -- success
1900 * none-zero failure code
1901 *==========================================================================*/
getCropInfo(cam_rect_t & crop)1902 int32_t QCameraStream::getCropInfo(cam_rect_t &crop)
1903 {
1904 pthread_mutex_lock(&mCropLock);
1905 crop = mCropInfo;
1906 pthread_mutex_unlock(&mCropLock);
1907 return NO_ERROR;
1908 }
1909
1910 /*===========================================================================
1911 * FUNCTION : setCropInfo
1912 *
1913 * DESCRIPTION: set crop info of the stream
1914 *
1915 * PARAMETERS :
1916 * @crop : struct to store new crop info
1917 *
1918 * RETURN : int32_t type of status
1919 * NO_ERROR -- success
1920 * none-zero failure code
1921 *==========================================================================*/
setCropInfo(cam_rect_t crop)1922 int32_t QCameraStream::setCropInfo(cam_rect_t crop)
1923 {
1924 pthread_mutex_lock(&mCropLock);
1925 mCropInfo = crop;
1926 pthread_mutex_unlock(&mCropLock);
1927 return NO_ERROR;
1928 }
1929
1930 /*===========================================================================
1931 * FUNCTION : getFrameDimension
1932 *
1933 * DESCRIPTION: query stream frame dimension info
1934 *
1935 * PARAMETERS :
1936 * @dim : reference to struct to store the queried frame dimension
1937 *
1938 * RETURN : int32_t type of status
1939 * NO_ERROR -- success
1940 * none-zero failure code
1941 *==========================================================================*/
getFrameDimension(cam_dimension_t & dim)1942 int32_t QCameraStream::getFrameDimension(cam_dimension_t &dim)
1943 {
1944 if (mStreamInfo != NULL) {
1945 if ((ROTATE_90 == mOnlineRotation) || (ROTATE_270 == mOnlineRotation)) {
1946 dim.width = mStreamInfo->dim.height;
1947 dim.height = mStreamInfo->dim.width;
1948 } else {
1949 dim = mStreamInfo->dim;
1950 }
1951 return 0;
1952 }
1953 return -1;
1954 }
1955
1956 /*===========================================================================
1957 * FUNCTION : getFormat
1958 *
1959 * DESCRIPTION: query stream format
1960 *
1961 * PARAMETERS :
1962 * @fmt : reference to stream format
1963 *
1964 * RETURN : int32_t type of status
1965 * NO_ERROR -- success
1966 * none-zero failure code
1967 *==========================================================================*/
getFormat(cam_format_t & fmt)1968 int32_t QCameraStream::getFormat(cam_format_t &fmt)
1969 {
1970 if (mStreamInfo != NULL) {
1971 fmt = mStreamInfo->fmt;
1972 return 0;
1973 }
1974 return -1;
1975 }
1976
1977 /*===========================================================================
1978 * FUNCTION : getMyServerID
1979 *
1980 * DESCRIPTION: query server stream ID
1981 *
1982 * PARAMETERS : None
1983 *
1984 * RETURN : stream ID from server
1985 *==========================================================================*/
getMyServerID()1986 uint32_t QCameraStream::getMyServerID() {
1987 if (mStreamInfo != NULL) {
1988 return mStreamInfo->stream_svr_id;
1989 } else {
1990 return 0;
1991 }
1992 }
1993
1994 /*===========================================================================
1995 * FUNCTION : acquireStreamBufs
1996 *
1997 * DESCRIPTION: acquire stream buffers and postpone their release.
1998 *
1999 * PARAMETERS : None
2000 *
2001 * RETURN : int32_t type of status
2002 * NO_ERROR -- success
2003 * none-zero failure code
2004 *==========================================================================*/
acquireStreamBufs()2005 int32_t QCameraStream::acquireStreamBufs()
2006 {
2007 mStreamBufsAcquired = true;
2008
2009 return NO_ERROR;
2010 }
2011
2012 /*===========================================================================
2013 * FUNCTION : mapBuf
2014 *
2015 * DESCRIPTION: map stream related buffer to backend server
2016 *
2017 * PARAMETERS :
2018 * @buf_type : mapping type of buffer
2019 * @buf_idx : index of buffer
2020 * @plane_idx: plane index
2021 * @fd : fd of the buffer
2022 * @size : lenght of the buffer
2023 * @ops_tbl : ptr to buf mapping/unmapping ops
2024 *
2025 * RETURN : int32_t type of status
2026 * NO_ERROR -- success
2027 * none-zero failure code
2028 *==========================================================================*/
mapBuf(uint8_t buf_type,uint32_t buf_idx,int32_t plane_idx,int fd,size_t size,mm_camera_map_unmap_ops_tbl_t * ops_tbl)2029 int32_t QCameraStream::mapBuf(uint8_t buf_type, uint32_t buf_idx,
2030 int32_t plane_idx, int fd, size_t size, mm_camera_map_unmap_ops_tbl_t *ops_tbl)
2031 {
2032 if (ops_tbl != NULL) {
2033 return ops_tbl->map_ops(buf_idx, plane_idx, fd,
2034 (uint32_t)size, (cam_mapping_buf_type)buf_type, ops_tbl->userdata);
2035 } else {
2036 return mCamOps->map_stream_buf(mCamHandle, mChannelHandle,
2037 mHandle, buf_type, buf_idx, plane_idx,
2038 fd, size);
2039 }
2040
2041 }
2042
2043 /*===========================================================================
2044 * FUNCTION : unmapBuf
2045 *
2046 * DESCRIPTION: unmap stream related buffer to backend server
2047 *
2048 * PARAMETERS :
2049 * @buf_type : mapping type of buffer
2050 * @buf_idx : index of buffer
2051 * @plane_idx: plane index
2052 * @ops_tbl : ptr to buf mapping/unmapping ops
2053 *
2054 * RETURN : int32_t type of status
2055 * NO_ERROR -- success
2056 * none-zero failure code
2057 *==========================================================================*/
unmapBuf(uint8_t buf_type,uint32_t buf_idx,int32_t plane_idx,mm_camera_map_unmap_ops_tbl_t * ops_tbl)2058 int32_t QCameraStream::unmapBuf(uint8_t buf_type, uint32_t buf_idx, int32_t plane_idx,
2059 mm_camera_map_unmap_ops_tbl_t *ops_tbl)
2060 {
2061 if (ops_tbl != NULL) {
2062 return ops_tbl->unmap_ops(buf_idx, plane_idx,
2063 (cam_mapping_buf_type)buf_type, ops_tbl->userdata);
2064 } else {
2065 return mCamOps->unmap_stream_buf(mCamHandle, mChannelHandle,
2066 mHandle, buf_type, buf_idx, plane_idx);
2067 }
2068 }
2069
2070 /*===========================================================================
2071 * FUNCTION : setParameter
2072 *
2073 * DESCRIPTION: set stream based parameters
2074 *
2075 * PARAMETERS :
2076 * @param : ptr to parameters to be set
2077 *
2078 * RETURN : int32_t type of status
2079 * NO_ERROR -- success
2080 * none-zero failure code
2081 *==========================================================================*/
setParameter(cam_stream_parm_buffer_t & param)2082 int32_t QCameraStream::setParameter(cam_stream_parm_buffer_t ¶m)
2083 {
2084 int32_t rc = NO_ERROR;
2085 pthread_mutex_lock(&mParameterLock);
2086 mStreamInfo->parm_buf = param;
2087 rc = mCamOps->set_stream_parms(mCamHandle,
2088 mChannelHandle,
2089 mHandle,
2090 &mStreamInfo->parm_buf);
2091 if (rc == NO_ERROR) {
2092 param = mStreamInfo->parm_buf;
2093 }
2094 pthread_mutex_unlock(&mParameterLock);
2095 return rc;
2096 }
2097
2098 /*===========================================================================
2099 * FUNCTION : getParameter
2100 *
2101 * DESCRIPTION: get stream based parameters
2102 *
2103 * PARAMETERS :
2104 * @param : ptr to parameters to be red
2105 *
2106 * RETURN : int32_t type of status
2107 * NO_ERROR -- success
2108 * none-zero failure code
2109 *==========================================================================*/
getParameter(cam_stream_parm_buffer_t & param)2110 int32_t QCameraStream::getParameter(cam_stream_parm_buffer_t ¶m)
2111 {
2112 int32_t rc = NO_ERROR;
2113 pthread_mutex_lock(&mParameterLock);
2114 mStreamInfo->parm_buf = param;
2115 rc = mCamOps->get_stream_parms(mCamHandle,
2116 mChannelHandle,
2117 mHandle,
2118 &mStreamInfo->parm_buf);
2119 if (rc == NO_ERROR) {
2120 param = mStreamInfo->parm_buf;
2121 }
2122 pthread_mutex_unlock(&mParameterLock);
2123 return rc;
2124 }
2125
2126 /*===========================================================================
2127 * FUNCTION : releaseFrameData
2128 *
2129 * DESCRIPTION: callback function to release frame data node
2130 *
2131 * PARAMETERS :
2132 * @data : ptr to post process input data
2133 * @user_data : user data ptr (QCameraReprocessor)
2134 *
2135 * RETURN : None
2136 *==========================================================================*/
releaseFrameData(void * data,void * user_data)2137 void QCameraStream::releaseFrameData(void *data, void *user_data)
2138 {
2139 QCameraStream *pme = (QCameraStream *)user_data;
2140 mm_camera_super_buf_t *frame = (mm_camera_super_buf_t *)data;
2141 if (NULL != pme) {
2142 pme->bufDone(frame->bufs[0]->buf_idx);
2143 }
2144 }
2145
2146 /*===========================================================================
2147 * FUNCTION : configStream
2148 *
2149 * DESCRIPTION: send stream configuration to back end
2150 *
2151 * PARAMETERS :
2152 *
2153 * RETURN : int32_t type of status
2154 * NO_ERROR -- success
2155 * none-zero failure code
2156 *==========================================================================*/
configStream()2157 int32_t QCameraStream::configStream()
2158 {
2159 int rc = NO_ERROR;
2160
2161 // Configure the stream
2162 mm_camera_stream_config_t stream_config;
2163 stream_config.stream_info = mStreamInfo;
2164 stream_config.mem_vtbl = mMemVtbl;
2165 stream_config.stream_cb = dataNotifyCB;
2166 stream_config.padding_info = mPaddingInfo;
2167 stream_config.userdata = this;
2168 rc = mCamOps->config_stream(mCamHandle,
2169 mChannelHandle, mHandle, &stream_config);
2170 if (rc < 0) {
2171 ALOGE("Failed to config stream, rc = %d", rc);
2172 mCamOps->unmap_stream_buf(mCamHandle,
2173 mChannelHandle,
2174 mHandle,
2175 CAM_MAPPING_BUF_TYPE_STREAM_INFO,
2176 0,
2177 -1);
2178 return UNKNOWN_ERROR;
2179 }
2180
2181 return rc;
2182 }
2183
2184 }; // namespace qcamera
2185