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