• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* Copyright (c) 2012-2014, 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 "QCamera3Stream"
31 //#define LOG_NDEBUG 0
32 
33 #include <utils/Log.h>
34 #include <utils/Errors.h>
35 #include "QCamera3HWI.h"
36 #include "QCamera3Stream.h"
37 #include "QCamera3Channel.h"
38 
39 using namespace android;
40 
41 namespace qcamera {
42 
43 /*===========================================================================
44  * FUNCTION   : get_bufs
45  *
46  * DESCRIPTION: static function entry to allocate stream buffers
47  *
48  * PARAMETERS :
49  *   @offset     : offset info of stream buffers
50  *   @num_bufs   : number of buffers allocated
51  *   @initial_reg_flag: flag to indicate if buffer needs to be registered
52  *                      at kernel initially
53  *   @bufs       : output of allocated buffers
54  *   @ops_tbl    : ptr to buf mapping/unmapping ops
55  *   @user_data  : user data ptr of ops_tbl
56  *
57  * RETURN     : int32_t type of status
58  *              NO_ERROR  -- success
59  *              none-zero failure code
60  *==========================================================================*/
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)61 int32_t QCamera3Stream::get_bufs(
62                      cam_frame_len_offset_t *offset,
63                      uint8_t *num_bufs,
64                      uint8_t **initial_reg_flag,
65                      mm_camera_buf_def_t **bufs,
66                      mm_camera_map_unmap_ops_tbl_t *ops_tbl,
67                      void *user_data)
68 {
69     QCamera3Stream *stream = reinterpret_cast<QCamera3Stream *>(user_data);
70     if (!stream) {
71         ALOGE("getBufs invalid stream pointer");
72         return NO_MEMORY;
73     }
74     return stream->getBufs(offset, num_bufs, initial_reg_flag, bufs, ops_tbl);
75 }
76 
77 /*===========================================================================
78  * FUNCTION   : put_bufs
79  *
80  * DESCRIPTION: static function entry to deallocate stream buffers
81  *
82  * PARAMETERS :
83  *   @ops_tbl    : ptr to buf mapping/unmapping ops
84  *   @user_data  : user data ptr of ops_tbl
85  *
86  * RETURN     : int32_t type of status
87  *              NO_ERROR  -- success
88  *              none-zero failure code
89  *==========================================================================*/
put_bufs(mm_camera_map_unmap_ops_tbl_t * ops_tbl,void * user_data)90 int32_t QCamera3Stream::put_bufs(
91                      mm_camera_map_unmap_ops_tbl_t *ops_tbl,
92                      void *user_data)
93 {
94     QCamera3Stream *stream = reinterpret_cast<QCamera3Stream *>(user_data);
95     if (!stream) {
96         ALOGE("putBufs invalid stream pointer");
97         return NO_MEMORY;
98     }
99     return stream->putBufs(ops_tbl);
100 }
101 
102 /*===========================================================================
103  * FUNCTION   : invalidate_buf
104  *
105  * DESCRIPTION: static function entry to invalidate a specific stream buffer
106  *
107  * PARAMETERS :
108  *   @index      : index of the stream buffer to invalidate
109  *   @user_data  : user data ptr of ops_tbl
110  *
111  * RETURN     : int32_t type of status
112  *              NO_ERROR  -- success
113  *              none-zero failure code
114  *==========================================================================*/
invalidate_buf(int index,void * user_data)115 int32_t QCamera3Stream::invalidate_buf(int index, void *user_data)
116 {
117     QCamera3Stream *stream = reinterpret_cast<QCamera3Stream *>(user_data);
118     if (!stream) {
119         ALOGE("invalid stream pointer");
120         return NO_MEMORY;
121     }
122     return stream->invalidateBuf(index);
123 }
124 
125 /*===========================================================================
126  * FUNCTION   : clean_invalidate_buf
127  *
128  * DESCRIPTION: static function entry to clean and invalidate a specific stream buffer
129  *
130  * PARAMETERS :
131  *   @index      : index of the stream buffer to invalidate
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  *==========================================================================*/
clean_invalidate_buf(int index,void * user_data)138 int32_t QCamera3Stream::clean_invalidate_buf(int index, void *user_data)
139 {
140     QCamera3Stream *stream = reinterpret_cast<QCamera3Stream *>(user_data);
141     if (!stream) {
142         ALOGE("invalid stream pointer");
143         return NO_MEMORY;
144     }
145     return stream->cleanInvalidateBuf(index);
146 }
147 
148 /*===========================================================================
149  * FUNCTION   : QCamera3Stream
150  *
151  * DESCRIPTION: constructor of QCamera3Stream
152  *
153  * PARAMETERS :
154  *   @allocator  : memory allocator obj
155  *   @camHandle  : camera handle
156  *   @chId       : channel handle
157  *   @camOps     : ptr to camera ops table
158  *   @paddingInfo: ptr to padding info
159  *
160  * RETURN     : None
161  *==========================================================================*/
QCamera3Stream(uint32_t camHandle,uint32_t chId,mm_camera_ops_t * camOps,cam_padding_info_t * paddingInfo,QCamera3Channel * channel)162 QCamera3Stream::QCamera3Stream(uint32_t camHandle,
163                              uint32_t chId,
164                              mm_camera_ops_t *camOps,
165                              cam_padding_info_t *paddingInfo,
166                              QCamera3Channel *channel) :
167         mCamHandle(camHandle),
168         mChannelHandle(chId),
169         mHandle(0),
170         mCamOps(camOps),
171         mStreamInfo(NULL),
172         mMemOps(NULL),
173         mNumBufs(0),
174         mDataCB(NULL),
175         mUserData(NULL),
176         mDataQ(releaseFrameData, this),
177         mStreamInfoBuf(NULL),
178         mStreamBufs(NULL),
179         mBufDefs(NULL),
180         mChannel(channel),
181         m_bActive(false)
182 {
183     mMemVtbl.user_data = this;
184     mMemVtbl.get_bufs = get_bufs;
185     mMemVtbl.put_bufs = put_bufs;
186     mMemVtbl.invalidate_buf = invalidate_buf;
187     mMemVtbl.clean_invalidate_buf = clean_invalidate_buf;
188     memset(&mFrameLenOffset, 0, sizeof(mFrameLenOffset));
189     memcpy(&mPaddingInfo, paddingInfo, sizeof(cam_padding_info_t));
190 }
191 
192 /*===========================================================================
193  * FUNCTION   : ~QCamera3Stream
194  *
195  * DESCRIPTION: deconstructor of QCamera3Stream
196  *
197  * PARAMETERS : None
198  *
199  * RETURN     : None
200  *==========================================================================*/
~QCamera3Stream()201 QCamera3Stream::~QCamera3Stream()
202 {
203     if (mStreamInfoBuf != NULL) {
204         int rc = mCamOps->unmap_stream_buf(mCamHandle,
205                     mChannelHandle, mHandle, CAM_MAPPING_BUF_TYPE_STREAM_INFO, 0, -1);
206         if (rc < 0) {
207             ALOGE("Failed to map stream info buffer");
208         }
209         mStreamInfoBuf->deallocate();
210         delete mStreamInfoBuf;
211         mStreamInfoBuf = NULL;
212     }
213 
214     // delete stream
215     if (mHandle > 0) {
216         mCamOps->delete_stream(mCamHandle, mChannelHandle, mHandle);
217         mHandle = 0;
218     }
219 }
220 
221 /*===========================================================================
222  * FUNCTION   : init
223  *
224  * DESCRIPTION: initialize stream obj
225  *
226  * PARAMETERS :
227  *   @streamInfoBuf: ptr to buf that contains stream info
228  *   @stream_cb    : stream data notify callback. Can be NULL if not needed
229  *   @userdata     : user data ptr
230  *
231  * RETURN     : int32_t type of status
232  *              NO_ERROR  -- success
233  *              none-zero failure code
234  *==========================================================================*/
init(cam_stream_type_t streamType,cam_format_t streamFormat,cam_dimension_t streamDim,cam_stream_reproc_config_t * reprocess_config,uint8_t minNumBuffers,stream_cb_routine stream_cb,void * userdata)235 int32_t QCamera3Stream::init(cam_stream_type_t streamType,
236                             cam_format_t streamFormat,
237                             cam_dimension_t streamDim,
238                             cam_stream_reproc_config_t* reprocess_config,
239                             uint8_t minNumBuffers,
240                             stream_cb_routine stream_cb,
241                             void *userdata)
242 {
243     int32_t rc = OK;
244     mm_camera_stream_config_t stream_config;
245 
246     mHandle = mCamOps->add_stream(mCamHandle, mChannelHandle);
247     if (!mHandle) {
248         ALOGE("add_stream failed");
249         rc = UNKNOWN_ERROR;
250         goto done;
251     }
252 
253     // allocate and map stream info memory
254     mStreamInfoBuf = new QCamera3HeapMemory();
255     if (mStreamInfoBuf == NULL) {
256         ALOGE("%s: no memory for stream info buf obj", __func__);
257         rc = -ENOMEM;
258         goto err1;
259     }
260     rc = mStreamInfoBuf->allocate(1, sizeof(cam_stream_info_t), false);
261     if (rc < 0) {
262         ALOGE("%s: no memory for stream info", __func__);
263         rc = -ENOMEM;
264         goto err2;
265     }
266 
267     mStreamInfo =
268         reinterpret_cast<cam_stream_info_t *>(mStreamInfoBuf->getPtr(0));
269     memset(mStreamInfo, 0, sizeof(cam_stream_info_t));
270     mStreamInfo->stream_type = streamType;
271     mStreamInfo->fmt = streamFormat;
272     mStreamInfo->dim = streamDim;
273     mStreamInfo->num_bufs = minNumBuffers;
274 
275     rc = mCamOps->map_stream_buf(mCamHandle,
276             mChannelHandle, mHandle, CAM_MAPPING_BUF_TYPE_STREAM_INFO,
277             0, -1, mStreamInfoBuf->getFd(0), mStreamInfoBuf->getSize(0));
278     if (rc < 0) {
279         ALOGE("Failed to map stream info buffer");
280         goto err3;
281     }
282 
283     mNumBufs = minNumBuffers;
284     if (reprocess_config != NULL) {
285        mStreamInfo->reprocess_config = *reprocess_config;
286        mStreamInfo->streaming_mode = CAM_STREAMING_MODE_BURST;
287        //mStreamInfo->num_of_burst = reprocess_config->offline.num_of_bufs;
288        mStreamInfo->num_of_burst = 1;
289        ALOGI("%s: num_of_burst is %d", __func__, mStreamInfo->num_of_burst);
290     } else {
291        mStreamInfo->streaming_mode = CAM_STREAMING_MODE_CONTINUOUS;
292     }
293 
294     // Configure the stream
295     stream_config.stream_info = mStreamInfo;
296     stream_config.mem_vtbl = mMemVtbl;
297     stream_config.padding_info = mPaddingInfo;
298     stream_config.userdata = this;
299     stream_config.stream_cb = dataNotifyCB;
300 
301     rc = mCamOps->config_stream(mCamHandle,
302             mChannelHandle, mHandle, &stream_config);
303     if (rc < 0) {
304         ALOGE("Failed to config stream, rc = %d", rc);
305         goto err4;
306     }
307 
308     mDataCB = stream_cb;
309     mUserData = userdata;
310     return 0;
311 
312 err4:
313     mCamOps->unmap_stream_buf(mCamHandle,
314             mChannelHandle, mHandle, CAM_MAPPING_BUF_TYPE_STREAM_INFO, 0, -1);
315 err3:
316     mStreamInfoBuf->deallocate();
317 err2:
318     delete mStreamInfoBuf;
319     mStreamInfoBuf = NULL;
320     mStreamInfo = NULL;
321 err1:
322     mCamOps->delete_stream(mCamHandle, mChannelHandle, mHandle);
323     mHandle = 0;
324     mNumBufs = 0;
325 done:
326     return rc;
327 }
328 
329 /*===========================================================================
330  * FUNCTION   : start
331  *
332  * DESCRIPTION: start stream. Will start main stream thread to handle stream
333  *              related ops.
334  *
335  * PARAMETERS : none
336  *
337  * RETURN     : int32_t type of status
338  *              NO_ERROR  -- success
339  *              none-zero failure code
340  *==========================================================================*/
start()341 int32_t QCamera3Stream::start()
342 {
343     int32_t rc = 0;
344     rc = mProcTh.launch(dataProcRoutine, this);
345     if (rc == NO_ERROR) {
346         m_bActive = true;
347     }
348     return rc;
349 }
350 
351 /*===========================================================================
352  * FUNCTION   : stop
353  *
354  * DESCRIPTION: stop stream. Will stop main stream thread
355  *
356  * PARAMETERS : none
357  *
358  * RETURN     : int32_t type of status
359  *              NO_ERROR  -- success
360  *              none-zero failure code
361  *==========================================================================*/
stop()362 int32_t QCamera3Stream::stop()
363 {
364     int32_t rc = 0;
365     rc = mProcTh.exit();
366     m_bActive = false;
367     return rc;
368 }
369 
370 /*===========================================================================
371  * FUNCTION   : processDataNotify
372  *
373  * DESCRIPTION: process stream data notify
374  *
375  * PARAMETERS :
376  *   @frame   : stream frame received
377  *
378  * RETURN     : int32_t type of status
379  *              NO_ERROR  -- success
380  *              none-zero failure code
381  *==========================================================================*/
processDataNotify(mm_camera_super_buf_t * frame)382 int32_t QCamera3Stream::processDataNotify(mm_camera_super_buf_t *frame)
383 {
384     ALOGV("%s: E\n", __func__);
385     int32_t rc;
386     if (m_bActive) {
387         mDataQ.enqueue((void *)frame);
388         rc = mProcTh.sendCmd(CAMERA_CMD_TYPE_DO_NEXT_JOB, FALSE, FALSE);
389     } else {
390         ALOGD("%s: Stream thread is not active, no ops here", __func__);
391         bufDone(frame->bufs[0]->buf_idx);
392         free(frame);
393         rc = NO_ERROR;
394     }
395     ALOGV("%s: X\n", __func__);
396     return rc;
397 }
398 
399 /*===========================================================================
400  * FUNCTION   : dataNotifyCB
401  *
402  * DESCRIPTION: callback for data notify. This function is registered with
403  *              mm-camera-interface to handle data notify
404  *
405  * PARAMETERS :
406  *   @recvd_frame   : stream frame received
407  *   userdata       : user data ptr
408  *
409  * RETURN     : none
410  *==========================================================================*/
dataNotifyCB(mm_camera_super_buf_t * recvd_frame,void * userdata)411 void QCamera3Stream::dataNotifyCB(mm_camera_super_buf_t *recvd_frame,
412                                  void *userdata)
413 {
414     ALOGV("%s: E\n", __func__);
415     QCamera3Stream* stream = (QCamera3Stream *)userdata;
416     if (stream == NULL ||
417         recvd_frame == NULL ||
418         recvd_frame->bufs[0] == NULL ||
419         recvd_frame->bufs[0]->stream_id != stream->getMyHandle()) {
420         ALOGE("%s: Not a valid stream to handle buf", __func__);
421         return;
422     }
423 
424     mm_camera_super_buf_t *frame =
425         (mm_camera_super_buf_t *)malloc(sizeof(mm_camera_super_buf_t));
426     if (frame == NULL) {
427         ALOGE("%s: No mem for mm_camera_buf_def_t", __func__);
428         stream->bufDone(recvd_frame->bufs[0]->buf_idx);
429         return;
430     }
431     *frame = *recvd_frame;
432     stream->processDataNotify(frame);
433     return;
434 }
435 
436 /*===========================================================================
437  * FUNCTION   : dataProcRoutine
438  *
439  * DESCRIPTION: function to process data in the main stream thread
440  *
441  * PARAMETERS :
442  *   @data    : user data ptr
443  *
444  * RETURN     : none
445  *==========================================================================*/
dataProcRoutine(void * data)446 void *QCamera3Stream::dataProcRoutine(void *data)
447 {
448     int running = 1;
449     int ret;
450     QCamera3Stream *pme = (QCamera3Stream *)data;
451     QCameraCmdThread *cmdThread = &pme->mProcTh;
452     cmdThread->setName("cam_stream_proc");
453 
454     ALOGV("%s: E", __func__);
455     do {
456         do {
457             ret = cam_sem_wait(&cmdThread->cmd_sem);
458             if (ret != 0 && errno != EINVAL) {
459                 ALOGE("%s: cam_sem_wait error (%s)",
460                       __func__, strerror(errno));
461                 return NULL;
462             }
463         } while (ret != 0);
464 
465         // we got notified about new cmd avail in cmd queue
466         camera_cmd_type_t cmd = cmdThread->getCmd();
467         switch (cmd) {
468         case CAMERA_CMD_TYPE_DO_NEXT_JOB:
469             {
470                 ALOGV("%s: Do next job", __func__);
471                 mm_camera_super_buf_t *frame =
472                     (mm_camera_super_buf_t *)pme->mDataQ.dequeue();
473                 if (NULL != frame) {
474                     if (pme->mDataCB != NULL) {
475                         pme->mDataCB(frame, pme, pme->mUserData);
476                     } else {
477                         // no data cb routine, return buf here
478                         pme->bufDone(frame->bufs[0]->buf_idx);
479                     }
480                 }
481             }
482             break;
483         case CAMERA_CMD_TYPE_EXIT:
484             ALOGD("%s: Exit", __func__);
485             /* flush data buf queue */
486             pme->mDataQ.flush();
487             running = 0;
488             break;
489         default:
490             break;
491         }
492     } while (running);
493     ALOGV("%s: X", __func__);
494     return NULL;
495 }
496 
497 /*===========================================================================
498  * FUNCTION   : getInternalFormatBuffer
499  *
500  * DESCRIPTION: return buffer in the internal format structure
501  *
502  * PARAMETERS :
503  *   @index   : index of buffer to be returned
504  *
505  * RETURN     : int32_t type of status
506  *              NO_ERROR  -- success
507  *              none-zero failure code
508  *==========================================================================*/
getInternalFormatBuffer(int index)509 mm_camera_buf_def_t* QCamera3Stream::getInternalFormatBuffer(int index)
510 {
511     mm_camera_buf_def_t *rc = NULL;
512     if ((index >= mNumBufs) || (mBufDefs == NULL) ||
513             (NULL == mBufDefs[index].mem_info)) {
514         ALOGE("%s:Index out of range/no internal buffers yet", __func__);
515         return NULL;
516     }
517 
518     rc = (mm_camera_buf_def_t*)malloc(sizeof(mm_camera_buf_def_t));
519     if(rc) {
520         memcpy(rc, &mBufDefs[index], sizeof(mm_camera_buf_def_t));
521     } else {
522         ALOGE("%s: Failed to allocate memory",__func__);
523     }
524     return rc;
525 }
526 
527 /*===========================================================================
528  * FUNCTION   : bufDone
529  *
530  * DESCRIPTION: return stream buffer to kernel
531  *
532  * PARAMETERS :
533  *   @index   : index of buffer to be returned
534  *
535  * RETURN     : int32_t type of status
536  *              NO_ERROR  -- success
537  *              none-zero failure code
538  *==========================================================================*/
bufDone(int index)539 int32_t QCamera3Stream::bufDone(int index)
540 {
541     int32_t rc = NO_ERROR;
542 
543     if (index >= mNumBufs || mBufDefs == NULL)
544         return BAD_INDEX;
545 
546     if( NULL == mBufDefs[index].mem_info) {
547         if (NULL == mMemOps) {
548             ALOGE("%s: Camera operations not initialized", __func__);
549             return NO_INIT;
550         }
551 
552         rc = mMemOps->map_ops(index, -1, mStreamBufs->getFd(index),
553                 mStreamBufs->getSize(index), mMemOps->userdata);
554         if (rc < 0) {
555             ALOGE("%s: Failed to map camera buffer %d", __func__, index);
556             return rc;
557         }
558 
559         rc = mStreamBufs->getBufDef(mFrameLenOffset, mBufDefs[index], index);
560         if (NO_ERROR != rc) {
561             ALOGE("%s: Couldn't find camera buffer definition", __func__);
562             mMemOps->unmap_ops(index, -1, mMemOps->userdata);
563             return rc;
564         }
565     }
566 
567     rc = mCamOps->qbuf(mCamHandle, mChannelHandle, &mBufDefs[index]);
568     if (rc < 0)
569         return FAILED_TRANSACTION;
570 
571     return rc;
572 }
573 
574 /*===========================================================================
575  * FUNCTION   : getBufs
576  *
577  * DESCRIPTION: allocate stream buffers
578  *
579  * PARAMETERS :
580  *   @offset     : offset info of stream buffers
581  *   @num_bufs   : number of buffers allocated
582  *   @initial_reg_flag: flag to indicate if buffer needs to be registered
583  *                      at kernel initially
584  *   @bufs       : output of allocated buffers
585  *   @ops_tbl    : ptr to buf mapping/unmapping ops
586  *
587  * RETURN     : int32_t type of status
588  *              NO_ERROR  -- success
589  *              none-zero failure code
590  *==========================================================================*/
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)591 int32_t QCamera3Stream::getBufs(cam_frame_len_offset_t *offset,
592                      uint8_t *num_bufs,
593                      uint8_t **initial_reg_flag,
594                      mm_camera_buf_def_t **bufs,
595                      mm_camera_map_unmap_ops_tbl_t *ops_tbl)
596 {
597     int rc = NO_ERROR;
598     uint8_t *regFlags;
599 
600     if (!ops_tbl) {
601         ALOGE("%s: ops_tbl is NULL", __func__);
602         return INVALID_OPERATION;
603     }
604 
605     mFrameLenOffset = *offset;
606     mMemOps = ops_tbl;
607 
608     mStreamBufs = mChannel->getStreamBufs(mFrameLenOffset.frame_len);
609     if (!mStreamBufs) {
610         ALOGE("%s: Failed to allocate stream buffers", __func__);
611         return NO_MEMORY;
612     }
613 
614     int registeredBuffers = mStreamBufs->getCnt();
615     for (int i = 0; i < registeredBuffers; i++) {
616         rc = ops_tbl->map_ops(i, -1, mStreamBufs->getFd(i),
617                 mStreamBufs->getSize(i), ops_tbl->userdata);
618         if (rc < 0) {
619             ALOGE("%s: map_stream_buf failed: %d", __func__, rc);
620             for (int j = 0; j < i; j++) {
621                 ops_tbl->unmap_ops(j, -1, ops_tbl->userdata);
622             }
623             return INVALID_OPERATION;
624         }
625     }
626 
627     //regFlags array is allocated by us, but consumed and freed by mm-camera-interface
628     regFlags = (uint8_t *)malloc(sizeof(uint8_t) * mNumBufs);
629     if (!regFlags) {
630         ALOGE("%s: Out of memory", __func__);
631         for (int i = 0; i < registeredBuffers; i++) {
632             ops_tbl->unmap_ops(i, -1, ops_tbl->userdata);
633         }
634         return NO_MEMORY;
635     }
636     memset(regFlags, 0, sizeof(uint8_t) * mNumBufs);
637 
638     mBufDefs = (mm_camera_buf_def_t *)malloc(mNumBufs * sizeof(mm_camera_buf_def_t));
639     if (mBufDefs == NULL) {
640         ALOGE("%s: Failed to allocate mm_camera_buf_def_t %d", __func__, rc);
641         for (int i = 0; i < registeredBuffers; i++) {
642             ops_tbl->unmap_ops(i, -1, ops_tbl->userdata);
643         }
644         free(regFlags);
645         regFlags = NULL;
646         return INVALID_OPERATION;
647     }
648     memset(mBufDefs, 0, mNumBufs * sizeof(mm_camera_buf_def_t));
649     for (int i = 0; i < registeredBuffers; i++) {
650         mStreamBufs->getBufDef(mFrameLenOffset, mBufDefs[i], i);
651     }
652 
653     rc = mStreamBufs->getRegFlags(regFlags);
654     if (rc < 0) {
655         ALOGE("%s: getRegFlags failed %d", __func__, rc);
656         for (int i = 0; i < registeredBuffers; i++) {
657             ops_tbl->unmap_ops(i, -1, ops_tbl->userdata);
658         }
659         free(mBufDefs);
660         mBufDefs = NULL;
661         free(regFlags);
662         regFlags = NULL;
663         return INVALID_OPERATION;
664     }
665 
666     *num_bufs = mNumBufs;
667     *initial_reg_flag = regFlags;
668     *bufs = mBufDefs;
669     return NO_ERROR;
670 }
671 
672 /*===========================================================================
673  * FUNCTION   : putBufs
674  *
675  * DESCRIPTION: deallocate stream buffers
676  *
677  * PARAMETERS :
678  *   @ops_tbl    : ptr to buf mapping/unmapping ops
679  *
680  * RETURN     : int32_t type of status
681  *              NO_ERROR  -- success
682  *              none-zero failure code
683  *==========================================================================*/
putBufs(mm_camera_map_unmap_ops_tbl_t * ops_tbl)684 int32_t QCamera3Stream::putBufs(mm_camera_map_unmap_ops_tbl_t *ops_tbl)
685 {
686     int rc = NO_ERROR;
687     for (int i = 0; i < mNumBufs; i++) {
688         if (NULL != mBufDefs[i].mem_info) {
689             rc = ops_tbl->unmap_ops(i, -1, ops_tbl->userdata);
690             if (rc < 0) {
691                 ALOGE("%s: map_stream_buf failed: %d", __func__, rc);
692             }
693         }
694     }
695     mBufDefs = NULL; // mBufDefs just keep a ptr to the buffer
696                      // mm-camera-interface own the buffer, so no need to free
697     memset(&mFrameLenOffset, 0, sizeof(mFrameLenOffset));
698     mChannel->putStreamBufs();
699 
700     return rc;
701 }
702 
703 /*===========================================================================
704  * FUNCTION   : invalidateBuf
705  *
706  * DESCRIPTION: invalidate a specific stream buffer
707  *
708  * PARAMETERS :
709  *   @index   : index of the buffer to invalidate
710  *
711  * RETURN     : int32_t type of status
712  *              NO_ERROR  -- success
713  *              none-zero failure code
714  *==========================================================================*/
invalidateBuf(int index)715 int32_t QCamera3Stream::invalidateBuf(int index)
716 {
717     return mStreamBufs->invalidateCache(index);
718 }
719 
720 /*===========================================================================
721  * FUNCTION   : cleanInvalidateBuf
722  *
723  * DESCRIPTION: clean and invalidate a specific stream buffer
724  *
725  * PARAMETERS :
726  *   @index   : index of the buffer to invalidate
727  *
728  * RETURN     : int32_t type of status
729  *              NO_ERROR  -- success
730  *              none-zero failure code
731  *==========================================================================*/
cleanInvalidateBuf(int index)732 int32_t QCamera3Stream::cleanInvalidateBuf(int index)
733 {
734     return mStreamBufs->cleanInvalidateCache(index);
735 }
736 
737 /*===========================================================================
738  * FUNCTION   : getFrameOffset
739  *
740  * DESCRIPTION: query stream buffer frame offset info
741  *
742  * PARAMETERS :
743  *   @offset  : reference to struct to store the queried frame offset info
744  *
745  * RETURN     : int32_t type of status
746  *              NO_ERROR  -- success
747  *              none-zero failure code
748  *==========================================================================*/
getFrameOffset(cam_frame_len_offset_t & offset)749 int32_t QCamera3Stream::getFrameOffset(cam_frame_len_offset_t &offset)
750 {
751     offset = mFrameLenOffset;
752     return 0;
753 }
754 
755 /*===========================================================================
756  * FUNCTION   : getFrameDimension
757  *
758  * DESCRIPTION: query stream frame dimension info
759  *
760  * PARAMETERS :
761  *   @dim     : reference to struct to store the queried frame dimension
762  *
763  * RETURN     : int32_t type of status
764  *              NO_ERROR  -- success
765  *              none-zero failure code
766  *==========================================================================*/
getFrameDimension(cam_dimension_t & dim)767 int32_t QCamera3Stream::getFrameDimension(cam_dimension_t &dim)
768 {
769     if (mStreamInfo != NULL) {
770         dim = mStreamInfo->dim;
771         return 0;
772     }
773     return -1;
774 }
775 
776 /*===========================================================================
777  * FUNCTION   : getFormat
778  *
779  * DESCRIPTION: query stream format
780  *
781  * PARAMETERS :
782  *   @fmt     : reference to stream format
783  *
784  * RETURN     : int32_t type of status
785  *              NO_ERROR  -- success
786  *              none-zero failure code
787  *==========================================================================*/
getFormat(cam_format_t & fmt)788 int32_t QCamera3Stream::getFormat(cam_format_t &fmt)
789 {
790     if (mStreamInfo != NULL) {
791         fmt = mStreamInfo->fmt;
792         return 0;
793     }
794     return -1;
795 }
796 
797 /*===========================================================================
798  * FUNCTION   : getMyServerID
799  *
800  * DESCRIPTION: query server stream ID
801  *
802  * PARAMETERS : None
803  *
804  * RETURN     : stream ID from server
805  *==========================================================================*/
getMyServerID()806 uint32_t QCamera3Stream::getMyServerID() {
807     if (mStreamInfo != NULL) {
808         return mStreamInfo->stream_svr_id;
809     } else {
810         return 0;
811     }
812 }
813 
814 /*===========================================================================
815  * FUNCTION   : getMyType
816  *
817  * DESCRIPTION: query stream type
818  *
819  * PARAMETERS : None
820  *
821  * RETURN     : type of stream
822  *==========================================================================*/
getMyType() const823 cam_stream_type_t QCamera3Stream::getMyType() const
824 {
825     if (mStreamInfo != NULL) {
826         return mStreamInfo->stream_type;
827     } else {
828         return CAM_STREAM_TYPE_MAX;
829     }
830 }
831 
832 /*===========================================================================
833  * FUNCTION   : mapBuf
834  *
835  * DESCRIPTION: map stream related buffer to backend server
836  *
837  * PARAMETERS :
838  *   @buf_type : mapping type of buffer
839  *   @buf_idx  : index of buffer
840  *   @plane_idx: plane index
841  *   @fd       : fd of the buffer
842  *   @size     : lenght of the buffer
843  *
844  * RETURN     : int32_t type of status
845  *              NO_ERROR  -- success
846  *              none-zero failure code
847  *==========================================================================*/
mapBuf(uint8_t buf_type,uint32_t buf_idx,int32_t plane_idx,int fd,uint32_t size)848 int32_t QCamera3Stream::mapBuf(uint8_t buf_type,
849                               uint32_t buf_idx,
850                               int32_t plane_idx,
851                               int fd,
852                               uint32_t size)
853 {
854     return mCamOps->map_stream_buf(mCamHandle, mChannelHandle,
855                                    mHandle, buf_type,
856                                    buf_idx, plane_idx,
857                                    fd, size);
858 
859 }
860 
861 /*===========================================================================
862  * FUNCTION   : unmapBuf
863  *
864  * DESCRIPTION: unmap stream related buffer to backend server
865  *
866  * PARAMETERS :
867  *   @buf_type : mapping type of buffer
868  *   @buf_idx  : index of buffer
869  *   @plane_idx: plane index
870  *
871  * RETURN     : int32_t type of status
872  *              NO_ERROR  -- success
873  *              none-zero failure code
874  *==========================================================================*/
unmapBuf(uint8_t buf_type,uint32_t buf_idx,int32_t plane_idx)875 int32_t QCamera3Stream::unmapBuf(uint8_t buf_type, uint32_t buf_idx, int32_t plane_idx)
876 {
877     return mCamOps->unmap_stream_buf(mCamHandle, mChannelHandle,
878                                      mHandle, buf_type,
879                                      buf_idx, plane_idx);
880 }
881 
882 /*===========================================================================
883  * FUNCTION   : setParameter
884  *
885  * DESCRIPTION: set stream based parameters
886  *
887  * PARAMETERS :
888  *   @param   : ptr to parameters to be set
889  *
890  * RETURN     : int32_t type of status
891  *              NO_ERROR  -- success
892  *              none-zero failure code
893  *==========================================================================*/
setParameter(cam_stream_parm_buffer_t & param)894 int32_t QCamera3Stream::setParameter(cam_stream_parm_buffer_t &param)
895 {
896     int32_t rc = NO_ERROR;
897     mStreamInfo->parm_buf = param;
898     rc = mCamOps->set_stream_parms(mCamHandle,
899                                    mChannelHandle,
900                                    mHandle,
901                                    &mStreamInfo->parm_buf);
902     if (rc == NO_ERROR) {
903         param = mStreamInfo->parm_buf;
904     }
905     return rc;
906 }
907 
908 /*===========================================================================
909  * FUNCTION   : releaseFrameData
910  *
911  * DESCRIPTION: callback function to release frame data node
912  *
913  * PARAMETERS :
914  *   @data      : ptr to post process input data
915  *   @user_data : user data ptr (QCameraReprocessor)
916  *
917  * RETURN     : None
918  *==========================================================================*/
releaseFrameData(void * data,void * user_data)919 void QCamera3Stream::releaseFrameData(void *data, void *user_data)
920 {
921     QCamera3Stream *pme = (QCamera3Stream *)user_data;
922     mm_camera_super_buf_t *frame = (mm_camera_super_buf_t *)data;
923     if (NULL != pme) {
924         pme->bufDone(frame->bufs[0]->buf_idx);
925     }
926 }
927 
928 }; // namespace qcamera
929