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