1 /* Copyright (c) 2012-2016, The Linux Foundation. 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 // System dependencies
33 #include <utils/Errors.h>
34
35 // Camera dependencies
36 #include "QCameraBufferMaps.h"
37 #include "QCamera2HWI.h"
38 #include "QCameraStream.h"
39
40 extern "C" {
41 #include "mm_camera_dbg.h"
42 }
43
44 #define CAMERA_MIN_ALLOCATED_BUFFERS 3
45
46 namespace qcamera {
47
48 /*===========================================================================
49 * FUNCTION : get_bufs
50 *
51 * DESCRIPTION: static function entry to allocate stream buffers
52 *
53 * PARAMETERS :
54 * @offset : offset info of stream buffers
55 * @num_bufs : number of buffers allocated
56 * @initial_reg_flag: flag to indicate if buffer needs to be registered
57 * at kernel initially
58 * @bufs : output of allocated buffers
59 * @ops_tbl : ptr to buf mapping/unmapping ops
60 * @user_data : user data ptr of ops_tbl
61 *
62 * RETURN : int32_t type of status
63 * NO_ERROR -- success
64 * none-zero failure code
65 *==========================================================================*/
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)66 int32_t QCameraStream::get_bufs(
67 cam_frame_len_offset_t *offset,
68 uint8_t *num_bufs,
69 uint8_t **initial_reg_flag,
70 mm_camera_buf_def_t **bufs,
71 mm_camera_map_unmap_ops_tbl_t *ops_tbl,
72 void *user_data)
73 {
74 QCameraStream *stream = reinterpret_cast<QCameraStream *>(user_data);
75 if (!stream) {
76 LOGE("getBufs invalid stream pointer");
77 return NO_MEMORY;
78 }
79
80 if (stream->mStreamInfo != NULL
81 && stream->mStreamInfo->streaming_mode == CAM_STREAMING_MODE_BATCH) {
82 //Batch Mode. Allocate Butch buffers
83 return stream->allocateBatchBufs(offset, num_bufs,
84 initial_reg_flag, bufs, ops_tbl);
85 } else {
86 // Plane Buffer. Allocate plane buffer
87 return stream->getBufs(offset, num_bufs,
88 initial_reg_flag, bufs, ops_tbl);
89 }
90 }
91
92 /*===========================================================================
93 * FUNCTION : get_bufs_deffered
94 *
95 * DESCRIPTION: static function entry to allocate deffered stream buffers
96 *
97 * PARAMETERS :
98 * @offset : offset info of stream buffers
99 * @num_bufs : number of buffers allocated
100 * @initial_reg_flag: flag to indicate if buffer needs to be registered
101 * at kernel initially
102 * @bufs : output of allocated buffers
103 * @ops_tbl : ptr to buf mapping/unmapping ops
104 * @user_data : user data ptr of ops_tbl
105 *
106 * RETURN : int32_t type of status
107 * NO_ERROR -- success
108 * none-zero failure code
109 *==========================================================================*/
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 * ops_tbl,void * user_data)110 int32_t QCameraStream::get_bufs_deffered(
111 cam_frame_len_offset_t * /* offset */,
112 uint8_t *num_bufs,
113 uint8_t **initial_reg_flag,
114 mm_camera_buf_def_t **bufs,
115 mm_camera_map_unmap_ops_tbl_t * ops_tbl,
116 void *user_data)
117 {
118 QCameraStream *stream = reinterpret_cast<QCameraStream *>(user_data);
119
120 if (!stream) {
121 LOGE("getBufs invalid stream pointer");
122 return NO_MEMORY;
123 }
124
125 return stream->getBufsDeferred(NULL /*offset*/, num_bufs, initial_reg_flag, bufs,
126 ops_tbl);
127 }
128
129 /*===========================================================================
130 * FUNCTION : put_bufs
131 *
132 * DESCRIPTION: static function entry to deallocate stream buffers
133 *
134 * PARAMETERS :
135 * @ops_tbl : ptr to buf mapping/unmapping ops
136 * @user_data : user data ptr of ops_tbl
137 *
138 * RETURN : int32_t type of status
139 * NO_ERROR -- success
140 * none-zero failure code
141 *==========================================================================*/
put_bufs(mm_camera_map_unmap_ops_tbl_t * ops_tbl,void * user_data)142 int32_t QCameraStream::put_bufs(
143 mm_camera_map_unmap_ops_tbl_t *ops_tbl,
144 void *user_data)
145 {
146 QCameraStream *stream = reinterpret_cast<QCameraStream *>(user_data);
147 if (!stream) {
148 LOGE("putBufs invalid stream pointer");
149 return NO_MEMORY;
150 }
151
152 if (stream->mStreamInfo != NULL
153 && stream->mStreamInfo->streaming_mode == CAM_STREAMING_MODE_BATCH) {
154 //Batch Mode. release Butch buffers
155 return stream->releaseBatchBufs(ops_tbl);
156 } else {
157 // Plane Buffer. release plane buffer
158 return stream->putBufs(ops_tbl);
159 }
160
161 }
162
163 /*===========================================================================
164 * FUNCTION : put_bufs_deffered
165 *
166 * DESCRIPTION: static function entry to deallocate deffered stream buffers
167 *
168 * PARAMETERS :
169 * @ops_tbl : ptr to buf mapping/unmapping ops
170 * @user_data : user data ptr of ops_tbl
171 *
172 * RETURN : int32_t type of status
173 * NO_ERROR -- success
174 * none-zero failure code
175 *==========================================================================*/
put_bufs_deffered(mm_camera_map_unmap_ops_tbl_t *,void * user_data)176 int32_t QCameraStream::put_bufs_deffered(
177 mm_camera_map_unmap_ops_tbl_t * /*ops_tbl */,
178 void * user_data )
179 {
180 QCameraStream *stream = reinterpret_cast<QCameraStream *>(user_data);
181
182 if (!stream) {
183 LOGE("put_bufs_deffered invalid stream pointer");
184 return NO_MEMORY;
185 }
186
187 return stream->putBufsDeffered();
188 }
189
190 /*===========================================================================
191 * FUNCTION : invalidate_buf
192 *
193 * DESCRIPTION: static function entry to invalidate a specific stream buffer
194 *
195 * PARAMETERS :
196 * @index : index of the stream buffer to invalidate
197 * @user_data : user data ptr of ops_tbl
198 *
199 * RETURN : int32_t type of status
200 * NO_ERROR -- success
201 * none-zero failure code
202 *==========================================================================*/
invalidate_buf(uint32_t index,void * user_data)203 int32_t QCameraStream::invalidate_buf(uint32_t index, void *user_data)
204 {
205 QCameraStream *stream = reinterpret_cast<QCameraStream *>(user_data);
206 if (!stream) {
207 LOGE("invalid stream pointer");
208 return NO_MEMORY;
209 }
210
211 if (stream->mStreamInfo->is_secure == SECURE){
212 return 0;
213 }
214
215 if (stream->mStreamInfo->streaming_mode == CAM_STREAMING_MODE_BATCH) {
216 for (int i = 0; i < stream->mBufDefs[index].user_buf.bufs_used; i++) {
217 uint32_t buf_idx = stream->mBufDefs[index].user_buf.buf_idx[i];
218 stream->invalidateBuf(buf_idx);
219 }
220 } else {
221 return stream->invalidateBuf(index);
222 }
223
224 return 0;
225 }
226
227 /*===========================================================================
228 * FUNCTION : clean_invalidate_buf
229 *
230 * DESCRIPTION: static function entry to clean invalidate a specific stream buffer
231 *
232 * PARAMETERS :
233 * @index : index of the stream buffer to clean invalidate
234 * @user_data : user data ptr of ops_tbl
235 *
236 * RETURN : int32_t type of status
237 * NO_ERROR -- success
238 * none-zero failure code
239 *==========================================================================*/
clean_invalidate_buf(uint32_t index,void * user_data)240 int32_t QCameraStream::clean_invalidate_buf(uint32_t index, void *user_data)
241 {
242 QCameraStream *stream = reinterpret_cast<QCameraStream *>(user_data);
243 if (!stream) {
244 LOGE("invalid stream pointer");
245 return NO_MEMORY;
246 }
247
248 if (stream->mStreamInfo->is_secure == SECURE){
249 return 0;
250 }
251
252 if (stream->mStreamInfo->streaming_mode == CAM_STREAMING_MODE_BATCH) {
253 for (int i = 0; i < stream->mBufDefs[index].user_buf.bufs_used; i++) {
254 uint32_t buf_idx = stream->mBufDefs[index].user_buf.buf_idx[i];
255 stream->cleanInvalidateBuf(buf_idx);
256 }
257 } else {
258 return stream->cleanInvalidateBuf(index);
259 }
260
261 return 0;
262 }
263
264 /*===========================================================================
265 * FUNCTION : clean_buf
266 *
267 * DESCRIPTION: static function entry to clean a specific stream buffer
268 *
269 * PARAMETERS :
270 * @index : index of the stream buffer to clean invalidate
271 * @user_data : user data ptr of ops_tbl
272 *
273 * RETURN : int32_t type of status
274 * NO_ERROR -- success
275 * none-zero failure code
276 *==========================================================================*/
clean_buf(uint32_t index,void * user_data)277 int32_t QCameraStream::clean_buf(uint32_t index, void *user_data)
278 {
279 QCameraStream *stream = reinterpret_cast<QCameraStream *>(user_data);
280 if (!stream) {
281 LOGE("invalid stream pointer");
282 return NO_MEMORY;
283 }
284
285 if (stream->mStreamInfo->is_secure == SECURE){
286 return 0;
287 }
288
289 if (stream->mStreamInfo->streaming_mode == CAM_STREAMING_MODE_BATCH) {
290 for (int i = 0; i < stream->mBufDefs[index].user_buf.bufs_used; i++) {
291 uint32_t buf_idx = stream->mBufDefs[index].user_buf.buf_idx[i];
292 stream->cleanBuf(buf_idx);
293 }
294 } else {
295 return stream->cleanBuf(index);
296 }
297
298 return 0;
299 }
300
301
302 /*===========================================================================
303 * FUNCTION : set_config_ops
304 *
305 * DESCRIPTION: static function update mm-interface ops functions
306 *
307 * PARAMETERS :
308 * @ops_tbl : ptr to buf mapping/unmapping ops
309 * @user_data : user data ptr of ops_tbl
310 *
311 * RETURN : int32_t type of status
312 * NO_ERROR -- success
313 * none-zero failure code
314 *==========================================================================*/
set_config_ops(mm_camera_map_unmap_ops_tbl_t * ops_tbl,void * user_data)315 int32_t QCameraStream::set_config_ops(mm_camera_map_unmap_ops_tbl_t *ops_tbl,
316 void *user_data)
317 {
318 QCameraStream *stream = reinterpret_cast<QCameraStream *>(user_data);
319 if (!stream) {
320 LOGE("Stream invalid");
321 return NO_MEMORY;
322 }
323
324 stream->m_MemOpsTbl = *ops_tbl;
325 return 0;
326 }
327
328 /*===========================================================================
329 * FUNCTION : QCameraStream
330 *
331 * DESCRIPTION: constructor of QCameraStream
332 *
333 * PARAMETERS :
334 * @allocator : memory allocator obj
335 * @camHandle : camera handle
336 * @chId : channel handle
337 * @camOps : ptr to camera ops table
338 * @paddingInfo: ptr to padding info
339 * @deffered : deferred stream
340 * @online_rotation: rotation applied online
341 *
342 * RETURN : None
343 *==========================================================================*/
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)344 QCameraStream::QCameraStream(QCameraAllocator &allocator,
345 uint32_t camHandle, uint32_t chId,
346 mm_camera_ops_t *camOps, cam_padding_info_t *paddingInfo,
347 bool deffered, cam_rotation_t online_rotation):
348 mDumpFrame(0),
349 mDumpMetaFrame(0),
350 mDumpSkipCnt(0),
351 mStreamTimestamp(0),
352 mCamHandle(camHandle),
353 mChannelHandle(chId),
354 mHandle(0),
355 mCamOps(camOps),
356 mStreamInfo(NULL),
357 mNumBufs(0),
358 mNumPlaneBufs(0),
359 mNumBufsNeedAlloc(0),
360 mRegFlags(NULL),
361 mDataCB(NULL),
362 mSYNCDataCB(NULL),
363 mUserData(NULL),
364 mDataQ(releaseFrameData, this),
365 mStreamInfoBuf(NULL),
366 mMiscBuf(NULL),
367 mStreamBufs(NULL),
368 mStreamBatchBufs(NULL),
369 mAllocator(allocator),
370 mBufDefs(NULL),
371 mPlaneBufDefs(NULL),
372 mOnlineRotation(online_rotation),
373 mStreamBufsAcquired(false),
374 m_bActive(false),
375 mDynBufAlloc(false),
376 mBufAllocPid(0),
377 mDefferedAllocation(deffered),
378 wait_for_cond(false),
379 mAllocTaskId(0),
380 mMapTaskId(0),
381 mSyncCBEnabled(false)
382 {
383 mDualStream = is_dual_camera_by_handle(chId);
384 if (get_main_camera_handle(chId)) {
385 mCamType = MM_CAMERA_TYPE_MAIN;
386 }
387 if (get_aux_camera_handle(chId)) {
388 mCamType |= MM_CAMERA_TYPE_AUX;
389 }
390 mMemVtbl.user_data = this;
391 if ( !deffered ) {
392 mMemVtbl.get_bufs = get_bufs;
393 mMemVtbl.put_bufs = put_bufs;
394 } else {
395 mMemVtbl.get_bufs = get_bufs_deffered;
396 mMemVtbl.put_bufs = put_bufs_deffered;
397 }
398 mMemVtbl.invalidate_buf = invalidate_buf;
399 mMemVtbl.clean_invalidate_buf = clean_invalidate_buf;
400 mMemVtbl.clean_buf = clean_buf;
401 mMemVtbl.set_config_ops = set_config_ops;
402 memset(&mFrameLenOffset, 0, sizeof(mFrameLenOffset));
403 memcpy(&mPaddingInfo, paddingInfo, sizeof(cam_padding_info_t));
404 memset(&mCropInfo, 0, sizeof(cam_rect_t));
405 memset(&m_MemOpsTbl, 0, sizeof(mm_camera_map_unmap_ops_tbl_t));
406 memset(&m_OutputCrop, 0, sizeof(cam_stream_parm_buffer_t));
407 memset(&m_ImgProp, 0, sizeof(cam_stream_parm_buffer_t));
408 memset(&mAllocTask, 0, sizeof(mAllocTask));
409 memset(&mMapTask, 0, sizeof(mMapTask));
410 pthread_mutex_init(&mCropLock, NULL);
411 pthread_mutex_init(&mParameterLock, NULL);
412 mCurMetaMemory = NULL;
413 mCurBufIndex = -1;
414 mCurMetaIndex = -1;
415 mFirstTimeStamp = 0;
416 memset (&mStreamMetaMemory, 0,
417 (sizeof(MetaMemory) * CAMERA_MIN_VIDEO_BATCH_BUFFERS));
418 pthread_mutex_init(&m_lock, NULL);
419 pthread_cond_init(&m_cond, NULL);
420 }
421
422 /*===========================================================================
423 * FUNCTION : ~QCameraStream
424 *
425 * DESCRIPTION: deconstructor of QCameraStream
426 *
427 * PARAMETERS : None
428 *
429 * RETURN : None
430 *==========================================================================*/
~QCameraStream()431 QCameraStream::~QCameraStream()
432 {
433 pthread_mutex_destroy(&mCropLock);
434 pthread_mutex_destroy(&mParameterLock);
435
436 mAllocator.waitForBackgroundTask(mAllocTaskId);
437 mAllocator.waitForBackgroundTask(mMapTaskId);
438 if (mBufAllocPid != 0) {
439 cond_signal(true);
440 LOGL("Wait for buf allocation thread dead");
441 // Wait for the allocation of additional stream buffers
442 pthread_join(mBufAllocPid, NULL);
443 mBufAllocPid = 0;
444 }
445
446 if (mDefferedAllocation) {
447 mStreamBufsAcquired = false;
448 releaseBuffs();
449 }
450
451 unmapStreamInfoBuf();
452 releaseStreamInfoBuf();
453
454 if (mMiscBuf) {
455 unMapBuf(mMiscBuf, CAM_MAPPING_BUF_TYPE_MISC_BUF, NULL);
456 releaseMiscBuf();
457 }
458
459 // delete stream
460 if (mHandle > 0) {
461 mCamOps->delete_stream(mCamHandle, mChannelHandle, mHandle);
462 mHandle = 0;
463 }
464 pthread_mutex_destroy(&m_lock);
465 pthread_cond_destroy(&m_cond);
466 mDualStream = 0;
467 }
468
469 /*===========================================================================
470 * FUNCTION : unmapStreamInfoBuf
471 *
472 * DESCRIPTION: Unmap stream info buffer
473 *
474 * PARAMETERS :
475 *
476 * RETURN : int32_t type of status
477 * NO_ERROR -- success
478 * none-zero failure code
479 *==========================================================================*/
unmapStreamInfoBuf()480 int32_t QCameraStream::unmapStreamInfoBuf()
481 {
482 int rc = NO_ERROR;
483
484 if (mStreamInfoBuf != NULL) {
485 rc = mCamOps->unmap_stream_buf(mCamHandle,
486 mChannelHandle,
487 mHandle,
488 CAM_MAPPING_BUF_TYPE_STREAM_INFO,
489 0,
490 -1);
491
492 if (rc < 0) {
493 LOGE("Failed to unmap stream info buffer");
494 }
495 }
496
497 return rc;
498 }
499
500 /*===========================================================================
501 * FUNCTION : releaseMiscBuf
502 *
503 * DESCRIPTION: Release misc buffers
504 *
505 * PARAMETERS :
506 *
507 * RETURN : int32_t type of status
508 * NO_ERROR -- success
509 * none-zero failure code
510 *==========================================================================*/
releaseMiscBuf()511 int32_t QCameraStream::releaseMiscBuf()
512 {
513 int rc = NO_ERROR;
514
515 if (mMiscBuf != NULL) {
516 mMiscBuf->deallocate();
517 delete mMiscBuf;
518 mMiscBuf = NULL;
519 }
520
521 return rc;
522 }
523
524 /*===========================================================================
525 * FUNCTION : releaseStreamInfoBuf
526 *
527 * DESCRIPTION: Release stream info buffer
528 *
529 * PARAMETERS :
530 *
531 * RETURN : int32_t type of status
532 * NO_ERROR -- success
533 * none-zero failure code
534 *==========================================================================*/
releaseStreamInfoBuf()535 int32_t QCameraStream::releaseStreamInfoBuf()
536 {
537 int rc = NO_ERROR;
538
539 if (mStreamInfoBuf != NULL) {
540 mStreamInfoBuf->deallocate();
541 delete mStreamInfoBuf;
542 mStreamInfoBuf = NULL;
543 mStreamInfo = NULL;
544 }
545
546 return rc;
547 }
548
549 /*===========================================================================
550 * FUNCTION : deleteStream
551 *
552 * DESCRIPTION: Deletes a camera stream
553 *
554 * PARAMETERS : None
555 *
556 * RETURN : None
557 *==========================================================================*/
deleteStream()558 void QCameraStream::deleteStream()
559 {
560 if (mHandle > 0) {
561 acquireStreamBufs();
562 releaseBuffs();
563 unmapStreamInfoBuf();
564 mCamOps->delete_stream(mCamHandle, mChannelHandle, mHandle);
565 }
566 }
567
568 /*===========================================================================
569 * FUNCTION : unMapBuf
570 *
571 * DESCRIPTION: unmaps buffers
572 *
573 * PARAMETERS :
574 * @heapBuf : heap buffer handler
575 * @bufType : buffer type
576 * @ops_tbl : ptr to buf mapping/unmapping ops
577 *
578 * RETURN : int32_t type of status
579 * NO_ERROR -- success
580 * none-zero failure code
581 *==========================================================================*/
unMapBuf(QCameraMemory * Buf,cam_mapping_buf_type bufType,__unused mm_camera_map_unmap_ops_tbl_t * ops_tbl)582 int32_t QCameraStream::unMapBuf(QCameraMemory *Buf,
583 cam_mapping_buf_type bufType, __unused mm_camera_map_unmap_ops_tbl_t *ops_tbl)
584 {
585 int32_t rc = NO_ERROR;
586 uint8_t cnt;
587 ssize_t bufSize = BAD_INDEX;
588 uint32_t i;
589
590 cnt = Buf->getCnt();
591 for (i = 0; i < cnt; i++) {
592 bufSize = Buf->getSize(i);
593 if (BAD_INDEX != bufSize) {
594 if (m_MemOpsTbl.unmap_ops == NULL ) {
595 rc = mCamOps->unmap_stream_buf(mCamHandle, mChannelHandle, mHandle,
596 bufType, i, -1);
597 } else {
598 rc = m_MemOpsTbl.unmap_ops(i, -1, bufType, m_MemOpsTbl.userdata);
599 }
600 if (rc < 0) {
601 LOGE("Failed to unmap buffer");
602 break;
603 }
604 } else {
605 LOGE("Failed to retrieve buffer size (bad index)");
606 rc = BAD_INDEX;
607 break;
608 }
609 }
610
611 return rc;
612 }
613
614 /*===========================================================================
615 * FUNCTION : mapBufs
616 *
617 * DESCRIPTION: maps buffers
618 *
619 * PARAMETERS :
620 * @heapBuf : heap buffer handler
621 * @bufType : buffer type
622 * @ops_tbl : ptr to buf mapping/unmapping ops
623 *
624 * RETURN : int32_t type of status
625 * NO_ERROR -- success
626 * none-zero failure code
627 *==========================================================================*/
mapBufs(QCameraMemory * Buf,cam_mapping_buf_type bufType,__unused mm_camera_map_unmap_ops_tbl_t * ops_tbl)628 int32_t QCameraStream::mapBufs(QCameraMemory *Buf,
629 cam_mapping_buf_type bufType, __unused mm_camera_map_unmap_ops_tbl_t *ops_tbl)
630 {
631 int32_t rc = NO_ERROR;
632 uint32_t i = 0;
633 uint32_t activeHandle = mHandle;
634 QCameraBufferMaps bufferMaps;
635
636 for (i = 0; i < Buf->getCnt(); i++) {
637 ssize_t bufSize = Buf->getSize(i);
638 if (BAD_INDEX == bufSize) {
639 LOGE("Failed to retrieve buffer size (bad index)");
640 return BAD_INDEX;
641 }
642
643 if ((bufType == CAM_MAPPING_BUF_TYPE_STREAM_INFO)
644 || (bufType == CAM_MAPPING_BUF_TYPE_MISC_BUF)) {
645 if ((i > 0 && isDualStream()) ||
646 (mCamType == MM_CAMERA_TYPE_AUX)) {
647 activeHandle = get_aux_camera_handle(mHandle);
648 } else {
649 activeHandle = get_main_camera_handle(mHandle);
650 }
651 }
652 rc = bufferMaps.enqueue(bufType, activeHandle, i /*buf index*/, -1 /*plane index*/,
653 0 /*cookie*/, Buf->getFd(i), bufSize, Buf->getPtr(i));
654
655 if (rc < 0) {
656 LOGE("Failed to map buffers");
657 return BAD_INDEX;
658 }
659 }
660
661 cam_buf_map_type_list bufMapList;
662 rc = bufferMaps.getCamBufMapList(bufMapList);
663 if (rc < 0) {
664 LOGE("Failed to map buffers");
665 return BAD_INDEX;
666 }
667
668 if (m_MemOpsTbl.bundled_map_ops == NULL) {
669 rc = mCamOps->map_stream_bufs(mCamHandle, mChannelHandle, &bufMapList);
670 } else {
671 rc = m_MemOpsTbl.bundled_map_ops(&bufMapList, m_MemOpsTbl.userdata);
672 }
673
674 if (rc < 0) {
675 LOGE("Failed to map buffer");
676 rc = BAD_INDEX;
677 }
678 return rc;
679 }
680
681 /*===========================================================================
682 * FUNCTION : backgroundAllocate
683 *
684 * DESCRIPTION: schedule buffers to be allocated in the background
685 *
686 * PARAMETERS :
687 *
688 * RETURN : int32_t type of status
689 * NO_ERROR -- success
690 * none-zero failure code
691 *==========================================================================*/
backgroundAllocate(void * data)692 int32_t QCameraStream::backgroundAllocate(void *data) {
693 QCameraStream *stream = (QCameraStream*)data;
694 int32_t rc = stream->allocateBuffers();
695 if (rc != NO_ERROR) {
696 LOGE("Error allocating buffers !!!");
697 }
698 return rc;
699 }
700
701 /*===========================================================================
702 * FUNCTION : backgroundMap
703 *
704 * DESCRIPTION: map buffers in the background
705 *
706 * PARAMETERS :
707 *
708 * RETURN : int32_t type of status
709 * NO_ERROR -- success
710 * none-zero failure code
711 *==========================================================================*/
backgroundMap(void * data)712 int32_t QCameraStream::backgroundMap(void *data) {
713 QCameraStream *stream = (QCameraStream*)data;
714 int32_t rc = stream->mapBuffers();
715 if (rc != NO_ERROR) {
716 LOGE("Error mapping buffers !!!");
717 }
718 return rc;
719 }
720
721 /*===========================================================================
722 * FUNCTION : init
723 *
724 * DESCRIPTION: initialize stream obj
725 *
726 * PARAMETERS :
727 * @streamInfoBuf: ptr to buf that contains stream info
728 * @miscBuf : ptr to buf that contains misc bufs
729 * @stream_cb : stream data notify callback. Can be NULL if not needed
730 * @userdata : user data ptr
731 * @bDynallocBuf : flag to indicate if buffer allocation can be in 2 steps
732 *
733 * RETURN : int32_t type of status
734 * NO_ERROR -- success
735 * none-zero failure code
736 *==========================================================================*/
init(QCameraHeapMemory * streamInfoBuf,QCameraHeapMemory * miscBuf,stream_cb_routine stream_cb,void * userdata,bool bDynallocBuf)737 int32_t QCameraStream::init(QCameraHeapMemory *streamInfoBuf,
738 QCameraHeapMemory *miscBuf,
739 stream_cb_routine stream_cb,
740 void *userdata,
741 bool bDynallocBuf)
742 {
743 int32_t rc = OK;
744
745 // assign and map stream info memory
746 mStreamInfoBuf = streamInfoBuf;
747 mStreamInfo = reinterpret_cast<cam_stream_info_t *>(mStreamInfoBuf->getPtr(0));
748 mNumBufs = mStreamInfo->num_bufs;
749 mDynBufAlloc = bDynallocBuf;
750
751 // Calculate buffer size for deffered allocation
752 if (mDefferedAllocation) {
753 rc = calcOffset(mStreamInfo);
754 if (rc < 0) {
755 LOGE("Failed to calculate stream offset");
756 goto done;
757 }
758
759 mAllocTask.bgFunction = backgroundAllocate;
760 mAllocTask.bgArgs = this;
761 mAllocTaskId = mAllocator.scheduleBackgroundTask(&mAllocTask);
762 if (mAllocTaskId == 0) {
763 LOGE("Failed to schedule buffer alloction");
764 rc = -ENOMEM;
765 goto done;
766 }
767 }
768
769 mHandle = mCamOps->add_stream(mCamHandle, mChannelHandle);
770 if (!mHandle) {
771 LOGE("add_stream failed");
772 rc = UNKNOWN_ERROR;
773 goto done;
774 }
775
776 mMasterCamera = MM_CAMERA_TYPE_MAIN;
777 if (mCamType & MM_CAMERA_TYPE_MAIN) {
778 mActiveCameras = MM_CAMERA_TYPE_MAIN;
779 }
780 if (mCamType & MM_CAMERA_TYPE_AUX) {
781 mActiveCameras |= MM_CAMERA_TYPE_AUX;
782 }
783 if (isDualStream()) {
784 if (needFrameSync()) {
785 mCamOps->handle_frame_sync_cb(mCamHandle, mChannelHandle,
786 mHandle, MM_CAMERA_CB_REQ_TYPE_FRAME_SYNC);
787 } else if (!needCbSwitch()) {
788 mCamOps->handle_frame_sync_cb(mCamHandle, mChannelHandle,
789 mHandle, MM_CAMERA_CB_REQ_TYPE_ALL_CB);
790 }
791 }
792
793 rc = mapBufs(mStreamInfoBuf, CAM_MAPPING_BUF_TYPE_STREAM_INFO, NULL);
794 if (rc < 0) {
795 LOGE("Failed to map stream info buffer");
796 goto err1;
797 }
798
799 mMiscBuf = miscBuf;
800 if (miscBuf) {
801 rc = mapBufs(mMiscBuf, CAM_MAPPING_BUF_TYPE_MISC_BUF, NULL);
802 if (rc < 0) {
803 LOGE("Failed to map miscellaneous buffer");
804 releaseMiscBuf();
805 goto err1;
806 }
807 }
808
809 rc = configStream();
810 if (rc < 0) {
811 LOGE("Failed to config stream ");
812 goto err1;
813 }
814
815 if (mDefferedAllocation) {
816 mMapTask.bgFunction = backgroundMap;
817 mMapTask.bgArgs = this;
818 mMapTaskId = mAllocator.scheduleBackgroundTask(&mMapTask);
819 if (mMapTaskId == 0) {
820 LOGE("Failed to schedule buffer alloction");
821 rc = -ENOMEM;
822 goto err1;
823 }
824 }
825
826 mDataCB = stream_cb;
827 mUserData = userdata;
828 return 0;
829
830 err1:
831 mCamOps->delete_stream(mCamHandle, mChannelHandle, mHandle);
832 mHandle = 0;
833 done:
834 return rc;
835 }
836
837 /*===========================================================================
838 * FUNCTION : calcOffset
839 *
840 * DESCRIPTION: calculate frame offset based on format and padding information
841 *
842 * PARAMETERS :
843 * @streamInfo : stream information
844 *
845 * RETURN : int32_t type of status
846 * 0 -- success
847 * -1 -- failure
848 *==========================================================================*/
calcOffset(cam_stream_info_t * streamInfo)849 int32_t QCameraStream::calcOffset(cam_stream_info_t *streamInfo)
850 {
851 int32_t rc = 0;
852
853 cam_dimension_t dim = streamInfo->dim;
854 if (streamInfo->pp_config.feature_mask & CAM_QCOM_FEATURE_ROTATION &&
855 streamInfo->stream_type != CAM_STREAM_TYPE_VIDEO) {
856 if (streamInfo->pp_config.rotation == ROTATE_90 ||
857 streamInfo->pp_config.rotation == ROTATE_270) {
858 // rotated by 90 or 270, need to switch width and height
859 dim.width = streamInfo->dim.height;
860 dim.height = streamInfo->dim.width;
861 }
862 }
863
864 switch (streamInfo->stream_type) {
865 case CAM_STREAM_TYPE_PREVIEW:
866 case CAM_STREAM_TYPE_CALLBACK:
867 rc = mm_stream_calc_offset_preview(streamInfo,
868 &dim,
869 &mPaddingInfo,
870 &streamInfo->buf_planes);
871 break;
872 case CAM_STREAM_TYPE_POSTVIEW:
873 rc = mm_stream_calc_offset_post_view(streamInfo,
874 &dim,
875 &mPaddingInfo,
876 &streamInfo->buf_planes);
877 break;
878 case CAM_STREAM_TYPE_SNAPSHOT:
879 rc = mm_stream_calc_offset_snapshot(streamInfo->fmt,
880 &dim,
881 &mPaddingInfo,
882 &streamInfo->buf_planes);
883 break;
884 case CAM_STREAM_TYPE_OFFLINE_PROC:
885 rc = mm_stream_calc_offset_postproc(streamInfo,
886 &mPaddingInfo,
887 &streamInfo->buf_planes);
888 break;
889 case CAM_STREAM_TYPE_VIDEO:
890 rc = mm_stream_calc_offset_video(streamInfo->fmt,
891 &dim, &streamInfo->buf_planes);
892 break;
893 case CAM_STREAM_TYPE_RAW:
894 rc = mm_stream_calc_offset_raw(streamInfo,
895 &dim,
896 &mPaddingInfo,
897 &streamInfo->buf_planes);
898 break;
899 case CAM_STREAM_TYPE_ANALYSIS:
900 rc = mm_stream_calc_offset_analysis(streamInfo->fmt,
901 &dim,
902 &mPaddingInfo,
903 &streamInfo->buf_planes);
904 break;
905 case CAM_STREAM_TYPE_METADATA:
906 rc = mm_stream_calc_offset_metadata(&dim,
907 &mPaddingInfo,
908 &streamInfo->buf_planes);
909 break;
910 default:
911 LOGE("not supported for stream type %d",
912 streamInfo->stream_type);
913 rc = -1;
914 break;
915 }
916 return rc;
917 }
918
919 /*===========================================================================
920 * FUNCTION : start
921 *
922 * DESCRIPTION: start stream. Will start main stream thread to handle stream
923 * related ops.
924 *
925 * PARAMETERS : none
926 *
927 * RETURN : int32_t type of status
928 * NO_ERROR -- success
929 * none-zero failure code
930 *==========================================================================*/
start()931 int32_t QCameraStream::start()
932 {
933 int32_t rc = 0;
934 mDataQ.init();
935 rc = mProcTh.launch(dataProcRoutine, this);
936 if (rc == NO_ERROR) {
937 m_bActive = true;
938 }
939
940 mCurMetaMemory = NULL;
941 mCurBufIndex = -1;
942 mCurMetaIndex = -1;
943 mFirstTimeStamp = 0;
944 memset (&mStreamMetaMemory, 0,
945 (sizeof(MetaMemory) * CAMERA_MIN_VIDEO_BATCH_BUFFERS));
946 return rc;
947 }
948
949 /*===========================================================================
950 * FUNCTION : stop
951 *
952 * DESCRIPTION: stop stream. Will stop main stream thread
953 *
954 * PARAMETERS : none
955 *
956 * RETURN : int32_t type of status
957 * NO_ERROR -- success
958 * none-zero failure code
959 *==========================================================================*/
stop()960 int32_t QCameraStream::stop()
961 {
962 int32_t rc = 0;
963 m_bActive = false;
964 mAllocator.waitForBackgroundTask(mAllocTaskId);
965 mAllocator.waitForBackgroundTask(mMapTaskId);
966 rc = mProcTh.exit();
967 return rc;
968 }
969
970 /*===========================================================================
971 * FUNCTION : syncRuntimeParams
972 *
973 * DESCRIPTION: query and sync runtime parameters like output crop
974 * buffer info etc.
975 *
976 * PARAMETERS : none
977 *
978 * RETURN : int32_t type of status
979 * NO_ERROR -- success
980 * none-zero failure code
981 *==========================================================================*/
syncRuntimeParams()982 int32_t QCameraStream::syncRuntimeParams()
983 {
984 int32_t ret = NO_ERROR;
985
986 memset(&m_OutputCrop, 0, sizeof(cam_stream_parm_buffer_t));
987 m_OutputCrop.type = CAM_STREAM_PARAM_TYPE_GET_OUTPUT_CROP;
988
989 ret = getParameter(m_OutputCrop);
990 if (ret != NO_ERROR) {
991 LOGE("stream getParameter for output crop failed");
992 return ret;
993 }
994
995 memset(&m_ImgProp, 0, sizeof(cam_stream_parm_buffer_t));
996 m_ImgProp.type = CAM_STREAM_PARAM_TYPE_GET_IMG_PROP;
997
998 ret = getParameter(m_ImgProp);
999 if (ret != NO_ERROR) {
1000 LOGE("stream getParameter for image prop failed");
1001 return ret;
1002 }
1003
1004 return ret;
1005 }
1006
1007 /*===========================================================================
1008 * FUNCTION : processZoomDone
1009 *
1010 * DESCRIPTION: process zoom done event
1011 *
1012 * PARAMETERS :
1013 * @previewWindoe : preview window ops table to set preview crop window
1014 * @crop_info : crop info
1015 *
1016 * RETURN : int32_t type of status
1017 * NO_ERROR -- success
1018 * none-zero failure code
1019 *==========================================================================*/
processZoomDone(preview_stream_ops_t * previewWindow,cam_crop_data_t & crop_info)1020 int32_t QCameraStream::processZoomDone(preview_stream_ops_t *previewWindow,
1021 cam_crop_data_t &crop_info)
1022 {
1023 int32_t rc = 0;
1024
1025 if (!m_bActive) {
1026 LOGL("Stream not active");
1027 return NO_ERROR;
1028 }
1029
1030 // get stream param for crop info
1031 for (int i = 0; i < crop_info.num_of_streams; i++) {
1032 if (crop_info.crop_info[i].stream_id == mStreamInfo->stream_svr_id) {
1033 pthread_mutex_lock(&mCropLock);
1034 mCropInfo = crop_info.crop_info[i].crop;
1035 pthread_mutex_unlock(&mCropLock);
1036
1037 // update preview window crop if it's preview/postview stream
1038 if ( (previewWindow != NULL) &&
1039 (mStreamInfo->stream_type == CAM_STREAM_TYPE_PREVIEW ||
1040 mStreamInfo->stream_type == CAM_STREAM_TYPE_POSTVIEW) ) {
1041 rc = previewWindow->set_crop(previewWindow,
1042 mCropInfo.left,
1043 mCropInfo.top,
1044 mCropInfo.width,
1045 mCropInfo.height);
1046 }
1047 break;
1048 }
1049 }
1050 return rc;
1051 }
1052
1053 /*===========================================================================
1054 * FUNCTION : processDataNotify
1055 *
1056 * DESCRIPTION: process stream data notify
1057 *
1058 * PARAMETERS :
1059 * @frame : stream frame received
1060 *
1061 * RETURN : int32_t type of status
1062 * NO_ERROR -- success
1063 * none-zero failure code
1064 *==========================================================================*/
processDataNotify(mm_camera_super_buf_t * frame)1065 int32_t QCameraStream::processDataNotify(mm_camera_super_buf_t *frame)
1066 {
1067 LOGD("\n");
1068
1069 if (mDataQ.enqueue((void *)frame)) {
1070 return mProcTh.sendCmd(CAMERA_CMD_TYPE_DO_NEXT_JOB, FALSE, FALSE);
1071 } else {
1072 if (!m_bActive) {
1073 LOGW("Stream thread is not active, no ops here %d", getMyType());
1074 } else {
1075 bufDone(frame);
1076 }
1077 free(frame);
1078 return NO_ERROR;
1079 }
1080 }
1081
1082 /*===========================================================================
1083 * FUNCTION : dataNotifySYNCCB
1084 *
1085 * DESCRIPTION: This function registered with interface for
1086 * SYNC callback if SYNC callback registered.
1087 *
1088 * PARAMETERS :
1089 * @recvd_frame : stream frame received
1090 * @userdata : user data ptr
1091 *
1092 * RETURN : none
1093 *==========================================================================*/
dataNotifySYNCCB(mm_camera_super_buf_t * recvd_frame,void * userdata)1094 void QCameraStream::dataNotifySYNCCB(mm_camera_super_buf_t *recvd_frame,
1095 void *userdata)
1096 {
1097 LOGD("\n");
1098 QCameraStream* stream = (QCameraStream *)userdata;
1099 if (stream == NULL ||
1100 recvd_frame == NULL ||
1101 recvd_frame->bufs[0] == NULL ||
1102 !validate_handle(stream->getMyHandle(),
1103 recvd_frame->bufs[0]->stream_id)) {
1104 LOGE("Not a valid stream to handle buf");
1105 return;
1106 }
1107 if ((stream->mSyncCBEnabled) && (stream->mSYNCDataCB != NULL))
1108 stream->mSYNCDataCB(recvd_frame, stream, stream->mUserData);
1109 return;
1110 }
1111
1112 /*===========================================================================
1113 * FUNCTION : dataNotifyCB
1114 *
1115 * DESCRIPTION: callback for data notify. This function is registered with
1116 * mm-camera-interface to handle data notify
1117 *
1118 * PARAMETERS :
1119 * @recvd_frame : stream frame received
1120 * userdata : user data ptr
1121 *
1122 * RETURN : none
1123 *==========================================================================*/
dataNotifyCB(mm_camera_super_buf_t * recvd_frame,void * userdata)1124 void QCameraStream::dataNotifyCB(mm_camera_super_buf_t *recvd_frame,
1125 void *userdata)
1126 {
1127 LOGD("\n");
1128 QCameraStream* stream = (QCameraStream *)userdata;
1129 if (stream == NULL ||
1130 recvd_frame == NULL ||
1131 recvd_frame->bufs[0] == NULL ||
1132 !(validate_handle(stream->getMyHandle(),
1133 recvd_frame->bufs[0]->stream_id))) {
1134 LOGE("Not a valid stream to handle buf");
1135 return;
1136 }
1137
1138 mm_camera_super_buf_t *frame =
1139 (mm_camera_super_buf_t *)malloc(sizeof(mm_camera_super_buf_t));
1140 if (frame == NULL) {
1141 LOGE("No mem for mm_camera_buf_def_t");
1142 stream->bufDone(recvd_frame);
1143 return;
1144 }
1145 *frame = *recvd_frame;
1146 stream->processDataNotify(frame);
1147 return;
1148 }
1149
1150 /*===========================================================================
1151 * FUNCTION : dataProcRoutine
1152 *
1153 * DESCRIPTION: function to process data in the main stream thread
1154 *
1155 * PARAMETERS :
1156 * @data : user data ptr
1157 *
1158 * RETURN : none
1159 *==========================================================================*/
dataProcRoutine(void * data)1160 void *QCameraStream::dataProcRoutine(void *data)
1161 {
1162 int running = 1;
1163 int ret;
1164 QCameraStream *pme = (QCameraStream *)data;
1165 QCameraCmdThread *cmdThread = &pme->mProcTh;
1166 cmdThread->setName("CAM_strmDatProc");
1167
1168 LOGD("E");
1169 do {
1170 do {
1171 ret = cam_sem_wait(&cmdThread->cmd_sem);
1172 if (ret != 0 && errno != EINVAL) {
1173 LOGE("cam_sem_wait error (%s)",
1174 strerror(errno));
1175 return NULL;
1176 }
1177 } while (ret != 0);
1178
1179 // we got notified about new cmd avail in cmd queue
1180 camera_cmd_type_t cmd = cmdThread->getCmd();
1181 switch (cmd) {
1182 case CAMERA_CMD_TYPE_DO_NEXT_JOB:
1183 {
1184 LOGH("Do next job");
1185 mm_camera_super_buf_t *frame =
1186 (mm_camera_super_buf_t *)pme->mDataQ.dequeue();
1187 if (NULL != frame) {
1188 if (pme->mDataCB != NULL) {
1189 pme->mDataCB(frame, pme, pme->mUserData);
1190 } else {
1191 // no data cb routine, return buf here
1192 pme->bufDone(frame);
1193 free(frame);
1194 }
1195 }
1196 }
1197 break;
1198 case CAMERA_CMD_TYPE_EXIT:
1199 LOGH("Exit");
1200 /* flush data buf queue */
1201 pme->mDataQ.flush();
1202 running = 0;
1203 break;
1204 default:
1205 break;
1206 }
1207 } while (running);
1208 LOGH("X");
1209 return NULL;
1210 }
1211
1212 /*===========================================================================
1213 * FUNCTION : bufDone
1214 *
1215 * DESCRIPTION: return stream buffer to kernel
1216 *
1217 * PARAMETERS :
1218 * @index : index of buffer to be returned
1219 *
1220 * RETURN : int32_t type of status
1221 * NO_ERROR -- success
1222 * none-zero failure code
1223 *==========================================================================*/
bufDone(uint32_t index)1224 int32_t QCameraStream::bufDone(uint32_t index)
1225 {
1226 int32_t rc = NO_ERROR;
1227
1228 if (index >= mNumBufs || mBufDefs == NULL)
1229 return BAD_INDEX;
1230
1231 rc = mCamOps->qbuf(mCamHandle, mChannelHandle, &mBufDefs[index]);
1232
1233 if (rc < 0)
1234 return rc;
1235
1236 return rc;
1237 }
1238
1239 /*===========================================================================
1240 * FUNCTION : bufDone
1241 *
1242 * DESCRIPTION: return a stream buf back to kernel
1243 *
1244 * PARAMETERS :
1245 * @super_buf : stream buf frame to be returned
1246 *
1247 * RETURN : int32_t type of status
1248 * NO_ERROR -- success
1249 * none-zero failure code
1250 *==========================================================================*/
bufDone(mm_camera_super_buf_t * super_buf)1251 int32_t QCameraStream::bufDone (mm_camera_super_buf_t *super_buf)
1252 {
1253 int32_t rc = NO_ERROR;
1254 for (uint32_t i = 0; i < super_buf->num_bufs; i++) {
1255 if (super_buf->bufs[i] != NULL) {
1256 rc |= bufDone(super_buf->bufs[i]->buf_idx);
1257 }
1258 }
1259 return rc;
1260 }
1261
1262 /*===========================================================================
1263 * FUNCTION : bufDone
1264 *
1265 * DESCRIPTION: return stream buffer to kernel
1266 *
1267 * PARAMETERS :
1268 * @opaque : stream frame/metadata buf to be returned
1269 * @isMetaData: flag if returned opaque is a metadatabuf or the real frame ptr
1270 *
1271 * RETURN : int32_t type of status
1272 * NO_ERROR -- success
1273 * none-zero failure code
1274 *==========================================================================*/
bufDone(const void * opaque,bool isMetaData)1275 int32_t QCameraStream::bufDone(const void *opaque, bool isMetaData)
1276 {
1277 int32_t rc = NO_ERROR;
1278 int index = -1;
1279 QCameraVideoMemory *mVideoMem = NULL;
1280 bool needPerfEvet = FALSE;
1281
1282 if ((mStreamInfo != NULL)
1283 && (mStreamInfo->streaming_mode == CAM_STREAMING_MODE_BATCH)
1284 && (mStreamBatchBufs != NULL)) {
1285 mVideoMem = (QCameraVideoMemory *)mStreamBatchBufs;
1286 } else if (mStreamBufs != NULL){
1287 mVideoMem = (QCameraVideoMemory *)mStreamBufs;
1288 }
1289
1290 //Close and delete duplicated native handle and FD's.
1291 if (mVideoMem != NULL) {
1292 index = mVideoMem->getMatchBufIndex(opaque, isMetaData);
1293 needPerfEvet = mVideoMem->needPerfEvent(opaque, isMetaData);
1294 rc = mVideoMem->closeNativeHandle(opaque, isMetaData);
1295 if (rc != NO_ERROR) {
1296 LOGE("Invalid video metadata");
1297 return rc;
1298 }
1299 } else {
1300 LOGE("Possible FD leak. Release recording called after stop");
1301 }
1302
1303 if (index == -1 || index >= mNumBufs || mBufDefs == NULL) {
1304 LOGE("Cannot find buf for opaque data = %p", opaque);
1305 return BAD_INDEX;
1306 }
1307
1308 if (needPerfEvet == TRUE) {
1309 //Trigger Perf Flush event to back-end
1310 cam_stream_parm_buffer_t param;
1311 memset(¶m, 0, sizeof(cam_stream_parm_buffer_t));
1312 param.type = CAM_STREAM_PARAM_TYPE_FLUSH_FRAME;
1313 rc = setParameter(param);
1314 }
1315
1316 if ((CAMERA_MIN_VIDEO_BATCH_BUFFERS > index)
1317 && mStreamMetaMemory[index].numBuffers > 0) {
1318 for (int i= 0; i < mStreamMetaMemory[index].numBuffers; i++) {
1319 uint8_t buf_idx = mStreamMetaMemory[index].buf_index[i];
1320 bufDone((uint32_t)buf_idx);
1321 }
1322 mStreamMetaMemory[index].consumerOwned = FALSE;
1323 mStreamMetaMemory[index].numBuffers = 0;
1324 } else {
1325 LOGH("Buffer Index = %d, Frame Idx = %d", index,
1326 mBufDefs[index].frame_idx);
1327 rc = bufDone((uint32_t)index);
1328 }
1329
1330 return rc;
1331 }
1332
1333 /*===========================================================================
1334 * FUNCTION : getNumQueuedBuf
1335 *
1336 * DESCRIPTION: return queued buffer count
1337 *
1338 * PARAMETERS : None
1339 *
1340 * RETURN : queued buffer count
1341 *==========================================================================*/
getNumQueuedBuf()1342 int32_t QCameraStream::getNumQueuedBuf()
1343 {
1344 int32_t rc = -1;
1345 if (mHandle > 0) {
1346 rc = mCamOps->get_queued_buf_count(mCamHandle, mChannelHandle, mHandle);
1347 }
1348 if (rc == -1) {
1349 LOGE("stream is not in active state. Invalid operation");
1350 }
1351 return rc;
1352 }
1353
1354 /*===========================================================================
1355 * FUNCTION : getBufs
1356 *
1357 * DESCRIPTION: allocate stream buffers
1358 *
1359 * PARAMETERS :
1360 * @offset : offset info of stream buffers
1361 * @num_bufs : number of buffers allocated
1362 * @initial_reg_flag: flag to indicate if buffer needs to be registered
1363 * at kernel initially
1364 * @bufs : output of allocated buffers
1365 * @ops_tbl : ptr to buf mapping/unmapping ops
1366 *
1367 * RETURN : int32_t type of status
1368 * NO_ERROR -- success
1369 * none-zero failure code
1370 *==========================================================================*/
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)1371 int32_t QCameraStream::getBufs(cam_frame_len_offset_t *offset,
1372 uint8_t *num_bufs,
1373 uint8_t **initial_reg_flag,
1374 mm_camera_buf_def_t **bufs,
1375 mm_camera_map_unmap_ops_tbl_t *ops_tbl)
1376 {
1377 int rc = NO_ERROR;
1378 uint8_t *regFlags;
1379
1380 if (!ops_tbl) {
1381 LOGE("ops_tbl is NULL");
1382 return INVALID_OPERATION;
1383 }
1384
1385 mFrameLenOffset = *offset;
1386
1387 uint8_t numBufAlloc = mNumBufs;
1388 mNumBufsNeedAlloc = 0;
1389 if (mDynBufAlloc) {
1390 numBufAlloc = CAMERA_MIN_ALLOCATED_BUFFERS;
1391 if (numBufAlloc > mNumBufs) {
1392 mDynBufAlloc = false;
1393 numBufAlloc = mNumBufs;
1394 } else {
1395 mNumBufsNeedAlloc = (uint8_t)(mNumBufs - numBufAlloc);
1396 }
1397 }
1398
1399 /* For some stream types, buffer allocation may have already begun
1400 * preemptively. If this is the case, we need to wait for the
1401 * preemptive allocation to complete before proceeding. */
1402 mAllocator.waitForDeferredAlloc(mStreamInfo->stream_type);
1403
1404 //Allocate stream buffer
1405 mStreamBufs = mAllocator.allocateStreamBuf(mStreamInfo->stream_type,
1406 mFrameLenOffset.frame_len, mFrameLenOffset.mp[0].stride,
1407 mFrameLenOffset.mp[0].scanline, numBufAlloc);
1408 if (!mStreamBufs) {
1409 LOGE("Failed to allocate stream buffers");
1410 return NO_MEMORY;
1411 }
1412
1413 mNumBufs = (uint8_t)(numBufAlloc + mNumBufsNeedAlloc);
1414 uint8_t numBufsToMap = mStreamBufs->getMappable();
1415
1416 QCameraBufferMaps bufferMaps;
1417 for (uint32_t i = 0; i < numBufsToMap; i++) {
1418 ssize_t bufSize = mStreamBufs->getSize(i);
1419 if (BAD_INDEX == bufSize) {
1420 LOGE("Failed to retrieve buffer size (bad index)");
1421 return INVALID_OPERATION;
1422 }
1423
1424 rc = bufferMaps.enqueue(CAM_MAPPING_BUF_TYPE_STREAM_BUF,
1425 0 /*stream id*/, i /*buf index*/, -1 /*plane index*/,
1426 0 /*cookie*/, mStreamBufs->getFd(i), bufSize,
1427 mStreamBufs->getPtr(i));
1428
1429 if (rc < 0) {
1430 LOGE("Failed to map buffers");
1431 return BAD_INDEX;
1432 }
1433 }
1434
1435 cam_buf_map_type_list bufMapList;
1436 rc = bufferMaps.getCamBufMapList(bufMapList);
1437 if (rc == NO_ERROR) {
1438 rc = ops_tbl->bundled_map_ops(&bufMapList, ops_tbl->userdata);
1439 }
1440 if (rc < 0) {
1441 LOGE("map_stream_buf failed: %d", rc);
1442 mStreamBufs->deallocate();
1443 delete mStreamBufs;
1444 mStreamBufs = NULL;
1445 return INVALID_OPERATION;
1446 }
1447
1448 //regFlags array is allocated by us, but consumed and freed by mm-camera-interface
1449 regFlags = (uint8_t *)malloc(sizeof(uint8_t) * mNumBufs);
1450 if (!regFlags) {
1451 LOGE("Out of memory");
1452 for (uint32_t i = 0; i < numBufsToMap; i++) {
1453 ops_tbl->unmap_ops(i, -1, CAM_MAPPING_BUF_TYPE_STREAM_BUF, ops_tbl->userdata);
1454 }
1455 mStreamBufs->deallocate();
1456 delete mStreamBufs;
1457 mStreamBufs = NULL;
1458 return NO_MEMORY;
1459 }
1460 memset(regFlags, 0, sizeof(uint8_t) * mNumBufs);
1461
1462 mBufDefs = (mm_camera_buf_def_t *)malloc(mNumBufs * sizeof(mm_camera_buf_def_t));
1463 if (mBufDefs == NULL) {
1464 LOGE("getRegFlags failed %d", rc);
1465 for (uint32_t i = 0; i < numBufsToMap; i++) {
1466 ops_tbl->unmap_ops(i, -1, CAM_MAPPING_BUF_TYPE_STREAM_BUF, ops_tbl->userdata);
1467 }
1468 mStreamBufs->deallocate();
1469 delete mStreamBufs;
1470 mStreamBufs = NULL;
1471 free(regFlags);
1472 regFlags = NULL;
1473 return INVALID_OPERATION;
1474 }
1475 memset(mBufDefs, 0, mNumBufs * sizeof(mm_camera_buf_def_t));
1476 for (uint32_t i = 0; i < numBufsToMap; i++) {
1477 mStreamBufs->getBufDef(mFrameLenOffset, mBufDefs[i], i);
1478 }
1479
1480 rc = mStreamBufs->getRegFlags(regFlags);
1481 if (rc < 0) {
1482 LOGE("getRegFlags failed %d", rc);
1483 for (uint32_t i = 0; i < numBufsToMap; i++) {
1484 ops_tbl->unmap_ops(i, -1, CAM_MAPPING_BUF_TYPE_STREAM_BUF, ops_tbl->userdata);
1485 }
1486 mStreamBufs->deallocate();
1487 delete mStreamBufs;
1488 mStreamBufs = NULL;
1489 free(mBufDefs);
1490 mBufDefs = NULL;
1491 free(regFlags);
1492 regFlags = NULL;
1493 return INVALID_OPERATION;
1494 }
1495
1496 *num_bufs = mNumBufs;
1497 *initial_reg_flag = regFlags;
1498 *bufs = mBufDefs;
1499 LOGH("stream type: %d, mRegFlags: 0x%x, numBufs: %d",
1500 mStreamInfo->stream_type, regFlags, mNumBufs);
1501
1502 if (mNumBufsNeedAlloc > 0) {
1503 pthread_mutex_lock(&m_lock);
1504 wait_for_cond = TRUE;
1505 pthread_mutex_unlock(&m_lock);
1506 LOGH("Still need to allocate %d buffers",
1507 mNumBufsNeedAlloc);
1508 // start another thread to allocate the rest of buffers
1509 pthread_create(&mBufAllocPid,
1510 NULL,
1511 BufAllocRoutine,
1512 this);
1513 pthread_setname_np(mBufAllocPid, "CAM_strmBuf");
1514 }
1515 return NO_ERROR;
1516 }
1517
1518 /*===========================================================================
1519 * FUNCTION : getBufsDeferred
1520 *
1521 * DESCRIPTION: allocate deferred stream buffers
1522 *
1523 * PARAMETERS :
1524 * @offset : offset info of stream buffers
1525 * @num_bufs : number of buffers allocated
1526 * @initial_reg_flag: flag to indicate if buffer needs to be registered
1527 * at kernel initially
1528 * @bufs : output of allocated buffers
1529 * @ops_tbl : ptr to buf mapping/unmapping ops
1530 *
1531 * RETURN : int32_t type of status
1532 * NO_ERROR -- success
1533 * none-zero failure code
1534 *==========================================================================*/
getBufsDeferred(__unused cam_frame_len_offset_t * offset,uint8_t * num_bufs,uint8_t ** initial_reg_flag,mm_camera_buf_def_t ** bufs,__unused mm_camera_map_unmap_ops_tbl_t * ops_tbl)1535 int32_t QCameraStream::getBufsDeferred(__unused cam_frame_len_offset_t *offset,
1536 uint8_t *num_bufs,
1537 uint8_t **initial_reg_flag,
1538 mm_camera_buf_def_t **bufs,
1539 __unused mm_camera_map_unmap_ops_tbl_t *ops_tbl)
1540 {
1541 int32_t rc = NO_ERROR;
1542 // wait for allocation
1543 rc = mAllocator.waitForBackgroundTask(mAllocTaskId);
1544 if (rc != NO_ERROR) {
1545 LOGE("Allocation Failed");
1546 return NO_MEMORY;
1547 }
1548
1549 if (!mRegFlags || !mBufDefs) {
1550 LOGE("reg flags or buf defs uninitialized");
1551 return NO_MEMORY;
1552 }
1553
1554 *initial_reg_flag = mRegFlags;
1555 *num_bufs = mNumBufs;
1556 *bufs = mBufDefs;
1557
1558 LOGH("stream type: %d, mRegFlags: 0x%x, numBufs: %d",
1559 getMyType(), mRegFlags, mNumBufs);
1560
1561 return NO_ERROR;
1562 }
1563 /*===========================================================================
1564 * FUNCTION : mapNewBuffer
1565 *
1566 * DESCRIPTION: map a new stream buffer
1567 *
1568 * PARAMETERS :
1569 *
1570 * RETURN : int32_t type of status
1571 * NO_ERROR -- success
1572 * none-zero failure code
1573 *==========================================================================*/
mapNewBuffer(uint32_t index)1574 int32_t QCameraStream::mapNewBuffer(uint32_t index)
1575 {
1576 LOGH("E - index = %d", index);
1577
1578 int rc = NO_ERROR;
1579
1580 if (mStreamBufs == NULL) {
1581 LOGE("Invalid Operation");
1582 return INVALID_OPERATION;
1583 }
1584
1585 ssize_t bufSize = mStreamBufs->getSize(index);
1586 if (BAD_INDEX == bufSize) {
1587 LOGE("Failed to retrieve buffer size (bad index)");
1588 return INVALID_OPERATION;
1589 }
1590
1591 cam_buf_map_type_list bufMapList;
1592 rc = QCameraBufferMaps::makeSingletonBufMapList(
1593 CAM_MAPPING_BUF_TYPE_STREAM_BUF, 0 /*stream id*/, index,
1594 -1 /*plane index*/, 0 /*cookie*/, mStreamBufs->getFd(index),
1595 bufSize, bufMapList, mStreamBufs->getPtr(index));
1596
1597 if (rc == NO_ERROR) {
1598 rc = m_MemOpsTbl.bundled_map_ops(&bufMapList, m_MemOpsTbl.userdata);
1599 }
1600 if (rc < 0) {
1601 LOGE("map_stream_buf failed: %d", rc);
1602 rc = INVALID_OPERATION;
1603 } else {
1604 mStreamBufs->getBufDef(mFrameLenOffset, mBufDefs[index], index);
1605 }
1606
1607 LOGH("X - rc = %d", rc);
1608 return rc;
1609 }
1610
1611 /*===========================================================================
1612 * FUNCTION : allocateBuffers
1613 *
1614 * DESCRIPTION: allocate stream buffers
1615 *
1616 * PARAMETERS :
1617 *
1618 * RETURN : int32_t type of status
1619 * NO_ERROR -- success
1620 * none-zero failure code
1621 *==========================================================================*/
allocateBuffers()1622 int32_t QCameraStream::allocateBuffers()
1623 {
1624 int32_t rc = NO_ERROR;
1625
1626 mFrameLenOffset = mStreamInfo->buf_planes.plane_info;
1627
1628 if (mStreamInfo->streaming_mode == CAM_STREAMING_MODE_BATCH) {
1629 return allocateBatchBufs(&mFrameLenOffset,
1630 &mNumBufs, &mRegFlags,
1631 &mBufDefs, NULL);
1632 }
1633
1634 /* This allocation is running in the deferred context, so it
1635 * is safe (and necessary) to assume any preemptive allocation
1636 * is already complete. Therefore, no need to wait here. */
1637
1638 uint8_t numBufAlloc = mNumBufs;
1639 mNumBufsNeedAlloc = 0;
1640 if (mDynBufAlloc) {
1641 numBufAlloc = CAMERA_MIN_ALLOCATED_BUFFERS;
1642 if (numBufAlloc > mNumBufs) {
1643 mDynBufAlloc = false;
1644 numBufAlloc = mNumBufs;
1645 } else {
1646 mNumBufsNeedAlloc = (uint8_t)(mNumBufs - numBufAlloc);
1647 }
1648 }
1649
1650 //Allocate and map stream info buffer
1651 mStreamBufs = mAllocator.allocateStreamBuf(mStreamInfo->stream_type,
1652 mFrameLenOffset.frame_len,
1653 mFrameLenOffset.mp[0].stride,
1654 mFrameLenOffset.mp[0].scanline,
1655 numBufAlloc);
1656
1657 if (!mStreamBufs) {
1658 LOGE("Failed to allocate stream buffers");
1659 return NO_MEMORY;
1660 }
1661
1662 mNumBufs = (uint8_t)(numBufAlloc + mNumBufsNeedAlloc);
1663 uint8_t numBufsToMap = mStreamBufs->getMappable();
1664
1665 //regFlags array is allocated by us,
1666 // but consumed and freed by mm-camera-interface
1667 mRegFlags = (uint8_t *)malloc(sizeof(uint8_t) * mNumBufs);
1668 if (!mRegFlags) {
1669 LOGE("Out of memory");
1670 for (uint32_t i = 0; i < numBufsToMap; i++) {
1671 unmapBuf(CAM_MAPPING_BUF_TYPE_STREAM_BUF, i, -1, NULL);
1672 }
1673 mStreamBufs->deallocate();
1674 delete mStreamBufs;
1675 mStreamBufs = NULL;
1676 return NO_MEMORY;
1677 }
1678 memset(mRegFlags, 0, sizeof(uint8_t) * mNumBufs);
1679
1680 size_t bufDefsSize = mNumBufs * sizeof(mm_camera_buf_def_t);
1681 mBufDefs = (mm_camera_buf_def_t *)malloc(bufDefsSize);
1682 if (mBufDefs == NULL) {
1683 LOGE("getRegFlags failed %d", rc);
1684 for (uint32_t i = 0; i < numBufsToMap; i++) {
1685 unmapBuf(CAM_MAPPING_BUF_TYPE_STREAM_BUF, i, -1, NULL);
1686 }
1687 mStreamBufs->deallocate();
1688 delete mStreamBufs;
1689 mStreamBufs = NULL;
1690 free(mRegFlags);
1691 mRegFlags = NULL;
1692 return INVALID_OPERATION;
1693 }
1694 memset(mBufDefs, 0, bufDefsSize);
1695 for (uint32_t i = 0; i < numBufsToMap; i++) {
1696 mStreamBufs->getBufDef(mFrameLenOffset, mBufDefs[i], i);
1697 }
1698
1699 rc = mStreamBufs->getRegFlags(mRegFlags);
1700 if (rc < 0) {
1701 LOGE("getRegFlags failed %d", rc);
1702 for (uint32_t i = 0; i < numBufsToMap; i++) {
1703 unmapBuf(CAM_MAPPING_BUF_TYPE_STREAM_BUF, i, -1, NULL);
1704 }
1705 mStreamBufs->deallocate();
1706 delete mStreamBufs;
1707 mStreamBufs = NULL;
1708 free(mBufDefs);
1709 mBufDefs = NULL;
1710 free(mRegFlags);
1711 mRegFlags = NULL;
1712 return INVALID_OPERATION;
1713 }
1714
1715 if (mNumBufsNeedAlloc > 0) {
1716 pthread_mutex_lock(&m_lock);
1717 wait_for_cond = TRUE;
1718 pthread_mutex_unlock(&m_lock);
1719 LOGH("Still need to allocate %d buffers",
1720 mNumBufsNeedAlloc);
1721 // start another thread to allocate the rest of buffers
1722 pthread_create(&mBufAllocPid,
1723 NULL,
1724 BufAllocRoutine,
1725 this);
1726 pthread_setname_np(mBufAllocPid, "CAM_strmBufAlloc");
1727 }
1728 return rc;
1729 }
1730
1731 /*===========================================================================
1732 * FUNCTION : mapBuffers
1733 *
1734 * DESCRIPTION: map stream buffers
1735 *
1736 * PARAMETERS :
1737 *
1738 * RETURN : int32_t type of status
1739 * NO_ERROR -- success
1740 * none-zero failure code
1741 *==========================================================================*/
mapBuffers()1742 int32_t QCameraStream::mapBuffers()
1743 {
1744 int32_t rc = NO_ERROR;
1745 QCameraBufferMaps bufferMaps;
1746
1747 rc = mAllocator.waitForBackgroundTask(mAllocTaskId);
1748 if (rc != NO_ERROR) {
1749 LOGE("Allocation Failed");
1750 return NO_MEMORY;
1751 }
1752
1753 if (mStreamBufs == NULL) {
1754 LOGE("Stream buffers not allocated");
1755 return UNKNOWN_ERROR;
1756 }
1757
1758 uint8_t numBufsToMap = mStreamBufs->getMappable();
1759 for (uint32_t i = 0; i < numBufsToMap; i++) {
1760 ssize_t bufSize = mStreamBufs->getSize(i);
1761 if (BAD_INDEX != bufSize) {
1762 rc = bufferMaps.enqueue(CAM_MAPPING_BUF_TYPE_STREAM_BUF, mHandle,
1763 i /*buf index*/, -1 /*plane index*/, 0 /*cookie*/,
1764 mStreamBufs->getFd(i), bufSize,
1765 mStreamBufs->getPtr(i));
1766
1767 if (rc < 0) {
1768 LOGE("Failed to map buffers");
1769 rc = BAD_INDEX;
1770 break;
1771 }
1772 } else {
1773 LOGE("Bad index %u", i);
1774 rc = BAD_INDEX;
1775 break;
1776 }
1777 }
1778
1779 cam_buf_map_type_list bufMapList;
1780 if (rc == NO_ERROR) {
1781 rc = bufferMaps.getCamBufMapList(bufMapList);
1782 }
1783 if (rc == NO_ERROR) {
1784 rc = mapBufs(bufMapList, NULL);
1785 }
1786 return rc;
1787 }
1788
1789 /*===========================================================================
1790 * FUNCTION : allocateBatchBufs
1791 *
1792 * DESCRIPTION: allocate stream batch buffers and stream buffers
1793 *
1794 * PARAMETERS :
1795 * @offset : offset info of stream buffers
1796 * @num_bufs : number of buffers allocated
1797 * @initial_reg_flag: flag to indicate if buffer needs to be registered
1798 * at kernel initially
1799 * @bufs : output of allocated buffers
1800 * @plane_bufs : output of allocated plane buffers
1801 * @ops_tbl : ptr to buf mapping/unmapping ops
1802 *
1803 * RETURN : int32_t type of status
1804 * NO_ERROR -- success
1805 * none-zero failure code
1806 *==========================================================================*/
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)1807 int32_t QCameraStream::allocateBatchBufs(cam_frame_len_offset_t *offset,
1808 uint8_t *num_bufs, uint8_t **initial_reg_flag,
1809 mm_camera_buf_def_t **bufs, mm_camera_map_unmap_ops_tbl_t *ops_tbl)
1810 {
1811 int rc = NO_ERROR;
1812 uint8_t *regFlags;
1813 QCameraBufferMaps bufferMaps;
1814 QCameraBufferMaps planeBufferMaps;
1815
1816 mFrameLenOffset = *offset;
1817
1818 LOGH("Batch Buffer allocation stream type = %d", getMyType());
1819
1820 //Allocate stream batch buffer
1821 mStreamBatchBufs = mAllocator.allocateStreamUserBuf (mStreamInfo);
1822 if (!mStreamBatchBufs) {
1823 LOGE("Failed to allocate stream batch buffers");
1824 return NO_MEMORY;
1825 }
1826
1827 uint8_t numBufsToMap = mStreamBatchBufs->getMappable();
1828
1829 //map batch buffers
1830 for (uint32_t i = 0; i < numBufsToMap; i++) {
1831 rc = bufferMaps.enqueue(CAM_MAPPING_BUF_TYPE_STREAM_USER_BUF,
1832 0 /*stream id*/, i /*buf index*/, -1 /*plane index*/,
1833 0 /*cookie*/, mStreamBatchBufs->getFd(i),
1834 mNumBufs, mStreamBatchBufs->getPtr(i));
1835
1836 if (rc < 0) {
1837 LOGE("Failed to map buffers");
1838 rc = BAD_INDEX;
1839 break;
1840 }
1841 }
1842
1843 cam_buf_map_type_list bufMapList;
1844 if (rc == NO_ERROR) {
1845 rc = bufferMaps.getCamBufMapList(bufMapList);
1846 }
1847 if (rc == NO_ERROR) {
1848 rc = mapBufs(bufMapList, ops_tbl);
1849 }
1850 if (rc < 0) {
1851 LOGE("Failed to map stream batch buffers");
1852 mStreamBatchBufs->deallocate();
1853 delete mStreamBatchBufs;
1854 mStreamBatchBufs = NULL;
1855 return NO_MEMORY;
1856 }
1857
1858 /*calculate stream Buffer count*/
1859 mNumPlaneBufs =
1860 (mNumBufs * mStreamInfo->user_buf_info.frame_buf_cnt);
1861
1862 /* For some stream types, buffer allocation may have already begun
1863 * preemptively. If this is the case, we need to wait for the
1864 * preemptive allocation to complete before proceeding. */
1865 mAllocator.waitForDeferredAlloc(mStreamInfo->stream_type);
1866
1867 //Allocate stream buffer
1868 mStreamBufs = mAllocator.allocateStreamBuf(mStreamInfo->stream_type,
1869 mFrameLenOffset.frame_len,mFrameLenOffset.mp[0].stride,
1870 mFrameLenOffset.mp[0].scanline,mNumPlaneBufs);
1871 if (!mStreamBufs) {
1872 LOGE("Failed to allocate stream buffers");
1873 rc = NO_MEMORY;
1874 goto err1;
1875 }
1876
1877 //Map plane stream buffers
1878 for (uint32_t i = 0; i < mNumPlaneBufs; i++) {
1879 ssize_t bufSize = mStreamBufs->getSize(i);
1880 if (BAD_INDEX != bufSize) {
1881 rc = planeBufferMaps.enqueue(CAM_MAPPING_BUF_TYPE_STREAM_BUF,
1882 0 /*stream id*/, i /*buf index*/, -1 /*plane index*/,
1883 0 /*cookie*/, mStreamBufs->getFd(i), bufSize,
1884 mStreamBufs->getPtr(i));
1885
1886 if (rc < 0) {
1887 LOGE("Failed to map buffers");
1888 mStreamBufs->deallocate();
1889 delete mStreamBufs;
1890 mStreamBufs = NULL;
1891 rc = INVALID_OPERATION;
1892 goto err1;
1893 }
1894 } else {
1895 LOGE("Failed to retrieve buffer size (bad index)");
1896 mStreamBufs->deallocate();
1897 delete mStreamBufs;
1898 mStreamBufs = NULL;
1899 rc = INVALID_OPERATION;
1900 goto err1;
1901 }
1902 }
1903
1904 cam_buf_map_type_list planeBufMapList;
1905 rc = planeBufferMaps.getCamBufMapList(planeBufMapList);
1906 if (rc == NO_ERROR) {
1907 rc = mapBufs(planeBufMapList, ops_tbl);
1908 }
1909
1910 if (rc < 0) {
1911 LOGE("map_stream_buf failed: %d", rc);
1912 mStreamBufs->deallocate();
1913 delete mStreamBufs;
1914 mStreamBufs = NULL;
1915 rc = INVALID_OPERATION;
1916 goto err1;
1917 }
1918
1919 LOGD("BATCH Buf Count = %d, Plane Buf Cnt = %d",
1920 mNumBufs, mNumPlaneBufs);
1921
1922 //regFlags array is allocated by us, but consumed and freed by mm-camera-interface
1923 regFlags = (uint8_t *)malloc(sizeof(uint8_t) * mNumBufs);
1924 if (!regFlags) {
1925 LOGE("Out of memory");
1926 for (uint32_t i = 0; i < mNumPlaneBufs; i++) {
1927 unmapBuf(CAM_MAPPING_BUF_TYPE_STREAM_BUF, i, -1, ops_tbl);
1928 }
1929 mStreamBufs->deallocate();
1930 delete mStreamBufs;
1931 mStreamBufs = NULL;
1932 rc = NO_MEMORY;
1933 goto err1;
1934 }
1935 memset(regFlags, 0, sizeof(uint8_t) * mNumBufs);
1936 for (uint32_t i = 0; i < mNumBufs; i++) {
1937 regFlags[i] = 1;
1938 }
1939
1940 mBufDefs = (mm_camera_buf_def_t *)malloc(mNumBufs * sizeof(mm_camera_buf_def_t));
1941 if (mBufDefs == NULL) {
1942 LOGE("getRegFlags failed %d", rc);
1943 for (uint32_t i = 0; i < mNumPlaneBufs; i++) {
1944 unmapBuf(CAM_MAPPING_BUF_TYPE_STREAM_BUF, i, -1, ops_tbl);
1945 }
1946 mStreamBufs->deallocate();
1947 delete mStreamBufs;
1948 mStreamBufs = NULL;
1949 free(regFlags);
1950 regFlags = NULL;
1951 rc = INVALID_OPERATION;
1952 goto err1;
1953 }
1954 memset(mBufDefs, 0, mNumBufs * sizeof(mm_camera_buf_def_t));
1955
1956 mPlaneBufDefs = (mm_camera_buf_def_t *)
1957 malloc(mNumPlaneBufs * (sizeof(mm_camera_buf_def_t)));
1958 if (mPlaneBufDefs == NULL) {
1959 LOGE("No Memory");
1960 free(regFlags);
1961 regFlags = NULL;
1962 free(mBufDefs);
1963 mBufDefs = NULL;
1964 for (uint32_t i = 0; i < mNumPlaneBufs; i++) {
1965 unmapBuf(CAM_MAPPING_BUF_TYPE_STREAM_BUF, i, -1, ops_tbl);
1966 }
1967 mStreamBufs->deallocate();
1968 delete mStreamBufs;
1969 mStreamBufs = NULL;
1970 free(regFlags);
1971 regFlags = NULL;
1972 rc = INVALID_OPERATION;
1973 goto err1;
1974 }
1975 memset(mPlaneBufDefs, 0,
1976 mNumPlaneBufs * (sizeof(mm_camera_buf_def_t)));
1977
1978 for (uint32_t i = 0; i < mStreamInfo->num_bufs; i++) {
1979 mStreamBatchBufs->getUserBufDef(mStreamInfo->user_buf_info,
1980 mBufDefs[i], i, mFrameLenOffset, mPlaneBufDefs,
1981 mStreamBufs);
1982 }
1983
1984 *num_bufs = mNumBufs;
1985 *initial_reg_flag = regFlags;
1986 *bufs = mBufDefs;
1987 LOGH("stream type: %d, numBufs: %d mNumPlaneBufs: %d",
1988 mStreamInfo->stream_type, mNumBufs, mNumPlaneBufs);
1989
1990 return NO_ERROR;
1991
1992 err1:
1993 mStreamBatchBufs->deallocate();
1994 delete mStreamBatchBufs;
1995 mStreamBatchBufs = NULL;
1996 return rc;
1997 }
1998
1999
2000 /*===========================================================================
2001 * FUNCTION : releaseBuffs
2002 *
2003 * DESCRIPTION: method to deallocate stream buffers
2004 *
2005 * PARAMETERS :
2006 *
2007 * RETURN : int32_t type of status
2008 * NO_ERROR -- success
2009 * none-zero failure code
2010 *==========================================================================*/
releaseBuffs()2011 int32_t QCameraStream::releaseBuffs()
2012 {
2013 int rc = NO_ERROR;
2014
2015 if (mBufAllocPid != 0) {
2016 cond_signal(true);
2017 LOGD("wait for buf allocation thread dead");
2018 pthread_join(mBufAllocPid, NULL);
2019 mBufAllocPid = 0;
2020 LOGD("return from buf allocation thread");
2021 }
2022
2023 if (mStreamInfo->streaming_mode == CAM_STREAMING_MODE_BATCH) {
2024 return releaseBatchBufs(NULL);
2025 }
2026
2027 if ((NULL != mBufDefs) && (mStreamBufs != NULL)) {
2028 uint8_t numBufsToUnmap = mStreamBufs->getMappable();
2029 for (uint32_t i = 0; i < numBufsToUnmap; i++) {
2030 rc = unmapBuf(CAM_MAPPING_BUF_TYPE_STREAM_BUF, i, -1, NULL);
2031 if (rc < 0) {
2032 LOGE("map_stream_buf failed: %d", rc);
2033 }
2034 }
2035
2036 // mBufDefs just keep a ptr to the buffer
2037 // mm-camera-interface own the buffer, so no need to free
2038 mBufDefs = NULL;
2039 memset(&mFrameLenOffset, 0, sizeof(mFrameLenOffset));
2040 }
2041 if (!mStreamBufsAcquired && (mStreamBufs != NULL)) {
2042 mStreamBufs->deallocate();
2043 delete mStreamBufs;
2044 mStreamBufs = NULL;
2045 }
2046 return rc;
2047 }
2048
2049 /*===========================================================================
2050 * FUNCTION : releaseBatchBufs
2051 *
2052 * DESCRIPTION: method to deallocate stream buffers and batch buffers
2053 *
2054 * PARAMETERS :
2055 * @ops_tbl : ptr to buf mapping/unmapping ops
2056 *
2057 * RETURN : int32_t type of status
2058 * NO_ERROR -- success
2059 * none-zero failure code
2060
2061 *==========================================================================*/
releaseBatchBufs(mm_camera_map_unmap_ops_tbl_t * ops_tbl)2062 int32_t QCameraStream::releaseBatchBufs(mm_camera_map_unmap_ops_tbl_t *ops_tbl)
2063 {
2064 int rc = NO_ERROR;
2065
2066 if (NULL != mPlaneBufDefs) {
2067 for (uint32_t i = 0; i < mNumPlaneBufs; i++) {
2068 rc = unmapBuf(CAM_MAPPING_BUF_TYPE_STREAM_BUF, i, -1, ops_tbl);
2069 if (rc < 0) {
2070 LOGE("map_stream_buf failed: %d", rc);
2071 }
2072 }
2073
2074 // mBufDefs just keep a ptr to the buffer
2075 // mm-camera-interface own the buffer, so no need to free
2076 mPlaneBufDefs = NULL;
2077 memset(&mFrameLenOffset, 0, sizeof(mFrameLenOffset));
2078 mNumPlaneBufs = 0;
2079 }
2080
2081 if (mStreamBufs != NULL) {
2082 mStreamBufs->deallocate();
2083 delete mStreamBufs;
2084 }
2085
2086 mBufDefs = NULL;
2087
2088 if (mStreamBatchBufs != NULL) {
2089 for (uint8_t i = 0; i < mStreamBatchBufs->getCnt(); i++) {
2090 unmapBuf(CAM_MAPPING_BUF_TYPE_STREAM_USER_BUF, i, -1, ops_tbl);
2091 }
2092 mStreamBatchBufs->deallocate();
2093 delete mStreamBatchBufs;
2094 mStreamBatchBufs = NULL;
2095 }
2096 return rc;
2097
2098 }
2099
2100 /*===========================================================================
2101 * FUNCTION : BufAllocRoutine
2102 *
2103 * DESCRIPTION: function to allocate additional stream buffers
2104 *
2105 * PARAMETERS :
2106 * @data : user data ptr
2107 *
2108 * RETURN : none
2109 *==========================================================================*/
BufAllocRoutine(void * data)2110 void *QCameraStream::BufAllocRoutine(void *data)
2111 {
2112 QCameraStream *pme = (QCameraStream *)data;
2113 int32_t rc = NO_ERROR;
2114
2115 LOGH("E");
2116 pme->cond_wait();
2117 if (pme->mNumBufsNeedAlloc > 0) {
2118 uint8_t numBufAlloc = (uint8_t)(pme->mNumBufs - pme->mNumBufsNeedAlloc);
2119 rc = pme->mAllocator.allocateMoreStreamBuf(pme->mStreamBufs,
2120 pme->mFrameLenOffset.frame_len,
2121 pme->mNumBufsNeedAlloc);
2122 if (rc != NO_ERROR) {
2123 LOGE("Failed to allocate buffers");
2124 pme->mNumBufsNeedAlloc = 0;
2125 return NULL;
2126 }
2127
2128 pme->mNumBufsNeedAlloc = 0;
2129 QCameraBufferMaps bufferMaps;
2130 for (uint32_t i = numBufAlloc; i < pme->mNumBufs; i++) {
2131 ssize_t bufSize = pme->mStreamBufs->getSize(i);
2132 if (BAD_INDEX == bufSize) {
2133 LOGE("Failed to retrieve buffer size (bad index)");
2134 return NULL;
2135 }
2136
2137 rc = bufferMaps.enqueue(CAM_MAPPING_BUF_TYPE_STREAM_BUF,
2138 pme->mHandle, i /*buf index*/, -1 /*plane index*/,
2139 0 /*cookie*/, pme->mStreamBufs->getFd(i), bufSize,
2140 pme->mStreamBufs->getPtr(i));
2141
2142 if (rc < 0) {
2143 LOGE("Failed to map buffers");
2144 return NULL;
2145 }
2146 }
2147
2148 cam_buf_map_type_list bufMapList;
2149 rc = bufferMaps.getCamBufMapList(bufMapList);
2150 if (rc == NO_ERROR) {
2151 rc = pme->m_MemOpsTbl.bundled_map_ops(&bufMapList, pme->m_MemOpsTbl.userdata);
2152 }
2153 if (rc != 0) {
2154 LOGE("Failed to map buffers with return code %d", rc);
2155 return NULL;
2156 }
2157
2158 for (uint32_t i = numBufAlloc; i < pme->mNumBufs; i++) {
2159 pme->mStreamBufs->getBufDef(pme->mFrameLenOffset, pme->mBufDefs[i], i);
2160 pme->mCamOps->qbuf(pme->mCamHandle, pme->mChannelHandle,
2161 &pme->mBufDefs[i]);
2162 }
2163 }
2164 LOGH("X");
2165 return NULL;
2166 }
2167
2168 /*===========================================================================
2169 * FUNCTION : cond_signal
2170 *
2171 * DESCRIPTION: signal if flag "wait_for_cond" is set
2172 *
2173 *==========================================================================*/
cond_signal(bool forceExit)2174 void QCameraStream::cond_signal(bool forceExit)
2175 {
2176 pthread_mutex_lock(&m_lock);
2177 if(wait_for_cond == TRUE){
2178 wait_for_cond = FALSE;
2179 if (forceExit) {
2180 mNumBufsNeedAlloc = 0;
2181 }
2182 pthread_cond_signal(&m_cond);
2183 }
2184 pthread_mutex_unlock(&m_lock);
2185 }
2186
2187
2188 /*===========================================================================
2189 * FUNCTION : cond_wait
2190 *
2191 * DESCRIPTION: wait on if flag "wait_for_cond" is set
2192 *
2193 *==========================================================================*/
cond_wait()2194 void QCameraStream::cond_wait()
2195 {
2196 pthread_mutex_lock(&m_lock);
2197 while (wait_for_cond == TRUE) {
2198 pthread_cond_wait(&m_cond, &m_lock);
2199 }
2200 pthread_mutex_unlock(&m_lock);
2201 }
2202
2203 /*===========================================================================
2204 * FUNCTION : putBufs
2205 *
2206 * DESCRIPTION: deallocate stream buffers
2207 *
2208 * PARAMETERS :
2209 * @ops_tbl : ptr to buf mapping/unmapping ops
2210 *
2211 * RETURN : int32_t type of status
2212 * NO_ERROR -- success
2213 * none-zero failure code
2214 *==========================================================================*/
putBufs(mm_camera_map_unmap_ops_tbl_t * ops_tbl)2215 int32_t QCameraStream::putBufs(mm_camera_map_unmap_ops_tbl_t *ops_tbl)
2216 {
2217 int rc = NO_ERROR;
2218
2219 if (mBufAllocPid != 0) {
2220 cond_signal(true);
2221 LOGL("wait for buf allocation thread dead");
2222 pthread_join(mBufAllocPid, NULL);
2223 mBufAllocPid = 0;
2224 LOGL("return from buf allocation thread");
2225 }
2226
2227 uint8_t numBufsToUnmap = mStreamBufs->getMappable();
2228 for (uint32_t i = 0; i < numBufsToUnmap; i++) {
2229 rc = ops_tbl->unmap_ops(i, -1, CAM_MAPPING_BUF_TYPE_STREAM_BUF, ops_tbl->userdata);
2230 if (rc < 0) {
2231 LOGE("map_stream_buf failed: %d", rc);
2232 }
2233 }
2234 mBufDefs = NULL; // mBufDefs just keep a ptr to the buffer
2235 // mm-camera-interface own the buffer, so no need to free
2236 memset(&mFrameLenOffset, 0, sizeof(mFrameLenOffset));
2237 if ( !mStreamBufsAcquired ) {
2238 mStreamBufs->deallocate();
2239 delete mStreamBufs;
2240 mStreamBufs = NULL;
2241 }
2242
2243 return rc;
2244 }
2245
2246 /*===========================================================================
2247 * FUNCTION : putBufsDeffered
2248 *
2249 * DESCRIPTION: function to deallocate deffered stream buffers
2250 *
2251 * PARAMETERS : none
2252 *
2253 * RETURN : int32_t type of status
2254 * NO_ERROR -- success
2255 * none-zero failure code
2256 *==========================================================================*/
putBufsDeffered()2257 int32_t QCameraStream::putBufsDeffered()
2258 {
2259 if (mBufAllocPid != 0) {
2260 cond_signal(true);
2261 LOGH("%s: wait for buf allocation thread dead", __func__);
2262 // Wait for the allocation of additional stream buffers
2263 pthread_join(mBufAllocPid, NULL);
2264 mBufAllocPid = 0;
2265 LOGH("%s: return from buf allocation thread", __func__);
2266 }
2267 // Deallocation of the deffered stream buffers handled separately
2268 return NO_ERROR;
2269 }
2270
2271 /*===========================================================================
2272 * FUNCTION : invalidateBuf
2273 *
2274 * DESCRIPTION: invalidate a specific stream buffer
2275 *
2276 * PARAMETERS :
2277 * @index : index of the buffer to invalidate
2278 *
2279 * RETURN : int32_t type of status
2280 * NO_ERROR -- success
2281 * none-zero failure code
2282 *==========================================================================*/
invalidateBuf(uint32_t index)2283 int32_t QCameraStream::invalidateBuf(uint32_t index)
2284 {
2285 if (mStreamBufs == NULL) {
2286 LOGE("Invalid Operation");
2287 return INVALID_OPERATION;
2288 }
2289 return mStreamBufs->invalidateCache(index);
2290 }
2291
2292 /*===========================================================================
2293 * FUNCTION : cleanInvalidateBuf
2294 *
2295 * DESCRIPTION: clean invalidate a specific stream buffer
2296 *
2297 * PARAMETERS :
2298 * @index : index of the buffer to clean invalidate
2299 *
2300 * RETURN : int32_t type of status
2301 * NO_ERROR -- success
2302 * none-zero failure code
2303 *==========================================================================*/
cleanInvalidateBuf(uint32_t index)2304 int32_t QCameraStream::cleanInvalidateBuf(uint32_t index)
2305 {
2306 if (mStreamBufs == NULL) {
2307 LOGE("Invalid Operation");
2308 return INVALID_OPERATION;
2309 }
2310 return mStreamBufs->cleanInvalidateCache(index);
2311 }
2312
2313 /*===========================================================================
2314 * FUNCTION : cleanBuf
2315 *
2316 * DESCRIPTION: clean a specific stream buffer
2317 *
2318 * PARAMETERS :
2319 * @index : index of the buffer to clean
2320 *
2321 * RETURN : int32_t type of status
2322 * NO_ERROR -- success
2323 * none-zero failure code
2324 *==========================================================================*/
cleanBuf(uint32_t index)2325 int32_t QCameraStream::cleanBuf(uint32_t index)
2326 {
2327 if (mStreamBufs == NULL) {
2328 LOGE("Invalid Operation");
2329 return INVALID_OPERATION;
2330 }
2331 return mStreamBufs->cleanCache(index);
2332 }
2333
2334 /*===========================================================================
2335 * FUNCTION : isTypeOf
2336 *
2337 * DESCRIPTION: helper function to determine if the stream is of the queried type
2338 *
2339 * PARAMETERS :
2340 * @type : stream type as of queried
2341 *
2342 * RETURN : true/false
2343 *==========================================================================*/
isTypeOf(cam_stream_type_t type)2344 bool QCameraStream::isTypeOf(cam_stream_type_t type)
2345 {
2346 if (mStreamInfo != NULL && (mStreamInfo->stream_type == type)) {
2347 return true;
2348 } else {
2349 return false;
2350 }
2351 }
2352
2353 /*===========================================================================
2354 * FUNCTION : isOrignalTypeOf
2355 *
2356 * DESCRIPTION: helper function to determine if the original stream is of the
2357 * queried type if it's reproc stream
2358 *
2359 * PARAMETERS :
2360 * @type : stream type as of queried
2361 *
2362 * RETURN : true/false
2363 *==========================================================================*/
isOrignalTypeOf(cam_stream_type_t type)2364 bool QCameraStream::isOrignalTypeOf(cam_stream_type_t type)
2365 {
2366 if (mStreamInfo != NULL &&
2367 mStreamInfo->stream_type == CAM_STREAM_TYPE_OFFLINE_PROC &&
2368 mStreamInfo->reprocess_config.pp_type == CAM_ONLINE_REPROCESS_TYPE &&
2369 mStreamInfo->reprocess_config.online.input_stream_type == type) {
2370 return true;
2371 } else if (
2372 mStreamInfo != NULL &&
2373 mStreamInfo->stream_type == CAM_STREAM_TYPE_OFFLINE_PROC &&
2374 mStreamInfo->reprocess_config.pp_type == CAM_OFFLINE_REPROCESS_TYPE &&
2375 mStreamInfo->reprocess_config.offline.input_type == type) {
2376 return true;
2377 } else {
2378 return false;
2379 }
2380 }
2381
2382 /*===========================================================================
2383 * FUNCTION : getMyType
2384 *
2385 * DESCRIPTION: return stream type
2386 *
2387 * PARAMETERS : none
2388 *
2389 * RETURN : stream type
2390 *==========================================================================*/
getMyType()2391 cam_stream_type_t QCameraStream::getMyType()
2392 {
2393 if (mStreamInfo != NULL) {
2394 return mStreamInfo->stream_type;
2395 } else {
2396 return CAM_STREAM_TYPE_DEFAULT;
2397 }
2398 }
2399
2400 /*===========================================================================
2401 * FUNCTION : getMyOriginalType
2402 *
2403 * DESCRIPTION: return stream type
2404 *
2405 * PARAMETERS : none
2406 *
2407 * RETURN : stream type
2408 *==========================================================================*/
getMyOriginalType()2409 cam_stream_type_t QCameraStream::getMyOriginalType()
2410 {
2411 if (mStreamInfo != NULL) {
2412 if (mStreamInfo->stream_type == CAM_STREAM_TYPE_OFFLINE_PROC &&
2413 mStreamInfo->reprocess_config.pp_type == CAM_ONLINE_REPROCESS_TYPE) {
2414 return mStreamInfo->reprocess_config.online.input_stream_type;
2415 } else if (mStreamInfo->stream_type == CAM_STREAM_TYPE_OFFLINE_PROC &&
2416 mStreamInfo->reprocess_config.pp_type == CAM_OFFLINE_REPROCESS_TYPE) {
2417 return mStreamInfo->reprocess_config.offline.input_type;
2418 } else {
2419 return mStreamInfo->stream_type;
2420 }
2421 } else {
2422 return CAM_STREAM_TYPE_DEFAULT;
2423 }
2424 }
2425
2426 /*===========================================================================
2427 * FUNCTION : getFrameOffset
2428 *
2429 * DESCRIPTION: query stream buffer frame offset info
2430 *
2431 * PARAMETERS :
2432 * @offset : reference to struct to store the queried frame offset info
2433 *
2434 * RETURN : int32_t type of status
2435 * NO_ERROR -- success
2436 * none-zero failure code
2437 *==========================================================================*/
getFrameOffset(cam_frame_len_offset_t & offset)2438 int32_t QCameraStream::getFrameOffset(cam_frame_len_offset_t &offset)
2439 {
2440 if (NULL == mStreamInfo) {
2441 return NO_INIT;
2442 }
2443
2444 offset = mFrameLenOffset;
2445 if ((ROTATE_90 == mOnlineRotation) || (ROTATE_270 == mOnlineRotation)
2446 || (offset.frame_len == 0) || (offset.num_planes == 0)) {
2447 // Re-calculate frame offset in case of online rotation
2448 cam_stream_info_t streamInfo = *mStreamInfo;
2449 getFrameDimension(streamInfo.dim);
2450 calcOffset(&streamInfo);
2451 offset = streamInfo.buf_planes.plane_info;
2452 }
2453
2454 return 0;
2455 }
2456
2457 /*===========================================================================
2458 * FUNCTION : getCropInfo
2459 *
2460 * DESCRIPTION: query crop info of the stream
2461 *
2462 * PARAMETERS :
2463 * @crop : reference to struct to store the queried crop info
2464 *
2465 * RETURN : int32_t type of status
2466 * NO_ERROR -- success
2467 * none-zero failure code
2468 *==========================================================================*/
getCropInfo(cam_rect_t & crop)2469 int32_t QCameraStream::getCropInfo(cam_rect_t &crop)
2470 {
2471 pthread_mutex_lock(&mCropLock);
2472 crop = mCropInfo;
2473 pthread_mutex_unlock(&mCropLock);
2474 return NO_ERROR;
2475 }
2476
2477 /*===========================================================================
2478 * FUNCTION : setCropInfo
2479 *
2480 * DESCRIPTION: set crop info of the stream
2481 *
2482 * PARAMETERS :
2483 * @crop : struct to store new crop info
2484 *
2485 * RETURN : int32_t type of status
2486 * NO_ERROR -- success
2487 * none-zero failure code
2488 *==========================================================================*/
setCropInfo(cam_rect_t crop)2489 int32_t QCameraStream::setCropInfo(cam_rect_t crop)
2490 {
2491 pthread_mutex_lock(&mCropLock);
2492 mCropInfo = crop;
2493 pthread_mutex_unlock(&mCropLock);
2494 return NO_ERROR;
2495 }
2496
2497 /*===========================================================================
2498 * FUNCTION : getFrameDimension
2499 *
2500 * DESCRIPTION: query stream frame dimension info
2501 *
2502 * PARAMETERS :
2503 * @dim : reference to struct to store the queried frame dimension
2504 *
2505 * RETURN : int32_t type of status
2506 * NO_ERROR -- success
2507 * none-zero failure code
2508 *==========================================================================*/
getFrameDimension(cam_dimension_t & dim)2509 int32_t QCameraStream::getFrameDimension(cam_dimension_t &dim)
2510 {
2511 if (mStreamInfo != NULL) {
2512 if ((ROTATE_90 == mOnlineRotation) || (ROTATE_270 == mOnlineRotation)) {
2513 dim.width = mStreamInfo->dim.height;
2514 dim.height = mStreamInfo->dim.width;
2515 } else {
2516 dim = mStreamInfo->dim;
2517 }
2518 return 0;
2519 }
2520 return -1;
2521 }
2522
2523 /*===========================================================================
2524 * FUNCTION : getFormat
2525 *
2526 * DESCRIPTION: query stream format
2527 *
2528 * PARAMETERS :
2529 * @fmt : reference to stream format
2530 *
2531 * RETURN : int32_t type of status
2532 * NO_ERROR -- success
2533 * none-zero failure code
2534 *==========================================================================*/
getFormat(cam_format_t & fmt)2535 int32_t QCameraStream::getFormat(cam_format_t &fmt)
2536 {
2537 if (mStreamInfo != NULL) {
2538 fmt = mStreamInfo->fmt;
2539 return 0;
2540 }
2541 return -1;
2542 }
2543
2544 /*===========================================================================
2545 * FUNCTION : getMyServerID
2546 *
2547 * DESCRIPTION: query server stream ID
2548 *
2549 * PARAMETERS : None
2550 *
2551 * RETURN : stream ID from server
2552 *==========================================================================*/
getMyServerID()2553 uint32_t QCameraStream::getMyServerID() {
2554 if (mStreamInfo != NULL) {
2555 return mStreamInfo->stream_svr_id;
2556 } else {
2557 return 0;
2558 }
2559 }
2560
2561 /*===========================================================================
2562 * FUNCTION : acquireStreamBufs
2563 *
2564 * DESCRIPTION: acquire stream buffers and postpone their release.
2565 *
2566 * PARAMETERS : None
2567 *
2568 * RETURN : int32_t type of status
2569 * NO_ERROR -- success
2570 * none-zero failure code
2571 *==========================================================================*/
acquireStreamBufs()2572 int32_t QCameraStream::acquireStreamBufs()
2573 {
2574 mStreamBufsAcquired = true;
2575
2576 return NO_ERROR;
2577 }
2578
2579 /*===========================================================================
2580 * FUNCTION : mapBuf
2581 *
2582 * DESCRIPTION: map stream related buffer to backend server
2583 *
2584 * PARAMETERS :
2585 * @buf_type : mapping type of buffer
2586 * @buf_idx : index of buffer
2587 * @plane_idx: plane index
2588 * @fd : fd of the buffer
2589 * @buffer : buffer address
2590 * @size : lenght of the buffer
2591 * @ops_tbl : ptr to buf mapping/unmapping ops
2592 *
2593 * RETURN : int32_t type of status
2594 * NO_ERROR -- success
2595 * none-zero failure code
2596 *==========================================================================*/
mapBuf(uint8_t buf_type,uint32_t buf_idx,int32_t plane_idx,int fd,void * buffer,size_t size,mm_camera_map_unmap_ops_tbl_t * ops_tbl)2597 int32_t QCameraStream::mapBuf(uint8_t buf_type, uint32_t buf_idx,
2598 int32_t plane_idx, int fd, void *buffer, size_t size,
2599 mm_camera_map_unmap_ops_tbl_t *ops_tbl)
2600 {
2601 cam_buf_map_type_list bufMapList;
2602 int32_t rc = QCameraBufferMaps::makeSingletonBufMapList(
2603 (cam_mapping_buf_type)buf_type, mHandle, buf_idx, plane_idx,
2604 0 /*cookie*/, fd, size, bufMapList, buffer);
2605
2606 if (rc != NO_ERROR) {
2607 return rc;
2608 }
2609
2610 return mapBufs(bufMapList, ops_tbl);
2611 }
2612
2613 /*===========================================================================
2614 * FUNCTION : mapBufs
2615 *
2616 * DESCRIPTION: map stream related buffers to backend server
2617 *
2618 * PARAMETERS :
2619 * @bufMapList : buffer mapping information
2620 * @ops_tbl : ptr to buf mapping/unmapping ops
2621 *
2622 * RETURN : int32_t type of status
2623 * NO_ERROR -- success
2624 * none-zero failure code
2625 *==========================================================================*/
2626
mapBufs(cam_buf_map_type_list bufMapList,__unused mm_camera_map_unmap_ops_tbl_t * ops_tbl)2627 int32_t QCameraStream::mapBufs(cam_buf_map_type_list bufMapList,
2628 __unused mm_camera_map_unmap_ops_tbl_t *ops_tbl)
2629 {
2630 if (m_MemOpsTbl.bundled_map_ops != NULL) {
2631 return m_MemOpsTbl.bundled_map_ops(&bufMapList, m_MemOpsTbl.userdata);
2632 } else {
2633 return mCamOps->map_stream_bufs(mCamHandle, mChannelHandle,
2634 &bufMapList);
2635 }
2636
2637 }
2638
2639 /*===========================================================================
2640 * FUNCTION : unmapBuf
2641 *
2642 * DESCRIPTION: unmap stream related buffer to backend server
2643 *
2644 * PARAMETERS :
2645 * @buf_type : mapping type of buffer
2646 * @buf_idx : index of buffer
2647 * @plane_idx: plane index
2648 * @ops_tbl : ptr to buf mapping/unmapping ops
2649 *
2650 * RETURN : int32_t type of status
2651 * NO_ERROR -- success
2652 * none-zero failure code
2653 *==========================================================================*/
unmapBuf(uint8_t buf_type,uint32_t buf_idx,int32_t plane_idx,mm_camera_map_unmap_ops_tbl_t * ops_tbl)2654 int32_t QCameraStream::unmapBuf(uint8_t buf_type, uint32_t buf_idx, int32_t plane_idx,
2655 mm_camera_map_unmap_ops_tbl_t *ops_tbl)
2656 {
2657 if (ops_tbl != NULL) {
2658 return ops_tbl->unmap_ops(buf_idx, plane_idx,
2659 (cam_mapping_buf_type)buf_type, ops_tbl->userdata);
2660 } else {
2661 return mCamOps->unmap_stream_buf(mCamHandle, mChannelHandle,
2662 mHandle, buf_type, buf_idx, plane_idx);
2663 }
2664 }
2665
2666 /*===========================================================================
2667 * FUNCTION : setParameter
2668 *
2669 * DESCRIPTION: set stream based parameters
2670 *
2671 * PARAMETERS :
2672 * @param : ptr to parameters to be set
2673 *
2674 * RETURN : int32_t type of status
2675 * NO_ERROR -- success
2676 * none-zero failure code
2677 *==========================================================================*/
setParameter(cam_stream_parm_buffer_t & param)2678 int32_t QCameraStream::setParameter(cam_stream_parm_buffer_t ¶m)
2679 {
2680 int32_t rc = NO_ERROR;
2681 pthread_mutex_lock(&mParameterLock);
2682 mStreamInfo->parm_buf = param;
2683 rc = mCamOps->set_stream_parms(mCamHandle,
2684 mChannelHandle,
2685 mHandle,
2686 &mStreamInfo->parm_buf);
2687 if (rc == NO_ERROR) {
2688 param = mStreamInfo->parm_buf;
2689 }
2690 pthread_mutex_unlock(&mParameterLock);
2691 return rc;
2692 }
2693
2694 /*===========================================================================
2695 * FUNCTION : getParameter
2696 *
2697 * DESCRIPTION: get stream based parameters
2698 *
2699 * PARAMETERS :
2700 * @param : ptr to parameters to be red
2701 *
2702 * RETURN : int32_t type of status
2703 * NO_ERROR -- success
2704 * none-zero failure code
2705 *==========================================================================*/
getParameter(cam_stream_parm_buffer_t & param)2706 int32_t QCameraStream::getParameter(cam_stream_parm_buffer_t ¶m)
2707 {
2708 int32_t rc = NO_ERROR;
2709 pthread_mutex_lock(&mParameterLock);
2710 mStreamInfo->parm_buf = param;
2711 rc = mCamOps->get_stream_parms(mCamHandle,
2712 mChannelHandle,
2713 mHandle,
2714 &mStreamInfo->parm_buf);
2715 if (rc == NO_ERROR) {
2716 param = mStreamInfo->parm_buf;
2717 }
2718 pthread_mutex_unlock(&mParameterLock);
2719 return rc;
2720 }
2721
2722 /*===========================================================================
2723 * FUNCTION : releaseFrameData
2724 *
2725 * DESCRIPTION: callback function to release frame data node
2726 *
2727 * PARAMETERS :
2728 * @data : ptr to post process input data
2729 * @user_data : user data ptr (QCameraReprocessor)
2730 *
2731 * RETURN : None
2732 *==========================================================================*/
releaseFrameData(void * data,void * user_data)2733 void QCameraStream::releaseFrameData(void *data, void *user_data)
2734 {
2735 QCameraStream *pme = (QCameraStream *)user_data;
2736 mm_camera_super_buf_t *frame = (mm_camera_super_buf_t *)data;
2737 if (NULL != pme) {
2738 pme->bufDone(frame->bufs[0]->buf_idx);
2739 }
2740 }
2741
2742 /*===========================================================================
2743 * FUNCTION : configStream
2744 *
2745 * DESCRIPTION: send stream configuration to back end
2746 *
2747 * PARAMETERS :
2748 *
2749 * RETURN : int32_t type of status
2750 * NO_ERROR -- success
2751 * none-zero failure code
2752 *==========================================================================*/
configStream()2753 int32_t QCameraStream::configStream()
2754 {
2755 int rc = NO_ERROR;
2756
2757 // Configure the stream
2758 mm_camera_stream_config_t stream_config;
2759 stream_config.stream_info = mStreamInfo;
2760 stream_config.mem_vtbl = mMemVtbl;
2761 stream_config.stream_cb_sync = NULL;
2762 stream_config.stream_cb = dataNotifyCB;
2763 stream_config.padding_info = mPaddingInfo;
2764 stream_config.userdata = this;
2765 rc = mCamOps->config_stream(mCamHandle,
2766 mChannelHandle, mHandle, &stream_config);
2767 if (rc < 0) {
2768 LOGE("Failed to config stream, rc = %d", rc);
2769 mCamOps->unmap_stream_buf(mCamHandle,
2770 mChannelHandle,
2771 mHandle,
2772 CAM_MAPPING_BUF_TYPE_STREAM_INFO,
2773 0,
2774 -1);
2775 return UNKNOWN_ERROR;
2776 }
2777
2778 return rc;
2779 }
2780
2781 /*===========================================================================
2782 * FUNCTION : setSyncDataCB
2783 *
2784 * DESCRIPTION: register callback with mm-interface for this stream
2785 *
2786 * PARAMETERS :
2787 @stream_cb : Callback function
2788 *
2789 * RETURN : int32_t type of status
2790 * NO_ERROR -- success
2791 * non-zero failure code
2792 *==========================================================================*/
setSyncDataCB(stream_cb_routine data_cb)2793 int32_t QCameraStream::setSyncDataCB(stream_cb_routine data_cb)
2794 {
2795 int32_t rc = NO_ERROR;
2796
2797 if (mCamOps != NULL) {
2798 mSYNCDataCB = data_cb;
2799 rc = mCamOps->register_stream_buf_cb(mCamHandle,
2800 mChannelHandle, mHandle, dataNotifySYNCCB, MM_CAMERA_STREAM_CB_TYPE_SYNC,
2801 this);
2802 if (rc == NO_ERROR) {
2803 mSyncCBEnabled = TRUE;
2804 return rc;
2805 }
2806 }
2807 LOGE("Interface handle is NULL");
2808 return UNKNOWN_ERROR;
2809 }
2810
2811 /*===========================================================================
2812 * FUNCTION : processCameraControl
2813 *
2814 * DESCRIPTION: Suspend and resume camera
2815 *
2816 * PARAMETERS :
2817 *
2818 * RETURN : int32_t type of status
2819 * NO_ERROR -- success
2820 * none-zero failure code
2821 *==========================================================================*/
processCameraControl(uint32_t camState)2822 int32_t QCameraStream::processCameraControl(uint32_t camState)
2823 {
2824 mActiveCameras = camState;
2825 return NO_ERROR;
2826 }
2827
2828 /*===========================================================================
2829 * FUNCTION : switchStreamCb
2830 *
2831 * DESCRIPTION: switch stream's in case of dual camera
2832 *
2833 * PARAMETERS :
2834 * @camMaster : Master camera
2835 *
2836 * RETURN : int32_t type of status
2837 * NO_ERROR -- success
2838 * none-zero failure code
2839 *==========================================================================*/
switchStreamCb(uint32_t camMaster)2840 int32_t QCameraStream::switchStreamCb(uint32_t camMaster)
2841 {
2842 int32_t ret = NO_ERROR;
2843 if (needCbSwitch() && (camMaster != mMasterCamera)) {
2844 ret = mCamOps->handle_frame_sync_cb(mCamHandle, mChannelHandle,
2845 mHandle, MM_CAMERA_CB_REQ_TYPE_SWITCH);
2846 }
2847 // Update master camera
2848 mMasterCamera = camMaster;
2849 return ret;
2850 }
2851
2852 /*===========================================================================
2853 * FUNCTION : needCbSwitch
2854 *
2855 * DESCRIPTION: Function to enable callback switch based on availability of
2856 * spatial alignment
2857 *
2858 * PARAMETERS :
2859 *
2860 * RETURN : int32_t type of status
2861 * NO_ERROR -- success
2862 * none-zero failure code
2863 *==========================================================================*/
needCbSwitch()2864 bool QCameraStream::needCbSwitch()
2865 {
2866 if (!isDualStream()) {
2867 return false;
2868 }
2869
2870 if ((mStreamInfo->pp_config.feature_mask & CAM_QTI_FEATURE_SAT)
2871 || (mStreamInfo->pp_config.feature_mask & CAM_QTI_FEATURE_SAC)
2872 || (needFrameSync())
2873 || (getMyType() == CAM_STREAM_TYPE_SNAPSHOT)
2874 || (getMyType() == CAM_STREAM_TYPE_METADATA)) {
2875 return false;
2876 } else {
2877 return true;
2878 }
2879 }
2880
2881 /*===========================================================================
2882 * FUNCTION : needFrameSync
2883 *
2884 * DESCRIPTION: Function to enable stream frame buffer sync
2885 *
2886 * PARAMETERS :
2887 *
2888 * RETURN : int32_t type of status
2889 * NO_ERROR -- success
2890 * none-zero failure code
2891 *==========================================================================*/
needFrameSync()2892 bool QCameraStream::needFrameSync()
2893 {
2894 if (!isDualStream()) {
2895 return false;
2896 }
2897
2898 switch (getMyType()) {
2899 default:
2900 return false;
2901 break;
2902 }
2903 }
2904
2905 /*===========================================================================
2906 * FUNCTION : setBundleInfo
2907 *
2908 * DESCRIPTION: set bundle for this stream to MCT
2909 *
2910 * PARAMETERS :
2911 *
2912 * RETURN : int32_t type of status
2913 * NO_ERROR -- success
2914 * none-zero failure code
2915 *==========================================================================*/
setBundleInfo()2916 int32_t QCameraStream::setBundleInfo()
2917 {
2918 int32_t ret = NO_ERROR;
2919 cam_bundle_config_t bundleInfo;
2920
2921 if ((isTypeOf(CAM_STREAM_TYPE_METADATA))
2922 || (isTypeOf(CAM_STREAM_TYPE_OFFLINE_PROC))) {
2923 // Skip metadata for reprocess now because PP module cannot handle meta data
2924 // May need furthur discussion if Imaginglib need meta data
2925 return ret;
2926 }
2927
2928 cam_stream_parm_buffer_t param, aux_param;
2929 uint32_t active_handle = get_main_camera_handle(mChannelHandle);
2930 memset(&bundleInfo, 0, sizeof(bundleInfo));
2931 if (active_handle) {
2932 ret = mCamOps->get_bundle_info(mCamHandle, active_handle,
2933 &bundleInfo);
2934 memset(¶m, 0, sizeof(cam_stream_parm_buffer_t));
2935 param.type = CAM_STREAM_PARAM_TYPE_SET_BUNDLE_INFO;
2936 param.bundleInfo = bundleInfo;
2937 }
2938
2939 memset(&aux_param, 0, sizeof(cam_stream_parm_buffer_t));
2940 if (isDualStream()) {
2941 active_handle = get_aux_camera_handle(mChannelHandle);
2942 memset(&bundleInfo, 0, sizeof(bundleInfo));
2943 ret = mCamOps->get_bundle_info(mCamHandle, active_handle,
2944 &bundleInfo);
2945 aux_param.type = CAM_STREAM_PARAM_TYPE_SET_BUNDLE_INFO;
2946 aux_param.bundleInfo = bundleInfo;
2947 }
2948 pthread_mutex_lock(&mParameterLock);
2949 mStreamInfo->parm_buf = param;
2950 if ((aux_param.bundleInfo.num_of_streams > 1)
2951 && (mStreamInfo->aux_str_info != NULL)) {
2952 mStreamInfo->aux_str_info->parm_buf = aux_param;
2953 }
2954
2955 if ((mStreamInfo->parm_buf.bundleInfo.num_of_streams > 1)
2956 || (((mStreamInfo->aux_str_info != NULL) &&
2957 (mStreamInfo->aux_str_info->parm_buf.bundleInfo.num_of_streams > 1)))) {
2958 ret = mCamOps->set_stream_parms(mCamHandle,
2959 mChannelHandle, mHandle,
2960 &mStreamInfo->parm_buf);
2961 }
2962 pthread_mutex_unlock(&mParameterLock);
2963 if (ret != NO_ERROR) {
2964 LOGE("stream setParameter for set bundle failed");
2965 return ret;
2966 }
2967 return ret;
2968 }
2969
2970 /*===========================================================================
2971 * FUNCTION : handleCacheOps
2972 *
2973 * DESCRIPTION: handle cache ops for this stream buffer
2974 *
2975 * PARAMETERS :
2976 @buf : stream buffer
2977 *
2978 * RETURN : int32_t type of status
2979 * NO_ERROR -- success
2980 * non-zero failure code
2981 *==========================================================================*/
handleCacheOps(mm_camera_buf_def_t * buf)2982 int32_t QCameraStream::handleCacheOps(mm_camera_buf_def_t* buf)
2983 {
2984 int32_t rc = 0;
2985 if( !buf) {
2986 LOGE("Error!! buf_info: %p", buf);
2987 rc = -1;
2988 return rc;
2989 }
2990 if ((mMemVtbl.clean_invalidate_buf == NULL) ||
2991 (mMemVtbl.invalidate_buf == NULL) ||
2992 (mMemVtbl.clean_buf == NULL)) {
2993 LOGI("Clean/Invalidate cache ops not supported");
2994 rc = -1;
2995 return rc;
2996 }
2997
2998 LOGH("[CACHE_OPS] Stream type: %d buf index: %d cache ops flags: 0x%x",
2999 buf->stream_type, buf->buf_idx, buf->cache_flags);
3000
3001 if ((buf->cache_flags & CPU_HAS_READ_WRITTEN) ==
3002 CPU_HAS_READ_WRITTEN) {
3003 rc = mMemVtbl.clean_invalidate_buf(
3004 buf->buf_idx, mMemVtbl.user_data);
3005 } else if ((buf->cache_flags & CPU_HAS_READ) ==
3006 CPU_HAS_READ) {
3007 rc = mMemVtbl.invalidate_buf(
3008 buf->buf_idx, mMemVtbl.user_data);
3009 } else if ((buf->cache_flags & CPU_HAS_WRITTEN) ==
3010 CPU_HAS_WRITTEN) {
3011 rc = mMemVtbl.clean_buf(
3012 buf->buf_idx, mMemVtbl.user_data);
3013 }
3014 if (rc != 0) {
3015 LOGW("Warning!! Clean/Invalidate cache failed on buffer index: %d",
3016 buf->buf_idx);
3017 }
3018 // Reset buffer cache flags after cache ops
3019 buf->cache_flags = 0;
3020 return rc;
3021 }
3022
3023
3024 }; // namespace qcamera
3025