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