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, Buf->getPtr(i));
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 mStreamBufs->getPtr(i));
1308
1309 if (rc < 0) {
1310 LOGE("Failed to map buffers");
1311 return BAD_INDEX;
1312 }
1313 }
1314
1315 cam_buf_map_type_list bufMapList;
1316 rc = bufferMaps.getCamBufMapList(bufMapList);
1317 if (rc == NO_ERROR) {
1318 rc = ops_tbl->bundled_map_ops(&bufMapList, ops_tbl->userdata);
1319 }
1320 if (rc < 0) {
1321 LOGE("map_stream_buf failed: %d", rc);
1322 mStreamBufs->deallocate();
1323 delete mStreamBufs;
1324 mStreamBufs = NULL;
1325 return INVALID_OPERATION;
1326 }
1327
1328 //regFlags array is allocated by us, but consumed and freed by mm-camera-interface
1329 regFlags = (uint8_t *)malloc(sizeof(uint8_t) * mNumBufs);
1330 if (!regFlags) {
1331 LOGE("Out of memory");
1332 for (uint32_t i = 0; i < numBufsToMap; i++) {
1333 ops_tbl->unmap_ops(i, -1, CAM_MAPPING_BUF_TYPE_STREAM_BUF, ops_tbl->userdata);
1334 }
1335 mStreamBufs->deallocate();
1336 delete mStreamBufs;
1337 mStreamBufs = NULL;
1338 return NO_MEMORY;
1339 }
1340 memset(regFlags, 0, sizeof(uint8_t) * mNumBufs);
1341
1342 mBufDefs = (mm_camera_buf_def_t *)malloc(mNumBufs * sizeof(mm_camera_buf_def_t));
1343 if (mBufDefs == NULL) {
1344 LOGE("getRegFlags failed %d", rc);
1345 for (uint32_t i = 0; i < numBufsToMap; i++) {
1346 ops_tbl->unmap_ops(i, -1, CAM_MAPPING_BUF_TYPE_STREAM_BUF, ops_tbl->userdata);
1347 }
1348 mStreamBufs->deallocate();
1349 delete mStreamBufs;
1350 mStreamBufs = NULL;
1351 free(regFlags);
1352 regFlags = NULL;
1353 return INVALID_OPERATION;
1354 }
1355 memset(mBufDefs, 0, mNumBufs * sizeof(mm_camera_buf_def_t));
1356 for (uint32_t i = 0; i < numBufsToMap; i++) {
1357 mStreamBufs->getBufDef(mFrameLenOffset, mBufDefs[i], i);
1358 }
1359
1360 rc = mStreamBufs->getRegFlags(regFlags);
1361 if (rc < 0) {
1362 LOGE("getRegFlags failed %d", rc);
1363 for (uint32_t i = 0; i < numBufsToMap; i++) {
1364 ops_tbl->unmap_ops(i, -1, CAM_MAPPING_BUF_TYPE_STREAM_BUF, ops_tbl->userdata);
1365 }
1366 mStreamBufs->deallocate();
1367 delete mStreamBufs;
1368 mStreamBufs = NULL;
1369 free(mBufDefs);
1370 mBufDefs = NULL;
1371 free(regFlags);
1372 regFlags = NULL;
1373 return INVALID_OPERATION;
1374 }
1375
1376 *num_bufs = mNumBufs;
1377 *initial_reg_flag = regFlags;
1378 *bufs = mBufDefs;
1379 LOGH("stream type: %d, mRegFlags: %p, numBufs: %d",
1380 mStreamInfo->stream_type, regFlags, mNumBufs);
1381
1382 if (mNumBufsNeedAlloc > 0) {
1383 pthread_mutex_lock(&m_lock);
1384 wait_for_cond = TRUE;
1385 pthread_mutex_unlock(&m_lock);
1386 LOGH("Still need to allocate %d buffers",
1387 mNumBufsNeedAlloc);
1388 // start another thread to allocate the rest of buffers
1389 pthread_create(&mBufAllocPid,
1390 NULL,
1391 BufAllocRoutine,
1392 this);
1393 pthread_setname_np(mBufAllocPid, "CAM_strmBuf");
1394 }
1395
1396 return NO_ERROR;
1397 }
1398
1399 /*===========================================================================
1400 * FUNCTION : getBufsDeferred
1401 *
1402 * DESCRIPTION: allocate deferred stream buffers
1403 *
1404 * PARAMETERS :
1405 * @offset : offset info of stream buffers
1406 * @num_bufs : number of buffers allocated
1407 * @initial_reg_flag: flag to indicate if buffer needs to be registered
1408 * at kernel initially
1409 * @bufs : output of allocated buffers
1410 * @ops_tbl : ptr to buf mapping/unmapping ops
1411 *
1412 * RETURN : int32_t type of status
1413 * NO_ERROR -- success
1414 * none-zero failure code
1415 *==========================================================================*/
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)1416 int32_t QCameraStream::getBufsDeferred(__unused cam_frame_len_offset_t *offset,
1417 uint8_t *num_bufs,
1418 uint8_t **initial_reg_flag,
1419 mm_camera_buf_def_t **bufs,
1420 __unused mm_camera_map_unmap_ops_tbl_t *ops_tbl)
1421 {
1422 int32_t rc = NO_ERROR;
1423 // wait for allocation
1424 rc = mAllocator.waitForBackgroundTask(mAllocTaskId);
1425 if (rc != NO_ERROR) {
1426 LOGE("Allocation Failed");
1427 return NO_MEMORY;
1428 }
1429
1430 if (!mRegFlags || !mBufDefs) {
1431 LOGE("reg flags or buf defs uninitialized");
1432 return NO_MEMORY;
1433 }
1434
1435 *initial_reg_flag = mRegFlags;
1436 *num_bufs = mNumBufs;
1437 *bufs = mBufDefs;
1438
1439 LOGH("stream type: %d, mRegFlags: 0x%x, numBufs: %d",
1440 getMyType(), mRegFlags, mNumBufs);
1441
1442 return NO_ERROR;
1443 }
1444 /*===========================================================================
1445 * FUNCTION : mapNewBuffer
1446 *
1447 * DESCRIPTION: map a new stream buffer
1448 *
1449 * PARAMETERS :
1450 *
1451 * RETURN : int32_t type of status
1452 * NO_ERROR -- success
1453 * none-zero failure code
1454 *==========================================================================*/
mapNewBuffer(uint32_t index)1455 int32_t QCameraStream::mapNewBuffer(uint32_t index)
1456 {
1457 LOGH("E - index = %d", index);
1458
1459 int rc = NO_ERROR;
1460
1461 if (mStreamBufs == NULL) {
1462 LOGE("Invalid Operation");
1463 return INVALID_OPERATION;
1464 }
1465
1466 ssize_t bufSize = mStreamBufs->getSize(index);
1467 if (BAD_INDEX == bufSize) {
1468 LOGE("Failed to retrieve buffer size (bad index)");
1469 return INVALID_OPERATION;
1470 }
1471
1472 cam_buf_map_type_list bufMapList;
1473 rc = QCameraBufferMaps::makeSingletonBufMapList(
1474 CAM_MAPPING_BUF_TYPE_STREAM_BUF, 0 /*stream id*/, index,
1475 -1 /*plane index*/, 0 /*cookie*/, mStreamBufs->getFd(index),
1476 bufSize, bufMapList, mStreamBufs->getPtr(index));
1477
1478 if (rc == NO_ERROR) {
1479 rc = m_MemOpsTbl.bundled_map_ops(&bufMapList, m_MemOpsTbl.userdata);
1480 }
1481 if (rc < 0) {
1482 LOGE("map_stream_buf failed: %d", rc);
1483 rc = INVALID_OPERATION;
1484 } else {
1485 mStreamBufs->getBufDef(mFrameLenOffset, mBufDefs[index], index);
1486 }
1487
1488 LOGH("X - rc = %d", rc);
1489 return rc;
1490 }
1491
1492 /*===========================================================================
1493 * FUNCTION : allocateBuffers
1494 *
1495 * DESCRIPTION: allocate stream buffers
1496 *
1497 * PARAMETERS :
1498 *
1499 * RETURN : int32_t type of status
1500 * NO_ERROR -- success
1501 * none-zero failure code
1502 *==========================================================================*/
allocateBuffers()1503 int32_t QCameraStream::allocateBuffers()
1504 {
1505 int32_t rc = NO_ERROR;
1506
1507 mFrameLenOffset = mStreamInfo->buf_planes.plane_info;
1508
1509 if (mStreamInfo->streaming_mode == CAM_STREAMING_MODE_BATCH) {
1510 return allocateBatchBufs(&mFrameLenOffset,
1511 &mNumBufs, &mRegFlags,
1512 &mBufDefs, NULL);
1513 }
1514
1515 /* This allocation is running in the deferred context, so it
1516 * is safe (and necessary) to assume any preemptive allocation
1517 * is already complete. Therefore, no need to wait here. */
1518
1519 uint8_t numBufAlloc = mNumBufs;
1520 mNumBufsNeedAlloc = 0;
1521 if (mDynBufAlloc) {
1522 numBufAlloc = CAMERA_MIN_ALLOCATED_BUFFERS;
1523 if (numBufAlloc > mNumBufs) {
1524 mDynBufAlloc = false;
1525 numBufAlloc = mNumBufs;
1526 } else {
1527 mNumBufsNeedAlloc = (uint8_t)(mNumBufs - numBufAlloc);
1528 }
1529 }
1530
1531 //Allocate and map stream info buffer
1532 mStreamBufs = mAllocator.allocateStreamBuf(mStreamInfo->stream_type,
1533 mFrameLenOffset.frame_len,
1534 mFrameLenOffset.mp[0].stride,
1535 mFrameLenOffset.mp[0].scanline,
1536 numBufAlloc);
1537
1538 if (!mStreamBufs) {
1539 LOGE("Failed to allocate stream buffers");
1540 return NO_MEMORY;
1541 }
1542
1543 mNumBufs = (uint8_t)(numBufAlloc + mNumBufsNeedAlloc);
1544 uint8_t numBufsToMap = mStreamBufs->getMappable();
1545
1546 //regFlags array is allocated by us,
1547 // but consumed and freed by mm-camera-interface
1548 mRegFlags = (uint8_t *)malloc(sizeof(uint8_t) * mNumBufs);
1549 if (!mRegFlags) {
1550 LOGE("Out of memory");
1551 for (uint32_t i = 0; i < numBufsToMap; i++) {
1552 unmapBuf(CAM_MAPPING_BUF_TYPE_STREAM_BUF, i, -1, NULL);
1553 }
1554 mStreamBufs->deallocate();
1555 delete mStreamBufs;
1556 mStreamBufs = NULL;
1557 return NO_MEMORY;
1558 }
1559 memset(mRegFlags, 0, sizeof(uint8_t) * mNumBufs);
1560
1561 size_t bufDefsSize = mNumBufs * sizeof(mm_camera_buf_def_t);
1562 mBufDefs = (mm_camera_buf_def_t *)malloc(bufDefsSize);
1563 if (mBufDefs == NULL) {
1564 LOGE("getRegFlags failed %d", rc);
1565 for (uint32_t i = 0; i < numBufsToMap; i++) {
1566 unmapBuf(CAM_MAPPING_BUF_TYPE_STREAM_BUF, i, -1, NULL);
1567 }
1568 mStreamBufs->deallocate();
1569 delete mStreamBufs;
1570 mStreamBufs = NULL;
1571 free(mRegFlags);
1572 mRegFlags = NULL;
1573 return INVALID_OPERATION;
1574 }
1575 memset(mBufDefs, 0, bufDefsSize);
1576 for (uint32_t i = 0; i < numBufsToMap; i++) {
1577 mStreamBufs->getBufDef(mFrameLenOffset, mBufDefs[i], i);
1578 }
1579
1580 rc = mStreamBufs->getRegFlags(mRegFlags);
1581 if (rc < 0) {
1582 LOGE("getRegFlags failed %d", rc);
1583 for (uint32_t i = 0; i < numBufsToMap; i++) {
1584 unmapBuf(CAM_MAPPING_BUF_TYPE_STREAM_BUF, i, -1, NULL);
1585 }
1586 mStreamBufs->deallocate();
1587 delete mStreamBufs;
1588 mStreamBufs = NULL;
1589 free(mBufDefs);
1590 mBufDefs = NULL;
1591 free(mRegFlags);
1592 mRegFlags = NULL;
1593 return INVALID_OPERATION;
1594 }
1595
1596 if (mNumBufsNeedAlloc > 0) {
1597 pthread_mutex_lock(&m_lock);
1598 wait_for_cond = TRUE;
1599 pthread_mutex_unlock(&m_lock);
1600 LOGH("Still need to allocate %d buffers",
1601 mNumBufsNeedAlloc);
1602 // start another thread to allocate the rest of buffers
1603 pthread_create(&mBufAllocPid,
1604 NULL,
1605 BufAllocRoutine,
1606 this);
1607 pthread_setname_np(mBufAllocPid, "CAM_strmBufAlloc");
1608 }
1609 return rc;
1610 }
1611
1612 /*===========================================================================
1613 * FUNCTION : mapBuffers
1614 *
1615 * DESCRIPTION: map stream buffers
1616 *
1617 * PARAMETERS :
1618 *
1619 * RETURN : int32_t type of status
1620 * NO_ERROR -- success
1621 * none-zero failure code
1622 *==========================================================================*/
mapBuffers()1623 int32_t QCameraStream::mapBuffers()
1624 {
1625 int32_t rc = NO_ERROR;
1626 QCameraBufferMaps bufferMaps;
1627
1628 rc = mAllocator.waitForBackgroundTask(mAllocTaskId);
1629 if (rc != NO_ERROR) {
1630 LOGE("Allocation Failed");
1631 return NO_MEMORY;
1632 }
1633
1634 if (mStreamBufs == NULL) {
1635 LOGE("Stream buffers not allocated");
1636 return UNKNOWN_ERROR;
1637 }
1638
1639 uint8_t numBufsToMap = mStreamBufs->getMappable();
1640 for (uint32_t i = 0; i < numBufsToMap; i++) {
1641 ssize_t bufSize = mStreamBufs->getSize(i);
1642 if (BAD_INDEX != bufSize) {
1643 rc = bufferMaps.enqueue(CAM_MAPPING_BUF_TYPE_STREAM_BUF, mHandle,
1644 i /*buf index*/, -1 /*plane index*/, 0 /*cookie*/,
1645 mStreamBufs->getFd(i), bufSize,
1646 mStreamBufs->getPtr(i));
1647
1648 if (rc < 0) {
1649 LOGE("Failed to map buffers");
1650 rc = BAD_INDEX;
1651 break;
1652 }
1653 } else {
1654 LOGE("Bad index %u", i);
1655 rc = BAD_INDEX;
1656 break;
1657 }
1658 }
1659
1660 cam_buf_map_type_list bufMapList;
1661 if (rc == NO_ERROR) {
1662 rc = bufferMaps.getCamBufMapList(bufMapList);
1663 }
1664 if (rc == NO_ERROR) {
1665 rc = mapBufs(bufMapList, NULL);
1666 }
1667 return rc;
1668 }
1669
1670 /*===========================================================================
1671 * FUNCTION : allocateBatchBufs
1672 *
1673 * DESCRIPTION: allocate stream batch buffers and stream buffers
1674 *
1675 * PARAMETERS :
1676 * @offset : offset info of stream buffers
1677 * @num_bufs : number of buffers allocated
1678 * @initial_reg_flag: flag to indicate if buffer needs to be registered
1679 * at kernel initially
1680 * @bufs : output of allocated buffers
1681 * @plane_bufs : output of allocated plane buffers
1682 * @ops_tbl : ptr to buf mapping/unmapping ops
1683 *
1684 * RETURN : int32_t type of status
1685 * NO_ERROR -- success
1686 * none-zero failure code
1687 *==========================================================================*/
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)1688 int32_t QCameraStream::allocateBatchBufs(cam_frame_len_offset_t *offset,
1689 uint8_t *num_bufs, uint8_t **initial_reg_flag,
1690 mm_camera_buf_def_t **bufs, mm_camera_map_unmap_ops_tbl_t *ops_tbl)
1691 {
1692 int rc = NO_ERROR;
1693 uint8_t *regFlags;
1694 QCameraBufferMaps bufferMaps;
1695 QCameraBufferMaps planeBufferMaps;
1696
1697 mFrameLenOffset = *offset;
1698
1699 LOGH("Batch Buffer allocation stream type = %d", getMyType());
1700
1701 //Allocate stream batch buffer
1702 mStreamBatchBufs = mAllocator.allocateStreamUserBuf (mStreamInfo);
1703 if (!mStreamBatchBufs) {
1704 LOGE("Failed to allocate stream batch buffers");
1705 return NO_MEMORY;
1706 }
1707
1708 uint8_t numBufsToMap = mStreamBatchBufs->getMappable();
1709
1710 //map batch buffers
1711 for (uint32_t i = 0; i < numBufsToMap; i++) {
1712 rc = bufferMaps.enqueue(CAM_MAPPING_BUF_TYPE_STREAM_USER_BUF,
1713 0 /*stream id*/, i /*buf index*/, -1 /*plane index*/,
1714 0 /*cookie*/, mStreamBatchBufs->getFd(i),
1715 mNumBufs, mStreamBatchBufs->getPtr(i));
1716
1717 if (rc < 0) {
1718 LOGE("Failed to map buffers");
1719 rc = BAD_INDEX;
1720 break;
1721 }
1722 }
1723
1724 cam_buf_map_type_list bufMapList;
1725 if (rc == NO_ERROR) {
1726 rc = bufferMaps.getCamBufMapList(bufMapList);
1727 }
1728 if (rc == NO_ERROR) {
1729 rc = mapBufs(bufMapList, ops_tbl);
1730 }
1731 if (rc < 0) {
1732 LOGE("Failed to map stream batch buffers");
1733 mStreamBatchBufs->deallocate();
1734 delete mStreamBatchBufs;
1735 mStreamBatchBufs = NULL;
1736 return NO_MEMORY;
1737 }
1738
1739 /*calculate stream Buffer count*/
1740 mNumPlaneBufs =
1741 (mNumBufs * mStreamInfo->user_buf_info.frame_buf_cnt);
1742
1743 /* For some stream types, buffer allocation may have already begun
1744 * preemptively. If this is the case, we need to wait for the
1745 * preemptive allocation to complete before proceeding. */
1746 mAllocator.waitForDeferredAlloc(mStreamInfo->stream_type);
1747
1748 //Allocate stream buffer
1749 mStreamBufs = mAllocator.allocateStreamBuf(mStreamInfo->stream_type,
1750 mFrameLenOffset.frame_len,mFrameLenOffset.mp[0].stride,
1751 mFrameLenOffset.mp[0].scanline,mNumPlaneBufs);
1752 if (!mStreamBufs) {
1753 LOGE("Failed to allocate stream buffers");
1754 rc = NO_MEMORY;
1755 goto err1;
1756 }
1757
1758 //Map plane stream buffers
1759 for (uint32_t i = 0; i < mNumPlaneBufs; i++) {
1760 ssize_t bufSize = mStreamBufs->getSize(i);
1761 if (BAD_INDEX != bufSize) {
1762 rc = planeBufferMaps.enqueue(CAM_MAPPING_BUF_TYPE_STREAM_BUF,
1763 0 /*stream id*/, i /*buf index*/, -1 /*plane index*/,
1764 0 /*cookie*/, mStreamBufs->getFd(i), bufSize,
1765 mStreamBufs->getPtr(i));
1766
1767 if (rc < 0) {
1768 LOGE("Failed to map buffers");
1769 mStreamBufs->deallocate();
1770 delete mStreamBufs;
1771 mStreamBufs = NULL;
1772 rc = INVALID_OPERATION;
1773 goto err1;
1774 }
1775 } else {
1776 LOGE("Failed to retrieve buffer size (bad index)");
1777 mStreamBufs->deallocate();
1778 delete mStreamBufs;
1779 mStreamBufs = NULL;
1780 rc = INVALID_OPERATION;
1781 goto err1;
1782 }
1783 }
1784
1785 cam_buf_map_type_list planeBufMapList;
1786 rc = planeBufferMaps.getCamBufMapList(planeBufMapList);
1787 if (rc == NO_ERROR) {
1788 rc = mapBufs(planeBufMapList, ops_tbl);
1789 }
1790
1791 if (rc < 0) {
1792 LOGE("map_stream_buf failed: %d", rc);
1793 mStreamBufs->deallocate();
1794 delete mStreamBufs;
1795 mStreamBufs = NULL;
1796 rc = INVALID_OPERATION;
1797 goto err1;
1798 }
1799
1800 LOGD("BATCH Buf Count = %d, Plane Buf Cnt = %d",
1801 mNumBufs, mNumPlaneBufs);
1802
1803 //regFlags array is allocated by us, but consumed and freed by mm-camera-interface
1804 regFlags = (uint8_t *)malloc(sizeof(uint8_t) * mNumBufs);
1805 if (!regFlags) {
1806 LOGE("Out of memory");
1807 for (uint32_t i = 0; i < mNumPlaneBufs; i++) {
1808 unmapBuf(CAM_MAPPING_BUF_TYPE_STREAM_BUF, i, -1, ops_tbl);
1809 }
1810 mStreamBufs->deallocate();
1811 delete mStreamBufs;
1812 mStreamBufs = NULL;
1813 rc = NO_MEMORY;
1814 goto err1;
1815 }
1816 memset(regFlags, 0, sizeof(uint8_t) * mNumBufs);
1817 for (uint32_t i = 0; i < mNumBufs; i++) {
1818 regFlags[i] = 1;
1819 }
1820
1821 mBufDefs = (mm_camera_buf_def_t *)malloc(mNumBufs * sizeof(mm_camera_buf_def_t));
1822 if (mBufDefs == NULL) {
1823 LOGE("getRegFlags failed %d", rc);
1824 for (uint32_t i = 0; i < mNumPlaneBufs; i++) {
1825 unmapBuf(CAM_MAPPING_BUF_TYPE_STREAM_BUF, i, -1, ops_tbl);
1826 }
1827 mStreamBufs->deallocate();
1828 delete mStreamBufs;
1829 mStreamBufs = NULL;
1830 free(regFlags);
1831 regFlags = NULL;
1832 rc = INVALID_OPERATION;
1833 goto err1;
1834 }
1835 memset(mBufDefs, 0, mNumBufs * sizeof(mm_camera_buf_def_t));
1836
1837 mPlaneBufDefs = (mm_camera_buf_def_t *)
1838 malloc(mNumPlaneBufs * (sizeof(mm_camera_buf_def_t)));
1839 if (mPlaneBufDefs == NULL) {
1840 LOGE("No Memory");
1841 free(regFlags);
1842 regFlags = NULL;
1843 free(mBufDefs);
1844 mBufDefs = NULL;
1845 for (uint32_t i = 0; i < mNumPlaneBufs; i++) {
1846 unmapBuf(CAM_MAPPING_BUF_TYPE_STREAM_BUF, i, -1, ops_tbl);
1847 }
1848 mStreamBufs->deallocate();
1849 delete mStreamBufs;
1850 mStreamBufs = NULL;
1851 free(regFlags);
1852 regFlags = NULL;
1853 rc = INVALID_OPERATION;
1854 goto err1;
1855 }
1856 memset(mPlaneBufDefs, 0,
1857 mNumPlaneBufs * (sizeof(mm_camera_buf_def_t)));
1858
1859 for (uint32_t i = 0; i < mStreamInfo->num_bufs; i++) {
1860 mStreamBatchBufs->getUserBufDef(mStreamInfo->user_buf_info,
1861 mBufDefs[i], i, mFrameLenOffset, mPlaneBufDefs,
1862 mStreamBufs);
1863 }
1864
1865 *num_bufs = mNumBufs;
1866 *initial_reg_flag = regFlags;
1867 *bufs = mBufDefs;
1868 LOGH("stream type: %d, numBufs: %d mNumPlaneBufs: %d",
1869 mStreamInfo->stream_type, mNumBufs, mNumPlaneBufs);
1870
1871 return NO_ERROR;
1872
1873 err1:
1874 mStreamBatchBufs->deallocate();
1875 delete mStreamBatchBufs;
1876 mStreamBatchBufs = NULL;
1877 return rc;
1878 }
1879
1880
1881 /*===========================================================================
1882 * FUNCTION : releaseBuffs
1883 *
1884 * DESCRIPTION: method to deallocate stream buffers
1885 *
1886 * PARAMETERS :
1887 *
1888 * RETURN : int32_t type of status
1889 * NO_ERROR -- success
1890 * none-zero failure code
1891 *==========================================================================*/
releaseBuffs()1892 int32_t QCameraStream::releaseBuffs()
1893 {
1894 int rc = NO_ERROR;
1895
1896 if (mStreamInfo->streaming_mode == CAM_STREAMING_MODE_BATCH) {
1897 return releaseBatchBufs(NULL);
1898 }
1899
1900 if ((NULL != mBufDefs) && (mStreamBufs != NULL)) {
1901 uint8_t numBufsToUnmap = mStreamBufs->getMappable();
1902 for (uint32_t i = 0; i < numBufsToUnmap; i++) {
1903 rc = unmapBuf(CAM_MAPPING_BUF_TYPE_STREAM_BUF, i, -1, NULL);
1904 if (rc < 0) {
1905 LOGE("map_stream_buf failed: %d", rc);
1906 }
1907 }
1908
1909 // mBufDefs just keep a ptr to the buffer
1910 // mm-camera-interface own the buffer, so no need to free
1911 mBufDefs = NULL;
1912 memset(&mFrameLenOffset, 0, sizeof(mFrameLenOffset));
1913 }
1914 if (!mStreamBufsAcquired && (mStreamBufs != NULL)) {
1915 mStreamBufs->deallocate();
1916 delete mStreamBufs;
1917 mStreamBufs = NULL;
1918 }
1919 return rc;
1920 }
1921
1922 /*===========================================================================
1923 * FUNCTION : releaseBatchBufs
1924 *
1925 * DESCRIPTION: method to deallocate stream buffers and batch buffers
1926 *
1927 * PARAMETERS :
1928 * @ops_tbl : ptr to buf mapping/unmapping ops
1929 *
1930 * RETURN : int32_t type of status
1931 * NO_ERROR -- success
1932 * none-zero failure code
1933
1934 *==========================================================================*/
releaseBatchBufs(mm_camera_map_unmap_ops_tbl_t * ops_tbl)1935 int32_t QCameraStream::releaseBatchBufs(mm_camera_map_unmap_ops_tbl_t *ops_tbl)
1936 {
1937 int rc = NO_ERROR;
1938
1939 if (NULL != mPlaneBufDefs) {
1940 for (uint32_t i = 0; i < mNumPlaneBufs; i++) {
1941 rc = unmapBuf(CAM_MAPPING_BUF_TYPE_STREAM_BUF, i, -1, ops_tbl);
1942 if (rc < 0) {
1943 LOGE("map_stream_buf failed: %d", rc);
1944 }
1945 }
1946
1947 // mBufDefs just keep a ptr to the buffer
1948 // mm-camera-interface own the buffer, so no need to free
1949 mPlaneBufDefs = NULL;
1950 memset(&mFrameLenOffset, 0, sizeof(mFrameLenOffset));
1951 mNumPlaneBufs = 0;
1952 }
1953
1954 if (mStreamBufs != NULL) {
1955 mStreamBufs->deallocate();
1956 delete mStreamBufs;
1957 }
1958
1959 mBufDefs = NULL;
1960
1961 if (mStreamBatchBufs != NULL) {
1962 for (uint8_t i = 0; i < mStreamBatchBufs->getCnt(); i++) {
1963 unmapBuf(CAM_MAPPING_BUF_TYPE_STREAM_USER_BUF, i, -1, ops_tbl);
1964 }
1965 mStreamBatchBufs->deallocate();
1966 delete mStreamBatchBufs;
1967 mStreamBatchBufs = NULL;
1968 }
1969 return rc;
1970
1971 }
1972
1973 /*===========================================================================
1974 * FUNCTION : BufAllocRoutine
1975 *
1976 * DESCRIPTION: function to allocate additional stream buffers
1977 *
1978 * PARAMETERS :
1979 * @data : user data ptr
1980 *
1981 * RETURN : none
1982 *==========================================================================*/
BufAllocRoutine(void * data)1983 void *QCameraStream::BufAllocRoutine(void *data)
1984 {
1985 QCameraStream *pme = (QCameraStream *)data;
1986 int32_t rc = NO_ERROR;
1987
1988 LOGH("E");
1989 pme->cond_wait();
1990 if (pme->mNumBufsNeedAlloc > 0) {
1991 uint8_t numBufAlloc = (uint8_t)(pme->mNumBufs - pme->mNumBufsNeedAlloc);
1992 rc = pme->mAllocator.allocateMoreStreamBuf(pme->mStreamBufs,
1993 pme->mFrameLenOffset.frame_len,
1994 pme->mNumBufsNeedAlloc);
1995 if (rc != NO_ERROR) {
1996 LOGE("Failed to allocate buffers");
1997 pme->mNumBufsNeedAlloc = 0;
1998 return NULL;
1999 }
2000
2001 pme->mNumBufsNeedAlloc = 0;
2002 QCameraBufferMaps bufferMaps;
2003 for (uint32_t i = numBufAlloc; i < pme->mNumBufs; i++) {
2004 ssize_t bufSize = pme->mStreamBufs->getSize(i);
2005 if (BAD_INDEX == bufSize) {
2006 LOGE("Failed to retrieve buffer size (bad index)");
2007 return NULL;
2008 }
2009
2010 rc = bufferMaps.enqueue(CAM_MAPPING_BUF_TYPE_STREAM_BUF,
2011 pme->mHandle, i /*buf index*/, -1 /*plane index*/,
2012 0 /*cookie*/, pme->mStreamBufs->getFd(i), bufSize,
2013 pme->mStreamBufs->getPtr(i));
2014
2015 if (rc < 0) {
2016 LOGE("Failed to map buffers");
2017 return NULL;
2018 }
2019 }
2020
2021 cam_buf_map_type_list bufMapList;
2022 rc = bufferMaps.getCamBufMapList(bufMapList);
2023 if (rc == NO_ERROR) {
2024 rc = pme->m_MemOpsTbl.bundled_map_ops(&bufMapList, pme->m_MemOpsTbl.userdata);
2025 }
2026 if (rc != 0) {
2027 LOGE("Failed to map buffers with return code %d", rc);
2028 return NULL;
2029 }
2030
2031 for (uint32_t i = numBufAlloc; i < pme->mNumBufs; i++) {
2032 pme->mStreamBufs->getBufDef(pme->mFrameLenOffset, pme->mBufDefs[i], i);
2033 pme->mCamOps->qbuf(pme->mCamHandle, pme->mChannelHandle,
2034 &pme->mBufDefs[i]);
2035 }
2036 }
2037 LOGH("X");
2038 return NULL;
2039 }
2040
2041 /*===========================================================================
2042 * FUNCTION : cond_signal
2043 *
2044 * DESCRIPTION: signal if flag "wait_for_cond" is set
2045 *
2046 *==========================================================================*/
cond_signal(bool forceExit)2047 void QCameraStream::cond_signal(bool forceExit)
2048 {
2049 pthread_mutex_lock(&m_lock);
2050 if(wait_for_cond == TRUE){
2051 wait_for_cond = FALSE;
2052 if (forceExit) {
2053 mNumBufsNeedAlloc = 0;
2054 }
2055 pthread_cond_signal(&m_cond);
2056 }
2057 pthread_mutex_unlock(&m_lock);
2058 }
2059
2060
2061 /*===========================================================================
2062 * FUNCTION : cond_wait
2063 *
2064 * DESCRIPTION: wait on if flag "wait_for_cond" is set
2065 *
2066 *==========================================================================*/
cond_wait()2067 void QCameraStream::cond_wait()
2068 {
2069 pthread_mutex_lock(&m_lock);
2070 while (wait_for_cond == TRUE) {
2071 pthread_cond_wait(&m_cond, &m_lock);
2072 }
2073 pthread_mutex_unlock(&m_lock);
2074 }
2075
2076 /*===========================================================================
2077 * FUNCTION : putBufs
2078 *
2079 * DESCRIPTION: deallocate stream buffers
2080 *
2081 * PARAMETERS :
2082 * @ops_tbl : ptr to buf mapping/unmapping ops
2083 *
2084 * RETURN : int32_t type of status
2085 * NO_ERROR -- success
2086 * none-zero failure code
2087 *==========================================================================*/
putBufs(mm_camera_map_unmap_ops_tbl_t * ops_tbl)2088 int32_t QCameraStream::putBufs(mm_camera_map_unmap_ops_tbl_t *ops_tbl)
2089 {
2090 int rc = NO_ERROR;
2091
2092 if (mBufAllocPid != 0) {
2093 cond_signal(true);
2094 LOGL("wait for buf allocation thread dead");
2095 pthread_join(mBufAllocPid, NULL);
2096 mBufAllocPid = 0;
2097 LOGL("return from buf allocation thread");
2098 }
2099
2100 uint8_t numBufsToUnmap = mStreamBufs->getMappable();
2101 for (uint32_t i = 0; i < numBufsToUnmap; i++) {
2102 rc = ops_tbl->unmap_ops(i, -1, CAM_MAPPING_BUF_TYPE_STREAM_BUF, ops_tbl->userdata);
2103 if (rc < 0) {
2104 LOGE("map_stream_buf failed: %d", rc);
2105 }
2106 }
2107 mBufDefs = NULL; // mBufDefs just keep a ptr to the buffer
2108 // mm-camera-interface own the buffer, so no need to free
2109 memset(&mFrameLenOffset, 0, sizeof(mFrameLenOffset));
2110 if ( !mStreamBufsAcquired ) {
2111 mStreamBufs->deallocate();
2112 delete mStreamBufs;
2113 mStreamBufs = NULL;
2114 }
2115
2116 return rc;
2117 }
2118
2119 /*===========================================================================
2120 * FUNCTION : putBufsDeffered
2121 *
2122 * DESCRIPTION: function to deallocate deffered stream buffers
2123 *
2124 * PARAMETERS : none
2125 *
2126 * RETURN : int32_t type of status
2127 * NO_ERROR -- success
2128 * none-zero failure code
2129 *==========================================================================*/
putBufsDeffered()2130 int32_t QCameraStream::putBufsDeffered()
2131 {
2132 if (mBufAllocPid != 0) {
2133 cond_signal(true);
2134 LOGH("%s: wait for buf allocation thread dead", __func__);
2135 // Wait for the allocation of additional stream buffers
2136 pthread_join(mBufAllocPid, NULL);
2137 mBufAllocPid = 0;
2138 LOGH("%s: return from buf allocation thread", __func__);
2139 }
2140 // Deallocation of the deffered stream buffers handled separately
2141 return NO_ERROR;
2142 }
2143
2144 /*===========================================================================
2145 * FUNCTION : invalidateBuf
2146 *
2147 * DESCRIPTION: invalidate a specific stream buffer
2148 *
2149 * PARAMETERS :
2150 * @index : index of the buffer to invalidate
2151 *
2152 * RETURN : int32_t type of status
2153 * NO_ERROR -- success
2154 * none-zero failure code
2155 *==========================================================================*/
invalidateBuf(uint32_t index)2156 int32_t QCameraStream::invalidateBuf(uint32_t index)
2157 {
2158 if (mStreamBufs == NULL) {
2159 LOGE("Invalid Operation");
2160 return INVALID_OPERATION;
2161 }
2162 return mStreamBufs->invalidateCache(index);
2163 }
2164
2165 /*===========================================================================
2166 * FUNCTION : cleanInvalidateBuf
2167 *
2168 * DESCRIPTION: clean invalidate a specific stream buffer
2169 *
2170 * PARAMETERS :
2171 * @index : index of the buffer to clean invalidate
2172 *
2173 * RETURN : int32_t type of status
2174 * NO_ERROR -- success
2175 * none-zero failure code
2176 *==========================================================================*/
cleanInvalidateBuf(uint32_t index)2177 int32_t QCameraStream::cleanInvalidateBuf(uint32_t index)
2178 {
2179 if (mStreamBufs == NULL) {
2180 LOGE("Invalid Operation");
2181 return INVALID_OPERATION;
2182 }
2183 return mStreamBufs->cleanInvalidateCache(index);
2184 }
2185
2186 /*===========================================================================
2187 * FUNCTION : isTypeOf
2188 *
2189 * DESCRIPTION: helper function to determine if the stream is of the queried type
2190 *
2191 * PARAMETERS :
2192 * @type : stream type as of queried
2193 *
2194 * RETURN : true/false
2195 *==========================================================================*/
isTypeOf(cam_stream_type_t type)2196 bool QCameraStream::isTypeOf(cam_stream_type_t type)
2197 {
2198 if (mStreamInfo != NULL && (mStreamInfo->stream_type == type)) {
2199 return true;
2200 } else {
2201 return false;
2202 }
2203 }
2204
2205 /*===========================================================================
2206 * FUNCTION : isOrignalTypeOf
2207 *
2208 * DESCRIPTION: helper function to determine if the original stream is of the
2209 * queried type if it's reproc stream
2210 *
2211 * PARAMETERS :
2212 * @type : stream type as of queried
2213 *
2214 * RETURN : true/false
2215 *==========================================================================*/
isOrignalTypeOf(cam_stream_type_t type)2216 bool QCameraStream::isOrignalTypeOf(cam_stream_type_t type)
2217 {
2218 if (mStreamInfo != NULL &&
2219 mStreamInfo->stream_type == CAM_STREAM_TYPE_OFFLINE_PROC &&
2220 mStreamInfo->reprocess_config.pp_type == CAM_ONLINE_REPROCESS_TYPE &&
2221 mStreamInfo->reprocess_config.online.input_stream_type == type) {
2222 return true;
2223 } else if (
2224 mStreamInfo != NULL &&
2225 mStreamInfo->stream_type == CAM_STREAM_TYPE_OFFLINE_PROC &&
2226 mStreamInfo->reprocess_config.pp_type == CAM_OFFLINE_REPROCESS_TYPE &&
2227 mStreamInfo->reprocess_config.offline.input_type == type) {
2228 return true;
2229 } else {
2230 return false;
2231 }
2232 }
2233
2234 /*===========================================================================
2235 * FUNCTION : getMyType
2236 *
2237 * DESCRIPTION: return stream type
2238 *
2239 * PARAMETERS : none
2240 *
2241 * RETURN : stream type
2242 *==========================================================================*/
getMyType()2243 cam_stream_type_t QCameraStream::getMyType()
2244 {
2245 if (mStreamInfo != NULL) {
2246 return mStreamInfo->stream_type;
2247 } else {
2248 return CAM_STREAM_TYPE_DEFAULT;
2249 }
2250 }
2251
2252 /*===========================================================================
2253 * FUNCTION : getMyOriginalType
2254 *
2255 * DESCRIPTION: return stream type
2256 *
2257 * PARAMETERS : none
2258 *
2259 * RETURN : stream type
2260 *==========================================================================*/
getMyOriginalType()2261 cam_stream_type_t QCameraStream::getMyOriginalType()
2262 {
2263 if (mStreamInfo != NULL) {
2264 if (mStreamInfo->stream_type == CAM_STREAM_TYPE_OFFLINE_PROC &&
2265 mStreamInfo->reprocess_config.pp_type == CAM_ONLINE_REPROCESS_TYPE) {
2266 return mStreamInfo->reprocess_config.online.input_stream_type;
2267 } else if (mStreamInfo->stream_type == CAM_STREAM_TYPE_OFFLINE_PROC &&
2268 mStreamInfo->reprocess_config.pp_type == CAM_OFFLINE_REPROCESS_TYPE) {
2269 return mStreamInfo->reprocess_config.offline.input_type;
2270 } else {
2271 return mStreamInfo->stream_type;
2272 }
2273 } else {
2274 return CAM_STREAM_TYPE_DEFAULT;
2275 }
2276 }
2277
2278 /*===========================================================================
2279 * FUNCTION : getFrameOffset
2280 *
2281 * DESCRIPTION: query stream buffer frame offset info
2282 *
2283 * PARAMETERS :
2284 * @offset : reference to struct to store the queried frame offset info
2285 *
2286 * RETURN : int32_t type of status
2287 * NO_ERROR -- success
2288 * none-zero failure code
2289 *==========================================================================*/
getFrameOffset(cam_frame_len_offset_t & offset)2290 int32_t QCameraStream::getFrameOffset(cam_frame_len_offset_t &offset)
2291 {
2292 if (NULL == mStreamInfo) {
2293 return NO_INIT;
2294 }
2295
2296 offset = mFrameLenOffset;
2297 if ((ROTATE_90 == mOnlineRotation) || (ROTATE_270 == mOnlineRotation)
2298 || (offset.frame_len == 0) || (offset.num_planes == 0)) {
2299 // Re-calculate frame offset in case of online rotation
2300 cam_stream_info_t streamInfo = *mStreamInfo;
2301 getFrameDimension(streamInfo.dim);
2302 calcOffset(&streamInfo);
2303 offset = streamInfo.buf_planes.plane_info;
2304 }
2305
2306 return 0;
2307 }
2308
2309 /*===========================================================================
2310 * FUNCTION : getCropInfo
2311 *
2312 * DESCRIPTION: query crop info of the stream
2313 *
2314 * PARAMETERS :
2315 * @crop : reference to struct to store the queried crop info
2316 *
2317 * RETURN : int32_t type of status
2318 * NO_ERROR -- success
2319 * none-zero failure code
2320 *==========================================================================*/
getCropInfo(cam_rect_t & crop)2321 int32_t QCameraStream::getCropInfo(cam_rect_t &crop)
2322 {
2323 pthread_mutex_lock(&mCropLock);
2324 crop = mCropInfo;
2325 pthread_mutex_unlock(&mCropLock);
2326 return NO_ERROR;
2327 }
2328
2329 /*===========================================================================
2330 * FUNCTION : setCropInfo
2331 *
2332 * DESCRIPTION: set crop info of the stream
2333 *
2334 * PARAMETERS :
2335 * @crop : struct to store new crop info
2336 *
2337 * RETURN : int32_t type of status
2338 * NO_ERROR -- success
2339 * none-zero failure code
2340 *==========================================================================*/
setCropInfo(cam_rect_t crop)2341 int32_t QCameraStream::setCropInfo(cam_rect_t crop)
2342 {
2343 pthread_mutex_lock(&mCropLock);
2344 mCropInfo = crop;
2345 pthread_mutex_unlock(&mCropLock);
2346 return NO_ERROR;
2347 }
2348
2349 /*===========================================================================
2350 * FUNCTION : getFrameDimension
2351 *
2352 * DESCRIPTION: query stream frame dimension info
2353 *
2354 * PARAMETERS :
2355 * @dim : reference to struct to store the queried frame dimension
2356 *
2357 * RETURN : int32_t type of status
2358 * NO_ERROR -- success
2359 * none-zero failure code
2360 *==========================================================================*/
getFrameDimension(cam_dimension_t & dim)2361 int32_t QCameraStream::getFrameDimension(cam_dimension_t &dim)
2362 {
2363 if (mStreamInfo != NULL) {
2364 if ((ROTATE_90 == mOnlineRotation) || (ROTATE_270 == mOnlineRotation)) {
2365 dim.width = mStreamInfo->dim.height;
2366 dim.height = mStreamInfo->dim.width;
2367 } else {
2368 dim = mStreamInfo->dim;
2369 }
2370 return 0;
2371 }
2372 return -1;
2373 }
2374
2375 /*===========================================================================
2376 * FUNCTION : getFormat
2377 *
2378 * DESCRIPTION: query stream format
2379 *
2380 * PARAMETERS :
2381 * @fmt : reference to stream format
2382 *
2383 * RETURN : int32_t type of status
2384 * NO_ERROR -- success
2385 * none-zero failure code
2386 *==========================================================================*/
getFormat(cam_format_t & fmt)2387 int32_t QCameraStream::getFormat(cam_format_t &fmt)
2388 {
2389 if (mStreamInfo != NULL) {
2390 fmt = mStreamInfo->fmt;
2391 return 0;
2392 }
2393 return -1;
2394 }
2395
2396 /*===========================================================================
2397 * FUNCTION : getMyServerID
2398 *
2399 * DESCRIPTION: query server stream ID
2400 *
2401 * PARAMETERS : None
2402 *
2403 * RETURN : stream ID from server
2404 *==========================================================================*/
getMyServerID()2405 uint32_t QCameraStream::getMyServerID() {
2406 if (mStreamInfo != NULL) {
2407 return mStreamInfo->stream_svr_id;
2408 } else {
2409 return 0;
2410 }
2411 }
2412
2413 /*===========================================================================
2414 * FUNCTION : acquireStreamBufs
2415 *
2416 * DESCRIPTION: acquire stream buffers and postpone their release.
2417 *
2418 * PARAMETERS : None
2419 *
2420 * RETURN : int32_t type of status
2421 * NO_ERROR -- success
2422 * none-zero failure code
2423 *==========================================================================*/
acquireStreamBufs()2424 int32_t QCameraStream::acquireStreamBufs()
2425 {
2426 mStreamBufsAcquired = true;
2427
2428 return NO_ERROR;
2429 }
2430
2431 /*===========================================================================
2432 * FUNCTION : mapBuf
2433 *
2434 * DESCRIPTION: map stream related buffer to backend server
2435 *
2436 * PARAMETERS :
2437 * @buf_type : mapping type of buffer
2438 * @buf_idx : index of buffer
2439 * @plane_idx: plane index
2440 * @fd : fd of the buffer
2441 * @buffer : buffer address
2442 * @size : lenght of the buffer
2443 * @ops_tbl : ptr to buf mapping/unmapping ops
2444 *
2445 * RETURN : int32_t type of status
2446 * NO_ERROR -- success
2447 * none-zero failure code
2448 *==========================================================================*/
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)2449 int32_t QCameraStream::mapBuf(uint8_t buf_type, uint32_t buf_idx,
2450 int32_t plane_idx, int fd, void *buffer, size_t size,
2451 mm_camera_map_unmap_ops_tbl_t *ops_tbl)
2452 {
2453 cam_buf_map_type_list bufMapList;
2454 int32_t rc = QCameraBufferMaps::makeSingletonBufMapList(
2455 (cam_mapping_buf_type)buf_type, mHandle, buf_idx, plane_idx,
2456 0 /*cookie*/, fd, size, bufMapList, buffer);
2457
2458 if (rc != NO_ERROR) {
2459 return rc;
2460 }
2461
2462 return mapBufs(bufMapList, ops_tbl);
2463 }
2464
2465 /*===========================================================================
2466 * FUNCTION : mapBufs
2467 *
2468 * DESCRIPTION: map stream related buffers to backend server
2469 *
2470 * PARAMETERS :
2471 * @bufMapList : buffer mapping information
2472 * @ops_tbl : ptr to buf mapping/unmapping ops
2473 *
2474 * RETURN : int32_t type of status
2475 * NO_ERROR -- success
2476 * none-zero failure code
2477 *==========================================================================*/
2478
mapBufs(cam_buf_map_type_list bufMapList,__unused mm_camera_map_unmap_ops_tbl_t * ops_tbl)2479 int32_t QCameraStream::mapBufs(cam_buf_map_type_list bufMapList,
2480 __unused mm_camera_map_unmap_ops_tbl_t *ops_tbl)
2481 {
2482 if (m_MemOpsTbl.bundled_map_ops != NULL) {
2483 return m_MemOpsTbl.bundled_map_ops(&bufMapList, m_MemOpsTbl.userdata);
2484 } else {
2485 return mCamOps->map_stream_bufs(mCamHandle, mChannelHandle,
2486 &bufMapList);
2487 }
2488
2489 }
2490
2491 /*===========================================================================
2492 * FUNCTION : unmapBuf
2493 *
2494 * DESCRIPTION: unmap 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 * @ops_tbl : ptr to buf mapping/unmapping ops
2501 *
2502 * RETURN : int32_t type of status
2503 * NO_ERROR -- success
2504 * none-zero failure code
2505 *==========================================================================*/
unmapBuf(uint8_t buf_type,uint32_t buf_idx,int32_t plane_idx,mm_camera_map_unmap_ops_tbl_t * ops_tbl)2506 int32_t QCameraStream::unmapBuf(uint8_t buf_type, uint32_t buf_idx, int32_t plane_idx,
2507 mm_camera_map_unmap_ops_tbl_t *ops_tbl)
2508 {
2509 if (ops_tbl != NULL) {
2510 return ops_tbl->unmap_ops(buf_idx, plane_idx,
2511 (cam_mapping_buf_type)buf_type, ops_tbl->userdata);
2512 } else {
2513 return mCamOps->unmap_stream_buf(mCamHandle, mChannelHandle,
2514 mHandle, buf_type, buf_idx, plane_idx);
2515 }
2516 }
2517
2518 /*===========================================================================
2519 * FUNCTION : setParameter
2520 *
2521 * DESCRIPTION: set stream based parameters
2522 *
2523 * PARAMETERS :
2524 * @param : ptr to parameters to be set
2525 *
2526 * RETURN : int32_t type of status
2527 * NO_ERROR -- success
2528 * none-zero failure code
2529 *==========================================================================*/
setParameter(cam_stream_parm_buffer_t & param)2530 int32_t QCameraStream::setParameter(cam_stream_parm_buffer_t ¶m)
2531 {
2532 int32_t rc = NO_ERROR;
2533 pthread_mutex_lock(&mParameterLock);
2534 mStreamInfo->parm_buf = param;
2535 rc = mCamOps->set_stream_parms(mCamHandle,
2536 mChannelHandle,
2537 mHandle,
2538 &mStreamInfo->parm_buf);
2539 if (rc == NO_ERROR) {
2540 param = mStreamInfo->parm_buf;
2541 }
2542 pthread_mutex_unlock(&mParameterLock);
2543 return rc;
2544 }
2545
2546 /*===========================================================================
2547 * FUNCTION : getParameter
2548 *
2549 * DESCRIPTION: get stream based parameters
2550 *
2551 * PARAMETERS :
2552 * @param : ptr to parameters to be red
2553 *
2554 * RETURN : int32_t type of status
2555 * NO_ERROR -- success
2556 * none-zero failure code
2557 *==========================================================================*/
getParameter(cam_stream_parm_buffer_t & param)2558 int32_t QCameraStream::getParameter(cam_stream_parm_buffer_t ¶m)
2559 {
2560 int32_t rc = NO_ERROR;
2561 pthread_mutex_lock(&mParameterLock);
2562 mStreamInfo->parm_buf = param;
2563 rc = mCamOps->get_stream_parms(mCamHandle,
2564 mChannelHandle,
2565 mHandle,
2566 &mStreamInfo->parm_buf);
2567 if (rc == NO_ERROR) {
2568 param = mStreamInfo->parm_buf;
2569 }
2570 pthread_mutex_unlock(&mParameterLock);
2571 return rc;
2572 }
2573
2574 /*===========================================================================
2575 * FUNCTION : releaseFrameData
2576 *
2577 * DESCRIPTION: callback function to release frame data node
2578 *
2579 * PARAMETERS :
2580 * @data : ptr to post process input data
2581 * @user_data : user data ptr (QCameraReprocessor)
2582 *
2583 * RETURN : None
2584 *==========================================================================*/
releaseFrameData(void * data,void * user_data)2585 void QCameraStream::releaseFrameData(void *data, void *user_data)
2586 {
2587 QCameraStream *pme = (QCameraStream *)user_data;
2588 mm_camera_super_buf_t *frame = (mm_camera_super_buf_t *)data;
2589 if (NULL != pme) {
2590 pme->bufDone(frame->bufs[0]->buf_idx);
2591 }
2592 }
2593
2594 /*===========================================================================
2595 * FUNCTION : configStream
2596 *
2597 * DESCRIPTION: send stream configuration to back end
2598 *
2599 * PARAMETERS :
2600 *
2601 * RETURN : int32_t type of status
2602 * NO_ERROR -- success
2603 * none-zero failure code
2604 *==========================================================================*/
configStream()2605 int32_t QCameraStream::configStream()
2606 {
2607 int rc = NO_ERROR;
2608
2609 // Configure the stream
2610 mm_camera_stream_config_t stream_config;
2611 stream_config.stream_info = mStreamInfo;
2612 stream_config.mem_vtbl = mMemVtbl;
2613 stream_config.stream_cb_sync = NULL;
2614 stream_config.stream_cb = dataNotifyCB;
2615 stream_config.padding_info = mPaddingInfo;
2616 stream_config.userdata = this;
2617 rc = mCamOps->config_stream(mCamHandle,
2618 mChannelHandle, mHandle, &stream_config);
2619 if (rc < 0) {
2620 LOGE("Failed to config stream, rc = %d", rc);
2621 mCamOps->unmap_stream_buf(mCamHandle,
2622 mChannelHandle,
2623 mHandle,
2624 CAM_MAPPING_BUF_TYPE_STREAM_INFO,
2625 0,
2626 -1);
2627 return UNKNOWN_ERROR;
2628 }
2629
2630 return rc;
2631 }
2632
2633 /*===========================================================================
2634 * FUNCTION : setSyncDataCB
2635 *
2636 * DESCRIPTION: register callback with mm-interface for this stream
2637 *
2638 * PARAMETERS :
2639 @stream_cb : Callback function
2640 *
2641 * RETURN : int32_t type of status
2642 * NO_ERROR -- success
2643 * non-zero failure code
2644 *==========================================================================*/
setSyncDataCB(stream_cb_routine data_cb)2645 int32_t QCameraStream::setSyncDataCB(stream_cb_routine data_cb)
2646 {
2647 int32_t rc = NO_ERROR;
2648
2649 if (mCamOps != NULL) {
2650 mSYNCDataCB = data_cb;
2651 rc = mCamOps->register_stream_buf_cb(mCamHandle,
2652 mChannelHandle, mHandle, dataNotifySYNCCB, MM_CAMERA_STREAM_CB_TYPE_SYNC,
2653 this);
2654 if (rc == NO_ERROR) {
2655 mSyncCBEnabled = TRUE;
2656 return rc;
2657 }
2658 }
2659 LOGE("Interface handle is NULL");
2660 return UNKNOWN_ERROR;
2661 }
2662
2663 }; // namespace qcamera
2664