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