1 /* Copyright (c) 2012-2014 The Linux Foundataion. All rights reserved. 2 * 3 * Redistribution and use in source and binary forms, with or without 4 * modification, are permitted provided that the following conditions are 5 * met: 6 * * Redistributions of source code must retain the above copyright 7 * notice, this list of conditions and the following disclaimer. 8 * * Redistributions in binary form must reproduce the above 9 * copyright notice, this list of conditions and the following 10 * disclaimer in the documentation and/or other materials provided 11 * with the distribution. 12 * * Neither the name of The Linux Foundation nor the names of its 13 * contributors may be used to endorse or promote products derived 14 * from this software without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED 17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS 20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 23 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 24 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 25 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 26 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 * 28 */ 29 30 #define LOG_TAG "QCameraStream" 31 32 #include <utils/Errors.h> 33 #include "QCamera2HWI.h" 34 #include "QCameraStream.h" 35 36 #define CAMERA_MIN_ALLOCATED_BUFFERS 3 37 38 namespace qcamera { 39 40 /*=========================================================================== 41 * FUNCTION : get_bufs 42 * 43 * DESCRIPTION: static function entry to allocate stream buffers 44 * 45 * PARAMETERS : 46 * @offset : offset info of stream buffers 47 * @num_bufs : number of buffers allocated 48 * @initial_reg_flag: flag to indicate if buffer needs to be registered 49 * at kernel initially 50 * @bufs : output of allocated buffers 51 * @ops_tbl : ptr to buf mapping/unmapping ops 52 * @user_data : user data ptr of ops_tbl 53 * 54 * RETURN : int32_t type of status 55 * NO_ERROR -- success 56 * none-zero failure code 57 *==========================================================================*/ 58 int32_t QCameraStream::get_bufs( 59 cam_frame_len_offset_t *offset, 60 uint8_t *num_bufs, 61 uint8_t **initial_reg_flag, 62 mm_camera_buf_def_t **bufs, 63 mm_camera_map_unmap_ops_tbl_t *ops_tbl, 64 void *user_data) 65 { 66 QCameraStream *stream = reinterpret_cast<QCameraStream *>(user_data); 67 if (!stream) { 68 ALOGE("getBufs invalid stream pointer"); 69 return NO_MEMORY; 70 } 71 return stream->getBufs(offset, num_bufs, initial_reg_flag, bufs, ops_tbl); 72 } 73 74 /*=========================================================================== 75 * FUNCTION : get_bufs_deffered 76 * 77 * DESCRIPTION: static function entry to allocate deffered stream buffers 78 * 79 * PARAMETERS : 80 * @offset : offset info of stream buffers 81 * @num_bufs : number of buffers allocated 82 * @initial_reg_flag: flag to indicate if buffer needs to be registered 83 * at kernel initially 84 * @bufs : output of allocated buffers 85 * @ops_tbl : ptr to buf mapping/unmapping ops 86 * @user_data : user data ptr of ops_tbl 87 * 88 * RETURN : int32_t type of status 89 * NO_ERROR -- success 90 * none-zero failure code 91 *==========================================================================*/ 92 int32_t QCameraStream::get_bufs_deffered( 93 cam_frame_len_offset_t * /* offset */, 94 uint8_t *num_bufs, 95 uint8_t **initial_reg_flag, 96 mm_camera_buf_def_t **bufs, 97 mm_camera_map_unmap_ops_tbl_t * /* ops_tbl */, 98 void *user_data) 99 { 100 QCameraStream *stream = reinterpret_cast<QCameraStream *>(user_data); 101 if (!stream) { 102 ALOGE("getBufs invalid stream pointer"); 103 return NO_MEMORY; 104 } 105 106 *initial_reg_flag = stream->mRegFlags; 107 *num_bufs = stream->mNumBufs; 108 *bufs = stream->mBufDefs; 109 return NO_ERROR; 110 } 111 112 /*=========================================================================== 113 * FUNCTION : put_bufs 114 * 115 * DESCRIPTION: static function entry to deallocate stream buffers 116 * 117 * PARAMETERS : 118 * @ops_tbl : ptr to buf mapping/unmapping ops 119 * @user_data : user data ptr of ops_tbl 120 * 121 * RETURN : int32_t type of status 122 * NO_ERROR -- success 123 * none-zero failure code 124 *==========================================================================*/ 125 int32_t QCameraStream::put_bufs( 126 mm_camera_map_unmap_ops_tbl_t *ops_tbl, 127 void *user_data) 128 { 129 QCameraStream *stream = reinterpret_cast<QCameraStream *>(user_data); 130 if (!stream) { 131 ALOGE("putBufs invalid stream pointer"); 132 return NO_MEMORY; 133 } 134 return stream->putBufs(ops_tbl); 135 } 136 137 /*=========================================================================== 138 * FUNCTION : put_bufs_deffered 139 * 140 * DESCRIPTION: static function entry to deallocate deffered stream buffers 141 * 142 * PARAMETERS : 143 * @ops_tbl : ptr to buf mapping/unmapping ops 144 * @user_data : user data ptr of ops_tbl 145 * 146 * RETURN : int32_t type of status 147 * NO_ERROR -- success 148 * none-zero failure code 149 *==========================================================================*/ 150 int32_t QCameraStream::put_bufs_deffered( 151 mm_camera_map_unmap_ops_tbl_t * /*ops_tbl */, 152 void * /*user_data*/ ) 153 { 154 // No op 155 // Used for handling buffers with deffered allocation. They are freed separately. 156 return NO_ERROR; 157 } 158 159 /*=========================================================================== 160 * FUNCTION : invalidate_buf 161 * 162 * DESCRIPTION: static function entry to invalidate a specific stream buffer 163 * 164 * PARAMETERS : 165 * @index : index of the stream buffer to invalidate 166 * @user_data : user data ptr of ops_tbl 167 * 168 * RETURN : int32_t type of status 169 * NO_ERROR -- success 170 * none-zero failure code 171 *==========================================================================*/ 172 int32_t QCameraStream::invalidate_buf(int index, void *user_data) 173 { 174 QCameraStream *stream = reinterpret_cast<QCameraStream *>(user_data); 175 if (!stream) { 176 ALOGE("invalid stream pointer"); 177 return NO_MEMORY; 178 } 179 if (stream->mStreamInfo->is_secure != SECURE) 180 return stream->invalidateBuf(index); 181 182 return 0; 183 } 184 185 /*=========================================================================== 186 * FUNCTION : clean_invalidate_buf 187 * 188 * DESCRIPTION: static function entry to clean invalidate a specific stream buffer 189 * 190 * PARAMETERS : 191 * @index : index of the stream buffer to clean invalidate 192 * @user_data : user data ptr of ops_tbl 193 * 194 * RETURN : int32_t type of status 195 * NO_ERROR -- success 196 * none-zero failure code 197 *==========================================================================*/ 198 int32_t QCameraStream::clean_invalidate_buf(int index, void *user_data) 199 { 200 QCameraStream *stream = reinterpret_cast<QCameraStream *>(user_data); 201 if (!stream) { 202 ALOGE("invalid stream pointer"); 203 return NO_MEMORY; 204 } 205 206 if (stream->mStreamInfo->is_secure != SECURE) 207 return stream->cleanInvalidateBuf(index); 208 209 return 0; 210 } 211 212 /*=========================================================================== 213 * FUNCTION : QCameraStream 214 * 215 * DESCRIPTION: constructor of QCameraStream 216 * 217 * PARAMETERS : 218 * @allocator : memory allocator obj 219 * @camHandle : camera handle 220 * @chId : channel handle 221 * @camOps : ptr to camera ops table 222 * @paddingInfo: ptr to padding info 223 * 224 * RETURN : None 225 *==========================================================================*/ 226 QCameraStream::QCameraStream(QCameraAllocator &allocator, 227 uint32_t camHandle, 228 uint32_t chId, 229 mm_camera_ops_t *camOps, 230 cam_padding_info_t *paddingInfo, 231 bool deffered) : 232 mDumpFrame(0), 233 mDumpMetaFrame(0), 234 mDumpSkipCnt(0), 235 mCamHandle(camHandle), 236 mChannelHandle(chId), 237 mHandle(0), 238 mCamOps(camOps), 239 mStreamInfo(NULL), 240 mNumBufs(0), 241 mNumBufsNeedAlloc(0), 242 mDataCB(NULL), 243 mUserData(NULL), 244 mDataQ(releaseFrameData, this), 245 mStreamInfoBuf(NULL), 246 mStreamBufs(NULL), 247 mAllocator(allocator), 248 mBufDefs(NULL), 249 mStreamBufsAcquired(false), 250 m_bActive(false), 251 mDynBufAlloc(false), 252 mBufAllocPid(0), 253 mDefferedAllocation(deffered), 254 wait_for_cond(false) 255 { 256 mMemVtbl.user_data = this; 257 if ( !deffered ) { 258 mMemVtbl.get_bufs = get_bufs; 259 mMemVtbl.put_bufs = put_bufs; 260 } else { 261 mMemVtbl.get_bufs = get_bufs_deffered; 262 mMemVtbl.put_bufs = put_bufs_deffered; 263 } 264 mMemVtbl.invalidate_buf = invalidate_buf; 265 mMemVtbl.clean_invalidate_buf = clean_invalidate_buf; 266 memset(&mFrameLenOffset, 0, sizeof(mFrameLenOffset)); 267 memcpy(&mPaddingInfo, paddingInfo, sizeof(cam_padding_info_t)); 268 memset(&mCropInfo, 0, sizeof(cam_rect_t)); 269 memset(&m_MemOpsTbl, 0, sizeof(mm_camera_map_unmap_ops_tbl_t)); 270 memset(&m_OutputCrop, 0, sizeof(cam_stream_parm_buffer_t)); 271 memset(&m_ImgProp, 0, sizeof(cam_stream_parm_buffer_t)); 272 pthread_mutex_init(&mCropLock, NULL); 273 pthread_mutex_init(&mParameterLock, NULL); 274 } 275 276 /*=========================================================================== 277 * FUNCTION : ~QCameraStream 278 * 279 * DESCRIPTION: deconstructor of QCameraStream 280 * 281 * PARAMETERS : None 282 * 283 * RETURN : None 284 *==========================================================================*/ 285 QCameraStream::~QCameraStream() 286 { 287 pthread_mutex_destroy(&mCropLock); 288 pthread_mutex_destroy(&mParameterLock); 289 290 if (mDefferedAllocation) { 291 mStreamBufsAcquired = false; 292 releaseBuffs(); 293 } 294 295 unmapStreamInfoBuf(); 296 releaseStreamInfoBuf(); 297 298 // delete stream 299 if (mHandle > 0) { 300 mCamOps->delete_stream(mCamHandle, mChannelHandle, mHandle); 301 mHandle = 0; 302 } 303 } 304 305 /*=========================================================================== 306 * FUNCTION : unmapStreamInfoBuf 307 * 308 * DESCRIPTION: Unmap stream info buffer 309 * 310 * PARAMETERS : 311 * 312 * RETURN : int32_t type of status 313 * NO_ERROR -- success 314 * none-zero failure code 315 *==========================================================================*/ 316 int32_t QCameraStream::unmapStreamInfoBuf() 317 { 318 int rc = NO_ERROR; 319 320 if (mStreamInfoBuf != NULL) { 321 rc = mCamOps->unmap_stream_buf(mCamHandle, 322 mChannelHandle, 323 mHandle, 324 CAM_MAPPING_BUF_TYPE_STREAM_INFO, 325 0, 326 -1); 327 328 if (rc < 0) { 329 ALOGE("Failed to unmap stream info buffer"); 330 } 331 } 332 333 return rc; 334 } 335 336 /*=========================================================================== 337 * FUNCTION : releaseStreamInfoBuf 338 * 339 * DESCRIPTION: Release stream info buffer 340 * 341 * PARAMETERS : 342 * 343 * RETURN : int32_t type of status 344 * NO_ERROR -- success 345 * none-zero failure code 346 *==========================================================================*/ 347 int32_t QCameraStream::releaseStreamInfoBuf() 348 { 349 int rc = NO_ERROR; 350 351 if (mStreamInfoBuf != NULL) { 352 mStreamInfoBuf->deallocate(); 353 delete mStreamInfoBuf; 354 mStreamInfoBuf = NULL; 355 } 356 357 return rc; 358 } 359 360 /*=========================================================================== 361 * FUNCTION : deleteStream 362 * 363 * DESCRIPTION: Deletes a camera stream 364 * 365 * PARAMETERS : None 366 * 367 * RETURN : None 368 *==========================================================================*/ 369 void QCameraStream::deleteStream() 370 { 371 if (mHandle > 0) { 372 acquireStreamBufs(); 373 releaseBuffs(); 374 unmapStreamInfoBuf(); 375 mCamOps->delete_stream(mCamHandle, mChannelHandle, mHandle); 376 } 377 } 378 379 /*=========================================================================== 380 * FUNCTION : init 381 * 382 * DESCRIPTION: initialize stream obj 383 * 384 * PARAMETERS : 385 * @streamInfoBuf: ptr to buf that contains stream info 386 * @stream_cb : stream data notify callback. Can be NULL if not needed 387 * @userdata : user data ptr 388 * @bDynallocBuf : flag to indicate if buffer allocation can be in 2 steps 389 * 390 * RETURN : int32_t type of status 391 * NO_ERROR -- success 392 * none-zero failure code 393 *==========================================================================*/ 394 int32_t QCameraStream::init(QCameraHeapMemory *streamInfoBuf, 395 uint8_t minNumBuffers, 396 stream_cb_routine stream_cb, 397 void *userdata, 398 bool bDynallocBuf) 399 { 400 int32_t rc = OK; 401 402 mHandle = mCamOps->add_stream(mCamHandle, mChannelHandle); 403 if (!mHandle) { 404 ALOGE("add_stream failed"); 405 rc = UNKNOWN_ERROR; 406 goto done; 407 } 408 409 // assign and map stream info memory 410 mStreamInfoBuf = streamInfoBuf; 411 mStreamInfo = reinterpret_cast<cam_stream_info_t *>(mStreamInfoBuf->getPtr(0)); 412 mNumBufs = minNumBuffers; 413 414 rc = mCamOps->map_stream_buf(mCamHandle, 415 mChannelHandle, mHandle, CAM_MAPPING_BUF_TYPE_STREAM_INFO, 416 0, -1, mStreamInfoBuf->getFd(0), mStreamInfoBuf->getSize(0)); 417 if (rc < 0) { 418 ALOGE("Failed to map stream info buffer"); 419 goto err1; 420 } 421 422 // Calculate buffer size for deffered allocation 423 if (mDefferedAllocation) { 424 rc = calcOffset(mStreamInfo); 425 if (rc < 0) { 426 ALOGE("%s : Failed to calculate stream offset", __func__); 427 goto err1; 428 } 429 } else { 430 rc = configStream(); 431 if (rc < 0) { 432 ALOGE("%s : Failed to config stream ", __func__); 433 goto err1; 434 } 435 } 436 437 mDataCB = stream_cb; 438 mUserData = userdata; 439 mDynBufAlloc = bDynallocBuf; 440 return 0; 441 442 err1: 443 mCamOps->delete_stream(mCamHandle, mChannelHandle, mHandle); 444 mHandle = 0; 445 mStreamInfoBuf = NULL; 446 mStreamInfo = NULL; 447 mNumBufs = 0; 448 done: 449 return rc; 450 } 451 452 /*=========================================================================== 453 * FUNCTION : calcOffset 454 * 455 * DESCRIPTION: calculate frame offset based on format and padding information 456 * 457 * PARAMETERS : 458 * @streamInfo : stream information 459 * 460 * RETURN : int32_t type of status 461 * 0 -- success 462 * -1 -- failure 463 *==========================================================================*/ 464 int32_t QCameraStream::calcOffset(cam_stream_info_t *streamInfo) 465 { 466 int32_t rc = 0; 467 468 cam_dimension_t dim = streamInfo->dim; 469 if (streamInfo->pp_config.feature_mask & CAM_QCOM_FEATURE_ROTATION && 470 streamInfo->stream_type != CAM_STREAM_TYPE_VIDEO) { 471 if (streamInfo->pp_config.rotation == ROTATE_90 || 472 streamInfo->pp_config.rotation == ROTATE_270) { 473 // rotated by 90 or 270, need to switch width and height 474 dim.width = streamInfo->dim.height; 475 dim.height = streamInfo->dim.width; 476 } 477 } 478 479 switch (streamInfo->stream_type) { 480 case CAM_STREAM_TYPE_PREVIEW: 481 rc = mm_stream_calc_offset_preview(streamInfo->fmt, 482 &dim, 483 &streamInfo->buf_planes); 484 break; 485 case CAM_STREAM_TYPE_POSTVIEW: 486 rc = mm_stream_calc_offset_post_view(streamInfo->fmt, 487 &dim, 488 &streamInfo->buf_planes); 489 break; 490 case CAM_STREAM_TYPE_SNAPSHOT: 491 rc = mm_stream_calc_offset_snapshot(streamInfo->fmt, 492 &dim, 493 &mPaddingInfo, 494 &streamInfo->buf_planes); 495 break; 496 case CAM_STREAM_TYPE_OFFLINE_PROC: 497 rc = mm_stream_calc_offset_postproc(streamInfo, 498 &mPaddingInfo, 499 &streamInfo->buf_planes); 500 break; 501 case CAM_STREAM_TYPE_VIDEO: 502 rc = mm_stream_calc_offset_video(&dim, 503 &streamInfo->buf_planes); 504 break; 505 case CAM_STREAM_TYPE_RAW: 506 rc = mm_stream_calc_offset_raw(streamInfo->fmt, 507 &dim, 508 &mPaddingInfo, 509 &streamInfo->buf_planes); 510 break; 511 case CAM_STREAM_TYPE_METADATA: 512 rc = mm_stream_calc_offset_metadata(&dim, 513 &mPaddingInfo, 514 &streamInfo->buf_planes); 515 break; 516 default: 517 ALOGE("%s: not supported for stream type %d", 518 __func__, streamInfo->stream_type); 519 rc = -1; 520 break; 521 } 522 return rc; 523 } 524 525 /*=========================================================================== 526 * FUNCTION : start 527 * 528 * DESCRIPTION: start stream. Will start main stream thread to handle stream 529 * related ops. 530 * 531 * PARAMETERS : none 532 * 533 * RETURN : int32_t type of status 534 * NO_ERROR -- success 535 * none-zero failure code 536 *==========================================================================*/ 537 int32_t QCameraStream::start() 538 { 539 int32_t rc = 0; 540 mDataQ.init(); 541 rc = mProcTh.launch(dataProcRoutine, this); 542 if (rc == NO_ERROR) { 543 m_bActive = true; 544 } 545 pthread_mutex_init(&m_lock, NULL); 546 pthread_cond_init(&m_cond, NULL); 547 return rc; 548 } 549 550 /*=========================================================================== 551 * FUNCTION : stop 552 * 553 * DESCRIPTION: stop stream. Will stop main stream thread 554 * 555 * PARAMETERS : none 556 * 557 * RETURN : int32_t type of status 558 * NO_ERROR -- success 559 * none-zero failure code 560 *==========================================================================*/ 561 int32_t QCameraStream::stop() 562 { 563 int32_t rc = 0; 564 m_bActive = false; 565 rc = mProcTh.exit(); 566 return rc; 567 } 568 569 /*=========================================================================== 570 * FUNCTION : syncRuntimeParams 571 * 572 * DESCRIPTION: query and sync runtime parameters like output crop 573 * buffer info etc. 574 * 575 * PARAMETERS : none 576 * 577 * RETURN : int32_t type of status 578 * NO_ERROR -- success 579 * none-zero failure code 580 *==========================================================================*/ 581 int32_t QCameraStream::syncRuntimeParams() 582 { 583 int32_t ret = NO_ERROR; 584 585 memset(&m_OutputCrop, 0, sizeof(cam_stream_parm_buffer_t)); 586 m_OutputCrop.type = CAM_STREAM_PARAM_TYPE_GET_OUTPUT_CROP; 587 588 ret = getParameter(m_OutputCrop); 589 if (ret != NO_ERROR) { 590 ALOGE("%s: stream getParameter for output crop failed", __func__); 591 return ret; 592 } 593 594 memset(&m_ImgProp, 0, sizeof(cam_stream_parm_buffer_t)); 595 m_ImgProp.type = CAM_STREAM_PARAM_TYPE_GET_IMG_PROP; 596 597 ret = getParameter(m_ImgProp); 598 if (ret != NO_ERROR) { 599 ALOGE("%s: stream getParameter for image prop failed", __func__); 600 return ret; 601 } 602 603 return ret; 604 } 605 606 /*=========================================================================== 607 * FUNCTION : processZoomDone 608 * 609 * DESCRIPTION: process zoom done event 610 * 611 * PARAMETERS : 612 * @previewWindoe : preview window ops table to set preview crop window 613 * @crop_info : crop info 614 * 615 * RETURN : int32_t type of status 616 * NO_ERROR -- success 617 * none-zero failure code 618 *==========================================================================*/ 619 int32_t QCameraStream::processZoomDone(preview_stream_ops_t *previewWindow, 620 cam_crop_data_t &crop_info) 621 { 622 int32_t rc = 0; 623 624 if (!m_bActive) { 625 ALOGV("%s : Stream not active", __func__); 626 return NO_ERROR; 627 } 628 629 // get stream param for crop info 630 for (int i = 0; i < crop_info.num_of_streams; i++) { 631 if (crop_info.crop_info[i].stream_id == mStreamInfo->stream_svr_id) { 632 pthread_mutex_lock(&mCropLock); 633 mCropInfo = crop_info.crop_info[i].crop; 634 pthread_mutex_unlock(&mCropLock); 635 636 // update preview window crop if it's preview/postview stream 637 if ( (previewWindow != NULL) && 638 (mStreamInfo->stream_type == CAM_STREAM_TYPE_PREVIEW || 639 mStreamInfo->stream_type == CAM_STREAM_TYPE_POSTVIEW) ) { 640 rc = previewWindow->set_crop(previewWindow, 641 mCropInfo.left, 642 mCropInfo.top, 643 mCropInfo.width, 644 mCropInfo.height); 645 } 646 break; 647 } 648 } 649 return rc; 650 } 651 652 /*=========================================================================== 653 * FUNCTION : processDataNotify 654 * 655 * DESCRIPTION: process stream data notify 656 * 657 * PARAMETERS : 658 * @frame : stream frame received 659 * 660 * RETURN : int32_t type of status 661 * NO_ERROR -- success 662 * none-zero failure code 663 *==========================================================================*/ 664 int32_t QCameraStream::processDataNotify(mm_camera_super_buf_t *frame) 665 { 666 CDBG("%s:\n", __func__); 667 if (mDataQ.enqueue((void *)frame)) { 668 return mProcTh.sendCmd(CAMERA_CMD_TYPE_DO_NEXT_JOB, FALSE, FALSE); 669 } else { 670 CDBG_HIGH("%s: Stream thread is not active, no ops here", __func__); 671 bufDone(frame->bufs[0]->buf_idx); 672 free(frame); 673 return NO_ERROR; 674 } 675 } 676 677 /*=========================================================================== 678 * FUNCTION : dataNotifyCB 679 * 680 * DESCRIPTION: callback for data notify. This function is registered with 681 * mm-camera-interface to handle data notify 682 * 683 * PARAMETERS : 684 * @recvd_frame : stream frame received 685 * userdata : user data ptr 686 * 687 * RETURN : none 688 *==========================================================================*/ 689 void QCameraStream::dataNotifyCB(mm_camera_super_buf_t *recvd_frame, 690 void *userdata) 691 { 692 CDBG("%s:\n", __func__); 693 QCameraStream* stream = (QCameraStream *)userdata; 694 if (stream == NULL || 695 recvd_frame == NULL || 696 recvd_frame->bufs[0] == NULL || 697 recvd_frame->bufs[0]->stream_id != stream->getMyHandle()) { 698 ALOGE("%s: Not a valid stream to handle buf", __func__); 699 return; 700 } 701 702 mm_camera_super_buf_t *frame = 703 (mm_camera_super_buf_t *)malloc(sizeof(mm_camera_super_buf_t)); 704 if (frame == NULL) { 705 ALOGE("%s: No mem for mm_camera_buf_def_t", __func__); 706 stream->bufDone(recvd_frame->bufs[0]->buf_idx); 707 return; 708 } 709 *frame = *recvd_frame; 710 stream->processDataNotify(frame); 711 return; 712 } 713 714 /*=========================================================================== 715 * FUNCTION : dataProcRoutine 716 * 717 * DESCRIPTION: function to process data in the main stream thread 718 * 719 * PARAMETERS : 720 * @data : user data ptr 721 * 722 * RETURN : none 723 *==========================================================================*/ 724 void *QCameraStream::dataProcRoutine(void *data) 725 { 726 int running = 1; 727 int ret; 728 QCameraStream *pme = (QCameraStream *)data; 729 QCameraCmdThread *cmdThread = &pme->mProcTh; 730 731 CDBG("%s: E", __func__); 732 do { 733 do { 734 ret = cam_sem_wait(&cmdThread->cmd_sem); 735 if (ret != 0 && errno != EINVAL) { 736 ALOGE("%s: cam_sem_wait error (%s)", 737 __func__, strerror(errno)); 738 return NULL; 739 } 740 } while (ret != 0); 741 742 // we got notified about new cmd avail in cmd queue 743 camera_cmd_type_t cmd = cmdThread->getCmd(); 744 switch (cmd) { 745 case CAMERA_CMD_TYPE_DO_NEXT_JOB: 746 { 747 CDBG_HIGH("%s: Do next job", __func__); 748 mm_camera_super_buf_t *frame = 749 (mm_camera_super_buf_t *)pme->mDataQ.dequeue(); 750 if (NULL != frame) { 751 if (pme->mDataCB != NULL) { 752 pme->mDataCB(frame, pme, pme->mUserData); 753 } else { 754 // no data cb routine, return buf here 755 pme->bufDone(frame->bufs[0]->buf_idx); 756 free(frame); 757 } 758 } 759 } 760 break; 761 case CAMERA_CMD_TYPE_EXIT: 762 CDBG_HIGH("%s: Exit", __func__); 763 /* flush data buf queue */ 764 pme->mDataQ.flush(); 765 running = 0; 766 break; 767 default: 768 break; 769 } 770 } while (running); 771 CDBG_HIGH("%s: X", __func__); 772 return NULL; 773 } 774 775 /*=========================================================================== 776 * FUNCTION : bufDone 777 * 778 * DESCRIPTION: return stream buffer to kernel 779 * 780 * PARAMETERS : 781 * @index : index of buffer to be returned 782 * 783 * RETURN : int32_t type of status 784 * NO_ERROR -- success 785 * none-zero failure code 786 *==========================================================================*/ 787 int32_t QCameraStream::bufDone(int index) 788 { 789 int32_t rc = NO_ERROR; 790 791 if (index >= mNumBufs || mBufDefs == NULL) 792 return BAD_INDEX; 793 794 rc = mCamOps->qbuf(mCamHandle, mChannelHandle, &mBufDefs[index]); 795 if (rc < 0) 796 return rc; 797 798 return rc; 799 } 800 801 /*=========================================================================== 802 * FUNCTION : bufDone 803 * 804 * DESCRIPTION: return stream buffer to kernel 805 * 806 * PARAMETERS : 807 * @opaque : stream frame/metadata buf to be returned 808 * @isMetaData: flag if returned opaque is a metadatabuf or the real frame ptr 809 * 810 * RETURN : int32_t type of status 811 * NO_ERROR -- success 812 * none-zero failure code 813 *==========================================================================*/ 814 int32_t QCameraStream::bufDone(const void *opaque, bool isMetaData) 815 { 816 int32_t rc = NO_ERROR; 817 818 int index = mStreamBufs->getMatchBufIndex(opaque, isMetaData); 819 if (index == -1 || index >= mNumBufs || mBufDefs == NULL) { 820 ALOGE("%s: Cannot find buf for opaque data = %p", __func__, opaque); 821 return BAD_INDEX; 822 } 823 CDBG_HIGH("%s: Buffer Index = %d, Frame Idx = %d", __func__, index, mBufDefs[index].frame_idx); 824 rc = bufDone(index); 825 return rc; 826 } 827 828 /*=========================================================================== 829 * FUNCTION : getBufs 830 * 831 * DESCRIPTION: allocate stream buffers 832 * 833 * PARAMETERS : 834 * @offset : offset info of stream buffers 835 * @num_bufs : number of buffers allocated 836 * @initial_reg_flag: flag to indicate if buffer needs to be registered 837 * at kernel initially 838 * @bufs : output of allocated buffers 839 * @ops_tbl : ptr to buf mapping/unmapping ops 840 * 841 * RETURN : int32_t type of status 842 * NO_ERROR -- success 843 * none-zero failure code 844 *==========================================================================*/ 845 int32_t QCameraStream::getBufs(cam_frame_len_offset_t *offset, 846 uint8_t *num_bufs, 847 uint8_t **initial_reg_flag, 848 mm_camera_buf_def_t **bufs, 849 mm_camera_map_unmap_ops_tbl_t *ops_tbl) 850 { 851 int rc = NO_ERROR; 852 uint8_t *regFlags; 853 854 if (!ops_tbl) { 855 ALOGE("%s: ops_tbl is NULL", __func__); 856 return INVALID_OPERATION; 857 } 858 859 mFrameLenOffset = *offset; 860 861 uint8_t numBufAlloc = mNumBufs; 862 mNumBufsNeedAlloc = 0; 863 if (mDynBufAlloc) { 864 numBufAlloc = CAMERA_MIN_ALLOCATED_BUFFERS; 865 if (numBufAlloc > mNumBufs) { 866 mDynBufAlloc = false; 867 numBufAlloc = mNumBufs; 868 } else { 869 mNumBufsNeedAlloc = mNumBufs - numBufAlloc; 870 } 871 } 872 873 //Allocate and map stream info buffer 874 mStreamBufs = mAllocator.allocateStreamBuf(mStreamInfo->stream_type, 875 mFrameLenOffset.frame_len, 876 mFrameLenOffset.mp[0].stride, 877 mFrameLenOffset.mp[0].scanline, 878 numBufAlloc); 879 mNumBufs = numBufAlloc + mNumBufsNeedAlloc; 880 881 if (!mStreamBufs) { 882 ALOGE("%s: Failed to allocate stream buffers", __func__); 883 return NO_MEMORY; 884 } 885 886 for (int i = 0; i < numBufAlloc; i++) { 887 rc = ops_tbl->map_ops(i, -1, mStreamBufs->getFd(i), 888 mStreamBufs->getSize(i), ops_tbl->userdata); 889 if (rc < 0) { 890 ALOGE("%s: map_stream_buf failed: %d", __func__, rc); 891 for (int j = 0; j < i; j++) { 892 ops_tbl->unmap_ops(j, -1, ops_tbl->userdata); 893 } 894 mStreamBufs->deallocate(); 895 delete mStreamBufs; 896 mStreamBufs = NULL; 897 return INVALID_OPERATION; 898 } 899 } 900 901 //regFlags array is allocated by us, but consumed and freed by mm-camera-interface 902 regFlags = (uint8_t *)malloc(sizeof(uint8_t) * mNumBufs); 903 if (!regFlags) { 904 ALOGE("%s: Out of memory", __func__); 905 for (int i = 0; i < numBufAlloc; i++) { 906 ops_tbl->unmap_ops(i, -1, ops_tbl->userdata); 907 } 908 mStreamBufs->deallocate(); 909 delete mStreamBufs; 910 mStreamBufs = NULL; 911 return NO_MEMORY; 912 } 913 memset(regFlags, 0, sizeof(uint8_t) * mNumBufs); 914 915 mBufDefs = (mm_camera_buf_def_t *)malloc(mNumBufs * sizeof(mm_camera_buf_def_t)); 916 if (mBufDefs == NULL) { 917 ALOGE("%s: getRegFlags failed %d", __func__, rc); 918 for (int i = 0; i < numBufAlloc; i++) { 919 ops_tbl->unmap_ops(i, -1, ops_tbl->userdata); 920 } 921 mStreamBufs->deallocate(); 922 delete mStreamBufs; 923 mStreamBufs = NULL; 924 free(regFlags); 925 regFlags = NULL; 926 return INVALID_OPERATION; 927 } 928 memset(mBufDefs, 0, mNumBufs * sizeof(mm_camera_buf_def_t)); 929 for (int i = 0; i < numBufAlloc; i++) { 930 mStreamBufs->getBufDef(mFrameLenOffset, mBufDefs[i], i); 931 } 932 933 rc = mStreamBufs->getRegFlags(regFlags); 934 if (rc < 0) { 935 ALOGE("%s: getRegFlags failed %d", __func__, rc); 936 for (int i = 0; i < numBufAlloc; i++) { 937 ops_tbl->unmap_ops(i, -1, ops_tbl->userdata); 938 } 939 mStreamBufs->deallocate(); 940 delete mStreamBufs; 941 mStreamBufs = NULL; 942 free(mBufDefs); 943 mBufDefs = NULL; 944 free(regFlags); 945 regFlags = NULL; 946 return INVALID_OPERATION; 947 } 948 949 *num_bufs = mNumBufs; 950 *initial_reg_flag = regFlags; 951 *bufs = mBufDefs; 952 953 if (mNumBufsNeedAlloc > 0) { 954 pthread_mutex_lock(&m_lock); 955 wait_for_cond = TRUE; 956 pthread_mutex_unlock(&m_lock); 957 CDBG_HIGH("%s: Still need to allocate %d buffers", 958 __func__, mNumBufsNeedAlloc); 959 // remember memops table 960 m_MemOpsTbl = *ops_tbl; 961 // start another thread to allocate the rest of buffers 962 pthread_create(&mBufAllocPid, 963 NULL, 964 BufAllocRoutine, 965 this); 966 } 967 968 return NO_ERROR; 969 } 970 971 /*=========================================================================== 972 * FUNCTION : allocateBuffers 973 * 974 * DESCRIPTION: allocate stream buffers 975 * 976 * PARAMETERS : 977 * 978 * RETURN : int32_t type of status 979 * NO_ERROR -- success 980 * none-zero failure code 981 *==========================================================================*/ 982 int32_t QCameraStream::allocateBuffers() 983 { 984 int rc = NO_ERROR; 985 986 mFrameLenOffset = mStreamInfo->buf_planes.plane_info; 987 988 //Allocate and map stream info buffer 989 mStreamBufs = mAllocator.allocateStreamBuf(mStreamInfo->stream_type, 990 mFrameLenOffset.frame_len, 991 mFrameLenOffset.mp[0].stride, 992 mFrameLenOffset.mp[0].scanline, 993 mNumBufs); 994 995 if (!mStreamBufs) { 996 ALOGE("%s: Failed to allocate stream buffers", __func__); 997 return NO_MEMORY; 998 } 999 1000 for (int i = 0; i < mNumBufs; i++) { 1001 rc = mapBuf(CAM_MAPPING_BUF_TYPE_STREAM_BUF, 1002 i, -1, 1003 mStreamBufs->getFd(i), 1004 mStreamBufs->getSize(i)); 1005 if (rc < 0) { 1006 ALOGE("%s: map_stream_buf failed: %d", __func__, rc); 1007 for (int j = 0; j < i; j++) { 1008 unmapBuf(CAM_MAPPING_BUF_TYPE_STREAM_BUF, i, -1); 1009 } 1010 mStreamBufs->deallocate(); 1011 delete mStreamBufs; 1012 mStreamBufs = NULL; 1013 return INVALID_OPERATION; 1014 } 1015 } 1016 1017 //regFlags array is allocated by us, 1018 // but consumed and freed by mm-camera-interface 1019 mRegFlags = (uint8_t *)malloc(sizeof(uint8_t) * mNumBufs); 1020 if (!mRegFlags) { 1021 ALOGE("%s: Out of memory", __func__); 1022 for (int i = 0; i < mNumBufs; i++) { 1023 unmapBuf(CAM_MAPPING_BUF_TYPE_STREAM_BUF, i, -1); 1024 } 1025 mStreamBufs->deallocate(); 1026 delete mStreamBufs; 1027 mStreamBufs = NULL; 1028 return NO_MEMORY; 1029 } 1030 memset(mRegFlags, 0, sizeof(uint8_t) * mNumBufs); 1031 1032 size_t bufDefsSize = mNumBufs * sizeof(mm_camera_buf_def_t); 1033 mBufDefs = (mm_camera_buf_def_t *)malloc(bufDefsSize); 1034 if (mBufDefs == NULL) { 1035 ALOGE("%s: getRegFlags failed %d", __func__, rc); 1036 for (int i = 0; i < mNumBufs; i++) { 1037 unmapBuf(CAM_MAPPING_BUF_TYPE_STREAM_BUF, i, -1); 1038 } 1039 mStreamBufs->deallocate(); 1040 delete mStreamBufs; 1041 mStreamBufs = NULL; 1042 free(mRegFlags); 1043 mRegFlags = NULL; 1044 return INVALID_OPERATION; 1045 } 1046 memset(mBufDefs, 0, bufDefsSize); 1047 for (int i = 0; i < mNumBufs; i++) { 1048 mStreamBufs->getBufDef(mFrameLenOffset, mBufDefs[i], i); 1049 } 1050 1051 rc = mStreamBufs->getRegFlags(mRegFlags); 1052 if (rc < 0) { 1053 ALOGE("%s: getRegFlags failed %d", __func__, rc); 1054 for (int i = 0; i < mNumBufs; i++) { 1055 unmapBuf(CAM_MAPPING_BUF_TYPE_STREAM_BUF, i, -1); 1056 } 1057 mStreamBufs->deallocate(); 1058 delete mStreamBufs; 1059 mStreamBufs = NULL; 1060 free(mBufDefs); 1061 mBufDefs = NULL; 1062 free(mRegFlags); 1063 mRegFlags = NULL; 1064 return INVALID_OPERATION; 1065 } 1066 1067 return NO_ERROR; 1068 } 1069 1070 1071 /*=========================================================================== 1072 * FUNCTION : releaseBuffs 1073 * 1074 * DESCRIPTION: method to deallocate stream buffers 1075 * 1076 * PARAMETERS : 1077 * 1078 * RETURN : int32_t type of status 1079 * NO_ERROR -- success 1080 * none-zero failure code 1081 *==========================================================================*/ 1082 int32_t QCameraStream::releaseBuffs() 1083 { 1084 int rc = NO_ERROR; 1085 1086 if (NULL != mBufDefs) { 1087 for (int i = 0; i < mNumBufs; i++) { 1088 rc = unmapBuf(CAM_MAPPING_BUF_TYPE_STREAM_BUF, i, -1); 1089 if (rc < 0) { 1090 ALOGE("%s: map_stream_buf failed: %d", __func__, rc); 1091 } 1092 } 1093 1094 // mBufDefs just keep a ptr to the buffer 1095 // mm-camera-interface own the buffer, so no need to free 1096 mBufDefs = NULL; 1097 memset(&mFrameLenOffset, 0, sizeof(mFrameLenOffset)); 1098 } 1099 if ( !mStreamBufsAcquired ) { 1100 mStreamBufs->deallocate(); 1101 delete mStreamBufs; 1102 } 1103 1104 return rc; 1105 } 1106 1107 1108 /*=========================================================================== 1109 * FUNCTION : BufAllocRoutine 1110 * 1111 * DESCRIPTION: function to allocate additional stream buffers 1112 * 1113 * PARAMETERS : 1114 * @data : user data ptr 1115 * 1116 * RETURN : none 1117 *==========================================================================*/ 1118 void *QCameraStream::BufAllocRoutine(void *data) 1119 { 1120 QCameraStream *pme = (QCameraStream *)data; 1121 int32_t rc = NO_ERROR; 1122 1123 CDBG_HIGH("%s: E", __func__); 1124 pme->cond_wait(); 1125 if (pme->mNumBufsNeedAlloc > 0) { 1126 uint8_t numBufAlloc = pme->mNumBufs - pme->mNumBufsNeedAlloc; 1127 rc = pme->mAllocator.allocateMoreStreamBuf(pme->mStreamBufs, 1128 pme->mFrameLenOffset.frame_len, 1129 pme->mNumBufsNeedAlloc); 1130 if (rc == NO_ERROR){ 1131 for (int i = numBufAlloc; i < pme->mNumBufs; i++) { 1132 rc = pme->m_MemOpsTbl.map_ops(i, -1, 1133 pme->mStreamBufs->getFd(i), 1134 pme->mStreamBufs->getSize(i), 1135 pme->m_MemOpsTbl.userdata); 1136 if (rc == 0) { 1137 pme->mStreamBufs->getBufDef(pme->mFrameLenOffset, 1138 pme->mBufDefs[i], i); 1139 pme->mCamOps->qbuf(pme->mCamHandle, 1140 pme->mChannelHandle, 1141 &pme->mBufDefs[i]); 1142 } else { 1143 ALOGE("%s: map_stream_buf %d failed: %d", __func__, rc, i); 1144 } 1145 } 1146 1147 pme->mNumBufsNeedAlloc = 0; 1148 } 1149 } 1150 CDBG_HIGH("%s: X", __func__); 1151 return NULL; 1152 } 1153 1154 /*=========================================================================== 1155 * FUNCTION : cond_signal 1156 * 1157 * DESCRIPTION: signal if flag "wait_for_cond" is set 1158 * 1159 *==========================================================================*/ 1160 void QCameraStream::cond_signal() 1161 { 1162 pthread_mutex_lock(&m_lock); 1163 if(wait_for_cond == TRUE){ 1164 wait_for_cond = FALSE; 1165 pthread_cond_signal(&m_cond); 1166 } 1167 pthread_mutex_unlock(&m_lock); 1168 } 1169 1170 1171 /*=========================================================================== 1172 * FUNCTION : cond_wait 1173 * 1174 * DESCRIPTION: wait on if flag "wait_for_cond" is set 1175 * 1176 *==========================================================================*/ 1177 void QCameraStream::cond_wait() 1178 { 1179 pthread_mutex_lock(&m_lock); 1180 while (wait_for_cond == TRUE) { 1181 pthread_cond_wait(&m_cond, &m_lock); 1182 } 1183 pthread_mutex_unlock(&m_lock); 1184 } 1185 1186 /*=========================================================================== 1187 * FUNCTION : putBufs 1188 * 1189 * DESCRIPTION: deallocate stream buffers 1190 * 1191 * PARAMETERS : 1192 * @ops_tbl : ptr to buf mapping/unmapping ops 1193 * 1194 * RETURN : int32_t type of status 1195 * NO_ERROR -- success 1196 * none-zero failure code 1197 *==========================================================================*/ 1198 int32_t QCameraStream::putBufs(mm_camera_map_unmap_ops_tbl_t *ops_tbl) 1199 { 1200 int rc = NO_ERROR; 1201 1202 if (mBufAllocPid != 0) { 1203 CDBG_HIGH("%s: wait for buf allocation thread dead", __func__); 1204 pthread_join(mBufAllocPid, NULL); 1205 mBufAllocPid = 0; 1206 CDBG_HIGH("%s: return from buf allocation thread", __func__); 1207 } 1208 1209 for (int i = 0; i < mNumBufs; i++) { 1210 rc = ops_tbl->unmap_ops(i, -1, ops_tbl->userdata); 1211 if (rc < 0) { 1212 ALOGE("%s: map_stream_buf failed: %d", __func__, rc); 1213 } 1214 } 1215 mBufDefs = NULL; // mBufDefs just keep a ptr to the buffer 1216 // mm-camera-interface own the buffer, so no need to free 1217 memset(&mFrameLenOffset, 0, sizeof(mFrameLenOffset)); 1218 if ( !mStreamBufsAcquired ) { 1219 mStreamBufs->deallocate(); 1220 delete mStreamBufs; 1221 } 1222 1223 return rc; 1224 } 1225 1226 /*=========================================================================== 1227 * FUNCTION : invalidateBuf 1228 * 1229 * DESCRIPTION: invalidate a specific stream buffer 1230 * 1231 * PARAMETERS : 1232 * @index : index of the buffer to invalidate 1233 * 1234 * RETURN : int32_t type of status 1235 * NO_ERROR -- success 1236 * none-zero failure code 1237 *==========================================================================*/ 1238 int32_t QCameraStream::invalidateBuf(int index) 1239 { 1240 return mStreamBufs->invalidateCache(index); 1241 } 1242 1243 /*=========================================================================== 1244 * FUNCTION : cleanInvalidateBuf 1245 * 1246 * DESCRIPTION: clean invalidate a specific stream buffer 1247 * 1248 * PARAMETERS : 1249 * @index : index of the buffer to clean invalidate 1250 * 1251 * RETURN : int32_t type of status 1252 * NO_ERROR -- success 1253 * none-zero failure code 1254 *==========================================================================*/ 1255 int32_t QCameraStream::cleanInvalidateBuf(int index) 1256 { 1257 return mStreamBufs->cleanInvalidateCache(index); 1258 } 1259 1260 /*=========================================================================== 1261 * FUNCTION : isTypeOf 1262 * 1263 * DESCRIPTION: helper function to determine if the stream is of the queried type 1264 * 1265 * PARAMETERS : 1266 * @type : stream type as of queried 1267 * 1268 * RETURN : true/false 1269 *==========================================================================*/ 1270 bool QCameraStream::isTypeOf(cam_stream_type_t type) 1271 { 1272 if (mStreamInfo != NULL && (mStreamInfo->stream_type == type)) { 1273 return true; 1274 } else { 1275 return false; 1276 } 1277 } 1278 1279 /*=========================================================================== 1280 * FUNCTION : isOrignalTypeOf 1281 * 1282 * DESCRIPTION: helper function to determine if the original stream is of the 1283 * queried type if it's reproc stream 1284 * 1285 * PARAMETERS : 1286 * @type : stream type as of queried 1287 * 1288 * RETURN : true/false 1289 *==========================================================================*/ 1290 bool QCameraStream::isOrignalTypeOf(cam_stream_type_t type) 1291 { 1292 if (mStreamInfo != NULL && 1293 mStreamInfo->stream_type == CAM_STREAM_TYPE_OFFLINE_PROC && 1294 mStreamInfo->reprocess_config.pp_type == CAM_ONLINE_REPROCESS_TYPE && 1295 mStreamInfo->reprocess_config.online.input_stream_type == type) { 1296 return true; 1297 } else if ( 1298 mStreamInfo != NULL && 1299 mStreamInfo->stream_type == CAM_STREAM_TYPE_OFFLINE_PROC && 1300 mStreamInfo->reprocess_config.pp_type == CAM_OFFLINE_REPROCESS_TYPE && 1301 mStreamInfo->reprocess_config.offline.input_type == type) { 1302 return true; 1303 } else { 1304 return false; 1305 } 1306 } 1307 1308 /*=========================================================================== 1309 * FUNCTION : getMyType 1310 * 1311 * DESCRIPTION: return stream type 1312 * 1313 * PARAMETERS : none 1314 * 1315 * RETURN : stream type 1316 *==========================================================================*/ 1317 cam_stream_type_t QCameraStream::getMyType() 1318 { 1319 if (mStreamInfo != NULL) { 1320 return mStreamInfo->stream_type; 1321 } else { 1322 return CAM_STREAM_TYPE_DEFAULT; 1323 } 1324 } 1325 1326 /*=========================================================================== 1327 * FUNCTION : getFrameOffset 1328 * 1329 * DESCRIPTION: query stream buffer frame offset info 1330 * 1331 * PARAMETERS : 1332 * @offset : reference to struct to store the queried frame offset info 1333 * 1334 * RETURN : int32_t type of status 1335 * NO_ERROR -- success 1336 * none-zero failure code 1337 *==========================================================================*/ 1338 int32_t QCameraStream::getFrameOffset(cam_frame_len_offset_t &offset) 1339 { 1340 offset = mFrameLenOffset; 1341 return 0; 1342 } 1343 1344 /*=========================================================================== 1345 * FUNCTION : getCropInfo 1346 * 1347 * DESCRIPTION: query crop info of the stream 1348 * 1349 * PARAMETERS : 1350 * @crop : reference to struct to store the queried crop info 1351 * 1352 * RETURN : int32_t type of status 1353 * NO_ERROR -- success 1354 * none-zero failure code 1355 *==========================================================================*/ 1356 int32_t QCameraStream::getCropInfo(cam_rect_t &crop) 1357 { 1358 pthread_mutex_lock(&mCropLock); 1359 crop = mCropInfo; 1360 pthread_mutex_unlock(&mCropLock); 1361 return NO_ERROR; 1362 } 1363 1364 /*=========================================================================== 1365 * FUNCTION : setCropInfo 1366 * 1367 * DESCRIPTION: set crop info of the stream 1368 * 1369 * PARAMETERS : 1370 * @crop : struct to store new crop info 1371 * 1372 * RETURN : int32_t type of status 1373 * NO_ERROR -- success 1374 * none-zero failure code 1375 *==========================================================================*/ 1376 int32_t QCameraStream::setCropInfo(cam_rect_t crop) 1377 { 1378 pthread_mutex_lock(&mCropLock); 1379 mCropInfo = crop; 1380 pthread_mutex_unlock(&mCropLock); 1381 return NO_ERROR; 1382 } 1383 1384 /*=========================================================================== 1385 * FUNCTION : getFrameDimension 1386 * 1387 * DESCRIPTION: query stream frame dimension info 1388 * 1389 * PARAMETERS : 1390 * @dim : reference to struct to store the queried frame dimension 1391 * 1392 * RETURN : int32_t type of status 1393 * NO_ERROR -- success 1394 * none-zero failure code 1395 *==========================================================================*/ 1396 int32_t QCameraStream::getFrameDimension(cam_dimension_t &dim) 1397 { 1398 if (mStreamInfo != NULL) { 1399 dim = mStreamInfo->dim; 1400 return 0; 1401 } 1402 return -1; 1403 } 1404 1405 /*=========================================================================== 1406 * FUNCTION : getFormat 1407 * 1408 * DESCRIPTION: query stream format 1409 * 1410 * PARAMETERS : 1411 * @fmt : reference to stream format 1412 * 1413 * RETURN : int32_t type of status 1414 * NO_ERROR -- success 1415 * none-zero failure code 1416 *==========================================================================*/ 1417 int32_t QCameraStream::getFormat(cam_format_t &fmt) 1418 { 1419 if (mStreamInfo != NULL) { 1420 fmt = mStreamInfo->fmt; 1421 return 0; 1422 } 1423 return -1; 1424 } 1425 1426 /*=========================================================================== 1427 * FUNCTION : getMyServerID 1428 * 1429 * DESCRIPTION: query server stream ID 1430 * 1431 * PARAMETERS : None 1432 * 1433 * RETURN : stream ID from server 1434 *==========================================================================*/ 1435 uint32_t QCameraStream::getMyServerID() { 1436 if (mStreamInfo != NULL) { 1437 return mStreamInfo->stream_svr_id; 1438 } else { 1439 return 0; 1440 } 1441 } 1442 1443 /*=========================================================================== 1444 * FUNCTION : acquireStreamBufs 1445 * 1446 * DESCRIPTION: acquire stream buffers and postpone their release. 1447 * 1448 * PARAMETERS : None 1449 * 1450 * RETURN : int32_t type of status 1451 * NO_ERROR -- success 1452 * none-zero failure code 1453 *==========================================================================*/ 1454 int32_t QCameraStream::acquireStreamBufs() 1455 { 1456 mStreamBufsAcquired = true; 1457 1458 return NO_ERROR; 1459 } 1460 1461 /*=========================================================================== 1462 * FUNCTION : mapBuf 1463 * 1464 * DESCRIPTION: map stream related buffer to backend server 1465 * 1466 * PARAMETERS : 1467 * @buf_type : mapping type of buffer 1468 * @buf_idx : index of buffer 1469 * @plane_idx: plane index 1470 * @fd : fd of the buffer 1471 * @size : lenght of the buffer 1472 * 1473 * RETURN : int32_t type of status 1474 * NO_ERROR -- success 1475 * none-zero failure code 1476 *==========================================================================*/ 1477 int32_t QCameraStream::mapBuf(uint8_t buf_type, 1478 uint32_t buf_idx, 1479 int32_t plane_idx, 1480 int fd, 1481 uint32_t size) 1482 { 1483 return mCamOps->map_stream_buf(mCamHandle, mChannelHandle, 1484 mHandle, buf_type, 1485 buf_idx, plane_idx, 1486 fd, size); 1487 1488 } 1489 1490 /*=========================================================================== 1491 * FUNCTION : unmapBuf 1492 * 1493 * DESCRIPTION: unmap stream related buffer to backend server 1494 * 1495 * PARAMETERS : 1496 * @buf_type : mapping type of buffer 1497 * @buf_idx : index of buffer 1498 * @plane_idx: plane index 1499 * 1500 * RETURN : int32_t type of status 1501 * NO_ERROR -- success 1502 * none-zero failure code 1503 *==========================================================================*/ 1504 int32_t QCameraStream::unmapBuf(uint8_t buf_type, uint32_t buf_idx, int32_t plane_idx) 1505 { 1506 return mCamOps->unmap_stream_buf(mCamHandle, mChannelHandle, 1507 mHandle, buf_type, 1508 buf_idx, plane_idx); 1509 1510 } 1511 1512 /*=========================================================================== 1513 * FUNCTION : setParameter 1514 * 1515 * DESCRIPTION: set stream based parameters 1516 * 1517 * PARAMETERS : 1518 * @param : ptr to parameters to be set 1519 * 1520 * RETURN : int32_t type of status 1521 * NO_ERROR -- success 1522 * none-zero failure code 1523 *==========================================================================*/ 1524 int32_t QCameraStream::setParameter(cam_stream_parm_buffer_t ¶m) 1525 { 1526 int32_t rc = NO_ERROR; 1527 pthread_mutex_lock(&mParameterLock); 1528 mStreamInfo->parm_buf = param; 1529 rc = mCamOps->set_stream_parms(mCamHandle, 1530 mChannelHandle, 1531 mHandle, 1532 &mStreamInfo->parm_buf); 1533 if (rc == NO_ERROR) { 1534 param = mStreamInfo->parm_buf; 1535 } 1536 pthread_mutex_unlock(&mParameterLock); 1537 return rc; 1538 } 1539 1540 /*=========================================================================== 1541 * FUNCTION : getParameter 1542 * 1543 * DESCRIPTION: get stream based parameters 1544 * 1545 * PARAMETERS : 1546 * @param : ptr to parameters to be red 1547 * 1548 * RETURN : int32_t type of status 1549 * NO_ERROR -- success 1550 * none-zero failure code 1551 *==========================================================================*/ 1552 int32_t QCameraStream::getParameter(cam_stream_parm_buffer_t ¶m) 1553 { 1554 int32_t rc = NO_ERROR; 1555 pthread_mutex_lock(&mParameterLock); 1556 mStreamInfo->parm_buf = param; 1557 rc = mCamOps->get_stream_parms(mCamHandle, 1558 mChannelHandle, 1559 mHandle, 1560 &mStreamInfo->parm_buf); 1561 if (rc == NO_ERROR) { 1562 param = mStreamInfo->parm_buf; 1563 } 1564 pthread_mutex_unlock(&mParameterLock); 1565 return rc; 1566 } 1567 1568 /*=========================================================================== 1569 * FUNCTION : releaseFrameData 1570 * 1571 * DESCRIPTION: callback function to release frame data node 1572 * 1573 * PARAMETERS : 1574 * @data : ptr to post process input data 1575 * @user_data : user data ptr (QCameraReprocessor) 1576 * 1577 * RETURN : None 1578 *==========================================================================*/ 1579 void QCameraStream::releaseFrameData(void *data, void *user_data) 1580 { 1581 QCameraStream *pme = (QCameraStream *)user_data; 1582 mm_camera_super_buf_t *frame = (mm_camera_super_buf_t *)data; 1583 if (NULL != pme) { 1584 pme->bufDone(frame->bufs[0]->buf_idx); 1585 } 1586 } 1587 1588 /*=========================================================================== 1589 * FUNCTION : configStream 1590 * 1591 * DESCRIPTION: send stream configuration to back end 1592 * 1593 * PARAMETERS : 1594 * 1595 * RETURN : int32_t type of status 1596 * NO_ERROR -- success 1597 * none-zero failure code 1598 *==========================================================================*/ 1599 int32_t QCameraStream::configStream() 1600 { 1601 int rc = NO_ERROR; 1602 1603 // Configure the stream 1604 mm_camera_stream_config_t stream_config; 1605 stream_config.stream_info = mStreamInfo; 1606 stream_config.mem_vtbl = mMemVtbl; 1607 stream_config.stream_cb = dataNotifyCB; 1608 stream_config.padding_info = mPaddingInfo; 1609 stream_config.userdata = this; 1610 rc = mCamOps->config_stream(mCamHandle, 1611 mChannelHandle, mHandle, &stream_config); 1612 if (rc < 0) { 1613 ALOGE("Failed to config stream, rc = %d", rc); 1614 mCamOps->unmap_stream_buf(mCamHandle, 1615 mChannelHandle, 1616 mHandle, 1617 CAM_MAPPING_BUF_TYPE_STREAM_INFO, 1618 0, 1619 -1); 1620 return UNKNOWN_ERROR; 1621 } 1622 1623 return rc; 1624 } 1625 1626 }; // namespace qcamera 1627