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 "QCameraStream" 31 32 #include <utils/Errors.h> 33 #include <QComOMXMetadata.h> 34 #include "QCamera2HWI.h" 35 #include "QCameraStream.h" 36 37 #define CAMERA_MIN_ALLOCATED_BUFFERS 3 38 39 namespace qcamera { 40 41 /*=========================================================================== 42 * FUNCTION : get_bufs 43 * 44 * DESCRIPTION: static function entry to allocate stream buffers 45 * 46 * PARAMETERS : 47 * @offset : offset info of stream buffers 48 * @num_bufs : number of buffers allocated 49 * @initial_reg_flag: flag to indicate if buffer needs to be registered 50 * at kernel initially 51 * @bufs : output of allocated buffers 52 * @ops_tbl : ptr to buf mapping/unmapping ops 53 * @user_data : user data ptr of ops_tbl 54 * 55 * RETURN : int32_t type of status 56 * NO_ERROR -- success 57 * none-zero failure code 58 *==========================================================================*/ 59 int32_t QCameraStream::get_bufs( 60 cam_frame_len_offset_t *offset, 61 uint8_t *num_bufs, 62 uint8_t **initial_reg_flag, 63 mm_camera_buf_def_t **bufs, 64 mm_camera_map_unmap_ops_tbl_t *ops_tbl, 65 void *user_data) 66 { 67 QCameraStream *stream = reinterpret_cast<QCameraStream *>(user_data); 68 if (!stream) { 69 ALOGE("getBufs invalid stream pointer"); 70 return NO_MEMORY; 71 } 72 73 if (stream->mStreamInfo != NULL 74 && stream->mStreamInfo->streaming_mode == CAM_STREAMING_MODE_BATCH) { 75 //Batch Mode. Allocate Butch buffers 76 return stream->allocateBatchBufs(offset, num_bufs, 77 initial_reg_flag, bufs, ops_tbl); 78 } else { 79 // Plane Buffer. Allocate plane buffer 80 return stream->getBufs(offset, num_bufs, 81 initial_reg_flag, bufs, ops_tbl); 82 } 83 } 84 85 /*=========================================================================== 86 * FUNCTION : get_bufs_deffered 87 * 88 * DESCRIPTION: static function entry to allocate deffered stream buffers 89 * 90 * PARAMETERS : 91 * @offset : offset info of stream buffers 92 * @num_bufs : number of buffers allocated 93 * @initial_reg_flag: flag to indicate if buffer needs to be registered 94 * at kernel initially 95 * @bufs : output of allocated buffers 96 * @ops_tbl : ptr to buf mapping/unmapping ops 97 * @user_data : user data ptr of ops_tbl 98 * 99 * RETURN : int32_t type of status 100 * NO_ERROR -- success 101 * none-zero failure code 102 *==========================================================================*/ 103 int32_t QCameraStream::get_bufs_deffered( 104 cam_frame_len_offset_t * /* offset */, 105 uint8_t *num_bufs, 106 uint8_t **initial_reg_flag, 107 mm_camera_buf_def_t **bufs, 108 mm_camera_map_unmap_ops_tbl_t * /* ops_tbl */, 109 void *user_data) 110 { 111 QCameraStream *stream = reinterpret_cast<QCameraStream *>(user_data); 112 if (!stream) { 113 ALOGE("getBufs invalid stream pointer"); 114 return NO_MEMORY; 115 } 116 117 *initial_reg_flag = stream->mRegFlags; 118 *num_bufs = stream->mNumBufs; 119 *bufs = stream->mBufDefs; 120 CDBG_HIGH("%s: stream type: %d, mRegFlags: %p, numBufs: %d", 121 __func__, stream->getMyType(), stream->mRegFlags, stream->mNumBufs); 122 return NO_ERROR; 123 } 124 125 /*=========================================================================== 126 * FUNCTION : put_bufs 127 * 128 * DESCRIPTION: static function entry to deallocate stream buffers 129 * 130 * PARAMETERS : 131 * @ops_tbl : ptr to buf mapping/unmapping ops 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 QCameraStream::put_bufs( 139 mm_camera_map_unmap_ops_tbl_t *ops_tbl, 140 void *user_data) 141 { 142 QCameraStream *stream = reinterpret_cast<QCameraStream *>(user_data); 143 if (!stream) { 144 ALOGE("putBufs invalid stream pointer"); 145 return NO_MEMORY; 146 } 147 148 if (stream->mStreamInfo != NULL 149 && stream->mStreamInfo->streaming_mode == CAM_STREAMING_MODE_BATCH) { 150 //Batch Mode. release Butch buffers 151 return stream->releaseBatchBufs(ops_tbl); 152 } else { 153 // Plane Buffer. release plane buffer 154 return stream->putBufs(ops_tbl); 155 } 156 157 } 158 159 /*=========================================================================== 160 * FUNCTION : put_bufs_deffered 161 * 162 * DESCRIPTION: static function entry to deallocate deffered stream buffers 163 * 164 * PARAMETERS : 165 * @ops_tbl : ptr to buf mapping/unmapping ops 166 * @user_data : user data ptr of ops_tbl 167 * 168 * RETURN : int32_t type of status 169 * NO_ERROR -- success 170 * none-zero failure code 171 *==========================================================================*/ 172 int32_t QCameraStream::put_bufs_deffered( 173 mm_camera_map_unmap_ops_tbl_t * /*ops_tbl */, 174 void * /*user_data*/ ) 175 { 176 // No op 177 // Used for handling buffers with deffered allocation. They are freed separately. 178 return NO_ERROR; 179 } 180 181 /*=========================================================================== 182 * FUNCTION : invalidate_buf 183 * 184 * DESCRIPTION: static function entry to invalidate a specific stream buffer 185 * 186 * PARAMETERS : 187 * @index : index of the stream buffer to invalidate 188 * @user_data : user data ptr of ops_tbl 189 * 190 * RETURN : int32_t type of status 191 * NO_ERROR -- success 192 * none-zero failure code 193 *==========================================================================*/ 194 int32_t QCameraStream::invalidate_buf(uint32_t index, void *user_data) 195 { 196 QCameraStream *stream = reinterpret_cast<QCameraStream *>(user_data); 197 if (!stream) { 198 ALOGE("invalid stream pointer"); 199 return NO_MEMORY; 200 } 201 202 if (stream->mStreamInfo->is_secure == SECURE){ 203 return 0; 204 } 205 206 if (stream->mStreamInfo->streaming_mode == CAM_STREAMING_MODE_BATCH) { 207 for (int i = 0; i < stream->mBufDefs[index].user_buf.bufs_used; i++) { 208 uint32_t buf_idx = stream->mBufDefs[index].user_buf.buf_idx[i]; 209 stream->invalidateBuf(buf_idx); 210 } 211 } else { 212 return stream->invalidateBuf(index); 213 } 214 215 return 0; 216 } 217 218 /*=========================================================================== 219 * FUNCTION : clean_invalidate_buf 220 * 221 * DESCRIPTION: static function entry to clean invalidate a specific stream buffer 222 * 223 * PARAMETERS : 224 * @index : index of the stream buffer to clean invalidate 225 * @user_data : user data ptr of ops_tbl 226 * 227 * RETURN : int32_t type of status 228 * NO_ERROR -- success 229 * none-zero failure code 230 *==========================================================================*/ 231 int32_t QCameraStream::clean_invalidate_buf(uint32_t index, void *user_data) 232 { 233 QCameraStream *stream = reinterpret_cast<QCameraStream *>(user_data); 234 if (!stream) { 235 ALOGE("invalid stream pointer"); 236 return NO_MEMORY; 237 } 238 239 if (stream->mStreamInfo->is_secure == SECURE){ 240 return 0; 241 } 242 243 if (stream->mStreamInfo->streaming_mode == CAM_STREAMING_MODE_BATCH) { 244 for (int i = 0; i < stream->mBufDefs[index].user_buf.bufs_used; i++) { 245 uint32_t buf_idx = stream->mBufDefs[index].user_buf.buf_idx[i]; 246 stream->cleanInvalidateBuf(buf_idx); 247 } 248 } else { 249 return stream->cleanInvalidateBuf(index); 250 } 251 252 return 0; 253 } 254 255 /*=========================================================================== 256 * FUNCTION : QCameraStream 257 * 258 * DESCRIPTION: constructor of QCameraStream 259 * 260 * PARAMETERS : 261 * @allocator : memory allocator obj 262 * @camHandle : camera handle 263 * @chId : channel handle 264 * @camOps : ptr to camera ops table 265 * @paddingInfo: ptr to padding info 266 * @deffered : deferred stream 267 * @online_rotation: rotation applied online 268 * 269 * RETURN : None 270 *==========================================================================*/ 271 QCameraStream::QCameraStream(QCameraAllocator &allocator, 272 uint32_t camHandle, uint32_t chId, 273 mm_camera_ops_t *camOps, cam_padding_info_t *paddingInfo, 274 bool deffered, cam_rotation_t online_rotation): 275 mDumpFrame(0), 276 mDumpMetaFrame(0), 277 mDumpSkipCnt(0), 278 mCamHandle(camHandle), 279 mChannelHandle(chId), 280 mHandle(0), 281 mCamOps(camOps), 282 mStreamInfo(NULL), 283 mNumBufs(0), 284 mNumPlaneBufs(0), 285 mNumBufsNeedAlloc(0), 286 mDataCB(NULL), 287 mUserData(NULL), 288 mDataQ(releaseFrameData, this), 289 mStreamInfoBuf(NULL), 290 mMiscBuf(NULL), 291 mStreamBufs(NULL), 292 mStreamBatchBufs(NULL), 293 mAllocator(allocator), 294 mBufDefs(NULL), 295 mPlaneBufDefs(NULL), 296 mOnlineRotation(online_rotation), 297 mStreamBufsAcquired(false), 298 m_bActive(false), 299 mDynBufAlloc(false), 300 mBufAllocPid(0), 301 mDefferedAllocation(deffered), 302 wait_for_cond(false) 303 { 304 mMemVtbl.user_data = this; 305 if ( !deffered ) { 306 mMemVtbl.get_bufs = get_bufs; 307 mMemVtbl.put_bufs = put_bufs; 308 } else { 309 mMemVtbl.get_bufs = get_bufs_deffered; 310 mMemVtbl.put_bufs = put_bufs_deffered; 311 } 312 mMemVtbl.invalidate_buf = invalidate_buf; 313 mMemVtbl.clean_invalidate_buf = clean_invalidate_buf; 314 memset(&mFrameLenOffset, 0, sizeof(mFrameLenOffset)); 315 memcpy(&mPaddingInfo, paddingInfo, sizeof(cam_padding_info_t)); 316 memset(&mCropInfo, 0, sizeof(cam_rect_t)); 317 memset(&m_MemOpsTbl, 0, sizeof(mm_camera_map_unmap_ops_tbl_t)); 318 memset(&m_OutputCrop, 0, sizeof(cam_stream_parm_buffer_t)); 319 memset(&m_ImgProp, 0, sizeof(cam_stream_parm_buffer_t)); 320 pthread_mutex_init(&mCropLock, NULL); 321 pthread_mutex_init(&mParameterLock, NULL); 322 } 323 324 /*=========================================================================== 325 * FUNCTION : ~QCameraStream 326 * 327 * DESCRIPTION: deconstructor of QCameraStream 328 * 329 * PARAMETERS : None 330 * 331 * RETURN : None 332 *==========================================================================*/ 333 QCameraStream::~QCameraStream() 334 { 335 pthread_mutex_destroy(&mCropLock); 336 pthread_mutex_destroy(&mParameterLock); 337 338 if (mDefferedAllocation) { 339 mStreamBufsAcquired = false; 340 releaseBuffs(); 341 } 342 343 unmapStreamInfoBuf(); 344 releaseStreamInfoBuf(); 345 346 if (mMiscBuf) { 347 unMapBuf(mMiscBuf, CAM_MAPPING_BUF_TYPE_MISC_BUF, NULL); 348 releaseMiscBuf(); 349 } 350 351 // delete stream 352 if (mHandle > 0) { 353 mCamOps->delete_stream(mCamHandle, mChannelHandle, mHandle); 354 mHandle = 0; 355 } 356 } 357 358 /*=========================================================================== 359 * FUNCTION : unmapStreamInfoBuf 360 * 361 * DESCRIPTION: Unmap stream info buffer 362 * 363 * PARAMETERS : 364 * 365 * RETURN : int32_t type of status 366 * NO_ERROR -- success 367 * none-zero failure code 368 *==========================================================================*/ 369 int32_t QCameraStream::unmapStreamInfoBuf() 370 { 371 int rc = NO_ERROR; 372 373 if (mStreamInfoBuf != NULL) { 374 rc = mCamOps->unmap_stream_buf(mCamHandle, 375 mChannelHandle, 376 mHandle, 377 CAM_MAPPING_BUF_TYPE_STREAM_INFO, 378 0, 379 -1); 380 381 if (rc < 0) { 382 ALOGE("Failed to unmap stream info buffer"); 383 } 384 } 385 386 return rc; 387 } 388 389 /*=========================================================================== 390 * FUNCTION : releaseMiscBuf 391 * 392 * DESCRIPTION: Release misc buffers 393 * 394 * PARAMETERS : 395 * 396 * RETURN : int32_t type of status 397 * NO_ERROR -- success 398 * none-zero failure code 399 *==========================================================================*/ 400 int32_t QCameraStream::releaseMiscBuf() 401 { 402 int rc = NO_ERROR; 403 404 if (mMiscBuf != NULL) { 405 mMiscBuf->deallocate(); 406 delete mMiscBuf; 407 mMiscBuf = NULL; 408 } 409 410 return rc; 411 } 412 413 /*=========================================================================== 414 * FUNCTION : releaseStreamInfoBuf 415 * 416 * DESCRIPTION: Release stream info buffer 417 * 418 * PARAMETERS : 419 * 420 * RETURN : int32_t type of status 421 * NO_ERROR -- success 422 * none-zero failure code 423 *==========================================================================*/ 424 int32_t QCameraStream::releaseStreamInfoBuf() 425 { 426 int rc = NO_ERROR; 427 428 if (mStreamInfoBuf != NULL) { 429 mStreamInfoBuf->deallocate(); 430 delete mStreamInfoBuf; 431 mStreamInfoBuf = NULL; 432 } 433 434 return rc; 435 } 436 437 /*=========================================================================== 438 * FUNCTION : deleteStream 439 * 440 * DESCRIPTION: Deletes a camera stream 441 * 442 * PARAMETERS : None 443 * 444 * RETURN : None 445 *==========================================================================*/ 446 void QCameraStream::deleteStream() 447 { 448 if (mHandle > 0) { 449 acquireStreamBufs(); 450 releaseBuffs(); 451 unmapStreamInfoBuf(); 452 mCamOps->delete_stream(mCamHandle, mChannelHandle, mHandle); 453 } 454 } 455 456 /*=========================================================================== 457 * FUNCTION : unMapBuf 458 * 459 * DESCRIPTION: unmaps buffers 460 * 461 * PARAMETERS : 462 * @heapBuf : heap buffer handler 463 * @bufType : buffer type 464 * @ops_tbl : ptr to buf mapping/unmapping ops 465 * 466 * RETURN : int32_t type of status 467 * NO_ERROR -- success 468 * none-zero failure code 469 *==========================================================================*/ 470 int32_t QCameraStream::unMapBuf(QCameraMemory *Buf, 471 cam_mapping_buf_type bufType, mm_camera_map_unmap_ops_tbl_t *ops_tbl) 472 { 473 int32_t rc = NO_ERROR; 474 uint8_t cnt; 475 ssize_t bufSize = BAD_INDEX; 476 uint32_t i; 477 478 cnt = Buf->getCnt(); 479 for (i = 0; i < cnt; i++) { 480 bufSize = Buf->getSize(i); 481 if (BAD_INDEX != bufSize) { 482 if (ops_tbl == NULL ) { 483 rc = mCamOps->unmap_stream_buf(mCamHandle, mChannelHandle, mHandle, 484 bufType, i, -1); 485 } else { 486 rc = ops_tbl->unmap_ops(i, -1, bufType, ops_tbl->userdata); 487 } 488 if (rc < 0) { 489 ALOGE("Failed to unmap buffer"); 490 break; 491 } 492 } else { 493 ALOGE("Failed to retrieve buffer size (bad index)"); 494 rc = BAD_INDEX; 495 break; 496 } 497 } 498 499 return rc; 500 } 501 502 /*=========================================================================== 503 * FUNCTION : mapBuf 504 * 505 * DESCRIPTION: maps buffers 506 * 507 * PARAMETERS : 508 * @heapBuf : heap buffer handler 509 * @bufType : buffer type 510 * @ops_tbl : ptr to buf mapping/unmapping ops 511 * 512 * RETURN : int32_t type of status 513 * NO_ERROR -- success 514 * none-zero failure code 515 *==========================================================================*/ 516 int32_t QCameraStream::mapBuf(QCameraMemory *Buf, 517 cam_mapping_buf_type bufType, mm_camera_map_unmap_ops_tbl_t *ops_tbl) 518 { 519 int32_t rc = NO_ERROR; 520 uint8_t cnt; 521 ssize_t bufSize = BAD_INDEX; 522 int32_t i = 0; 523 524 cnt = Buf->getCnt(); 525 for (i = 0; i < cnt; i++) { 526 bufSize = Buf->getSize((uint32_t)i); 527 if (BAD_INDEX != bufSize) { 528 if (ops_tbl == NULL) { 529 rc = mCamOps->map_stream_buf(mCamHandle, mChannelHandle, mHandle, 530 (uint8_t)bufType, (uint32_t)i, -1, 531 Buf->getFd((uint32_t)i), (uint32_t)bufSize); 532 } else { 533 rc = ops_tbl->map_ops((uint32_t)i, -1, Buf->getFd((uint32_t)i), 534 (uint32_t)bufSize, bufType, ops_tbl->userdata); 535 } 536 if (rc < 0) { 537 ALOGE("Failed to map buffer"); 538 goto err1; 539 } 540 } else { 541 ALOGE("Failed to retrieve buffer size (bad index)"); 542 rc = BAD_INDEX; 543 goto err1; 544 } 545 } 546 547 return rc; 548 err1: 549 i -= 1; 550 for (; i >= 0; i--) { 551 bufSize = Buf->getSize((uint32_t)i); 552 if (BAD_INDEX != bufSize) { 553 if (ops_tbl == NULL) { 554 rc = mCamOps->unmap_stream_buf(mCamHandle, mChannelHandle, mHandle, 555 (uint8_t)bufType, (uint32_t)i, -1); 556 } else { 557 rc = ops_tbl->unmap_ops((uint32_t)i, -1, bufType, ops_tbl->userdata); 558 } 559 if (rc < 0) { 560 ALOGE("Failed to unmap buffer"); 561 } 562 } else { 563 ALOGE("Failed to retrieve buffer size (bad index)"); 564 rc = BAD_INDEX; 565 } 566 } 567 return rc; 568 } 569 570 /*=========================================================================== 571 * FUNCTION : init 572 * 573 * DESCRIPTION: initialize stream obj 574 * 575 * PARAMETERS : 576 * @streamInfoBuf: ptr to buf that contains stream info 577 * @miscBuf : ptr to buf that contains misc bufs 578 * @stream_cb : stream data notify callback. Can be NULL if not needed 579 * @userdata : user data ptr 580 * @bDynallocBuf : flag to indicate if buffer allocation can be in 2 steps 581 * 582 * RETURN : int32_t type of status 583 * NO_ERROR -- success 584 * none-zero failure code 585 *==========================================================================*/ 586 int32_t QCameraStream::init(QCameraHeapMemory *streamInfoBuf, 587 QCameraHeapMemory *miscBuf, 588 uint8_t minNumBuffers, 589 stream_cb_routine stream_cb, 590 void *userdata, 591 bool bDynallocBuf) 592 { 593 int32_t rc = OK; 594 595 mHandle = mCamOps->add_stream(mCamHandle, mChannelHandle); 596 if (!mHandle) { 597 ALOGE("add_stream failed"); 598 rc = UNKNOWN_ERROR; 599 if (streamInfoBuf != NULL) { 600 streamInfoBuf->deallocate(); 601 delete streamInfoBuf; 602 streamInfoBuf = NULL; 603 } 604 goto done; 605 } 606 607 // assign and map stream info memory 608 mStreamInfoBuf = streamInfoBuf; 609 mStreamInfo = reinterpret_cast<cam_stream_info_t *>(mStreamInfoBuf->getPtr(0)); 610 mNumBufs = minNumBuffers; 611 612 rc = mapBuf(mStreamInfoBuf, CAM_MAPPING_BUF_TYPE_STREAM_INFO, NULL); 613 if (rc < 0) { 614 ALOGE("Failed to map stream info buffer"); 615 releaseStreamInfoBuf(); 616 mStreamInfo = 0; 617 goto err1; 618 } 619 620 mMiscBuf = miscBuf; 621 if (miscBuf) { 622 rc = mapBuf(mMiscBuf, CAM_MAPPING_BUF_TYPE_MISC_BUF, NULL); 623 if (rc < 0) { 624 ALOGE("Failed to map miscellaneous buffer"); 625 releaseMiscBuf(); 626 goto err1; 627 } 628 } 629 630 // Calculate buffer size for deffered allocation 631 if (mDefferedAllocation) { 632 rc = calcOffset(mStreamInfo); 633 if (rc < 0) { 634 ALOGE("%s : Failed to calculate stream offset", __func__); 635 goto err1; 636 } 637 } else { 638 rc = configStream(); 639 if (rc < 0) { 640 ALOGE("%s : Failed to config stream ", __func__); 641 goto err1; 642 } 643 } 644 645 mDataCB = stream_cb; 646 mUserData = userdata; 647 mDynBufAlloc = bDynallocBuf; 648 return 0; 649 650 err1: 651 mCamOps->delete_stream(mCamHandle, mChannelHandle, mHandle); 652 mHandle = 0; 653 mNumBufs = 0; 654 done: 655 return rc; 656 } 657 658 /*=========================================================================== 659 * FUNCTION : calcOffset 660 * 661 * DESCRIPTION: calculate frame offset based on format and padding information 662 * 663 * PARAMETERS : 664 * @streamInfo : stream information 665 * 666 * RETURN : int32_t type of status 667 * 0 -- success 668 * -1 -- failure 669 *==========================================================================*/ 670 int32_t QCameraStream::calcOffset(cam_stream_info_t *streamInfo) 671 { 672 int32_t rc = 0; 673 674 cam_dimension_t dim = streamInfo->dim; 675 if (streamInfo->pp_config.feature_mask & CAM_QCOM_FEATURE_ROTATION && 676 streamInfo->stream_type != CAM_STREAM_TYPE_VIDEO) { 677 if (streamInfo->pp_config.rotation == ROTATE_90 || 678 streamInfo->pp_config.rotation == ROTATE_270) { 679 // rotated by 90 or 270, need to switch width and height 680 dim.width = streamInfo->dim.height; 681 dim.height = streamInfo->dim.width; 682 } 683 } 684 685 switch (streamInfo->stream_type) { 686 case CAM_STREAM_TYPE_PREVIEW: 687 rc = mm_stream_calc_offset_preview(streamInfo->fmt, 688 &dim, 689 &streamInfo->buf_planes); 690 break; 691 case CAM_STREAM_TYPE_POSTVIEW: 692 rc = mm_stream_calc_offset_post_view(streamInfo->fmt, 693 &dim, 694 &streamInfo->buf_planes); 695 break; 696 case CAM_STREAM_TYPE_SNAPSHOT: 697 rc = mm_stream_calc_offset_snapshot(streamInfo->fmt, 698 &dim, 699 &mPaddingInfo, 700 &streamInfo->buf_planes); 701 break; 702 case CAM_STREAM_TYPE_OFFLINE_PROC: 703 rc = mm_stream_calc_offset_postproc(streamInfo, 704 &mPaddingInfo, 705 &streamInfo->buf_planes); 706 break; 707 case CAM_STREAM_TYPE_VIDEO: 708 rc = mm_stream_calc_offset_video(&dim, 709 &streamInfo->buf_planes); 710 break; 711 case CAM_STREAM_TYPE_RAW: 712 rc = mm_stream_calc_offset_raw(streamInfo->fmt, 713 &dim, 714 &mPaddingInfo, 715 &streamInfo->buf_planes); 716 break; 717 case CAM_STREAM_TYPE_ANALYSIS: 718 rc = mm_stream_calc_offset_analysis(streamInfo->fmt, 719 &dim, 720 &mPaddingInfo, 721 &streamInfo->buf_planes); 722 break; 723 case CAM_STREAM_TYPE_METADATA: 724 rc = mm_stream_calc_offset_metadata(&dim, 725 &mPaddingInfo, 726 &streamInfo->buf_planes); 727 break; 728 default: 729 ALOGE("%s: not supported for stream type %d", 730 __func__, streamInfo->stream_type); 731 rc = -1; 732 break; 733 } 734 return rc; 735 } 736 737 /*=========================================================================== 738 * FUNCTION : start 739 * 740 * DESCRIPTION: start stream. Will start main stream thread to handle stream 741 * related ops. 742 * 743 * PARAMETERS : none 744 * 745 * RETURN : int32_t type of status 746 * NO_ERROR -- success 747 * none-zero failure code 748 *==========================================================================*/ 749 int32_t QCameraStream::start() 750 { 751 int32_t rc = 0; 752 mDataQ.init(); 753 rc = mProcTh.launch(dataProcRoutine, this); 754 if (rc == NO_ERROR) { 755 m_bActive = true; 756 } 757 pthread_mutex_init(&m_lock, NULL); 758 pthread_cond_init(&m_cond, NULL); 759 return rc; 760 } 761 762 /*=========================================================================== 763 * FUNCTION : stop 764 * 765 * DESCRIPTION: stop stream. Will stop main stream thread 766 * 767 * PARAMETERS : none 768 * 769 * RETURN : int32_t type of status 770 * NO_ERROR -- success 771 * none-zero failure code 772 *==========================================================================*/ 773 int32_t QCameraStream::stop() 774 { 775 int32_t rc = 0; 776 m_bActive = false; 777 rc = mProcTh.exit(); 778 return rc; 779 } 780 781 /*=========================================================================== 782 * FUNCTION : syncRuntimeParams 783 * 784 * DESCRIPTION: query and sync runtime parameters like output crop 785 * buffer info etc. 786 * 787 * PARAMETERS : none 788 * 789 * RETURN : int32_t type of status 790 * NO_ERROR -- success 791 * none-zero failure code 792 *==========================================================================*/ 793 int32_t QCameraStream::syncRuntimeParams() 794 { 795 int32_t ret = NO_ERROR; 796 797 memset(&m_OutputCrop, 0, sizeof(cam_stream_parm_buffer_t)); 798 m_OutputCrop.type = CAM_STREAM_PARAM_TYPE_GET_OUTPUT_CROP; 799 800 ret = getParameter(m_OutputCrop); 801 if (ret != NO_ERROR) { 802 ALOGE("%s: stream getParameter for output crop failed", __func__); 803 return ret; 804 } 805 806 memset(&m_ImgProp, 0, sizeof(cam_stream_parm_buffer_t)); 807 m_ImgProp.type = CAM_STREAM_PARAM_TYPE_GET_IMG_PROP; 808 809 ret = getParameter(m_ImgProp); 810 if (ret != NO_ERROR) { 811 ALOGE("%s: stream getParameter for image prop failed", __func__); 812 return ret; 813 } 814 815 return ret; 816 } 817 818 /*=========================================================================== 819 * FUNCTION : processZoomDone 820 * 821 * DESCRIPTION: process zoom done event 822 * 823 * PARAMETERS : 824 * @previewWindoe : preview window ops table to set preview crop window 825 * @crop_info : crop info 826 * 827 * RETURN : int32_t type of status 828 * NO_ERROR -- success 829 * none-zero failure code 830 *==========================================================================*/ 831 int32_t QCameraStream::processZoomDone(preview_stream_ops_t *previewWindow, 832 cam_crop_data_t &crop_info) 833 { 834 int32_t rc = 0; 835 836 if (!m_bActive) { 837 ALOGV("%s : Stream not active", __func__); 838 return NO_ERROR; 839 } 840 841 // get stream param for crop info 842 for (int i = 0; i < crop_info.num_of_streams; i++) { 843 if (crop_info.crop_info[i].stream_id == mStreamInfo->stream_svr_id) { 844 pthread_mutex_lock(&mCropLock); 845 mCropInfo = crop_info.crop_info[i].crop; 846 pthread_mutex_unlock(&mCropLock); 847 848 // update preview window crop if it's preview/postview stream 849 if ( (previewWindow != NULL) && 850 (mStreamInfo->stream_type == CAM_STREAM_TYPE_PREVIEW || 851 mStreamInfo->stream_type == CAM_STREAM_TYPE_POSTVIEW) ) { 852 rc = previewWindow->set_crop(previewWindow, 853 mCropInfo.left, 854 mCropInfo.top, 855 mCropInfo.width, 856 mCropInfo.height); 857 } 858 break; 859 } 860 } 861 return rc; 862 } 863 864 /*=========================================================================== 865 * FUNCTION : processDataNotify 866 * 867 * DESCRIPTION: process stream data notify 868 * 869 * PARAMETERS : 870 * @frame : stream frame received 871 * 872 * RETURN : int32_t type of status 873 * NO_ERROR -- success 874 * none-zero failure code 875 *==========================================================================*/ 876 int32_t QCameraStream::processDataNotify(mm_camera_super_buf_t *frame) 877 { 878 CDBG("%s:\n", __func__); 879 if (mDataQ.enqueue((void *)frame)) { 880 return mProcTh.sendCmd(CAMERA_CMD_TYPE_DO_NEXT_JOB, FALSE, FALSE); 881 } else { 882 CDBG_HIGH("%s: Stream thread is not active, no ops here", __func__); 883 bufDone(frame->bufs[0]->buf_idx); 884 free(frame); 885 return NO_ERROR; 886 } 887 } 888 889 /*=========================================================================== 890 * FUNCTION : dataNotifyCB 891 * 892 * DESCRIPTION: callback for data notify. This function is registered with 893 * mm-camera-interface to handle data notify 894 * 895 * PARAMETERS : 896 * @recvd_frame : stream frame received 897 * userdata : user data ptr 898 * 899 * RETURN : none 900 *==========================================================================*/ 901 void QCameraStream::dataNotifyCB(mm_camera_super_buf_t *recvd_frame, 902 void *userdata) 903 { 904 CDBG("%s:\n", __func__); 905 QCameraStream* stream = (QCameraStream *)userdata; 906 if (stream == NULL || 907 recvd_frame == NULL || 908 recvd_frame->bufs[0] == NULL || 909 recvd_frame->bufs[0]->stream_id != stream->getMyHandle()) { 910 ALOGE("%s: Not a valid stream to handle buf", __func__); 911 return; 912 } 913 914 mm_camera_super_buf_t *frame = 915 (mm_camera_super_buf_t *)malloc(sizeof(mm_camera_super_buf_t)); 916 if (frame == NULL) { 917 ALOGE("%s: No mem for mm_camera_buf_def_t", __func__); 918 stream->bufDone(recvd_frame->bufs[0]->buf_idx); 919 return; 920 } 921 *frame = *recvd_frame; 922 stream->processDataNotify(frame); 923 return; 924 } 925 926 /*=========================================================================== 927 * FUNCTION : dataProcRoutine 928 * 929 * DESCRIPTION: function to process data in the main stream thread 930 * 931 * PARAMETERS : 932 * @data : user data ptr 933 * 934 * RETURN : none 935 *==========================================================================*/ 936 void *QCameraStream::dataProcRoutine(void *data) 937 { 938 int running = 1; 939 int ret; 940 QCameraStream *pme = (QCameraStream *)data; 941 QCameraCmdThread *cmdThread = &pme->mProcTh; 942 cmdThread->setName("CAM_strmDatProc"); 943 944 CDBG("%s: E", __func__); 945 do { 946 do { 947 ret = cam_sem_wait(&cmdThread->cmd_sem); 948 if (ret != 0 && errno != EINVAL) { 949 ALOGE("%s: cam_sem_wait error (%s)", 950 __func__, strerror(errno)); 951 return NULL; 952 } 953 } while (ret != 0); 954 955 // we got notified about new cmd avail in cmd queue 956 camera_cmd_type_t cmd = cmdThread->getCmd(); 957 switch (cmd) { 958 case CAMERA_CMD_TYPE_DO_NEXT_JOB: 959 { 960 CDBG_HIGH("%s: Do next job", __func__); 961 mm_camera_super_buf_t *frame = 962 (mm_camera_super_buf_t *)pme->mDataQ.dequeue(); 963 if (NULL != frame) { 964 if (pme->mDataCB != NULL) { 965 pme->mDataCB(frame, pme, pme->mUserData); 966 } else { 967 // no data cb routine, return buf here 968 pme->bufDone(frame->bufs[0]->buf_idx); 969 free(frame); 970 } 971 } 972 } 973 break; 974 case CAMERA_CMD_TYPE_EXIT: 975 CDBG_HIGH("%s: Exit", __func__); 976 /* flush data buf queue */ 977 pme->mDataQ.flush(); 978 running = 0; 979 break; 980 default: 981 break; 982 } 983 } while (running); 984 CDBG_HIGH("%s: X", __func__); 985 return NULL; 986 } 987 988 /*=========================================================================== 989 * FUNCTION : bufDone 990 * 991 * DESCRIPTION: return stream buffer to kernel 992 * 993 * PARAMETERS : 994 * @index : index of buffer to be returned 995 * 996 * RETURN : int32_t type of status 997 * NO_ERROR -- success 998 * none-zero failure code 999 *==========================================================================*/ 1000 int32_t QCameraStream::bufDone(uint32_t index) 1001 { 1002 int32_t rc = NO_ERROR; 1003 1004 if (index >= mNumBufs || mBufDefs == NULL) 1005 return BAD_INDEX; 1006 1007 rc = mCamOps->qbuf(mCamHandle, mChannelHandle, &mBufDefs[index]); 1008 if (rc < 0) 1009 return rc; 1010 1011 return rc; 1012 } 1013 1014 /*=========================================================================== 1015 * FUNCTION : bufDone 1016 * 1017 * DESCRIPTION: return stream buffer to kernel 1018 * 1019 * PARAMETERS : 1020 * @opaque : stream frame/metadata buf to be returned 1021 * @isMetaData: flag if returned opaque is a metadatabuf or the real frame ptr 1022 * 1023 * RETURN : int32_t type of status 1024 * NO_ERROR -- success 1025 * none-zero failure code 1026 *==========================================================================*/ 1027 int32_t QCameraStream::bufDone(const void *opaque, bool isMetaData) 1028 { 1029 int32_t rc = NO_ERROR; 1030 int index; 1031 1032 if (mStreamInfo != NULL 1033 && mStreamInfo->streaming_mode == CAM_STREAMING_MODE_BATCH) { 1034 index = mStreamBatchBufs->getMatchBufIndex(opaque, TRUE); 1035 if (index == -1 || index >= mNumBufs || mBufDefs == NULL) { 1036 ALOGE("%s: Cannot find buf for opaque data = %p", __func__, opaque); 1037 return BAD_INDEX; 1038 } 1039 camera_memory_t *video_mem = mStreamBatchBufs->getMemory(index, true); 1040 if (video_mem != NULL) { 1041 struct encoder_media_buffer_type * packet = 1042 (struct encoder_media_buffer_type *)video_mem->data; 1043 native_handle_t *nh = const_cast<native_handle_t *>(packet->meta_handle); 1044 if (NULL != nh) { 1045 if (native_handle_delete(nh)) { 1046 ALOGE("%s: Unable to delete native handle", __func__); 1047 } 1048 } else { 1049 ALOGE("%s : native handle not available", __func__); 1050 } 1051 } 1052 } else { 1053 index = mStreamBufs->getMatchBufIndex(opaque, isMetaData); 1054 if (index == -1 || index >= mNumBufs || mBufDefs == NULL) { 1055 ALOGE("%s: Cannot find buf for opaque data = %p", __func__, opaque); 1056 return BAD_INDEX; 1057 } 1058 CDBG_HIGH("%s: Buffer Index = %d, Frame Idx = %d", __func__, index, 1059 mBufDefs[index].frame_idx); 1060 } 1061 rc = bufDone((uint32_t)index); 1062 return rc; 1063 } 1064 1065 /*=========================================================================== 1066 * FUNCTION : getNumQueuedBuf 1067 * 1068 * DESCRIPTION: return queued buffer count 1069 * 1070 * PARAMETERS : None 1071 * 1072 * RETURN : queued buffer count 1073 *==========================================================================*/ 1074 int32_t QCameraStream::getNumQueuedBuf() 1075 { 1076 int32_t rc = -1; 1077 if (mHandle > 0) { 1078 rc = mCamOps->get_queued_buf_count(mCamHandle, mChannelHandle, mHandle); 1079 } 1080 if (rc == -1) { 1081 ALOGE("%s: stream is not in active state. Invalid operation", __func__); 1082 } 1083 return rc; 1084 } 1085 1086 /*=========================================================================== 1087 * FUNCTION : getBufs 1088 * 1089 * DESCRIPTION: allocate stream buffers 1090 * 1091 * PARAMETERS : 1092 * @offset : offset info of stream buffers 1093 * @num_bufs : number of buffers allocated 1094 * @initial_reg_flag: flag to indicate if buffer needs to be registered 1095 * at kernel initially 1096 * @bufs : output of allocated buffers 1097 * @ops_tbl : ptr to buf mapping/unmapping ops 1098 * 1099 * RETURN : int32_t type of status 1100 * NO_ERROR -- success 1101 * none-zero failure code 1102 *==========================================================================*/ 1103 int32_t QCameraStream::getBufs(cam_frame_len_offset_t *offset, 1104 uint8_t *num_bufs, 1105 uint8_t **initial_reg_flag, 1106 mm_camera_buf_def_t **bufs, 1107 mm_camera_map_unmap_ops_tbl_t *ops_tbl) 1108 { 1109 int rc = NO_ERROR; 1110 uint8_t *regFlags; 1111 1112 if (!ops_tbl) { 1113 ALOGE("%s: ops_tbl is NULL", __func__); 1114 return INVALID_OPERATION; 1115 } 1116 1117 mFrameLenOffset = *offset; 1118 1119 uint8_t numBufAlloc = mNumBufs; 1120 mNumBufsNeedAlloc = 0; 1121 if (mDynBufAlloc) { 1122 numBufAlloc = CAMERA_MIN_ALLOCATED_BUFFERS; 1123 if (numBufAlloc > mNumBufs) { 1124 mDynBufAlloc = false; 1125 numBufAlloc = mNumBufs; 1126 } else { 1127 mNumBufsNeedAlloc = (uint8_t)(mNumBufs - numBufAlloc); 1128 } 1129 } 1130 1131 //Allocate stream buffer 1132 mStreamBufs = mAllocator.allocateStreamBuf(mStreamInfo->stream_type, 1133 mFrameLenOffset.frame_len, mFrameLenOffset.mp[0].stride, 1134 mFrameLenOffset.mp[0].scanline, numBufAlloc); 1135 if (!mStreamBufs) { 1136 ALOGE("%s: Failed to allocate stream buffers", __func__); 1137 return NO_MEMORY; 1138 } 1139 1140 mNumBufs = (uint8_t)(numBufAlloc + mNumBufsNeedAlloc); 1141 1142 for (uint32_t i = 0; i < numBufAlloc; i++) { 1143 ssize_t bufSize = mStreamBufs->getSize(i); 1144 if (BAD_INDEX != bufSize) { 1145 rc = ops_tbl->map_ops(i, -1, mStreamBufs->getFd(i), 1146 (uint32_t)bufSize, CAM_MAPPING_BUF_TYPE_STREAM_BUF, ops_tbl->userdata); 1147 if (rc < 0) { 1148 ALOGE("%s: map_stream_buf failed: %d", __func__, rc); 1149 for (uint32_t j = 0; j < i; j++) { 1150 ops_tbl->unmap_ops(j, -1, CAM_MAPPING_BUF_TYPE_STREAM_BUF, ops_tbl->userdata); 1151 } 1152 mStreamBufs->deallocate(); 1153 delete mStreamBufs; 1154 mStreamBufs = NULL; 1155 return INVALID_OPERATION; 1156 } 1157 } else { 1158 ALOGE("Failed to retrieve buffer size (bad index)"); 1159 return INVALID_OPERATION; 1160 } 1161 } 1162 1163 //regFlags array is allocated by us, but consumed and freed by mm-camera-interface 1164 regFlags = (uint8_t *)malloc(sizeof(uint8_t) * mNumBufs); 1165 if (!regFlags) { 1166 ALOGE("%s: Out of memory", __func__); 1167 for (uint32_t i = 0; i < numBufAlloc; i++) { 1168 ops_tbl->unmap_ops(i, -1, CAM_MAPPING_BUF_TYPE_STREAM_BUF, ops_tbl->userdata); 1169 } 1170 mStreamBufs->deallocate(); 1171 delete mStreamBufs; 1172 mStreamBufs = NULL; 1173 return NO_MEMORY; 1174 } 1175 memset(regFlags, 0, sizeof(uint8_t) * mNumBufs); 1176 1177 mBufDefs = (mm_camera_buf_def_t *)malloc(mNumBufs * sizeof(mm_camera_buf_def_t)); 1178 if (mBufDefs == NULL) { 1179 ALOGE("%s: getRegFlags failed %d", __func__, rc); 1180 for (uint32_t i = 0; i < numBufAlloc; i++) { 1181 ops_tbl->unmap_ops(i, -1, CAM_MAPPING_BUF_TYPE_STREAM_BUF, ops_tbl->userdata); 1182 } 1183 mStreamBufs->deallocate(); 1184 delete mStreamBufs; 1185 mStreamBufs = NULL; 1186 free(regFlags); 1187 regFlags = NULL; 1188 return INVALID_OPERATION; 1189 } 1190 memset(mBufDefs, 0, mNumBufs * sizeof(mm_camera_buf_def_t)); 1191 for (uint32_t i = 0; i < numBufAlloc; i++) { 1192 mStreamBufs->getBufDef(mFrameLenOffset, mBufDefs[i], i); 1193 } 1194 1195 rc = mStreamBufs->getRegFlags(regFlags); 1196 if (rc < 0) { 1197 ALOGE("%s: getRegFlags failed %d", __func__, rc); 1198 for (uint32_t i = 0; i < numBufAlloc; i++) { 1199 ops_tbl->unmap_ops(i, -1, CAM_MAPPING_BUF_TYPE_STREAM_BUF, ops_tbl->userdata); 1200 } 1201 mStreamBufs->deallocate(); 1202 delete mStreamBufs; 1203 mStreamBufs = NULL; 1204 free(mBufDefs); 1205 mBufDefs = NULL; 1206 free(regFlags); 1207 regFlags = NULL; 1208 return INVALID_OPERATION; 1209 } 1210 1211 *num_bufs = mNumBufs; 1212 *initial_reg_flag = regFlags; 1213 *bufs = mBufDefs; 1214 CDBG_HIGH("%s: stream type: %d, mRegFlags: %p, numBufs: %d", 1215 __func__, mStreamInfo->stream_type, regFlags, mNumBufs); 1216 1217 if (mNumBufsNeedAlloc > 0) { 1218 pthread_mutex_lock(&m_lock); 1219 wait_for_cond = TRUE; 1220 pthread_mutex_unlock(&m_lock); 1221 CDBG_HIGH("%s: Still need to allocate %d buffers", 1222 __func__, mNumBufsNeedAlloc); 1223 // remember memops table 1224 m_MemOpsTbl = *ops_tbl; 1225 // start another thread to allocate the rest of buffers 1226 pthread_create(&mBufAllocPid, 1227 NULL, 1228 BufAllocRoutine, 1229 this); 1230 pthread_setname_np(mBufAllocPid, "CAM_strmBufAlloc"); 1231 } 1232 1233 return NO_ERROR; 1234 } 1235 1236 /*=========================================================================== 1237 * FUNCTION : allocateBuffers 1238 * 1239 * DESCRIPTION: allocate stream buffers 1240 * 1241 * PARAMETERS : 1242 * 1243 * RETURN : int32_t type of status 1244 * NO_ERROR -- success 1245 * none-zero failure code 1246 *==========================================================================*/ 1247 int32_t QCameraStream::allocateBuffers() 1248 { 1249 int rc = NO_ERROR; 1250 1251 mFrameLenOffset = mStreamInfo->buf_planes.plane_info; 1252 1253 if (mStreamInfo->streaming_mode == CAM_STREAMING_MODE_BATCH) { 1254 return allocateBatchBufs(&mFrameLenOffset, 1255 &mNumBufs, &mRegFlags, 1256 &mBufDefs, NULL); 1257 } 1258 1259 //Allocate and map stream info buffer 1260 mStreamBufs = mAllocator.allocateStreamBuf(mStreamInfo->stream_type, 1261 mFrameLenOffset.frame_len, 1262 mFrameLenOffset.mp[0].stride, 1263 mFrameLenOffset.mp[0].scanline, 1264 mNumBufs); 1265 1266 if (!mStreamBufs) { 1267 ALOGE("%s: Failed to allocate stream buffers", __func__); 1268 return NO_MEMORY; 1269 } 1270 1271 for (uint32_t i = 0; i < mNumBufs; i++) { 1272 ssize_t bufSize = mStreamBufs->getSize(i); 1273 if (BAD_INDEX != bufSize) { 1274 rc = mapBuf(CAM_MAPPING_BUF_TYPE_STREAM_BUF, i, -1, 1275 mStreamBufs->getFd(i), (size_t)bufSize, NULL); 1276 ALOGE_IF((rc < 0), "%s: map_stream_buf failed: %d", __func__, rc); 1277 } else { 1278 ALOGE("%s: Bad index %u", __func__, i); 1279 rc = BAD_INDEX; 1280 } 1281 if (rc < 0) { 1282 ALOGE("%s: Cleanup after error: %d", __func__, rc); 1283 for (uint32_t j = 0; j < i; j++) { 1284 unmapBuf(CAM_MAPPING_BUF_TYPE_STREAM_BUF, j, -1, NULL); 1285 } 1286 mStreamBufs->deallocate(); 1287 delete mStreamBufs; 1288 mStreamBufs = NULL; 1289 return INVALID_OPERATION; 1290 } 1291 } 1292 1293 //regFlags array is allocated by us, 1294 // but consumed and freed by mm-camera-interface 1295 mRegFlags = (uint8_t *)malloc(sizeof(uint8_t) * mNumBufs); 1296 if (!mRegFlags) { 1297 ALOGE("%s: Out of memory", __func__); 1298 for (uint32_t i = 0; i < mNumBufs; i++) { 1299 unmapBuf(CAM_MAPPING_BUF_TYPE_STREAM_BUF, i, -1, NULL); 1300 } 1301 mStreamBufs->deallocate(); 1302 delete mStreamBufs; 1303 mStreamBufs = NULL; 1304 return NO_MEMORY; 1305 } 1306 memset(mRegFlags, 0, sizeof(uint8_t) * mNumBufs); 1307 1308 size_t bufDefsSize = mNumBufs * sizeof(mm_camera_buf_def_t); 1309 mBufDefs = (mm_camera_buf_def_t *)malloc(bufDefsSize); 1310 if (mBufDefs == NULL) { 1311 ALOGE("%s: getRegFlags failed %d", __func__, rc); 1312 for (uint32_t i = 0; i < mNumBufs; i++) { 1313 unmapBuf(CAM_MAPPING_BUF_TYPE_STREAM_BUF, i, -1, NULL); 1314 } 1315 mStreamBufs->deallocate(); 1316 delete mStreamBufs; 1317 mStreamBufs = NULL; 1318 free(mRegFlags); 1319 mRegFlags = NULL; 1320 return INVALID_OPERATION; 1321 } 1322 memset(mBufDefs, 0, bufDefsSize); 1323 for (uint32_t i = 0; i < mNumBufs; i++) { 1324 mStreamBufs->getBufDef(mFrameLenOffset, mBufDefs[i], i); 1325 } 1326 1327 rc = mStreamBufs->getRegFlags(mRegFlags); 1328 if (rc < 0) { 1329 ALOGE("%s: getRegFlags failed %d", __func__, rc); 1330 for (uint32_t i = 0; i < mNumBufs; i++) { 1331 unmapBuf(CAM_MAPPING_BUF_TYPE_STREAM_BUF, i, -1, NULL); 1332 } 1333 mStreamBufs->deallocate(); 1334 delete mStreamBufs; 1335 mStreamBufs = NULL; 1336 free(mBufDefs); 1337 mBufDefs = NULL; 1338 free(mRegFlags); 1339 mRegFlags = NULL; 1340 return INVALID_OPERATION; 1341 } 1342 1343 return NO_ERROR; 1344 } 1345 1346 /*=========================================================================== 1347 * FUNCTION : allocateBatchBufs 1348 * 1349 * DESCRIPTION: allocate stream batch buffers and stream buffers 1350 * 1351 * PARAMETERS : 1352 * @offset : offset info of stream buffers 1353 * @num_bufs : number of buffers allocated 1354 * @initial_reg_flag: flag to indicate if buffer needs to be registered 1355 * at kernel initially 1356 * @bufs : output of allocated buffers 1357 * @plane_bufs : output of allocated plane buffers 1358 * @ops_tbl : ptr to buf mapping/unmapping ops 1359 * 1360 * RETURN : int32_t type of status 1361 * NO_ERROR -- success 1362 * none-zero failure code 1363 *==========================================================================*/ 1364 int32_t QCameraStream::allocateBatchBufs(cam_frame_len_offset_t *offset, 1365 uint8_t *num_bufs, uint8_t **initial_reg_flag, 1366 mm_camera_buf_def_t **bufs, mm_camera_map_unmap_ops_tbl_t *ops_tbl) 1367 { 1368 int rc = NO_ERROR; 1369 uint8_t *regFlags; 1370 1371 mFrameLenOffset = *offset; 1372 1373 CDBG_HIGH("%s : Batch Buffer allocation stream type = %d", __func__, getMyType()); 1374 1375 //Allocate stream batch buffer 1376 mStreamBatchBufs = mAllocator.allocateStreamUserBuf (mStreamInfo); 1377 if (!mStreamBatchBufs) { 1378 ALOGE("%s: Failed to allocate stream batch buffers", __func__); 1379 return NO_MEMORY; 1380 } 1381 1382 //map batch buffers 1383 for (uint32_t i = 0; i < mStreamBatchBufs->getCnt(); i++) { 1384 rc = mapBuf(CAM_MAPPING_BUF_TYPE_STREAM_USER_BUF, i, -1, 1385 mStreamBatchBufs->getFd(i), (size_t)mNumBufs, ops_tbl); 1386 if (rc < 0) { 1387 ALOGE("Failed to map stream batch buffer"); 1388 for (uint32_t j = 0; j < i; j++) { 1389 unmapBuf(CAM_MAPPING_BUF_TYPE_STREAM_USER_BUF, j, -1, ops_tbl); 1390 } 1391 mStreamBatchBufs->deallocate(); 1392 delete mStreamBatchBufs; 1393 mStreamBatchBufs = NULL; 1394 return NO_MEMORY; 1395 } 1396 } 1397 1398 /*calculate stream Buffer count*/ 1399 mNumPlaneBufs = 1400 (mNumBufs * mStreamInfo->user_buf_info.frame_buf_cnt); 1401 1402 //Allocate stream buffer 1403 mStreamBufs = mAllocator.allocateStreamBuf(mStreamInfo->stream_type, 1404 mFrameLenOffset.frame_len,mFrameLenOffset.mp[0].stride, 1405 mFrameLenOffset.mp[0].scanline,mNumPlaneBufs); 1406 if (!mStreamBufs) { 1407 ALOGE("%s: Failed to allocate stream buffers", __func__); 1408 rc = NO_MEMORY; 1409 goto err1; 1410 } 1411 1412 //Map plane stream buffers 1413 for (uint32_t i = 0; i < mNumPlaneBufs; i++) { 1414 ssize_t bufSize = mStreamBufs->getSize(i); 1415 if (BAD_INDEX != bufSize) { 1416 rc = mapBuf(CAM_MAPPING_BUF_TYPE_STREAM_BUF, i, -1, 1417 mStreamBufs->getFd(i), (size_t)bufSize, ops_tbl); 1418 if (rc < 0) { 1419 ALOGE("%s: map_stream_buf failed: %d", __func__, rc); 1420 for (uint32_t j = 0; j < i; j++) { 1421 unmapBuf(CAM_MAPPING_BUF_TYPE_STREAM_BUF, j, -1, ops_tbl); 1422 } 1423 mStreamBufs->deallocate(); 1424 delete mStreamBufs; 1425 mStreamBufs = NULL; 1426 rc = INVALID_OPERATION; 1427 goto err1; 1428 } 1429 } else { 1430 ALOGE("Failed to retrieve buffer size (bad index)"); 1431 mStreamBufs->deallocate(); 1432 delete mStreamBufs; 1433 mStreamBufs = NULL; 1434 rc = INVALID_OPERATION; 1435 goto err1; 1436 } 1437 } 1438 1439 CDBG ("%s: BATCH Buf Count = %d, Plane Buf Cnt = %d", __func__, 1440 mNumBufs, mNumPlaneBufs); 1441 1442 //regFlags array is allocated by us, but consumed and freed by mm-camera-interface 1443 regFlags = (uint8_t *)malloc(sizeof(uint8_t) * mNumBufs); 1444 if (!regFlags) { 1445 ALOGE("%s: Out of memory", __func__); 1446 for (uint32_t i = 0; i < mNumPlaneBufs; i++) { 1447 unmapBuf(CAM_MAPPING_BUF_TYPE_STREAM_BUF, i, -1, ops_tbl); 1448 } 1449 mStreamBufs->deallocate(); 1450 delete mStreamBufs; 1451 mStreamBufs = NULL; 1452 rc = NO_MEMORY; 1453 goto err1; 1454 } 1455 memset(regFlags, 0, sizeof(uint8_t) * mNumBufs); 1456 for (uint32_t i = 0; i < mNumBufs; i++) { 1457 regFlags[i] = 1; 1458 } 1459 1460 mBufDefs = (mm_camera_buf_def_t *)malloc(mNumBufs * sizeof(mm_camera_buf_def_t)); 1461 if (mBufDefs == NULL) { 1462 ALOGE("%s: getRegFlags failed %d", __func__, rc); 1463 for (uint32_t i = 0; i < mNumPlaneBufs; i++) { 1464 unmapBuf(CAM_MAPPING_BUF_TYPE_STREAM_BUF, i, -1, ops_tbl); 1465 } 1466 mStreamBufs->deallocate(); 1467 delete mStreamBufs; 1468 mStreamBufs = NULL; 1469 free(regFlags); 1470 regFlags = NULL; 1471 rc = INVALID_OPERATION; 1472 goto err1; 1473 } 1474 memset(mBufDefs, 0, mNumBufs * sizeof(mm_camera_buf_def_t)); 1475 1476 mPlaneBufDefs = (mm_camera_buf_def_t *) 1477 malloc(mNumPlaneBufs * (sizeof(mm_camera_buf_def_t))); 1478 if (mPlaneBufDefs == NULL) { 1479 ALOGE("%s : No Memory", __func__); 1480 free(regFlags); 1481 regFlags = NULL; 1482 free(mBufDefs); 1483 mBufDefs = NULL; 1484 for (uint32_t i = 0; i < mNumPlaneBufs; i++) { 1485 unmapBuf(CAM_MAPPING_BUF_TYPE_STREAM_BUF, i, -1, ops_tbl); 1486 } 1487 mStreamBufs->deallocate(); 1488 delete mStreamBufs; 1489 mStreamBufs = NULL; 1490 free(regFlags); 1491 regFlags = NULL; 1492 rc = INVALID_OPERATION; 1493 goto err1; 1494 } 1495 memset(mPlaneBufDefs, 0, 1496 mNumPlaneBufs * (sizeof(mm_camera_buf_def_t))); 1497 1498 for (uint32_t i = 0; i < mStreamInfo->num_bufs; i++) { 1499 mStreamBatchBufs->getUserBufDef(mStreamInfo->user_buf_info, 1500 mBufDefs[i], i, mFrameLenOffset, mPlaneBufDefs, 1501 mStreamBufs); 1502 } 1503 1504 *num_bufs = mNumBufs; 1505 *initial_reg_flag = regFlags; 1506 *bufs = mBufDefs; 1507 CDBG_HIGH("%s: stream type: %d, numBufs: %d mNumPlaneBufs: %d", 1508 __func__, mStreamInfo->stream_type, mNumBufs, mNumPlaneBufs); 1509 1510 return NO_ERROR; 1511 1512 err1: 1513 for (uint8_t i = 0; i < mStreamBatchBufs->getCnt(); i++) { 1514 unmapBuf(CAM_MAPPING_BUF_TYPE_STREAM_USER_BUF, i, -1, ops_tbl); 1515 } 1516 mStreamBatchBufs->deallocate(); 1517 delete mStreamBatchBufs; 1518 mStreamBatchBufs = NULL; 1519 return rc; 1520 } 1521 1522 1523 /*=========================================================================== 1524 * FUNCTION : releaseBuffs 1525 * 1526 * DESCRIPTION: method to deallocate stream buffers 1527 * 1528 * PARAMETERS : 1529 * 1530 * RETURN : int32_t type of status 1531 * NO_ERROR -- success 1532 * none-zero failure code 1533 *==========================================================================*/ 1534 int32_t QCameraStream::releaseBuffs() 1535 { 1536 int rc = NO_ERROR; 1537 1538 if (mStreamInfo->streaming_mode == CAM_STREAMING_MODE_BATCH) { 1539 return releaseBatchBufs(NULL); 1540 } 1541 1542 if (NULL != mBufDefs) { 1543 for (uint32_t i = 0; i < mNumBufs; i++) { 1544 rc = unmapBuf(CAM_MAPPING_BUF_TYPE_STREAM_BUF, i, -1, NULL); 1545 if (rc < 0) { 1546 ALOGE("%s: map_stream_buf failed: %d", __func__, rc); 1547 } 1548 } 1549 1550 // mBufDefs just keep a ptr to the buffer 1551 // mm-camera-interface own the buffer, so no need to free 1552 mBufDefs = NULL; 1553 memset(&mFrameLenOffset, 0, sizeof(mFrameLenOffset)); 1554 } 1555 if (!mStreamBufsAcquired && mStreamBufs != NULL) { 1556 mStreamBufs->deallocate(); 1557 delete mStreamBufs; 1558 } 1559 1560 return rc; 1561 } 1562 1563 /*=========================================================================== 1564 * FUNCTION : releaseBatchBufs 1565 * 1566 * DESCRIPTION: method to deallocate stream buffers and batch buffers 1567 * 1568 * PARAMETERS : 1569 * @ops_tbl : ptr to buf mapping/unmapping ops 1570 * 1571 * RETURN : int32_t type of status 1572 * NO_ERROR -- success 1573 * none-zero failure code 1574 1575 *==========================================================================*/ 1576 int32_t QCameraStream::releaseBatchBufs(mm_camera_map_unmap_ops_tbl_t *ops_tbl) 1577 { 1578 int rc = NO_ERROR; 1579 1580 if (NULL != mPlaneBufDefs) { 1581 for (uint32_t i = 0; i < mNumPlaneBufs; i++) { 1582 rc = unmapBuf(CAM_MAPPING_BUF_TYPE_STREAM_BUF, i, -1, ops_tbl); 1583 if (rc < 0) { 1584 ALOGE("%s: map_stream_buf failed: %d", __func__, rc); 1585 } 1586 } 1587 1588 // mBufDefs just keep a ptr to the buffer 1589 // mm-camera-interface own the buffer, so no need to free 1590 mPlaneBufDefs = NULL; 1591 memset(&mFrameLenOffset, 0, sizeof(mFrameLenOffset)); 1592 mNumPlaneBufs = 0; 1593 } 1594 1595 if ( mStreamBufs != NULL) { 1596 mStreamBufs->deallocate(); 1597 delete mStreamBufs; 1598 } 1599 1600 mBufDefs = NULL; 1601 1602 if (mStreamBatchBufs != NULL) { 1603 for (uint8_t i = 0; i < mStreamBatchBufs->getCnt(); i++) { 1604 unmapBuf(CAM_MAPPING_BUF_TYPE_STREAM_USER_BUF, i, -1, ops_tbl); 1605 } 1606 mStreamBatchBufs->deallocate(); 1607 delete mStreamBatchBufs; 1608 mStreamBatchBufs = NULL; 1609 } 1610 return rc; 1611 1612 } 1613 1614 /*=========================================================================== 1615 * FUNCTION : BufAllocRoutine 1616 * 1617 * DESCRIPTION: function to allocate additional stream buffers 1618 * 1619 * PARAMETERS : 1620 * @data : user data ptr 1621 * 1622 * RETURN : none 1623 *==========================================================================*/ 1624 void *QCameraStream::BufAllocRoutine(void *data) 1625 { 1626 QCameraStream *pme = (QCameraStream *)data; 1627 int32_t rc = NO_ERROR; 1628 1629 CDBG_HIGH("%s: E", __func__); 1630 pme->cond_wait(); 1631 if (pme->mNumBufsNeedAlloc > 0) { 1632 uint8_t numBufAlloc = (uint8_t)(pme->mNumBufs - pme->mNumBufsNeedAlloc); 1633 rc = pme->mAllocator.allocateMoreStreamBuf(pme->mStreamBufs, 1634 pme->mFrameLenOffset.frame_len, 1635 pme->mNumBufsNeedAlloc); 1636 if (rc == NO_ERROR){ 1637 for (uint32_t i = numBufAlloc; i < pme->mNumBufs; i++) { 1638 ssize_t bufSize = pme->mStreamBufs->getSize(i); 1639 if (BAD_INDEX != bufSize) { 1640 rc = pme->m_MemOpsTbl.map_ops(i, -1, pme->mStreamBufs->getFd(i), 1641 (uint32_t)bufSize, CAM_MAPPING_BUF_TYPE_STREAM_BUF, 1642 pme->m_MemOpsTbl.userdata); 1643 if (rc == 0) { 1644 pme->mStreamBufs->getBufDef(pme->mFrameLenOffset, pme->mBufDefs[i], i); 1645 pme->mCamOps->qbuf(pme->mCamHandle, pme->mChannelHandle, 1646 &pme->mBufDefs[i]); 1647 } else { 1648 ALOGE("%s: map_stream_buf %d failed: %d", __func__, rc, i); 1649 } 1650 } else { 1651 ALOGE("Failed to retrieve buffer size (bad index)"); 1652 } 1653 } 1654 1655 pme->mNumBufsNeedAlloc = 0; 1656 } 1657 } 1658 CDBG_HIGH("%s: X", __func__); 1659 return NULL; 1660 } 1661 1662 /*=========================================================================== 1663 * FUNCTION : cond_signal 1664 * 1665 * DESCRIPTION: signal if flag "wait_for_cond" is set 1666 * 1667 *==========================================================================*/ 1668 void QCameraStream::cond_signal() 1669 { 1670 pthread_mutex_lock(&m_lock); 1671 if(wait_for_cond == TRUE){ 1672 wait_for_cond = FALSE; 1673 pthread_cond_signal(&m_cond); 1674 } 1675 pthread_mutex_unlock(&m_lock); 1676 } 1677 1678 1679 /*=========================================================================== 1680 * FUNCTION : cond_wait 1681 * 1682 * DESCRIPTION: wait on if flag "wait_for_cond" is set 1683 * 1684 *==========================================================================*/ 1685 void QCameraStream::cond_wait() 1686 { 1687 pthread_mutex_lock(&m_lock); 1688 while (wait_for_cond == TRUE) { 1689 pthread_cond_wait(&m_cond, &m_lock); 1690 } 1691 pthread_mutex_unlock(&m_lock); 1692 } 1693 1694 /*=========================================================================== 1695 * FUNCTION : putBufs 1696 * 1697 * DESCRIPTION: deallocate stream buffers 1698 * 1699 * PARAMETERS : 1700 * @ops_tbl : ptr to buf mapping/unmapping ops 1701 * 1702 * RETURN : int32_t type of status 1703 * NO_ERROR -- success 1704 * none-zero failure code 1705 *==========================================================================*/ 1706 int32_t QCameraStream::putBufs(mm_camera_map_unmap_ops_tbl_t *ops_tbl) 1707 { 1708 int rc = NO_ERROR; 1709 1710 if (mBufAllocPid != 0) { 1711 CDBG_HIGH("%s: wait for buf allocation thread dead", __func__); 1712 pthread_join(mBufAllocPid, NULL); 1713 mBufAllocPid = 0; 1714 CDBG_HIGH("%s: return from buf allocation thread", __func__); 1715 } 1716 1717 for (uint32_t i = 0; i < mNumBufs; i++) { 1718 rc = ops_tbl->unmap_ops(i, -1, CAM_MAPPING_BUF_TYPE_STREAM_BUF, ops_tbl->userdata); 1719 if (rc < 0) { 1720 ALOGE("%s: map_stream_buf failed: %d", __func__, rc); 1721 } 1722 } 1723 mBufDefs = NULL; // mBufDefs just keep a ptr to the buffer 1724 // mm-camera-interface own the buffer, so no need to free 1725 memset(&mFrameLenOffset, 0, sizeof(mFrameLenOffset)); 1726 if ( !mStreamBufsAcquired ) { 1727 mStreamBufs->deallocate(); 1728 delete mStreamBufs; 1729 } 1730 1731 return rc; 1732 } 1733 1734 /*=========================================================================== 1735 * FUNCTION : invalidateBuf 1736 * 1737 * DESCRIPTION: invalidate a specific stream buffer 1738 * 1739 * PARAMETERS : 1740 * @index : index of the buffer to invalidate 1741 * 1742 * RETURN : int32_t type of status 1743 * NO_ERROR -- success 1744 * none-zero failure code 1745 *==========================================================================*/ 1746 int32_t QCameraStream::invalidateBuf(uint32_t index) 1747 { 1748 return mStreamBufs->invalidateCache(index); 1749 } 1750 1751 /*=========================================================================== 1752 * FUNCTION : cleanInvalidateBuf 1753 * 1754 * DESCRIPTION: clean invalidate a specific stream buffer 1755 * 1756 * PARAMETERS : 1757 * @index : index of the buffer to clean invalidate 1758 * 1759 * RETURN : int32_t type of status 1760 * NO_ERROR -- success 1761 * none-zero failure code 1762 *==========================================================================*/ 1763 int32_t QCameraStream::cleanInvalidateBuf(uint32_t index) 1764 { 1765 return mStreamBufs->cleanInvalidateCache(index); 1766 } 1767 1768 /*=========================================================================== 1769 * FUNCTION : isTypeOf 1770 * 1771 * DESCRIPTION: helper function to determine if the stream is of the queried type 1772 * 1773 * PARAMETERS : 1774 * @type : stream type as of queried 1775 * 1776 * RETURN : true/false 1777 *==========================================================================*/ 1778 bool QCameraStream::isTypeOf(cam_stream_type_t type) 1779 { 1780 if (mStreamInfo != NULL && (mStreamInfo->stream_type == type)) { 1781 return true; 1782 } else { 1783 return false; 1784 } 1785 } 1786 1787 /*=========================================================================== 1788 * FUNCTION : isOrignalTypeOf 1789 * 1790 * DESCRIPTION: helper function to determine if the original stream is of the 1791 * queried type if it's reproc stream 1792 * 1793 * PARAMETERS : 1794 * @type : stream type as of queried 1795 * 1796 * RETURN : true/false 1797 *==========================================================================*/ 1798 bool QCameraStream::isOrignalTypeOf(cam_stream_type_t type) 1799 { 1800 if (mStreamInfo != NULL && 1801 mStreamInfo->stream_type == CAM_STREAM_TYPE_OFFLINE_PROC && 1802 mStreamInfo->reprocess_config.pp_type == CAM_ONLINE_REPROCESS_TYPE && 1803 mStreamInfo->reprocess_config.online.input_stream_type == type) { 1804 return true; 1805 } else if ( 1806 mStreamInfo != NULL && 1807 mStreamInfo->stream_type == CAM_STREAM_TYPE_OFFLINE_PROC && 1808 mStreamInfo->reprocess_config.pp_type == CAM_OFFLINE_REPROCESS_TYPE && 1809 mStreamInfo->reprocess_config.offline.input_type == type) { 1810 return true; 1811 } else { 1812 return false; 1813 } 1814 } 1815 1816 /*=========================================================================== 1817 * FUNCTION : getMyType 1818 * 1819 * DESCRIPTION: return stream type 1820 * 1821 * PARAMETERS : none 1822 * 1823 * RETURN : stream type 1824 *==========================================================================*/ 1825 cam_stream_type_t QCameraStream::getMyType() 1826 { 1827 if (mStreamInfo != NULL) { 1828 return mStreamInfo->stream_type; 1829 } else { 1830 return CAM_STREAM_TYPE_DEFAULT; 1831 } 1832 } 1833 1834 /*=========================================================================== 1835 * FUNCTION : getMyOriginalType 1836 * 1837 * DESCRIPTION: return stream type 1838 * 1839 * PARAMETERS : none 1840 * 1841 * RETURN : stream type 1842 *==========================================================================*/ 1843 cam_stream_type_t QCameraStream::getMyOriginalType() 1844 { 1845 if (mStreamInfo != NULL) { 1846 if (mStreamInfo->stream_type == CAM_STREAM_TYPE_OFFLINE_PROC && 1847 mStreamInfo->reprocess_config.pp_type == CAM_ONLINE_REPROCESS_TYPE) { 1848 return mStreamInfo->reprocess_config.online.input_stream_type; 1849 } else if (mStreamInfo->stream_type == CAM_STREAM_TYPE_OFFLINE_PROC && 1850 mStreamInfo->reprocess_config.pp_type == CAM_OFFLINE_REPROCESS_TYPE) { 1851 return mStreamInfo->reprocess_config.offline.input_type; 1852 } else { 1853 return mStreamInfo->stream_type; 1854 } 1855 } else { 1856 return CAM_STREAM_TYPE_DEFAULT; 1857 } 1858 } 1859 1860 /*=========================================================================== 1861 * FUNCTION : getFrameOffset 1862 * 1863 * DESCRIPTION: query stream buffer frame offset info 1864 * 1865 * PARAMETERS : 1866 * @offset : reference to struct to store the queried frame offset info 1867 * 1868 * RETURN : int32_t type of status 1869 * NO_ERROR -- success 1870 * none-zero failure code 1871 *==========================================================================*/ 1872 int32_t QCameraStream::getFrameOffset(cam_frame_len_offset_t &offset) 1873 { 1874 if (NULL == mStreamInfo) { 1875 return NO_INIT; 1876 } 1877 1878 offset = mFrameLenOffset; 1879 if ((ROTATE_90 == mOnlineRotation) || (ROTATE_270 == mOnlineRotation)) { 1880 // Re-calculate frame offset in case of online rotation 1881 cam_stream_info_t streamInfo = *mStreamInfo; 1882 getFrameDimension(streamInfo.dim); 1883 calcOffset(&streamInfo); 1884 offset = streamInfo.buf_planes.plane_info; 1885 } 1886 1887 return 0; 1888 } 1889 1890 /*=========================================================================== 1891 * FUNCTION : getCropInfo 1892 * 1893 * DESCRIPTION: query crop info of the stream 1894 * 1895 * PARAMETERS : 1896 * @crop : reference to struct to store the queried crop info 1897 * 1898 * RETURN : int32_t type of status 1899 * NO_ERROR -- success 1900 * none-zero failure code 1901 *==========================================================================*/ 1902 int32_t QCameraStream::getCropInfo(cam_rect_t &crop) 1903 { 1904 pthread_mutex_lock(&mCropLock); 1905 crop = mCropInfo; 1906 pthread_mutex_unlock(&mCropLock); 1907 return NO_ERROR; 1908 } 1909 1910 /*=========================================================================== 1911 * FUNCTION : setCropInfo 1912 * 1913 * DESCRIPTION: set crop info of the stream 1914 * 1915 * PARAMETERS : 1916 * @crop : struct to store new crop info 1917 * 1918 * RETURN : int32_t type of status 1919 * NO_ERROR -- success 1920 * none-zero failure code 1921 *==========================================================================*/ 1922 int32_t QCameraStream::setCropInfo(cam_rect_t crop) 1923 { 1924 pthread_mutex_lock(&mCropLock); 1925 mCropInfo = crop; 1926 pthread_mutex_unlock(&mCropLock); 1927 return NO_ERROR; 1928 } 1929 1930 /*=========================================================================== 1931 * FUNCTION : getFrameDimension 1932 * 1933 * DESCRIPTION: query stream frame dimension info 1934 * 1935 * PARAMETERS : 1936 * @dim : reference to struct to store the queried frame dimension 1937 * 1938 * RETURN : int32_t type of status 1939 * NO_ERROR -- success 1940 * none-zero failure code 1941 *==========================================================================*/ 1942 int32_t QCameraStream::getFrameDimension(cam_dimension_t &dim) 1943 { 1944 if (mStreamInfo != NULL) { 1945 if ((ROTATE_90 == mOnlineRotation) || (ROTATE_270 == mOnlineRotation)) { 1946 dim.width = mStreamInfo->dim.height; 1947 dim.height = mStreamInfo->dim.width; 1948 } else { 1949 dim = mStreamInfo->dim; 1950 } 1951 return 0; 1952 } 1953 return -1; 1954 } 1955 1956 /*=========================================================================== 1957 * FUNCTION : getFormat 1958 * 1959 * DESCRIPTION: query stream format 1960 * 1961 * PARAMETERS : 1962 * @fmt : reference to stream format 1963 * 1964 * RETURN : int32_t type of status 1965 * NO_ERROR -- success 1966 * none-zero failure code 1967 *==========================================================================*/ 1968 int32_t QCameraStream::getFormat(cam_format_t &fmt) 1969 { 1970 if (mStreamInfo != NULL) { 1971 fmt = mStreamInfo->fmt; 1972 return 0; 1973 } 1974 return -1; 1975 } 1976 1977 /*=========================================================================== 1978 * FUNCTION : getMyServerID 1979 * 1980 * DESCRIPTION: query server stream ID 1981 * 1982 * PARAMETERS : None 1983 * 1984 * RETURN : stream ID from server 1985 *==========================================================================*/ 1986 uint32_t QCameraStream::getMyServerID() { 1987 if (mStreamInfo != NULL) { 1988 return mStreamInfo->stream_svr_id; 1989 } else { 1990 return 0; 1991 } 1992 } 1993 1994 /*=========================================================================== 1995 * FUNCTION : acquireStreamBufs 1996 * 1997 * DESCRIPTION: acquire stream buffers and postpone their release. 1998 * 1999 * PARAMETERS : None 2000 * 2001 * RETURN : int32_t type of status 2002 * NO_ERROR -- success 2003 * none-zero failure code 2004 *==========================================================================*/ 2005 int32_t QCameraStream::acquireStreamBufs() 2006 { 2007 mStreamBufsAcquired = true; 2008 2009 return NO_ERROR; 2010 } 2011 2012 /*=========================================================================== 2013 * FUNCTION : mapBuf 2014 * 2015 * DESCRIPTION: map stream related buffer to backend server 2016 * 2017 * PARAMETERS : 2018 * @buf_type : mapping type of buffer 2019 * @buf_idx : index of buffer 2020 * @plane_idx: plane index 2021 * @fd : fd of the buffer 2022 * @size : lenght of the buffer 2023 * @ops_tbl : ptr to buf mapping/unmapping ops 2024 * 2025 * RETURN : int32_t type of status 2026 * NO_ERROR -- success 2027 * none-zero failure code 2028 *==========================================================================*/ 2029 int32_t QCameraStream::mapBuf(uint8_t buf_type, uint32_t buf_idx, 2030 int32_t plane_idx, int fd, size_t size, mm_camera_map_unmap_ops_tbl_t *ops_tbl) 2031 { 2032 if (ops_tbl != NULL) { 2033 return ops_tbl->map_ops(buf_idx, plane_idx, fd, 2034 (uint32_t)size, (cam_mapping_buf_type)buf_type, ops_tbl->userdata); 2035 } else { 2036 return mCamOps->map_stream_buf(mCamHandle, mChannelHandle, 2037 mHandle, buf_type, buf_idx, plane_idx, 2038 fd, size); 2039 } 2040 2041 } 2042 2043 /*=========================================================================== 2044 * FUNCTION : unmapBuf 2045 * 2046 * DESCRIPTION: unmap stream related buffer to backend server 2047 * 2048 * PARAMETERS : 2049 * @buf_type : mapping type of buffer 2050 * @buf_idx : index of buffer 2051 * @plane_idx: plane index 2052 * @ops_tbl : ptr to buf mapping/unmapping ops 2053 * 2054 * RETURN : int32_t type of status 2055 * NO_ERROR -- success 2056 * none-zero failure code 2057 *==========================================================================*/ 2058 int32_t QCameraStream::unmapBuf(uint8_t buf_type, uint32_t buf_idx, int32_t plane_idx, 2059 mm_camera_map_unmap_ops_tbl_t *ops_tbl) 2060 { 2061 if (ops_tbl != NULL) { 2062 return ops_tbl->unmap_ops(buf_idx, plane_idx, 2063 (cam_mapping_buf_type)buf_type, ops_tbl->userdata); 2064 } else { 2065 return mCamOps->unmap_stream_buf(mCamHandle, mChannelHandle, 2066 mHandle, buf_type, buf_idx, plane_idx); 2067 } 2068 } 2069 2070 /*=========================================================================== 2071 * FUNCTION : setParameter 2072 * 2073 * DESCRIPTION: set stream based parameters 2074 * 2075 * PARAMETERS : 2076 * @param : ptr to parameters to be set 2077 * 2078 * RETURN : int32_t type of status 2079 * NO_ERROR -- success 2080 * none-zero failure code 2081 *==========================================================================*/ 2082 int32_t QCameraStream::setParameter(cam_stream_parm_buffer_t ¶m) 2083 { 2084 int32_t rc = NO_ERROR; 2085 pthread_mutex_lock(&mParameterLock); 2086 mStreamInfo->parm_buf = param; 2087 rc = mCamOps->set_stream_parms(mCamHandle, 2088 mChannelHandle, 2089 mHandle, 2090 &mStreamInfo->parm_buf); 2091 if (rc == NO_ERROR) { 2092 param = mStreamInfo->parm_buf; 2093 } 2094 pthread_mutex_unlock(&mParameterLock); 2095 return rc; 2096 } 2097 2098 /*=========================================================================== 2099 * FUNCTION : getParameter 2100 * 2101 * DESCRIPTION: get stream based parameters 2102 * 2103 * PARAMETERS : 2104 * @param : ptr to parameters to be red 2105 * 2106 * RETURN : int32_t type of status 2107 * NO_ERROR -- success 2108 * none-zero failure code 2109 *==========================================================================*/ 2110 int32_t QCameraStream::getParameter(cam_stream_parm_buffer_t ¶m) 2111 { 2112 int32_t rc = NO_ERROR; 2113 pthread_mutex_lock(&mParameterLock); 2114 mStreamInfo->parm_buf = param; 2115 rc = mCamOps->get_stream_parms(mCamHandle, 2116 mChannelHandle, 2117 mHandle, 2118 &mStreamInfo->parm_buf); 2119 if (rc == NO_ERROR) { 2120 param = mStreamInfo->parm_buf; 2121 } 2122 pthread_mutex_unlock(&mParameterLock); 2123 return rc; 2124 } 2125 2126 /*=========================================================================== 2127 * FUNCTION : releaseFrameData 2128 * 2129 * DESCRIPTION: callback function to release frame data node 2130 * 2131 * PARAMETERS : 2132 * @data : ptr to post process input data 2133 * @user_data : user data ptr (QCameraReprocessor) 2134 * 2135 * RETURN : None 2136 *==========================================================================*/ 2137 void QCameraStream::releaseFrameData(void *data, void *user_data) 2138 { 2139 QCameraStream *pme = (QCameraStream *)user_data; 2140 mm_camera_super_buf_t *frame = (mm_camera_super_buf_t *)data; 2141 if (NULL != pme) { 2142 pme->bufDone(frame->bufs[0]->buf_idx); 2143 } 2144 } 2145 2146 /*=========================================================================== 2147 * FUNCTION : configStream 2148 * 2149 * DESCRIPTION: send stream configuration to back end 2150 * 2151 * PARAMETERS : 2152 * 2153 * RETURN : int32_t type of status 2154 * NO_ERROR -- success 2155 * none-zero failure code 2156 *==========================================================================*/ 2157 int32_t QCameraStream::configStream() 2158 { 2159 int rc = NO_ERROR; 2160 2161 // Configure the stream 2162 mm_camera_stream_config_t stream_config; 2163 stream_config.stream_info = mStreamInfo; 2164 stream_config.mem_vtbl = mMemVtbl; 2165 stream_config.stream_cb = dataNotifyCB; 2166 stream_config.padding_info = mPaddingInfo; 2167 stream_config.userdata = this; 2168 rc = mCamOps->config_stream(mCamHandle, 2169 mChannelHandle, mHandle, &stream_config); 2170 if (rc < 0) { 2171 ALOGE("Failed to config stream, rc = %d", rc); 2172 mCamOps->unmap_stream_buf(mCamHandle, 2173 mChannelHandle, 2174 mHandle, 2175 CAM_MAPPING_BUF_TYPE_STREAM_INFO, 2176 0, 2177 -1); 2178 return UNKNOWN_ERROR; 2179 } 2180 2181 return rc; 2182 } 2183 2184 }; // namespace qcamera 2185