1 /* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved. 2 * 3 * Redistribution and use in source and binary forms, with or without 4 * modification, are permitted provided that the following conditions are 5 * met: 6 * * Redistributions of source code must retain the above copyright 7 * notice, this list of conditions and the following disclaimer. 8 * * Redistributions in binary form must reproduce the above 9 * copyright notice, this list of conditions and the following 10 * disclaimer in the documentation and/or other materials provided 11 * with the distribution. 12 * * Neither the name of The Linux Foundation nor the names of its 13 * contributors may be used to endorse or promote products derived 14 * from this software without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED 17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS 20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 23 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 24 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 25 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 26 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 * 28 */ 29 30 #define LOG_TAG "QCameraChannel" 31 32 // System dependencies 33 #include <utils/Errors.h> 34 35 // Camera dependencies 36 #include "QCamera2HWI.h" 37 38 extern "C" { 39 #include "mm_camera_dbg.h" 40 } 41 42 using namespace android; 43 44 namespace qcamera { 45 46 /*=========================================================================== 47 * FUNCTION : QCameraChannel 48 * 49 * DESCRIPTION: constrcutor of QCameraChannel 50 * 51 * PARAMETERS : 52 * @cam_handle : camera handle 53 * @cam_ops : ptr to camera ops table 54 * 55 * RETURN : none 56 *==========================================================================*/ 57 QCameraChannel::QCameraChannel(uint32_t cam_handle, 58 mm_camera_ops_t *cam_ops) 59 { 60 m_camHandle = cam_handle; 61 m_camOps = cam_ops; 62 m_bIsActive = false; 63 m_bAllowDynBufAlloc = false; 64 65 m_handle = 0; 66 } 67 68 /*=========================================================================== 69 * FUNCTION : QCameraChannel 70 * 71 * DESCRIPTION: default constrcutor of QCameraChannel 72 * 73 * PARAMETERS : none 74 * 75 * RETURN : none 76 *==========================================================================*/ 77 QCameraChannel::QCameraChannel() 78 { 79 m_camHandle = 0; 80 m_camOps = NULL; 81 m_bIsActive = false; 82 83 m_handle = 0; 84 } 85 86 /*=========================================================================== 87 * FUNCTION : ~QCameraChannel 88 * 89 * DESCRIPTION: destructor of QCameraChannel 90 * 91 * PARAMETERS : none 92 * 93 * RETURN : none 94 *==========================================================================*/ 95 QCameraChannel::~QCameraChannel() 96 { 97 if (m_bIsActive) { 98 stop(); 99 } 100 for (size_t i = 0; i < mStreams.size(); i++) { 101 if (mStreams[i] != NULL) { 102 if (m_handle == mStreams[i]->getChannelHandle()) { 103 delete mStreams[i]; 104 } 105 } 106 } 107 mStreams.clear(); 108 m_camOps->delete_channel(m_camHandle, m_handle); 109 m_handle = 0; 110 } 111 112 /*=========================================================================== 113 * FUNCTION : deleteChannel 114 * 115 * DESCRIPTION: deletes a camera channel 116 * 117 * PARAMETERS : none 118 * 119 * RETURN : none 120 *==========================================================================*/ 121 void QCameraChannel::deleteChannel() 122 { 123 if (m_bIsActive) { 124 stop(); 125 } 126 for (size_t i = 0; i < mStreams.size(); i++) { 127 if ((mStreams[i] != NULL) && (m_handle == mStreams[i]->getChannelHandle())) { 128 mStreams[i]->deleteStream(); 129 } 130 } 131 m_camOps->delete_channel(m_camHandle, m_handle); 132 } 133 134 /*=========================================================================== 135 * FUNCTION : setStreamSyncCB 136 * 137 * DESCRIPTION: reg callback function to stream of stream type 138 * 139 * PARAMETERS : 140 * @stream_type : Stream type for which callback needs to be registered. 141 * @stream_cb : Callback function 142 143 * RETURN : int32_t type of status 144 * NO_ERROR -- success 145 * non-zero failure code 146 *==========================================================================*/ 147 int32_t QCameraChannel::setStreamSyncCB (cam_stream_type_t stream_type, 148 stream_cb_routine stream_cb) 149 { 150 int32_t rc = UNKNOWN_ERROR; 151 for (size_t i = 0; i < mStreams.size(); i++) { 152 if ((mStreams[i] != NULL) && (stream_type == mStreams[i]->getMyType())) { 153 rc = mStreams[i]->setSyncDataCB(stream_cb); 154 break; 155 } 156 } 157 return rc; 158 } 159 160 /*=========================================================================== 161 * FUNCTION : init 162 * 163 * DESCRIPTION: initialization of channel 164 * 165 * PARAMETERS : 166 * @attr : channel bundle attribute setting 167 * @dataCB : data notify callback 168 * @userData: user data ptr 169 * 170 * RETURN : int32_t type of status 171 * NO_ERROR -- success 172 * none-zero failure code 173 *==========================================================================*/ 174 int32_t QCameraChannel::init(mm_camera_channel_attr_t *attr, 175 mm_camera_buf_notify_t dataCB, 176 void *userData) 177 { 178 m_handle = m_camOps->add_channel(m_camHandle, 179 attr, 180 dataCB, 181 userData); 182 if (m_handle == 0) { 183 LOGE("Add channel failed"); 184 return UNKNOWN_ERROR; 185 } 186 return NO_ERROR; 187 } 188 189 /*=========================================================================== 190 * FUNCTION : addStream 191 * 192 * DESCRIPTION: add a stream into channel 193 * 194 * PARAMETERS : 195 * @allocator : stream related buffer allocator 196 * @streamInfoBuf : ptr to buf that contains stream info 197 * @miscBuf : ptr to buf that contains misc buffers 198 * @minStreamBufNum: number of stream buffers needed 199 * @paddingInfo : padding information 200 * @stream_cb : stream data notify callback 201 * @userdata : user data ptr 202 * @bDynAllocBuf : flag indicating if allow allocate buffers in 2 steps 203 * @online_rotation: rotation applied online 204 * 205 * RETURN : int32_t type of status 206 * NO_ERROR -- success 207 * none-zero failure code 208 *==========================================================================*/ 209 int32_t QCameraChannel::addStream(QCameraAllocator &allocator, 210 QCameraHeapMemory *streamInfoBuf, QCameraHeapMemory *miscBuf, 211 uint8_t minStreamBufNum, cam_padding_info_t *paddingInfo, 212 stream_cb_routine stream_cb, void *userdata, bool bDynAllocBuf, 213 bool bDeffAlloc, cam_rotation_t online_rotation) 214 { 215 int32_t rc = NO_ERROR; 216 if (mStreams.size() >= MAX_STREAM_NUM_IN_BUNDLE) { 217 LOGE("stream number (%zu) exceeds max limit (%d)", 218 mStreams.size(), MAX_STREAM_NUM_IN_BUNDLE); 219 if (streamInfoBuf != NULL) { 220 streamInfoBuf->deallocate(); 221 delete streamInfoBuf; 222 streamInfoBuf = NULL; 223 } 224 return BAD_VALUE; 225 } 226 QCameraStream *pStream = new QCameraStream(allocator, 227 m_camHandle, m_handle, m_camOps, paddingInfo, bDeffAlloc, 228 online_rotation); 229 if (pStream == NULL) { 230 LOGE("No mem for Stream"); 231 if (streamInfoBuf != NULL) { 232 streamInfoBuf->deallocate(); 233 delete streamInfoBuf; 234 streamInfoBuf = NULL; 235 } 236 return NO_MEMORY; 237 } 238 239 rc = pStream->init(streamInfoBuf, miscBuf, minStreamBufNum, 240 stream_cb, userdata, bDynAllocBuf); 241 if (rc == 0) { 242 mStreams.add(pStream); 243 } else { 244 delete pStream; 245 } 246 return rc; 247 } 248 249 /*=========================================================================== 250 * FUNCTION : linkStream 251 * 252 * DESCRIPTION: link a stream into channel 253 * 254 * PARAMETERS : 255 * @ch : Channel which the stream belongs to 256 * @stream : Stream which needs to be linked 257 * 258 * RETURN : int32_t type of status 259 * NO_ERROR -- success 260 * none-zero failure code 261 *==========================================================================*/ 262 int32_t QCameraChannel::linkStream(QCameraChannel *ch, QCameraStream *stream) 263 { 264 int32_t rc = NO_ERROR; 265 266 if ((0 == m_handle) || (NULL == ch) || (NULL == stream)) { 267 return NO_INIT; 268 } 269 270 int32_t handle = m_camOps->link_stream(m_camHandle, 271 ch->getMyHandle(), 272 stream->getMyHandle(), 273 m_handle); 274 if (0 == handle) { 275 LOGE("Linking of stream failed"); 276 rc = INVALID_OPERATION; 277 } else { 278 mStreams.add(stream); 279 } 280 281 return rc; 282 } 283 284 /*=========================================================================== 285 * FUNCTION : start 286 * 287 * DESCRIPTION: start channel, which will start all streams belong to this channel 288 * 289 * PARAMETERS : None 290 * 291 * RETURN : int32_t type of status 292 * NO_ERROR -- success 293 * none-zero failure code 294 *==========================================================================*/ 295 int32_t QCameraChannel::start() 296 { 297 int32_t rc = NO_ERROR; 298 299 if(m_bIsActive) { 300 LOGW("Attempt to start active channel"); 301 return rc; 302 } 303 if (mStreams.size() > 1) { 304 // there is more than one stream in the channel 305 // we need to notify mctl that all streams in this channel need to be bundled 306 cam_bundle_config_t bundleInfo; 307 memset(&bundleInfo, 0, sizeof(bundleInfo)); 308 rc = m_camOps->get_bundle_info(m_camHandle, m_handle, &bundleInfo); 309 if (rc != NO_ERROR) { 310 LOGE("get_bundle_info failed"); 311 return rc; 312 } 313 if (bundleInfo.num_of_streams > 1) { 314 for (int i = 0; i < bundleInfo.num_of_streams; i++) { 315 QCameraStream *pStream = getStreamByServerID(bundleInfo.stream_ids[i]); 316 if (pStream != NULL) { 317 if ((pStream->isTypeOf(CAM_STREAM_TYPE_METADATA)) 318 || (pStream->isTypeOf(CAM_STREAM_TYPE_OFFLINE_PROC))) { 319 // Skip metadata for reprocess now because PP module cannot handle meta data 320 // May need furthur discussion if Imaginglib need meta data 321 continue; 322 } 323 324 cam_stream_parm_buffer_t param; 325 memset(¶m, 0, sizeof(cam_stream_parm_buffer_t)); 326 param.type = CAM_STREAM_PARAM_TYPE_SET_BUNDLE_INFO; 327 param.bundleInfo = bundleInfo; 328 rc = pStream->setParameter(param); 329 if (rc != NO_ERROR) { 330 LOGE("stream setParameter for set bundle failed"); 331 return rc; 332 } 333 } 334 } 335 } 336 } 337 338 for (size_t i = 0; i < mStreams.size(); i++) { 339 if ((mStreams[i] != NULL) && 340 (m_handle == mStreams[i]->getChannelHandle())) { 341 mStreams[i]->start(); 342 } 343 } 344 rc = m_camOps->start_channel(m_camHandle, m_handle); 345 346 if (rc != NO_ERROR) { 347 for (size_t i = 0; i < mStreams.size(); i++) { 348 if ((mStreams[i] != NULL) && 349 (m_handle == mStreams[i]->getChannelHandle())) { 350 mStreams[i]->stop(); 351 } 352 } 353 } else { 354 m_bIsActive = true; 355 for (size_t i = 0; i < mStreams.size(); i++) { 356 if (mStreams[i] != NULL) { 357 mStreams[i]->cond_signal(); 358 } 359 } 360 } 361 362 return rc; 363 } 364 365 /*=========================================================================== 366 * FUNCTION : stop 367 * 368 * DESCRIPTION: stop a channel, which will stop all streams belong to this channel 369 * 370 * PARAMETERS : none 371 * 372 * RETURN : int32_t type of status 373 * NO_ERROR -- success 374 * none-zero failure code 375 *==========================================================================*/ 376 int32_t QCameraChannel::stop() 377 { 378 int32_t rc = NO_ERROR; 379 size_t i = 0; 380 381 if (!m_bIsActive) { 382 return NO_INIT; 383 } 384 385 while(i < mStreams.size()) { 386 if (mStreams[i] != NULL) { 387 if (m_handle == mStreams[i]->getChannelHandle()) { 388 mStreams[i]->stop(); 389 i++; 390 } else { 391 // Remove linked stream from stream list 392 mStreams.removeAt(i); 393 } 394 } 395 } 396 397 rc = m_camOps->stop_channel(m_camHandle, m_handle); 398 399 m_bIsActive = false; 400 return rc; 401 } 402 403 /*=========================================================================== 404 * FUNCTION : bufDone 405 * 406 * DESCRIPTION: return a stream buf back to kernel 407 * 408 * PARAMETERS : 409 * @recvd_frame : stream buf frame to be returned 410 * 411 * RETURN : int32_t type of status 412 * NO_ERROR -- success 413 * none-zero failure code 414 *==========================================================================*/ 415 int32_t QCameraChannel::bufDone(mm_camera_super_buf_t *recvd_frame) 416 { 417 int32_t rc = NO_ERROR; 418 for (uint32_t i = 0; i < recvd_frame->num_bufs; i++) { 419 if (recvd_frame->bufs[i] != NULL) { 420 for (size_t j = 0; j < mStreams.size(); j++) { 421 if (mStreams[j] != NULL && 422 mStreams[j]->getMyHandle() == recvd_frame->bufs[i]->stream_id) { 423 rc = mStreams[j]->bufDone(recvd_frame->bufs[i]->buf_idx); 424 break; // break loop j 425 } 426 } 427 } 428 } 429 430 return rc; 431 } 432 433 /*=========================================================================== 434 * FUNCTION : bufDone 435 * 436 * DESCRIPTION: return specified buffer from super buffer to kernel 437 * 438 * PARAMETERS : 439 * @recvd_frame : stream buf frame to be returned 440 * @stream_id : stream ID of the buffer to be released 441 * 442 * RETURN : int32_t type of status 443 * NO_ERROR -- success 444 * none-zero failure code 445 *==========================================================================*/ 446 int32_t QCameraChannel::bufDone(mm_camera_super_buf_t *recvd_frame, uint32_t stream_id) 447 { 448 int32_t rc = NO_ERROR; 449 int32_t index; 450 for (int32_t i = 0; i < (int32_t)recvd_frame->num_bufs; i++) { 451 index = -1; 452 if ((recvd_frame->bufs[i] != NULL) && 453 (recvd_frame->bufs[i]->stream_id == stream_id)) { 454 for (size_t j = 0; j < mStreams.size(); j++) { 455 if ((mStreams[j] != NULL) && 456 (mStreams[j]->getMyHandle() == stream_id)) { 457 rc = mStreams[j]->bufDone(recvd_frame->bufs[i]->buf_idx); 458 index = i; 459 break; // break loop j 460 } 461 } 462 if ((index >= 0) && (index < (int32_t)recvd_frame->num_bufs)) { 463 for (int32_t j = index; j < (int32_t)(recvd_frame->num_bufs - 1); j++) { 464 recvd_frame->bufs[j] = recvd_frame->bufs[j + 1]; 465 } 466 recvd_frame->num_bufs--; 467 i--; 468 } 469 } 470 } 471 472 return rc; 473 } 474 475 /*=========================================================================== 476 * FUNCTION : processZoomDone 477 * 478 * DESCRIPTION: process zoom done event 479 * 480 * PARAMETERS : 481 * @previewWindoe : ptr to preview window ops table, needed to set preview 482 * crop information 483 * @crop_info : crop info as a result of zoom operation 484 * 485 * RETURN : int32_t type of status 486 * NO_ERROR -- success 487 * none-zero failure code 488 *==========================================================================*/ 489 int32_t QCameraChannel::processZoomDone(preview_stream_ops_t *previewWindow, 490 cam_crop_data_t &crop_info) 491 { 492 int32_t rc = NO_ERROR; 493 for (size_t i = 0; i < mStreams.size(); i++) { 494 if ((mStreams[i] != NULL) && 495 (m_handle == mStreams[i]->getChannelHandle())) { 496 rc = mStreams[i]->processZoomDone(previewWindow, crop_info); 497 } 498 } 499 return rc; 500 } 501 502 /*=========================================================================== 503 * FUNCTION : getStreamByHandle 504 * 505 * DESCRIPTION: return stream object by stream handle 506 * 507 * PARAMETERS : 508 * @streamHandle : stream handle 509 * 510 * RETURN : stream object. NULL if not found 511 *==========================================================================*/ 512 QCameraStream *QCameraChannel::getStreamByHandle(uint32_t streamHandle) 513 { 514 for (size_t i = 0; i < mStreams.size(); i++) { 515 if (mStreams[i] != NULL && mStreams[i]->getMyHandle() == streamHandle) { 516 return mStreams[i]; 517 } 518 } 519 return NULL; 520 } 521 522 /*=========================================================================== 523 * FUNCTION : getStreamByServerID 524 * 525 * DESCRIPTION: return stream object by stream server ID from daemon 526 * 527 * PARAMETERS : 528 * @serverID : stream server ID 529 * 530 * RETURN : stream object. NULL if not found 531 *==========================================================================*/ 532 QCameraStream *QCameraChannel::getStreamByServerID(uint32_t serverID) 533 { 534 for (size_t i = 0; i < mStreams.size(); i++) { 535 if (mStreams[i] != NULL && mStreams[i]->getMyServerID() == serverID) { 536 return mStreams[i]; 537 } 538 } 539 return NULL; 540 } 541 542 /*=========================================================================== 543 * FUNCTION : getStreamByIndex 544 * 545 * DESCRIPTION: return stream object by index of streams in the channel 546 * 547 * PARAMETERS : 548 * @index : index of stream in the channel 549 * 550 * RETURN : stream object. NULL if not found 551 *==========================================================================*/ 552 QCameraStream *QCameraChannel::getStreamByIndex(uint32_t index) 553 { 554 if (index >= MAX_STREAM_NUM_IN_BUNDLE) { 555 return NULL; 556 } 557 558 if (index < mStreams.size()) { 559 return mStreams[index]; 560 } 561 return NULL; 562 } 563 564 /*=========================================================================== 565 * FUNCTION : UpdateStreamBasedParameters 566 * 567 * DESCRIPTION: update any stream based settings from parameters 568 * 569 * PARAMETERS : 570 * @param : reference to parameters object 571 * 572 * RETURN : int32_t type of status 573 * NO_ERROR -- success 574 * none-zero failure code 575 *==========================================================================*/ 576 int32_t QCameraChannel::UpdateStreamBasedParameters(QCameraParametersIntf ¶m) 577 { 578 int32_t rc = NO_ERROR; 579 if (param.isPreviewFlipChanged()) { 580 // try to find preview stream 581 for (size_t i = 0; i < mStreams.size(); i++) { 582 if ((mStreams[i] != NULL) && 583 (m_handle == mStreams[i]->getChannelHandle()) && 584 (mStreams[i]->isTypeOf(CAM_STREAM_TYPE_PREVIEW) || 585 (mStreams[i]->isOrignalTypeOf(CAM_STREAM_TYPE_PREVIEW))) ) { 586 cam_stream_parm_buffer_t param_buf; 587 memset(¶m_buf, 0, sizeof(cam_stream_parm_buffer_t)); 588 param_buf.type = CAM_STREAM_PARAM_TYPE_SET_FLIP; 589 param_buf.flipInfo.flip_mask = 590 (uint32_t)param.getFlipMode(CAM_STREAM_TYPE_PREVIEW); 591 rc = mStreams[i]->setParameter(param_buf); 592 if (rc != NO_ERROR) { 593 LOGW("set preview stream flip failed"); 594 } 595 } 596 } 597 } 598 if (param.isVideoFlipChanged()) { 599 // try to find video stream 600 for (size_t i = 0; i < mStreams.size(); i++) { 601 if ((mStreams[i] != NULL) && 602 (m_handle == mStreams[i]->getChannelHandle()) && 603 (mStreams[i]->isTypeOf(CAM_STREAM_TYPE_VIDEO) || 604 (mStreams[i]->isOrignalTypeOf(CAM_STREAM_TYPE_VIDEO))) ) { 605 cam_stream_parm_buffer_t param_buf; 606 memset(¶m_buf, 0, sizeof(cam_stream_parm_buffer_t)); 607 param_buf.type = CAM_STREAM_PARAM_TYPE_SET_FLIP; 608 param_buf.flipInfo.flip_mask = 609 (uint32_t)param.getFlipMode(CAM_STREAM_TYPE_VIDEO); 610 rc = mStreams[i]->setParameter(param_buf); 611 if (rc != NO_ERROR) { 612 LOGW("set video stream flip failed"); 613 } 614 } 615 } 616 } 617 if (param.isSnapshotFlipChanged()) { 618 // try to find snapshot/postview stream 619 for (size_t i = 0; i < mStreams.size(); i++) { 620 if (mStreams[i] != NULL && 621 (m_handle == mStreams[i]->getChannelHandle()) && 622 (mStreams[i]->isTypeOf(CAM_STREAM_TYPE_SNAPSHOT) || 623 mStreams[i]->isOrignalTypeOf(CAM_STREAM_TYPE_SNAPSHOT) || 624 mStreams[i]->isTypeOf(CAM_STREAM_TYPE_POSTVIEW) || 625 mStreams[i]->isOrignalTypeOf(CAM_STREAM_TYPE_POSTVIEW) ) ) { 626 cam_stream_parm_buffer_t param_buf; 627 memset(¶m_buf, 0, sizeof(cam_stream_parm_buffer_t)); 628 param_buf.type = CAM_STREAM_PARAM_TYPE_SET_FLIP; 629 param_buf.flipInfo.flip_mask = 630 (uint32_t)param.getFlipMode(CAM_STREAM_TYPE_SNAPSHOT); 631 rc = mStreams[i]->setParameter(param_buf); 632 if (rc != NO_ERROR) { 633 LOGW("set snapshot stream flip failed"); 634 } 635 } 636 } 637 } 638 return rc; 639 } 640 641 /*=========================================================================== 642 * FUNCTION : QCameraPicChannel 643 * 644 * DESCRIPTION: constructor of QCameraPicChannel 645 * 646 * PARAMETERS : 647 * @cam_handle : camera handle 648 * @cam_ops : ptr to camera ops table 649 * 650 * RETURN : none 651 *==========================================================================*/ 652 QCameraPicChannel::QCameraPicChannel(uint32_t cam_handle, 653 mm_camera_ops_t *cam_ops) : 654 QCameraChannel(cam_handle, cam_ops) 655 { 656 m_bAllowDynBufAlloc = true; 657 } 658 659 /*=========================================================================== 660 * FUNCTION : QCameraPicChannel 661 * 662 * DESCRIPTION: default constructor of QCameraPicChannel 663 * 664 * PARAMETERS : none 665 * 666 * RETURN : none 667 *==========================================================================*/ 668 QCameraPicChannel::QCameraPicChannel() 669 { 670 m_bAllowDynBufAlloc = true; 671 } 672 673 /*=========================================================================== 674 * FUNCTION : ~QCameraPicChannel 675 * 676 * DESCRIPTION: destructor of QCameraPicChannel 677 * 678 * PARAMETERS : none 679 * 680 * RETURN : none 681 *==========================================================================*/ 682 QCameraPicChannel::~QCameraPicChannel() 683 { 684 } 685 686 /*=========================================================================== 687 * FUNCTION : takePicture 688 * 689 * DESCRIPTION: send request for queued snapshot frames 690 * 691 * PARAMETERS : 692 * @buf : request buf info 693 * 694 * RETURN : int32_t type of status 695 * NO_ERROR -- success 696 * none-zero failure code 697 *==========================================================================*/ 698 int32_t QCameraPicChannel::takePicture (mm_camera_req_buf_t *buf) 699 { 700 int32_t rc = m_camOps->request_super_buf(m_camHandle, m_handle, buf); 701 return rc; 702 } 703 704 /*=========================================================================== 705 * FUNCTION : cancelPicture 706 * 707 * DESCRIPTION: cancel request for queued snapshot frames 708 * 709 * PARAMETERS : none 710 * 711 * RETURN : int32_t type of status 712 * NO_ERROR -- success 713 * none-zero failure code 714 *==========================================================================*/ 715 int32_t QCameraPicChannel::cancelPicture() 716 { 717 int32_t rc = m_camOps->cancel_super_buf_request(m_camHandle, m_handle); 718 return rc; 719 } 720 721 /*=========================================================================== 722 * FUNCTION : stopAdvancedCapture 723 * 724 * DESCRIPTION: stop advanced capture based on advanced capture type. 725 * 726 * PARAMETERS : 727 * @type : advanced capture type. 728 * 729 * RETURN : int32_t type of status 730 * NO_ERROR -- success 731 * none-zero failure code 732 *==========================================================================*/ 733 int32_t QCameraPicChannel::stopAdvancedCapture(mm_camera_advanced_capture_t type) 734 { 735 int32_t rc = m_camOps->process_advanced_capture(m_camHandle, 736 m_handle, type, 0, NULL); 737 return rc; 738 } 739 740 /*=========================================================================== 741 * FUNCTION : startAdvancedCapture 742 * 743 * DESCRIPTION: start advanced capture based on advanced capture type. 744 * 745 * PARAMETERS : 746 * @type : advanced capture type. 747 * @config: advance capture config 748 * 749 * RETURN : int32_t type of status 750 * NO_ERROR -- success 751 * none-zero failure code 752 *==========================================================================*/ 753 int32_t QCameraPicChannel::startAdvancedCapture(mm_camera_advanced_capture_t type, 754 cam_capture_frame_config_t *config) 755 { 756 int32_t rc = NO_ERROR; 757 758 rc = m_camOps->process_advanced_capture(m_camHandle, m_handle, type, 759 1, config); 760 return rc; 761 } 762 763 /*=========================================================================== 764 * FUNCTION : flushSuperbuffer 765 * 766 * DESCRIPTION: flush the all superbuffer frames. 767 * 768 * PARAMETERS : 769 * @frame_idx : frame index of focused frame 770 * 771 * RETURN : int32_t type of status 772 * NO_ERROR -- success 773 * none-zero failure code 774 *==========================================================================*/ 775 int32_t QCameraPicChannel::flushSuperbuffer(uint32_t frame_idx) 776 { 777 int32_t rc = m_camOps->flush_super_buf_queue(m_camHandle, m_handle, frame_idx); 778 return rc; 779 } 780 781 /*=========================================================================== 782 * FUNCTION : QCameraVideoChannel 783 * 784 * DESCRIPTION: constructor of QCameraVideoChannel 785 * 786 * PARAMETERS : 787 * @cam_handle : camera handle 788 * @cam_ops : ptr to camera ops table 789 * 790 * RETURN : none 791 *==========================================================================*/ 792 QCameraVideoChannel::QCameraVideoChannel(uint32_t cam_handle, 793 mm_camera_ops_t *cam_ops) : 794 QCameraChannel(cam_handle, cam_ops) 795 { 796 } 797 798 /*=========================================================================== 799 * FUNCTION : QCameraVideoChannel 800 * 801 * DESCRIPTION: default constructor of QCameraVideoChannel 802 * 803 * PARAMETERS : none 804 * 805 * RETURN : none 806 *==========================================================================*/ 807 QCameraVideoChannel::QCameraVideoChannel() 808 { 809 } 810 811 /*=========================================================================== 812 * FUNCTION : ~QCameraVideoChannel 813 * 814 * DESCRIPTION: destructor of QCameraVideoChannel 815 * 816 * PARAMETERS : none 817 * 818 * RETURN : none 819 *==========================================================================*/ 820 QCameraVideoChannel::~QCameraVideoChannel() 821 { 822 } 823 824 /*=========================================================================== 825 * FUNCTION : takePicture 826 * 827 * DESCRIPTION: send request for queued snapshot frames 828 * 829 * PARAMETERS : 830 * @mm_camera_req_buf_t : request buf info 831 * 832 * RETURN : int32_t type of status 833 * NO_ERROR -- success 834 * none-zero failure code 835 *==========================================================================*/ 836 int32_t QCameraVideoChannel::takePicture(mm_camera_req_buf_t *buf) 837 { 838 int32_t rc = m_camOps->request_super_buf(m_camHandle, m_handle, buf); 839 return rc; 840 } 841 842 /*=========================================================================== 843 * FUNCTION : cancelPicture 844 * 845 * DESCRIPTION: cancel request for queued snapshot frames 846 * 847 * PARAMETERS : none 848 * 849 * RETURN : int32_t type of status 850 * NO_ERROR -- success 851 * none-zero failure code 852 *==========================================================================*/ 853 int32_t QCameraVideoChannel::cancelPicture() 854 { 855 int32_t rc = m_camOps->cancel_super_buf_request(m_camHandle, m_handle); 856 return rc; 857 } 858 859 /*=========================================================================== 860 * FUNCTION : releaseFrame 861 * 862 * DESCRIPTION: return video frame from app 863 * 864 * PARAMETERS : 865 * @opaque : ptr to video frame to be returned 866 * @isMetaData : if frame is a metadata or real frame 867 * 868 * RETURN : int32_t type of status 869 * NO_ERROR -- success 870 * none-zero failure code 871 *==========================================================================*/ 872 int32_t QCameraVideoChannel::releaseFrame(const void * opaque, bool isMetaData) 873 { 874 QCameraStream *pVideoStream = NULL; 875 for (size_t i = 0; i < mStreams.size(); i++) { 876 if (mStreams[i] != NULL && mStreams[i]->isTypeOf(CAM_STREAM_TYPE_VIDEO)) { 877 pVideoStream = mStreams[i]; 878 break; 879 } 880 } 881 882 if (NULL == pVideoStream) { 883 LOGE("No video stream in the channel"); 884 return BAD_VALUE; 885 } 886 887 int32_t rc = pVideoStream->bufDone(opaque, isMetaData); 888 return rc; 889 } 890 891 /*=========================================================================== 892 * FUNCTION : QCameraReprocessChannel 893 * 894 * DESCRIPTION: constructor of QCameraReprocessChannel 895 * 896 * PARAMETERS : 897 * @cam_handle : camera handle 898 * @cam_ops : ptr to camera ops table 899 * 900 * RETURN : none 901 *==========================================================================*/ 902 QCameraReprocessChannel::QCameraReprocessChannel(uint32_t cam_handle, 903 mm_camera_ops_t *cam_ops) : 904 QCameraChannel(cam_handle, cam_ops), 905 m_pSrcChannel(NULL), 906 mPassCount(0) 907 { 908 memset(mSrcStreamHandles, 0, sizeof(mSrcStreamHandles)); 909 } 910 911 /*=========================================================================== 912 * FUNCTION : QCameraReprocessChannel 913 * 914 * DESCRIPTION: default constructor of QCameraReprocessChannel 915 * 916 * PARAMETERS : none 917 * 918 * RETURN : none 919 *==========================================================================*/ 920 QCameraReprocessChannel::QCameraReprocessChannel() : 921 m_pSrcChannel(NULL), 922 mPassCount(0) 923 { 924 } 925 926 /*=========================================================================== 927 * FUNCTION : ~QCameraReprocessChannel 928 * 929 * DESCRIPTION: destructor of QCameraReprocessChannel 930 * 931 * PARAMETERS : none 932 * 933 * RETURN : none 934 *==========================================================================*/ 935 QCameraReprocessChannel::~QCameraReprocessChannel() 936 { 937 } 938 939 /*=========================================================================== 940 * FUNCTION : addReprocStreamsFromSource 941 * 942 * DESCRIPTION: add reprocess streams from input source channel 943 * 944 * PARAMETERS : 945 * @allocator : stream related buffer allocator 946 * @featureConfig : pp feature configuration 947 * @pSrcChannel : ptr to input source channel that needs reprocess 948 * @minStreamBufNum: number of stream buffers needed 949 * @burstNum : number of burst captures needed 950 * @paddingInfo : padding information 951 * @param : reference to parameters 952 * @contStream : continous streaming mode or burst 953 * @offline : configure for offline reprocessing 954 * 955 * RETURN : int32_t type of status 956 * NO_ERROR -- success 957 * none-zero failure code 958 *==========================================================================*/ 959 int32_t QCameraReprocessChannel::addReprocStreamsFromSource( 960 QCameraAllocator& allocator, cam_pp_feature_config_t &featureConfig, 961 QCameraChannel *pSrcChannel, uint8_t minStreamBufNum, uint8_t burstNum, 962 cam_padding_info_t *paddingInfo, QCameraParametersIntf ¶m, bool contStream, 963 bool offline) 964 { 965 int32_t rc = 0; 966 QCameraStream *pStream = NULL; 967 QCameraHeapMemory *pStreamInfoBuf = NULL; 968 QCameraHeapMemory *pMiscBuf = NULL; 969 cam_stream_info_t *streamInfo = NULL; 970 cam_padding_info_t padding; 971 972 memset(mSrcStreamHandles, 0, sizeof(mSrcStreamHandles)); 973 if (NULL == paddingInfo) { 974 return BAD_VALUE; 975 } 976 padding = *paddingInfo; 977 //Use maximum padding so that the buffer 978 //can be rotated 979 padding.width_padding = MAX(padding.width_padding, padding.height_padding); 980 padding.height_padding = padding.width_padding; 981 padding.offset_info.offset_x = 0; 982 padding.offset_info.offset_y = 0; 983 984 LOGD("num of src stream = %d", pSrcChannel->getNumOfStreams()); 985 986 for (uint32_t i = 0; i < pSrcChannel->getNumOfStreams(); i++) { 987 cam_pp_feature_config_t pp_featuremask = featureConfig; 988 pStream = pSrcChannel->getStreamByIndex(i); 989 if (pStream != NULL) { 990 if (param.getofflineRAW() && !((pStream->isTypeOf(CAM_STREAM_TYPE_RAW)) 991 || (pStream->isTypeOf(CAM_STREAM_TYPE_POSTVIEW)) 992 || (pStream->isTypeOf(CAM_STREAM_TYPE_METADATA)) 993 || (pStream->isOrignalTypeOf(CAM_STREAM_TYPE_RAW)))) { 994 //Skip all the stream other than RAW and POSTVIEW incase of offline of RAW 995 continue; 996 } 997 998 if (pStream->isTypeOf(CAM_STREAM_TYPE_RAW) 999 && (!param.getofflineRAW())) { 1000 // Skip raw for reprocess now because PP module cannot handle 1001 // meta data&raw. May need furthur discussion if Imaginglib need meta data 1002 continue; 1003 } 1004 1005 if (((pStream->isTypeOf(CAM_STREAM_TYPE_METADATA)) 1006 && !(param.getManualCaptureMode() >= 1007 CAM_MANUAL_CAPTURE_TYPE_3)) 1008 || (pStream->isTypeOf(CAM_STREAM_TYPE_ANALYSIS))) { 1009 // Skip metadata 1010 continue; 1011 } 1012 1013 if (pStream->isTypeOf(CAM_STREAM_TYPE_PREVIEW) || 1014 pStream->isTypeOf(CAM_STREAM_TYPE_POSTVIEW) || 1015 pStream->isOrignalTypeOf(CAM_STREAM_TYPE_PREVIEW) || 1016 pStream->isOrignalTypeOf(CAM_STREAM_TYPE_POSTVIEW)) { 1017 cam_feature_mask_t feature_mask = featureConfig.feature_mask; 1018 1019 // skip thumbnail reprocessing if not needed 1020 if (!param.needThumbnailReprocess(&feature_mask)) { 1021 continue; 1022 } 1023 // CAC, SHARPNESS, FLIP and WNR would have been already applied - 1024 // on preview/postview stream in realtime. 1025 // So, need not apply again. 1026 feature_mask &= ~(CAM_QCOM_FEATURE_DENOISE2D | 1027 CAM_QCOM_FEATURE_CAC | 1028 CAM_QCOM_FEATURE_SHARPNESS | 1029 CAM_QCOM_FEATURE_FLIP | 1030 CAM_QCOM_FEATURE_RAW_PROCESSING); 1031 if (!feature_mask) { 1032 // Skip thumbnail stream reprocessing since no other 1033 //reprocessing is enabled. 1034 continue; 1035 } 1036 } 1037 1038 if (pStream->isTypeOf(CAM_STREAM_TYPE_METADATA)) { 1039 pp_featuremask.feature_mask = 0; 1040 pp_featuremask.feature_mask |= CAM_QCOM_FEATURE_METADATA_PROCESSING; 1041 } 1042 1043 pStreamInfoBuf = allocator.allocateStreamInfoBuf(CAM_STREAM_TYPE_OFFLINE_PROC); 1044 if (pStreamInfoBuf == NULL) { 1045 LOGE("no mem for stream info buf"); 1046 rc = NO_MEMORY; 1047 break; 1048 } 1049 1050 streamInfo = (cam_stream_info_t *)pStreamInfoBuf->getPtr(0); 1051 memset(streamInfo, 0, sizeof(cam_stream_info_t)); 1052 streamInfo->stream_type = CAM_STREAM_TYPE_OFFLINE_PROC; 1053 // Enable CPP high performance mode to put it in turbo frequency mode for 1054 // burst/longshot/HDR snapshot cases 1055 streamInfo->perf_mode = CAM_PERF_HIGH_PERFORMANCE; 1056 if (param.getofflineRAW() && pStream->isTypeOf(CAM_STREAM_TYPE_RAW)) { 1057 streamInfo->fmt = CAM_FORMAT_YUV_420_NV21; 1058 } else { 1059 rc = pStream->getFormat(streamInfo->fmt); 1060 } 1061 1062 if (pStream->isTypeOf(CAM_STREAM_TYPE_POSTVIEW) || 1063 pStream->isTypeOf(CAM_STREAM_TYPE_PREVIEW)) { 1064 param.getThumbnailSize(&(streamInfo->dim.width), &(streamInfo->dim.height)); 1065 } else { 1066 if ((param.isPostProcScaling()) && 1067 (pp_featuremask.feature_mask & CAM_QCOM_FEATURE_SCALE)) { 1068 rc = param.getStreamDimension(CAM_STREAM_TYPE_OFFLINE_PROC, 1069 streamInfo->dim); 1070 } else if ((param.getofflineRAW()) && 1071 (pStream->isTypeOf(CAM_STREAM_TYPE_RAW))) { 1072 param.getStreamDimension(CAM_STREAM_TYPE_SNAPSHOT,streamInfo->dim); 1073 } else { 1074 rc = pStream->getFrameDimension(streamInfo->dim); 1075 } 1076 } 1077 1078 if ( contStream ) { 1079 streamInfo->streaming_mode = CAM_STREAMING_MODE_CONTINUOUS; 1080 streamInfo->num_of_burst = 0; 1081 } else { 1082 streamInfo->streaming_mode = CAM_STREAMING_MODE_BURST; 1083 streamInfo->num_of_burst = burstNum; 1084 } 1085 streamInfo->num_bufs = minStreamBufNum; 1086 1087 cam_stream_reproc_config_t rp_cfg; 1088 memset(&rp_cfg, 0, sizeof(cam_stream_reproc_config_t)); 1089 if (offline) { 1090 cam_frame_len_offset_t offset; 1091 memset(&offset, 0, sizeof(cam_frame_len_offset_t)); 1092 1093 rp_cfg.pp_type = CAM_OFFLINE_REPROCESS_TYPE; 1094 pStream->getFormat(rp_cfg.offline.input_fmt); 1095 pStream->getFrameDimension(rp_cfg.offline.input_dim); 1096 pStream->getFrameOffset(offset); 1097 rp_cfg.offline.input_buf_planes.plane_info = offset; 1098 rp_cfg.offline.input_type = pStream->getMyOriginalType(); 1099 //For input metadata + input buffer 1100 rp_cfg.offline.num_of_bufs = 2; 1101 } else { 1102 rp_cfg.pp_type = CAM_ONLINE_REPROCESS_TYPE; 1103 rp_cfg.online.input_stream_id = pStream->getMyServerID(); 1104 rp_cfg.online.input_stream_type = pStream->getMyOriginalType(); 1105 } 1106 param.getStreamRotation(streamInfo->stream_type, 1107 streamInfo->pp_config, streamInfo->dim); 1108 streamInfo->reprocess_config = rp_cfg; 1109 streamInfo->reprocess_config.pp_feature_config = pp_featuremask; 1110 1111 if (!(pStream->isTypeOf(CAM_STREAM_TYPE_SNAPSHOT) 1112 || pStream->isOrignalTypeOf(CAM_STREAM_TYPE_SNAPSHOT) 1113 || pStream->isTypeOf(CAM_STREAM_TYPE_RAW) 1114 || pStream->isOrignalTypeOf(CAM_STREAM_TYPE_RAW))) { 1115 // CAC, SHARPNESS, FLIP and WNR would have been already applied - 1116 // on preview/postview stream in realtime. Need not apply again. 1117 streamInfo->reprocess_config.pp_feature_config.feature_mask &= 1118 ~CAM_QCOM_FEATURE_CAC; 1119 streamInfo->reprocess_config.pp_feature_config.feature_mask &= 1120 ~CAM_QCOM_FEATURE_SHARPNESS; 1121 streamInfo->reprocess_config.pp_feature_config.feature_mask &= 1122 ~CAM_QCOM_FEATURE_FLIP; 1123 //Don't do WNR for thumbnail 1124 streamInfo->reprocess_config.pp_feature_config.feature_mask &= 1125 ~CAM_QCOM_FEATURE_DENOISE2D; 1126 streamInfo->reprocess_config.pp_feature_config.feature_mask &= 1127 ~CAM_QCOM_FEATURE_CDS; 1128 streamInfo->reprocess_config.pp_feature_config.feature_mask &= 1129 ~CAM_QCOM_FEATURE_DSDN; 1130 //No need of RAW processing for other than RAW streams 1131 streamInfo->reprocess_config.pp_feature_config.feature_mask &= 1132 ~CAM_QCOM_FEATURE_RAW_PROCESSING; 1133 1134 if (param.isHDREnabled() 1135 && !param.isHDRThumbnailProcessNeeded()){ 1136 streamInfo->reprocess_config.pp_feature_config.feature_mask 1137 &= ~CAM_QCOM_FEATURE_HDR; 1138 } 1139 } 1140 1141 cam_stream_type_t type = CAM_STREAM_TYPE_DEFAULT; 1142 if (offline) { 1143 type = streamInfo->reprocess_config.offline.input_type; 1144 } else { 1145 type = streamInfo->reprocess_config.online.input_stream_type; 1146 } 1147 if (type == CAM_STREAM_TYPE_SNAPSHOT) { 1148 int flipMode = param.getFlipMode(type); 1149 if (flipMode > 0) { 1150 streamInfo->reprocess_config.pp_feature_config.feature_mask |= 1151 CAM_QCOM_FEATURE_FLIP; 1152 streamInfo->reprocess_config.pp_feature_config.flip = (uint32_t)flipMode; 1153 } 1154 } 1155 1156 if ((streamInfo->reprocess_config.pp_feature_config.feature_mask 1157 & CAM_QCOM_FEATURE_SCALE) 1158 && param.isReprocScaleEnabled() 1159 && param.isUnderReprocScaling()) { 1160 //we only Scale Snapshot frame 1161 if (pStream->isTypeOf(CAM_STREAM_TYPE_SNAPSHOT)) { 1162 streamInfo->dim.width = 1163 streamInfo->reprocess_config.pp_feature_config.scale_param.output_width; 1164 streamInfo->dim.height = 1165 streamInfo->reprocess_config.pp_feature_config.scale_param.output_height; 1166 } 1167 LOGH("stream width=%d, height=%d.", 1168 streamInfo->dim.width, streamInfo->dim.height); 1169 } 1170 1171 // save source stream handler 1172 mSrcStreamHandles[mStreams.size()] = pStream->getMyHandle(); 1173 1174 pMiscBuf = allocator.allocateMiscBuf(streamInfo); 1175 1176 LOGH("Configure Reprocessing: stream = %d, res = %dX%d, fmt = %d, type = %d", 1177 pStream->getMyOriginalType(), streamInfo->dim.width, 1178 streamInfo->dim.height, streamInfo->fmt, type); 1179 1180 // add reprocess stream 1181 if (streamInfo->reprocess_config.pp_feature_config.feature_mask 1182 & CAM_QCOM_FEATURE_ROTATION) { 1183 rc = addStream(allocator, pStreamInfoBuf, pMiscBuf, 1184 minStreamBufNum, &padding, NULL, NULL, false, false, 1185 streamInfo->reprocess_config.pp_feature_config.rotation); 1186 } else { 1187 rc = addStream(allocator, pStreamInfoBuf, pMiscBuf, 1188 minStreamBufNum, &padding, NULL, NULL, false, false); 1189 } 1190 if (rc != NO_ERROR) { 1191 LOGE("add reprocess stream failed, ret = %d", rc); 1192 break; 1193 } 1194 } 1195 } 1196 1197 if (rc == NO_ERROR) { 1198 m_pSrcChannel = pSrcChannel; 1199 } 1200 return rc; 1201 } 1202 1203 /*=========================================================================== 1204 * FUNCTION : getStreamBySrouceHandle 1205 * 1206 * DESCRIPTION: find reprocess stream by its source stream handle 1207 * 1208 * PARAMETERS : 1209 * @srcHandle : source stream handle 1210 * 1211 * RETURN : ptr to reprocess stream if found. NULL if not found 1212 *==========================================================================*/ 1213 QCameraStream * QCameraReprocessChannel::getStreamBySrouceHandle(uint32_t srcHandle) 1214 { 1215 QCameraStream *pStream = NULL; 1216 1217 for (size_t i = 0; i < mStreams.size(); i++) { 1218 if (mSrcStreamHandles[i] == srcHandle) { 1219 pStream = mStreams[i]; 1220 break; 1221 } 1222 } 1223 1224 return pStream; 1225 } 1226 1227 /*=========================================================================== 1228 * FUNCTION : stop 1229 * 1230 * DESCRIPTION: stop channel and unmap offline buffers 1231 * 1232 * PARAMETERS : none 1233 * 1234 * RETURN : int32_t type of status 1235 * NO_ERROR -- success 1236 * none-zero failure code 1237 *==========================================================================*/ 1238 int32_t QCameraReprocessChannel::stop() 1239 { 1240 int32_t rc = QCameraChannel::stop(); 1241 1242 if (!mOfflineBuffers.empty()) { 1243 QCameraStream *stream = NULL; 1244 List<OfflineBuffer>::iterator it = mOfflineBuffers.begin(); 1245 int error = NO_ERROR; 1246 for( ; it != mOfflineBuffers.end(); it++) { 1247 stream = (*it).stream; 1248 if (NULL != stream) { 1249 error = stream->unmapBuf((*it).type, 1250 (*it).index, 1251 -1); 1252 if (NO_ERROR != error) { 1253 LOGE("Error during offline buffer unmap %d", 1254 error); 1255 } 1256 } 1257 } 1258 mOfflineBuffers.clear(); 1259 } 1260 return rc; 1261 } 1262 1263 /*=========================================================================== 1264 * FUNCTION : doReprocessOffline 1265 * 1266 * DESCRIPTION: request to do offline reprocess on the frame 1267 * 1268 * PARAMETERS : 1269 * @frame : frame to be performed a reprocess 1270 * @meta_buf : Metadata buffer for reprocessing 1271 * @pStream : Actual reprocess stream 1272 * 1273 * RETURN : int32_t type of status 1274 * NO_ERROR -- success 1275 * none-zero failure code 1276 *==========================================================================*/ 1277 int32_t QCameraReprocessChannel::doReprocessOffline(mm_camera_buf_def_t *frame, 1278 mm_camera_buf_def_t *meta_buf, QCameraStream *pStream) 1279 { 1280 int32_t rc = 0; 1281 OfflineBuffer mappedBuffer; 1282 uint32_t buf_index = 0; 1283 uint32_t meta_buf_index = 0; 1284 1285 if ((frame == NULL) || (meta_buf == NULL)) { 1286 LOGE("Invalid Input Paramters"); 1287 return INVALID_OPERATION; 1288 } 1289 1290 if (pStream == NULL) { 1291 pStream = getStreamBySrouceHandle(frame->stream_id); 1292 if (pStream == NULL) { 1293 LOGE("Input validation failed."); 1294 return INVALID_OPERATION; 1295 } 1296 } 1297 1298 if (!mOfflineBuffers.empty()) { 1299 List<OfflineBuffer>::iterator it = mOfflineBuffers.begin(); 1300 for( ; it != mOfflineBuffers.end(); it++) { 1301 buf_index = (buf_index < ((*it).index)) ? ((*it).index) : buf_index; 1302 } 1303 buf_index += 1; 1304 } 1305 1306 meta_buf_index = buf_index; 1307 if (meta_buf != NULL) { 1308 rc = pStream->mapBuf(CAM_MAPPING_BUF_TYPE_OFFLINE_META_BUF, 1309 meta_buf_index, 1310 -1, 1311 meta_buf->fd, 1312 meta_buf->buffer, 1313 meta_buf->frame_len); 1314 if (NO_ERROR != rc ) { 1315 LOGE("Error during metadata buffer mapping"); 1316 rc = -1; 1317 return rc; 1318 } 1319 1320 mappedBuffer.index = meta_buf_index; 1321 mappedBuffer.stream = pStream; 1322 mappedBuffer.type = CAM_MAPPING_BUF_TYPE_OFFLINE_META_BUF; 1323 mOfflineBuffers.push_back(mappedBuffer); 1324 buf_index += 1; 1325 } 1326 1327 rc = pStream->mapBuf(CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF, 1328 buf_index, 1329 -1, 1330 frame->fd, 1331 frame->buffer, 1332 frame->frame_len); 1333 if (NO_ERROR != rc ) { 1334 LOGE("Error during reprocess input buffer mapping"); 1335 rc = -1; 1336 return rc; 1337 } 1338 mappedBuffer.index = buf_index; 1339 mappedBuffer.stream = pStream; 1340 mappedBuffer.type = CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF; 1341 mOfflineBuffers.push_back(mappedBuffer); 1342 1343 cam_stream_parm_buffer_t param; 1344 memset(¶m, 0, sizeof(cam_stream_parm_buffer_t)); 1345 1346 param.type = CAM_STREAM_PARAM_TYPE_DO_REPROCESS; 1347 param.reprocess.buf_index = buf_index; 1348 param.reprocess.frame_idx = frame->frame_idx; 1349 1350 if (meta_buf != NULL) { 1351 param.reprocess.meta_present = 1; 1352 param.reprocess.meta_buf_index = meta_buf_index; 1353 } 1354 1355 LOGI("Offline reprocessing id = %d buf Id = %d meta index = %d type = %d", 1356 param.reprocess.frame_idx, param.reprocess.buf_index, 1357 param.reprocess.meta_buf_index, pStream->getMyOriginalType()); 1358 1359 rc = pStream->setParameter(param); 1360 if (rc != NO_ERROR) { 1361 LOGE("stream setParameter for reprocess failed"); 1362 return rc; 1363 } 1364 return rc; 1365 } 1366 1367 /*=========================================================================== 1368 * FUNCTION : doReprocessOffline 1369 * 1370 * DESCRIPTION: request to do offline reprocess on the frame 1371 * 1372 * PARAMETERS : 1373 * @frame : frame to be performed a reprocess 1374 * @meta_buf : Metadata buffer for reprocessing 1375 * @mParameter : camera parameters 1376 * 1377 * RETURN : int32_t type of status 1378 * NO_ERROR -- success 1379 * none-zero failure code 1380 *==========================================================================*/ 1381 int32_t QCameraReprocessChannel::doReprocessOffline(mm_camera_super_buf_t *frame, 1382 mm_camera_buf_def_t *meta_buf, QCameraParametersIntf &mParameter) 1383 { 1384 int32_t rc = 0; 1385 QCameraStream *pStream = NULL; 1386 1387 if (mStreams.size() < 1) { 1388 LOGE("No reprocess streams"); 1389 return -1; 1390 } 1391 if (m_pSrcChannel == NULL) { 1392 LOGE("No source channel for reprocess"); 1393 return -1; 1394 } 1395 1396 if (frame == NULL) { 1397 LOGE("Invalid source frame"); 1398 return BAD_VALUE; 1399 } 1400 1401 for (uint32_t i = 0; i < frame->num_bufs; i++) { 1402 pStream = getStreamBySrouceHandle(frame->bufs[i]->stream_id); 1403 if ((pStream != NULL) && 1404 (m_handle == pStream->getChannelHandle())) { 1405 if (mParameter.getofflineRAW() && 1406 !((pStream->isOrignalTypeOf(CAM_STREAM_TYPE_RAW)) 1407 || (pStream->isOrignalTypeOf(CAM_STREAM_TYPE_METADATA)))) { 1408 continue; 1409 } 1410 1411 if ((pStream->isOrignalTypeOf(CAM_STREAM_TYPE_METADATA) 1412 && (mParameter.getManualCaptureMode() 1413 < CAM_MANUAL_CAPTURE_TYPE_3)) 1414 || (pStream->isTypeOf(CAM_STREAM_TYPE_ANALYSIS))) { 1415 // Skip metadata for reprocess now because PP module cannot handle meta data 1416 // May need furthur discussion if Imaginglib need meta data 1417 continue; 1418 } 1419 1420 // Update Metadata 1421 if (meta_buf != NULL) { 1422 uint32_t stream_id = frame->bufs[i]->stream_id; 1423 QCameraStream *srcStream = 1424 m_pSrcChannel->getStreamByHandle(stream_id); 1425 metadata_buffer_t *pMetaData = 1426 (metadata_buffer_t *)meta_buf->buffer; 1427 if ((NULL != pMetaData) && (NULL != srcStream)) { 1428 IF_META_AVAILABLE(cam_crop_data_t, crop, 1429 CAM_INTF_META_CROP_DATA, pMetaData) { 1430 if (MAX_NUM_STREAMS > crop->num_of_streams) { 1431 for (int j = 0; j < MAX_NUM_STREAMS; j++) { 1432 if (crop->crop_info[j].stream_id == 1433 srcStream->getMyServerID()) { 1434 // Store crop/roi information for offline reprocess 1435 // in the reprocess stream slot 1436 crop->crop_info[crop->num_of_streams].crop = 1437 crop->crop_info[j].crop; 1438 crop->crop_info[crop->num_of_streams].roi_map = 1439 crop->crop_info[j].roi_map; 1440 for (uint8_t k = 0; k < mStreams.size(); k++) { 1441 if (srcStream->getMyType() == 1442 mStreams[k]->getMyOriginalType()) { 1443 crop->crop_info[crop->num_of_streams].stream_id = 1444 mStreams[k]->getMyServerID(); 1445 break; 1446 } 1447 } 1448 crop->num_of_streams++; 1449 break; 1450 } 1451 } 1452 } else { 1453 LOGE("No space to add reprocess stream crop/roi information"); 1454 } 1455 } 1456 } 1457 } 1458 1459 rc = doReprocessOffline (frame->bufs[i], meta_buf, pStream); 1460 } 1461 } 1462 return rc; 1463 } 1464 1465 /*=========================================================================== 1466 * FUNCTION : doReprocess 1467 * 1468 * DESCRIPTION: request to do a reprocess on the frame 1469 * 1470 * PARAMETERS : 1471 * @frame : frame to be performed a reprocess 1472 * @mParameter : camera parameters 1473 * @pMetaStream: Metadata stream handle 1474 * @meta_buf_index : Metadata buffer index 1475 * 1476 * RETURN : int32_t type of status 1477 * NO_ERROR -- success 1478 * none-zero failure code 1479 *==========================================================================*/ 1480 int32_t QCameraReprocessChannel::doReprocess(mm_camera_super_buf_t *frame, 1481 QCameraParametersIntf &mParameter, QCameraStream *pMetaStream, 1482 uint8_t meta_buf_index) 1483 { 1484 int32_t rc = 0; 1485 if (mStreams.size() < 1) { 1486 LOGE("No reprocess streams"); 1487 return -1; 1488 } 1489 if (m_pSrcChannel == NULL) { 1490 LOGE("No source channel for reprocess"); 1491 return -1; 1492 } 1493 1494 if (pMetaStream == NULL) { 1495 LOGW("Null Metadata buffer for processing"); 1496 } 1497 1498 for (uint32_t i = 0; i < frame->num_bufs; i++) { 1499 QCameraStream *pStream = getStreamBySrouceHandle(frame->bufs[i]->stream_id); 1500 if ((pStream != NULL) && (m_handle == pStream->getChannelHandle())) { 1501 if (mParameter.getofflineRAW() && !((pStream->isOrignalTypeOf(CAM_STREAM_TYPE_RAW)) 1502 || (pStream->isOrignalTypeOf(CAM_STREAM_TYPE_POSTVIEW)) 1503 || (pStream->isOrignalTypeOf(CAM_STREAM_TYPE_METADATA)))) { 1504 //Skip all the stream other than RAW and POSTVIEW incase of offline of RAW 1505 continue; 1506 } 1507 if ((pStream->isOrignalTypeOf(CAM_STREAM_TYPE_METADATA) 1508 && (mParameter.getManualCaptureMode() 1509 < CAM_MANUAL_CAPTURE_TYPE_3)) 1510 || (pStream->isTypeOf(CAM_STREAM_TYPE_ANALYSIS))) { 1511 // Skip metadata for reprocess now because PP module cannot handle meta data 1512 // May need furthur discussion if Imaginglib need meta data 1513 continue; 1514 } 1515 1516 cam_stream_parm_buffer_t param; 1517 memset(¶m, 0, sizeof(cam_stream_parm_buffer_t)); 1518 param.type = CAM_STREAM_PARAM_TYPE_DO_REPROCESS; 1519 param.reprocess.buf_index = frame->bufs[i]->buf_idx; 1520 param.reprocess.frame_idx = frame->bufs[i]->frame_idx; 1521 if (pMetaStream != NULL) { 1522 // we have meta data frame bundled, sent together with reprocess frame 1523 param.reprocess.meta_present = 1; 1524 param.reprocess.meta_stream_handle = pMetaStream->getMyServerID(); 1525 param.reprocess.meta_buf_index = meta_buf_index; 1526 } 1527 1528 LOGI("Online reprocessing id = %d buf Id = %d meta index = %d type = %d", 1529 param.reprocess.frame_idx, param.reprocess.buf_index, 1530 param.reprocess.meta_buf_index, pStream->getMyOriginalType()); 1531 1532 rc = pStream->setParameter(param); 1533 if (rc != NO_ERROR) { 1534 LOGE("stream setParameter for reprocess failed"); 1535 break; 1536 } 1537 } 1538 } 1539 return rc; 1540 } 1541 1542 /*=========================================================================== 1543 * FUNCTION : doReprocess 1544 * 1545 * DESCRIPTION: request to do a reprocess on the frame 1546 * 1547 * PARAMETERS : 1548 * @buf_fd : fd to the input buffer that needs reprocess 1549 * @buffer : buffer pointer of actual buffer 1550 * @buf_lenght : length of the input buffer 1551 * @ret_val : result of reprocess. 1552 * Example: Could be faceID in case of register face image. 1553 * 1554 * RETURN : int32_t type of status 1555 * NO_ERROR -- success 1556 * none-zero failure code 1557 *==========================================================================*/ 1558 int32_t QCameraReprocessChannel::doReprocess(int buf_fd, void *buffer, 1559 size_t buf_length, int32_t &ret_val) 1560 { 1561 int32_t rc = 0; 1562 if (mStreams.size() < 1) { 1563 LOGE("No reprocess streams"); 1564 return -1; 1565 } 1566 1567 uint32_t buf_idx = 0; 1568 for (size_t i = 0; i < mStreams.size(); i++) { 1569 if ((mStreams[i] != NULL) && 1570 (m_handle != mStreams[i]->getChannelHandle())) { 1571 continue; 1572 } 1573 rc = mStreams[i]->mapBuf(CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF, 1574 buf_idx, -1, 1575 buf_fd, buffer, buf_length); 1576 1577 if (rc == NO_ERROR) { 1578 cam_stream_parm_buffer_t param; 1579 memset(¶m, 0, sizeof(cam_stream_parm_buffer_t)); 1580 param.type = CAM_STREAM_PARAM_TYPE_DO_REPROCESS; 1581 param.reprocess.buf_index = buf_idx; 1582 rc = mStreams[i]->setParameter(param); 1583 if (rc == NO_ERROR) { 1584 ret_val = param.reprocess.ret_val; 1585 } 1586 mStreams[i]->unmapBuf(CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF, 1587 buf_idx, -1); 1588 } 1589 } 1590 return rc; 1591 } 1592 1593 }; // namespace qcamera 1594