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); 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 1308 if (rc < 0) { 1309 LOGE("Failed to map buffers"); 1310 return BAD_INDEX; 1311 } 1312 } 1313 1314 cam_buf_map_type_list bufMapList; 1315 rc = bufferMaps.getCamBufMapList(bufMapList); 1316 if (rc == NO_ERROR) { 1317 rc = ops_tbl->bundled_map_ops(&bufMapList, ops_tbl->userdata); 1318 } 1319 if (rc < 0) { 1320 LOGE("map_stream_buf failed: %d", rc); 1321 mStreamBufs->deallocate(); 1322 delete mStreamBufs; 1323 mStreamBufs = NULL; 1324 return INVALID_OPERATION; 1325 } 1326 1327 //regFlags array is allocated by us, but consumed and freed by mm-camera-interface 1328 regFlags = (uint8_t *)malloc(sizeof(uint8_t) * mNumBufs); 1329 if (!regFlags) { 1330 LOGE("Out of memory"); 1331 for (uint32_t i = 0; i < numBufsToMap; i++) { 1332 ops_tbl->unmap_ops(i, -1, CAM_MAPPING_BUF_TYPE_STREAM_BUF, ops_tbl->userdata); 1333 } 1334 mStreamBufs->deallocate(); 1335 delete mStreamBufs; 1336 mStreamBufs = NULL; 1337 return NO_MEMORY; 1338 } 1339 memset(regFlags, 0, sizeof(uint8_t) * mNumBufs); 1340 1341 mBufDefs = (mm_camera_buf_def_t *)malloc(mNumBufs * sizeof(mm_camera_buf_def_t)); 1342 if (mBufDefs == NULL) { 1343 LOGE("getRegFlags failed %d", rc); 1344 for (uint32_t i = 0; i < numBufsToMap; i++) { 1345 ops_tbl->unmap_ops(i, -1, CAM_MAPPING_BUF_TYPE_STREAM_BUF, ops_tbl->userdata); 1346 } 1347 mStreamBufs->deallocate(); 1348 delete mStreamBufs; 1349 mStreamBufs = NULL; 1350 free(regFlags); 1351 regFlags = NULL; 1352 return INVALID_OPERATION; 1353 } 1354 memset(mBufDefs, 0, mNumBufs * sizeof(mm_camera_buf_def_t)); 1355 for (uint32_t i = 0; i < numBufsToMap; i++) { 1356 mStreamBufs->getBufDef(mFrameLenOffset, mBufDefs[i], i); 1357 } 1358 1359 rc = mStreamBufs->getRegFlags(regFlags); 1360 if (rc < 0) { 1361 LOGE("getRegFlags failed %d", rc); 1362 for (uint32_t i = 0; i < numBufsToMap; i++) { 1363 ops_tbl->unmap_ops(i, -1, CAM_MAPPING_BUF_TYPE_STREAM_BUF, ops_tbl->userdata); 1364 } 1365 mStreamBufs->deallocate(); 1366 delete mStreamBufs; 1367 mStreamBufs = NULL; 1368 free(mBufDefs); 1369 mBufDefs = NULL; 1370 free(regFlags); 1371 regFlags = NULL; 1372 return INVALID_OPERATION; 1373 } 1374 1375 *num_bufs = mNumBufs; 1376 *initial_reg_flag = regFlags; 1377 *bufs = mBufDefs; 1378 LOGH("stream type: %d, mRegFlags: 0x%x, numBufs: %d", 1379 mStreamInfo->stream_type, regFlags, mNumBufs); 1380 1381 if (mNumBufsNeedAlloc > 0) { 1382 pthread_mutex_lock(&m_lock); 1383 wait_for_cond = TRUE; 1384 pthread_mutex_unlock(&m_lock); 1385 LOGH("Still need to allocate %d buffers", 1386 mNumBufsNeedAlloc); 1387 // start another thread to allocate the rest of buffers 1388 pthread_create(&mBufAllocPid, 1389 NULL, 1390 BufAllocRoutine, 1391 this); 1392 pthread_setname_np(mBufAllocPid, "CAM_strmBuf"); 1393 } 1394 1395 return NO_ERROR; 1396 } 1397 1398 /*=========================================================================== 1399 * FUNCTION : getBufsDeferred 1400 * 1401 * DESCRIPTION: allocate deferred stream buffers 1402 * 1403 * PARAMETERS : 1404 * @offset : offset info of stream buffers 1405 * @num_bufs : number of buffers allocated 1406 * @initial_reg_flag: flag to indicate if buffer needs to be registered 1407 * at kernel initially 1408 * @bufs : output of allocated buffers 1409 * @ops_tbl : ptr to buf mapping/unmapping ops 1410 * 1411 * RETURN : int32_t type of status 1412 * NO_ERROR -- success 1413 * none-zero failure code 1414 *==========================================================================*/ 1415 int32_t QCameraStream::getBufsDeferred(__unused cam_frame_len_offset_t *offset, 1416 uint8_t *num_bufs, 1417 uint8_t **initial_reg_flag, 1418 mm_camera_buf_def_t **bufs, 1419 __unused mm_camera_map_unmap_ops_tbl_t *ops_tbl) 1420 { 1421 int32_t rc = NO_ERROR; 1422 // wait for allocation 1423 rc = mAllocator.waitForBackgroundTask(mAllocTaskId); 1424 if (rc != NO_ERROR) { 1425 LOGE("Allocation Failed"); 1426 return NO_MEMORY; 1427 } 1428 1429 if (!mRegFlags || !mBufDefs) { 1430 LOGE("reg flags or buf defs uninitialized"); 1431 return NO_MEMORY; 1432 } 1433 1434 *initial_reg_flag = mRegFlags; 1435 *num_bufs = mNumBufs; 1436 *bufs = mBufDefs; 1437 1438 LOGH("stream type: %d, mRegFlags: 0x%x, numBufs: %d", 1439 getMyType(), mRegFlags, mNumBufs); 1440 1441 return NO_ERROR; 1442 } 1443 /*=========================================================================== 1444 * FUNCTION : mapNewBuffer 1445 * 1446 * DESCRIPTION: map a new stream buffer 1447 * 1448 * PARAMETERS : 1449 * 1450 * RETURN : int32_t type of status 1451 * NO_ERROR -- success 1452 * none-zero failure code 1453 *==========================================================================*/ 1454 int32_t QCameraStream::mapNewBuffer(uint32_t index) 1455 { 1456 LOGH("E - index = %d", index); 1457 1458 int rc = NO_ERROR; 1459 1460 if (mStreamBufs == NULL) { 1461 LOGE("Invalid Operation"); 1462 return INVALID_OPERATION; 1463 } 1464 1465 ssize_t bufSize = mStreamBufs->getSize(index); 1466 if (BAD_INDEX == bufSize) { 1467 LOGE("Failed to retrieve buffer size (bad index)"); 1468 return INVALID_OPERATION; 1469 } 1470 1471 cam_buf_map_type_list bufMapList; 1472 rc = QCameraBufferMaps::makeSingletonBufMapList( 1473 CAM_MAPPING_BUF_TYPE_STREAM_BUF, 0 /*stream id*/, index, 1474 -1 /*plane index*/, 0 /*cookie*/, mStreamBufs->getFd(index), 1475 bufSize, bufMapList); 1476 1477 if (rc == NO_ERROR) { 1478 rc = m_MemOpsTbl.bundled_map_ops(&bufMapList, m_MemOpsTbl.userdata); 1479 } 1480 if (rc < 0) { 1481 LOGE("map_stream_buf failed: %d", rc); 1482 rc = INVALID_OPERATION; 1483 } else { 1484 mStreamBufs->getBufDef(mFrameLenOffset, mBufDefs[index], index); 1485 } 1486 1487 LOGH("X - rc = %d", rc); 1488 return rc; 1489 } 1490 1491 /*=========================================================================== 1492 * FUNCTION : allocateBuffers 1493 * 1494 * DESCRIPTION: allocate stream buffers 1495 * 1496 * PARAMETERS : 1497 * 1498 * RETURN : int32_t type of status 1499 * NO_ERROR -- success 1500 * none-zero failure code 1501 *==========================================================================*/ 1502 int32_t QCameraStream::allocateBuffers() 1503 { 1504 int32_t rc = NO_ERROR; 1505 1506 mFrameLenOffset = mStreamInfo->buf_planes.plane_info; 1507 1508 if (mStreamInfo->streaming_mode == CAM_STREAMING_MODE_BATCH) { 1509 return allocateBatchBufs(&mFrameLenOffset, 1510 &mNumBufs, &mRegFlags, 1511 &mBufDefs, NULL); 1512 } 1513 1514 /* This allocation is running in the deferred context, so it 1515 * is safe (and necessary) to assume any preemptive allocation 1516 * is already complete. Therefore, no need to wait here. */ 1517 1518 uint8_t numBufAlloc = mNumBufs; 1519 mNumBufsNeedAlloc = 0; 1520 if (mDynBufAlloc) { 1521 numBufAlloc = CAMERA_MIN_ALLOCATED_BUFFERS; 1522 if (numBufAlloc > mNumBufs) { 1523 mDynBufAlloc = false; 1524 numBufAlloc = mNumBufs; 1525 } else { 1526 mNumBufsNeedAlloc = (uint8_t)(mNumBufs - numBufAlloc); 1527 } 1528 } 1529 1530 //Allocate and map stream info buffer 1531 mStreamBufs = mAllocator.allocateStreamBuf(mStreamInfo->stream_type, 1532 mFrameLenOffset.frame_len, 1533 mFrameLenOffset.mp[0].stride, 1534 mFrameLenOffset.mp[0].scanline, 1535 numBufAlloc); 1536 1537 if (!mStreamBufs) { 1538 LOGE("Failed to allocate stream buffers"); 1539 return NO_MEMORY; 1540 } 1541 1542 mNumBufs = (uint8_t)(numBufAlloc + mNumBufsNeedAlloc); 1543 uint8_t numBufsToMap = mStreamBufs->getMappable(); 1544 1545 //regFlags array is allocated by us, 1546 // but consumed and freed by mm-camera-interface 1547 mRegFlags = (uint8_t *)malloc(sizeof(uint8_t) * mNumBufs); 1548 if (!mRegFlags) { 1549 LOGE("Out of memory"); 1550 for (uint32_t i = 0; i < numBufsToMap; i++) { 1551 unmapBuf(CAM_MAPPING_BUF_TYPE_STREAM_BUF, i, -1, NULL); 1552 } 1553 mStreamBufs->deallocate(); 1554 delete mStreamBufs; 1555 mStreamBufs = NULL; 1556 return NO_MEMORY; 1557 } 1558 memset(mRegFlags, 0, sizeof(uint8_t) * mNumBufs); 1559 1560 size_t bufDefsSize = mNumBufs * sizeof(mm_camera_buf_def_t); 1561 mBufDefs = (mm_camera_buf_def_t *)malloc(bufDefsSize); 1562 if (mBufDefs == NULL) { 1563 LOGE("getRegFlags failed %d", rc); 1564 for (uint32_t i = 0; i < numBufsToMap; i++) { 1565 unmapBuf(CAM_MAPPING_BUF_TYPE_STREAM_BUF, i, -1, NULL); 1566 } 1567 mStreamBufs->deallocate(); 1568 delete mStreamBufs; 1569 mStreamBufs = NULL; 1570 free(mRegFlags); 1571 mRegFlags = NULL; 1572 return INVALID_OPERATION; 1573 } 1574 memset(mBufDefs, 0, bufDefsSize); 1575 for (uint32_t i = 0; i < numBufsToMap; i++) { 1576 mStreamBufs->getBufDef(mFrameLenOffset, mBufDefs[i], i); 1577 } 1578 1579 rc = mStreamBufs->getRegFlags(mRegFlags); 1580 if (rc < 0) { 1581 LOGE("getRegFlags failed %d", rc); 1582 for (uint32_t i = 0; i < numBufsToMap; i++) { 1583 unmapBuf(CAM_MAPPING_BUF_TYPE_STREAM_BUF, i, -1, NULL); 1584 } 1585 mStreamBufs->deallocate(); 1586 delete mStreamBufs; 1587 mStreamBufs = NULL; 1588 free(mBufDefs); 1589 mBufDefs = NULL; 1590 free(mRegFlags); 1591 mRegFlags = NULL; 1592 return INVALID_OPERATION; 1593 } 1594 1595 if (mNumBufsNeedAlloc > 0) { 1596 pthread_mutex_lock(&m_lock); 1597 wait_for_cond = TRUE; 1598 pthread_mutex_unlock(&m_lock); 1599 LOGH("Still need to allocate %d buffers", 1600 mNumBufsNeedAlloc); 1601 // start another thread to allocate the rest of buffers 1602 pthread_create(&mBufAllocPid, 1603 NULL, 1604 BufAllocRoutine, 1605 this); 1606 pthread_setname_np(mBufAllocPid, "CAM_strmBufAlloc"); 1607 } 1608 return rc; 1609 } 1610 1611 /*=========================================================================== 1612 * FUNCTION : mapBuffers 1613 * 1614 * DESCRIPTION: map stream buffers 1615 * 1616 * PARAMETERS : 1617 * 1618 * RETURN : int32_t type of status 1619 * NO_ERROR -- success 1620 * none-zero failure code 1621 *==========================================================================*/ 1622 int32_t QCameraStream::mapBuffers() 1623 { 1624 int32_t rc = NO_ERROR; 1625 QCameraBufferMaps bufferMaps; 1626 1627 rc = mAllocator.waitForBackgroundTask(mAllocTaskId); 1628 if (rc != NO_ERROR) { 1629 LOGE("Allocation Failed"); 1630 return NO_MEMORY; 1631 } 1632 1633 if (mStreamBufs == NULL) { 1634 LOGE("Stream buffers not allocated"); 1635 return UNKNOWN_ERROR; 1636 } 1637 1638 uint8_t numBufsToMap = mStreamBufs->getMappable(); 1639 for (uint32_t i = 0; i < numBufsToMap; i++) { 1640 ssize_t bufSize = mStreamBufs->getSize(i); 1641 if (BAD_INDEX != bufSize) { 1642 rc = bufferMaps.enqueue(CAM_MAPPING_BUF_TYPE_STREAM_BUF, mHandle, 1643 i /*buf index*/, -1 /*plane index*/, 0 /*cookie*/, 1644 mStreamBufs->getFd(i), bufSize); 1645 1646 if (rc < 0) { 1647 LOGE("Failed to map buffers"); 1648 rc = BAD_INDEX; 1649 break; 1650 } 1651 } else { 1652 LOGE("Bad index %u", i); 1653 rc = BAD_INDEX; 1654 break; 1655 } 1656 } 1657 1658 cam_buf_map_type_list bufMapList; 1659 if (rc == NO_ERROR) { 1660 rc = bufferMaps.getCamBufMapList(bufMapList); 1661 } 1662 if (rc == NO_ERROR) { 1663 rc = mapBufs(bufMapList, NULL); 1664 } 1665 return rc; 1666 } 1667 1668 /*=========================================================================== 1669 * FUNCTION : allocateBatchBufs 1670 * 1671 * DESCRIPTION: allocate stream batch buffers and stream buffers 1672 * 1673 * PARAMETERS : 1674 * @offset : offset info of stream buffers 1675 * @num_bufs : number of buffers allocated 1676 * @initial_reg_flag: flag to indicate if buffer needs to be registered 1677 * at kernel initially 1678 * @bufs : output of allocated buffers 1679 * @plane_bufs : output of allocated plane buffers 1680 * @ops_tbl : ptr to buf mapping/unmapping ops 1681 * 1682 * RETURN : int32_t type of status 1683 * NO_ERROR -- success 1684 * none-zero failure code 1685 *==========================================================================*/ 1686 int32_t QCameraStream::allocateBatchBufs(cam_frame_len_offset_t *offset, 1687 uint8_t *num_bufs, uint8_t **initial_reg_flag, 1688 mm_camera_buf_def_t **bufs, mm_camera_map_unmap_ops_tbl_t *ops_tbl) 1689 { 1690 int rc = NO_ERROR; 1691 uint8_t *regFlags; 1692 QCameraBufferMaps bufferMaps; 1693 QCameraBufferMaps planeBufferMaps; 1694 1695 mFrameLenOffset = *offset; 1696 1697 LOGH("Batch Buffer allocation stream type = %d", getMyType()); 1698 1699 //Allocate stream batch buffer 1700 mStreamBatchBufs = mAllocator.allocateStreamUserBuf (mStreamInfo); 1701 if (!mStreamBatchBufs) { 1702 LOGE("Failed to allocate stream batch buffers"); 1703 return NO_MEMORY; 1704 } 1705 1706 uint8_t numBufsToMap = mStreamBatchBufs->getMappable(); 1707 1708 //map batch buffers 1709 for (uint32_t i = 0; i < numBufsToMap; i++) { 1710 rc = bufferMaps.enqueue(CAM_MAPPING_BUF_TYPE_STREAM_USER_BUF, 1711 0 /*stream id*/, i /*buf index*/, -1 /*plane index*/, 1712 0 /*cookie*/, mStreamBatchBufs->getFd(i), mNumBufs); 1713 1714 if (rc < 0) { 1715 LOGE("Failed to map buffers"); 1716 rc = BAD_INDEX; 1717 break; 1718 } 1719 } 1720 1721 cam_buf_map_type_list bufMapList; 1722 if (rc == NO_ERROR) { 1723 rc = bufferMaps.getCamBufMapList(bufMapList); 1724 } 1725 if (rc == NO_ERROR) { 1726 rc = mapBufs(bufMapList, ops_tbl); 1727 } 1728 if (rc < 0) { 1729 LOGE("Failed to map stream batch buffers"); 1730 mStreamBatchBufs->deallocate(); 1731 delete mStreamBatchBufs; 1732 mStreamBatchBufs = NULL; 1733 return NO_MEMORY; 1734 } 1735 1736 /*calculate stream Buffer count*/ 1737 mNumPlaneBufs = 1738 (mNumBufs * mStreamInfo->user_buf_info.frame_buf_cnt); 1739 1740 /* For some stream types, buffer allocation may have already begun 1741 * preemptively. If this is the case, we need to wait for the 1742 * preemptive allocation to complete before proceeding. */ 1743 mAllocator.waitForDeferredAlloc(mStreamInfo->stream_type); 1744 1745 //Allocate stream buffer 1746 mStreamBufs = mAllocator.allocateStreamBuf(mStreamInfo->stream_type, 1747 mFrameLenOffset.frame_len,mFrameLenOffset.mp[0].stride, 1748 mFrameLenOffset.mp[0].scanline,mNumPlaneBufs); 1749 if (!mStreamBufs) { 1750 LOGE("Failed to allocate stream buffers"); 1751 rc = NO_MEMORY; 1752 goto err1; 1753 } 1754 1755 //Map plane stream buffers 1756 for (uint32_t i = 0; i < mNumPlaneBufs; i++) { 1757 ssize_t bufSize = mStreamBufs->getSize(i); 1758 if (BAD_INDEX != bufSize) { 1759 rc = planeBufferMaps.enqueue(CAM_MAPPING_BUF_TYPE_STREAM_BUF, 1760 0 /*stream id*/, i /*buf index*/, -1 /*plane index*/, 1761 0 /*cookie*/, mStreamBufs->getFd(i), bufSize); 1762 1763 if (rc < 0) { 1764 LOGE("Failed to map buffers"); 1765 mStreamBufs->deallocate(); 1766 delete mStreamBufs; 1767 mStreamBufs = NULL; 1768 rc = INVALID_OPERATION; 1769 goto err1; 1770 } 1771 } else { 1772 LOGE("Failed to retrieve buffer size (bad index)"); 1773 mStreamBufs->deallocate(); 1774 delete mStreamBufs; 1775 mStreamBufs = NULL; 1776 rc = INVALID_OPERATION; 1777 goto err1; 1778 } 1779 } 1780 1781 cam_buf_map_type_list planeBufMapList; 1782 rc = planeBufferMaps.getCamBufMapList(planeBufMapList); 1783 if (rc == NO_ERROR) { 1784 rc = mapBufs(planeBufMapList, ops_tbl); 1785 } 1786 1787 if (rc < 0) { 1788 LOGE("map_stream_buf failed: %d", rc); 1789 mStreamBufs->deallocate(); 1790 delete mStreamBufs; 1791 mStreamBufs = NULL; 1792 rc = INVALID_OPERATION; 1793 goto err1; 1794 } 1795 1796 LOGD("BATCH Buf Count = %d, Plane Buf Cnt = %d", 1797 mNumBufs, mNumPlaneBufs); 1798 1799 //regFlags array is allocated by us, but consumed and freed by mm-camera-interface 1800 regFlags = (uint8_t *)malloc(sizeof(uint8_t) * mNumBufs); 1801 if (!regFlags) { 1802 LOGE("Out of memory"); 1803 for (uint32_t i = 0; i < mNumPlaneBufs; i++) { 1804 unmapBuf(CAM_MAPPING_BUF_TYPE_STREAM_BUF, i, -1, ops_tbl); 1805 } 1806 mStreamBufs->deallocate(); 1807 delete mStreamBufs; 1808 mStreamBufs = NULL; 1809 rc = NO_MEMORY; 1810 goto err1; 1811 } 1812 memset(regFlags, 0, sizeof(uint8_t) * mNumBufs); 1813 for (uint32_t i = 0; i < mNumBufs; i++) { 1814 regFlags[i] = 1; 1815 } 1816 1817 mBufDefs = (mm_camera_buf_def_t *)malloc(mNumBufs * sizeof(mm_camera_buf_def_t)); 1818 if (mBufDefs == NULL) { 1819 LOGE("getRegFlags failed %d", rc); 1820 for (uint32_t i = 0; i < mNumPlaneBufs; i++) { 1821 unmapBuf(CAM_MAPPING_BUF_TYPE_STREAM_BUF, i, -1, ops_tbl); 1822 } 1823 mStreamBufs->deallocate(); 1824 delete mStreamBufs; 1825 mStreamBufs = NULL; 1826 free(regFlags); 1827 regFlags = NULL; 1828 rc = INVALID_OPERATION; 1829 goto err1; 1830 } 1831 memset(mBufDefs, 0, mNumBufs * sizeof(mm_camera_buf_def_t)); 1832 1833 mPlaneBufDefs = (mm_camera_buf_def_t *) 1834 malloc(mNumPlaneBufs * (sizeof(mm_camera_buf_def_t))); 1835 if (mPlaneBufDefs == NULL) { 1836 LOGE("No Memory"); 1837 free(regFlags); 1838 regFlags = NULL; 1839 free(mBufDefs); 1840 mBufDefs = NULL; 1841 for (uint32_t i = 0; i < mNumPlaneBufs; i++) { 1842 unmapBuf(CAM_MAPPING_BUF_TYPE_STREAM_BUF, i, -1, ops_tbl); 1843 } 1844 mStreamBufs->deallocate(); 1845 delete mStreamBufs; 1846 mStreamBufs = NULL; 1847 free(regFlags); 1848 regFlags = NULL; 1849 rc = INVALID_OPERATION; 1850 goto err1; 1851 } 1852 memset(mPlaneBufDefs, 0, 1853 mNumPlaneBufs * (sizeof(mm_camera_buf_def_t))); 1854 1855 for (uint32_t i = 0; i < mStreamInfo->num_bufs; i++) { 1856 mStreamBatchBufs->getUserBufDef(mStreamInfo->user_buf_info, 1857 mBufDefs[i], i, mFrameLenOffset, mPlaneBufDefs, 1858 mStreamBufs); 1859 } 1860 1861 *num_bufs = mNumBufs; 1862 *initial_reg_flag = regFlags; 1863 *bufs = mBufDefs; 1864 LOGH("stream type: %d, numBufs: %d mNumPlaneBufs: %d", 1865 mStreamInfo->stream_type, mNumBufs, mNumPlaneBufs); 1866 1867 return NO_ERROR; 1868 1869 err1: 1870 mStreamBatchBufs->deallocate(); 1871 delete mStreamBatchBufs; 1872 mStreamBatchBufs = NULL; 1873 return rc; 1874 } 1875 1876 1877 /*=========================================================================== 1878 * FUNCTION : releaseBuffs 1879 * 1880 * DESCRIPTION: method to deallocate stream buffers 1881 * 1882 * PARAMETERS : 1883 * 1884 * RETURN : int32_t type of status 1885 * NO_ERROR -- success 1886 * none-zero failure code 1887 *==========================================================================*/ 1888 int32_t QCameraStream::releaseBuffs() 1889 { 1890 int rc = NO_ERROR; 1891 1892 if (mStreamInfo->streaming_mode == CAM_STREAMING_MODE_BATCH) { 1893 return releaseBatchBufs(NULL); 1894 } 1895 1896 if ((NULL != mBufDefs) && (mStreamBufs != NULL)) { 1897 uint8_t numBufsToUnmap = mStreamBufs->getMappable(); 1898 for (uint32_t i = 0; i < numBufsToUnmap; i++) { 1899 rc = unmapBuf(CAM_MAPPING_BUF_TYPE_STREAM_BUF, i, -1, NULL); 1900 if (rc < 0) { 1901 LOGE("map_stream_buf failed: %d", rc); 1902 } 1903 } 1904 1905 // mBufDefs just keep a ptr to the buffer 1906 // mm-camera-interface own the buffer, so no need to free 1907 mBufDefs = NULL; 1908 memset(&mFrameLenOffset, 0, sizeof(mFrameLenOffset)); 1909 } 1910 if (!mStreamBufsAcquired && (mStreamBufs != NULL)) { 1911 mStreamBufs->deallocate(); 1912 delete mStreamBufs; 1913 mStreamBufs = NULL; 1914 } 1915 return rc; 1916 } 1917 1918 /*=========================================================================== 1919 * FUNCTION : releaseBatchBufs 1920 * 1921 * DESCRIPTION: method to deallocate stream buffers and batch buffers 1922 * 1923 * PARAMETERS : 1924 * @ops_tbl : ptr to buf mapping/unmapping ops 1925 * 1926 * RETURN : int32_t type of status 1927 * NO_ERROR -- success 1928 * none-zero failure code 1929 1930 *==========================================================================*/ 1931 int32_t QCameraStream::releaseBatchBufs(mm_camera_map_unmap_ops_tbl_t *ops_tbl) 1932 { 1933 int rc = NO_ERROR; 1934 1935 if (NULL != mPlaneBufDefs) { 1936 for (uint32_t i = 0; i < mNumPlaneBufs; i++) { 1937 rc = unmapBuf(CAM_MAPPING_BUF_TYPE_STREAM_BUF, i, -1, ops_tbl); 1938 if (rc < 0) { 1939 LOGE("map_stream_buf failed: %d", rc); 1940 } 1941 } 1942 1943 // mBufDefs just keep a ptr to the buffer 1944 // mm-camera-interface own the buffer, so no need to free 1945 mPlaneBufDefs = NULL; 1946 memset(&mFrameLenOffset, 0, sizeof(mFrameLenOffset)); 1947 mNumPlaneBufs = 0; 1948 } 1949 1950 if (mStreamBufs != NULL) { 1951 mStreamBufs->deallocate(); 1952 delete mStreamBufs; 1953 } 1954 1955 mBufDefs = NULL; 1956 1957 if (mStreamBatchBufs != NULL) { 1958 for (uint8_t i = 0; i < mStreamBatchBufs->getCnt(); i++) { 1959 unmapBuf(CAM_MAPPING_BUF_TYPE_STREAM_USER_BUF, i, -1, ops_tbl); 1960 } 1961 mStreamBatchBufs->deallocate(); 1962 delete mStreamBatchBufs; 1963 mStreamBatchBufs = NULL; 1964 } 1965 return rc; 1966 1967 } 1968 1969 /*=========================================================================== 1970 * FUNCTION : BufAllocRoutine 1971 * 1972 * DESCRIPTION: function to allocate additional stream buffers 1973 * 1974 * PARAMETERS : 1975 * @data : user data ptr 1976 * 1977 * RETURN : none 1978 *==========================================================================*/ 1979 void *QCameraStream::BufAllocRoutine(void *data) 1980 { 1981 QCameraStream *pme = (QCameraStream *)data; 1982 int32_t rc = NO_ERROR; 1983 1984 LOGH("E"); 1985 pme->cond_wait(); 1986 if (pme->mNumBufsNeedAlloc > 0) { 1987 uint8_t numBufAlloc = (uint8_t)(pme->mNumBufs - pme->mNumBufsNeedAlloc); 1988 rc = pme->mAllocator.allocateMoreStreamBuf(pme->mStreamBufs, 1989 pme->mFrameLenOffset.frame_len, 1990 pme->mNumBufsNeedAlloc); 1991 if (rc != NO_ERROR) { 1992 LOGE("Failed to allocate buffers"); 1993 pme->mNumBufsNeedAlloc = 0; 1994 return NULL; 1995 } 1996 1997 pme->mNumBufsNeedAlloc = 0; 1998 QCameraBufferMaps bufferMaps; 1999 for (uint32_t i = numBufAlloc; i < pme->mNumBufs; i++) { 2000 ssize_t bufSize = pme->mStreamBufs->getSize(i); 2001 if (BAD_INDEX == bufSize) { 2002 LOGE("Failed to retrieve buffer size (bad index)"); 2003 return NULL; 2004 } 2005 2006 rc = bufferMaps.enqueue(CAM_MAPPING_BUF_TYPE_STREAM_BUF, 2007 pme->mHandle, i /*buf index*/, -1 /*plane index*/, 2008 0 /*cookie*/, pme->mStreamBufs->getFd(i), bufSize); 2009 2010 if (rc < 0) { 2011 LOGE("Failed to map buffers"); 2012 return NULL; 2013 } 2014 } 2015 2016 cam_buf_map_type_list bufMapList; 2017 rc = bufferMaps.getCamBufMapList(bufMapList); 2018 if (rc == NO_ERROR) { 2019 rc = pme->m_MemOpsTbl.bundled_map_ops(&bufMapList, pme->m_MemOpsTbl.userdata); 2020 } 2021 if (rc != 0) { 2022 LOGE("Failed to map buffers with return code %d", rc); 2023 return NULL; 2024 } 2025 2026 for (uint32_t i = numBufAlloc; i < pme->mNumBufs; i++) { 2027 pme->mStreamBufs->getBufDef(pme->mFrameLenOffset, pme->mBufDefs[i], i); 2028 pme->mCamOps->qbuf(pme->mCamHandle, pme->mChannelHandle, 2029 &pme->mBufDefs[i]); 2030 } 2031 } 2032 LOGH("X"); 2033 return NULL; 2034 } 2035 2036 /*=========================================================================== 2037 * FUNCTION : cond_signal 2038 * 2039 * DESCRIPTION: signal if flag "wait_for_cond" is set 2040 * 2041 *==========================================================================*/ 2042 void QCameraStream::cond_signal(bool forceExit) 2043 { 2044 pthread_mutex_lock(&m_lock); 2045 if(wait_for_cond == TRUE){ 2046 wait_for_cond = FALSE; 2047 if (forceExit) { 2048 mNumBufsNeedAlloc = 0; 2049 } 2050 pthread_cond_signal(&m_cond); 2051 } 2052 pthread_mutex_unlock(&m_lock); 2053 } 2054 2055 2056 /*=========================================================================== 2057 * FUNCTION : cond_wait 2058 * 2059 * DESCRIPTION: wait on if flag "wait_for_cond" is set 2060 * 2061 *==========================================================================*/ 2062 void QCameraStream::cond_wait() 2063 { 2064 pthread_mutex_lock(&m_lock); 2065 while (wait_for_cond == TRUE) { 2066 pthread_cond_wait(&m_cond, &m_lock); 2067 } 2068 pthread_mutex_unlock(&m_lock); 2069 } 2070 2071 /*=========================================================================== 2072 * FUNCTION : putBufs 2073 * 2074 * DESCRIPTION: deallocate stream buffers 2075 * 2076 * PARAMETERS : 2077 * @ops_tbl : ptr to buf mapping/unmapping ops 2078 * 2079 * RETURN : int32_t type of status 2080 * NO_ERROR -- success 2081 * none-zero failure code 2082 *==========================================================================*/ 2083 int32_t QCameraStream::putBufs(mm_camera_map_unmap_ops_tbl_t *ops_tbl) 2084 { 2085 int rc = NO_ERROR; 2086 2087 if (mBufAllocPid != 0) { 2088 cond_signal(true); 2089 LOGL("wait for buf allocation thread dead"); 2090 pthread_join(mBufAllocPid, NULL); 2091 mBufAllocPid = 0; 2092 LOGL("return from buf allocation thread"); 2093 } 2094 2095 uint8_t numBufsToUnmap = mStreamBufs->getMappable(); 2096 for (uint32_t i = 0; i < numBufsToUnmap; i++) { 2097 rc = ops_tbl->unmap_ops(i, -1, CAM_MAPPING_BUF_TYPE_STREAM_BUF, ops_tbl->userdata); 2098 if (rc < 0) { 2099 LOGE("map_stream_buf failed: %d", rc); 2100 } 2101 } 2102 mBufDefs = NULL; // mBufDefs just keep a ptr to the buffer 2103 // mm-camera-interface own the buffer, so no need to free 2104 memset(&mFrameLenOffset, 0, sizeof(mFrameLenOffset)); 2105 if ( !mStreamBufsAcquired ) { 2106 mStreamBufs->deallocate(); 2107 delete mStreamBufs; 2108 mStreamBufs = NULL; 2109 } 2110 2111 return rc; 2112 } 2113 2114 /*=========================================================================== 2115 * FUNCTION : putBufsDeffered 2116 * 2117 * DESCRIPTION: function to deallocate deffered stream buffers 2118 * 2119 * PARAMETERS : none 2120 * 2121 * RETURN : int32_t type of status 2122 * NO_ERROR -- success 2123 * none-zero failure code 2124 *==========================================================================*/ 2125 int32_t QCameraStream::putBufsDeffered() 2126 { 2127 if (mBufAllocPid != 0) { 2128 cond_signal(true); 2129 LOGH("%s: wait for buf allocation thread dead", __func__); 2130 // Wait for the allocation of additional stream buffers 2131 pthread_join(mBufAllocPid, NULL); 2132 mBufAllocPid = 0; 2133 LOGH("%s: return from buf allocation thread", __func__); 2134 } 2135 // Deallocation of the deffered stream buffers handled separately 2136 return NO_ERROR; 2137 } 2138 2139 /*=========================================================================== 2140 * FUNCTION : invalidateBuf 2141 * 2142 * DESCRIPTION: invalidate a specific stream buffer 2143 * 2144 * PARAMETERS : 2145 * @index : index of the buffer to invalidate 2146 * 2147 * RETURN : int32_t type of status 2148 * NO_ERROR -- success 2149 * none-zero failure code 2150 *==========================================================================*/ 2151 int32_t QCameraStream::invalidateBuf(uint32_t index) 2152 { 2153 if (mStreamBufs == NULL) { 2154 LOGE("Invalid Operation"); 2155 return INVALID_OPERATION; 2156 } 2157 return mStreamBufs->invalidateCache(index); 2158 } 2159 2160 /*=========================================================================== 2161 * FUNCTION : cleanInvalidateBuf 2162 * 2163 * DESCRIPTION: clean invalidate a specific stream buffer 2164 * 2165 * PARAMETERS : 2166 * @index : index of the buffer to clean invalidate 2167 * 2168 * RETURN : int32_t type of status 2169 * NO_ERROR -- success 2170 * none-zero failure code 2171 *==========================================================================*/ 2172 int32_t QCameraStream::cleanInvalidateBuf(uint32_t index) 2173 { 2174 if (mStreamBufs == NULL) { 2175 LOGE("Invalid Operation"); 2176 return INVALID_OPERATION; 2177 } 2178 return mStreamBufs->cleanInvalidateCache(index); 2179 } 2180 2181 /*=========================================================================== 2182 * FUNCTION : isTypeOf 2183 * 2184 * DESCRIPTION: helper function to determine if the stream is of the queried type 2185 * 2186 * PARAMETERS : 2187 * @type : stream type as of queried 2188 * 2189 * RETURN : true/false 2190 *==========================================================================*/ 2191 bool QCameraStream::isTypeOf(cam_stream_type_t type) 2192 { 2193 if (mStreamInfo != NULL && (mStreamInfo->stream_type == type)) { 2194 return true; 2195 } else { 2196 return false; 2197 } 2198 } 2199 2200 /*=========================================================================== 2201 * FUNCTION : isOrignalTypeOf 2202 * 2203 * DESCRIPTION: helper function to determine if the original stream is of the 2204 * queried type if it's reproc stream 2205 * 2206 * PARAMETERS : 2207 * @type : stream type as of queried 2208 * 2209 * RETURN : true/false 2210 *==========================================================================*/ 2211 bool QCameraStream::isOrignalTypeOf(cam_stream_type_t type) 2212 { 2213 if (mStreamInfo != NULL && 2214 mStreamInfo->stream_type == CAM_STREAM_TYPE_OFFLINE_PROC && 2215 mStreamInfo->reprocess_config.pp_type == CAM_ONLINE_REPROCESS_TYPE && 2216 mStreamInfo->reprocess_config.online.input_stream_type == type) { 2217 return true; 2218 } else if ( 2219 mStreamInfo != NULL && 2220 mStreamInfo->stream_type == CAM_STREAM_TYPE_OFFLINE_PROC && 2221 mStreamInfo->reprocess_config.pp_type == CAM_OFFLINE_REPROCESS_TYPE && 2222 mStreamInfo->reprocess_config.offline.input_type == type) { 2223 return true; 2224 } else { 2225 return false; 2226 } 2227 } 2228 2229 /*=========================================================================== 2230 * FUNCTION : getMyType 2231 * 2232 * DESCRIPTION: return stream type 2233 * 2234 * PARAMETERS : none 2235 * 2236 * RETURN : stream type 2237 *==========================================================================*/ 2238 cam_stream_type_t QCameraStream::getMyType() 2239 { 2240 if (mStreamInfo != NULL) { 2241 return mStreamInfo->stream_type; 2242 } else { 2243 return CAM_STREAM_TYPE_DEFAULT; 2244 } 2245 } 2246 2247 /*=========================================================================== 2248 * FUNCTION : getMyOriginalType 2249 * 2250 * DESCRIPTION: return stream type 2251 * 2252 * PARAMETERS : none 2253 * 2254 * RETURN : stream type 2255 *==========================================================================*/ 2256 cam_stream_type_t QCameraStream::getMyOriginalType() 2257 { 2258 if (mStreamInfo != NULL) { 2259 if (mStreamInfo->stream_type == CAM_STREAM_TYPE_OFFLINE_PROC && 2260 mStreamInfo->reprocess_config.pp_type == CAM_ONLINE_REPROCESS_TYPE) { 2261 return mStreamInfo->reprocess_config.online.input_stream_type; 2262 } else if (mStreamInfo->stream_type == CAM_STREAM_TYPE_OFFLINE_PROC && 2263 mStreamInfo->reprocess_config.pp_type == CAM_OFFLINE_REPROCESS_TYPE) { 2264 return mStreamInfo->reprocess_config.offline.input_type; 2265 } else { 2266 return mStreamInfo->stream_type; 2267 } 2268 } else { 2269 return CAM_STREAM_TYPE_DEFAULT; 2270 } 2271 } 2272 2273 /*=========================================================================== 2274 * FUNCTION : getFrameOffset 2275 * 2276 * DESCRIPTION: query stream buffer frame offset info 2277 * 2278 * PARAMETERS : 2279 * @offset : reference to struct to store the queried frame offset info 2280 * 2281 * RETURN : int32_t type of status 2282 * NO_ERROR -- success 2283 * none-zero failure code 2284 *==========================================================================*/ 2285 int32_t QCameraStream::getFrameOffset(cam_frame_len_offset_t &offset) 2286 { 2287 if (NULL == mStreamInfo) { 2288 return NO_INIT; 2289 } 2290 2291 offset = mFrameLenOffset; 2292 if ((ROTATE_90 == mOnlineRotation) || (ROTATE_270 == mOnlineRotation) 2293 || (offset.frame_len == 0) || (offset.num_planes == 0)) { 2294 // Re-calculate frame offset in case of online rotation 2295 cam_stream_info_t streamInfo = *mStreamInfo; 2296 getFrameDimension(streamInfo.dim); 2297 calcOffset(&streamInfo); 2298 offset = streamInfo.buf_planes.plane_info; 2299 } 2300 2301 return 0; 2302 } 2303 2304 /*=========================================================================== 2305 * FUNCTION : getCropInfo 2306 * 2307 * DESCRIPTION: query crop info of the stream 2308 * 2309 * PARAMETERS : 2310 * @crop : reference to struct to store the queried crop info 2311 * 2312 * RETURN : int32_t type of status 2313 * NO_ERROR -- success 2314 * none-zero failure code 2315 *==========================================================================*/ 2316 int32_t QCameraStream::getCropInfo(cam_rect_t &crop) 2317 { 2318 pthread_mutex_lock(&mCropLock); 2319 crop = mCropInfo; 2320 pthread_mutex_unlock(&mCropLock); 2321 return NO_ERROR; 2322 } 2323 2324 /*=========================================================================== 2325 * FUNCTION : setCropInfo 2326 * 2327 * DESCRIPTION: set crop info of the stream 2328 * 2329 * PARAMETERS : 2330 * @crop : struct to store new crop info 2331 * 2332 * RETURN : int32_t type of status 2333 * NO_ERROR -- success 2334 * none-zero failure code 2335 *==========================================================================*/ 2336 int32_t QCameraStream::setCropInfo(cam_rect_t crop) 2337 { 2338 pthread_mutex_lock(&mCropLock); 2339 mCropInfo = crop; 2340 pthread_mutex_unlock(&mCropLock); 2341 return NO_ERROR; 2342 } 2343 2344 /*=========================================================================== 2345 * FUNCTION : getFrameDimension 2346 * 2347 * DESCRIPTION: query stream frame dimension info 2348 * 2349 * PARAMETERS : 2350 * @dim : reference to struct to store the queried frame dimension 2351 * 2352 * RETURN : int32_t type of status 2353 * NO_ERROR -- success 2354 * none-zero failure code 2355 *==========================================================================*/ 2356 int32_t QCameraStream::getFrameDimension(cam_dimension_t &dim) 2357 { 2358 if (mStreamInfo != NULL) { 2359 if ((ROTATE_90 == mOnlineRotation) || (ROTATE_270 == mOnlineRotation)) { 2360 dim.width = mStreamInfo->dim.height; 2361 dim.height = mStreamInfo->dim.width; 2362 } else { 2363 dim = mStreamInfo->dim; 2364 } 2365 return 0; 2366 } 2367 return -1; 2368 } 2369 2370 /*=========================================================================== 2371 * FUNCTION : getFormat 2372 * 2373 * DESCRIPTION: query stream format 2374 * 2375 * PARAMETERS : 2376 * @fmt : reference to stream format 2377 * 2378 * RETURN : int32_t type of status 2379 * NO_ERROR -- success 2380 * none-zero failure code 2381 *==========================================================================*/ 2382 int32_t QCameraStream::getFormat(cam_format_t &fmt) 2383 { 2384 if (mStreamInfo != NULL) { 2385 fmt = mStreamInfo->fmt; 2386 return 0; 2387 } 2388 return -1; 2389 } 2390 2391 /*=========================================================================== 2392 * FUNCTION : getMyServerID 2393 * 2394 * DESCRIPTION: query server stream ID 2395 * 2396 * PARAMETERS : None 2397 * 2398 * RETURN : stream ID from server 2399 *==========================================================================*/ 2400 uint32_t QCameraStream::getMyServerID() { 2401 if (mStreamInfo != NULL) { 2402 return mStreamInfo->stream_svr_id; 2403 } else { 2404 return 0; 2405 } 2406 } 2407 2408 /*=========================================================================== 2409 * FUNCTION : acquireStreamBufs 2410 * 2411 * DESCRIPTION: acquire stream buffers and postpone their release. 2412 * 2413 * PARAMETERS : None 2414 * 2415 * RETURN : int32_t type of status 2416 * NO_ERROR -- success 2417 * none-zero failure code 2418 *==========================================================================*/ 2419 int32_t QCameraStream::acquireStreamBufs() 2420 { 2421 mStreamBufsAcquired = true; 2422 2423 return NO_ERROR; 2424 } 2425 2426 /*=========================================================================== 2427 * FUNCTION : mapBuf 2428 * 2429 * DESCRIPTION: map stream related buffer to backend server 2430 * 2431 * PARAMETERS : 2432 * @buf_type : mapping type of buffer 2433 * @buf_idx : index of buffer 2434 * @plane_idx: plane index 2435 * @fd : fd of the buffer 2436 * @size : lenght of the buffer 2437 * @ops_tbl : ptr to buf mapping/unmapping ops 2438 * 2439 * RETURN : int32_t type of status 2440 * NO_ERROR -- success 2441 * none-zero failure code 2442 *==========================================================================*/ 2443 int32_t QCameraStream::mapBuf(uint8_t buf_type, uint32_t buf_idx, 2444 int32_t plane_idx, int fd, size_t size, mm_camera_map_unmap_ops_tbl_t *ops_tbl) 2445 { 2446 cam_buf_map_type_list bufMapList; 2447 int32_t rc = QCameraBufferMaps::makeSingletonBufMapList( 2448 (cam_mapping_buf_type)buf_type, mHandle, buf_idx, plane_idx, 2449 0 /*cookie*/, fd, size, bufMapList); 2450 2451 if (rc != NO_ERROR) { 2452 return rc; 2453 } 2454 2455 return mapBufs(bufMapList, ops_tbl); 2456 } 2457 2458 /*=========================================================================== 2459 * FUNCTION : mapBufs 2460 * 2461 * DESCRIPTION: map stream related buffers to backend server 2462 * 2463 * PARAMETERS : 2464 * @bufMapList : buffer mapping information 2465 * @ops_tbl : ptr to buf mapping/unmapping ops 2466 * 2467 * RETURN : int32_t type of status 2468 * NO_ERROR -- success 2469 * none-zero failure code 2470 *==========================================================================*/ 2471 2472 int32_t QCameraStream::mapBufs(cam_buf_map_type_list bufMapList, 2473 __unused mm_camera_map_unmap_ops_tbl_t *ops_tbl) 2474 { 2475 if (m_MemOpsTbl.bundled_map_ops != NULL) { 2476 return m_MemOpsTbl.bundled_map_ops(&bufMapList, m_MemOpsTbl.userdata); 2477 } else { 2478 return mCamOps->map_stream_bufs(mCamHandle, mChannelHandle, 2479 &bufMapList); 2480 } 2481 2482 } 2483 2484 /*=========================================================================== 2485 * FUNCTION : unmapBuf 2486 * 2487 * DESCRIPTION: unmap stream related buffer to backend server 2488 * 2489 * PARAMETERS : 2490 * @buf_type : mapping type of buffer 2491 * @buf_idx : index of buffer 2492 * @plane_idx: plane index 2493 * @ops_tbl : ptr to buf mapping/unmapping ops 2494 * 2495 * RETURN : int32_t type of status 2496 * NO_ERROR -- success 2497 * none-zero failure code 2498 *==========================================================================*/ 2499 int32_t QCameraStream::unmapBuf(uint8_t buf_type, uint32_t buf_idx, int32_t plane_idx, 2500 mm_camera_map_unmap_ops_tbl_t *ops_tbl) 2501 { 2502 if (ops_tbl != NULL) { 2503 return ops_tbl->unmap_ops(buf_idx, plane_idx, 2504 (cam_mapping_buf_type)buf_type, ops_tbl->userdata); 2505 } else { 2506 return mCamOps->unmap_stream_buf(mCamHandle, mChannelHandle, 2507 mHandle, buf_type, buf_idx, plane_idx); 2508 } 2509 } 2510 2511 /*=========================================================================== 2512 * FUNCTION : setParameter 2513 * 2514 * DESCRIPTION: set stream based parameters 2515 * 2516 * PARAMETERS : 2517 * @param : ptr to parameters to be set 2518 * 2519 * RETURN : int32_t type of status 2520 * NO_ERROR -- success 2521 * none-zero failure code 2522 *==========================================================================*/ 2523 int32_t QCameraStream::setParameter(cam_stream_parm_buffer_t ¶m) 2524 { 2525 int32_t rc = NO_ERROR; 2526 pthread_mutex_lock(&mParameterLock); 2527 mStreamInfo->parm_buf = param; 2528 rc = mCamOps->set_stream_parms(mCamHandle, 2529 mChannelHandle, 2530 mHandle, 2531 &mStreamInfo->parm_buf); 2532 if (rc == NO_ERROR) { 2533 param = mStreamInfo->parm_buf; 2534 } 2535 pthread_mutex_unlock(&mParameterLock); 2536 return rc; 2537 } 2538 2539 /*=========================================================================== 2540 * FUNCTION : getParameter 2541 * 2542 * DESCRIPTION: get stream based parameters 2543 * 2544 * PARAMETERS : 2545 * @param : ptr to parameters to be red 2546 * 2547 * RETURN : int32_t type of status 2548 * NO_ERROR -- success 2549 * none-zero failure code 2550 *==========================================================================*/ 2551 int32_t QCameraStream::getParameter(cam_stream_parm_buffer_t ¶m) 2552 { 2553 int32_t rc = NO_ERROR; 2554 pthread_mutex_lock(&mParameterLock); 2555 mStreamInfo->parm_buf = param; 2556 rc = mCamOps->get_stream_parms(mCamHandle, 2557 mChannelHandle, 2558 mHandle, 2559 &mStreamInfo->parm_buf); 2560 if (rc == NO_ERROR) { 2561 param = mStreamInfo->parm_buf; 2562 } 2563 pthread_mutex_unlock(&mParameterLock); 2564 return rc; 2565 } 2566 2567 /*=========================================================================== 2568 * FUNCTION : releaseFrameData 2569 * 2570 * DESCRIPTION: callback function to release frame data node 2571 * 2572 * PARAMETERS : 2573 * @data : ptr to post process input data 2574 * @user_data : user data ptr (QCameraReprocessor) 2575 * 2576 * RETURN : None 2577 *==========================================================================*/ 2578 void QCameraStream::releaseFrameData(void *data, void *user_data) 2579 { 2580 QCameraStream *pme = (QCameraStream *)user_data; 2581 mm_camera_super_buf_t *frame = (mm_camera_super_buf_t *)data; 2582 if (NULL != pme) { 2583 pme->bufDone(frame->bufs[0]->buf_idx); 2584 } 2585 } 2586 2587 /*=========================================================================== 2588 * FUNCTION : configStream 2589 * 2590 * DESCRIPTION: send stream configuration to back end 2591 * 2592 * PARAMETERS : 2593 * 2594 * RETURN : int32_t type of status 2595 * NO_ERROR -- success 2596 * none-zero failure code 2597 *==========================================================================*/ 2598 int32_t QCameraStream::configStream() 2599 { 2600 int rc = NO_ERROR; 2601 2602 // Configure the stream 2603 mm_camera_stream_config_t stream_config; 2604 stream_config.stream_info = mStreamInfo; 2605 stream_config.mem_vtbl = mMemVtbl; 2606 stream_config.stream_cb_sync = NULL; 2607 stream_config.stream_cb = dataNotifyCB; 2608 stream_config.padding_info = mPaddingInfo; 2609 stream_config.userdata = this; 2610 rc = mCamOps->config_stream(mCamHandle, 2611 mChannelHandle, mHandle, &stream_config); 2612 if (rc < 0) { 2613 LOGE("Failed to config stream, rc = %d", rc); 2614 mCamOps->unmap_stream_buf(mCamHandle, 2615 mChannelHandle, 2616 mHandle, 2617 CAM_MAPPING_BUF_TYPE_STREAM_INFO, 2618 0, 2619 -1); 2620 return UNKNOWN_ERROR; 2621 } 2622 2623 return rc; 2624 } 2625 2626 /*=========================================================================== 2627 * FUNCTION : setSyncDataCB 2628 * 2629 * DESCRIPTION: register callback with mm-interface for this stream 2630 * 2631 * PARAMETERS : 2632 @stream_cb : Callback function 2633 * 2634 * RETURN : int32_t type of status 2635 * NO_ERROR -- success 2636 * non-zero failure code 2637 *==========================================================================*/ 2638 int32_t QCameraStream::setSyncDataCB(stream_cb_routine data_cb) 2639 { 2640 int32_t rc = NO_ERROR; 2641 2642 if (mCamOps != NULL) { 2643 mSYNCDataCB = data_cb; 2644 rc = mCamOps->register_stream_buf_cb(mCamHandle, 2645 mChannelHandle, mHandle, dataNotifySYNCCB, MM_CAMERA_STREAM_CB_TYPE_SYNC, 2646 this); 2647 if (rc == NO_ERROR) { 2648 mSyncCBEnabled = TRUE; 2649 return rc; 2650 } 2651 } 2652 LOGE("Interface handle is NULL"); 2653 return UNKNOWN_ERROR; 2654 } 2655 2656 }; // namespace qcamera 2657