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