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