1 /* Copyright (c) 2012-2015, 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 m_bAllowDynBufAlloc = false; 59 60 m_handle = 0; 61 } 62 63 /*=========================================================================== 64 * FUNCTION : QCameraChannel 65 * 66 * DESCRIPTION: default constrcutor of QCameraChannel 67 * 68 * PARAMETERS : none 69 * 70 * RETURN : none 71 *==========================================================================*/ 72 QCameraChannel::QCameraChannel() 73 { 74 m_camHandle = 0; 75 m_camOps = NULL; 76 m_bIsActive = false; 77 78 m_handle = 0; 79 } 80 81 /*=========================================================================== 82 * FUNCTION : ~QCameraChannel 83 * 84 * DESCRIPTION: destructor of QCameraChannel 85 * 86 * PARAMETERS : none 87 * 88 * RETURN : none 89 *==========================================================================*/ 90 QCameraChannel::~QCameraChannel() 91 { 92 if (m_bIsActive) { 93 stop(); 94 } 95 for (size_t i = 0; i < mStreams.size(); i++) { 96 if (mStreams[i] != NULL) { 97 if (m_handle == mStreams[i]->getChannelHandle()) { 98 delete mStreams[i]; 99 } 100 } 101 } 102 mStreams.clear(); 103 m_camOps->delete_channel(m_camHandle, m_handle); 104 m_handle = 0; 105 } 106 107 /*=========================================================================== 108 * FUNCTION : deleteChannel 109 * 110 * DESCRIPTION: deletes a camera channel 111 * 112 * PARAMETERS : none 113 * 114 * RETURN : none 115 *==========================================================================*/ 116 void QCameraChannel::deleteChannel() 117 { 118 if (m_bIsActive) { 119 stop(); 120 } 121 for (size_t i = 0; i < mStreams.size(); i++) { 122 if ((mStreams[i] != NULL) && (m_handle == mStreams[i]->getChannelHandle())) { 123 mStreams[i]->deleteStream(); 124 } 125 } 126 m_camOps->delete_channel(m_camHandle, m_handle); 127 } 128 129 /*=========================================================================== 130 * FUNCTION : init 131 * 132 * DESCRIPTION: initialization of channel 133 * 134 * PARAMETERS : 135 * @attr : channel bundle attribute setting 136 * @dataCB : data notify callback 137 * @userData: user data ptr 138 * 139 * RETURN : int32_t type of status 140 * NO_ERROR -- success 141 * none-zero failure code 142 *==========================================================================*/ 143 int32_t QCameraChannel::init(mm_camera_channel_attr_t *attr, 144 mm_camera_buf_notify_t dataCB, 145 void *userData) 146 { 147 m_handle = m_camOps->add_channel(m_camHandle, 148 attr, 149 dataCB, 150 userData); 151 if (m_handle == 0) { 152 ALOGE("%s: Add channel failed", __func__); 153 return UNKNOWN_ERROR; 154 } 155 return NO_ERROR; 156 } 157 158 /*=========================================================================== 159 * FUNCTION : addStream 160 * 161 * DESCRIPTION: add a stream into channel 162 * 163 * PARAMETERS : 164 * @allocator : stream related buffer allocator 165 * @streamInfoBuf : ptr to buf that contains stream info 166 * @miscBuf : ptr to buf that contains misc buffers 167 * @minStreamBufNum: number of stream buffers needed 168 * @paddingInfo : padding information 169 * @stream_cb : stream data notify callback 170 * @userdata : user data ptr 171 * @bDynAllocBuf : flag indicating if allow allocate buffers in 2 steps 172 * @online_rotation: rotation applied online 173 * 174 * RETURN : int32_t type of status 175 * NO_ERROR -- success 176 * none-zero failure code 177 *==========================================================================*/ 178 int32_t QCameraChannel::addStream(QCameraAllocator &allocator, 179 QCameraHeapMemory *streamInfoBuf, QCameraHeapMemory *miscBuf, 180 uint8_t minStreamBufNum, cam_padding_info_t *paddingInfo, 181 stream_cb_routine stream_cb, void *userdata, bool bDynAllocBuf, 182 bool bDeffAlloc, cam_rotation_t online_rotation) 183 { 184 int32_t rc = NO_ERROR; 185 if (mStreams.size() >= MAX_STREAM_NUM_IN_BUNDLE) { 186 ALOGE("%s: stream number (%zu) exceeds max limit (%d)", 187 __func__, mStreams.size(), MAX_STREAM_NUM_IN_BUNDLE); 188 if (streamInfoBuf != NULL) { 189 streamInfoBuf->deallocate(); 190 delete streamInfoBuf; 191 streamInfoBuf = NULL; 192 } 193 return BAD_VALUE; 194 } 195 QCameraStream *pStream = new QCameraStream(allocator, 196 m_camHandle, m_handle, m_camOps, paddingInfo, bDeffAlloc, 197 online_rotation); 198 if (pStream == NULL) { 199 ALOGE("%s: No mem for Stream", __func__); 200 if (streamInfoBuf != NULL) { 201 streamInfoBuf->deallocate(); 202 delete streamInfoBuf; 203 streamInfoBuf = NULL; 204 } 205 return NO_MEMORY; 206 } 207 208 rc = pStream->init(streamInfoBuf, miscBuf, minStreamBufNum, 209 stream_cb, userdata, bDynAllocBuf); 210 if (rc == 0) { 211 mStreams.add(pStream); 212 } else { 213 delete pStream; 214 } 215 return rc; 216 } 217 /*=========================================================================== 218 * FUNCTION : config 219 * 220 * DESCRIPTION: Configure any deffered channel streams 221 * 222 * PARAMETERS : None 223 * 224 * RETURN : int32_t type of status 225 * NO_ERROR -- success 226 * none-zero failure code 227 *==========================================================================*/ 228 int32_t QCameraChannel::config() 229 { 230 int32_t rc = NO_ERROR; 231 for (size_t i = 0; i < mStreams.size(); ++i) { 232 if ( mStreams[i]->isDeffered() ) { 233 rc = mStreams[i]->configStream(); 234 if (rc != NO_ERROR) { 235 break; 236 } 237 } 238 } 239 return rc; 240 } 241 242 /*=========================================================================== 243 * FUNCTION : linkStream 244 * 245 * DESCRIPTION: link a stream into channel 246 * 247 * PARAMETERS : 248 * @ch : Channel which the stream belongs to 249 * @stream : Stream which needs to be linked 250 * 251 * RETURN : int32_t type of status 252 * NO_ERROR -- success 253 * none-zero failure code 254 *==========================================================================*/ 255 int32_t QCameraChannel::linkStream(QCameraChannel *ch, QCameraStream *stream) 256 { 257 int32_t rc = NO_ERROR; 258 259 if ((0 == m_handle) || (NULL == ch) || (NULL == stream)) { 260 return NO_INIT; 261 } 262 263 int32_t handle = m_camOps->link_stream(m_camHandle, 264 ch->getMyHandle(), 265 stream->getMyHandle(), 266 m_handle); 267 if (0 == handle) { 268 ALOGE("%s : Linking of stream failed", __func__); 269 rc = INVALID_OPERATION; 270 } else { 271 mStreams.add(stream); 272 } 273 274 return rc; 275 } 276 277 /*=========================================================================== 278 * FUNCTION : start 279 * 280 * DESCRIPTION: start channel, which will start all streams belong to this channel 281 * 282 * PARAMETERS : None 283 * 284 * RETURN : int32_t type of status 285 * NO_ERROR -- success 286 * none-zero failure code 287 *==========================================================================*/ 288 int32_t QCameraChannel::start() 289 { 290 int32_t rc = NO_ERROR; 291 292 if (mStreams.size() > 1) { 293 // there is more than one stream in the channel 294 // we need to notify mctl that all streams in this channel need to be bundled 295 cam_bundle_config_t bundleInfo; 296 memset(&bundleInfo, 0, sizeof(bundleInfo)); 297 rc = m_camOps->get_bundle_info(m_camHandle, m_handle, &bundleInfo); 298 if (rc != NO_ERROR) { 299 ALOGE("%s: get_bundle_info failed", __func__); 300 return rc; 301 } 302 if (bundleInfo.num_of_streams > 1) { 303 for (int i = 0; i < bundleInfo.num_of_streams; i++) { 304 QCameraStream *pStream = getStreamByServerID(bundleInfo.stream_ids[i]); 305 if (pStream != NULL) { 306 if (pStream->isTypeOf(CAM_STREAM_TYPE_METADATA)) { 307 // Skip metadata for reprocess now because PP module cannot handle meta data 308 // May need furthur discussion if Imaginglib need meta data 309 continue; 310 } 311 312 cam_stream_parm_buffer_t param; 313 memset(¶m, 0, sizeof(cam_stream_parm_buffer_t)); 314 param.type = CAM_STREAM_PARAM_TYPE_SET_BUNDLE_INFO; 315 param.bundleInfo = bundleInfo; 316 rc = pStream->setParameter(param); 317 if (rc != NO_ERROR) { 318 ALOGE("%s: stream setParameter for set bundle failed", __func__); 319 return rc; 320 } 321 } 322 } 323 } 324 } 325 326 for (size_t i = 0; i < mStreams.size(); i++) { 327 if ((mStreams[i] != NULL) && 328 (m_handle == mStreams[i]->getChannelHandle())) { 329 mStreams[i]->start(); 330 } 331 } 332 rc = m_camOps->start_channel(m_camHandle, m_handle); 333 334 if (rc != NO_ERROR) { 335 for (size_t i = 0; i < mStreams.size(); i++) { 336 if ((mStreams[i] != NULL) && 337 (m_handle == mStreams[i]->getChannelHandle())) { 338 mStreams[i]->stop(); 339 } 340 } 341 } else { 342 m_bIsActive = true; 343 for (size_t i = 0; i < mStreams.size(); i++) { 344 if (mStreams[i] != NULL) { 345 mStreams[i]->cond_signal(); 346 } 347 } 348 } 349 350 return rc; 351 } 352 353 /*=========================================================================== 354 * FUNCTION : stop 355 * 356 * DESCRIPTION: stop a channel, which will stop all streams belong to this channel 357 * 358 * PARAMETERS : none 359 * 360 * RETURN : int32_t type of status 361 * NO_ERROR -- success 362 * none-zero failure code 363 *==========================================================================*/ 364 int32_t QCameraChannel::stop() 365 { 366 int32_t rc = NO_ERROR; 367 ssize_t linkedIdx = -1; 368 369 if (!m_bIsActive) { 370 return NO_INIT; 371 } 372 373 for (size_t i = 0; i < mStreams.size(); i++) { 374 if (mStreams[i] != NULL) { 375 if (m_handle == mStreams[i]->getChannelHandle()) { 376 mStreams[i]->stop(); 377 } else { 378 // Remove linked stream from stream list 379 linkedIdx = (ssize_t)i; 380 } 381 } 382 } 383 if (linkedIdx > 0) { 384 mStreams.removeAt((size_t)linkedIdx); 385 } 386 387 rc = m_camOps->stop_channel(m_camHandle, m_handle); 388 389 m_bIsActive = false; 390 return rc; 391 } 392 393 /*=========================================================================== 394 * FUNCTION : bufDone 395 * 396 * DESCRIPTION: return a stream buf back to kernel 397 * 398 * PARAMETERS : 399 * @recvd_frame : stream buf frame to be returned 400 * 401 * RETURN : int32_t type of status 402 * NO_ERROR -- success 403 * none-zero failure code 404 *==========================================================================*/ 405 int32_t QCameraChannel::bufDone(mm_camera_super_buf_t *recvd_frame) 406 { 407 int32_t rc = NO_ERROR; 408 for (uint32_t i = 0; i < recvd_frame->num_bufs; i++) { 409 if (recvd_frame->bufs[i] != NULL) { 410 for (size_t j = 0; j < mStreams.size(); j++) { 411 if (mStreams[j] != NULL && 412 mStreams[j]->getMyHandle() == recvd_frame->bufs[i]->stream_id) { 413 rc = mStreams[j]->bufDone(recvd_frame->bufs[i]->buf_idx); 414 break; // break loop j 415 } 416 } 417 } 418 } 419 420 return rc; 421 } 422 423 /*=========================================================================== 424 * FUNCTION : processZoomDone 425 * 426 * DESCRIPTION: process zoom done event 427 * 428 * PARAMETERS : 429 * @previewWindoe : ptr to preview window ops table, needed to set preview 430 * crop information 431 * @crop_info : crop info as a result of zoom operation 432 * 433 * RETURN : int32_t type of status 434 * NO_ERROR -- success 435 * none-zero failure code 436 *==========================================================================*/ 437 int32_t QCameraChannel::processZoomDone(preview_stream_ops_t *previewWindow, 438 cam_crop_data_t &crop_info) 439 { 440 int32_t rc = NO_ERROR; 441 for (size_t i = 0; i < mStreams.size(); i++) { 442 if ((mStreams[i] != NULL) && 443 (m_handle == mStreams[i]->getChannelHandle())) { 444 rc = mStreams[i]->processZoomDone(previewWindow, crop_info); 445 } 446 } 447 return rc; 448 } 449 450 /*=========================================================================== 451 * FUNCTION : getStreamByHandle 452 * 453 * DESCRIPTION: return stream object by stream handle 454 * 455 * PARAMETERS : 456 * @streamHandle : stream handle 457 * 458 * RETURN : stream object. NULL if not found 459 *==========================================================================*/ 460 QCameraStream *QCameraChannel::getStreamByHandle(uint32_t streamHandle) 461 { 462 for (size_t i = 0; i < mStreams.size(); i++) { 463 if (mStreams[i] != NULL && mStreams[i]->getMyHandle() == streamHandle) { 464 return mStreams[i]; 465 } 466 } 467 return NULL; 468 } 469 470 /*=========================================================================== 471 * FUNCTION : getStreamByServerID 472 * 473 * DESCRIPTION: return stream object by stream server ID from daemon 474 * 475 * PARAMETERS : 476 * @serverID : stream server ID 477 * 478 * RETURN : stream object. NULL if not found 479 *==========================================================================*/ 480 QCameraStream *QCameraChannel::getStreamByServerID(uint32_t serverID) 481 { 482 for (size_t i = 0; i < mStreams.size(); i++) { 483 if (mStreams[i] != NULL && mStreams[i]->getMyServerID() == serverID) { 484 return mStreams[i]; 485 } 486 } 487 return NULL; 488 } 489 490 /*=========================================================================== 491 * FUNCTION : getStreamByIndex 492 * 493 * DESCRIPTION: return stream object by index of streams in the channel 494 * 495 * PARAMETERS : 496 * @index : index of stream in the channel 497 * 498 * RETURN : stream object. NULL if not found 499 *==========================================================================*/ 500 QCameraStream *QCameraChannel::getStreamByIndex(uint32_t index) 501 { 502 if (index >= MAX_STREAM_NUM_IN_BUNDLE) { 503 return NULL; 504 } 505 506 if (index < mStreams.size()) { 507 return mStreams[index]; 508 } 509 return NULL; 510 } 511 512 /*=========================================================================== 513 * FUNCTION : UpdateStreamBasedParameters 514 * 515 * DESCRIPTION: update any stream based settings from parameters 516 * 517 * PARAMETERS : 518 * @param : reference to parameters object 519 * 520 * RETURN : int32_t type of status 521 * NO_ERROR -- success 522 * none-zero failure code 523 *==========================================================================*/ 524 int32_t QCameraChannel::UpdateStreamBasedParameters(QCameraParameters ¶m) 525 { 526 int32_t rc = NO_ERROR; 527 if (param.isPreviewFlipChanged()) { 528 // try to find preview stream 529 for (size_t i = 0; i < mStreams.size(); i++) { 530 if ((mStreams[i] != NULL) && 531 (m_handle == mStreams[i]->getChannelHandle()) && 532 (mStreams[i]->isTypeOf(CAM_STREAM_TYPE_PREVIEW) || 533 (mStreams[i]->isOrignalTypeOf(CAM_STREAM_TYPE_PREVIEW))) ) { 534 cam_stream_parm_buffer_t param_buf; 535 memset(¶m_buf, 0, sizeof(cam_stream_parm_buffer_t)); 536 param_buf.type = CAM_STREAM_PARAM_TYPE_SET_FLIP; 537 param_buf.flipInfo.flip_mask = 538 (uint32_t)param.getFlipMode(CAM_STREAM_TYPE_PREVIEW); 539 rc = mStreams[i]->setParameter(param_buf); 540 if (rc != NO_ERROR) { 541 ALOGE("%s: set preview stream flip failed", __func__); 542 } 543 } 544 } 545 } 546 if (param.isVideoFlipChanged()) { 547 // try to find video stream 548 for (size_t i = 0; i < mStreams.size(); i++) { 549 if ((mStreams[i] != NULL) && 550 (m_handle == mStreams[i]->getChannelHandle()) && 551 (mStreams[i]->isTypeOf(CAM_STREAM_TYPE_VIDEO) || 552 (mStreams[i]->isOrignalTypeOf(CAM_STREAM_TYPE_VIDEO))) ) { 553 cam_stream_parm_buffer_t param_buf; 554 memset(¶m_buf, 0, sizeof(cam_stream_parm_buffer_t)); 555 param_buf.type = CAM_STREAM_PARAM_TYPE_SET_FLIP; 556 param_buf.flipInfo.flip_mask = 557 (uint32_t)param.getFlipMode(CAM_STREAM_TYPE_VIDEO); 558 rc = mStreams[i]->setParameter(param_buf); 559 if (rc != NO_ERROR) { 560 ALOGE("%s: set video stream flip failed", __func__); 561 } 562 } 563 } 564 } 565 if (param.isSnapshotFlipChanged()) { 566 // try to find snapshot/postview stream 567 for (size_t i = 0; i < mStreams.size(); i++) { 568 if (mStreams[i] != NULL && 569 (m_handle == mStreams[i]->getChannelHandle()) && 570 (mStreams[i]->isTypeOf(CAM_STREAM_TYPE_SNAPSHOT) || 571 mStreams[i]->isOrignalTypeOf(CAM_STREAM_TYPE_SNAPSHOT) || 572 mStreams[i]->isTypeOf(CAM_STREAM_TYPE_POSTVIEW) || 573 mStreams[i]->isOrignalTypeOf(CAM_STREAM_TYPE_POSTVIEW) ) ) { 574 cam_stream_parm_buffer_t param_buf; 575 memset(¶m_buf, 0, sizeof(cam_stream_parm_buffer_t)); 576 param_buf.type = CAM_STREAM_PARAM_TYPE_SET_FLIP; 577 param_buf.flipInfo.flip_mask = 578 (uint32_t)param.getFlipMode(CAM_STREAM_TYPE_SNAPSHOT); 579 rc = mStreams[i]->setParameter(param_buf); 580 if (rc != NO_ERROR) { 581 ALOGE("%s: set snapshot stream flip failed", __func__); 582 } 583 } 584 } 585 } 586 return rc; 587 } 588 589 /*=========================================================================== 590 * FUNCTION : QCameraPicChannel 591 * 592 * DESCRIPTION: constructor of QCameraPicChannel 593 * 594 * PARAMETERS : 595 * @cam_handle : camera handle 596 * @cam_ops : ptr to camera ops table 597 * 598 * RETURN : none 599 *==========================================================================*/ 600 QCameraPicChannel::QCameraPicChannel(uint32_t cam_handle, 601 mm_camera_ops_t *cam_ops) : 602 QCameraChannel(cam_handle, cam_ops) 603 { 604 m_bAllowDynBufAlloc = true; 605 } 606 607 /*=========================================================================== 608 * FUNCTION : QCameraPicChannel 609 * 610 * DESCRIPTION: default constructor of QCameraPicChannel 611 * 612 * PARAMETERS : none 613 * 614 * RETURN : none 615 *==========================================================================*/ 616 QCameraPicChannel::QCameraPicChannel() 617 { 618 m_bAllowDynBufAlloc = true; 619 } 620 621 /*=========================================================================== 622 * FUNCTION : ~QCameraPicChannel 623 * 624 * DESCRIPTION: destructor of QCameraPicChannel 625 * 626 * PARAMETERS : none 627 * 628 * RETURN : none 629 *==========================================================================*/ 630 QCameraPicChannel::~QCameraPicChannel() 631 { 632 } 633 634 /*=========================================================================== 635 * FUNCTION : takePicture 636 * 637 * DESCRIPTION: send request for queued snapshot frames 638 * 639 * PARAMETERS : 640 * @num_of_snapshot : number of snapshot frames requested 641 * @num_of_retro_snapshot : number of retro snapshot frames requested 642 * 643 * RETURN : int32_t type of status 644 * NO_ERROR -- success 645 * none-zero failure code 646 *==========================================================================*/ 647 int32_t QCameraPicChannel::takePicture ( 648 uint8_t num_of_snapshot, 649 uint8_t num_of_retro_snapshot) 650 { 651 int32_t rc = m_camOps->request_super_buf(m_camHandle, 652 m_handle, 653 num_of_snapshot, 654 num_of_retro_snapshot); 655 return rc; 656 } 657 658 /*=========================================================================== 659 * FUNCTION : cancelPicture 660 * 661 * DESCRIPTION: cancel request for queued snapshot frames 662 * 663 * PARAMETERS : none 664 * 665 * RETURN : int32_t type of status 666 * NO_ERROR -- success 667 * none-zero failure code 668 *==========================================================================*/ 669 int32_t QCameraPicChannel::cancelPicture() 670 { 671 int32_t rc = m_camOps->cancel_super_buf_request(m_camHandle, m_handle); 672 return rc; 673 } 674 675 /*=========================================================================== 676 * FUNCTION : stopAdvancedCapture 677 * 678 * DESCRIPTION: stop advanced capture based on advanced capture type. 679 * 680 * PARAMETERS : 681 * @type : advanced capture type. 682 * 683 * RETURN : int32_t type of status 684 * NO_ERROR -- success 685 * none-zero failure code 686 *==========================================================================*/ 687 int32_t QCameraPicChannel::stopAdvancedCapture(mm_camera_advanced_capture_t type) 688 { 689 int32_t rc = m_camOps->process_advanced_capture(m_camHandle, 690 m_handle, type, 0, NULL); 691 return rc; 692 } 693 694 /*=========================================================================== 695 * FUNCTION : startAdvancedCapture 696 * 697 * DESCRIPTION: start advanced capture based on advanced capture type. 698 * 699 * PARAMETERS : 700 * @type : advanced capture type. 701 * @config: advance capture config 702 * 703 * RETURN : int32_t type of status 704 * NO_ERROR -- success 705 * none-zero failure code 706 *==========================================================================*/ 707 int32_t QCameraPicChannel::startAdvancedCapture(mm_camera_advanced_capture_t type, 708 cam_capture_frame_config_t *config) 709 { 710 int32_t rc = NO_ERROR; 711 712 rc = m_camOps->process_advanced_capture(m_camHandle, m_handle, type, 713 1, config); 714 return rc; 715 } 716 717 /*=========================================================================== 718 * FUNCTION : flushSuperbuffer 719 * 720 * DESCRIPTION: flush the all superbuffer frames. 721 * 722 * PARAMETERS : 723 * @frame_idx : frame index of focused frame 724 * 725 * RETURN : int32_t type of status 726 * NO_ERROR -- success 727 * none-zero failure code 728 *==========================================================================*/ 729 int32_t QCameraPicChannel::flushSuperbuffer(uint32_t frame_idx) 730 { 731 int32_t rc = m_camOps->flush_super_buf_queue(m_camHandle, m_handle, frame_idx); 732 return rc; 733 } 734 735 /*=========================================================================== 736 * FUNCTION : QCameraVideoChannel 737 * 738 * DESCRIPTION: constructor of QCameraVideoChannel 739 * 740 * PARAMETERS : 741 * @cam_handle : camera handle 742 * @cam_ops : ptr to camera ops table 743 * 744 * RETURN : none 745 *==========================================================================*/ 746 QCameraVideoChannel::QCameraVideoChannel(uint32_t cam_handle, 747 mm_camera_ops_t *cam_ops) : 748 QCameraChannel(cam_handle, cam_ops) 749 { 750 } 751 752 /*=========================================================================== 753 * FUNCTION : QCameraVideoChannel 754 * 755 * DESCRIPTION: default constructor of QCameraVideoChannel 756 * 757 * PARAMETERS : none 758 * 759 * RETURN : none 760 *==========================================================================*/ 761 QCameraVideoChannel::QCameraVideoChannel() 762 { 763 } 764 765 /*=========================================================================== 766 * FUNCTION : ~QCameraVideoChannel 767 * 768 * DESCRIPTION: destructor of QCameraVideoChannel 769 * 770 * PARAMETERS : none 771 * 772 * RETURN : none 773 *==========================================================================*/ 774 QCameraVideoChannel::~QCameraVideoChannel() 775 { 776 } 777 778 /*=========================================================================== 779 * FUNCTION : releaseFrame 780 * 781 * DESCRIPTION: return video frame from app 782 * 783 * PARAMETERS : 784 * @opaque : ptr to video frame to be returned 785 * @isMetaData : if frame is a metadata or real frame 786 * 787 * RETURN : int32_t type of status 788 * NO_ERROR -- success 789 * none-zero failure code 790 *==========================================================================*/ 791 int32_t QCameraVideoChannel::releaseFrame(const void * opaque, bool isMetaData) 792 { 793 QCameraStream *pVideoStream = NULL; 794 for (size_t i = 0; i < mStreams.size(); i++) { 795 if (mStreams[i] != NULL && mStreams[i]->isTypeOf(CAM_STREAM_TYPE_VIDEO)) { 796 pVideoStream = mStreams[i]; 797 break; 798 } 799 } 800 801 if (NULL == pVideoStream) { 802 ALOGE("%s: No video stream in the channel", __func__); 803 return BAD_VALUE; 804 } 805 806 int32_t rc = pVideoStream->bufDone(opaque, isMetaData); 807 return rc; 808 } 809 810 /*=========================================================================== 811 * FUNCTION : QCameraReprocessChannel 812 * 813 * DESCRIPTION: constructor of QCameraReprocessChannel 814 * 815 * PARAMETERS : 816 * @cam_handle : camera handle 817 * @cam_ops : ptr to camera ops table 818 * @pp_mask : post-proccess feature mask 819 * 820 * RETURN : none 821 *==========================================================================*/ 822 QCameraReprocessChannel::QCameraReprocessChannel(uint32_t cam_handle, 823 mm_camera_ops_t *cam_ops) : 824 QCameraChannel(cam_handle, cam_ops), 825 m_pSrcChannel(NULL) 826 { 827 memset(mSrcStreamHandles, 0, sizeof(mSrcStreamHandles)); 828 } 829 830 /*=========================================================================== 831 * FUNCTION : QCameraReprocessChannel 832 * 833 * DESCRIPTION: default constructor of QCameraReprocessChannel 834 * 835 * PARAMETERS : none 836 * 837 * RETURN : none 838 *==========================================================================*/ 839 QCameraReprocessChannel::QCameraReprocessChannel() : 840 m_pSrcChannel(NULL) 841 { 842 } 843 844 /*=========================================================================== 845 * FUNCTION : ~QCameraReprocessChannel 846 * 847 * DESCRIPTION: destructor of QCameraReprocessChannel 848 * 849 * PARAMETERS : none 850 * 851 * RETURN : none 852 *==========================================================================*/ 853 QCameraReprocessChannel::~QCameraReprocessChannel() 854 { 855 } 856 857 /*=========================================================================== 858 * FUNCTION : addReprocStreamsFromSource 859 * 860 * DESCRIPTION: add reprocess streams from input source channel 861 * 862 * PARAMETERS : 863 * @allocator : stream related buffer allocator 864 * @featureConfig : pp feature configuration 865 * @pSrcChannel : ptr to input source channel that needs reprocess 866 * @minStreamBufNum: number of stream buffers needed 867 * @burstNum : number of burst captures needed 868 * @paddingInfo : padding information 869 * @param : reference to parameters 870 * @contStream : continous streaming mode or burst 871 * @offline : configure for offline reprocessing 872 * 873 * RETURN : int32_t type of status 874 * NO_ERROR -- success 875 * none-zero failure code 876 *==========================================================================*/ 877 int32_t QCameraReprocessChannel::addReprocStreamsFromSource( 878 QCameraAllocator& allocator, cam_pp_feature_config_t &featureConfig, 879 QCameraChannel *pSrcChannel, uint8_t minStreamBufNum, uint8_t burstNum, 880 cam_padding_info_t *paddingInfo, QCameraParameters ¶m, bool contStream, 881 bool offline) 882 { 883 int32_t rc = 0; 884 QCameraStream *pStream = NULL; 885 QCameraHeapMemory *pStreamInfoBuf = NULL; 886 QCameraHeapMemory *pMiscBuf = NULL; 887 cam_stream_info_t *streamInfo = NULL; 888 cam_padding_info_t padding; 889 890 memset(mSrcStreamHandles, 0, sizeof(mSrcStreamHandles)); 891 if (NULL == paddingInfo) { 892 return BAD_VALUE; 893 } 894 padding = *paddingInfo; 895 //Use maximum padding so that the buffer 896 //can be rotated 897 padding.width_padding = MAX(padding.width_padding, padding.height_padding); 898 padding.height_padding = padding.width_padding; 899 900 CDBG("%s : %d: num of src stream = %d", __func__, __LINE__, pSrcChannel->getNumOfStreams()); 901 902 for (uint32_t i = 0; i < pSrcChannel->getNumOfStreams(); i++) { 903 pStream = pSrcChannel->getStreamByIndex(i); 904 if (pStream != NULL) { 905 if (param.getofflineRAW() && !pStream->isTypeOf(CAM_STREAM_TYPE_RAW)) { 906 //Skip all the stream other than RAW incase of offline of RAW 907 continue; 908 } 909 if (pStream->isTypeOf(CAM_STREAM_TYPE_RAW) && !param.getofflineRAW()) { 910 // Skip raw for reprocess now because PP module cannot handle 911 // meta data&raw. May need furthur discussion if Imaginglib need meta data 912 continue; 913 } 914 915 if ((pStream->isTypeOf(CAM_STREAM_TYPE_METADATA)) || 916 (pStream->isTypeOf(CAM_STREAM_TYPE_ANALYSIS))) { 917 // Skip metadata 918 continue; 919 } 920 921 if (pStream->isTypeOf(CAM_STREAM_TYPE_POSTVIEW) || 922 pStream->isTypeOf(CAM_STREAM_TYPE_PREVIEW)) { 923 // Skip postview: in non zsl case, dont want to send 924 // thumbnail through reprocess. 925 // Skip preview: for same reason for zsl case 926 continue; 927 } 928 929 if (pStream->isTypeOf(CAM_STREAM_TYPE_PREVIEW) || 930 pStream->isTypeOf(CAM_STREAM_TYPE_POSTVIEW) || 931 pStream->isOrignalTypeOf(CAM_STREAM_TYPE_PREVIEW) || 932 pStream->isOrignalTypeOf(CAM_STREAM_TYPE_POSTVIEW) || 933 (param.getofflineRAW() && pStream->isTypeOf(CAM_STREAM_TYPE_RAW))) { 934 uint32_t feature_mask = featureConfig.feature_mask; 935 936 if ((feature_mask & ~CAM_QCOM_FEATURE_HDR) == 0 937 && param.isHDREnabled() 938 && !param.isHDRThumbnailProcessNeeded()) { 939 940 // Skip thumbnail stream reprocessing in HDR 941 // if only hdr is enabled 942 continue; 943 } 944 945 // skip thumbnail reprocessing if not needed 946 if (!param.needThumbnailReprocess(&feature_mask)) { 947 continue; 948 } 949 950 //Don't do WNR for thumbnail 951 feature_mask &= ~CAM_QCOM_FEATURE_DENOISE2D; 952 if (!feature_mask) { 953 // Skip thumbnail stream reprocessing since no other 954 //reprocessing is enabled. 955 continue; 956 } 957 } 958 959 pStreamInfoBuf = allocator.allocateStreamInfoBuf(CAM_STREAM_TYPE_OFFLINE_PROC); 960 if (pStreamInfoBuf == NULL) { 961 ALOGE("%s: no mem for stream info buf", __func__); 962 rc = NO_MEMORY; 963 break; 964 } 965 966 streamInfo = (cam_stream_info_t *)pStreamInfoBuf->getPtr(0); 967 memset(streamInfo, 0, sizeof(cam_stream_info_t)); 968 streamInfo->stream_type = CAM_STREAM_TYPE_OFFLINE_PROC; 969 // Enable CPP high performance mode to put it in turbo frequency mode for 970 // burst/longshot/HDR snapshot cases 971 streamInfo->perf_mode = CAM_PERF_HIGH_PERFORMANCE; 972 if (param.getofflineRAW() && pStream->isTypeOf(CAM_STREAM_TYPE_RAW)) { 973 streamInfo->fmt = CAM_FORMAT_YUV_420_NV21; 974 } else { 975 rc = pStream->getFormat(streamInfo->fmt); 976 } 977 rc = pStream->getFrameDimension(streamInfo->dim); 978 if ( contStream ) { 979 streamInfo->streaming_mode = CAM_STREAMING_MODE_CONTINUOUS; 980 streamInfo->num_of_burst = 0; 981 } else { 982 streamInfo->streaming_mode = CAM_STREAMING_MODE_BURST; 983 streamInfo->num_of_burst = burstNum; 984 } 985 986 cam_stream_reproc_config_t rp_cfg; 987 memset(&rp_cfg, 0, sizeof(cam_stream_reproc_config_t)); 988 if (offline) { 989 cam_frame_len_offset_t offset; 990 memset(&offset, 0, sizeof(cam_frame_len_offset_t)); 991 992 rp_cfg.pp_type = CAM_OFFLINE_REPROCESS_TYPE; 993 pStream->getFormat(rp_cfg.offline.input_fmt); 994 pStream->getFrameDimension(rp_cfg.offline.input_dim); 995 pStream->getFrameOffset(offset); 996 rp_cfg.offline.input_buf_planes.plane_info = offset; 997 rp_cfg.offline.input_type = pStream->getMyOriginalType(); 998 //For input metadata + input buffer 999 rp_cfg.offline.num_of_bufs = 2; 1000 } else { 1001 rp_cfg.pp_type = CAM_ONLINE_REPROCESS_TYPE; 1002 rp_cfg.online.input_stream_id = pStream->getMyServerID(); 1003 rp_cfg.online.input_stream_type = pStream->getMyOriginalType(); 1004 } 1005 param.getStreamRotation(streamInfo->stream_type, 1006 streamInfo->pp_config, streamInfo->dim); 1007 streamInfo->reprocess_config = rp_cfg; 1008 streamInfo->reprocess_config.pp_feature_config = featureConfig; 1009 1010 if (!(pStream->isTypeOf(CAM_STREAM_TYPE_SNAPSHOT) || 1011 pStream->isOrignalTypeOf(CAM_STREAM_TYPE_SNAPSHOT))) { 1012 streamInfo->reprocess_config.pp_feature_config.feature_mask &= ~CAM_QCOM_FEATURE_CAC; 1013 //Don't do WNR for thumbnail 1014 streamInfo->reprocess_config.pp_feature_config.feature_mask &= ~CAM_QCOM_FEATURE_DENOISE2D; 1015 1016 if (param.isHDREnabled() 1017 && !param.isHDRThumbnailProcessNeeded()){ 1018 streamInfo->reprocess_config.pp_feature_config.feature_mask 1019 &= ~CAM_QCOM_FEATURE_HDR; 1020 } 1021 } 1022 1023 1024 if (streamInfo->reprocess_config.online.input_stream_type == CAM_STREAM_TYPE_SNAPSHOT) { 1025 // Reprocess can be for both zsl and non-zsl cases 1026 int flipMode = 1027 param.getFlipMode(streamInfo->reprocess_config.online.input_stream_type); 1028 if (flipMode > 0) { 1029 streamInfo->reprocess_config.pp_feature_config.feature_mask |= 1030 CAM_QCOM_FEATURE_FLIP; 1031 streamInfo->reprocess_config.pp_feature_config.flip = (uint32_t)flipMode; 1032 } 1033 } 1034 1035 if (streamInfo->reprocess_config.offline.input_type == CAM_STREAM_TYPE_SNAPSHOT) { 1036 int flipMode = 1037 param.getFlipMode(streamInfo->reprocess_config.offline.input_type); 1038 if (flipMode > 0) { 1039 streamInfo->reprocess_config.pp_feature_config.feature_mask |= 1040 CAM_QCOM_FEATURE_FLIP; 1041 streamInfo->reprocess_config.pp_feature_config.flip = (uint32_t)flipMode; 1042 } 1043 } 1044 1045 if ((streamInfo->reprocess_config.pp_feature_config.feature_mask 1046 & CAM_QCOM_FEATURE_SCALE) 1047 && param.m_reprocScaleParam.isScaleEnabled() 1048 && param.m_reprocScaleParam.isUnderScaling()) { 1049 //we only Scale Snapshot frame 1050 if (pStream->isTypeOf(CAM_STREAM_TYPE_SNAPSHOT)) { 1051 streamInfo->dim.width = 1052 streamInfo->reprocess_config.pp_feature_config.scale_param.output_width; 1053 streamInfo->dim.height = 1054 streamInfo->reprocess_config.pp_feature_config.scale_param.output_height; 1055 } 1056 CDBG_HIGH("%s: stream width=%d, height=%d.", 1057 __func__, streamInfo->dim.width, streamInfo->dim.height); 1058 } 1059 1060 // save source stream handler 1061 mSrcStreamHandles[mStreams.size()] = pStream->getMyHandle(); 1062 1063 pMiscBuf = allocator.allocateMiscBuf(streamInfo); 1064 1065 // add reprocess stream 1066 rc = addStream(allocator, pStreamInfoBuf, pMiscBuf, 1067 minStreamBufNum, &padding, NULL, NULL, false, false, 1068 streamInfo->reprocess_config.pp_feature_config.rotation); 1069 if (rc != NO_ERROR) { 1070 ALOGE("%s: add reprocess stream failed, ret = %d", __func__, rc); 1071 break; 1072 } 1073 } 1074 } 1075 1076 if (rc == NO_ERROR) { 1077 m_pSrcChannel = pSrcChannel; 1078 } 1079 return rc; 1080 } 1081 1082 /*=========================================================================== 1083 * FUNCTION : getStreamBySrouceHandle 1084 * 1085 * DESCRIPTION: find reprocess stream by its source stream handle 1086 * 1087 * PARAMETERS : 1088 * @srcHandle : source stream handle 1089 * 1090 * RETURN : ptr to reprocess stream if found. NULL if not found 1091 *==========================================================================*/ 1092 QCameraStream * QCameraReprocessChannel::getStreamBySrouceHandle(uint32_t srcHandle) 1093 { 1094 QCameraStream *pStream = NULL; 1095 1096 for (size_t i = 0; i < mStreams.size(); i++) { 1097 if (mSrcStreamHandles[i] == srcHandle) { 1098 pStream = mStreams[i]; 1099 break; 1100 } 1101 } 1102 1103 return pStream; 1104 } 1105 1106 /*=========================================================================== 1107 * FUNCTION : stop 1108 * 1109 * DESCRIPTION: Unmap offline buffers and stop channel 1110 * 1111 * PARAMETERS : none 1112 * 1113 * RETURN : int32_t type of status 1114 * NO_ERROR -- success 1115 * none-zero failure code 1116 *==========================================================================*/ 1117 int32_t QCameraReprocessChannel::stop() 1118 { 1119 if (!mOfflineBuffers.empty()) { 1120 QCameraStream *stream = NULL; 1121 List<OfflineBuffer>::iterator it = mOfflineBuffers.begin(); 1122 int error = NO_ERROR; 1123 for( ; it != mOfflineBuffers.end(); it++) { 1124 stream = (*it).stream; 1125 if (NULL != stream) { 1126 error = stream->unmapBuf((*it).type, 1127 (*it).index, 1128 -1); 1129 if (NO_ERROR != error) { 1130 ALOGE("%s: Error during offline buffer unmap %d", 1131 __func__, error); 1132 } 1133 } 1134 } 1135 mOfflineBuffers.clear(); 1136 } 1137 1138 return QCameraChannel::stop(); 1139 } 1140 1141 /*=========================================================================== 1142 * FUNCTION : doReprocessOffline 1143 * 1144 * DESCRIPTION: request to do offline reprocess on the frame 1145 * 1146 * PARAMETERS : 1147 * @frame : frame to be performed a reprocess 1148 * @meta_buf : Metadata buffer for reprocessing 1149 * 1150 * RETURN : int32_t type of status 1151 * NO_ERROR -- success 1152 * none-zero failure code 1153 *==========================================================================*/ 1154 int32_t QCameraReprocessChannel::doReprocessOffline(mm_camera_super_buf_t *frame, 1155 mm_camera_buf_def_t *meta_buf) 1156 { 1157 int32_t rc = 0; 1158 OfflineBuffer mappedBuffer; 1159 QCameraStream *pStream = NULL; 1160 1161 if (mStreams.size() < 1) { 1162 ALOGE("%s: No reprocess streams", __func__); 1163 return -1; 1164 } 1165 if (m_pSrcChannel == NULL) { 1166 ALOGE("%s: No source channel for reprocess", __func__); 1167 return -1; 1168 } 1169 1170 if (frame == NULL) { 1171 ALOGE("%s: Invalid source frame", __func__); 1172 return BAD_VALUE; 1173 } 1174 1175 for (uint32_t i = 0; i < frame->num_bufs; i++) { 1176 pStream = getStreamBySrouceHandle(frame->bufs[i]->stream_id); 1177 if ((pStream != NULL) && 1178 (m_handle == pStream->getChannelHandle())) { 1179 if (pStream->isTypeOf(CAM_STREAM_TYPE_METADATA)) { 1180 continue; 1181 } 1182 1183 uint32_t meta_buf_index = 0; 1184 if (NULL != meta_buf) { 1185 rc = pStream->mapBuf(CAM_MAPPING_BUF_TYPE_OFFLINE_META_BUF, 1186 meta_buf_index, 1187 -1, 1188 meta_buf->fd, 1189 meta_buf->frame_len); 1190 if (NO_ERROR != rc ) { 1191 ALOGE("%s : Error during metadata buffer mapping", 1192 __func__); 1193 break; 1194 } 1195 // we have meta data sent together with reprocess frame 1196 uint32_t stream_id = frame->bufs[i]->stream_id; 1197 QCameraStream *srcStream = 1198 m_pSrcChannel->getStreamByHandle(stream_id); 1199 metadata_buffer_t *pMetaData = 1200 (metadata_buffer_t *)meta_buf->buffer; 1201 if ((NULL != pMetaData) && (NULL != srcStream)) { 1202 IF_META_AVAILABLE(cam_crop_data_t, crop, CAM_INTF_META_CROP_DATA, pMetaData) { 1203 if (MAX_NUM_STREAMS > crop->num_of_streams) { 1204 for (int j = 0; j < MAX_NUM_STREAMS; j++) { 1205 if (crop->crop_info[j].stream_id == 1206 srcStream->getMyServerID()) { 1207 // Store crop/roi information for offline reprocess 1208 // in the reprocess stream slot 1209 crop->crop_info[crop->num_of_streams].crop = 1210 crop->crop_info[j].crop; 1211 crop->crop_info[crop->num_of_streams].roi_map = 1212 crop->crop_info[j].roi_map; 1213 crop->crop_info[crop->num_of_streams].stream_id = 1214 mStreams[0]->getMyServerID(); 1215 crop->num_of_streams++; 1216 1217 break; 1218 } 1219 } 1220 } else { 1221 ALOGE("%s: No space to add reprocess stream crop/roi information", 1222 __func__); 1223 } 1224 } 1225 } 1226 } 1227 mappedBuffer.index = meta_buf_index; 1228 mappedBuffer.stream = pStream; 1229 mappedBuffer.type = CAM_MAPPING_BUF_TYPE_OFFLINE_META_BUF; 1230 mOfflineBuffers.push_back(mappedBuffer); 1231 1232 uint32_t buf_index = 1; 1233 rc = pStream->mapBuf(CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF, 1234 buf_index, 1235 -1, 1236 frame->bufs[i]->fd, 1237 frame->bufs[i]->frame_len); 1238 if (NO_ERROR != rc ) { 1239 ALOGE("%s : Error during reprocess input buffer mapping", 1240 __func__); 1241 break; 1242 } 1243 mappedBuffer.index = buf_index; 1244 mappedBuffer.stream = pStream; 1245 mappedBuffer.type = CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF; 1246 mOfflineBuffers.push_back(mappedBuffer); 1247 1248 cam_stream_parm_buffer_t param; 1249 memset(¶m, 0, sizeof(cam_stream_parm_buffer_t)); 1250 1251 param.type = CAM_STREAM_PARAM_TYPE_DO_REPROCESS; 1252 param.reprocess.buf_index = buf_index; 1253 param.reprocess.frame_idx = frame->bufs[i]->frame_idx; 1254 param.reprocess.meta_present = 1; 1255 param.reprocess.meta_buf_index = meta_buf_index; 1256 1257 rc = pStream->setParameter(param); 1258 if (rc != NO_ERROR) { 1259 ALOGE("%s: stream setParameter for reprocess failed", 1260 __func__); 1261 break; 1262 } 1263 } 1264 } 1265 return rc; 1266 } 1267 1268 /*=========================================================================== 1269 * FUNCTION : doReprocess 1270 * 1271 * DESCRIPTION: request to do a reprocess on the frame 1272 * 1273 * PARAMETERS : 1274 * @frame : frame to be performed a reprocess 1275 * @mParameter : camera parameters 1276 * @pMetaStream: Metadata stream handle 1277 * @meta_buf_index : Metadata buffer index 1278 * 1279 * RETURN : int32_t type of status 1280 * NO_ERROR -- success 1281 * none-zero failure code 1282 *==========================================================================*/ 1283 int32_t QCameraReprocessChannel::doReprocess(mm_camera_super_buf_t *frame, 1284 QCameraParameters &mParameter, QCameraStream *pMetaStream, 1285 uint8_t meta_buf_index) 1286 { 1287 int32_t rc = 0; 1288 if (mStreams.size() < 1) { 1289 ALOGE("%s: No reprocess streams", __func__); 1290 return -1; 1291 } 1292 if (m_pSrcChannel == NULL) { 1293 ALOGE("%s: No source channel for reprocess", __func__); 1294 return -1; 1295 } 1296 1297 for (uint32_t i = 0; i < frame->num_bufs; i++) { 1298 QCameraStream *pStream = getStreamBySrouceHandle(frame->bufs[i]->stream_id); 1299 if ((pStream != NULL) && (m_handle == pStream->getChannelHandle())) { 1300 if (mParameter.getofflineRAW() && 1301 !pStream->isOrignalTypeOf(CAM_STREAM_TYPE_RAW)) { 1302 continue; 1303 } 1304 if ((pStream->isTypeOf(CAM_STREAM_TYPE_METADATA)) || 1305 (pStream->isTypeOf(CAM_STREAM_TYPE_ANALYSIS))) { 1306 // Skip metadata for reprocess now because PP module cannot handle meta data 1307 // May need furthur discussion if Imaginglib need meta data 1308 continue; 1309 } 1310 1311 if (pStream->isTypeOf(CAM_STREAM_TYPE_POSTVIEW) || 1312 pStream->isTypeOf(CAM_STREAM_TYPE_PREVIEW)) { 1313 // Skip postview: In non zsl case, dont want to send 1314 // thumbnail through reprocess. 1315 // Skip preview: for same reason in ZSL case 1316 continue; 1317 } 1318 1319 cam_stream_parm_buffer_t param; 1320 memset(¶m, 0, sizeof(cam_stream_parm_buffer_t)); 1321 param.type = CAM_STREAM_PARAM_TYPE_DO_REPROCESS; 1322 param.reprocess.buf_index = frame->bufs[i]->buf_idx; 1323 param.reprocess.frame_idx = frame->bufs[i]->frame_idx; 1324 if (pMetaStream != NULL) { 1325 // we have meta data frame bundled, sent together with reprocess frame 1326 param.reprocess.meta_present = 1; 1327 param.reprocess.meta_stream_handle = pMetaStream->getMyServerID(); 1328 param.reprocess.meta_buf_index = meta_buf_index; 1329 } 1330 1331 CDBG_HIGH("Frame for reprocessing id = %d buf Id = %d meta index = %d", 1332 param.reprocess.frame_idx, param.reprocess.buf_index, 1333 param.reprocess.meta_buf_index); 1334 1335 rc = pStream->setParameter(param); 1336 if (rc != NO_ERROR) { 1337 ALOGE("%s: stream setParameter for reprocess failed", __func__); 1338 break; 1339 } 1340 } 1341 } 1342 return rc; 1343 } 1344 1345 /*=========================================================================== 1346 * FUNCTION : doReprocess 1347 * 1348 * DESCRIPTION: request to do a reprocess on the frame 1349 * 1350 * PARAMETERS : 1351 * @buf_fd : fd to the input buffer that needs reprocess 1352 * @buf_lenght : length of the input buffer 1353 * @ret_val : result of reprocess. 1354 * Example: Could be faceID in case of register face image. 1355 * 1356 * RETURN : int32_t type of status 1357 * NO_ERROR -- success 1358 * none-zero failure code 1359 *==========================================================================*/ 1360 int32_t QCameraReprocessChannel::doReprocess(int buf_fd, 1361 size_t buf_length, int32_t &ret_val) 1362 { 1363 int32_t rc = 0; 1364 if (mStreams.size() < 1) { 1365 ALOGE("%s: No reprocess streams", __func__); 1366 return -1; 1367 } 1368 1369 uint32_t buf_idx = 0; 1370 for (size_t i = 0; i < mStreams.size(); i++) { 1371 if ((mStreams[i] != NULL) && 1372 (m_handle != mStreams[i]->getChannelHandle())) { 1373 continue; 1374 } 1375 rc = mStreams[i]->mapBuf(CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF, 1376 buf_idx, -1, 1377 buf_fd, buf_length); 1378 1379 if (rc == NO_ERROR) { 1380 cam_stream_parm_buffer_t param; 1381 memset(¶m, 0, sizeof(cam_stream_parm_buffer_t)); 1382 param.type = CAM_STREAM_PARAM_TYPE_DO_REPROCESS; 1383 param.reprocess.buf_index = buf_idx; 1384 rc = mStreams[i]->setParameter(param); 1385 if (rc == NO_ERROR) { 1386 ret_val = param.reprocess.ret_val; 1387 } 1388 mStreams[i]->unmapBuf(CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF, 1389 buf_idx, -1); 1390 } 1391 } 1392 return rc; 1393 } 1394 1395 }; // namespace qcamera 1396