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