1 /* Copyright (c) 2012-2015, The Linux Foundataion. 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 #include <utils/Errors.h>
33 #include <QComOMXMetadata.h>
34 #include "QCamera2HWI.h"
35 #include "QCameraStream.h"
36 
37 #define CAMERA_MIN_ALLOCATED_BUFFERS     3
38 
39 namespace qcamera {
40 
41 /*===========================================================================
42  * FUNCTION   : get_bufs
43  *
44  * DESCRIPTION: static function entry to allocate stream buffers
45  *
46  * PARAMETERS :
47  *   @offset     : offset info of stream buffers
48  *   @num_bufs   : number of buffers allocated
49  *   @initial_reg_flag: flag to indicate if buffer needs to be registered
50  *                      at kernel initially
51  *   @bufs       : output of allocated buffers
52  *   @ops_tbl    : ptr to buf mapping/unmapping ops
53  *   @user_data  : user data ptr of ops_tbl
54  *
55  * RETURN     : int32_t type of status
56  *              NO_ERROR  -- success
57  *              none-zero failure code
58  *==========================================================================*/
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)59 int32_t QCameraStream::get_bufs(
60                      cam_frame_len_offset_t *offset,
61                      uint8_t *num_bufs,
62                      uint8_t **initial_reg_flag,
63                      mm_camera_buf_def_t **bufs,
64                      mm_camera_map_unmap_ops_tbl_t *ops_tbl,
65                      void *user_data)
66 {
67     QCameraStream *stream = reinterpret_cast<QCameraStream *>(user_data);
68     if (!stream) {
69         ALOGE("getBufs invalid stream pointer");
70         return NO_MEMORY;
71     }
72 
73     if (stream->mStreamInfo != NULL
74             && stream->mStreamInfo->streaming_mode == CAM_STREAMING_MODE_BATCH) {
75         //Batch Mode. Allocate Butch buffers
76         return stream->allocateBatchBufs(offset, num_bufs,
77                 initial_reg_flag, bufs, ops_tbl);
78     } else {
79         // Plane Buffer. Allocate plane buffer
80         return stream->getBufs(offset, num_bufs,
81                 initial_reg_flag, bufs, ops_tbl);
82     }
83 }
84 
85 /*===========================================================================
86  * FUNCTION   : get_bufs_deffered
87  *
88  * DESCRIPTION: static function entry to allocate deffered stream buffers
89  *
90  * PARAMETERS :
91  *   @offset     : offset info of stream buffers
92  *   @num_bufs   : number of buffers allocated
93  *   @initial_reg_flag: flag to indicate if buffer needs to be registered
94  *                      at kernel initially
95  *   @bufs       : output of allocated buffers
96  *   @ops_tbl    : ptr to buf mapping/unmapping ops
97  *   @user_data  : user data ptr of ops_tbl
98  *
99  * RETURN     : int32_t type of status
100  *              NO_ERROR  -- success
101  *              none-zero failure code
102  *==========================================================================*/
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 *,void * user_data)103 int32_t QCameraStream::get_bufs_deffered(
104         cam_frame_len_offset_t * /* offset */,
105         uint8_t *num_bufs,
106         uint8_t **initial_reg_flag,
107         mm_camera_buf_def_t **bufs,
108         mm_camera_map_unmap_ops_tbl_t * /* ops_tbl */,
109         void *user_data)
110 {
111     QCameraStream *stream = reinterpret_cast<QCameraStream *>(user_data);
112     if (!stream) {
113         ALOGE("getBufs invalid stream pointer");
114         return NO_MEMORY;
115     }
116 
117     *initial_reg_flag   = stream->mRegFlags;
118     *num_bufs           = stream->mNumBufs;
119     *bufs               = stream->mBufDefs;
120     CDBG_HIGH("%s: stream type: %d, mRegFlags: 0x%x, numBufs: %d",
121             __func__, stream->getMyType(), stream->mRegFlags, stream->mNumBufs);
122     return NO_ERROR;
123 }
124 
125 /*===========================================================================
126  * FUNCTION   : put_bufs
127  *
128  * DESCRIPTION: static function entry to deallocate stream buffers
129  *
130  * PARAMETERS :
131  *   @ops_tbl    : ptr to buf mapping/unmapping ops
132  *   @user_data  : user data ptr of ops_tbl
133  *
134  * RETURN     : int32_t type of status
135  *              NO_ERROR  -- success
136  *              none-zero failure code
137  *==========================================================================*/
put_bufs(mm_camera_map_unmap_ops_tbl_t * ops_tbl,void * user_data)138 int32_t QCameraStream::put_bufs(
139         mm_camera_map_unmap_ops_tbl_t *ops_tbl,
140         void *user_data)
141 {
142     QCameraStream *stream = reinterpret_cast<QCameraStream *>(user_data);
143     if (!stream) {
144         ALOGE("putBufs invalid stream pointer");
145         return NO_MEMORY;
146     }
147 
148     if (stream->mStreamInfo != NULL
149             && stream->mStreamInfo->streaming_mode == CAM_STREAMING_MODE_BATCH) {
150         //Batch Mode. release  Butch buffers
151         return stream->releaseBatchBufs(ops_tbl);
152     } else {
153         // Plane Buffer. release  plane buffer
154         return stream->putBufs(ops_tbl);
155     }
156 
157 }
158 
159 /*===========================================================================
160  * FUNCTION   : put_bufs_deffered
161  *
162  * DESCRIPTION: static function entry to deallocate deffered stream buffers
163  *
164  * PARAMETERS :
165  *   @ops_tbl    : ptr to buf mapping/unmapping ops
166  *   @user_data  : user data ptr of ops_tbl
167  *
168  * RETURN     : int32_t type of status
169  *              NO_ERROR  -- success
170  *              none-zero failure code
171  *==========================================================================*/
put_bufs_deffered(mm_camera_map_unmap_ops_tbl_t *,void *)172 int32_t QCameraStream::put_bufs_deffered(
173         mm_camera_map_unmap_ops_tbl_t * /*ops_tbl */,
174         void * /*user_data*/ )
175 {
176     // No op
177     // Used for handling buffers with deffered allocation. They are freed separately.
178     return NO_ERROR;
179 }
180 
181 /*===========================================================================
182  * FUNCTION   : invalidate_buf
183  *
184  * DESCRIPTION: static function entry to invalidate a specific stream buffer
185  *
186  * PARAMETERS :
187  *   @index      : index of the stream buffer to invalidate
188  *   @user_data  : user data ptr of ops_tbl
189  *
190  * RETURN     : int32_t type of status
191  *              NO_ERROR  -- success
192  *              none-zero failure code
193  *==========================================================================*/
invalidate_buf(uint32_t index,void * user_data)194 int32_t QCameraStream::invalidate_buf(uint32_t index, void *user_data)
195 {
196     QCameraStream *stream = reinterpret_cast<QCameraStream *>(user_data);
197     if (!stream) {
198         ALOGE("invalid stream pointer");
199         return NO_MEMORY;
200     }
201 
202     if (stream->mStreamInfo->is_secure == SECURE){
203         return 0;
204     }
205 
206     if (stream->mStreamInfo->streaming_mode == CAM_STREAMING_MODE_BATCH) {
207         for (int i = 0; i < stream->mBufDefs[index].user_buf.bufs_used; i++) {
208             uint32_t buf_idx = stream->mBufDefs[index].user_buf.buf_idx[i];
209             stream->invalidateBuf(buf_idx);
210         }
211     } else {
212         return stream->invalidateBuf(index);
213     }
214 
215     return 0;
216 }
217 
218 /*===========================================================================
219  * FUNCTION   : clean_invalidate_buf
220  *
221  * DESCRIPTION: static function entry to clean invalidate a specific stream buffer
222  *
223  * PARAMETERS :
224  *   @index      : index of the stream buffer to clean invalidate
225  *   @user_data  : user data ptr of ops_tbl
226  *
227  * RETURN     : int32_t type of status
228  *              NO_ERROR  -- success
229  *              none-zero failure code
230  *==========================================================================*/
clean_invalidate_buf(uint32_t index,void * user_data)231 int32_t QCameraStream::clean_invalidate_buf(uint32_t index, void *user_data)
232 {
233     QCameraStream *stream = reinterpret_cast<QCameraStream *>(user_data);
234     if (!stream) {
235         ALOGE("invalid stream pointer");
236         return NO_MEMORY;
237     }
238 
239     if (stream->mStreamInfo->is_secure == SECURE){
240         return 0;
241     }
242 
243     if (stream->mStreamInfo->streaming_mode == CAM_STREAMING_MODE_BATCH) {
244         for (int i = 0; i < stream->mBufDefs[index].user_buf.bufs_used; i++) {
245             uint32_t buf_idx = stream->mBufDefs[index].user_buf.buf_idx[i];
246             stream->cleanInvalidateBuf(buf_idx);
247         }
248     } else {
249         return stream->cleanInvalidateBuf(index);
250     }
251 
252     return 0;
253 }
254 
255 /*===========================================================================
256  * FUNCTION   : QCameraStream
257  *
258  * DESCRIPTION: constructor of QCameraStream
259  *
260  * PARAMETERS :
261  *   @allocator  : memory allocator obj
262  *   @camHandle  : camera handle
263  *   @chId       : channel handle
264  *   @camOps     : ptr to camera ops table
265  *   @paddingInfo: ptr to padding info
266  *   @deffered   : deferred stream
267  *   @online_rotation: rotation applied online
268  *
269  * RETURN     : None
270  *==========================================================================*/
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)271 QCameraStream::QCameraStream(QCameraAllocator &allocator,
272         uint32_t camHandle, uint32_t chId,
273         mm_camera_ops_t *camOps, cam_padding_info_t *paddingInfo,
274         bool deffered, cam_rotation_t online_rotation):
275         mDumpFrame(0),
276         mDumpMetaFrame(0),
277         mDumpSkipCnt(0),
278         mCamHandle(camHandle),
279         mChannelHandle(chId),
280         mHandle(0),
281         mCamOps(camOps),
282         mStreamInfo(NULL),
283         mNumBufs(0),
284         mNumPlaneBufs(0),
285         mNumBufsNeedAlloc(0),
286         mDataCB(NULL),
287         mUserData(NULL),
288         mDataQ(releaseFrameData, this),
289         mStreamInfoBuf(NULL),
290         mMiscBuf(NULL),
291         mStreamBufs(NULL),
292         mStreamBatchBufs(NULL),
293         mAllocator(allocator),
294         mBufDefs(NULL),
295         mPlaneBufDefs(NULL),
296         mOnlineRotation(online_rotation),
297         mStreamBufsAcquired(false),
298         m_bActive(false),
299         mDynBufAlloc(false),
300         mBufAllocPid(0),
301         mDefferedAllocation(deffered),
302         wait_for_cond(false)
303 {
304     mMemVtbl.user_data = this;
305     if ( !deffered ) {
306         mMemVtbl.get_bufs = get_bufs;
307         mMemVtbl.put_bufs = put_bufs;
308     } else {
309         mMemVtbl.get_bufs = get_bufs_deffered;
310         mMemVtbl.put_bufs = put_bufs_deffered;
311     }
312     mMemVtbl.invalidate_buf = invalidate_buf;
313     mMemVtbl.clean_invalidate_buf = clean_invalidate_buf;
314     memset(&mFrameLenOffset, 0, sizeof(mFrameLenOffset));
315     memcpy(&mPaddingInfo, paddingInfo, sizeof(cam_padding_info_t));
316     memset(&mCropInfo, 0, sizeof(cam_rect_t));
317     memset(&m_MemOpsTbl, 0, sizeof(mm_camera_map_unmap_ops_tbl_t));
318     memset(&m_OutputCrop, 0, sizeof(cam_stream_parm_buffer_t));
319     memset(&m_ImgProp, 0, sizeof(cam_stream_parm_buffer_t));
320     pthread_mutex_init(&mCropLock, NULL);
321     pthread_mutex_init(&mParameterLock, NULL);
322 }
323 
324 /*===========================================================================
325  * FUNCTION   : ~QCameraStream
326  *
327  * DESCRIPTION: deconstructor of QCameraStream
328  *
329  * PARAMETERS : None
330  *
331  * RETURN     : None
332  *==========================================================================*/
~QCameraStream()333 QCameraStream::~QCameraStream()
334 {
335     pthread_mutex_destroy(&mCropLock);
336     pthread_mutex_destroy(&mParameterLock);
337 
338     if (mDefferedAllocation) {
339         mStreamBufsAcquired = false;
340         releaseBuffs();
341     }
342 
343     unmapStreamInfoBuf();
344     releaseStreamInfoBuf();
345 
346     if (mMiscBuf) {
347         unMapBuf(mMiscBuf, CAM_MAPPING_BUF_TYPE_MISC_BUF, NULL);
348         releaseMiscBuf();
349     }
350 
351     // delete stream
352     if (mHandle > 0) {
353         mCamOps->delete_stream(mCamHandle, mChannelHandle, mHandle);
354         mHandle = 0;
355     }
356 }
357 
358 /*===========================================================================
359  * FUNCTION   : unmapStreamInfoBuf
360  *
361  * DESCRIPTION: Unmap stream info buffer
362  *
363  * PARAMETERS :
364  *
365  * RETURN     : int32_t type of status
366  *              NO_ERROR  -- success
367  *              none-zero failure code
368  *==========================================================================*/
unmapStreamInfoBuf()369 int32_t QCameraStream::unmapStreamInfoBuf()
370 {
371     int rc = NO_ERROR;
372 
373     if (mStreamInfoBuf != NULL) {
374         rc = mCamOps->unmap_stream_buf(mCamHandle,
375             mChannelHandle,
376             mHandle,
377             CAM_MAPPING_BUF_TYPE_STREAM_INFO,
378             0,
379             -1);
380 
381         if (rc < 0) {
382             ALOGE("Failed to unmap stream info buffer");
383         }
384     }
385 
386     return rc;
387 }
388 
389 /*===========================================================================
390  * FUNCTION   : releaseMiscBuf
391  *
392  * DESCRIPTION: Release misc buffers
393  *
394  * PARAMETERS :
395  *
396  * RETURN     : int32_t type of status
397  *              NO_ERROR  -- success
398  *              none-zero failure code
399  *==========================================================================*/
releaseMiscBuf()400 int32_t QCameraStream::releaseMiscBuf()
401 {
402     int rc = NO_ERROR;
403 
404     if (mMiscBuf != NULL) {
405         mMiscBuf->deallocate();
406         delete mMiscBuf;
407         mMiscBuf = NULL;
408     }
409 
410     return rc;
411 }
412 
413 /*===========================================================================
414  * FUNCTION   : releaseStreamInfoBuf
415  *
416  * DESCRIPTION: Release stream info buffer
417  *
418  * PARAMETERS :
419  *
420  * RETURN     : int32_t type of status
421  *              NO_ERROR  -- success
422  *              none-zero failure code
423  *==========================================================================*/
releaseStreamInfoBuf()424 int32_t QCameraStream::releaseStreamInfoBuf()
425 {
426     int rc = NO_ERROR;
427 
428     if (mStreamInfoBuf != NULL) {
429         mStreamInfoBuf->deallocate();
430         delete mStreamInfoBuf;
431         mStreamInfoBuf = NULL;
432     }
433 
434     return rc;
435 }
436 
437 /*===========================================================================
438  * FUNCTION   : deleteStream
439  *
440  * DESCRIPTION: Deletes a camera stream
441  *
442  * PARAMETERS : None
443  *
444  * RETURN     : None
445  *==========================================================================*/
deleteStream()446 void QCameraStream::deleteStream()
447 {
448     if (mHandle > 0) {
449         acquireStreamBufs();
450         releaseBuffs();
451         unmapStreamInfoBuf();
452         mCamOps->delete_stream(mCamHandle, mChannelHandle, mHandle);
453     }
454 }
455 
456 /*===========================================================================
457  * FUNCTION   : unMapBuf
458  *
459  * DESCRIPTION: unmaps buffers
460  *
461  * PARAMETERS :
462  *   @heapBuf      : heap buffer handler
463  *   @bufType      : buffer type
464  *   @ops_tbl    : ptr to buf mapping/unmapping ops
465  *
466  * RETURN     : int32_t type of status
467  *              NO_ERROR  -- success
468  *              none-zero failure code
469  *==========================================================================*/
unMapBuf(QCameraMemory * Buf,cam_mapping_buf_type bufType,mm_camera_map_unmap_ops_tbl_t * ops_tbl)470 int32_t QCameraStream::unMapBuf(QCameraMemory *Buf,
471         cam_mapping_buf_type bufType, mm_camera_map_unmap_ops_tbl_t *ops_tbl)
472 {
473     int32_t rc = NO_ERROR;
474     uint8_t cnt;
475     ssize_t bufSize = BAD_INDEX;
476     uint32_t i;
477 
478     cnt = Buf->getCnt();
479     for (i = 0; i < cnt; i++) {
480         bufSize = Buf->getSize(i);
481         if (BAD_INDEX != bufSize) {
482             if (ops_tbl == NULL ) {
483                 rc = mCamOps->unmap_stream_buf(mCamHandle, mChannelHandle, mHandle,
484                         bufType, i, -1);
485             } else {
486                 rc = ops_tbl->unmap_ops(i, -1, bufType, ops_tbl->userdata);
487             }
488             if (rc < 0) {
489                 ALOGE("Failed to unmap buffer");
490                 break;
491             }
492         } else {
493             ALOGE("Failed to retrieve buffer size (bad index)");
494             rc = BAD_INDEX;
495             break;
496         }
497     }
498 
499     return rc;
500 }
501 
502 /*===========================================================================
503  * FUNCTION   : mapBuf
504  *
505  * DESCRIPTION: maps buffers
506  *
507  * PARAMETERS :
508  *   @heapBuf      : heap buffer handler
509  *   @bufType      : buffer type
510  *   @ops_tbl    : ptr to buf mapping/unmapping ops
511  *
512  * RETURN     : int32_t type of status
513  *              NO_ERROR  -- success
514  *              none-zero failure code
515  *==========================================================================*/
mapBuf(QCameraMemory * Buf,cam_mapping_buf_type bufType,mm_camera_map_unmap_ops_tbl_t * ops_tbl)516 int32_t QCameraStream::mapBuf(QCameraMemory *Buf,
517         cam_mapping_buf_type bufType, mm_camera_map_unmap_ops_tbl_t *ops_tbl)
518 {
519     int32_t rc = NO_ERROR;
520     uint8_t cnt;
521     ssize_t bufSize = BAD_INDEX;
522     int32_t i = 0;
523 
524     cnt = Buf->getCnt();
525     for (i = 0; i < cnt; i++) {
526         bufSize = Buf->getSize((uint32_t)i);
527         if (BAD_INDEX != bufSize) {
528             if (ops_tbl == NULL) {
529                 rc = mCamOps->map_stream_buf(mCamHandle, mChannelHandle, mHandle,
530                         (uint8_t)bufType, (uint32_t)i, -1,
531                         Buf->getFd((uint32_t)i), (uint32_t)bufSize);
532             } else {
533                 rc = ops_tbl->map_ops((uint32_t)i, -1, Buf->getFd((uint32_t)i),
534                         (uint32_t)bufSize, bufType, ops_tbl->userdata);
535             }
536             if (rc < 0) {
537                 ALOGE("Failed to map buffer");
538                 goto err1;
539             }
540         } else {
541             ALOGE("Failed to retrieve buffer size (bad index)");
542             rc = BAD_INDEX;
543             goto err1;
544         }
545     }
546 
547     return rc;
548 err1:
549     i -= 1;
550     for (; i >= 0; i--) {
551         bufSize = Buf->getSize((uint32_t)i);
552         if (BAD_INDEX != bufSize) {
553             if (ops_tbl == NULL) {
554                 rc = mCamOps->unmap_stream_buf(mCamHandle, mChannelHandle, mHandle,
555                         (uint8_t)bufType, (uint32_t)i, -1);
556             } else {
557                 rc = ops_tbl->unmap_ops((uint32_t)i, -1, bufType, ops_tbl->userdata);
558             }
559             if (rc < 0) {
560                 ALOGE("Failed to unmap buffer");
561             }
562         } else {
563             ALOGE("Failed to retrieve buffer size (bad index)");
564             rc = BAD_INDEX;
565         }
566     }
567     return rc;
568 }
569 
570 /*===========================================================================
571  * FUNCTION   : init
572  *
573  * DESCRIPTION: initialize stream obj
574  *
575  * PARAMETERS :
576  *   @streamInfoBuf: ptr to buf that contains stream info
577  *   @miscBuf      : ptr to buf that contains misc bufs
578  *   @stream_cb    : stream data notify callback. Can be NULL if not needed
579  *   @userdata     : user data ptr
580  *   @bDynallocBuf : flag to indicate if buffer allocation can be in 2 steps
581  *
582  * RETURN     : int32_t type of status
583  *              NO_ERROR  -- success
584  *              none-zero failure code
585  *==========================================================================*/
init(QCameraHeapMemory * streamInfoBuf,QCameraHeapMemory * miscBuf,uint8_t minNumBuffers,stream_cb_routine stream_cb,void * userdata,bool bDynallocBuf)586 int32_t QCameraStream::init(QCameraHeapMemory *streamInfoBuf,
587         QCameraHeapMemory *miscBuf,
588         uint8_t minNumBuffers,
589         stream_cb_routine stream_cb,
590         void *userdata,
591         bool bDynallocBuf)
592 {
593     int32_t rc = OK;
594 
595     mHandle = mCamOps->add_stream(mCamHandle, mChannelHandle);
596     if (!mHandle) {
597         ALOGE("add_stream failed");
598         rc = UNKNOWN_ERROR;
599         if (streamInfoBuf != NULL) {
600             streamInfoBuf->deallocate();
601             delete streamInfoBuf;
602             streamInfoBuf = NULL;
603         }
604         goto done;
605     }
606 
607     // assign and map stream info memory
608     mStreamInfoBuf = streamInfoBuf;
609     mStreamInfo = reinterpret_cast<cam_stream_info_t *>(mStreamInfoBuf->getPtr(0));
610     mNumBufs = minNumBuffers;
611 
612     rc = mapBuf(mStreamInfoBuf, CAM_MAPPING_BUF_TYPE_STREAM_INFO, NULL);
613     if (rc < 0) {
614         ALOGE("Failed to map stream info buffer");
615         releaseStreamInfoBuf();
616         mStreamInfo = 0;
617         goto err1;
618     }
619 
620     mMiscBuf = miscBuf;
621     if (miscBuf) {
622         rc = mapBuf(mMiscBuf, CAM_MAPPING_BUF_TYPE_MISC_BUF, NULL);
623         if (rc < 0) {
624             ALOGE("Failed to map miscellaneous buffer");
625             releaseMiscBuf();
626             goto err1;
627         }
628     }
629 
630     // Calculate buffer size for deffered allocation
631     if (mDefferedAllocation) {
632         rc = calcOffset(mStreamInfo);
633         if (rc < 0) {
634             ALOGE("%s : Failed to calculate stream offset", __func__);
635             goto err1;
636         }
637     } else {
638         rc = configStream();
639         if (rc < 0) {
640             ALOGE("%s : Failed to config stream ", __func__);
641             goto err1;
642         }
643     }
644 
645     mDataCB = stream_cb;
646     mUserData = userdata;
647     mDynBufAlloc = bDynallocBuf;
648     return 0;
649 
650 err1:
651     mCamOps->delete_stream(mCamHandle, mChannelHandle, mHandle);
652     mHandle = 0;
653     mNumBufs = 0;
654 done:
655     return rc;
656 }
657 
658 /*===========================================================================
659  * FUNCTION   : calcOffset
660  *
661  * DESCRIPTION: calculate frame offset based on format and padding information
662  *
663  * PARAMETERS :
664  *   @streamInfo  : stream information
665  *
666  * RETURN     : int32_t type of status
667  *              0  -- success
668  *              -1 -- failure
669  *==========================================================================*/
calcOffset(cam_stream_info_t * streamInfo)670 int32_t QCameraStream::calcOffset(cam_stream_info_t *streamInfo)
671 {
672     int32_t rc = 0;
673 
674     cam_dimension_t dim = streamInfo->dim;
675     if (streamInfo->pp_config.feature_mask & CAM_QCOM_FEATURE_ROTATION &&
676             streamInfo->stream_type != CAM_STREAM_TYPE_VIDEO) {
677         if (streamInfo->pp_config.rotation == ROTATE_90 ||
678                 streamInfo->pp_config.rotation == ROTATE_270) {
679             // rotated by 90 or 270, need to switch width and height
680             dim.width = streamInfo->dim.height;
681             dim.height = streamInfo->dim.width;
682         }
683     }
684 
685     switch (streamInfo->stream_type) {
686     case CAM_STREAM_TYPE_PREVIEW:
687         rc = mm_stream_calc_offset_preview(streamInfo->fmt,
688                 &dim,
689                 &streamInfo->buf_planes);
690         break;
691     case CAM_STREAM_TYPE_POSTVIEW:
692         rc = mm_stream_calc_offset_post_view(streamInfo->fmt,
693                 &dim,
694                 &streamInfo->buf_planes);
695         break;
696     case CAM_STREAM_TYPE_SNAPSHOT:
697         rc = mm_stream_calc_offset_snapshot(streamInfo->fmt,
698                 &dim,
699                 &mPaddingInfo,
700                 &streamInfo->buf_planes);
701         break;
702     case CAM_STREAM_TYPE_OFFLINE_PROC:
703         rc = mm_stream_calc_offset_postproc(streamInfo,
704                 &mPaddingInfo,
705                 &streamInfo->buf_planes);
706         break;
707     case CAM_STREAM_TYPE_VIDEO:
708         rc = mm_stream_calc_offset_video(&dim,
709                 &streamInfo->buf_planes);
710         break;
711     case CAM_STREAM_TYPE_RAW:
712         rc = mm_stream_calc_offset_raw(streamInfo->fmt,
713                 &dim,
714                 &mPaddingInfo,
715                 &streamInfo->buf_planes);
716         break;
717     case CAM_STREAM_TYPE_ANALYSIS:
718         rc = mm_stream_calc_offset_analysis(streamInfo->fmt,
719                 &dim,
720                 &mPaddingInfo,
721                 &streamInfo->buf_planes);
722         break;
723     case CAM_STREAM_TYPE_METADATA:
724         rc = mm_stream_calc_offset_metadata(&dim,
725                 &mPaddingInfo,
726                 &streamInfo->buf_planes);
727         break;
728     default:
729         ALOGE("%s: not supported for stream type %d",
730                 __func__, streamInfo->stream_type);
731         rc = -1;
732         break;
733     }
734     return rc;
735 }
736 
737 /*===========================================================================
738  * FUNCTION   : start
739  *
740  * DESCRIPTION: start stream. Will start main stream thread to handle stream
741  *              related ops.
742  *
743  * PARAMETERS : none
744  *
745  * RETURN     : int32_t type of status
746  *              NO_ERROR  -- success
747  *              none-zero failure code
748  *==========================================================================*/
start()749 int32_t QCameraStream::start()
750 {
751     int32_t rc = 0;
752     mDataQ.init();
753     rc = mProcTh.launch(dataProcRoutine, this);
754     if (rc == NO_ERROR) {
755         m_bActive = true;
756     }
757     pthread_mutex_init(&m_lock, NULL);
758     pthread_cond_init(&m_cond, NULL);
759     return rc;
760 }
761 
762 /*===========================================================================
763  * FUNCTION   : stop
764  *
765  * DESCRIPTION: stop stream. Will stop main stream thread
766  *
767  * PARAMETERS : none
768  *
769  * RETURN     : int32_t type of status
770  *              NO_ERROR  -- success
771  *              none-zero failure code
772  *==========================================================================*/
stop()773 int32_t QCameraStream::stop()
774 {
775     int32_t rc = 0;
776     m_bActive = false;
777     rc = mProcTh.exit();
778     return rc;
779 }
780 
781 /*===========================================================================
782  * FUNCTION   : syncRuntimeParams
783  *
784  * DESCRIPTION: query and sync runtime parameters like output crop
785  *              buffer info etc.
786  *
787  * PARAMETERS : none
788  *
789  * RETURN     : int32_t type of status
790  *              NO_ERROR  -- success
791  *              none-zero failure code
792  *==========================================================================*/
syncRuntimeParams()793 int32_t QCameraStream::syncRuntimeParams()
794 {
795     int32_t ret = NO_ERROR;
796 
797     memset(&m_OutputCrop, 0, sizeof(cam_stream_parm_buffer_t));
798     m_OutputCrop.type = CAM_STREAM_PARAM_TYPE_GET_OUTPUT_CROP;
799 
800     ret = getParameter(m_OutputCrop);
801     if (ret != NO_ERROR) {
802         ALOGE("%s: stream getParameter for output crop failed", __func__);
803         return ret;
804     }
805 
806     memset(&m_ImgProp, 0, sizeof(cam_stream_parm_buffer_t));
807     m_ImgProp.type = CAM_STREAM_PARAM_TYPE_GET_IMG_PROP;
808 
809     ret = getParameter(m_ImgProp);
810     if (ret != NO_ERROR) {
811         ALOGE("%s: stream getParameter for image prop failed", __func__);
812         return ret;
813     }
814 
815     return ret;
816 }
817 
818 /*===========================================================================
819  * FUNCTION   : processZoomDone
820  *
821  * DESCRIPTION: process zoom done event
822  *
823  * PARAMETERS :
824  *   @previewWindoe : preview window ops table to set preview crop window
825  *   @crop_info     : crop info
826  *
827  * RETURN     : int32_t type of status
828  *              NO_ERROR  -- success
829  *              none-zero failure code
830  *==========================================================================*/
processZoomDone(preview_stream_ops_t * previewWindow,cam_crop_data_t & crop_info)831 int32_t QCameraStream::processZoomDone(preview_stream_ops_t *previewWindow,
832                                        cam_crop_data_t &crop_info)
833 {
834     int32_t rc = 0;
835 
836     if (!m_bActive) {
837         ALOGV("%s : Stream not active", __func__);
838         return NO_ERROR;
839     }
840 
841     // get stream param for crop info
842     for (int i = 0; i < crop_info.num_of_streams; i++) {
843         if (crop_info.crop_info[i].stream_id == mStreamInfo->stream_svr_id) {
844             pthread_mutex_lock(&mCropLock);
845             mCropInfo = crop_info.crop_info[i].crop;
846             pthread_mutex_unlock(&mCropLock);
847 
848             // update preview window crop if it's preview/postview stream
849             if ( (previewWindow != NULL) &&
850                  (mStreamInfo->stream_type == CAM_STREAM_TYPE_PREVIEW ||
851                   mStreamInfo->stream_type == CAM_STREAM_TYPE_POSTVIEW) ) {
852                 rc = previewWindow->set_crop(previewWindow,
853                                              mCropInfo.left,
854                                              mCropInfo.top,
855                                              mCropInfo.width,
856                                              mCropInfo.height);
857             }
858             break;
859         }
860     }
861     return rc;
862 }
863 
864 /*===========================================================================
865  * FUNCTION   : processDataNotify
866  *
867  * DESCRIPTION: process stream data notify
868  *
869  * PARAMETERS :
870  *   @frame   : stream frame received
871  *
872  * RETURN     : int32_t type of status
873  *              NO_ERROR  -- success
874  *              none-zero failure code
875  *==========================================================================*/
processDataNotify(mm_camera_super_buf_t * frame)876 int32_t QCameraStream::processDataNotify(mm_camera_super_buf_t *frame)
877 {
878     CDBG("%s:\n", __func__);
879     if (mDataQ.enqueue((void *)frame)) {
880         return mProcTh.sendCmd(CAMERA_CMD_TYPE_DO_NEXT_JOB, FALSE, FALSE);
881     } else {
882         CDBG_HIGH("%s: Stream thread is not active, no ops here", __func__);
883         bufDone(frame->bufs[0]->buf_idx);
884         free(frame);
885         return NO_ERROR;
886     }
887 }
888 
889 /*===========================================================================
890  * FUNCTION   : dataNotifyCB
891  *
892  * DESCRIPTION: callback for data notify. This function is registered with
893  *              mm-camera-interface to handle data notify
894  *
895  * PARAMETERS :
896  *   @recvd_frame   : stream frame received
897  *   userdata       : user data ptr
898  *
899  * RETURN     : none
900  *==========================================================================*/
dataNotifyCB(mm_camera_super_buf_t * recvd_frame,void * userdata)901 void QCameraStream::dataNotifyCB(mm_camera_super_buf_t *recvd_frame,
902                                  void *userdata)
903 {
904     CDBG("%s:\n", __func__);
905     QCameraStream* stream = (QCameraStream *)userdata;
906     if (stream == NULL ||
907         recvd_frame == NULL ||
908         recvd_frame->bufs[0] == NULL ||
909         recvd_frame->bufs[0]->stream_id != stream->getMyHandle()) {
910         ALOGE("%s: Not a valid stream to handle buf", __func__);
911         return;
912     }
913 
914     mm_camera_super_buf_t *frame =
915         (mm_camera_super_buf_t *)malloc(sizeof(mm_camera_super_buf_t));
916     if (frame == NULL) {
917         ALOGE("%s: No mem for mm_camera_buf_def_t", __func__);
918         stream->bufDone(recvd_frame->bufs[0]->buf_idx);
919         return;
920     }
921     *frame = *recvd_frame;
922     stream->processDataNotify(frame);
923     return;
924 }
925 
926 /*===========================================================================
927  * FUNCTION   : dataProcRoutine
928  *
929  * DESCRIPTION: function to process data in the main stream thread
930  *
931  * PARAMETERS :
932  *   @data    : user data ptr
933  *
934  * RETURN     : none
935  *==========================================================================*/
dataProcRoutine(void * data)936 void *QCameraStream::dataProcRoutine(void *data)
937 {
938     int running = 1;
939     int ret;
940     QCameraStream *pme = (QCameraStream *)data;
941     QCameraCmdThread *cmdThread = &pme->mProcTh;
942     cmdThread->setName("CAM_strmDatProc");
943 
944     CDBG("%s: E", __func__);
945     do {
946         do {
947             ret = cam_sem_wait(&cmdThread->cmd_sem);
948             if (ret != 0 && errno != EINVAL) {
949                 ALOGE("%s: cam_sem_wait error (%s)",
950                       __func__, strerror(errno));
951                 return NULL;
952             }
953         } while (ret != 0);
954 
955         // we got notified about new cmd avail in cmd queue
956         camera_cmd_type_t cmd = cmdThread->getCmd();
957         switch (cmd) {
958         case CAMERA_CMD_TYPE_DO_NEXT_JOB:
959             {
960                 CDBG_HIGH("%s: Do next job", __func__);
961                 mm_camera_super_buf_t *frame =
962                     (mm_camera_super_buf_t *)pme->mDataQ.dequeue();
963                 if (NULL != frame) {
964                     if (pme->mDataCB != NULL) {
965                         pme->mDataCB(frame, pme, pme->mUserData);
966                     } else {
967                         // no data cb routine, return buf here
968                         pme->bufDone(frame->bufs[0]->buf_idx);
969                         free(frame);
970                     }
971                 }
972             }
973             break;
974         case CAMERA_CMD_TYPE_EXIT:
975             CDBG_HIGH("%s: Exit", __func__);
976             /* flush data buf queue */
977             pme->mDataQ.flush();
978             running = 0;
979             break;
980         default:
981             break;
982         }
983     } while (running);
984     CDBG_HIGH("%s: X", __func__);
985     return NULL;
986 }
987 
988 /*===========================================================================
989  * FUNCTION   : bufDone
990  *
991  * DESCRIPTION: return stream buffer to kernel
992  *
993  * PARAMETERS :
994  *   @index   : index of buffer to be returned
995  *
996  * RETURN     : int32_t type of status
997  *              NO_ERROR  -- success
998  *              none-zero failure code
999  *==========================================================================*/
bufDone(uint32_t index)1000 int32_t QCameraStream::bufDone(uint32_t index)
1001 {
1002     int32_t rc = NO_ERROR;
1003 
1004     if (index >= mNumBufs || mBufDefs == NULL)
1005         return BAD_INDEX;
1006 
1007     rc = mCamOps->qbuf(mCamHandle, mChannelHandle, &mBufDefs[index]);
1008     if (rc < 0)
1009         return rc;
1010 
1011     return rc;
1012 }
1013 
1014 /*===========================================================================
1015  * FUNCTION   : bufDone
1016  *
1017  * DESCRIPTION: return stream buffer to kernel
1018  *
1019  * PARAMETERS :
1020  *   @opaque    : stream frame/metadata buf to be returned
1021  *   @isMetaData: flag if returned opaque is a metadatabuf or the real frame ptr
1022  *
1023  * RETURN     : int32_t type of status
1024  *              NO_ERROR  -- success
1025  *              none-zero failure code
1026  *==========================================================================*/
bufDone(const void * opaque,bool isMetaData)1027 int32_t QCameraStream::bufDone(const void *opaque, bool isMetaData)
1028 {
1029     int32_t rc = NO_ERROR;
1030     int index;
1031 
1032     if (mStreamInfo != NULL
1033             && mStreamInfo->streaming_mode == CAM_STREAMING_MODE_BATCH) {
1034         index = mStreamBatchBufs->getMatchBufIndex(opaque, TRUE);
1035         if (index == -1 || index >= mNumBufs || mBufDefs == NULL) {
1036             ALOGE("%s: Cannot find buf for opaque data = %p", __func__, opaque);
1037             return BAD_INDEX;
1038         }
1039         camera_memory_t *video_mem = mStreamBatchBufs->getMemory(index, true);
1040         if (video_mem != NULL) {
1041             struct encoder_media_buffer_type * packet =
1042                     (struct encoder_media_buffer_type *)video_mem->data;
1043             native_handle_t *nh = const_cast<native_handle_t *>(packet->meta_handle);
1044             if (NULL != nh) {
1045                if (native_handle_delete(nh)) {
1046                    ALOGE("%s: Unable to delete native handle", __func__);
1047                }
1048             } else {
1049                ALOGE("%s : native handle not available", __func__);
1050             }
1051         }
1052     } else {
1053         index = mStreamBufs->getMatchBufIndex(opaque, isMetaData);
1054         if (index == -1 || index >= mNumBufs || mBufDefs == NULL) {
1055             ALOGE("%s: Cannot find buf for opaque data = %p", __func__, opaque);
1056             return BAD_INDEX;
1057         }
1058         CDBG_HIGH("%s: Buffer Index = %d, Frame Idx = %d", __func__, index,
1059                 mBufDefs[index].frame_idx);
1060     }
1061     rc = bufDone((uint32_t)index);
1062     return rc;
1063 }
1064 
1065 /*===========================================================================
1066  * FUNCTION   : getNumQueuedBuf
1067  *
1068  * DESCRIPTION: return queued buffer count
1069  *
1070  * PARAMETERS : None
1071  *
1072  * RETURN     : queued buffer count
1073  *==========================================================================*/
getNumQueuedBuf()1074 int32_t QCameraStream::getNumQueuedBuf()
1075 {
1076     int32_t rc = -1;
1077     if (mHandle > 0) {
1078         rc = mCamOps->get_queued_buf_count(mCamHandle, mChannelHandle, mHandle);
1079     }
1080     if (rc == -1) {
1081         ALOGE("%s: stream is not in active state. Invalid operation", __func__);
1082     }
1083     return rc;
1084 }
1085 
1086 /*===========================================================================
1087  * FUNCTION   : getBufs
1088  *
1089  * DESCRIPTION: allocate stream buffers
1090  *
1091  * PARAMETERS :
1092  *   @offset     : offset info of stream buffers
1093  *   @num_bufs   : number of buffers allocated
1094  *   @initial_reg_flag: flag to indicate if buffer needs to be registered
1095  *                      at kernel initially
1096  *   @bufs       : output of allocated buffers
1097  *   @ops_tbl    : ptr to buf mapping/unmapping ops
1098  *
1099  * RETURN     : int32_t type of status
1100  *              NO_ERROR  -- success
1101  *              none-zero failure code
1102  *==========================================================================*/
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)1103 int32_t QCameraStream::getBufs(cam_frame_len_offset_t *offset,
1104         uint8_t *num_bufs,
1105         uint8_t **initial_reg_flag,
1106         mm_camera_buf_def_t **bufs,
1107         mm_camera_map_unmap_ops_tbl_t *ops_tbl)
1108 {
1109     int rc = NO_ERROR;
1110     uint8_t *regFlags;
1111 
1112     if (!ops_tbl) {
1113         ALOGE("%s: ops_tbl is NULL", __func__);
1114         return INVALID_OPERATION;
1115     }
1116 
1117     mFrameLenOffset = *offset;
1118 
1119     uint8_t numBufAlloc = mNumBufs;
1120     mNumBufsNeedAlloc = 0;
1121     if (mDynBufAlloc) {
1122         numBufAlloc = CAMERA_MIN_ALLOCATED_BUFFERS;
1123         if (numBufAlloc > mNumBufs) {
1124             mDynBufAlloc = false;
1125             numBufAlloc = mNumBufs;
1126         } else {
1127             mNumBufsNeedAlloc = (uint8_t)(mNumBufs - numBufAlloc);
1128         }
1129     }
1130 
1131     //Allocate stream buffer
1132     mStreamBufs = mAllocator.allocateStreamBuf(mStreamInfo->stream_type,
1133             mFrameLenOffset.frame_len, mFrameLenOffset.mp[0].stride,
1134             mFrameLenOffset.mp[0].scanline, numBufAlloc);
1135     if (!mStreamBufs) {
1136         ALOGE("%s: Failed to allocate stream buffers", __func__);
1137         return NO_MEMORY;
1138     }
1139 
1140     mNumBufs = (uint8_t)(numBufAlloc + mNumBufsNeedAlloc);
1141 
1142     for (uint32_t i = 0; i < numBufAlloc; i++) {
1143         ssize_t bufSize = mStreamBufs->getSize(i);
1144         if (BAD_INDEX != bufSize) {
1145             rc = ops_tbl->map_ops(i, -1, mStreamBufs->getFd(i),
1146                     (uint32_t)bufSize, CAM_MAPPING_BUF_TYPE_STREAM_BUF, ops_tbl->userdata);
1147             if (rc < 0) {
1148                 ALOGE("%s: map_stream_buf failed: %d", __func__, rc);
1149                 for (uint32_t j = 0; j < i; j++) {
1150                     ops_tbl->unmap_ops(j, -1, CAM_MAPPING_BUF_TYPE_STREAM_BUF, ops_tbl->userdata);
1151                 }
1152                 mStreamBufs->deallocate();
1153                 delete mStreamBufs;
1154                 mStreamBufs = NULL;
1155                 return INVALID_OPERATION;
1156             }
1157         } else {
1158             ALOGE("Failed to retrieve buffer size (bad index)");
1159             return INVALID_OPERATION;
1160         }
1161     }
1162 
1163     //regFlags array is allocated by us, but consumed and freed by mm-camera-interface
1164     regFlags = (uint8_t *)malloc(sizeof(uint8_t) * mNumBufs);
1165     if (!regFlags) {
1166         ALOGE("%s: Out of memory", __func__);
1167         for (uint32_t i = 0; i < numBufAlloc; i++) {
1168             ops_tbl->unmap_ops(i, -1, CAM_MAPPING_BUF_TYPE_STREAM_BUF, ops_tbl->userdata);
1169         }
1170         mStreamBufs->deallocate();
1171         delete mStreamBufs;
1172         mStreamBufs = NULL;
1173         return NO_MEMORY;
1174     }
1175     memset(regFlags, 0, sizeof(uint8_t) * mNumBufs);
1176 
1177     mBufDefs = (mm_camera_buf_def_t *)malloc(mNumBufs * sizeof(mm_camera_buf_def_t));
1178     if (mBufDefs == NULL) {
1179         ALOGE("%s: getRegFlags failed %d", __func__, rc);
1180         for (uint32_t i = 0; i < numBufAlloc; i++) {
1181             ops_tbl->unmap_ops(i, -1, CAM_MAPPING_BUF_TYPE_STREAM_BUF, ops_tbl->userdata);
1182         }
1183         mStreamBufs->deallocate();
1184         delete mStreamBufs;
1185         mStreamBufs = NULL;
1186         free(regFlags);
1187         regFlags = NULL;
1188         return INVALID_OPERATION;
1189     }
1190     memset(mBufDefs, 0, mNumBufs * sizeof(mm_camera_buf_def_t));
1191     for (uint32_t i = 0; i < numBufAlloc; i++) {
1192         mStreamBufs->getBufDef(mFrameLenOffset, mBufDefs[i], i);
1193     }
1194 
1195     rc = mStreamBufs->getRegFlags(regFlags);
1196     if (rc < 0) {
1197         ALOGE("%s: getRegFlags failed %d", __func__, rc);
1198         for (uint32_t i = 0; i < numBufAlloc; i++) {
1199             ops_tbl->unmap_ops(i, -1, CAM_MAPPING_BUF_TYPE_STREAM_BUF, ops_tbl->userdata);
1200         }
1201         mStreamBufs->deallocate();
1202         delete mStreamBufs;
1203         mStreamBufs = NULL;
1204         free(mBufDefs);
1205         mBufDefs = NULL;
1206         free(regFlags);
1207         regFlags = NULL;
1208         return INVALID_OPERATION;
1209     }
1210 
1211     *num_bufs = mNumBufs;
1212     *initial_reg_flag = regFlags;
1213     *bufs = mBufDefs;
1214     CDBG_HIGH("%s: stream type: %d, mRegFlags: 0x%x, numBufs: %d",
1215             __func__, mStreamInfo->stream_type, regFlags, mBufDefs);
1216 
1217     if (mNumBufsNeedAlloc > 0) {
1218         pthread_mutex_lock(&m_lock);
1219         wait_for_cond = TRUE;
1220         pthread_mutex_unlock(&m_lock);
1221         CDBG_HIGH("%s: Still need to allocate %d buffers",
1222               __func__, mNumBufsNeedAlloc);
1223         // remember memops table
1224         m_MemOpsTbl = *ops_tbl;
1225         // start another thread to allocate the rest of buffers
1226         pthread_create(&mBufAllocPid,
1227                        NULL,
1228                        BufAllocRoutine,
1229                        this);
1230         pthread_setname_np(mBufAllocPid, "CAM_strmBufAlloc");
1231     }
1232 
1233     return NO_ERROR;
1234 }
1235 
1236 /*===========================================================================
1237  * FUNCTION   : allocateBuffers
1238  *
1239  * DESCRIPTION: allocate stream buffers
1240  *
1241  * PARAMETERS :
1242  *
1243  * RETURN     : int32_t type of status
1244  *              NO_ERROR  -- success
1245  *              none-zero failure code
1246  *==========================================================================*/
allocateBuffers()1247 int32_t QCameraStream::allocateBuffers()
1248 {
1249     int rc = NO_ERROR;
1250 
1251     mFrameLenOffset = mStreamInfo->buf_planes.plane_info;
1252 
1253     if (mStreamInfo->streaming_mode == CAM_STREAMING_MODE_BATCH) {
1254         return allocateBatchBufs(&mFrameLenOffset,
1255                 &mNumBufs, &mRegFlags,
1256                 &mBufDefs, NULL);
1257     }
1258 
1259     //Allocate and map stream info buffer
1260     mStreamBufs = mAllocator.allocateStreamBuf(mStreamInfo->stream_type,
1261             mFrameLenOffset.frame_len,
1262             mFrameLenOffset.mp[0].stride,
1263             mFrameLenOffset.mp[0].scanline,
1264             mNumBufs);
1265 
1266     if (!mStreamBufs) {
1267         ALOGE("%s: Failed to allocate stream buffers", __func__);
1268         return NO_MEMORY;
1269     }
1270 
1271     for (uint32_t i = 0; i < mNumBufs; i++) {
1272         ssize_t bufSize = mStreamBufs->getSize(i);
1273         if (BAD_INDEX != bufSize) {
1274             rc = mapBuf(CAM_MAPPING_BUF_TYPE_STREAM_BUF, i, -1,
1275                     mStreamBufs->getFd(i), (size_t)bufSize, NULL);
1276             ALOGE_IF((rc < 0), "%s: map_stream_buf failed: %d", __func__, rc);
1277         } else {
1278             ALOGE("%s: Bad index %u", __func__, i);
1279             rc = BAD_INDEX;
1280         }
1281         if (rc < 0) {
1282             ALOGE("%s: Cleanup after error: %d", __func__, rc);
1283             for (uint32_t j = 0; j < i; j++) {
1284                 unmapBuf(CAM_MAPPING_BUF_TYPE_STREAM_BUF, j, -1, NULL);
1285             }
1286             mStreamBufs->deallocate();
1287             delete mStreamBufs;
1288             mStreamBufs = NULL;
1289             return INVALID_OPERATION;
1290         }
1291     }
1292 
1293     //regFlags array is allocated by us,
1294     // but consumed and freed by mm-camera-interface
1295     mRegFlags = (uint8_t *)malloc(sizeof(uint8_t) * mNumBufs);
1296     if (!mRegFlags) {
1297         ALOGE("%s: Out of memory", __func__);
1298         for (uint32_t i = 0; i < mNumBufs; i++) {
1299             unmapBuf(CAM_MAPPING_BUF_TYPE_STREAM_BUF, i, -1, NULL);
1300         }
1301         mStreamBufs->deallocate();
1302         delete mStreamBufs;
1303         mStreamBufs = NULL;
1304         return NO_MEMORY;
1305     }
1306     memset(mRegFlags, 0, sizeof(uint8_t) * mNumBufs);
1307 
1308     size_t bufDefsSize = mNumBufs * sizeof(mm_camera_buf_def_t);
1309     mBufDefs = (mm_camera_buf_def_t *)malloc(bufDefsSize);
1310     if (mBufDefs == NULL) {
1311         ALOGE("%s: getRegFlags failed %d", __func__, rc);
1312         for (uint32_t i = 0; i < mNumBufs; i++) {
1313             unmapBuf(CAM_MAPPING_BUF_TYPE_STREAM_BUF, i, -1, NULL);
1314         }
1315         mStreamBufs->deallocate();
1316         delete mStreamBufs;
1317         mStreamBufs = NULL;
1318         free(mRegFlags);
1319         mRegFlags = NULL;
1320         return INVALID_OPERATION;
1321     }
1322     memset(mBufDefs, 0, bufDefsSize);
1323     for (uint32_t i = 0; i < mNumBufs; i++) {
1324         mStreamBufs->getBufDef(mFrameLenOffset, mBufDefs[i], i);
1325     }
1326 
1327     rc = mStreamBufs->getRegFlags(mRegFlags);
1328     if (rc < 0) {
1329         ALOGE("%s: getRegFlags failed %d", __func__, rc);
1330         for (uint32_t i = 0; i < mNumBufs; i++) {
1331             unmapBuf(CAM_MAPPING_BUF_TYPE_STREAM_BUF, i, -1, NULL);
1332         }
1333         mStreamBufs->deallocate();
1334         delete mStreamBufs;
1335         mStreamBufs = NULL;
1336         free(mBufDefs);
1337         mBufDefs = NULL;
1338         free(mRegFlags);
1339         mRegFlags = NULL;
1340         return INVALID_OPERATION;
1341     }
1342 
1343     return NO_ERROR;
1344 }
1345 
1346 /*===========================================================================
1347  * FUNCTION   : allocateBatchBufs
1348  *
1349  * DESCRIPTION: allocate stream batch buffers and stream buffers
1350  *
1351  * PARAMETERS :
1352  *   @offset     : offset info of stream buffers
1353  *   @num_bufs   : number of buffers allocated
1354  *   @initial_reg_flag: flag to indicate if buffer needs to be registered
1355  *                      at kernel initially
1356  *   @bufs       : output of allocated buffers
1357  *   @plane_bufs    : output of allocated plane buffers
1358   *   @ops_tbl    : ptr to buf mapping/unmapping ops
1359  *
1360  * RETURN     : int32_t type of status
1361  *              NO_ERROR  -- success
1362  *              none-zero failure code
1363  *==========================================================================*/
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)1364 int32_t QCameraStream::allocateBatchBufs(cam_frame_len_offset_t *offset,
1365         uint8_t *num_bufs, uint8_t **initial_reg_flag,
1366         mm_camera_buf_def_t **bufs, mm_camera_map_unmap_ops_tbl_t *ops_tbl)
1367 {
1368     int rc = NO_ERROR;
1369     uint8_t *regFlags;
1370 
1371     mFrameLenOffset = *offset;
1372 
1373     CDBG_HIGH("%s : Batch Buffer allocation stream type = %d", __func__, getMyType());
1374 
1375     //Allocate stream batch buffer
1376     mStreamBatchBufs = mAllocator.allocateStreamUserBuf (mStreamInfo);
1377     if (!mStreamBatchBufs) {
1378         ALOGE("%s: Failed to allocate stream batch buffers", __func__);
1379         return NO_MEMORY;
1380     }
1381 
1382     //map batch buffers
1383     for (uint32_t i = 0; i < mStreamBatchBufs->getCnt(); i++) {
1384         rc = mapBuf(CAM_MAPPING_BUF_TYPE_STREAM_USER_BUF, i, -1,
1385                     mStreamBatchBufs->getFd(i), (size_t)mNumBufs, ops_tbl);
1386         if (rc < 0) {
1387             ALOGE("Failed to map stream batch buffer");
1388             for (uint32_t j = 0; j < i; j++) {
1389                 unmapBuf(CAM_MAPPING_BUF_TYPE_STREAM_USER_BUF, j, -1, ops_tbl);
1390             }
1391             mStreamBatchBufs->deallocate();
1392             delete mStreamBatchBufs;
1393             mStreamBatchBufs = NULL;
1394             return NO_MEMORY;
1395         }
1396     }
1397 
1398     /*calculate stream Buffer count*/
1399     mNumPlaneBufs =
1400             (mNumBufs * mStreamInfo->user_buf_info.frame_buf_cnt);
1401 
1402     //Allocate stream buffer
1403     mStreamBufs = mAllocator.allocateStreamBuf(mStreamInfo->stream_type,
1404             mFrameLenOffset.frame_len,mFrameLenOffset.mp[0].stride,
1405             mFrameLenOffset.mp[0].scanline,mNumPlaneBufs);
1406     if (!mStreamBufs) {
1407         ALOGE("%s: Failed to allocate stream buffers", __func__);
1408         rc = NO_MEMORY;
1409         goto err1;
1410     }
1411 
1412     //Map plane stream buffers
1413     for (uint32_t i = 0; i < mNumPlaneBufs; i++) {
1414         ssize_t bufSize = mStreamBufs->getSize(i);
1415         if (BAD_INDEX != bufSize) {
1416             rc = mapBuf(CAM_MAPPING_BUF_TYPE_STREAM_BUF, i, -1,
1417                     mStreamBufs->getFd(i), (size_t)bufSize, ops_tbl);
1418             if (rc < 0) {
1419                 ALOGE("%s: map_stream_buf failed: %d", __func__, rc);
1420                 for (uint32_t j = 0; j < i; j++) {
1421                     unmapBuf(CAM_MAPPING_BUF_TYPE_STREAM_BUF, j, -1, ops_tbl);
1422                 }
1423                 mStreamBufs->deallocate();
1424                 delete mStreamBufs;
1425                 mStreamBufs = NULL;
1426                 rc = INVALID_OPERATION;
1427                 goto err1;
1428             }
1429         } else {
1430             ALOGE("Failed to retrieve buffer size (bad index)");
1431             mStreamBufs->deallocate();
1432             delete mStreamBufs;
1433             mStreamBufs = NULL;
1434             rc = INVALID_OPERATION;
1435             goto err1;
1436         }
1437     }
1438 
1439     CDBG ("%s: BATCH Buf Count = %d, Plane Buf Cnt = %d", __func__,
1440             mNumBufs, mNumPlaneBufs);
1441 
1442     //regFlags array is allocated by us, but consumed and freed by mm-camera-interface
1443     regFlags = (uint8_t *)malloc(sizeof(uint8_t) * mNumBufs);
1444     if (!regFlags) {
1445         ALOGE("%s: Out of memory", __func__);
1446         for (uint32_t i = 0; i < mNumPlaneBufs; i++) {
1447             unmapBuf(CAM_MAPPING_BUF_TYPE_STREAM_BUF, i, -1, ops_tbl);
1448         }
1449         mStreamBufs->deallocate();
1450         delete mStreamBufs;
1451         mStreamBufs = NULL;
1452         rc = NO_MEMORY;
1453         goto err1;
1454     }
1455     memset(regFlags, 0, sizeof(uint8_t) * mNumBufs);
1456     for (uint32_t i = 0; i < mNumBufs; i++) {
1457         regFlags[i] = 1;
1458     }
1459 
1460     mBufDefs = (mm_camera_buf_def_t *)malloc(mNumBufs * sizeof(mm_camera_buf_def_t));
1461     if (mBufDefs == NULL) {
1462         ALOGE("%s: getRegFlags failed %d", __func__, rc);
1463         for (uint32_t i = 0; i < mNumPlaneBufs; i++) {
1464             unmapBuf(CAM_MAPPING_BUF_TYPE_STREAM_BUF, i, -1, ops_tbl);
1465         }
1466         mStreamBufs->deallocate();
1467         delete mStreamBufs;
1468         mStreamBufs = NULL;
1469         free(regFlags);
1470         regFlags = NULL;
1471         rc = INVALID_OPERATION;
1472         goto err1;
1473     }
1474     memset(mBufDefs, 0, mNumBufs * sizeof(mm_camera_buf_def_t));
1475 
1476     mPlaneBufDefs = (mm_camera_buf_def_t *)
1477             malloc(mNumPlaneBufs * (sizeof(mm_camera_buf_def_t)));
1478     if (mPlaneBufDefs == NULL) {
1479         ALOGE("%s : No Memory", __func__);
1480         free(regFlags);
1481         regFlags = NULL;
1482         free(mBufDefs);
1483         mBufDefs = NULL;
1484         for (uint32_t i = 0; i < mNumPlaneBufs; i++) {
1485             unmapBuf(CAM_MAPPING_BUF_TYPE_STREAM_BUF, i, -1, ops_tbl);
1486         }
1487         mStreamBufs->deallocate();
1488         delete mStreamBufs;
1489         mStreamBufs = NULL;
1490         free(regFlags);
1491         regFlags = NULL;
1492         rc = INVALID_OPERATION;
1493         goto err1;
1494     }
1495     memset(mPlaneBufDefs, 0,
1496              mNumPlaneBufs * (sizeof(mm_camera_buf_def_t)));
1497 
1498     for (uint32_t i = 0; i < mStreamInfo->num_bufs; i++) {
1499         mStreamBatchBufs->getUserBufDef(mStreamInfo->user_buf_info,
1500                 mBufDefs[i], i, mFrameLenOffset, mPlaneBufDefs,
1501                 mStreamBufs);
1502     }
1503 
1504     *num_bufs = mNumBufs;
1505     *initial_reg_flag = regFlags;
1506     *bufs = mBufDefs;
1507     CDBG_HIGH("%s: stream type: %d, numBufs: %d mNumPlaneBufs: %d",
1508             __func__, mStreamInfo->stream_type, mNumBufs, mNumPlaneBufs);
1509 
1510     return NO_ERROR;
1511 
1512 err1:
1513     for (uint8_t i = 0; i < mStreamBatchBufs->getCnt(); i++) {
1514         unmapBuf(CAM_MAPPING_BUF_TYPE_STREAM_USER_BUF, i, -1, ops_tbl);
1515     }
1516     mStreamBatchBufs->deallocate();
1517     delete mStreamBatchBufs;
1518     mStreamBatchBufs = NULL;
1519     return rc;
1520 }
1521 
1522 
1523 /*===========================================================================
1524  * FUNCTION   : releaseBuffs
1525  *
1526  * DESCRIPTION: method to deallocate stream buffers
1527  *
1528  * PARAMETERS :
1529  *
1530  * RETURN     : int32_t type of status
1531  *              NO_ERROR  -- success
1532  *              none-zero failure code
1533  *==========================================================================*/
releaseBuffs()1534 int32_t QCameraStream::releaseBuffs()
1535 {
1536     int rc = NO_ERROR;
1537 
1538     if (mStreamInfo->streaming_mode == CAM_STREAMING_MODE_BATCH) {
1539         return releaseBatchBufs(NULL);
1540     }
1541 
1542     if (NULL != mBufDefs) {
1543         for (uint32_t i = 0; i < mNumBufs; i++) {
1544             rc = unmapBuf(CAM_MAPPING_BUF_TYPE_STREAM_BUF, i, -1, NULL);
1545             if (rc < 0) {
1546                 ALOGE("%s: map_stream_buf failed: %d", __func__, rc);
1547             }
1548         }
1549 
1550         // mBufDefs just keep a ptr to the buffer
1551         // mm-camera-interface own the buffer, so no need to free
1552         mBufDefs = NULL;
1553         memset(&mFrameLenOffset, 0, sizeof(mFrameLenOffset));
1554     }
1555     if (!mStreamBufsAcquired && mStreamBufs != NULL) {
1556         mStreamBufs->deallocate();
1557         delete mStreamBufs;
1558     }
1559 
1560     return rc;
1561 }
1562 
1563 /*===========================================================================
1564  * FUNCTION   : releaseBatchBufs
1565  *
1566  * DESCRIPTION: method to deallocate stream buffers and batch buffers
1567  *
1568  * PARAMETERS :
1569  *   @ops_tbl    : ptr to buf mapping/unmapping ops
1570  *
1571  * RETURN     : int32_t type of status
1572  *              NO_ERROR  -- success
1573  *              none-zero failure code
1574 
1575  *==========================================================================*/
releaseBatchBufs(mm_camera_map_unmap_ops_tbl_t * ops_tbl)1576 int32_t QCameraStream::releaseBatchBufs(mm_camera_map_unmap_ops_tbl_t *ops_tbl)
1577 {
1578     int rc = NO_ERROR;
1579 
1580     if (NULL != mPlaneBufDefs) {
1581         for (uint32_t i = 0; i < mNumPlaneBufs; i++) {
1582             rc = unmapBuf(CAM_MAPPING_BUF_TYPE_STREAM_BUF, i, -1, ops_tbl);
1583             if (rc < 0) {
1584                 ALOGE("%s: map_stream_buf failed: %d", __func__, rc);
1585             }
1586         }
1587 
1588         // mBufDefs just keep a ptr to the buffer
1589         // mm-camera-interface own the buffer, so no need to free
1590         mPlaneBufDefs = NULL;
1591         memset(&mFrameLenOffset, 0, sizeof(mFrameLenOffset));
1592         mNumPlaneBufs = 0;
1593     }
1594 
1595     if ( mStreamBufs != NULL) {
1596         mStreamBufs->deallocate();
1597         delete mStreamBufs;
1598     }
1599 
1600     mBufDefs = NULL;
1601 
1602     if (mStreamBatchBufs != NULL) {
1603         for (uint8_t i = 0; i < mStreamBatchBufs->getCnt(); i++) {
1604             unmapBuf(CAM_MAPPING_BUF_TYPE_STREAM_USER_BUF, i, -1, ops_tbl);
1605         }
1606         mStreamBatchBufs->deallocate();
1607         delete mStreamBatchBufs;
1608         mStreamBatchBufs = NULL;
1609     }
1610     return rc;
1611 
1612 }
1613 
1614 /*===========================================================================
1615  * FUNCTION   : BufAllocRoutine
1616  *
1617  * DESCRIPTION: function to allocate additional stream buffers
1618  *
1619  * PARAMETERS :
1620  *   @data    : user data ptr
1621  *
1622  * RETURN     : none
1623  *==========================================================================*/
BufAllocRoutine(void * data)1624 void *QCameraStream::BufAllocRoutine(void *data)
1625 {
1626     QCameraStream *pme = (QCameraStream *)data;
1627     int32_t rc = NO_ERROR;
1628 
1629     CDBG_HIGH("%s: E", __func__);
1630     pme->cond_wait();
1631     if (pme->mNumBufsNeedAlloc > 0) {
1632         uint8_t numBufAlloc = (uint8_t)(pme->mNumBufs - pme->mNumBufsNeedAlloc);
1633         rc = pme->mAllocator.allocateMoreStreamBuf(pme->mStreamBufs,
1634                                                    pme->mFrameLenOffset.frame_len,
1635                                                    pme->mNumBufsNeedAlloc);
1636         if (rc == NO_ERROR){
1637             for (uint32_t i = numBufAlloc; i < pme->mNumBufs; i++) {
1638                 ssize_t bufSize = pme->mStreamBufs->getSize(i);
1639                 if (BAD_INDEX != bufSize) {
1640                     rc = pme->m_MemOpsTbl.map_ops(i, -1, pme->mStreamBufs->getFd(i),
1641                             (uint32_t)bufSize, CAM_MAPPING_BUF_TYPE_STREAM_BUF,
1642                             pme->m_MemOpsTbl.userdata);
1643                     if (rc == 0) {
1644                         pme->mStreamBufs->getBufDef(pme->mFrameLenOffset, pme->mBufDefs[i], i);
1645                         pme->mCamOps->qbuf(pme->mCamHandle, pme->mChannelHandle,
1646                                 &pme->mBufDefs[i]);
1647                     } else {
1648                         ALOGE("%s: map_stream_buf %d failed: %d", __func__, rc, i);
1649                     }
1650                 } else {
1651                     ALOGE("Failed to retrieve buffer size (bad index)");
1652                 }
1653             }
1654 
1655             pme->mNumBufsNeedAlloc = 0;
1656         }
1657     }
1658     CDBG_HIGH("%s: X", __func__);
1659     return NULL;
1660 }
1661 
1662 /*===========================================================================
1663  * FUNCTION   : cond_signal
1664  *
1665  * DESCRIPTION: signal if flag "wait_for_cond" is set
1666  *
1667  *==========================================================================*/
cond_signal()1668 void QCameraStream::cond_signal()
1669 {
1670     pthread_mutex_lock(&m_lock);
1671     if(wait_for_cond == TRUE){
1672         wait_for_cond = FALSE;
1673         pthread_cond_signal(&m_cond);
1674     }
1675     pthread_mutex_unlock(&m_lock);
1676 }
1677 
1678 
1679 /*===========================================================================
1680  * FUNCTION   : cond_wait
1681  *
1682  * DESCRIPTION: wait on if flag "wait_for_cond" is set
1683  *
1684  *==========================================================================*/
cond_wait()1685 void QCameraStream::cond_wait()
1686 {
1687     pthread_mutex_lock(&m_lock);
1688     while (wait_for_cond == TRUE) {
1689         pthread_cond_wait(&m_cond, &m_lock);
1690     }
1691     pthread_mutex_unlock(&m_lock);
1692 }
1693 
1694 /*===========================================================================
1695  * FUNCTION   : putBufs
1696  *
1697  * DESCRIPTION: deallocate stream buffers
1698  *
1699  * PARAMETERS :
1700  *   @ops_tbl    : ptr to buf mapping/unmapping ops
1701  *
1702  * RETURN     : int32_t type of status
1703  *              NO_ERROR  -- success
1704  *              none-zero failure code
1705  *==========================================================================*/
putBufs(mm_camera_map_unmap_ops_tbl_t * ops_tbl)1706 int32_t QCameraStream::putBufs(mm_camera_map_unmap_ops_tbl_t *ops_tbl)
1707 {
1708     int rc = NO_ERROR;
1709 
1710     if (mBufAllocPid != 0) {
1711         CDBG_HIGH("%s: wait for buf allocation thread dead", __func__);
1712         pthread_join(mBufAllocPid, NULL);
1713         mBufAllocPid = 0;
1714         CDBG_HIGH("%s: return from buf allocation thread", __func__);
1715     }
1716 
1717     for (uint32_t i = 0; i < mNumBufs; i++) {
1718         rc = ops_tbl->unmap_ops(i, -1, CAM_MAPPING_BUF_TYPE_STREAM_BUF, ops_tbl->userdata);
1719         if (rc < 0) {
1720             ALOGE("%s: map_stream_buf failed: %d", __func__, rc);
1721         }
1722     }
1723     mBufDefs = NULL; // mBufDefs just keep a ptr to the buffer
1724                      // mm-camera-interface own the buffer, so no need to free
1725     memset(&mFrameLenOffset, 0, sizeof(mFrameLenOffset));
1726     if ( !mStreamBufsAcquired ) {
1727         mStreamBufs->deallocate();
1728         delete mStreamBufs;
1729     }
1730 
1731     return rc;
1732 }
1733 
1734 /*===========================================================================
1735  * FUNCTION   : invalidateBuf
1736  *
1737  * DESCRIPTION: invalidate a specific stream buffer
1738  *
1739  * PARAMETERS :
1740  *   @index   : index of the buffer to invalidate
1741  *
1742  * RETURN     : int32_t type of status
1743  *              NO_ERROR  -- success
1744  *              none-zero failure code
1745  *==========================================================================*/
invalidateBuf(uint32_t index)1746 int32_t QCameraStream::invalidateBuf(uint32_t index)
1747 {
1748     return mStreamBufs->invalidateCache(index);
1749 }
1750 
1751 /*===========================================================================
1752  * FUNCTION   : cleanInvalidateBuf
1753  *
1754  * DESCRIPTION: clean invalidate a specific stream buffer
1755  *
1756  * PARAMETERS :
1757  *   @index   : index of the buffer to clean invalidate
1758  *
1759  * RETURN     : int32_t type of status
1760  *              NO_ERROR  -- success
1761  *              none-zero failure code
1762  *==========================================================================*/
cleanInvalidateBuf(uint32_t index)1763 int32_t QCameraStream::cleanInvalidateBuf(uint32_t index)
1764 {
1765     return mStreamBufs->cleanInvalidateCache(index);
1766 }
1767 
1768 /*===========================================================================
1769  * FUNCTION   : isTypeOf
1770  *
1771  * DESCRIPTION: helper function to determine if the stream is of the queried type
1772  *
1773  * PARAMETERS :
1774  *   @type    : stream type as of queried
1775  *
1776  * RETURN     : true/false
1777  *==========================================================================*/
isTypeOf(cam_stream_type_t type)1778 bool QCameraStream::isTypeOf(cam_stream_type_t type)
1779 {
1780     if (mStreamInfo != NULL && (mStreamInfo->stream_type == type)) {
1781         return true;
1782     } else {
1783         return false;
1784     }
1785 }
1786 
1787 /*===========================================================================
1788  * FUNCTION   : isOrignalTypeOf
1789  *
1790  * DESCRIPTION: helper function to determine if the original stream is of the
1791  *              queried type if it's reproc stream
1792  *
1793  * PARAMETERS :
1794  *   @type    : stream type as of queried
1795  *
1796  * RETURN     : true/false
1797  *==========================================================================*/
isOrignalTypeOf(cam_stream_type_t type)1798 bool QCameraStream::isOrignalTypeOf(cam_stream_type_t type)
1799 {
1800     if (mStreamInfo != NULL &&
1801         mStreamInfo->stream_type == CAM_STREAM_TYPE_OFFLINE_PROC &&
1802         mStreamInfo->reprocess_config.pp_type == CAM_ONLINE_REPROCESS_TYPE &&
1803         mStreamInfo->reprocess_config.online.input_stream_type == type) {
1804         return true;
1805     } else if (
1806         mStreamInfo != NULL &&
1807         mStreamInfo->stream_type == CAM_STREAM_TYPE_OFFLINE_PROC &&
1808         mStreamInfo->reprocess_config.pp_type == CAM_OFFLINE_REPROCESS_TYPE &&
1809         mStreamInfo->reprocess_config.offline.input_type == type) {
1810         return true;
1811     } else {
1812         return false;
1813     }
1814 }
1815 
1816 /*===========================================================================
1817  * FUNCTION   : getMyType
1818  *
1819  * DESCRIPTION: return stream type
1820  *
1821  * PARAMETERS : none
1822  *
1823  * RETURN     : stream type
1824  *==========================================================================*/
getMyType()1825 cam_stream_type_t QCameraStream::getMyType()
1826 {
1827     if (mStreamInfo != NULL) {
1828         return mStreamInfo->stream_type;
1829     } else {
1830         return CAM_STREAM_TYPE_DEFAULT;
1831     }
1832 }
1833 
1834 /*===========================================================================
1835  * FUNCTION   : getMyOriginalType
1836  *
1837  * DESCRIPTION: return stream type
1838  *
1839  * PARAMETERS : none
1840  *
1841  * RETURN     : stream type
1842  *==========================================================================*/
getMyOriginalType()1843 cam_stream_type_t QCameraStream::getMyOriginalType()
1844 {
1845     if (mStreamInfo != NULL) {
1846         if (mStreamInfo->stream_type == CAM_STREAM_TYPE_OFFLINE_PROC &&
1847                 mStreamInfo->reprocess_config.pp_type == CAM_ONLINE_REPROCESS_TYPE) {
1848             return mStreamInfo->reprocess_config.online.input_stream_type;
1849         } else if (mStreamInfo->stream_type == CAM_STREAM_TYPE_OFFLINE_PROC &&
1850                 mStreamInfo->reprocess_config.pp_type == CAM_OFFLINE_REPROCESS_TYPE) {
1851             return mStreamInfo->reprocess_config.offline.input_type;
1852         } else {
1853             return mStreamInfo->stream_type;
1854         }
1855     } else {
1856         return CAM_STREAM_TYPE_DEFAULT;
1857     }
1858 }
1859 
1860 /*===========================================================================
1861  * FUNCTION   : getFrameOffset
1862  *
1863  * DESCRIPTION: query stream buffer frame offset info
1864  *
1865  * PARAMETERS :
1866  *   @offset  : reference to struct to store the queried frame offset info
1867  *
1868  * RETURN     : int32_t type of status
1869  *              NO_ERROR  -- success
1870  *              none-zero failure code
1871  *==========================================================================*/
getFrameOffset(cam_frame_len_offset_t & offset)1872 int32_t QCameraStream::getFrameOffset(cam_frame_len_offset_t &offset)
1873 {
1874     if (NULL == mStreamInfo) {
1875         return NO_INIT;
1876     }
1877 
1878     offset = mFrameLenOffset;
1879     if ((ROTATE_90 == mOnlineRotation) || (ROTATE_270 == mOnlineRotation)) {
1880         // Re-calculate frame offset in case of online rotation
1881         cam_stream_info_t streamInfo = *mStreamInfo;
1882         getFrameDimension(streamInfo.dim);
1883         calcOffset(&streamInfo);
1884         offset = streamInfo.buf_planes.plane_info;
1885     }
1886 
1887     return 0;
1888 }
1889 
1890 /*===========================================================================
1891  * FUNCTION   : getCropInfo
1892  *
1893  * DESCRIPTION: query crop info of the stream
1894  *
1895  * PARAMETERS :
1896  *   @crop    : reference to struct to store the queried crop info
1897  *
1898  * RETURN     : int32_t type of status
1899  *              NO_ERROR  -- success
1900  *              none-zero failure code
1901  *==========================================================================*/
getCropInfo(cam_rect_t & crop)1902 int32_t QCameraStream::getCropInfo(cam_rect_t &crop)
1903 {
1904     pthread_mutex_lock(&mCropLock);
1905     crop = mCropInfo;
1906     pthread_mutex_unlock(&mCropLock);
1907     return NO_ERROR;
1908 }
1909 
1910 /*===========================================================================
1911  * FUNCTION   : setCropInfo
1912  *
1913  * DESCRIPTION: set crop info of the stream
1914  *
1915  * PARAMETERS :
1916  *   @crop    : struct to store new crop info
1917  *
1918  * RETURN     : int32_t type of status
1919  *              NO_ERROR  -- success
1920  *              none-zero failure code
1921  *==========================================================================*/
setCropInfo(cam_rect_t crop)1922 int32_t QCameraStream::setCropInfo(cam_rect_t crop)
1923 {
1924     pthread_mutex_lock(&mCropLock);
1925     mCropInfo = crop;
1926     pthread_mutex_unlock(&mCropLock);
1927     return NO_ERROR;
1928 }
1929 
1930 /*===========================================================================
1931  * FUNCTION   : getFrameDimension
1932  *
1933  * DESCRIPTION: query stream frame dimension info
1934  *
1935  * PARAMETERS :
1936  *   @dim     : reference to struct to store the queried frame dimension
1937  *
1938  * RETURN     : int32_t type of status
1939  *              NO_ERROR  -- success
1940  *              none-zero failure code
1941  *==========================================================================*/
getFrameDimension(cam_dimension_t & dim)1942 int32_t QCameraStream::getFrameDimension(cam_dimension_t &dim)
1943 {
1944     if (mStreamInfo != NULL) {
1945         if ((ROTATE_90 == mOnlineRotation) || (ROTATE_270 == mOnlineRotation)) {
1946             dim.width = mStreamInfo->dim.height;
1947             dim.height = mStreamInfo->dim.width;
1948         } else {
1949             dim = mStreamInfo->dim;
1950         }
1951         return 0;
1952     }
1953     return -1;
1954 }
1955 
1956 /*===========================================================================
1957  * FUNCTION   : getFormat
1958  *
1959  * DESCRIPTION: query stream format
1960  *
1961  * PARAMETERS :
1962  *   @fmt     : reference to stream format
1963  *
1964  * RETURN     : int32_t type of status
1965  *              NO_ERROR  -- success
1966  *              none-zero failure code
1967  *==========================================================================*/
getFormat(cam_format_t & fmt)1968 int32_t QCameraStream::getFormat(cam_format_t &fmt)
1969 {
1970     if (mStreamInfo != NULL) {
1971         fmt = mStreamInfo->fmt;
1972         return 0;
1973     }
1974     return -1;
1975 }
1976 
1977 /*===========================================================================
1978  * FUNCTION   : getMyServerID
1979  *
1980  * DESCRIPTION: query server stream ID
1981  *
1982  * PARAMETERS : None
1983  *
1984  * RETURN     : stream ID from server
1985  *==========================================================================*/
getMyServerID()1986 uint32_t QCameraStream::getMyServerID() {
1987     if (mStreamInfo != NULL) {
1988         return mStreamInfo->stream_svr_id;
1989     } else {
1990         return 0;
1991     }
1992 }
1993 
1994 /*===========================================================================
1995  * FUNCTION   : acquireStreamBufs
1996  *
1997  * DESCRIPTION: acquire stream buffers and postpone their release.
1998  *
1999  * PARAMETERS : None
2000  *
2001  * RETURN     : int32_t type of status
2002  *              NO_ERROR  -- success
2003  *              none-zero failure code
2004  *==========================================================================*/
acquireStreamBufs()2005 int32_t QCameraStream::acquireStreamBufs()
2006 {
2007     mStreamBufsAcquired = true;
2008 
2009     return NO_ERROR;
2010 }
2011 
2012 /*===========================================================================
2013  * FUNCTION   : mapBuf
2014  *
2015  * DESCRIPTION: map stream related buffer to backend server
2016  *
2017  * PARAMETERS :
2018  *   @buf_type : mapping type of buffer
2019  *   @buf_idx  : index of buffer
2020  *   @plane_idx: plane index
2021  *   @fd       : fd of the buffer
2022  *   @size     : lenght of the buffer
2023  *   @ops_tbl    : ptr to buf mapping/unmapping ops
2024  *
2025  * RETURN     : int32_t type of status
2026  *              NO_ERROR  -- success
2027  *              none-zero failure code
2028  *==========================================================================*/
mapBuf(uint8_t buf_type,uint32_t buf_idx,int32_t plane_idx,int fd,size_t size,mm_camera_map_unmap_ops_tbl_t * ops_tbl)2029 int32_t QCameraStream::mapBuf(uint8_t buf_type, uint32_t buf_idx,
2030         int32_t plane_idx, int fd, size_t size, mm_camera_map_unmap_ops_tbl_t *ops_tbl)
2031 {
2032     if (ops_tbl != NULL) {
2033         return ops_tbl->map_ops(buf_idx, plane_idx, fd,
2034                 (uint32_t)size, (cam_mapping_buf_type)buf_type, ops_tbl->userdata);
2035     } else {
2036         return mCamOps->map_stream_buf(mCamHandle, mChannelHandle,
2037                 mHandle, buf_type, buf_idx, plane_idx,
2038                 fd, size);
2039     }
2040 
2041 }
2042 
2043 /*===========================================================================
2044  * FUNCTION   : unmapBuf
2045  *
2046  * DESCRIPTION: unmap stream related buffer to backend server
2047  *
2048  * PARAMETERS :
2049  *   @buf_type : mapping type of buffer
2050  *   @buf_idx  : index of buffer
2051  *   @plane_idx: plane index
2052  *   @ops_tbl    : ptr to buf mapping/unmapping ops
2053  *
2054  * RETURN     : int32_t type of status
2055  *              NO_ERROR  -- success
2056  *              none-zero failure code
2057  *==========================================================================*/
unmapBuf(uint8_t buf_type,uint32_t buf_idx,int32_t plane_idx,mm_camera_map_unmap_ops_tbl_t * ops_tbl)2058 int32_t QCameraStream::unmapBuf(uint8_t buf_type, uint32_t buf_idx, int32_t plane_idx,
2059         mm_camera_map_unmap_ops_tbl_t *ops_tbl)
2060 {
2061     if (ops_tbl != NULL) {
2062         return ops_tbl->unmap_ops(buf_idx, plane_idx,
2063                 (cam_mapping_buf_type)buf_type, ops_tbl->userdata);
2064     } else {
2065         return mCamOps->unmap_stream_buf(mCamHandle, mChannelHandle,
2066                 mHandle, buf_type, buf_idx, plane_idx);
2067     }
2068 }
2069 
2070 /*===========================================================================
2071  * FUNCTION   : setParameter
2072  *
2073  * DESCRIPTION: set stream based parameters
2074  *
2075  * PARAMETERS :
2076  *   @param   : ptr to parameters to be set
2077  *
2078  * RETURN     : int32_t type of status
2079  *              NO_ERROR  -- success
2080  *              none-zero failure code
2081  *==========================================================================*/
setParameter(cam_stream_parm_buffer_t & param)2082 int32_t QCameraStream::setParameter(cam_stream_parm_buffer_t &param)
2083 {
2084     int32_t rc = NO_ERROR;
2085     pthread_mutex_lock(&mParameterLock);
2086     mStreamInfo->parm_buf = param;
2087     rc = mCamOps->set_stream_parms(mCamHandle,
2088                                    mChannelHandle,
2089                                    mHandle,
2090                                    &mStreamInfo->parm_buf);
2091     if (rc == NO_ERROR) {
2092         param = mStreamInfo->parm_buf;
2093     }
2094     pthread_mutex_unlock(&mParameterLock);
2095     return rc;
2096 }
2097 
2098 /*===========================================================================
2099  * FUNCTION   : getParameter
2100  *
2101  * DESCRIPTION: get stream based parameters
2102  *
2103  * PARAMETERS :
2104  *   @param   : ptr to parameters to be red
2105  *
2106  * RETURN     : int32_t type of status
2107  *              NO_ERROR  -- success
2108  *              none-zero failure code
2109  *==========================================================================*/
getParameter(cam_stream_parm_buffer_t & param)2110 int32_t QCameraStream::getParameter(cam_stream_parm_buffer_t &param)
2111 {
2112     int32_t rc = NO_ERROR;
2113     pthread_mutex_lock(&mParameterLock);
2114     mStreamInfo->parm_buf = param;
2115     rc = mCamOps->get_stream_parms(mCamHandle,
2116                                    mChannelHandle,
2117                                    mHandle,
2118                                    &mStreamInfo->parm_buf);
2119     if (rc == NO_ERROR) {
2120         param = mStreamInfo->parm_buf;
2121     }
2122     pthread_mutex_unlock(&mParameterLock);
2123     return rc;
2124 }
2125 
2126 /*===========================================================================
2127  * FUNCTION   : releaseFrameData
2128  *
2129  * DESCRIPTION: callback function to release frame data node
2130  *
2131  * PARAMETERS :
2132  *   @data      : ptr to post process input data
2133  *   @user_data : user data ptr (QCameraReprocessor)
2134  *
2135  * RETURN     : None
2136  *==========================================================================*/
releaseFrameData(void * data,void * user_data)2137 void QCameraStream::releaseFrameData(void *data, void *user_data)
2138 {
2139     QCameraStream *pme = (QCameraStream *)user_data;
2140     mm_camera_super_buf_t *frame = (mm_camera_super_buf_t *)data;
2141     if (NULL != pme) {
2142         pme->bufDone(frame->bufs[0]->buf_idx);
2143     }
2144 }
2145 
2146 /*===========================================================================
2147  * FUNCTION   : configStream
2148  *
2149  * DESCRIPTION: send stream configuration to back end
2150  *
2151  * PARAMETERS :
2152  *
2153  * RETURN     : int32_t type of status
2154  *              NO_ERROR  -- success
2155  *              none-zero failure code
2156  *==========================================================================*/
configStream()2157 int32_t QCameraStream::configStream()
2158 {
2159     int rc = NO_ERROR;
2160 
2161     // Configure the stream
2162     mm_camera_stream_config_t stream_config;
2163     stream_config.stream_info = mStreamInfo;
2164     stream_config.mem_vtbl = mMemVtbl;
2165     stream_config.stream_cb = dataNotifyCB;
2166     stream_config.padding_info = mPaddingInfo;
2167     stream_config.userdata = this;
2168     rc = mCamOps->config_stream(mCamHandle,
2169                 mChannelHandle, mHandle, &stream_config);
2170     if (rc < 0) {
2171         ALOGE("Failed to config stream, rc = %d", rc);
2172         mCamOps->unmap_stream_buf(mCamHandle,
2173                 mChannelHandle,
2174                 mHandle,
2175                 CAM_MAPPING_BUF_TYPE_STREAM_INFO,
2176                 0,
2177                 -1);
2178         return UNKNOWN_ERROR;
2179     }
2180 
2181     return rc;
2182 }
2183 
2184 }; // namespace qcamera
2185