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