1 /* Copyright (c) 2012-2013, 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 "QCameraChannel" 31 32 #include <utils/Errors.h> 33 #include "QCameraParameters.h" 34 #include "QCamera2HWI.h" 35 #include "QCameraChannel.h" 36 37 using namespace android; 38 39 namespace qcamera { 40 41 /*=========================================================================== 42 * FUNCTION : QCameraChannel 43 * 44 * DESCRIPTION: constrcutor of QCameraChannel 45 * 46 * PARAMETERS : 47 * @cam_handle : camera handle 48 * @cam_ops : ptr to camera ops table 49 * 50 * RETURN : none 51 *==========================================================================*/ 52 QCameraChannel::QCameraChannel(uint32_t cam_handle, 53 mm_camera_ops_t *cam_ops) 54 { 55 m_camHandle = cam_handle; 56 m_camOps = cam_ops; 57 m_bIsActive = false; 58 59 m_handle = 0; 60 m_numStreams = 0; 61 memset(mStreams, 0, sizeof(mStreams)); 62 } 63 64 /*=========================================================================== 65 * FUNCTION : QCameraChannel 66 * 67 * DESCRIPTION: default constrcutor of QCameraChannel 68 * 69 * PARAMETERS : none 70 * 71 * RETURN : none 72 *==========================================================================*/ 73 QCameraChannel::QCameraChannel() 74 { 75 m_camHandle = 0; 76 m_camOps = NULL; 77 m_bIsActive = false; 78 79 m_handle = 0; 80 m_numStreams = 0; 81 memset(mStreams, 0, sizeof(mStreams)); 82 } 83 84 /*=========================================================================== 85 * FUNCTION : ~QCameraChannel 86 * 87 * DESCRIPTION: destructor of QCameraChannel 88 * 89 * PARAMETERS : none 90 * 91 * RETURN : none 92 *==========================================================================*/ 93 QCameraChannel::~QCameraChannel() 94 { 95 if (m_bIsActive) { 96 stop(); 97 } 98 99 for (int i = 0; i < m_numStreams; i++) { 100 if (mStreams[i] != NULL) { 101 delete mStreams[i]; 102 mStreams[i] = 0; 103 } 104 } 105 m_numStreams = 0; 106 m_camOps->delete_channel(m_camHandle, m_handle); 107 m_handle = 0; 108 } 109 110 /*=========================================================================== 111 * FUNCTION : init 112 * 113 * DESCRIPTION: initialization of channel 114 * 115 * PARAMETERS : 116 * @attr : channel bundle attribute setting 117 * @dataCB : data notify callback 118 * @userData: user data ptr 119 * 120 * RETURN : int32_t type of status 121 * NO_ERROR -- success 122 * none-zero failure code 123 *==========================================================================*/ 124 int32_t QCameraChannel::init(mm_camera_channel_attr_t *attr, 125 mm_camera_buf_notify_t dataCB, 126 void *userData) 127 { 128 m_handle = m_camOps->add_channel(m_camHandle, 129 attr, 130 dataCB, 131 userData); 132 if (m_handle == 0) { 133 ALOGE("%s: Add channel failed", __func__); 134 return UNKNOWN_ERROR; 135 } 136 return NO_ERROR; 137 } 138 139 /*=========================================================================== 140 * FUNCTION : addStream 141 * 142 * DESCRIPTION: add a stream into channel 143 * 144 * PARAMETERS : 145 * @allocator : stream related buffer allocator 146 * @streamInfoBuf : ptr to buf that constains stream info 147 * @minStreamBufNum: number of stream buffers needed 148 * @paddingInfo : padding information 149 * @stream_cb : stream data notify callback 150 * @userdata : user data ptr 151 * 152 * RETURN : int32_t type of status 153 * NO_ERROR -- success 154 * none-zero failure code 155 *==========================================================================*/ 156 int32_t QCameraChannel::addStream(QCameraAllocator &allocator, 157 QCameraHeapMemory *streamInfoBuf, 158 uint8_t minStreamBufNum, 159 cam_padding_info_t *paddingInfo, 160 stream_cb_routine stream_cb, 161 void *userdata) 162 { 163 int32_t rc = NO_ERROR; 164 if (m_numStreams >= MAX_STREAM_NUM_IN_BUNDLE) { 165 ALOGE("%s: stream number (%d) exceeds max limit (%d)", 166 __func__, m_numStreams, MAX_STREAM_NUM_IN_BUNDLE); 167 return BAD_VALUE; 168 } 169 QCameraStream *pStream = new QCameraStream(allocator, 170 m_camHandle, 171 m_handle, 172 m_camOps, 173 paddingInfo); 174 if (pStream == NULL) { 175 ALOGE("%s: No mem for Stream", __func__); 176 return NO_MEMORY; 177 } 178 179 rc = pStream->init(streamInfoBuf, minStreamBufNum, stream_cb, userdata); 180 if (rc == 0) { 181 mStreams[m_numStreams] = pStream; 182 m_numStreams++; 183 } else { 184 delete pStream; 185 } 186 return rc; 187 } 188 189 /*=========================================================================== 190 * FUNCTION : start 191 * 192 * DESCRIPTION: start channel, which will start all streams belong to this channel 193 * 194 * PARAMETERS : None 195 * 196 * RETURN : int32_t type of status 197 * NO_ERROR -- success 198 * none-zero failure code 199 *==========================================================================*/ 200 int32_t QCameraChannel::start() 201 { 202 int32_t rc = NO_ERROR; 203 204 if (m_numStreams > 1) { 205 // there is more than one stream in the channel 206 // we need to notify mctl that all streams in this channel need to be bundled 207 cam_bundle_config_t bundleInfo; 208 memset(&bundleInfo, 0, sizeof(bundleInfo)); 209 rc = m_camOps->get_bundle_info(m_camHandle, m_handle, &bundleInfo); 210 if (rc != NO_ERROR) { 211 ALOGE("%s: get_bundle_info failed", __func__); 212 return rc; 213 } 214 if (bundleInfo.num_of_streams > 1) { 215 for (int i = 0; i < bundleInfo.num_of_streams; i++) { 216 QCameraStream *pStream = getStreamByServerID(bundleInfo.stream_ids[i]); 217 if (pStream != NULL) { 218 if (pStream->isTypeOf(CAM_STREAM_TYPE_METADATA)) { 219 // Skip metadata for reprocess now because PP module cannot handle meta data 220 // May need furthur discussion if Imaginglib need meta data 221 continue; 222 } 223 224 cam_stream_parm_buffer_t param; 225 memset(¶m, 0, sizeof(cam_stream_parm_buffer_t)); 226 param.type = CAM_STREAM_PARAM_TYPE_SET_BUNDLE_INFO; 227 param.bundleInfo = bundleInfo; 228 rc = pStream->setParameter(param); 229 if (rc != NO_ERROR) { 230 ALOGE("%s: stream setParameter for set bundle failed", __func__); 231 return rc; 232 } 233 } 234 } 235 } 236 } 237 238 for (int i = 0; i < m_numStreams; i++) { 239 if (mStreams[i] != NULL) { 240 mStreams[i]->start(); 241 } 242 } 243 rc = m_camOps->start_channel(m_camHandle, m_handle); 244 245 if (rc != NO_ERROR) { 246 for (int i = 0; i < m_numStreams; i++) { 247 if (mStreams[i] != NULL) { 248 mStreams[i]->stop(); 249 } 250 } 251 } else { 252 m_bIsActive = true; 253 } 254 255 return rc; 256 } 257 258 /*=========================================================================== 259 * FUNCTION : stop 260 * 261 * DESCRIPTION: stop a channel, which will stop all streams belong to this channel 262 * 263 * PARAMETERS : none 264 * 265 * RETURN : int32_t type of status 266 * NO_ERROR -- success 267 * none-zero failure code 268 *==========================================================================*/ 269 int32_t QCameraChannel::stop() 270 { 271 int32_t rc = NO_ERROR; 272 rc = m_camOps->stop_channel(m_camHandle, m_handle); 273 274 for (int i = 0; i < m_numStreams; i++) { 275 if (mStreams[i] != NULL) { 276 mStreams[i]->stop(); 277 } 278 } 279 280 m_bIsActive = false; 281 return rc; 282 } 283 284 /*=========================================================================== 285 * FUNCTION : bufDone 286 * 287 * DESCRIPTION: return a stream buf back to kernel 288 * 289 * PARAMETERS : 290 * @recvd_frame : stream buf frame to be returned 291 * 292 * RETURN : int32_t type of status 293 * NO_ERROR -- success 294 * none-zero failure code 295 *==========================================================================*/ 296 int32_t QCameraChannel::bufDone(mm_camera_super_buf_t *recvd_frame) 297 { 298 int32_t rc = NO_ERROR; 299 for (int i = 0; i < recvd_frame->num_bufs; i++) { 300 if (recvd_frame->bufs[i] != NULL) { 301 for (int j = 0; j < m_numStreams; j++) { 302 if (mStreams[j] != NULL && 303 mStreams[j]->getMyHandle() == recvd_frame->bufs[i]->stream_id) { 304 rc = mStreams[j]->bufDone(recvd_frame->bufs[i]->buf_idx); 305 break; // break loop j 306 } 307 } 308 } 309 } 310 311 return rc; 312 } 313 314 /*=========================================================================== 315 * FUNCTION : processZoomDone 316 * 317 * DESCRIPTION: process zoom done event 318 * 319 * PARAMETERS : 320 * @previewWindoe : ptr to preview window ops table, needed to set preview 321 * crop information 322 * @crop_info : crop info as a result of zoom operation 323 * 324 * RETURN : int32_t type of status 325 * NO_ERROR -- success 326 * none-zero failure code 327 *==========================================================================*/ 328 int32_t QCameraChannel::processZoomDone(preview_stream_ops_t *previewWindow, 329 cam_crop_data_t &crop_info) 330 { 331 int32_t rc = NO_ERROR; 332 for (int i = 0; i < m_numStreams; i++) { 333 if (mStreams[i] != NULL) { 334 rc = mStreams[i]->processZoomDone(previewWindow, crop_info); 335 } 336 } 337 return rc; 338 } 339 340 /*=========================================================================== 341 * FUNCTION : getStreamByHandle 342 * 343 * DESCRIPTION: return stream object by stream handle 344 * 345 * PARAMETERS : 346 * @streamHandle : stream handle 347 * 348 * RETURN : stream object. NULL if not found 349 *==========================================================================*/ 350 QCameraStream *QCameraChannel::getStreamByHandle(uint32_t streamHandle) 351 { 352 for (int i = 0; i < m_numStreams; i++) { 353 if (mStreams[i] != NULL && mStreams[i]->getMyHandle() == streamHandle) { 354 return mStreams[i]; 355 } 356 } 357 return NULL; 358 } 359 360 /*=========================================================================== 361 * FUNCTION : getStreamByServerID 362 * 363 * DESCRIPTION: return stream object by stream server ID from daemon 364 * 365 * PARAMETERS : 366 * @serverID : stream server ID 367 * 368 * RETURN : stream object. NULL if not found 369 *==========================================================================*/ 370 QCameraStream *QCameraChannel::getStreamByServerID(uint32_t serverID) 371 { 372 for (int i = 0; i < m_numStreams; i++) { 373 if (mStreams[i] != NULL && mStreams[i]->getMyServerID() == serverID) { 374 return mStreams[i]; 375 } 376 } 377 return NULL; 378 } 379 380 /*=========================================================================== 381 * FUNCTION : getStreamByIndex 382 * 383 * DESCRIPTION: return stream object by index of streams in the channel 384 * 385 * PARAMETERS : 386 * @index : index of stream in the channel 387 * 388 * RETURN : stream object. NULL if not found 389 *==========================================================================*/ 390 QCameraStream *QCameraChannel::getStreamByIndex(uint8_t index) 391 { 392 if (index < m_numStreams) { 393 return mStreams[index]; 394 } 395 return NULL; 396 } 397 398 /*=========================================================================== 399 * FUNCTION : QCameraPicChannel 400 * 401 * DESCRIPTION: constructor of QCameraPicChannel 402 * 403 * PARAMETERS : 404 * @cam_handle : camera handle 405 * @cam_ops : ptr to camera ops table 406 * 407 * RETURN : none 408 *==========================================================================*/ 409 QCameraPicChannel::QCameraPicChannel(uint32_t cam_handle, 410 mm_camera_ops_t *cam_ops) : 411 QCameraChannel(cam_handle, cam_ops) 412 { 413 } 414 415 /*=========================================================================== 416 * FUNCTION : QCameraPicChannel 417 * 418 * DESCRIPTION: default constructor of QCameraPicChannel 419 * 420 * PARAMETERS : none 421 * 422 * RETURN : none 423 *==========================================================================*/ 424 QCameraPicChannel::QCameraPicChannel() 425 { 426 } 427 428 /*=========================================================================== 429 * FUNCTION : ~QCameraPicChannel 430 * 431 * DESCRIPTION: destructor of QCameraPicChannel 432 * 433 * PARAMETERS : none 434 * 435 * RETURN : none 436 *==========================================================================*/ 437 QCameraPicChannel::~QCameraPicChannel() 438 { 439 } 440 441 /*=========================================================================== 442 * FUNCTION : takePicture 443 * 444 * DESCRIPTION: send request for queued snapshot frames 445 * 446 * PARAMETERS : 447 * @num_of_snapshot : number of snapshot frames requested 448 * 449 * RETURN : int32_t type of status 450 * NO_ERROR -- success 451 * none-zero failure code 452 *==========================================================================*/ 453 int32_t QCameraPicChannel::takePicture(uint8_t num_of_snapshot) 454 { 455 int32_t rc = m_camOps->request_super_buf(m_camHandle, 456 m_handle, 457 num_of_snapshot); 458 return rc; 459 } 460 461 /*=========================================================================== 462 * FUNCTION : cancelPicture 463 * 464 * DESCRIPTION: cancel request for queued snapshot frames 465 * 466 * PARAMETERS : none 467 * 468 * RETURN : int32_t type of status 469 * NO_ERROR -- success 470 * none-zero failure code 471 *==========================================================================*/ 472 int32_t QCameraPicChannel::cancelPicture() 473 { 474 int32_t rc = m_camOps->cancel_super_buf_request(m_camHandle, m_handle); 475 return rc; 476 } 477 478 /*=========================================================================== 479 * FUNCTION : QCameraVideoChannel 480 * 481 * DESCRIPTION: constructor of QCameraVideoChannel 482 * 483 * PARAMETERS : 484 * @cam_handle : camera handle 485 * @cam_ops : ptr to camera ops table 486 * 487 * RETURN : none 488 *==========================================================================*/ 489 QCameraVideoChannel::QCameraVideoChannel(uint32_t cam_handle, 490 mm_camera_ops_t *cam_ops) : 491 QCameraChannel(cam_handle, cam_ops) 492 { 493 } 494 495 /*=========================================================================== 496 * FUNCTION : QCameraVideoChannel 497 * 498 * DESCRIPTION: default constructor of QCameraVideoChannel 499 * 500 * PARAMETERS : none 501 * 502 * RETURN : none 503 *==========================================================================*/ 504 QCameraVideoChannel::QCameraVideoChannel() 505 { 506 } 507 508 /*=========================================================================== 509 * FUNCTION : ~QCameraVideoChannel 510 * 511 * DESCRIPTION: destructor of QCameraVideoChannel 512 * 513 * PARAMETERS : none 514 * 515 * RETURN : none 516 *==========================================================================*/ 517 QCameraVideoChannel::~QCameraVideoChannel() 518 { 519 } 520 521 /*=========================================================================== 522 * FUNCTION : releaseFrame 523 * 524 * DESCRIPTION: return video frame from app 525 * 526 * PARAMETERS : 527 * @opaque : ptr to video frame to be returned 528 * @isMetaData : if frame is a metadata or real frame 529 * 530 * RETURN : int32_t type of status 531 * NO_ERROR -- success 532 * none-zero failure code 533 *==========================================================================*/ 534 int32_t QCameraVideoChannel::releaseFrame(const void * opaque, bool isMetaData) 535 { 536 QCameraStream *pVideoStream = NULL; 537 for (int i = 0; i < m_numStreams; i++) { 538 if (mStreams[i] != NULL && mStreams[i]->isTypeOf(CAM_STREAM_TYPE_VIDEO)) { 539 pVideoStream = mStreams[i]; 540 break; 541 } 542 } 543 544 if (NULL == pVideoStream) { 545 ALOGE("%s: No video stream in the channel", __func__); 546 return BAD_VALUE; 547 } 548 549 int32_t rc = pVideoStream->bufDone(opaque, isMetaData); 550 return rc; 551 } 552 553 /*=========================================================================== 554 * FUNCTION : QCameraReprocessChannel 555 * 556 * DESCRIPTION: constructor of QCameraReprocessChannel 557 * 558 * PARAMETERS : 559 * @cam_handle : camera handle 560 * @cam_ops : ptr to camera ops table 561 * @pp_mask : post-proccess feature mask 562 * 563 * RETURN : none 564 *==========================================================================*/ 565 QCameraReprocessChannel::QCameraReprocessChannel(uint32_t cam_handle, 566 mm_camera_ops_t *cam_ops) : 567 QCameraChannel(cam_handle, cam_ops), 568 m_pSrcChannel(NULL) 569 { 570 memset(mSrcStreamHandles, 0, sizeof(mSrcStreamHandles)); 571 } 572 573 /*=========================================================================== 574 * FUNCTION : QCameraReprocessChannel 575 * 576 * DESCRIPTION: default constructor of QCameraReprocessChannel 577 * 578 * PARAMETERS : none 579 * 580 * RETURN : none 581 *==========================================================================*/ 582 QCameraReprocessChannel::QCameraReprocessChannel() : 583 m_pSrcChannel(NULL) 584 { 585 } 586 587 /*=========================================================================== 588 * FUNCTION : ~QCameraReprocessChannel 589 * 590 * DESCRIPTION: destructor of QCameraReprocessChannel 591 * 592 * PARAMETERS : none 593 * 594 * RETURN : none 595 *==========================================================================*/ 596 QCameraReprocessChannel::~QCameraReprocessChannel() 597 { 598 } 599 600 /*=========================================================================== 601 * FUNCTION : addReprocStreamsFromSource 602 * 603 * DESCRIPTION: add reprocess streams from input source channel 604 * 605 * PARAMETERS : 606 * @allocator : stream related buffer allocator 607 * @config : pp feature configuration 608 * @pSrcChannel : ptr to input source channel that needs reprocess 609 * @minStreamBufNum: number of stream buffers needed 610 * @paddingInfo : padding information 611 * 612 * RETURN : int32_t type of status 613 * NO_ERROR -- success 614 * none-zero failure code 615 *==========================================================================*/ 616 int32_t QCameraReprocessChannel::addReprocStreamsFromSource(QCameraAllocator& allocator, 617 cam_pp_feature_config_t &config, 618 QCameraChannel *pSrcChannel, 619 uint8_t minStreamBufNum, 620 cam_padding_info_t *paddingInfo) 621 { 622 int32_t rc = 0; 623 QCameraStream *pStream = NULL; 624 QCameraHeapMemory *pStreamInfoBuf = NULL; 625 cam_stream_info_t *streamInfo = NULL; 626 627 memset(mSrcStreamHandles, 0, sizeof(mSrcStreamHandles)); 628 629 for (int i = 0; i < pSrcChannel->getNumOfStreams(); i++) { 630 pStream = pSrcChannel->getStreamByIndex(i); 631 if (pStream != NULL) { 632 if (pStream->isTypeOf(CAM_STREAM_TYPE_METADATA)) { 633 // Skip metadata for reprocess now because PP module cannot handle meta data 634 // May need furthur discussion if Imaginglib need meta data 635 continue; 636 } 637 638 pStreamInfoBuf = allocator.allocateStreamInfoBuf(CAM_STREAM_TYPE_OFFLINE_PROC); 639 if (pStreamInfoBuf == NULL) { 640 ALOGE("%s: no mem for stream info buf", __func__); 641 rc = NO_MEMORY; 642 break; 643 } 644 645 streamInfo = (cam_stream_info_t *)pStreamInfoBuf->getPtr(0); 646 memset(streamInfo, 0, sizeof(cam_stream_info_t)); 647 streamInfo->stream_type = CAM_STREAM_TYPE_OFFLINE_PROC; 648 rc = pStream->getFormat(streamInfo->fmt); 649 rc = pStream->getFrameDimension(streamInfo->dim); 650 streamInfo->streaming_mode = CAM_STREAMING_MODE_BURST; 651 streamInfo->num_of_burst = minStreamBufNum; 652 653 streamInfo->reprocess_config.pp_type = CAM_ONLINE_REPROCESS_TYPE; 654 streamInfo->reprocess_config.online.input_stream_id = pStream->getMyServerID(); 655 streamInfo->reprocess_config.online.input_stream_type = pStream->getMyType(); 656 streamInfo->reprocess_config.pp_feature_config = config; 657 658 if (!(pStream->isTypeOf(CAM_STREAM_TYPE_SNAPSHOT) || 659 pStream->isTypeOf(CAM_STREAM_TYPE_NON_ZSL_SNAPSHOT) || 660 pStream->isOrignalTypeOf(CAM_STREAM_TYPE_SNAPSHOT) || 661 pStream->isOrignalTypeOf(CAM_STREAM_TYPE_NON_ZSL_SNAPSHOT))) { 662 streamInfo->reprocess_config.pp_feature_config.feature_mask &= ~CAM_QCOM_FEATURE_CAC; 663 } 664 if (streamInfo->reprocess_config.pp_feature_config.feature_mask & CAM_QCOM_FEATURE_ROTATION) { 665 if (streamInfo->reprocess_config.pp_feature_config.rotation == ROTATE_90 || 666 streamInfo->reprocess_config.pp_feature_config.rotation == ROTATE_270) { 667 // rotated by 90 or 270, need to switch width and height 668 int32_t temp = streamInfo->dim.height; 669 streamInfo->dim.height = streamInfo->dim.width; 670 streamInfo->dim.width = temp; 671 } 672 } 673 674 // save source stream handler 675 mSrcStreamHandles[m_numStreams] = pStream->getMyHandle(); 676 677 // add reprocess stream 678 rc = addStream(allocator, 679 pStreamInfoBuf, minStreamBufNum, 680 paddingInfo, 681 NULL, NULL); 682 if (rc != NO_ERROR) { 683 ALOGE("%s: add reprocess stream failed, ret = %d", __func__, rc); 684 break; 685 } 686 } 687 } 688 689 if (rc == NO_ERROR) { 690 m_pSrcChannel = pSrcChannel; 691 } 692 return rc; 693 } 694 695 /*=========================================================================== 696 * FUNCTION : getStreamBySrouceHandle 697 * 698 * DESCRIPTION: find reprocess stream by its source stream handle 699 * 700 * PARAMETERS : 701 * @srcHandle : source stream handle 702 * 703 * RETURN : ptr to reprocess stream if found. NULL if not found 704 *==========================================================================*/ 705 QCameraStream * QCameraReprocessChannel::getStreamBySrouceHandle(uint32_t srcHandle) 706 { 707 QCameraStream *pStream = NULL; 708 709 for (int i = 0; i < m_numStreams; i++) { 710 if (mSrcStreamHandles[i] == srcHandle) { 711 pStream = mStreams[i]; 712 break; 713 } 714 } 715 716 return pStream; 717 } 718 719 /*=========================================================================== 720 * FUNCTION : doReprocess 721 * 722 * DESCRIPTION: request to do a reprocess on the frame 723 * 724 * PARAMETERS : 725 * @frame : frame to be performed a reprocess 726 * 727 * RETURN : int32_t type of status 728 * NO_ERROR -- success 729 * none-zero failure code 730 *==========================================================================*/ 731 int32_t QCameraReprocessChannel::doReprocess(mm_camera_super_buf_t *frame) 732 { 733 int32_t rc = 0; 734 if (m_numStreams < 1) { 735 ALOGE("%s: No reprocess stream is created", __func__); 736 return -1; 737 } 738 if (m_pSrcChannel == NULL) { 739 ALOGE("%s: No source channel for reprocess", __func__); 740 return -1; 741 } 742 743 // find meta data stream and index of meta data frame in the superbuf 744 QCameraStream *pMetaStream = NULL; 745 uint8_t meta_buf_index = 0; 746 for (int i = 0; i < frame->num_bufs; i++) { 747 QCameraStream *pStream = m_pSrcChannel->getStreamByHandle(frame->bufs[i]->stream_id); 748 if (pStream != NULL) { 749 if (pStream->isTypeOf(CAM_STREAM_TYPE_METADATA)) { 750 meta_buf_index = frame->bufs[i]->buf_idx; 751 pMetaStream = pStream; 752 break; 753 } 754 } 755 } 756 757 for (int i = 0; i < frame->num_bufs; i++) { 758 QCameraStream *pStream = getStreamBySrouceHandle(frame->bufs[i]->stream_id); 759 if (pStream != NULL) { 760 if (pStream->isTypeOf(CAM_STREAM_TYPE_METADATA)) { 761 // Skip metadata for reprocess now because PP module cannot handle meta data 762 // May need furthur discussion if Imaginglib need meta data 763 continue; 764 } 765 766 cam_stream_parm_buffer_t param; 767 memset(¶m, 0, sizeof(cam_stream_parm_buffer_t)); 768 param.type = CAM_STREAM_PARAM_TYPE_DO_REPROCESS; 769 param.reprocess.buf_index = frame->bufs[i]->buf_idx; 770 param.reprocess.frame_idx = frame->bufs[i]->frame_idx; 771 if (pMetaStream != NULL) { 772 // we have meta data frame bundled, sent together with reprocess frame 773 param.reprocess.meta_present = 1; 774 param.reprocess.meta_stream_handle = pMetaStream->getMyServerID(); 775 param.reprocess.meta_buf_index = meta_buf_index; 776 } 777 rc = pStream->setParameter(param); 778 if (rc != NO_ERROR) { 779 ALOGE("%s: stream setParameter for reprocess failed", __func__); 780 break; 781 } 782 } 783 } 784 return rc; 785 } 786 787 /*=========================================================================== 788 * FUNCTION : doReprocess 789 * 790 * DESCRIPTION: request to do a reprocess on the frame 791 * 792 * PARAMETERS : 793 * @buf_fd : fd to the input buffer that needs reprocess 794 * @buf_lenght : length of the input buffer 795 * @ret_val : result of reprocess. 796 * Example: Could be faceID in case of register face image. 797 * 798 * RETURN : int32_t type of status 799 * NO_ERROR -- success 800 * none-zero failure code 801 *==========================================================================*/ 802 int32_t QCameraReprocessChannel::doReprocess(int buf_fd, 803 uint32_t buf_length, 804 int32_t &ret_val) 805 { 806 int32_t rc = 0; 807 if (m_numStreams < 1) { 808 ALOGE("%s: No reprocess stream is created", __func__); 809 return -1; 810 } 811 812 uint32_t buf_idx = 0; 813 for (int i = 0; i < m_numStreams; i++) { 814 rc = mStreams[i]->mapBuf(CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF, 815 buf_idx, -1, 816 buf_fd, buf_length); 817 818 if (rc == NO_ERROR) { 819 cam_stream_parm_buffer_t param; 820 memset(¶m, 0, sizeof(cam_stream_parm_buffer_t)); 821 param.type = CAM_STREAM_PARAM_TYPE_DO_REPROCESS; 822 param.reprocess.buf_index = buf_idx; 823 rc = mStreams[i]->setParameter(param); 824 if (rc == NO_ERROR) { 825 ret_val = param.reprocess.ret_val; 826 } 827 mStreams[i]->unmapBuf(CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF, 828 buf_idx, -1); 829 } 830 } 831 return rc; 832 } 833 834 }; // namespace qcamera 835