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