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