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