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