1 /* Copyright (c) 2012-2015, The Linux Foundataion. All rights reserved.
2 *
3 * Redistribution and use in source and binary forms, with or without
4 * modification, are permitted provided that the following conditions are
5 * met:
6 * * Redistributions of source code must retain the above copyright
7 * notice, this list of conditions and the following disclaimer.
8 * * Redistributions in binary form must reproduce the above
9 * copyright notice, this list of conditions and the following
10 * disclaimer in the documentation and/or other materials provided
11 * with the distribution.
12 * * Neither the name of The Linux Foundation nor the names of its
13 * contributors may be used to endorse or promote products derived
14 * from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
23 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
25 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
26 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 *
28 */
29
30 #define LOG_TAG "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 un-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 : bufDone
500 *
501 * DESCRIPTION: return stream buffer to kernel
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 *==========================================================================*/
bufDone(int index)510 int32_t QCamera3Stream::bufDone(int index)
511 {
512 int32_t rc = NO_ERROR;
513 Mutex::Autolock lock(mLock);
514
515 if ((index >= mNumBufs) || (mBufDefs == NULL)) {
516 return BAD_INDEX;
517 }
518
519 if( NULL == mBufDefs[index].mem_info) {
520 if (NULL == mMemOps) {
521 ALOGE("%s: Camera operations not initialized", __func__);
522 return NO_INIT;
523 }
524
525 rc = mMemOps->map_ops(index, -1, mStreamBufs->getFd(index),
526 mStreamBufs->getSize(index), mMemOps->userdata);
527 if (rc < 0) {
528 ALOGE("%s: Failed to map camera buffer %d", __func__, index);
529 return rc;
530 }
531
532 rc = mStreamBufs->getBufDef(mFrameLenOffset, mBufDefs[index], index);
533 if (NO_ERROR != rc) {
534 ALOGE("%s: Couldn't find camera buffer definition", __func__);
535 mMemOps->unmap_ops(index, -1, mMemOps->userdata);
536 return rc;
537 }
538 }
539
540 rc = mCamOps->qbuf(mCamHandle, mChannelHandle, &mBufDefs[index]);
541 if (rc < 0) {
542 return FAILED_TRANSACTION;
543 }
544
545 return rc;
546 }
547
548 /*===========================================================================
549 * FUNCTION : bufRelease
550 *
551 * DESCRIPTION: release all resources associated with this buffer
552 *
553 * PARAMETERS :
554 * @index : index of buffer to be released
555 *
556 * RETURN : int32_t type of status
557 * NO_ERROR -- success
558 * none-zero failure code
559 *==========================================================================*/
bufRelease(int32_t index)560 int32_t QCamera3Stream::bufRelease(int32_t index)
561 {
562 int32_t rc = NO_ERROR;
563 Mutex::Autolock lock(mLock);
564
565 if ((index >= mNumBufs) || (mBufDefs == NULL)) {
566 return BAD_INDEX;
567 }
568
569 if (NULL != mBufDefs[index].mem_info) {
570 if (NULL == mMemOps) {
571 ALOGE("%s: Camera operations not initialized", __func__);
572 return NO_INIT;
573 }
574
575 rc = mMemOps->unmap_ops(index, -1, mMemOps->userdata);
576 if (rc < 0) {
577 ALOGE("%s: Failed to un-map camera buffer %d", __func__, index);
578 return rc;
579 }
580
581 mBufDefs[index].mem_info = NULL;
582 } else {
583 ALOGE("%s: Buffer at index %d not registered", __func__, index);
584 return BAD_INDEX;
585 }
586
587 return rc;
588 }
589
590 /*===========================================================================
591 * FUNCTION : getBufs
592 *
593 * DESCRIPTION: allocate stream buffers
594 *
595 * PARAMETERS :
596 * @offset : offset info of stream buffers
597 * @num_bufs : number of buffers allocated
598 * @initial_reg_flag: flag to indicate if buffer needs to be registered
599 * at kernel initially
600 * @bufs : output of allocated buffers
601 * @ops_tbl : ptr to buf mapping/unmapping ops
602 *
603 * RETURN : int32_t type of status
604 * NO_ERROR -- success
605 * none-zero failure code
606 *==========================================================================*/
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)607 int32_t QCamera3Stream::getBufs(cam_frame_len_offset_t *offset,
608 uint8_t *num_bufs,
609 uint8_t **initial_reg_flag,
610 mm_camera_buf_def_t **bufs,
611 mm_camera_map_unmap_ops_tbl_t *ops_tbl)
612 {
613 int rc = NO_ERROR;
614 uint8_t *regFlags;
615 Mutex::Autolock lock(mLock);
616
617 if (!ops_tbl) {
618 ALOGE("%s: ops_tbl is NULL", __func__);
619 return INVALID_OPERATION;
620 }
621
622 mFrameLenOffset = *offset;
623 mMemOps = ops_tbl;
624
625 mStreamBufs = mChannel->getStreamBufs(mFrameLenOffset.frame_len);
626 if (!mStreamBufs) {
627 ALOGE("%s: Failed to allocate stream buffers", __func__);
628 return NO_MEMORY;
629 }
630
631 int registeredBuffers = mStreamBufs->getCnt();
632 for (int i = 0; i < registeredBuffers; i++) {
633 rc = ops_tbl->map_ops(i, -1, mStreamBufs->getFd(i),
634 mStreamBufs->getSize(i), ops_tbl->userdata);
635 if (rc < 0) {
636 ALOGE("%s: map_stream_buf failed: %d", __func__, rc);
637 for (int j = 0; j < i; j++) {
638 ops_tbl->unmap_ops(j, -1, ops_tbl->userdata);
639 }
640 return INVALID_OPERATION;
641 }
642 }
643
644 //regFlags array is allocated by us, but consumed and freed by mm-camera-interface
645 regFlags = (uint8_t *)malloc(sizeof(uint8_t) * mNumBufs);
646 if (!regFlags) {
647 ALOGE("%s: Out of memory", __func__);
648 for (int i = 0; i < registeredBuffers; i++) {
649 ops_tbl->unmap_ops(i, -1, ops_tbl->userdata);
650 }
651 return NO_MEMORY;
652 }
653 memset(regFlags, 0, sizeof(uint8_t) * mNumBufs);
654
655 mBufDefs = (mm_camera_buf_def_t *)malloc(mNumBufs * sizeof(mm_camera_buf_def_t));
656 if (mBufDefs == NULL) {
657 ALOGE("%s: Failed to allocate mm_camera_buf_def_t %d", __func__, rc);
658 for (int i = 0; i < registeredBuffers; i++) {
659 ops_tbl->unmap_ops(i, -1, ops_tbl->userdata);
660 }
661 free(regFlags);
662 regFlags = NULL;
663 return INVALID_OPERATION;
664 }
665 memset(mBufDefs, 0, mNumBufs * sizeof(mm_camera_buf_def_t));
666 for (int i = 0; i < registeredBuffers; i++) {
667 mStreamBufs->getBufDef(mFrameLenOffset, mBufDefs[i], i);
668 }
669
670 rc = mStreamBufs->getRegFlags(regFlags);
671 if (rc < 0) {
672 ALOGE("%s: getRegFlags failed %d", __func__, rc);
673 for (int i = 0; i < registeredBuffers; i++) {
674 ops_tbl->unmap_ops(i, -1, ops_tbl->userdata);
675 }
676 free(mBufDefs);
677 mBufDefs = NULL;
678 free(regFlags);
679 regFlags = NULL;
680 return INVALID_OPERATION;
681 }
682
683 *num_bufs = mNumBufs;
684 *initial_reg_flag = regFlags;
685 *bufs = mBufDefs;
686 return NO_ERROR;
687 }
688
689 /*===========================================================================
690 * FUNCTION : putBufs
691 *
692 * DESCRIPTION: deallocate stream buffers
693 *
694 * PARAMETERS :
695 * @ops_tbl : ptr to buf mapping/unmapping ops
696 *
697 * RETURN : int32_t type of status
698 * NO_ERROR -- success
699 * none-zero failure code
700 *==========================================================================*/
putBufs(mm_camera_map_unmap_ops_tbl_t * ops_tbl)701 int32_t QCamera3Stream::putBufs(mm_camera_map_unmap_ops_tbl_t *ops_tbl)
702 {
703 int rc = NO_ERROR;
704 Mutex::Autolock lock(mLock);
705
706 for (int i = 0; i < mNumBufs; i++) {
707 if (NULL != mBufDefs[i].mem_info) {
708 rc = ops_tbl->unmap_ops(i, -1, ops_tbl->userdata);
709 if (rc < 0) {
710 ALOGE("%s: un-map stream buf failed: %d", __func__, rc);
711 }
712 }
713 }
714 mBufDefs = NULL; // mBufDefs just keep a ptr to the buffer
715 // mm-camera-interface own the buffer, so no need to free
716 memset(&mFrameLenOffset, 0, sizeof(mFrameLenOffset));
717 mChannel->putStreamBufs();
718
719 return rc;
720 }
721
722 /*===========================================================================
723 * FUNCTION : invalidateBuf
724 *
725 * DESCRIPTION: invalidate a specific stream buffer
726 *
727 * PARAMETERS :
728 * @index : index of the buffer to invalidate
729 *
730 * RETURN : int32_t type of status
731 * NO_ERROR -- success
732 * none-zero failure code
733 *==========================================================================*/
invalidateBuf(int index)734 int32_t QCamera3Stream::invalidateBuf(int index)
735 {
736 return mStreamBufs->invalidateCache(index);
737 }
738
739 /*===========================================================================
740 * FUNCTION : cleanInvalidateBuf
741 *
742 * DESCRIPTION: clean and invalidate a specific stream buffer
743 *
744 * PARAMETERS :
745 * @index : index of the buffer to invalidate
746 *
747 * RETURN : int32_t type of status
748 * NO_ERROR -- success
749 * none-zero failure code
750 *==========================================================================*/
cleanInvalidateBuf(int index)751 int32_t QCamera3Stream::cleanInvalidateBuf(int index)
752 {
753 return mStreamBufs->cleanInvalidateCache(index);
754 }
755
756 /*===========================================================================
757 * FUNCTION : getFrameOffset
758 *
759 * DESCRIPTION: query stream buffer frame offset info
760 *
761 * PARAMETERS :
762 * @offset : reference to struct to store the queried frame offset info
763 *
764 * RETURN : int32_t type of status
765 * NO_ERROR -- success
766 * none-zero failure code
767 *==========================================================================*/
getFrameOffset(cam_frame_len_offset_t & offset)768 int32_t QCamera3Stream::getFrameOffset(cam_frame_len_offset_t &offset)
769 {
770 offset = mFrameLenOffset;
771 return 0;
772 }
773
774 /*===========================================================================
775 * FUNCTION : getFrameDimension
776 *
777 * DESCRIPTION: query stream frame dimension info
778 *
779 * PARAMETERS :
780 * @dim : reference to struct to store the queried frame dimension
781 *
782 * RETURN : int32_t type of status
783 * NO_ERROR -- success
784 * none-zero failure code
785 *==========================================================================*/
getFrameDimension(cam_dimension_t & dim)786 int32_t QCamera3Stream::getFrameDimension(cam_dimension_t &dim)
787 {
788 if (mStreamInfo != NULL) {
789 dim = mStreamInfo->dim;
790 return 0;
791 }
792 return -1;
793 }
794
795 /*===========================================================================
796 * FUNCTION : getFormat
797 *
798 * DESCRIPTION: query stream format
799 *
800 * PARAMETERS :
801 * @fmt : reference to stream format
802 *
803 * RETURN : int32_t type of status
804 * NO_ERROR -- success
805 * none-zero failure code
806 *==========================================================================*/
getFormat(cam_format_t & fmt)807 int32_t QCamera3Stream::getFormat(cam_format_t &fmt)
808 {
809 if (mStreamInfo != NULL) {
810 fmt = mStreamInfo->fmt;
811 return 0;
812 }
813 return -1;
814 }
815
816 /*===========================================================================
817 * FUNCTION : getMyServerID
818 *
819 * DESCRIPTION: query server stream ID
820 *
821 * PARAMETERS : None
822 *
823 * RETURN : stream ID from server
824 *==========================================================================*/
getMyServerID()825 uint32_t QCamera3Stream::getMyServerID() {
826 if (mStreamInfo != NULL) {
827 return mStreamInfo->stream_svr_id;
828 } else {
829 return 0;
830 }
831 }
832
833 /*===========================================================================
834 * FUNCTION : getMyType
835 *
836 * DESCRIPTION: query stream type
837 *
838 * PARAMETERS : None
839 *
840 * RETURN : type of stream
841 *==========================================================================*/
getMyType() const842 cam_stream_type_t QCamera3Stream::getMyType() const
843 {
844 if (mStreamInfo != NULL) {
845 return mStreamInfo->stream_type;
846 } else {
847 return CAM_STREAM_TYPE_MAX;
848 }
849 }
850
851 /*===========================================================================
852 * FUNCTION : mapBuf
853 *
854 * DESCRIPTION: map stream related buffer to backend server
855 *
856 * PARAMETERS :
857 * @buf_type : mapping type of buffer
858 * @buf_idx : index of buffer
859 * @plane_idx: plane index
860 * @fd : fd of the buffer
861 * @size : lenght of the buffer
862 *
863 * RETURN : int32_t type of status
864 * NO_ERROR -- success
865 * none-zero failure code
866 *==========================================================================*/
mapBuf(uint8_t buf_type,uint32_t buf_idx,int32_t plane_idx,int fd,uint32_t size)867 int32_t QCamera3Stream::mapBuf(uint8_t buf_type,
868 uint32_t buf_idx,
869 int32_t plane_idx,
870 int fd,
871 uint32_t size)
872 {
873 return mCamOps->map_stream_buf(mCamHandle, mChannelHandle,
874 mHandle, buf_type,
875 buf_idx, plane_idx,
876 fd, size);
877
878 }
879
880 /*===========================================================================
881 * FUNCTION : unmapBuf
882 *
883 * DESCRIPTION: unmap stream related buffer to backend server
884 *
885 * PARAMETERS :
886 * @buf_type : mapping type of buffer
887 * @buf_idx : index of buffer
888 * @plane_idx: plane index
889 *
890 * RETURN : int32_t type of status
891 * NO_ERROR -- success
892 * none-zero failure code
893 *==========================================================================*/
unmapBuf(uint8_t buf_type,uint32_t buf_idx,int32_t plane_idx)894 int32_t QCamera3Stream::unmapBuf(uint8_t buf_type, uint32_t buf_idx, int32_t plane_idx)
895 {
896 return mCamOps->unmap_stream_buf(mCamHandle, mChannelHandle,
897 mHandle, buf_type,
898 buf_idx, plane_idx);
899 }
900
901 /*===========================================================================
902 * FUNCTION : setParameter
903 *
904 * DESCRIPTION: set stream based parameters
905 *
906 * PARAMETERS :
907 * @param : ptr to parameters to be set
908 *
909 * RETURN : int32_t type of status
910 * NO_ERROR -- success
911 * none-zero failure code
912 *==========================================================================*/
setParameter(cam_stream_parm_buffer_t & param)913 int32_t QCamera3Stream::setParameter(cam_stream_parm_buffer_t ¶m)
914 {
915 int32_t rc = NO_ERROR;
916 mStreamInfo->parm_buf = param;
917 rc = mCamOps->set_stream_parms(mCamHandle,
918 mChannelHandle,
919 mHandle,
920 &mStreamInfo->parm_buf);
921 if (rc == NO_ERROR) {
922 param = mStreamInfo->parm_buf;
923 }
924 return rc;
925 }
926
927 /*===========================================================================
928 * FUNCTION : releaseFrameData
929 *
930 * DESCRIPTION: callback function to release frame data node
931 *
932 * PARAMETERS :
933 * @data : ptr to post process input data
934 * @user_data : user data ptr (QCameraReprocessor)
935 *
936 * RETURN : None
937 *==========================================================================*/
releaseFrameData(void * data,void * user_data)938 void QCamera3Stream::releaseFrameData(void *data, void *user_data)
939 {
940 QCamera3Stream *pme = (QCamera3Stream *)user_data;
941 mm_camera_super_buf_t *frame = (mm_camera_super_buf_t *)data;
942 if (NULL != pme) {
943 pme->bufDone(frame->bufs[0]->buf_idx);
944 }
945 }
946
947 }; // namespace qcamera
948