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 39using namespace android; 40 41namespace 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 *==========================================================================*/ 61int32_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 *==========================================================================*/ 90int32_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 *==========================================================================*/ 115int32_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 *==========================================================================*/ 138int32_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 *==========================================================================*/ 162QCamera3Stream::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 *==========================================================================*/ 200QCamera3Stream::~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 *==========================================================================*/ 234int32_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 311err4: 312 mCamOps->unmap_stream_buf(mCamHandle, 313 mChannelHandle, mHandle, CAM_MAPPING_BUF_TYPE_STREAM_INFO, 0, -1); 314err3: 315 mStreamInfoBuf->deallocate(); 316err2: 317 delete mStreamInfoBuf; 318 mStreamInfoBuf = NULL; 319 mStreamInfo = NULL; 320err1: 321 mCamOps->delete_stream(mCamHandle, mChannelHandle, mHandle); 322 mHandle = 0; 323 mNumBufs = 0; 324done: 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 *==========================================================================*/ 340int32_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 *==========================================================================*/ 360int32_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 *==========================================================================*/ 379int32_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 *==========================================================================*/ 407void 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 *==========================================================================*/ 442void *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 *==========================================================================*/ 505mm_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 *==========================================================================*/ 535int32_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 *==========================================================================*/ 587int32_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 *==========================================================================*/ 680int32_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 *==========================================================================*/ 711int32_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 *==========================================================================*/ 728int32_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 *==========================================================================*/ 745int32_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 *==========================================================================*/ 763int32_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 *==========================================================================*/ 784int32_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 *==========================================================================*/ 802uint32_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 *==========================================================================*/ 819cam_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 *==========================================================================*/ 844int32_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 *==========================================================================*/ 871int32_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 *==========================================================================*/ 890int32_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 *==========================================================================*/ 915void 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