1 /* Copyright (c) 2012-2016, The Linux Foundation. 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 // System dependencies 33 #include <utils/Errors.h> 34 35 // Camera dependencies 36 #include "QCameraBufferMaps.h" 37 #include "QCamera2HWI.h" 38 #include "QCameraStream.h" 39 40 extern "C" { 41 #include "mm_camera_dbg.h" 42 } 43 44 #define CAMERA_MIN_ALLOCATED_BUFFERS 3 45 46 namespace qcamera { 47 48 /*=========================================================================== 49 * FUNCTION : get_bufs 50 * 51 * DESCRIPTION: static function entry to allocate stream buffers 52 * 53 * PARAMETERS : 54 * @offset : offset info of stream buffers 55 * @num_bufs : number of buffers allocated 56 * @initial_reg_flag: flag to indicate if buffer needs to be registered 57 * at kernel initially 58 * @bufs : output of allocated buffers 59 * @ops_tbl : ptr to buf mapping/unmapping ops 60 * @user_data : user data ptr of ops_tbl 61 * 62 * RETURN : int32_t type of status 63 * NO_ERROR -- success 64 * none-zero failure code 65 *==========================================================================*/ 66 int32_t QCameraStream::get_bufs( 67 cam_frame_len_offset_t *offset, 68 uint8_t *num_bufs, 69 uint8_t **initial_reg_flag, 70 mm_camera_buf_def_t **bufs, 71 mm_camera_map_unmap_ops_tbl_t *ops_tbl, 72 void *user_data) 73 { 74 QCameraStream *stream = reinterpret_cast<QCameraStream *>(user_data); 75 if (!stream) { 76 LOGE("getBufs invalid stream pointer"); 77 return NO_MEMORY; 78 } 79 80 if (stream->mStreamInfo != NULL 81 && stream->mStreamInfo->streaming_mode == CAM_STREAMING_MODE_BATCH) { 82 //Batch Mode. Allocate Butch buffers 83 return stream->allocateBatchBufs(offset, num_bufs, 84 initial_reg_flag, bufs, ops_tbl); 85 } else { 86 // Plane Buffer. Allocate plane buffer 87 return stream->getBufs(offset, num_bufs, 88 initial_reg_flag, bufs, ops_tbl); 89 } 90 } 91 92 /*=========================================================================== 93 * FUNCTION : get_bufs_deffered 94 * 95 * DESCRIPTION: static function entry to allocate deffered stream buffers 96 * 97 * PARAMETERS : 98 * @offset : offset info of stream buffers 99 * @num_bufs : number of buffers allocated 100 * @initial_reg_flag: flag to indicate if buffer needs to be registered 101 * at kernel initially 102 * @bufs : output of allocated buffers 103 * @ops_tbl : ptr to buf mapping/unmapping ops 104 * @user_data : user data ptr of ops_tbl 105 * 106 * RETURN : int32_t type of status 107 * NO_ERROR -- success 108 * none-zero failure code 109 *==========================================================================*/ 110 int32_t QCameraStream::get_bufs_deffered( 111 cam_frame_len_offset_t * /* offset */, 112 uint8_t *num_bufs, 113 uint8_t **initial_reg_flag, 114 mm_camera_buf_def_t **bufs, 115 mm_camera_map_unmap_ops_tbl_t * ops_tbl, 116 void *user_data) 117 { 118 QCameraStream *stream = reinterpret_cast<QCameraStream *>(user_data); 119 120 if (!stream) { 121 LOGE("getBufs invalid stream pointer"); 122 return NO_MEMORY; 123 } 124 125 return stream->getBufsDeferred(NULL /*offset*/, num_bufs, initial_reg_flag, bufs, 126 ops_tbl); 127 } 128 129 /*=========================================================================== 130 * FUNCTION : put_bufs 131 * 132 * DESCRIPTION: static function entry to deallocate stream buffers 133 * 134 * PARAMETERS : 135 * @ops_tbl : ptr to buf mapping/unmapping ops 136 * @user_data : user data ptr of ops_tbl 137 * 138 * RETURN : int32_t type of status 139 * NO_ERROR -- success 140 * none-zero failure code 141 *==========================================================================*/ 142 int32_t QCameraStream::put_bufs( 143 mm_camera_map_unmap_ops_tbl_t *ops_tbl, 144 void *user_data) 145 { 146 QCameraStream *stream = reinterpret_cast<QCameraStream *>(user_data); 147 if (!stream) { 148 LOGE("putBufs invalid stream pointer"); 149 return NO_MEMORY; 150 } 151 152 if (stream->mStreamInfo != NULL 153 && stream->mStreamInfo->streaming_mode == CAM_STREAMING_MODE_BATCH) { 154 //Batch Mode. release Butch buffers 155 return stream->releaseBatchBufs(ops_tbl); 156 } else { 157 // Plane Buffer. release plane buffer 158 return stream->putBufs(ops_tbl); 159 } 160 161 } 162 163 /*=========================================================================== 164 * FUNCTION : put_bufs_deffered 165 * 166 * DESCRIPTION: static function entry to deallocate deffered stream buffers 167 * 168 * PARAMETERS : 169 * @ops_tbl : ptr to buf mapping/unmapping ops 170 * @user_data : user data ptr of ops_tbl 171 * 172 * RETURN : int32_t type of status 173 * NO_ERROR -- success 174 * none-zero failure code 175 *==========================================================================*/ 176 int32_t QCameraStream::put_bufs_deffered( 177 mm_camera_map_unmap_ops_tbl_t * /*ops_tbl */, 178 void * user_data ) 179 { 180 QCameraStream *stream = reinterpret_cast<QCameraStream *>(user_data); 181 182 if (!stream) { 183 LOGE("put_bufs_deffered invalid stream pointer"); 184 return NO_MEMORY; 185 } 186 187 return stream->putBufsDeffered(); 188 } 189 190 /*=========================================================================== 191 * FUNCTION : invalidate_buf 192 * 193 * DESCRIPTION: static function entry to invalidate a specific stream buffer 194 * 195 * PARAMETERS : 196 * @index : index of the stream buffer to invalidate 197 * @user_data : user data ptr of ops_tbl 198 * 199 * RETURN : int32_t type of status 200 * NO_ERROR -- success 201 * none-zero failure code 202 *==========================================================================*/ 203 int32_t QCameraStream::invalidate_buf(uint32_t index, void *user_data) 204 { 205 QCameraStream *stream = reinterpret_cast<QCameraStream *>(user_data); 206 if (!stream) { 207 LOGE("invalid stream pointer"); 208 return NO_MEMORY; 209 } 210 211 if (stream->mStreamInfo->is_secure == SECURE){ 212 return 0; 213 } 214 215 if (stream->mStreamInfo->streaming_mode == CAM_STREAMING_MODE_BATCH) { 216 for (int i = 0; i < stream->mBufDefs[index].user_buf.bufs_used; i++) { 217 uint32_t buf_idx = stream->mBufDefs[index].user_buf.buf_idx[i]; 218 stream->invalidateBuf(buf_idx); 219 } 220 } else { 221 return stream->invalidateBuf(index); 222 } 223 224 return 0; 225 } 226 227 /*=========================================================================== 228 * FUNCTION : clean_invalidate_buf 229 * 230 * DESCRIPTION: static function entry to clean invalidate a specific stream buffer 231 * 232 * PARAMETERS : 233 * @index : index of the stream buffer to clean invalidate 234 * @user_data : user data ptr of ops_tbl 235 * 236 * RETURN : int32_t type of status 237 * NO_ERROR -- success 238 * none-zero failure code 239 *==========================================================================*/ 240 int32_t QCameraStream::clean_invalidate_buf(uint32_t index, void *user_data) 241 { 242 QCameraStream *stream = reinterpret_cast<QCameraStream *>(user_data); 243 if (!stream) { 244 LOGE("invalid stream pointer"); 245 return NO_MEMORY; 246 } 247 248 if (stream->mStreamInfo->is_secure == SECURE){ 249 return 0; 250 } 251 252 if (stream->mStreamInfo->streaming_mode == CAM_STREAMING_MODE_BATCH) { 253 for (int i = 0; i < stream->mBufDefs[index].user_buf.bufs_used; i++) { 254 uint32_t buf_idx = stream->mBufDefs[index].user_buf.buf_idx[i]; 255 stream->cleanInvalidateBuf(buf_idx); 256 } 257 } else { 258 return stream->cleanInvalidateBuf(index); 259 } 260 261 return 0; 262 } 263 264 /*=========================================================================== 265 * FUNCTION : clean_buf 266 * 267 * DESCRIPTION: static function entry to clean a specific stream buffer 268 * 269 * PARAMETERS : 270 * @index : index of the stream buffer to clean invalidate 271 * @user_data : user data ptr of ops_tbl 272 * 273 * RETURN : int32_t type of status 274 * NO_ERROR -- success 275 * none-zero failure code 276 *==========================================================================*/ 277 int32_t QCameraStream::clean_buf(uint32_t index, void *user_data) 278 { 279 QCameraStream *stream = reinterpret_cast<QCameraStream *>(user_data); 280 if (!stream) { 281 LOGE("invalid stream pointer"); 282 return NO_MEMORY; 283 } 284 285 if (stream->mStreamInfo->is_secure == SECURE){ 286 return 0; 287 } 288 289 if (stream->mStreamInfo->streaming_mode == CAM_STREAMING_MODE_BATCH) { 290 for (int i = 0; i < stream->mBufDefs[index].user_buf.bufs_used; i++) { 291 uint32_t buf_idx = stream->mBufDefs[index].user_buf.buf_idx[i]; 292 stream->cleanBuf(buf_idx); 293 } 294 } else { 295 return stream->cleanBuf(index); 296 } 297 298 return 0; 299 } 300 301 302 /*=========================================================================== 303 * FUNCTION : set_config_ops 304 * 305 * DESCRIPTION: static function update mm-interface ops functions 306 * 307 * PARAMETERS : 308 * @ops_tbl : ptr to buf mapping/unmapping ops 309 * @user_data : user data ptr of ops_tbl 310 * 311 * RETURN : int32_t type of status 312 * NO_ERROR -- success 313 * none-zero failure code 314 *==========================================================================*/ 315 int32_t QCameraStream::set_config_ops(mm_camera_map_unmap_ops_tbl_t *ops_tbl, 316 void *user_data) 317 { 318 QCameraStream *stream = reinterpret_cast<QCameraStream *>(user_data); 319 if (!stream) { 320 LOGE("Stream invalid"); 321 return NO_MEMORY; 322 } 323 324 stream->m_MemOpsTbl = *ops_tbl; 325 return 0; 326 } 327 328 /*=========================================================================== 329 * FUNCTION : QCameraStream 330 * 331 * DESCRIPTION: constructor of QCameraStream 332 * 333 * PARAMETERS : 334 * @allocator : memory allocator obj 335 * @camHandle : camera handle 336 * @chId : channel handle 337 * @camOps : ptr to camera ops table 338 * @paddingInfo: ptr to padding info 339 * @deffered : deferred stream 340 * @online_rotation: rotation applied online 341 * 342 * RETURN : None 343 *==========================================================================*/ 344 QCameraStream::QCameraStream(QCameraAllocator &allocator, 345 uint32_t camHandle, uint32_t chId, 346 mm_camera_ops_t *camOps, cam_padding_info_t *paddingInfo, 347 bool deffered, cam_rotation_t online_rotation): 348 mDumpFrame(0), 349 mDumpMetaFrame(0), 350 mDumpSkipCnt(0), 351 mStreamTimestamp(0), 352 mCamHandle(camHandle), 353 mChannelHandle(chId), 354 mHandle(0), 355 mCamOps(camOps), 356 mStreamInfo(NULL), 357 mNumBufs(0), 358 mNumPlaneBufs(0), 359 mNumBufsNeedAlloc(0), 360 mRegFlags(NULL), 361 mDataCB(NULL), 362 mSYNCDataCB(NULL), 363 mUserData(NULL), 364 mDataQ(releaseFrameData, this), 365 mStreamInfoBuf(NULL), 366 mMiscBuf(NULL), 367 mStreamBufs(NULL), 368 mStreamBatchBufs(NULL), 369 mAllocator(allocator), 370 mBufDefs(NULL), 371 mPlaneBufDefs(NULL), 372 mOnlineRotation(online_rotation), 373 mStreamBufsAcquired(false), 374 m_bActive(false), 375 mDynBufAlloc(false), 376 mBufAllocPid(0), 377 mDefferedAllocation(deffered), 378 wait_for_cond(false), 379 mAllocTaskId(0), 380 mMapTaskId(0), 381 mSyncCBEnabled(false) 382 { 383 mDualStream = is_dual_camera_by_handle(chId); 384 if (get_main_camera_handle(chId)) { 385 mCamType = MM_CAMERA_TYPE_MAIN; 386 } 387 if (get_aux_camera_handle(chId)) { 388 mCamType |= MM_CAMERA_TYPE_AUX; 389 } 390 mMemVtbl.user_data = this; 391 if ( !deffered ) { 392 mMemVtbl.get_bufs = get_bufs; 393 mMemVtbl.put_bufs = put_bufs; 394 } else { 395 mMemVtbl.get_bufs = get_bufs_deffered; 396 mMemVtbl.put_bufs = put_bufs_deffered; 397 } 398 mMemVtbl.invalidate_buf = invalidate_buf; 399 mMemVtbl.clean_invalidate_buf = clean_invalidate_buf; 400 mMemVtbl.clean_buf = clean_buf; 401 mMemVtbl.set_config_ops = set_config_ops; 402 memset(&mFrameLenOffset, 0, sizeof(mFrameLenOffset)); 403 memcpy(&mPaddingInfo, paddingInfo, sizeof(cam_padding_info_t)); 404 memset(&mCropInfo, 0, sizeof(cam_rect_t)); 405 memset(&m_MemOpsTbl, 0, sizeof(mm_camera_map_unmap_ops_tbl_t)); 406 memset(&m_OutputCrop, 0, sizeof(cam_stream_parm_buffer_t)); 407 memset(&m_ImgProp, 0, sizeof(cam_stream_parm_buffer_t)); 408 memset(&mAllocTask, 0, sizeof(mAllocTask)); 409 memset(&mMapTask, 0, sizeof(mMapTask)); 410 pthread_mutex_init(&mCropLock, NULL); 411 pthread_mutex_init(&mParameterLock, NULL); 412 mCurMetaMemory = NULL; 413 mCurBufIndex = -1; 414 mCurMetaIndex = -1; 415 mFirstTimeStamp = 0; 416 memset (&mStreamMetaMemory, 0, 417 (sizeof(MetaMemory) * CAMERA_MIN_VIDEO_BATCH_BUFFERS)); 418 pthread_mutex_init(&m_lock, NULL); 419 pthread_cond_init(&m_cond, NULL); 420 } 421 422 /*=========================================================================== 423 * FUNCTION : ~QCameraStream 424 * 425 * DESCRIPTION: deconstructor of QCameraStream 426 * 427 * PARAMETERS : None 428 * 429 * RETURN : None 430 *==========================================================================*/ 431 QCameraStream::~QCameraStream() 432 { 433 pthread_mutex_destroy(&mCropLock); 434 pthread_mutex_destroy(&mParameterLock); 435 436 mAllocator.waitForBackgroundTask(mAllocTaskId); 437 mAllocator.waitForBackgroundTask(mMapTaskId); 438 if (mBufAllocPid != 0) { 439 cond_signal(true); 440 LOGL("Wait for buf allocation thread dead"); 441 // Wait for the allocation of additional stream buffers 442 pthread_join(mBufAllocPid, NULL); 443 mBufAllocPid = 0; 444 } 445 446 if (mDefferedAllocation) { 447 mStreamBufsAcquired = false; 448 releaseBuffs(); 449 } 450 451 unmapStreamInfoBuf(); 452 releaseStreamInfoBuf(); 453 454 if (mMiscBuf) { 455 unMapBuf(mMiscBuf, CAM_MAPPING_BUF_TYPE_MISC_BUF, NULL); 456 releaseMiscBuf(); 457 } 458 459 // delete stream 460 if (mHandle > 0) { 461 mCamOps->delete_stream(mCamHandle, mChannelHandle, mHandle); 462 mHandle = 0; 463 } 464 pthread_mutex_destroy(&m_lock); 465 pthread_cond_destroy(&m_cond); 466 mDualStream = 0; 467 } 468 469 /*=========================================================================== 470 * FUNCTION : unmapStreamInfoBuf 471 * 472 * DESCRIPTION: Unmap stream info buffer 473 * 474 * PARAMETERS : 475 * 476 * RETURN : int32_t type of status 477 * NO_ERROR -- success 478 * none-zero failure code 479 *==========================================================================*/ 480 int32_t QCameraStream::unmapStreamInfoBuf() 481 { 482 int rc = NO_ERROR; 483 484 if (mStreamInfoBuf != NULL) { 485 rc = mCamOps->unmap_stream_buf(mCamHandle, 486 mChannelHandle, 487 mHandle, 488 CAM_MAPPING_BUF_TYPE_STREAM_INFO, 489 0, 490 -1); 491 492 if (rc < 0) { 493 LOGE("Failed to unmap stream info buffer"); 494 } 495 } 496 497 return rc; 498 } 499 500 /*=========================================================================== 501 * FUNCTION : releaseMiscBuf 502 * 503 * DESCRIPTION: Release misc buffers 504 * 505 * PARAMETERS : 506 * 507 * RETURN : int32_t type of status 508 * NO_ERROR -- success 509 * none-zero failure code 510 *==========================================================================*/ 511 int32_t QCameraStream::releaseMiscBuf() 512 { 513 int rc = NO_ERROR; 514 515 if (mMiscBuf != NULL) { 516 mMiscBuf->deallocate(); 517 delete mMiscBuf; 518 mMiscBuf = NULL; 519 } 520 521 return rc; 522 } 523 524 /*=========================================================================== 525 * FUNCTION : releaseStreamInfoBuf 526 * 527 * DESCRIPTION: Release stream info buffer 528 * 529 * PARAMETERS : 530 * 531 * RETURN : int32_t type of status 532 * NO_ERROR -- success 533 * none-zero failure code 534 *==========================================================================*/ 535 int32_t QCameraStream::releaseStreamInfoBuf() 536 { 537 int rc = NO_ERROR; 538 539 if (mStreamInfoBuf != NULL) { 540 mStreamInfoBuf->deallocate(); 541 delete mStreamInfoBuf; 542 mStreamInfoBuf = NULL; 543 mStreamInfo = NULL; 544 } 545 546 return rc; 547 } 548 549 /*=========================================================================== 550 * FUNCTION : deleteStream 551 * 552 * DESCRIPTION: Deletes a camera stream 553 * 554 * PARAMETERS : None 555 * 556 * RETURN : None 557 *==========================================================================*/ 558 void QCameraStream::deleteStream() 559 { 560 if (mHandle > 0) { 561 acquireStreamBufs(); 562 releaseBuffs(); 563 unmapStreamInfoBuf(); 564 mCamOps->delete_stream(mCamHandle, mChannelHandle, mHandle); 565 } 566 } 567 568 /*=========================================================================== 569 * FUNCTION : unMapBuf 570 * 571 * DESCRIPTION: unmaps buffers 572 * 573 * PARAMETERS : 574 * @heapBuf : heap buffer handler 575 * @bufType : buffer type 576 * @ops_tbl : ptr to buf mapping/unmapping ops 577 * 578 * RETURN : int32_t type of status 579 * NO_ERROR -- success 580 * none-zero failure code 581 *==========================================================================*/ 582 int32_t QCameraStream::unMapBuf(QCameraMemory *Buf, 583 cam_mapping_buf_type bufType, __unused mm_camera_map_unmap_ops_tbl_t *ops_tbl) 584 { 585 int32_t rc = NO_ERROR; 586 uint8_t cnt; 587 ssize_t bufSize = BAD_INDEX; 588 uint32_t i; 589 590 cnt = Buf->getCnt(); 591 for (i = 0; i < cnt; i++) { 592 bufSize = Buf->getSize(i); 593 if (BAD_INDEX != bufSize) { 594 if (m_MemOpsTbl.unmap_ops == NULL ) { 595 rc = mCamOps->unmap_stream_buf(mCamHandle, mChannelHandle, mHandle, 596 bufType, i, -1); 597 } else { 598 rc = m_MemOpsTbl.unmap_ops(i, -1, bufType, m_MemOpsTbl.userdata); 599 } 600 if (rc < 0) { 601 LOGE("Failed to unmap buffer"); 602 break; 603 } 604 } else { 605 LOGE("Failed to retrieve buffer size (bad index)"); 606 rc = BAD_INDEX; 607 break; 608 } 609 } 610 611 return rc; 612 } 613 614 /*=========================================================================== 615 * FUNCTION : mapBufs 616 * 617 * DESCRIPTION: maps buffers 618 * 619 * PARAMETERS : 620 * @heapBuf : heap buffer handler 621 * @bufType : buffer type 622 * @ops_tbl : ptr to buf mapping/unmapping ops 623 * 624 * RETURN : int32_t type of status 625 * NO_ERROR -- success 626 * none-zero failure code 627 *==========================================================================*/ 628 int32_t QCameraStream::mapBufs(QCameraMemory *Buf, 629 cam_mapping_buf_type bufType, __unused mm_camera_map_unmap_ops_tbl_t *ops_tbl) 630 { 631 int32_t rc = NO_ERROR; 632 uint32_t i = 0; 633 uint32_t activeHandle = mHandle; 634 QCameraBufferMaps bufferMaps; 635 636 for (i = 0; i < Buf->getCnt(); i++) { 637 ssize_t bufSize = Buf->getSize(i); 638 if (BAD_INDEX == bufSize) { 639 LOGE("Failed to retrieve buffer size (bad index)"); 640 return BAD_INDEX; 641 } 642 643 if ((bufType == CAM_MAPPING_BUF_TYPE_STREAM_INFO) 644 || (bufType == CAM_MAPPING_BUF_TYPE_MISC_BUF)) { 645 if ((i > 0 && isDualStream()) || 646 (mCamType == MM_CAMERA_TYPE_AUX)) { 647 activeHandle = get_aux_camera_handle(mHandle); 648 } else { 649 activeHandle = get_main_camera_handle(mHandle); 650 } 651 } 652 rc = bufferMaps.enqueue(bufType, activeHandle, i /*buf index*/, -1 /*plane index*/, 653 0 /*cookie*/, Buf->getFd(i), bufSize, Buf->getPtr(i)); 654 655 if (rc < 0) { 656 LOGE("Failed to map buffers"); 657 return BAD_INDEX; 658 } 659 } 660 661 cam_buf_map_type_list bufMapList; 662 rc = bufferMaps.getCamBufMapList(bufMapList); 663 if (rc < 0) { 664 LOGE("Failed to map buffers"); 665 return BAD_INDEX; 666 } 667 668 if (m_MemOpsTbl.bundled_map_ops == NULL) { 669 rc = mCamOps->map_stream_bufs(mCamHandle, mChannelHandle, &bufMapList); 670 } else { 671 rc = m_MemOpsTbl.bundled_map_ops(&bufMapList, m_MemOpsTbl.userdata); 672 } 673 674 if (rc < 0) { 675 LOGE("Failed to map buffer"); 676 rc = BAD_INDEX; 677 } 678 return rc; 679 } 680 681 /*=========================================================================== 682 * FUNCTION : backgroundAllocate 683 * 684 * DESCRIPTION: schedule buffers to be allocated in the background 685 * 686 * PARAMETERS : 687 * 688 * RETURN : int32_t type of status 689 * NO_ERROR -- success 690 * none-zero failure code 691 *==========================================================================*/ 692 int32_t QCameraStream::backgroundAllocate(void *data) { 693 QCameraStream *stream = (QCameraStream*)data; 694 int32_t rc = stream->allocateBuffers(); 695 if (rc != NO_ERROR) { 696 LOGE("Error allocating buffers !!!"); 697 } 698 return rc; 699 } 700 701 /*=========================================================================== 702 * FUNCTION : backgroundMap 703 * 704 * DESCRIPTION: map buffers in the background 705 * 706 * PARAMETERS : 707 * 708 * RETURN : int32_t type of status 709 * NO_ERROR -- success 710 * none-zero failure code 711 *==========================================================================*/ 712 int32_t QCameraStream::backgroundMap(void *data) { 713 QCameraStream *stream = (QCameraStream*)data; 714 int32_t rc = stream->mapBuffers(); 715 if (rc != NO_ERROR) { 716 LOGE("Error mapping buffers !!!"); 717 } 718 return rc; 719 } 720 721 /*=========================================================================== 722 * FUNCTION : init 723 * 724 * DESCRIPTION: initialize stream obj 725 * 726 * PARAMETERS : 727 * @streamInfoBuf: ptr to buf that contains stream info 728 * @miscBuf : ptr to buf that contains misc bufs 729 * @stream_cb : stream data notify callback. Can be NULL if not needed 730 * @userdata : user data ptr 731 * @bDynallocBuf : flag to indicate if buffer allocation can be in 2 steps 732 * 733 * RETURN : int32_t type of status 734 * NO_ERROR -- success 735 * none-zero failure code 736 *==========================================================================*/ 737 int32_t QCameraStream::init(QCameraHeapMemory *streamInfoBuf, 738 QCameraHeapMemory *miscBuf, 739 stream_cb_routine stream_cb, 740 void *userdata, 741 bool bDynallocBuf) 742 { 743 int32_t rc = OK; 744 745 // assign and map stream info memory 746 mStreamInfoBuf = streamInfoBuf; 747 mStreamInfo = reinterpret_cast<cam_stream_info_t *>(mStreamInfoBuf->getPtr(0)); 748 mNumBufs = mStreamInfo->num_bufs; 749 mDynBufAlloc = bDynallocBuf; 750 751 // Calculate buffer size for deffered allocation 752 if (mDefferedAllocation) { 753 rc = calcOffset(mStreamInfo); 754 if (rc < 0) { 755 LOGE("Failed to calculate stream offset"); 756 goto done; 757 } 758 759 mAllocTask.bgFunction = backgroundAllocate; 760 mAllocTask.bgArgs = this; 761 mAllocTaskId = mAllocator.scheduleBackgroundTask(&mAllocTask); 762 if (mAllocTaskId == 0) { 763 LOGE("Failed to schedule buffer alloction"); 764 rc = -ENOMEM; 765 goto done; 766 } 767 } 768 769 mHandle = mCamOps->add_stream(mCamHandle, mChannelHandle); 770 if (!mHandle) { 771 LOGE("add_stream failed"); 772 rc = UNKNOWN_ERROR; 773 goto done; 774 } 775 776 mMasterCamera = MM_CAMERA_TYPE_MAIN; 777 if (mCamType & MM_CAMERA_TYPE_MAIN) { 778 mActiveCameras = MM_CAMERA_TYPE_MAIN; 779 } 780 if (mCamType & MM_CAMERA_TYPE_AUX) { 781 mActiveCameras |= MM_CAMERA_TYPE_AUX; 782 } 783 if (isDualStream()) { 784 if (needFrameSync()) { 785 mCamOps->handle_frame_sync_cb(mCamHandle, mChannelHandle, 786 mHandle, MM_CAMERA_CB_REQ_TYPE_FRAME_SYNC); 787 } else if (!needCbSwitch()) { 788 mCamOps->handle_frame_sync_cb(mCamHandle, mChannelHandle, 789 mHandle, MM_CAMERA_CB_REQ_TYPE_ALL_CB); 790 } 791 } 792 793 rc = mapBufs(mStreamInfoBuf, CAM_MAPPING_BUF_TYPE_STREAM_INFO, NULL); 794 if (rc < 0) { 795 LOGE("Failed to map stream info buffer"); 796 goto err1; 797 } 798 799 mMiscBuf = miscBuf; 800 if (miscBuf) { 801 rc = mapBufs(mMiscBuf, CAM_MAPPING_BUF_TYPE_MISC_BUF, NULL); 802 if (rc < 0) { 803 LOGE("Failed to map miscellaneous buffer"); 804 releaseMiscBuf(); 805 goto err1; 806 } 807 } 808 809 rc = configStream(); 810 if (rc < 0) { 811 LOGE("Failed to config stream "); 812 goto err1; 813 } 814 815 if (mDefferedAllocation) { 816 mMapTask.bgFunction = backgroundMap; 817 mMapTask.bgArgs = this; 818 mMapTaskId = mAllocator.scheduleBackgroundTask(&mMapTask); 819 if (mMapTaskId == 0) { 820 LOGE("Failed to schedule buffer alloction"); 821 rc = -ENOMEM; 822 goto err1; 823 } 824 } 825 826 mDataCB = stream_cb; 827 mUserData = userdata; 828 return 0; 829 830 err1: 831 mCamOps->delete_stream(mCamHandle, mChannelHandle, mHandle); 832 mHandle = 0; 833 done: 834 return rc; 835 } 836 837 /*=========================================================================== 838 * FUNCTION : calcOffset 839 * 840 * DESCRIPTION: calculate frame offset based on format and padding information 841 * 842 * PARAMETERS : 843 * @streamInfo : stream information 844 * 845 * RETURN : int32_t type of status 846 * 0 -- success 847 * -1 -- failure 848 *==========================================================================*/ 849 int32_t QCameraStream::calcOffset(cam_stream_info_t *streamInfo) 850 { 851 int32_t rc = 0; 852 853 cam_dimension_t dim = streamInfo->dim; 854 if (streamInfo->pp_config.feature_mask & CAM_QCOM_FEATURE_ROTATION && 855 streamInfo->stream_type != CAM_STREAM_TYPE_VIDEO) { 856 if (streamInfo->pp_config.rotation == ROTATE_90 || 857 streamInfo->pp_config.rotation == ROTATE_270) { 858 // rotated by 90 or 270, need to switch width and height 859 dim.width = streamInfo->dim.height; 860 dim.height = streamInfo->dim.width; 861 } 862 } 863 864 switch (streamInfo->stream_type) { 865 case CAM_STREAM_TYPE_PREVIEW: 866 case CAM_STREAM_TYPE_CALLBACK: 867 rc = mm_stream_calc_offset_preview(streamInfo, 868 &dim, 869 &mPaddingInfo, 870 &streamInfo->buf_planes); 871 break; 872 case CAM_STREAM_TYPE_POSTVIEW: 873 rc = mm_stream_calc_offset_post_view(streamInfo, 874 &dim, 875 &mPaddingInfo, 876 &streamInfo->buf_planes); 877 break; 878 case CAM_STREAM_TYPE_SNAPSHOT: 879 rc = mm_stream_calc_offset_snapshot(streamInfo->fmt, 880 &dim, 881 &mPaddingInfo, 882 &streamInfo->buf_planes); 883 break; 884 case CAM_STREAM_TYPE_OFFLINE_PROC: 885 rc = mm_stream_calc_offset_postproc(streamInfo, 886 &mPaddingInfo, 887 &streamInfo->buf_planes); 888 break; 889 case CAM_STREAM_TYPE_VIDEO: 890 rc = mm_stream_calc_offset_video(streamInfo->fmt, 891 &dim, &streamInfo->buf_planes); 892 break; 893 case CAM_STREAM_TYPE_RAW: 894 rc = mm_stream_calc_offset_raw(streamInfo->fmt, 895 &dim, 896 &mPaddingInfo, 897 &streamInfo->buf_planes); 898 break; 899 case CAM_STREAM_TYPE_ANALYSIS: 900 rc = mm_stream_calc_offset_analysis(streamInfo->fmt, 901 &dim, 902 &mPaddingInfo, 903 &streamInfo->buf_planes); 904 break; 905 case CAM_STREAM_TYPE_METADATA: 906 rc = mm_stream_calc_offset_metadata(&dim, 907 &mPaddingInfo, 908 &streamInfo->buf_planes); 909 break; 910 default: 911 LOGE("not supported for stream type %d", 912 streamInfo->stream_type); 913 rc = -1; 914 break; 915 } 916 return rc; 917 } 918 919 /*=========================================================================== 920 * FUNCTION : start 921 * 922 * DESCRIPTION: start stream. Will start main stream thread to handle stream 923 * related ops. 924 * 925 * PARAMETERS : none 926 * 927 * RETURN : int32_t type of status 928 * NO_ERROR -- success 929 * none-zero failure code 930 *==========================================================================*/ 931 int32_t QCameraStream::start() 932 { 933 int32_t rc = 0; 934 mDataQ.init(); 935 rc = mProcTh.launch(dataProcRoutine, this); 936 if (rc == NO_ERROR) { 937 m_bActive = true; 938 } 939 940 mCurMetaMemory = NULL; 941 mCurBufIndex = -1; 942 mCurMetaIndex = -1; 943 mFirstTimeStamp = 0; 944 memset (&mStreamMetaMemory, 0, 945 (sizeof(MetaMemory) * CAMERA_MIN_VIDEO_BATCH_BUFFERS)); 946 return rc; 947 } 948 949 /*=========================================================================== 950 * FUNCTION : stop 951 * 952 * DESCRIPTION: stop stream. Will stop main stream thread 953 * 954 * PARAMETERS : none 955 * 956 * RETURN : int32_t type of status 957 * NO_ERROR -- success 958 * none-zero failure code 959 *==========================================================================*/ 960 int32_t QCameraStream::stop() 961 { 962 int32_t rc = 0; 963 m_bActive = false; 964 mAllocator.waitForBackgroundTask(mAllocTaskId); 965 mAllocator.waitForBackgroundTask(mMapTaskId); 966 rc = mProcTh.exit(); 967 return rc; 968 } 969 970 /*=========================================================================== 971 * FUNCTION : syncRuntimeParams 972 * 973 * DESCRIPTION: query and sync runtime parameters like output crop 974 * buffer info etc. 975 * 976 * PARAMETERS : none 977 * 978 * RETURN : int32_t type of status 979 * NO_ERROR -- success 980 * none-zero failure code 981 *==========================================================================*/ 982 int32_t QCameraStream::syncRuntimeParams() 983 { 984 int32_t ret = NO_ERROR; 985 986 memset(&m_OutputCrop, 0, sizeof(cam_stream_parm_buffer_t)); 987 m_OutputCrop.type = CAM_STREAM_PARAM_TYPE_GET_OUTPUT_CROP; 988 989 ret = getParameter(m_OutputCrop); 990 if (ret != NO_ERROR) { 991 LOGE("stream getParameter for output crop failed"); 992 return ret; 993 } 994 995 memset(&m_ImgProp, 0, sizeof(cam_stream_parm_buffer_t)); 996 m_ImgProp.type = CAM_STREAM_PARAM_TYPE_GET_IMG_PROP; 997 998 ret = getParameter(m_ImgProp); 999 if (ret != NO_ERROR) { 1000 LOGE("stream getParameter for image prop failed"); 1001 return ret; 1002 } 1003 1004 return ret; 1005 } 1006 1007 /*=========================================================================== 1008 * FUNCTION : processZoomDone 1009 * 1010 * DESCRIPTION: process zoom done event 1011 * 1012 * PARAMETERS : 1013 * @previewWindoe : preview window ops table to set preview crop window 1014 * @crop_info : crop info 1015 * 1016 * RETURN : int32_t type of status 1017 * NO_ERROR -- success 1018 * none-zero failure code 1019 *==========================================================================*/ 1020 int32_t QCameraStream::processZoomDone(preview_stream_ops_t *previewWindow, 1021 cam_crop_data_t &crop_info) 1022 { 1023 int32_t rc = 0; 1024 1025 if (!m_bActive) { 1026 LOGL("Stream not active"); 1027 return NO_ERROR; 1028 } 1029 1030 // get stream param for crop info 1031 for (int i = 0; i < crop_info.num_of_streams; i++) { 1032 if (crop_info.crop_info[i].stream_id == mStreamInfo->stream_svr_id) { 1033 pthread_mutex_lock(&mCropLock); 1034 mCropInfo = crop_info.crop_info[i].crop; 1035 pthread_mutex_unlock(&mCropLock); 1036 1037 // update preview window crop if it's preview/postview stream 1038 if ( (previewWindow != NULL) && 1039 (mStreamInfo->stream_type == CAM_STREAM_TYPE_PREVIEW || 1040 mStreamInfo->stream_type == CAM_STREAM_TYPE_POSTVIEW) ) { 1041 rc = previewWindow->set_crop(previewWindow, 1042 mCropInfo.left, 1043 mCropInfo.top, 1044 mCropInfo.width, 1045 mCropInfo.height); 1046 } 1047 break; 1048 } 1049 } 1050 return rc; 1051 } 1052 1053 /*=========================================================================== 1054 * FUNCTION : processDataNotify 1055 * 1056 * DESCRIPTION: process stream data notify 1057 * 1058 * PARAMETERS : 1059 * @frame : stream frame received 1060 * 1061 * RETURN : int32_t type of status 1062 * NO_ERROR -- success 1063 * none-zero failure code 1064 *==========================================================================*/ 1065 int32_t QCameraStream::processDataNotify(mm_camera_super_buf_t *frame) 1066 { 1067 LOGD("\n"); 1068 1069 if (mDataQ.enqueue((void *)frame)) { 1070 return mProcTh.sendCmd(CAMERA_CMD_TYPE_DO_NEXT_JOB, FALSE, FALSE); 1071 } else { 1072 if (!m_bActive) { 1073 LOGW("Stream thread is not active, no ops here %d", getMyType()); 1074 } else { 1075 bufDone(frame); 1076 } 1077 free(frame); 1078 return NO_ERROR; 1079 } 1080 } 1081 1082 /*=========================================================================== 1083 * FUNCTION : dataNotifySYNCCB 1084 * 1085 * DESCRIPTION: This function registered with interface for 1086 * SYNC callback if SYNC callback registered. 1087 * 1088 * PARAMETERS : 1089 * @recvd_frame : stream frame received 1090 * @userdata : user data ptr 1091 * 1092 * RETURN : none 1093 *==========================================================================*/ 1094 void QCameraStream::dataNotifySYNCCB(mm_camera_super_buf_t *recvd_frame, 1095 void *userdata) 1096 { 1097 LOGD("\n"); 1098 QCameraStream* stream = (QCameraStream *)userdata; 1099 if (stream == NULL || 1100 recvd_frame == NULL || 1101 recvd_frame->bufs[0] == NULL || 1102 !validate_handle(stream->getMyHandle(), 1103 recvd_frame->bufs[0]->stream_id)) { 1104 LOGE("Not a valid stream to handle buf"); 1105 return; 1106 } 1107 if ((stream->mSyncCBEnabled) && (stream->mSYNCDataCB != NULL)) 1108 stream->mSYNCDataCB(recvd_frame, stream, stream->mUserData); 1109 return; 1110 } 1111 1112 /*=========================================================================== 1113 * FUNCTION : dataNotifyCB 1114 * 1115 * DESCRIPTION: callback for data notify. This function is registered with 1116 * mm-camera-interface to handle data notify 1117 * 1118 * PARAMETERS : 1119 * @recvd_frame : stream frame received 1120 * userdata : user data ptr 1121 * 1122 * RETURN : none 1123 *==========================================================================*/ 1124 void QCameraStream::dataNotifyCB(mm_camera_super_buf_t *recvd_frame, 1125 void *userdata) 1126 { 1127 LOGD("\n"); 1128 QCameraStream* stream = (QCameraStream *)userdata; 1129 if (stream == NULL || 1130 recvd_frame == NULL || 1131 recvd_frame->bufs[0] == NULL || 1132 !(validate_handle(stream->getMyHandle(), 1133 recvd_frame->bufs[0]->stream_id))) { 1134 LOGE("Not a valid stream to handle buf"); 1135 return; 1136 } 1137 1138 mm_camera_super_buf_t *frame = 1139 (mm_camera_super_buf_t *)malloc(sizeof(mm_camera_super_buf_t)); 1140 if (frame == NULL) { 1141 LOGE("No mem for mm_camera_buf_def_t"); 1142 stream->bufDone(recvd_frame); 1143 return; 1144 } 1145 *frame = *recvd_frame; 1146 stream->processDataNotify(frame); 1147 return; 1148 } 1149 1150 /*=========================================================================== 1151 * FUNCTION : dataProcRoutine 1152 * 1153 * DESCRIPTION: function to process data in the main stream thread 1154 * 1155 * PARAMETERS : 1156 * @data : user data ptr 1157 * 1158 * RETURN : none 1159 *==========================================================================*/ 1160 void *QCameraStream::dataProcRoutine(void *data) 1161 { 1162 int running = 1; 1163 int ret; 1164 QCameraStream *pme = (QCameraStream *)data; 1165 QCameraCmdThread *cmdThread = &pme->mProcTh; 1166 cmdThread->setName("CAM_strmDatProc"); 1167 1168 LOGD("E"); 1169 do { 1170 do { 1171 ret = cam_sem_wait(&cmdThread->cmd_sem); 1172 if (ret != 0 && errno != EINVAL) { 1173 LOGE("cam_sem_wait error (%s)", 1174 strerror(errno)); 1175 return NULL; 1176 } 1177 } while (ret != 0); 1178 1179 // we got notified about new cmd avail in cmd queue 1180 camera_cmd_type_t cmd = cmdThread->getCmd(); 1181 switch (cmd) { 1182 case CAMERA_CMD_TYPE_DO_NEXT_JOB: 1183 { 1184 LOGH("Do next job"); 1185 mm_camera_super_buf_t *frame = 1186 (mm_camera_super_buf_t *)pme->mDataQ.dequeue(); 1187 if (NULL != frame) { 1188 if (pme->mDataCB != NULL) { 1189 pme->mDataCB(frame, pme, pme->mUserData); 1190 } else { 1191 // no data cb routine, return buf here 1192 pme->bufDone(frame); 1193 free(frame); 1194 } 1195 } 1196 } 1197 break; 1198 case CAMERA_CMD_TYPE_EXIT: 1199 LOGH("Exit"); 1200 /* flush data buf queue */ 1201 pme->mDataQ.flush(); 1202 running = 0; 1203 break; 1204 default: 1205 break; 1206 } 1207 } while (running); 1208 LOGH("X"); 1209 return NULL; 1210 } 1211 1212 /*=========================================================================== 1213 * FUNCTION : bufDone 1214 * 1215 * DESCRIPTION: return stream buffer to kernel 1216 * 1217 * PARAMETERS : 1218 * @index : index of buffer to be returned 1219 * 1220 * RETURN : int32_t type of status 1221 * NO_ERROR -- success 1222 * none-zero failure code 1223 *==========================================================================*/ 1224 int32_t QCameraStream::bufDone(uint32_t index) 1225 { 1226 int32_t rc = NO_ERROR; 1227 1228 if (index >= mNumBufs || mBufDefs == NULL) 1229 return BAD_INDEX; 1230 1231 rc = mCamOps->qbuf(mCamHandle, mChannelHandle, &mBufDefs[index]); 1232 1233 if (rc < 0) 1234 return rc; 1235 1236 return rc; 1237 } 1238 1239 /*=========================================================================== 1240 * FUNCTION : bufDone 1241 * 1242 * DESCRIPTION: return a stream buf back to kernel 1243 * 1244 * PARAMETERS : 1245 * @super_buf : stream buf frame to be returned 1246 * 1247 * RETURN : int32_t type of status 1248 * NO_ERROR -- success 1249 * none-zero failure code 1250 *==========================================================================*/ 1251 int32_t QCameraStream::bufDone (mm_camera_super_buf_t *super_buf) 1252 { 1253 int32_t rc = NO_ERROR; 1254 for (uint32_t i = 0; i < super_buf->num_bufs; i++) { 1255 if (super_buf->bufs[i] != NULL) { 1256 rc |= bufDone(super_buf->bufs[i]->buf_idx); 1257 } 1258 } 1259 return rc; 1260 } 1261 1262 /*=========================================================================== 1263 * FUNCTION : bufDone 1264 * 1265 * DESCRIPTION: return stream buffer to kernel 1266 * 1267 * PARAMETERS : 1268 * @opaque : stream frame/metadata buf to be returned 1269 * @isMetaData: flag if returned opaque is a metadatabuf or the real frame ptr 1270 * 1271 * RETURN : int32_t type of status 1272 * NO_ERROR -- success 1273 * none-zero failure code 1274 *==========================================================================*/ 1275 int32_t QCameraStream::bufDone(const void *opaque, bool isMetaData) 1276 { 1277 int32_t rc = NO_ERROR; 1278 int index = -1; 1279 QCameraVideoMemory *mVideoMem = NULL; 1280 bool needPerfEvet = FALSE; 1281 1282 if ((mStreamInfo != NULL) 1283 && (mStreamInfo->streaming_mode == CAM_STREAMING_MODE_BATCH) 1284 && (mStreamBatchBufs != NULL)) { 1285 mVideoMem = (QCameraVideoMemory *)mStreamBatchBufs; 1286 } else if (mStreamBufs != NULL){ 1287 mVideoMem = (QCameraVideoMemory *)mStreamBufs; 1288 } 1289 1290 //Close and delete duplicated native handle and FD's. 1291 if (mVideoMem != NULL) { 1292 index = mVideoMem->getMatchBufIndex(opaque, isMetaData); 1293 needPerfEvet = mVideoMem->needPerfEvent(opaque, isMetaData); 1294 rc = mVideoMem->closeNativeHandle(opaque, isMetaData); 1295 if (rc != NO_ERROR) { 1296 LOGE("Invalid video metadata"); 1297 return rc; 1298 } 1299 } else { 1300 LOGE("Possible FD leak. Release recording called after stop"); 1301 } 1302 1303 if (index == -1 || index >= mNumBufs || mBufDefs == NULL) { 1304 LOGE("Cannot find buf for opaque data = %p", opaque); 1305 return BAD_INDEX; 1306 } 1307 1308 if (needPerfEvet == TRUE) { 1309 //Trigger Perf Flush event to back-end 1310 cam_stream_parm_buffer_t param; 1311 memset(¶m, 0, sizeof(cam_stream_parm_buffer_t)); 1312 param.type = CAM_STREAM_PARAM_TYPE_FLUSH_FRAME; 1313 rc = setParameter(param); 1314 } 1315 1316 if ((CAMERA_MIN_VIDEO_BATCH_BUFFERS > index) 1317 && mStreamMetaMemory[index].numBuffers > 0) { 1318 for (int i= 0; i < mStreamMetaMemory[index].numBuffers; i++) { 1319 uint8_t buf_idx = mStreamMetaMemory[index].buf_index[i]; 1320 bufDone((uint32_t)buf_idx); 1321 } 1322 mStreamMetaMemory[index].consumerOwned = FALSE; 1323 mStreamMetaMemory[index].numBuffers = 0; 1324 } else { 1325 LOGH("Buffer Index = %d, Frame Idx = %d", index, 1326 mBufDefs[index].frame_idx); 1327 rc = bufDone((uint32_t)index); 1328 } 1329 1330 return rc; 1331 } 1332 1333 /*=========================================================================== 1334 * FUNCTION : getNumQueuedBuf 1335 * 1336 * DESCRIPTION: return queued buffer count 1337 * 1338 * PARAMETERS : None 1339 * 1340 * RETURN : queued buffer count 1341 *==========================================================================*/ 1342 int32_t QCameraStream::getNumQueuedBuf() 1343 { 1344 int32_t rc = -1; 1345 if (mHandle > 0) { 1346 rc = mCamOps->get_queued_buf_count(mCamHandle, mChannelHandle, mHandle); 1347 } 1348 if (rc == -1) { 1349 LOGE("stream is not in active state. Invalid operation"); 1350 } 1351 return rc; 1352 } 1353 1354 /*=========================================================================== 1355 * FUNCTION : getBufs 1356 * 1357 * DESCRIPTION: allocate stream buffers 1358 * 1359 * PARAMETERS : 1360 * @offset : offset info of stream buffers 1361 * @num_bufs : number of buffers allocated 1362 * @initial_reg_flag: flag to indicate if buffer needs to be registered 1363 * at kernel initially 1364 * @bufs : output of allocated buffers 1365 * @ops_tbl : ptr to buf mapping/unmapping ops 1366 * 1367 * RETURN : int32_t type of status 1368 * NO_ERROR -- success 1369 * none-zero failure code 1370 *==========================================================================*/ 1371 int32_t QCameraStream::getBufs(cam_frame_len_offset_t *offset, 1372 uint8_t *num_bufs, 1373 uint8_t **initial_reg_flag, 1374 mm_camera_buf_def_t **bufs, 1375 mm_camera_map_unmap_ops_tbl_t *ops_tbl) 1376 { 1377 int rc = NO_ERROR; 1378 uint8_t *regFlags; 1379 1380 if (!ops_tbl) { 1381 LOGE("ops_tbl is NULL"); 1382 return INVALID_OPERATION; 1383 } 1384 1385 mFrameLenOffset = *offset; 1386 1387 uint8_t numBufAlloc = mNumBufs; 1388 mNumBufsNeedAlloc = 0; 1389 if (mDynBufAlloc) { 1390 numBufAlloc = CAMERA_MIN_ALLOCATED_BUFFERS; 1391 if (numBufAlloc > mNumBufs) { 1392 mDynBufAlloc = false; 1393 numBufAlloc = mNumBufs; 1394 } else { 1395 mNumBufsNeedAlloc = (uint8_t)(mNumBufs - numBufAlloc); 1396 } 1397 } 1398 1399 /* For some stream types, buffer allocation may have already begun 1400 * preemptively. If this is the case, we need to wait for the 1401 * preemptive allocation to complete before proceeding. */ 1402 mAllocator.waitForDeferredAlloc(mStreamInfo->stream_type); 1403 1404 //Allocate stream buffer 1405 mStreamBufs = mAllocator.allocateStreamBuf(mStreamInfo->stream_type, 1406 mFrameLenOffset.frame_len, mFrameLenOffset.mp[0].stride, 1407 mFrameLenOffset.mp[0].scanline, numBufAlloc); 1408 if (!mStreamBufs) { 1409 LOGE("Failed to allocate stream buffers"); 1410 return NO_MEMORY; 1411 } 1412 1413 mNumBufs = (uint8_t)(numBufAlloc + mNumBufsNeedAlloc); 1414 uint8_t numBufsToMap = mStreamBufs->getMappable(); 1415 1416 QCameraBufferMaps bufferMaps; 1417 for (uint32_t i = 0; i < numBufsToMap; i++) { 1418 ssize_t bufSize = mStreamBufs->getSize(i); 1419 if (BAD_INDEX == bufSize) { 1420 LOGE("Failed to retrieve buffer size (bad index)"); 1421 return INVALID_OPERATION; 1422 } 1423 1424 rc = bufferMaps.enqueue(CAM_MAPPING_BUF_TYPE_STREAM_BUF, 1425 0 /*stream id*/, i /*buf index*/, -1 /*plane index*/, 1426 0 /*cookie*/, mStreamBufs->getFd(i), bufSize, 1427 mStreamBufs->getPtr(i)); 1428 1429 if (rc < 0) { 1430 LOGE("Failed to map buffers"); 1431 return BAD_INDEX; 1432 } 1433 } 1434 1435 cam_buf_map_type_list bufMapList; 1436 rc = bufferMaps.getCamBufMapList(bufMapList); 1437 if (rc == NO_ERROR) { 1438 rc = ops_tbl->bundled_map_ops(&bufMapList, ops_tbl->userdata); 1439 } 1440 if (rc < 0) { 1441 LOGE("map_stream_buf failed: %d", rc); 1442 mStreamBufs->deallocate(); 1443 delete mStreamBufs; 1444 mStreamBufs = NULL; 1445 return INVALID_OPERATION; 1446 } 1447 1448 //regFlags array is allocated by us, but consumed and freed by mm-camera-interface 1449 regFlags = (uint8_t *)malloc(sizeof(uint8_t) * mNumBufs); 1450 if (!regFlags) { 1451 LOGE("Out of memory"); 1452 for (uint32_t i = 0; i < numBufsToMap; i++) { 1453 ops_tbl->unmap_ops(i, -1, CAM_MAPPING_BUF_TYPE_STREAM_BUF, ops_tbl->userdata); 1454 } 1455 mStreamBufs->deallocate(); 1456 delete mStreamBufs; 1457 mStreamBufs = NULL; 1458 return NO_MEMORY; 1459 } 1460 memset(regFlags, 0, sizeof(uint8_t) * mNumBufs); 1461 1462 mBufDefs = (mm_camera_buf_def_t *)malloc(mNumBufs * sizeof(mm_camera_buf_def_t)); 1463 if (mBufDefs == NULL) { 1464 LOGE("getRegFlags failed %d", rc); 1465 for (uint32_t i = 0; i < numBufsToMap; i++) { 1466 ops_tbl->unmap_ops(i, -1, CAM_MAPPING_BUF_TYPE_STREAM_BUF, ops_tbl->userdata); 1467 } 1468 mStreamBufs->deallocate(); 1469 delete mStreamBufs; 1470 mStreamBufs = NULL; 1471 free(regFlags); 1472 regFlags = NULL; 1473 return INVALID_OPERATION; 1474 } 1475 memset(mBufDefs, 0, mNumBufs * sizeof(mm_camera_buf_def_t)); 1476 for (uint32_t i = 0; i < numBufsToMap; i++) { 1477 mStreamBufs->getBufDef(mFrameLenOffset, mBufDefs[i], i); 1478 } 1479 1480 rc = mStreamBufs->getRegFlags(regFlags); 1481 if (rc < 0) { 1482 LOGE("getRegFlags failed %d", rc); 1483 for (uint32_t i = 0; i < numBufsToMap; i++) { 1484 ops_tbl->unmap_ops(i, -1, CAM_MAPPING_BUF_TYPE_STREAM_BUF, ops_tbl->userdata); 1485 } 1486 mStreamBufs->deallocate(); 1487 delete mStreamBufs; 1488 mStreamBufs = NULL; 1489 free(mBufDefs); 1490 mBufDefs = NULL; 1491 free(regFlags); 1492 regFlags = NULL; 1493 return INVALID_OPERATION; 1494 } 1495 1496 *num_bufs = mNumBufs; 1497 *initial_reg_flag = regFlags; 1498 *bufs = mBufDefs; 1499 LOGH("stream type: %d, mRegFlags: 0x%x, numBufs: %d", 1500 mStreamInfo->stream_type, regFlags, mNumBufs); 1501 1502 if (mNumBufsNeedAlloc > 0) { 1503 pthread_mutex_lock(&m_lock); 1504 wait_for_cond = TRUE; 1505 pthread_mutex_unlock(&m_lock); 1506 LOGH("Still need to allocate %d buffers", 1507 mNumBufsNeedAlloc); 1508 // start another thread to allocate the rest of buffers 1509 pthread_create(&mBufAllocPid, 1510 NULL, 1511 BufAllocRoutine, 1512 this); 1513 pthread_setname_np(mBufAllocPid, "CAM_strmBuf"); 1514 } 1515 return NO_ERROR; 1516 } 1517 1518 /*=========================================================================== 1519 * FUNCTION : getBufsDeferred 1520 * 1521 * DESCRIPTION: allocate deferred stream buffers 1522 * 1523 * PARAMETERS : 1524 * @offset : offset info of stream buffers 1525 * @num_bufs : number of buffers allocated 1526 * @initial_reg_flag: flag to indicate if buffer needs to be registered 1527 * at kernel initially 1528 * @bufs : output of allocated buffers 1529 * @ops_tbl : ptr to buf mapping/unmapping ops 1530 * 1531 * RETURN : int32_t type of status 1532 * NO_ERROR -- success 1533 * none-zero failure code 1534 *==========================================================================*/ 1535 int32_t QCameraStream::getBufsDeferred(__unused cam_frame_len_offset_t *offset, 1536 uint8_t *num_bufs, 1537 uint8_t **initial_reg_flag, 1538 mm_camera_buf_def_t **bufs, 1539 __unused mm_camera_map_unmap_ops_tbl_t *ops_tbl) 1540 { 1541 int32_t rc = NO_ERROR; 1542 // wait for allocation 1543 rc = mAllocator.waitForBackgroundTask(mAllocTaskId); 1544 if (rc != NO_ERROR) { 1545 LOGE("Allocation Failed"); 1546 return NO_MEMORY; 1547 } 1548 1549 if (!mRegFlags || !mBufDefs) { 1550 LOGE("reg flags or buf defs uninitialized"); 1551 return NO_MEMORY; 1552 } 1553 1554 *initial_reg_flag = mRegFlags; 1555 *num_bufs = mNumBufs; 1556 *bufs = mBufDefs; 1557 1558 LOGH("stream type: %d, mRegFlags: 0x%x, numBufs: %d", 1559 getMyType(), mRegFlags, mNumBufs); 1560 1561 return NO_ERROR; 1562 } 1563 /*=========================================================================== 1564 * FUNCTION : mapNewBuffer 1565 * 1566 * DESCRIPTION: map a new stream buffer 1567 * 1568 * PARAMETERS : 1569 * 1570 * RETURN : int32_t type of status 1571 * NO_ERROR -- success 1572 * none-zero failure code 1573 *==========================================================================*/ 1574 int32_t QCameraStream::mapNewBuffer(uint32_t index) 1575 { 1576 LOGH("E - index = %d", index); 1577 1578 int rc = NO_ERROR; 1579 1580 if (mStreamBufs == NULL) { 1581 LOGE("Invalid Operation"); 1582 return INVALID_OPERATION; 1583 } 1584 1585 ssize_t bufSize = mStreamBufs->getSize(index); 1586 if (BAD_INDEX == bufSize) { 1587 LOGE("Failed to retrieve buffer size (bad index)"); 1588 return INVALID_OPERATION; 1589 } 1590 1591 cam_buf_map_type_list bufMapList; 1592 rc = QCameraBufferMaps::makeSingletonBufMapList( 1593 CAM_MAPPING_BUF_TYPE_STREAM_BUF, 0 /*stream id*/, index, 1594 -1 /*plane index*/, 0 /*cookie*/, mStreamBufs->getFd(index), 1595 bufSize, bufMapList, mStreamBufs->getPtr(index)); 1596 1597 if (rc == NO_ERROR) { 1598 rc = m_MemOpsTbl.bundled_map_ops(&bufMapList, m_MemOpsTbl.userdata); 1599 } 1600 if (rc < 0) { 1601 LOGE("map_stream_buf failed: %d", rc); 1602 rc = INVALID_OPERATION; 1603 } else { 1604 mStreamBufs->getBufDef(mFrameLenOffset, mBufDefs[index], index); 1605 } 1606 1607 LOGH("X - rc = %d", rc); 1608 return rc; 1609 } 1610 1611 /*=========================================================================== 1612 * FUNCTION : allocateBuffers 1613 * 1614 * DESCRIPTION: allocate stream buffers 1615 * 1616 * PARAMETERS : 1617 * 1618 * RETURN : int32_t type of status 1619 * NO_ERROR -- success 1620 * none-zero failure code 1621 *==========================================================================*/ 1622 int32_t QCameraStream::allocateBuffers() 1623 { 1624 int32_t rc = NO_ERROR; 1625 1626 mFrameLenOffset = mStreamInfo->buf_planes.plane_info; 1627 1628 if (mStreamInfo->streaming_mode == CAM_STREAMING_MODE_BATCH) { 1629 return allocateBatchBufs(&mFrameLenOffset, 1630 &mNumBufs, &mRegFlags, 1631 &mBufDefs, NULL); 1632 } 1633 1634 /* This allocation is running in the deferred context, so it 1635 * is safe (and necessary) to assume any preemptive allocation 1636 * is already complete. Therefore, no need to wait here. */ 1637 1638 uint8_t numBufAlloc = mNumBufs; 1639 mNumBufsNeedAlloc = 0; 1640 if (mDynBufAlloc) { 1641 numBufAlloc = CAMERA_MIN_ALLOCATED_BUFFERS; 1642 if (numBufAlloc > mNumBufs) { 1643 mDynBufAlloc = false; 1644 numBufAlloc = mNumBufs; 1645 } else { 1646 mNumBufsNeedAlloc = (uint8_t)(mNumBufs - numBufAlloc); 1647 } 1648 } 1649 1650 //Allocate and map stream info buffer 1651 mStreamBufs = mAllocator.allocateStreamBuf(mStreamInfo->stream_type, 1652 mFrameLenOffset.frame_len, 1653 mFrameLenOffset.mp[0].stride, 1654 mFrameLenOffset.mp[0].scanline, 1655 numBufAlloc); 1656 1657 if (!mStreamBufs) { 1658 LOGE("Failed to allocate stream buffers"); 1659 return NO_MEMORY; 1660 } 1661 1662 mNumBufs = (uint8_t)(numBufAlloc + mNumBufsNeedAlloc); 1663 uint8_t numBufsToMap = mStreamBufs->getMappable(); 1664 1665 //regFlags array is allocated by us, 1666 // but consumed and freed by mm-camera-interface 1667 mRegFlags = (uint8_t *)malloc(sizeof(uint8_t) * mNumBufs); 1668 if (!mRegFlags) { 1669 LOGE("Out of memory"); 1670 for (uint32_t i = 0; i < numBufsToMap; i++) { 1671 unmapBuf(CAM_MAPPING_BUF_TYPE_STREAM_BUF, i, -1, NULL); 1672 } 1673 mStreamBufs->deallocate(); 1674 delete mStreamBufs; 1675 mStreamBufs = NULL; 1676 return NO_MEMORY; 1677 } 1678 memset(mRegFlags, 0, sizeof(uint8_t) * mNumBufs); 1679 1680 size_t bufDefsSize = mNumBufs * sizeof(mm_camera_buf_def_t); 1681 mBufDefs = (mm_camera_buf_def_t *)malloc(bufDefsSize); 1682 if (mBufDefs == NULL) { 1683 LOGE("getRegFlags failed %d", rc); 1684 for (uint32_t i = 0; i < numBufsToMap; i++) { 1685 unmapBuf(CAM_MAPPING_BUF_TYPE_STREAM_BUF, i, -1, NULL); 1686 } 1687 mStreamBufs->deallocate(); 1688 delete mStreamBufs; 1689 mStreamBufs = NULL; 1690 free(mRegFlags); 1691 mRegFlags = NULL; 1692 return INVALID_OPERATION; 1693 } 1694 memset(mBufDefs, 0, bufDefsSize); 1695 for (uint32_t i = 0; i < numBufsToMap; i++) { 1696 mStreamBufs->getBufDef(mFrameLenOffset, mBufDefs[i], i); 1697 } 1698 1699 rc = mStreamBufs->getRegFlags(mRegFlags); 1700 if (rc < 0) { 1701 LOGE("getRegFlags failed %d", rc); 1702 for (uint32_t i = 0; i < numBufsToMap; i++) { 1703 unmapBuf(CAM_MAPPING_BUF_TYPE_STREAM_BUF, i, -1, NULL); 1704 } 1705 mStreamBufs->deallocate(); 1706 delete mStreamBufs; 1707 mStreamBufs = NULL; 1708 free(mBufDefs); 1709 mBufDefs = NULL; 1710 free(mRegFlags); 1711 mRegFlags = NULL; 1712 return INVALID_OPERATION; 1713 } 1714 1715 if (mNumBufsNeedAlloc > 0) { 1716 pthread_mutex_lock(&m_lock); 1717 wait_for_cond = TRUE; 1718 pthread_mutex_unlock(&m_lock); 1719 LOGH("Still need to allocate %d buffers", 1720 mNumBufsNeedAlloc); 1721 // start another thread to allocate the rest of buffers 1722 pthread_create(&mBufAllocPid, 1723 NULL, 1724 BufAllocRoutine, 1725 this); 1726 pthread_setname_np(mBufAllocPid, "CAM_strmBufAlloc"); 1727 } 1728 return rc; 1729 } 1730 1731 /*=========================================================================== 1732 * FUNCTION : mapBuffers 1733 * 1734 * DESCRIPTION: map stream buffers 1735 * 1736 * PARAMETERS : 1737 * 1738 * RETURN : int32_t type of status 1739 * NO_ERROR -- success 1740 * none-zero failure code 1741 *==========================================================================*/ 1742 int32_t QCameraStream::mapBuffers() 1743 { 1744 int32_t rc = NO_ERROR; 1745 QCameraBufferMaps bufferMaps; 1746 1747 rc = mAllocator.waitForBackgroundTask(mAllocTaskId); 1748 if (rc != NO_ERROR) { 1749 LOGE("Allocation Failed"); 1750 return NO_MEMORY; 1751 } 1752 1753 if (mStreamBufs == NULL) { 1754 LOGE("Stream buffers not allocated"); 1755 return UNKNOWN_ERROR; 1756 } 1757 1758 uint8_t numBufsToMap = mStreamBufs->getMappable(); 1759 for (uint32_t i = 0; i < numBufsToMap; i++) { 1760 ssize_t bufSize = mStreamBufs->getSize(i); 1761 if (BAD_INDEX != bufSize) { 1762 rc = bufferMaps.enqueue(CAM_MAPPING_BUF_TYPE_STREAM_BUF, mHandle, 1763 i /*buf index*/, -1 /*plane index*/, 0 /*cookie*/, 1764 mStreamBufs->getFd(i), bufSize, 1765 mStreamBufs->getPtr(i)); 1766 1767 if (rc < 0) { 1768 LOGE("Failed to map buffers"); 1769 rc = BAD_INDEX; 1770 break; 1771 } 1772 } else { 1773 LOGE("Bad index %u", i); 1774 rc = BAD_INDEX; 1775 break; 1776 } 1777 } 1778 1779 cam_buf_map_type_list bufMapList; 1780 if (rc == NO_ERROR) { 1781 rc = bufferMaps.getCamBufMapList(bufMapList); 1782 } 1783 if (rc == NO_ERROR) { 1784 rc = mapBufs(bufMapList, NULL); 1785 } 1786 return rc; 1787 } 1788 1789 /*=========================================================================== 1790 * FUNCTION : allocateBatchBufs 1791 * 1792 * DESCRIPTION: allocate stream batch buffers and stream buffers 1793 * 1794 * PARAMETERS : 1795 * @offset : offset info of stream buffers 1796 * @num_bufs : number of buffers allocated 1797 * @initial_reg_flag: flag to indicate if buffer needs to be registered 1798 * at kernel initially 1799 * @bufs : output of allocated buffers 1800 * @plane_bufs : output of allocated plane buffers 1801 * @ops_tbl : ptr to buf mapping/unmapping ops 1802 * 1803 * RETURN : int32_t type of status 1804 * NO_ERROR -- success 1805 * none-zero failure code 1806 *==========================================================================*/ 1807 int32_t QCameraStream::allocateBatchBufs(cam_frame_len_offset_t *offset, 1808 uint8_t *num_bufs, uint8_t **initial_reg_flag, 1809 mm_camera_buf_def_t **bufs, mm_camera_map_unmap_ops_tbl_t *ops_tbl) 1810 { 1811 int rc = NO_ERROR; 1812 uint8_t *regFlags; 1813 QCameraBufferMaps bufferMaps; 1814 QCameraBufferMaps planeBufferMaps; 1815 1816 mFrameLenOffset = *offset; 1817 1818 LOGH("Batch Buffer allocation stream type = %d", getMyType()); 1819 1820 //Allocate stream batch buffer 1821 mStreamBatchBufs = mAllocator.allocateStreamUserBuf (mStreamInfo); 1822 if (!mStreamBatchBufs) { 1823 LOGE("Failed to allocate stream batch buffers"); 1824 return NO_MEMORY; 1825 } 1826 1827 uint8_t numBufsToMap = mStreamBatchBufs->getMappable(); 1828 1829 //map batch buffers 1830 for (uint32_t i = 0; i < numBufsToMap; i++) { 1831 rc = bufferMaps.enqueue(CAM_MAPPING_BUF_TYPE_STREAM_USER_BUF, 1832 0 /*stream id*/, i /*buf index*/, -1 /*plane index*/, 1833 0 /*cookie*/, mStreamBatchBufs->getFd(i), 1834 mNumBufs, mStreamBatchBufs->getPtr(i)); 1835 1836 if (rc < 0) { 1837 LOGE("Failed to map buffers"); 1838 rc = BAD_INDEX; 1839 break; 1840 } 1841 } 1842 1843 cam_buf_map_type_list bufMapList; 1844 if (rc == NO_ERROR) { 1845 rc = bufferMaps.getCamBufMapList(bufMapList); 1846 } 1847 if (rc == NO_ERROR) { 1848 rc = mapBufs(bufMapList, ops_tbl); 1849 } 1850 if (rc < 0) { 1851 LOGE("Failed to map stream batch buffers"); 1852 mStreamBatchBufs->deallocate(); 1853 delete mStreamBatchBufs; 1854 mStreamBatchBufs = NULL; 1855 return NO_MEMORY; 1856 } 1857 1858 /*calculate stream Buffer count*/ 1859 mNumPlaneBufs = 1860 (mNumBufs * mStreamInfo->user_buf_info.frame_buf_cnt); 1861 1862 /* For some stream types, buffer allocation may have already begun 1863 * preemptively. If this is the case, we need to wait for the 1864 * preemptive allocation to complete before proceeding. */ 1865 mAllocator.waitForDeferredAlloc(mStreamInfo->stream_type); 1866 1867 //Allocate stream buffer 1868 mStreamBufs = mAllocator.allocateStreamBuf(mStreamInfo->stream_type, 1869 mFrameLenOffset.frame_len,mFrameLenOffset.mp[0].stride, 1870 mFrameLenOffset.mp[0].scanline,mNumPlaneBufs); 1871 if (!mStreamBufs) { 1872 LOGE("Failed to allocate stream buffers"); 1873 rc = NO_MEMORY; 1874 goto err1; 1875 } 1876 1877 //Map plane stream buffers 1878 for (uint32_t i = 0; i < mNumPlaneBufs; i++) { 1879 ssize_t bufSize = mStreamBufs->getSize(i); 1880 if (BAD_INDEX != bufSize) { 1881 rc = planeBufferMaps.enqueue(CAM_MAPPING_BUF_TYPE_STREAM_BUF, 1882 0 /*stream id*/, i /*buf index*/, -1 /*plane index*/, 1883 0 /*cookie*/, mStreamBufs->getFd(i), bufSize, 1884 mStreamBufs->getPtr(i)); 1885 1886 if (rc < 0) { 1887 LOGE("Failed to map buffers"); 1888 mStreamBufs->deallocate(); 1889 delete mStreamBufs; 1890 mStreamBufs = NULL; 1891 rc = INVALID_OPERATION; 1892 goto err1; 1893 } 1894 } else { 1895 LOGE("Failed to retrieve buffer size (bad index)"); 1896 mStreamBufs->deallocate(); 1897 delete mStreamBufs; 1898 mStreamBufs = NULL; 1899 rc = INVALID_OPERATION; 1900 goto err1; 1901 } 1902 } 1903 1904 cam_buf_map_type_list planeBufMapList; 1905 rc = planeBufferMaps.getCamBufMapList(planeBufMapList); 1906 if (rc == NO_ERROR) { 1907 rc = mapBufs(planeBufMapList, ops_tbl); 1908 } 1909 1910 if (rc < 0) { 1911 LOGE("map_stream_buf failed: %d", rc); 1912 mStreamBufs->deallocate(); 1913 delete mStreamBufs; 1914 mStreamBufs = NULL; 1915 rc = INVALID_OPERATION; 1916 goto err1; 1917 } 1918 1919 LOGD("BATCH Buf Count = %d, Plane Buf Cnt = %d", 1920 mNumBufs, mNumPlaneBufs); 1921 1922 //regFlags array is allocated by us, but consumed and freed by mm-camera-interface 1923 regFlags = (uint8_t *)malloc(sizeof(uint8_t) * mNumBufs); 1924 if (!regFlags) { 1925 LOGE("Out of memory"); 1926 for (uint32_t i = 0; i < mNumPlaneBufs; i++) { 1927 unmapBuf(CAM_MAPPING_BUF_TYPE_STREAM_BUF, i, -1, ops_tbl); 1928 } 1929 mStreamBufs->deallocate(); 1930 delete mStreamBufs; 1931 mStreamBufs = NULL; 1932 rc = NO_MEMORY; 1933 goto err1; 1934 } 1935 memset(regFlags, 0, sizeof(uint8_t) * mNumBufs); 1936 for (uint32_t i = 0; i < mNumBufs; i++) { 1937 regFlags[i] = 1; 1938 } 1939 1940 mBufDefs = (mm_camera_buf_def_t *)malloc(mNumBufs * sizeof(mm_camera_buf_def_t)); 1941 if (mBufDefs == NULL) { 1942 LOGE("getRegFlags failed %d", rc); 1943 for (uint32_t i = 0; i < mNumPlaneBufs; i++) { 1944 unmapBuf(CAM_MAPPING_BUF_TYPE_STREAM_BUF, i, -1, ops_tbl); 1945 } 1946 mStreamBufs->deallocate(); 1947 delete mStreamBufs; 1948 mStreamBufs = NULL; 1949 free(regFlags); 1950 regFlags = NULL; 1951 rc = INVALID_OPERATION; 1952 goto err1; 1953 } 1954 memset(mBufDefs, 0, mNumBufs * sizeof(mm_camera_buf_def_t)); 1955 1956 mPlaneBufDefs = (mm_camera_buf_def_t *) 1957 malloc(mNumPlaneBufs * (sizeof(mm_camera_buf_def_t))); 1958 if (mPlaneBufDefs == NULL) { 1959 LOGE("No Memory"); 1960 free(regFlags); 1961 regFlags = NULL; 1962 free(mBufDefs); 1963 mBufDefs = NULL; 1964 for (uint32_t i = 0; i < mNumPlaneBufs; i++) { 1965 unmapBuf(CAM_MAPPING_BUF_TYPE_STREAM_BUF, i, -1, ops_tbl); 1966 } 1967 mStreamBufs->deallocate(); 1968 delete mStreamBufs; 1969 mStreamBufs = NULL; 1970 free(regFlags); 1971 regFlags = NULL; 1972 rc = INVALID_OPERATION; 1973 goto err1; 1974 } 1975 memset(mPlaneBufDefs, 0, 1976 mNumPlaneBufs * (sizeof(mm_camera_buf_def_t))); 1977 1978 for (uint32_t i = 0; i < mStreamInfo->num_bufs; i++) { 1979 mStreamBatchBufs->getUserBufDef(mStreamInfo->user_buf_info, 1980 mBufDefs[i], i, mFrameLenOffset, mPlaneBufDefs, 1981 mStreamBufs); 1982 } 1983 1984 *num_bufs = mNumBufs; 1985 *initial_reg_flag = regFlags; 1986 *bufs = mBufDefs; 1987 LOGH("stream type: %d, numBufs: %d mNumPlaneBufs: %d", 1988 mStreamInfo->stream_type, mNumBufs, mNumPlaneBufs); 1989 1990 return NO_ERROR; 1991 1992 err1: 1993 mStreamBatchBufs->deallocate(); 1994 delete mStreamBatchBufs; 1995 mStreamBatchBufs = NULL; 1996 return rc; 1997 } 1998 1999 2000 /*=========================================================================== 2001 * FUNCTION : releaseBuffs 2002 * 2003 * DESCRIPTION: method to deallocate stream buffers 2004 * 2005 * PARAMETERS : 2006 * 2007 * RETURN : int32_t type of status 2008 * NO_ERROR -- success 2009 * none-zero failure code 2010 *==========================================================================*/ 2011 int32_t QCameraStream::releaseBuffs() 2012 { 2013 int rc = NO_ERROR; 2014 2015 if (mBufAllocPid != 0) { 2016 cond_signal(true); 2017 LOGD("wait for buf allocation thread dead"); 2018 pthread_join(mBufAllocPid, NULL); 2019 mBufAllocPid = 0; 2020 LOGD("return from buf allocation thread"); 2021 } 2022 2023 if (mStreamInfo->streaming_mode == CAM_STREAMING_MODE_BATCH) { 2024 return releaseBatchBufs(NULL); 2025 } 2026 2027 if ((NULL != mBufDefs) && (mStreamBufs != NULL)) { 2028 uint8_t numBufsToUnmap = mStreamBufs->getMappable(); 2029 for (uint32_t i = 0; i < numBufsToUnmap; i++) { 2030 rc = unmapBuf(CAM_MAPPING_BUF_TYPE_STREAM_BUF, i, -1, NULL); 2031 if (rc < 0) { 2032 LOGE("map_stream_buf failed: %d", rc); 2033 } 2034 } 2035 2036 // mBufDefs just keep a ptr to the buffer 2037 // mm-camera-interface own the buffer, so no need to free 2038 mBufDefs = NULL; 2039 memset(&mFrameLenOffset, 0, sizeof(mFrameLenOffset)); 2040 } 2041 if (!mStreamBufsAcquired && (mStreamBufs != NULL)) { 2042 mStreamBufs->deallocate(); 2043 delete mStreamBufs; 2044 mStreamBufs = NULL; 2045 } 2046 return rc; 2047 } 2048 2049 /*=========================================================================== 2050 * FUNCTION : releaseBatchBufs 2051 * 2052 * DESCRIPTION: method to deallocate stream buffers and batch buffers 2053 * 2054 * PARAMETERS : 2055 * @ops_tbl : ptr to buf mapping/unmapping ops 2056 * 2057 * RETURN : int32_t type of status 2058 * NO_ERROR -- success 2059 * none-zero failure code 2060 2061 *==========================================================================*/ 2062 int32_t QCameraStream::releaseBatchBufs(mm_camera_map_unmap_ops_tbl_t *ops_tbl) 2063 { 2064 int rc = NO_ERROR; 2065 2066 if (NULL != mPlaneBufDefs) { 2067 for (uint32_t i = 0; i < mNumPlaneBufs; i++) { 2068 rc = unmapBuf(CAM_MAPPING_BUF_TYPE_STREAM_BUF, i, -1, ops_tbl); 2069 if (rc < 0) { 2070 LOGE("map_stream_buf failed: %d", rc); 2071 } 2072 } 2073 2074 // mBufDefs just keep a ptr to the buffer 2075 // mm-camera-interface own the buffer, so no need to free 2076 mPlaneBufDefs = NULL; 2077 memset(&mFrameLenOffset, 0, sizeof(mFrameLenOffset)); 2078 mNumPlaneBufs = 0; 2079 } 2080 2081 if (mStreamBufs != NULL) { 2082 mStreamBufs->deallocate(); 2083 delete mStreamBufs; 2084 } 2085 2086 mBufDefs = NULL; 2087 2088 if (mStreamBatchBufs != NULL) { 2089 for (uint8_t i = 0; i < mStreamBatchBufs->getCnt(); i++) { 2090 unmapBuf(CAM_MAPPING_BUF_TYPE_STREAM_USER_BUF, i, -1, ops_tbl); 2091 } 2092 mStreamBatchBufs->deallocate(); 2093 delete mStreamBatchBufs; 2094 mStreamBatchBufs = NULL; 2095 } 2096 return rc; 2097 2098 } 2099 2100 /*=========================================================================== 2101 * FUNCTION : BufAllocRoutine 2102 * 2103 * DESCRIPTION: function to allocate additional stream buffers 2104 * 2105 * PARAMETERS : 2106 * @data : user data ptr 2107 * 2108 * RETURN : none 2109 *==========================================================================*/ 2110 void *QCameraStream::BufAllocRoutine(void *data) 2111 { 2112 QCameraStream *pme = (QCameraStream *)data; 2113 int32_t rc = NO_ERROR; 2114 2115 LOGH("E"); 2116 pme->cond_wait(); 2117 if (pme->mNumBufsNeedAlloc > 0) { 2118 uint8_t numBufAlloc = (uint8_t)(pme->mNumBufs - pme->mNumBufsNeedAlloc); 2119 rc = pme->mAllocator.allocateMoreStreamBuf(pme->mStreamBufs, 2120 pme->mFrameLenOffset.frame_len, 2121 pme->mNumBufsNeedAlloc); 2122 if (rc != NO_ERROR) { 2123 LOGE("Failed to allocate buffers"); 2124 pme->mNumBufsNeedAlloc = 0; 2125 return NULL; 2126 } 2127 2128 pme->mNumBufsNeedAlloc = 0; 2129 QCameraBufferMaps bufferMaps; 2130 for (uint32_t i = numBufAlloc; i < pme->mNumBufs; i++) { 2131 ssize_t bufSize = pme->mStreamBufs->getSize(i); 2132 if (BAD_INDEX == bufSize) { 2133 LOGE("Failed to retrieve buffer size (bad index)"); 2134 return NULL; 2135 } 2136 2137 rc = bufferMaps.enqueue(CAM_MAPPING_BUF_TYPE_STREAM_BUF, 2138 pme->mHandle, i /*buf index*/, -1 /*plane index*/, 2139 0 /*cookie*/, pme->mStreamBufs->getFd(i), bufSize, 2140 pme->mStreamBufs->getPtr(i)); 2141 2142 if (rc < 0) { 2143 LOGE("Failed to map buffers"); 2144 return NULL; 2145 } 2146 } 2147 2148 cam_buf_map_type_list bufMapList; 2149 rc = bufferMaps.getCamBufMapList(bufMapList); 2150 if (rc == NO_ERROR) { 2151 rc = pme->m_MemOpsTbl.bundled_map_ops(&bufMapList, pme->m_MemOpsTbl.userdata); 2152 } 2153 if (rc != 0) { 2154 LOGE("Failed to map buffers with return code %d", rc); 2155 return NULL; 2156 } 2157 2158 for (uint32_t i = numBufAlloc; i < pme->mNumBufs; i++) { 2159 pme->mStreamBufs->getBufDef(pme->mFrameLenOffset, pme->mBufDefs[i], i); 2160 pme->mCamOps->qbuf(pme->mCamHandle, pme->mChannelHandle, 2161 &pme->mBufDefs[i]); 2162 } 2163 } 2164 LOGH("X"); 2165 return NULL; 2166 } 2167 2168 /*=========================================================================== 2169 * FUNCTION : cond_signal 2170 * 2171 * DESCRIPTION: signal if flag "wait_for_cond" is set 2172 * 2173 *==========================================================================*/ 2174 void QCameraStream::cond_signal(bool forceExit) 2175 { 2176 pthread_mutex_lock(&m_lock); 2177 if(wait_for_cond == TRUE){ 2178 wait_for_cond = FALSE; 2179 if (forceExit) { 2180 mNumBufsNeedAlloc = 0; 2181 } 2182 pthread_cond_signal(&m_cond); 2183 } 2184 pthread_mutex_unlock(&m_lock); 2185 } 2186 2187 2188 /*=========================================================================== 2189 * FUNCTION : cond_wait 2190 * 2191 * DESCRIPTION: wait on if flag "wait_for_cond" is set 2192 * 2193 *==========================================================================*/ 2194 void QCameraStream::cond_wait() 2195 { 2196 pthread_mutex_lock(&m_lock); 2197 while (wait_for_cond == TRUE) { 2198 pthread_cond_wait(&m_cond, &m_lock); 2199 } 2200 pthread_mutex_unlock(&m_lock); 2201 } 2202 2203 /*=========================================================================== 2204 * FUNCTION : putBufs 2205 * 2206 * DESCRIPTION: deallocate stream buffers 2207 * 2208 * PARAMETERS : 2209 * @ops_tbl : ptr to buf mapping/unmapping ops 2210 * 2211 * RETURN : int32_t type of status 2212 * NO_ERROR -- success 2213 * none-zero failure code 2214 *==========================================================================*/ 2215 int32_t QCameraStream::putBufs(mm_camera_map_unmap_ops_tbl_t *ops_tbl) 2216 { 2217 int rc = NO_ERROR; 2218 2219 if (mBufAllocPid != 0) { 2220 cond_signal(true); 2221 LOGL("wait for buf allocation thread dead"); 2222 pthread_join(mBufAllocPid, NULL); 2223 mBufAllocPid = 0; 2224 LOGL("return from buf allocation thread"); 2225 } 2226 2227 uint8_t numBufsToUnmap = mStreamBufs->getMappable(); 2228 for (uint32_t i = 0; i < numBufsToUnmap; i++) { 2229 rc = ops_tbl->unmap_ops(i, -1, CAM_MAPPING_BUF_TYPE_STREAM_BUF, ops_tbl->userdata); 2230 if (rc < 0) { 2231 LOGE("map_stream_buf failed: %d", rc); 2232 } 2233 } 2234 mBufDefs = NULL; // mBufDefs just keep a ptr to the buffer 2235 // mm-camera-interface own the buffer, so no need to free 2236 memset(&mFrameLenOffset, 0, sizeof(mFrameLenOffset)); 2237 if ( !mStreamBufsAcquired ) { 2238 mStreamBufs->deallocate(); 2239 delete mStreamBufs; 2240 mStreamBufs = NULL; 2241 } 2242 2243 return rc; 2244 } 2245 2246 /*=========================================================================== 2247 * FUNCTION : putBufsDeffered 2248 * 2249 * DESCRIPTION: function to deallocate deffered stream buffers 2250 * 2251 * PARAMETERS : none 2252 * 2253 * RETURN : int32_t type of status 2254 * NO_ERROR -- success 2255 * none-zero failure code 2256 *==========================================================================*/ 2257 int32_t QCameraStream::putBufsDeffered() 2258 { 2259 if (mBufAllocPid != 0) { 2260 cond_signal(true); 2261 LOGH("%s: wait for buf allocation thread dead", __func__); 2262 // Wait for the allocation of additional stream buffers 2263 pthread_join(mBufAllocPid, NULL); 2264 mBufAllocPid = 0; 2265 LOGH("%s: return from buf allocation thread", __func__); 2266 } 2267 // Deallocation of the deffered stream buffers handled separately 2268 return NO_ERROR; 2269 } 2270 2271 /*=========================================================================== 2272 * FUNCTION : invalidateBuf 2273 * 2274 * DESCRIPTION: invalidate a specific stream buffer 2275 * 2276 * PARAMETERS : 2277 * @index : index of the buffer to invalidate 2278 * 2279 * RETURN : int32_t type of status 2280 * NO_ERROR -- success 2281 * none-zero failure code 2282 *==========================================================================*/ 2283 int32_t QCameraStream::invalidateBuf(uint32_t index) 2284 { 2285 if (mStreamBufs == NULL) { 2286 LOGE("Invalid Operation"); 2287 return INVALID_OPERATION; 2288 } 2289 return mStreamBufs->invalidateCache(index); 2290 } 2291 2292 /*=========================================================================== 2293 * FUNCTION : cleanInvalidateBuf 2294 * 2295 * DESCRIPTION: clean invalidate a specific stream buffer 2296 * 2297 * PARAMETERS : 2298 * @index : index of the buffer to clean invalidate 2299 * 2300 * RETURN : int32_t type of status 2301 * NO_ERROR -- success 2302 * none-zero failure code 2303 *==========================================================================*/ 2304 int32_t QCameraStream::cleanInvalidateBuf(uint32_t index) 2305 { 2306 if (mStreamBufs == NULL) { 2307 LOGE("Invalid Operation"); 2308 return INVALID_OPERATION; 2309 } 2310 return mStreamBufs->cleanInvalidateCache(index); 2311 } 2312 2313 /*=========================================================================== 2314 * FUNCTION : cleanBuf 2315 * 2316 * DESCRIPTION: clean a specific stream buffer 2317 * 2318 * PARAMETERS : 2319 * @index : index of the buffer to clean 2320 * 2321 * RETURN : int32_t type of status 2322 * NO_ERROR -- success 2323 * none-zero failure code 2324 *==========================================================================*/ 2325 int32_t QCameraStream::cleanBuf(uint32_t index) 2326 { 2327 if (mStreamBufs == NULL) { 2328 LOGE("Invalid Operation"); 2329 return INVALID_OPERATION; 2330 } 2331 return mStreamBufs->cleanCache(index); 2332 } 2333 2334 /*=========================================================================== 2335 * FUNCTION : isTypeOf 2336 * 2337 * DESCRIPTION: helper function to determine if the stream is of the queried type 2338 * 2339 * PARAMETERS : 2340 * @type : stream type as of queried 2341 * 2342 * RETURN : true/false 2343 *==========================================================================*/ 2344 bool QCameraStream::isTypeOf(cam_stream_type_t type) 2345 { 2346 if (mStreamInfo != NULL && (mStreamInfo->stream_type == type)) { 2347 return true; 2348 } else { 2349 return false; 2350 } 2351 } 2352 2353 /*=========================================================================== 2354 * FUNCTION : isOrignalTypeOf 2355 * 2356 * DESCRIPTION: helper function to determine if the original stream is of the 2357 * queried type if it's reproc stream 2358 * 2359 * PARAMETERS : 2360 * @type : stream type as of queried 2361 * 2362 * RETURN : true/false 2363 *==========================================================================*/ 2364 bool QCameraStream::isOrignalTypeOf(cam_stream_type_t type) 2365 { 2366 if (mStreamInfo != NULL && 2367 mStreamInfo->stream_type == CAM_STREAM_TYPE_OFFLINE_PROC && 2368 mStreamInfo->reprocess_config.pp_type == CAM_ONLINE_REPROCESS_TYPE && 2369 mStreamInfo->reprocess_config.online.input_stream_type == type) { 2370 return true; 2371 } else if ( 2372 mStreamInfo != NULL && 2373 mStreamInfo->stream_type == CAM_STREAM_TYPE_OFFLINE_PROC && 2374 mStreamInfo->reprocess_config.pp_type == CAM_OFFLINE_REPROCESS_TYPE && 2375 mStreamInfo->reprocess_config.offline.input_type == type) { 2376 return true; 2377 } else { 2378 return false; 2379 } 2380 } 2381 2382 /*=========================================================================== 2383 * FUNCTION : getMyType 2384 * 2385 * DESCRIPTION: return stream type 2386 * 2387 * PARAMETERS : none 2388 * 2389 * RETURN : stream type 2390 *==========================================================================*/ 2391 cam_stream_type_t QCameraStream::getMyType() 2392 { 2393 if (mStreamInfo != NULL) { 2394 return mStreamInfo->stream_type; 2395 } else { 2396 return CAM_STREAM_TYPE_DEFAULT; 2397 } 2398 } 2399 2400 /*=========================================================================== 2401 * FUNCTION : getMyOriginalType 2402 * 2403 * DESCRIPTION: return stream type 2404 * 2405 * PARAMETERS : none 2406 * 2407 * RETURN : stream type 2408 *==========================================================================*/ 2409 cam_stream_type_t QCameraStream::getMyOriginalType() 2410 { 2411 if (mStreamInfo != NULL) { 2412 if (mStreamInfo->stream_type == CAM_STREAM_TYPE_OFFLINE_PROC && 2413 mStreamInfo->reprocess_config.pp_type == CAM_ONLINE_REPROCESS_TYPE) { 2414 return mStreamInfo->reprocess_config.online.input_stream_type; 2415 } else if (mStreamInfo->stream_type == CAM_STREAM_TYPE_OFFLINE_PROC && 2416 mStreamInfo->reprocess_config.pp_type == CAM_OFFLINE_REPROCESS_TYPE) { 2417 return mStreamInfo->reprocess_config.offline.input_type; 2418 } else { 2419 return mStreamInfo->stream_type; 2420 } 2421 } else { 2422 return CAM_STREAM_TYPE_DEFAULT; 2423 } 2424 } 2425 2426 /*=========================================================================== 2427 * FUNCTION : getFrameOffset 2428 * 2429 * DESCRIPTION: query stream buffer frame offset info 2430 * 2431 * PARAMETERS : 2432 * @offset : reference to struct to store the queried frame offset info 2433 * 2434 * RETURN : int32_t type of status 2435 * NO_ERROR -- success 2436 * none-zero failure code 2437 *==========================================================================*/ 2438 int32_t QCameraStream::getFrameOffset(cam_frame_len_offset_t &offset) 2439 { 2440 if (NULL == mStreamInfo) { 2441 return NO_INIT; 2442 } 2443 2444 offset = mFrameLenOffset; 2445 if ((ROTATE_90 == mOnlineRotation) || (ROTATE_270 == mOnlineRotation) 2446 || (offset.frame_len == 0) || (offset.num_planes == 0)) { 2447 // Re-calculate frame offset in case of online rotation 2448 cam_stream_info_t streamInfo = *mStreamInfo; 2449 getFrameDimension(streamInfo.dim); 2450 calcOffset(&streamInfo); 2451 offset = streamInfo.buf_planes.plane_info; 2452 } 2453 2454 return 0; 2455 } 2456 2457 /*=========================================================================== 2458 * FUNCTION : getCropInfo 2459 * 2460 * DESCRIPTION: query crop info of the stream 2461 * 2462 * PARAMETERS : 2463 * @crop : reference to struct to store the queried crop info 2464 * 2465 * RETURN : int32_t type of status 2466 * NO_ERROR -- success 2467 * none-zero failure code 2468 *==========================================================================*/ 2469 int32_t QCameraStream::getCropInfo(cam_rect_t &crop) 2470 { 2471 pthread_mutex_lock(&mCropLock); 2472 crop = mCropInfo; 2473 pthread_mutex_unlock(&mCropLock); 2474 return NO_ERROR; 2475 } 2476 2477 /*=========================================================================== 2478 * FUNCTION : setCropInfo 2479 * 2480 * DESCRIPTION: set crop info of the stream 2481 * 2482 * PARAMETERS : 2483 * @crop : struct to store new crop info 2484 * 2485 * RETURN : int32_t type of status 2486 * NO_ERROR -- success 2487 * none-zero failure code 2488 *==========================================================================*/ 2489 int32_t QCameraStream::setCropInfo(cam_rect_t crop) 2490 { 2491 pthread_mutex_lock(&mCropLock); 2492 mCropInfo = crop; 2493 pthread_mutex_unlock(&mCropLock); 2494 return NO_ERROR; 2495 } 2496 2497 /*=========================================================================== 2498 * FUNCTION : getFrameDimension 2499 * 2500 * DESCRIPTION: query stream frame dimension info 2501 * 2502 * PARAMETERS : 2503 * @dim : reference to struct to store the queried frame dimension 2504 * 2505 * RETURN : int32_t type of status 2506 * NO_ERROR -- success 2507 * none-zero failure code 2508 *==========================================================================*/ 2509 int32_t QCameraStream::getFrameDimension(cam_dimension_t &dim) 2510 { 2511 if (mStreamInfo != NULL) { 2512 if ((ROTATE_90 == mOnlineRotation) || (ROTATE_270 == mOnlineRotation)) { 2513 dim.width = mStreamInfo->dim.height; 2514 dim.height = mStreamInfo->dim.width; 2515 } else { 2516 dim = mStreamInfo->dim; 2517 } 2518 return 0; 2519 } 2520 return -1; 2521 } 2522 2523 /*=========================================================================== 2524 * FUNCTION : getFormat 2525 * 2526 * DESCRIPTION: query stream format 2527 * 2528 * PARAMETERS : 2529 * @fmt : reference to stream format 2530 * 2531 * RETURN : int32_t type of status 2532 * NO_ERROR -- success 2533 * none-zero failure code 2534 *==========================================================================*/ 2535 int32_t QCameraStream::getFormat(cam_format_t &fmt) 2536 { 2537 if (mStreamInfo != NULL) { 2538 fmt = mStreamInfo->fmt; 2539 return 0; 2540 } 2541 return -1; 2542 } 2543 2544 /*=========================================================================== 2545 * FUNCTION : getMyServerID 2546 * 2547 * DESCRIPTION: query server stream ID 2548 * 2549 * PARAMETERS : None 2550 * 2551 * RETURN : stream ID from server 2552 *==========================================================================*/ 2553 uint32_t QCameraStream::getMyServerID() { 2554 if (mStreamInfo != NULL) { 2555 return mStreamInfo->stream_svr_id; 2556 } else { 2557 return 0; 2558 } 2559 } 2560 2561 /*=========================================================================== 2562 * FUNCTION : acquireStreamBufs 2563 * 2564 * DESCRIPTION: acquire stream buffers and postpone their release. 2565 * 2566 * PARAMETERS : None 2567 * 2568 * RETURN : int32_t type of status 2569 * NO_ERROR -- success 2570 * none-zero failure code 2571 *==========================================================================*/ 2572 int32_t QCameraStream::acquireStreamBufs() 2573 { 2574 mStreamBufsAcquired = true; 2575 2576 return NO_ERROR; 2577 } 2578 2579 /*=========================================================================== 2580 * FUNCTION : mapBuf 2581 * 2582 * DESCRIPTION: map stream related buffer to backend server 2583 * 2584 * PARAMETERS : 2585 * @buf_type : mapping type of buffer 2586 * @buf_idx : index of buffer 2587 * @plane_idx: plane index 2588 * @fd : fd of the buffer 2589 * @buffer : buffer address 2590 * @size : lenght of the buffer 2591 * @ops_tbl : ptr to buf mapping/unmapping ops 2592 * 2593 * RETURN : int32_t type of status 2594 * NO_ERROR -- success 2595 * none-zero failure code 2596 *==========================================================================*/ 2597 int32_t QCameraStream::mapBuf(uint8_t buf_type, uint32_t buf_idx, 2598 int32_t plane_idx, int fd, void *buffer, size_t size, 2599 mm_camera_map_unmap_ops_tbl_t *ops_tbl) 2600 { 2601 cam_buf_map_type_list bufMapList; 2602 int32_t rc = QCameraBufferMaps::makeSingletonBufMapList( 2603 (cam_mapping_buf_type)buf_type, mHandle, buf_idx, plane_idx, 2604 0 /*cookie*/, fd, size, bufMapList, buffer); 2605 2606 if (rc != NO_ERROR) { 2607 return rc; 2608 } 2609 2610 return mapBufs(bufMapList, ops_tbl); 2611 } 2612 2613 /*=========================================================================== 2614 * FUNCTION : mapBufs 2615 * 2616 * DESCRIPTION: map stream related buffers to backend server 2617 * 2618 * PARAMETERS : 2619 * @bufMapList : buffer mapping information 2620 * @ops_tbl : ptr to buf mapping/unmapping ops 2621 * 2622 * RETURN : int32_t type of status 2623 * NO_ERROR -- success 2624 * none-zero failure code 2625 *==========================================================================*/ 2626 2627 int32_t QCameraStream::mapBufs(cam_buf_map_type_list bufMapList, 2628 __unused mm_camera_map_unmap_ops_tbl_t *ops_tbl) 2629 { 2630 if (m_MemOpsTbl.bundled_map_ops != NULL) { 2631 return m_MemOpsTbl.bundled_map_ops(&bufMapList, m_MemOpsTbl.userdata); 2632 } else { 2633 return mCamOps->map_stream_bufs(mCamHandle, mChannelHandle, 2634 &bufMapList); 2635 } 2636 2637 } 2638 2639 /*=========================================================================== 2640 * FUNCTION : unmapBuf 2641 * 2642 * DESCRIPTION: unmap stream related buffer to backend server 2643 * 2644 * PARAMETERS : 2645 * @buf_type : mapping type of buffer 2646 * @buf_idx : index of buffer 2647 * @plane_idx: plane index 2648 * @ops_tbl : ptr to buf mapping/unmapping ops 2649 * 2650 * RETURN : int32_t type of status 2651 * NO_ERROR -- success 2652 * none-zero failure code 2653 *==========================================================================*/ 2654 int32_t QCameraStream::unmapBuf(uint8_t buf_type, uint32_t buf_idx, int32_t plane_idx, 2655 mm_camera_map_unmap_ops_tbl_t *ops_tbl) 2656 { 2657 if (ops_tbl != NULL) { 2658 return ops_tbl->unmap_ops(buf_idx, plane_idx, 2659 (cam_mapping_buf_type)buf_type, ops_tbl->userdata); 2660 } else { 2661 return mCamOps->unmap_stream_buf(mCamHandle, mChannelHandle, 2662 mHandle, buf_type, buf_idx, plane_idx); 2663 } 2664 } 2665 2666 /*=========================================================================== 2667 * FUNCTION : setParameter 2668 * 2669 * DESCRIPTION: set stream based parameters 2670 * 2671 * PARAMETERS : 2672 * @param : ptr to parameters to be set 2673 * 2674 * RETURN : int32_t type of status 2675 * NO_ERROR -- success 2676 * none-zero failure code 2677 *==========================================================================*/ 2678 int32_t QCameraStream::setParameter(cam_stream_parm_buffer_t ¶m) 2679 { 2680 int32_t rc = NO_ERROR; 2681 pthread_mutex_lock(&mParameterLock); 2682 mStreamInfo->parm_buf = param; 2683 rc = mCamOps->set_stream_parms(mCamHandle, 2684 mChannelHandle, 2685 mHandle, 2686 &mStreamInfo->parm_buf); 2687 if (rc == NO_ERROR) { 2688 param = mStreamInfo->parm_buf; 2689 } 2690 pthread_mutex_unlock(&mParameterLock); 2691 return rc; 2692 } 2693 2694 /*=========================================================================== 2695 * FUNCTION : getParameter 2696 * 2697 * DESCRIPTION: get stream based parameters 2698 * 2699 * PARAMETERS : 2700 * @param : ptr to parameters to be red 2701 * 2702 * RETURN : int32_t type of status 2703 * NO_ERROR -- success 2704 * none-zero failure code 2705 *==========================================================================*/ 2706 int32_t QCameraStream::getParameter(cam_stream_parm_buffer_t ¶m) 2707 { 2708 int32_t rc = NO_ERROR; 2709 pthread_mutex_lock(&mParameterLock); 2710 mStreamInfo->parm_buf = param; 2711 rc = mCamOps->get_stream_parms(mCamHandle, 2712 mChannelHandle, 2713 mHandle, 2714 &mStreamInfo->parm_buf); 2715 if (rc == NO_ERROR) { 2716 param = mStreamInfo->parm_buf; 2717 } 2718 pthread_mutex_unlock(&mParameterLock); 2719 return rc; 2720 } 2721 2722 /*=========================================================================== 2723 * FUNCTION : releaseFrameData 2724 * 2725 * DESCRIPTION: callback function to release frame data node 2726 * 2727 * PARAMETERS : 2728 * @data : ptr to post process input data 2729 * @user_data : user data ptr (QCameraReprocessor) 2730 * 2731 * RETURN : None 2732 *==========================================================================*/ 2733 void QCameraStream::releaseFrameData(void *data, void *user_data) 2734 { 2735 QCameraStream *pme = (QCameraStream *)user_data; 2736 mm_camera_super_buf_t *frame = (mm_camera_super_buf_t *)data; 2737 if (NULL != pme) { 2738 pme->bufDone(frame->bufs[0]->buf_idx); 2739 } 2740 } 2741 2742 /*=========================================================================== 2743 * FUNCTION : configStream 2744 * 2745 * DESCRIPTION: send stream configuration to back end 2746 * 2747 * PARAMETERS : 2748 * 2749 * RETURN : int32_t type of status 2750 * NO_ERROR -- success 2751 * none-zero failure code 2752 *==========================================================================*/ 2753 int32_t QCameraStream::configStream() 2754 { 2755 int rc = NO_ERROR; 2756 2757 // Configure the stream 2758 mm_camera_stream_config_t stream_config; 2759 stream_config.stream_info = mStreamInfo; 2760 stream_config.mem_vtbl = mMemVtbl; 2761 stream_config.stream_cb_sync = NULL; 2762 stream_config.stream_cb = dataNotifyCB; 2763 stream_config.padding_info = mPaddingInfo; 2764 stream_config.userdata = this; 2765 rc = mCamOps->config_stream(mCamHandle, 2766 mChannelHandle, mHandle, &stream_config); 2767 if (rc < 0) { 2768 LOGE("Failed to config stream, rc = %d", rc); 2769 mCamOps->unmap_stream_buf(mCamHandle, 2770 mChannelHandle, 2771 mHandle, 2772 CAM_MAPPING_BUF_TYPE_STREAM_INFO, 2773 0, 2774 -1); 2775 return UNKNOWN_ERROR; 2776 } 2777 2778 return rc; 2779 } 2780 2781 /*=========================================================================== 2782 * FUNCTION : setSyncDataCB 2783 * 2784 * DESCRIPTION: register callback with mm-interface for this stream 2785 * 2786 * PARAMETERS : 2787 @stream_cb : Callback function 2788 * 2789 * RETURN : int32_t type of status 2790 * NO_ERROR -- success 2791 * non-zero failure code 2792 *==========================================================================*/ 2793 int32_t QCameraStream::setSyncDataCB(stream_cb_routine data_cb) 2794 { 2795 int32_t rc = NO_ERROR; 2796 2797 if (mCamOps != NULL) { 2798 mSYNCDataCB = data_cb; 2799 rc = mCamOps->register_stream_buf_cb(mCamHandle, 2800 mChannelHandle, mHandle, dataNotifySYNCCB, MM_CAMERA_STREAM_CB_TYPE_SYNC, 2801 this); 2802 if (rc == NO_ERROR) { 2803 mSyncCBEnabled = TRUE; 2804 return rc; 2805 } 2806 } 2807 LOGE("Interface handle is NULL"); 2808 return UNKNOWN_ERROR; 2809 } 2810 2811 /*=========================================================================== 2812 * FUNCTION : processCameraControl 2813 * 2814 * DESCRIPTION: Suspend and resume camera 2815 * 2816 * PARAMETERS : 2817 * 2818 * RETURN : int32_t type of status 2819 * NO_ERROR -- success 2820 * none-zero failure code 2821 *==========================================================================*/ 2822 int32_t QCameraStream::processCameraControl(uint32_t camState) 2823 { 2824 mActiveCameras = camState; 2825 return NO_ERROR; 2826 } 2827 2828 /*=========================================================================== 2829 * FUNCTION : switchStreamCb 2830 * 2831 * DESCRIPTION: switch stream's in case of dual camera 2832 * 2833 * PARAMETERS : 2834 * @camMaster : Master camera 2835 * 2836 * RETURN : int32_t type of status 2837 * NO_ERROR -- success 2838 * none-zero failure code 2839 *==========================================================================*/ 2840 int32_t QCameraStream::switchStreamCb(uint32_t camMaster) 2841 { 2842 int32_t ret = NO_ERROR; 2843 if (needCbSwitch() && (camMaster != mMasterCamera)) { 2844 ret = mCamOps->handle_frame_sync_cb(mCamHandle, mChannelHandle, 2845 mHandle, MM_CAMERA_CB_REQ_TYPE_SWITCH); 2846 } 2847 // Update master camera 2848 mMasterCamera = camMaster; 2849 return ret; 2850 } 2851 2852 /*=========================================================================== 2853 * FUNCTION : needCbSwitch 2854 * 2855 * DESCRIPTION: Function to enable callback switch based on availability of 2856 * spatial alignment 2857 * 2858 * PARAMETERS : 2859 * 2860 * RETURN : int32_t type of status 2861 * NO_ERROR -- success 2862 * none-zero failure code 2863 *==========================================================================*/ 2864 bool QCameraStream::needCbSwitch() 2865 { 2866 if (!isDualStream()) { 2867 return false; 2868 } 2869 2870 if ((mStreamInfo->pp_config.feature_mask & CAM_QTI_FEATURE_SAT) 2871 || (mStreamInfo->pp_config.feature_mask & CAM_QTI_FEATURE_SAC) 2872 || (needFrameSync()) 2873 || (getMyType() == CAM_STREAM_TYPE_SNAPSHOT) 2874 || (getMyType() == CAM_STREAM_TYPE_METADATA)) { 2875 return false; 2876 } else { 2877 return true; 2878 } 2879 } 2880 2881 /*=========================================================================== 2882 * FUNCTION : needFrameSync 2883 * 2884 * DESCRIPTION: Function to enable stream frame buffer sync 2885 * 2886 * PARAMETERS : 2887 * 2888 * RETURN : int32_t type of status 2889 * NO_ERROR -- success 2890 * none-zero failure code 2891 *==========================================================================*/ 2892 bool QCameraStream::needFrameSync() 2893 { 2894 if (!isDualStream()) { 2895 return false; 2896 } 2897 2898 switch (getMyType()) { 2899 default: 2900 return false; 2901 break; 2902 } 2903 } 2904 2905 /*=========================================================================== 2906 * FUNCTION : setBundleInfo 2907 * 2908 * DESCRIPTION: set bundle for this stream to MCT 2909 * 2910 * PARAMETERS : 2911 * 2912 * RETURN : int32_t type of status 2913 * NO_ERROR -- success 2914 * none-zero failure code 2915 *==========================================================================*/ 2916 int32_t QCameraStream::setBundleInfo() 2917 { 2918 int32_t ret = NO_ERROR; 2919 cam_bundle_config_t bundleInfo; 2920 2921 if ((isTypeOf(CAM_STREAM_TYPE_METADATA)) 2922 || (isTypeOf(CAM_STREAM_TYPE_OFFLINE_PROC))) { 2923 // Skip metadata for reprocess now because PP module cannot handle meta data 2924 // May need furthur discussion if Imaginglib need meta data 2925 return ret; 2926 } 2927 2928 cam_stream_parm_buffer_t param, aux_param; 2929 uint32_t active_handle = get_main_camera_handle(mChannelHandle); 2930 memset(&bundleInfo, 0, sizeof(bundleInfo)); 2931 if (active_handle) { 2932 ret = mCamOps->get_bundle_info(mCamHandle, active_handle, 2933 &bundleInfo); 2934 memset(¶m, 0, sizeof(cam_stream_parm_buffer_t)); 2935 param.type = CAM_STREAM_PARAM_TYPE_SET_BUNDLE_INFO; 2936 param.bundleInfo = bundleInfo; 2937 } 2938 2939 memset(&aux_param, 0, sizeof(cam_stream_parm_buffer_t)); 2940 if (isDualStream()) { 2941 active_handle = get_aux_camera_handle(mChannelHandle); 2942 memset(&bundleInfo, 0, sizeof(bundleInfo)); 2943 ret = mCamOps->get_bundle_info(mCamHandle, active_handle, 2944 &bundleInfo); 2945 aux_param.type = CAM_STREAM_PARAM_TYPE_SET_BUNDLE_INFO; 2946 aux_param.bundleInfo = bundleInfo; 2947 } 2948 pthread_mutex_lock(&mParameterLock); 2949 mStreamInfo->parm_buf = param; 2950 if ((aux_param.bundleInfo.num_of_streams > 1) 2951 && (mStreamInfo->aux_str_info != NULL)) { 2952 mStreamInfo->aux_str_info->parm_buf = aux_param; 2953 } 2954 2955 if ((mStreamInfo->parm_buf.bundleInfo.num_of_streams > 1) 2956 || (((mStreamInfo->aux_str_info != NULL) && 2957 (mStreamInfo->aux_str_info->parm_buf.bundleInfo.num_of_streams > 1)))) { 2958 ret = mCamOps->set_stream_parms(mCamHandle, 2959 mChannelHandle, mHandle, 2960 &mStreamInfo->parm_buf); 2961 } 2962 pthread_mutex_unlock(&mParameterLock); 2963 if (ret != NO_ERROR) { 2964 LOGE("stream setParameter for set bundle failed"); 2965 return ret; 2966 } 2967 return ret; 2968 } 2969 2970 /*=========================================================================== 2971 * FUNCTION : handleCacheOps 2972 * 2973 * DESCRIPTION: handle cache ops for this stream buffer 2974 * 2975 * PARAMETERS : 2976 @buf : stream buffer 2977 * 2978 * RETURN : int32_t type of status 2979 * NO_ERROR -- success 2980 * non-zero failure code 2981 *==========================================================================*/ 2982 int32_t QCameraStream::handleCacheOps(mm_camera_buf_def_t* buf) 2983 { 2984 int32_t rc = 0; 2985 if( !buf) { 2986 LOGE("Error!! buf_info: %p", buf); 2987 rc = -1; 2988 return rc; 2989 } 2990 if ((mMemVtbl.clean_invalidate_buf == NULL) || 2991 (mMemVtbl.invalidate_buf == NULL) || 2992 (mMemVtbl.clean_buf == NULL)) { 2993 LOGI("Clean/Invalidate cache ops not supported"); 2994 rc = -1; 2995 return rc; 2996 } 2997 2998 LOGH("[CACHE_OPS] Stream type: %d buf index: %d cache ops flags: 0x%x", 2999 buf->stream_type, buf->buf_idx, buf->cache_flags); 3000 3001 if ((buf->cache_flags & CPU_HAS_READ_WRITTEN) == 3002 CPU_HAS_READ_WRITTEN) { 3003 rc = mMemVtbl.clean_invalidate_buf( 3004 buf->buf_idx, mMemVtbl.user_data); 3005 } else if ((buf->cache_flags & CPU_HAS_READ) == 3006 CPU_HAS_READ) { 3007 rc = mMemVtbl.invalidate_buf( 3008 buf->buf_idx, mMemVtbl.user_data); 3009 } else if ((buf->cache_flags & CPU_HAS_WRITTEN) == 3010 CPU_HAS_WRITTEN) { 3011 rc = mMemVtbl.clean_buf( 3012 buf->buf_idx, mMemVtbl.user_data); 3013 } 3014 if (rc != 0) { 3015 LOGW("Warning!! Clean/Invalidate cache failed on buffer index: %d", 3016 buf->buf_idx); 3017 } 3018 // Reset buffer cache flags after cache ops 3019 buf->cache_flags = 0; 3020 return rc; 3021 } 3022 3023 3024 }; // namespace qcamera 3025