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