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 38extern "C" { 39#include "mm_camera_dbg.h" 40} 41 42using namespace android; 43 44namespace 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 *==========================================================================*/ 57QCameraChannel::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 *==========================================================================*/ 77QCameraChannel::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 *==========================================================================*/ 95QCameraChannel::~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 *==========================================================================*/ 121void 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 *==========================================================================*/ 147int32_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 *==========================================================================*/ 174int32_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 *==========================================================================*/ 209int32_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 *==========================================================================*/ 262int32_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 *==========================================================================*/ 295int32_t QCameraChannel::start() 296{ 297 int32_t rc = NO_ERROR; 298 299 if (mStreams.size() > 1) { 300 // there is more than one stream in the channel 301 // we need to notify mctl that all streams in this channel need to be bundled 302 cam_bundle_config_t bundleInfo; 303 memset(&bundleInfo, 0, sizeof(bundleInfo)); 304 rc = m_camOps->get_bundle_info(m_camHandle, m_handle, &bundleInfo); 305 if (rc != NO_ERROR) { 306 LOGE("get_bundle_info failed"); 307 return rc; 308 } 309 if (bundleInfo.num_of_streams > 1) { 310 for (int i = 0; i < bundleInfo.num_of_streams; i++) { 311 QCameraStream *pStream = getStreamByServerID(bundleInfo.stream_ids[i]); 312 if (pStream != NULL) { 313 if ((pStream->isTypeOf(CAM_STREAM_TYPE_METADATA)) 314 || (pStream->isTypeOf(CAM_STREAM_TYPE_OFFLINE_PROC))) { 315 // Skip metadata for reprocess now because PP module cannot handle meta data 316 // May need furthur discussion if Imaginglib need meta data 317 continue; 318 } 319 320 cam_stream_parm_buffer_t param; 321 memset(¶m, 0, sizeof(cam_stream_parm_buffer_t)); 322 param.type = CAM_STREAM_PARAM_TYPE_SET_BUNDLE_INFO; 323 param.bundleInfo = bundleInfo; 324 rc = pStream->setParameter(param); 325 if (rc != NO_ERROR) { 326 LOGE("stream setParameter for set bundle failed"); 327 return rc; 328 } 329 } 330 } 331 } 332 } 333 334 for (size_t i = 0; i < mStreams.size(); i++) { 335 if ((mStreams[i] != NULL) && 336 (m_handle == mStreams[i]->getChannelHandle())) { 337 mStreams[i]->start(); 338 } 339 } 340 rc = m_camOps->start_channel(m_camHandle, m_handle); 341 342 if (rc != NO_ERROR) { 343 for (size_t i = 0; i < mStreams.size(); i++) { 344 if ((mStreams[i] != NULL) && 345 (m_handle == mStreams[i]->getChannelHandle())) { 346 mStreams[i]->stop(); 347 } 348 } 349 } else { 350 m_bIsActive = true; 351 for (size_t i = 0; i < mStreams.size(); i++) { 352 if (mStreams[i] != NULL) { 353 mStreams[i]->cond_signal(); 354 } 355 } 356 } 357 358 return rc; 359} 360 361/*=========================================================================== 362 * FUNCTION : stop 363 * 364 * DESCRIPTION: stop a channel, which will stop all streams belong to this channel 365 * 366 * PARAMETERS : none 367 * 368 * RETURN : int32_t type of status 369 * NO_ERROR -- success 370 * none-zero failure code 371 *==========================================================================*/ 372int32_t QCameraChannel::stop() 373{ 374 int32_t rc = NO_ERROR; 375 size_t i = 0; 376 377 if (!m_bIsActive) { 378 return NO_INIT; 379 } 380 381 while(i < mStreams.size()) { 382 if (mStreams[i] != NULL) { 383 if (m_handle == mStreams[i]->getChannelHandle()) { 384 mStreams[i]->stop(); 385 i++; 386 } else { 387 // Remove linked stream from stream list 388 mStreams.removeAt(i); 389 } 390 } 391 } 392 393 rc = m_camOps->stop_channel(m_camHandle, m_handle); 394 395 m_bIsActive = false; 396 return rc; 397} 398 399/*=========================================================================== 400 * FUNCTION : bufDone 401 * 402 * DESCRIPTION: return a stream buf back to kernel 403 * 404 * PARAMETERS : 405 * @recvd_frame : stream buf frame to be returned 406 * 407 * RETURN : int32_t type of status 408 * NO_ERROR -- success 409 * none-zero failure code 410 *==========================================================================*/ 411int32_t QCameraChannel::bufDone(mm_camera_super_buf_t *recvd_frame) 412{ 413 int32_t rc = NO_ERROR; 414 for (uint32_t i = 0; i < recvd_frame->num_bufs; i++) { 415 if (recvd_frame->bufs[i] != NULL) { 416 for (size_t j = 0; j < mStreams.size(); j++) { 417 if (mStreams[j] != NULL && 418 mStreams[j]->getMyHandle() == recvd_frame->bufs[i]->stream_id) { 419 rc = mStreams[j]->bufDone(recvd_frame->bufs[i]->buf_idx); 420 break; // break loop j 421 } 422 } 423 } 424 } 425 426 return rc; 427} 428 429/*=========================================================================== 430 * FUNCTION : bufDone 431 * 432 * DESCRIPTION: return specified buffer from super buffer to kernel 433 * 434 * PARAMETERS : 435 * @recvd_frame : stream buf frame to be returned 436 * @stream_id : stream ID of the buffer to be released 437 * 438 * RETURN : int32_t type of status 439 * NO_ERROR -- success 440 * none-zero failure code 441 *==========================================================================*/ 442int32_t QCameraChannel::bufDone(mm_camera_super_buf_t *recvd_frame, uint32_t stream_id) 443{ 444 int32_t rc = NO_ERROR; 445 int32_t index; 446 for (int32_t i = 0; i < (int32_t)recvd_frame->num_bufs; i++) { 447 index = -1; 448 if ((recvd_frame->bufs[i] != NULL) && 449 (recvd_frame->bufs[i]->stream_id == stream_id)) { 450 for (size_t j = 0; j < mStreams.size(); j++) { 451 if ((mStreams[j] != NULL) && 452 (mStreams[j]->getMyHandle() == stream_id)) { 453 rc = mStreams[j]->bufDone(recvd_frame->bufs[i]->buf_idx); 454 index = i; 455 break; // break loop j 456 } 457 } 458 if ((index >= 0) && (index < (int32_t)recvd_frame->num_bufs)) { 459 for (int32_t j = index; j < (int32_t)(recvd_frame->num_bufs - 1); j++) { 460 recvd_frame->bufs[j] = recvd_frame->bufs[j + 1]; 461 } 462 recvd_frame->num_bufs--; 463 i--; 464 } 465 } 466 } 467 468 return rc; 469} 470 471/*=========================================================================== 472 * FUNCTION : processZoomDone 473 * 474 * DESCRIPTION: process zoom done event 475 * 476 * PARAMETERS : 477 * @previewWindoe : ptr to preview window ops table, needed to set preview 478 * crop information 479 * @crop_info : crop info as a result of zoom operation 480 * 481 * RETURN : int32_t type of status 482 * NO_ERROR -- success 483 * none-zero failure code 484 *==========================================================================*/ 485int32_t QCameraChannel::processZoomDone(preview_stream_ops_t *previewWindow, 486 cam_crop_data_t &crop_info) 487{ 488 int32_t rc = NO_ERROR; 489 for (size_t i = 0; i < mStreams.size(); i++) { 490 if ((mStreams[i] != NULL) && 491 (m_handle == mStreams[i]->getChannelHandle())) { 492 rc = mStreams[i]->processZoomDone(previewWindow, crop_info); 493 } 494 } 495 return rc; 496} 497 498/*=========================================================================== 499 * FUNCTION : getStreamByHandle 500 * 501 * DESCRIPTION: return stream object by stream handle 502 * 503 * PARAMETERS : 504 * @streamHandle : stream handle 505 * 506 * RETURN : stream object. NULL if not found 507 *==========================================================================*/ 508QCameraStream *QCameraChannel::getStreamByHandle(uint32_t streamHandle) 509{ 510 for (size_t i = 0; i < mStreams.size(); i++) { 511 if (mStreams[i] != NULL && mStreams[i]->getMyHandle() == streamHandle) { 512 return mStreams[i]; 513 } 514 } 515 return NULL; 516} 517 518/*=========================================================================== 519 * FUNCTION : getStreamByServerID 520 * 521 * DESCRIPTION: return stream object by stream server ID from daemon 522 * 523 * PARAMETERS : 524 * @serverID : stream server ID 525 * 526 * RETURN : stream object. NULL if not found 527 *==========================================================================*/ 528QCameraStream *QCameraChannel::getStreamByServerID(uint32_t serverID) 529{ 530 for (size_t i = 0; i < mStreams.size(); i++) { 531 if (mStreams[i] != NULL && mStreams[i]->getMyServerID() == serverID) { 532 return mStreams[i]; 533 } 534 } 535 return NULL; 536} 537 538/*=========================================================================== 539 * FUNCTION : getStreamByIndex 540 * 541 * DESCRIPTION: return stream object by index of streams in the channel 542 * 543 * PARAMETERS : 544 * @index : index of stream in the channel 545 * 546 * RETURN : stream object. NULL if not found 547 *==========================================================================*/ 548QCameraStream *QCameraChannel::getStreamByIndex(uint32_t index) 549{ 550 if (index >= MAX_STREAM_NUM_IN_BUNDLE) { 551 return NULL; 552 } 553 554 if (index < mStreams.size()) { 555 return mStreams[index]; 556 } 557 return NULL; 558} 559 560/*=========================================================================== 561 * FUNCTION : UpdateStreamBasedParameters 562 * 563 * DESCRIPTION: update any stream based settings from parameters 564 * 565 * PARAMETERS : 566 * @param : reference to parameters object 567 * 568 * RETURN : int32_t type of status 569 * NO_ERROR -- success 570 * none-zero failure code 571 *==========================================================================*/ 572int32_t QCameraChannel::UpdateStreamBasedParameters(QCameraParametersIntf ¶m) 573{ 574 int32_t rc = NO_ERROR; 575 if (param.isPreviewFlipChanged()) { 576 // try to find preview stream 577 for (size_t i = 0; i < mStreams.size(); i++) { 578 if ((mStreams[i] != NULL) && 579 (m_handle == mStreams[i]->getChannelHandle()) && 580 (mStreams[i]->isTypeOf(CAM_STREAM_TYPE_PREVIEW) || 581 (mStreams[i]->isOrignalTypeOf(CAM_STREAM_TYPE_PREVIEW))) ) { 582 cam_stream_parm_buffer_t param_buf; 583 memset(¶m_buf, 0, sizeof(cam_stream_parm_buffer_t)); 584 param_buf.type = CAM_STREAM_PARAM_TYPE_SET_FLIP; 585 param_buf.flipInfo.flip_mask = 586 (uint32_t)param.getFlipMode(CAM_STREAM_TYPE_PREVIEW); 587 rc = mStreams[i]->setParameter(param_buf); 588 if (rc != NO_ERROR) { 589 LOGW("set preview stream flip failed"); 590 } 591 } 592 } 593 } 594 if (param.isVideoFlipChanged()) { 595 // try to find video stream 596 for (size_t i = 0; i < mStreams.size(); i++) { 597 if ((mStreams[i] != NULL) && 598 (m_handle == mStreams[i]->getChannelHandle()) && 599 (mStreams[i]->isTypeOf(CAM_STREAM_TYPE_VIDEO) || 600 (mStreams[i]->isOrignalTypeOf(CAM_STREAM_TYPE_VIDEO))) ) { 601 cam_stream_parm_buffer_t param_buf; 602 memset(¶m_buf, 0, sizeof(cam_stream_parm_buffer_t)); 603 param_buf.type = CAM_STREAM_PARAM_TYPE_SET_FLIP; 604 param_buf.flipInfo.flip_mask = 605 (uint32_t)param.getFlipMode(CAM_STREAM_TYPE_VIDEO); 606 rc = mStreams[i]->setParameter(param_buf); 607 if (rc != NO_ERROR) { 608 LOGW("set video stream flip failed"); 609 } 610 } 611 } 612 } 613 if (param.isSnapshotFlipChanged()) { 614 // try to find snapshot/postview stream 615 for (size_t i = 0; i < mStreams.size(); i++) { 616 if (mStreams[i] != NULL && 617 (m_handle == mStreams[i]->getChannelHandle()) && 618 (mStreams[i]->isTypeOf(CAM_STREAM_TYPE_SNAPSHOT) || 619 mStreams[i]->isOrignalTypeOf(CAM_STREAM_TYPE_SNAPSHOT) || 620 mStreams[i]->isTypeOf(CAM_STREAM_TYPE_POSTVIEW) || 621 mStreams[i]->isOrignalTypeOf(CAM_STREAM_TYPE_POSTVIEW) ) ) { 622 cam_stream_parm_buffer_t param_buf; 623 memset(¶m_buf, 0, sizeof(cam_stream_parm_buffer_t)); 624 param_buf.type = CAM_STREAM_PARAM_TYPE_SET_FLIP; 625 param_buf.flipInfo.flip_mask = 626 (uint32_t)param.getFlipMode(CAM_STREAM_TYPE_SNAPSHOT); 627 rc = mStreams[i]->setParameter(param_buf); 628 if (rc != NO_ERROR) { 629 LOGW("set snapshot stream flip failed"); 630 } 631 } 632 } 633 } 634 return rc; 635} 636 637/*=========================================================================== 638 * FUNCTION : QCameraPicChannel 639 * 640 * DESCRIPTION: constructor of QCameraPicChannel 641 * 642 * PARAMETERS : 643 * @cam_handle : camera handle 644 * @cam_ops : ptr to camera ops table 645 * 646 * RETURN : none 647 *==========================================================================*/ 648QCameraPicChannel::QCameraPicChannel(uint32_t cam_handle, 649 mm_camera_ops_t *cam_ops) : 650 QCameraChannel(cam_handle, cam_ops) 651{ 652 m_bAllowDynBufAlloc = true; 653} 654 655/*=========================================================================== 656 * FUNCTION : QCameraPicChannel 657 * 658 * DESCRIPTION: default constructor of QCameraPicChannel 659 * 660 * PARAMETERS : none 661 * 662 * RETURN : none 663 *==========================================================================*/ 664QCameraPicChannel::QCameraPicChannel() 665{ 666 m_bAllowDynBufAlloc = true; 667} 668 669/*=========================================================================== 670 * FUNCTION : ~QCameraPicChannel 671 * 672 * DESCRIPTION: destructor of QCameraPicChannel 673 * 674 * PARAMETERS : none 675 * 676 * RETURN : none 677 *==========================================================================*/ 678QCameraPicChannel::~QCameraPicChannel() 679{ 680} 681 682/*=========================================================================== 683 * FUNCTION : takePicture 684 * 685 * DESCRIPTION: send request for queued snapshot frames 686 * 687 * PARAMETERS : 688 * @buf : request buf info 689 * 690 * RETURN : int32_t type of status 691 * NO_ERROR -- success 692 * none-zero failure code 693 *==========================================================================*/ 694int32_t QCameraPicChannel::takePicture (mm_camera_req_buf_t *buf) 695{ 696 int32_t rc = m_camOps->request_super_buf(m_camHandle, m_handle, buf); 697 return rc; 698} 699 700/*=========================================================================== 701 * FUNCTION : cancelPicture 702 * 703 * DESCRIPTION: cancel request for queued snapshot frames 704 * 705 * PARAMETERS : none 706 * 707 * RETURN : int32_t type of status 708 * NO_ERROR -- success 709 * none-zero failure code 710 *==========================================================================*/ 711int32_t QCameraPicChannel::cancelPicture() 712{ 713 int32_t rc = m_camOps->cancel_super_buf_request(m_camHandle, m_handle); 714 return rc; 715} 716 717/*=========================================================================== 718 * FUNCTION : stopAdvancedCapture 719 * 720 * DESCRIPTION: stop advanced capture based on advanced capture type. 721 * 722 * PARAMETERS : 723 * @type : advanced capture type. 724 * 725 * RETURN : int32_t type of status 726 * NO_ERROR -- success 727 * none-zero failure code 728 *==========================================================================*/ 729int32_t QCameraPicChannel::stopAdvancedCapture(mm_camera_advanced_capture_t type) 730{ 731 int32_t rc = m_camOps->process_advanced_capture(m_camHandle, 732 m_handle, type, 0, NULL); 733 return rc; 734} 735 736/*=========================================================================== 737 * FUNCTION : startAdvancedCapture 738 * 739 * DESCRIPTION: start advanced capture based on advanced capture type. 740 * 741 * PARAMETERS : 742 * @type : advanced capture type. 743 * @config: advance capture config 744 * 745 * RETURN : int32_t type of status 746 * NO_ERROR -- success 747 * none-zero failure code 748 *==========================================================================*/ 749int32_t QCameraPicChannel::startAdvancedCapture(mm_camera_advanced_capture_t type, 750 cam_capture_frame_config_t *config) 751{ 752 int32_t rc = NO_ERROR; 753 754 rc = m_camOps->process_advanced_capture(m_camHandle, m_handle, type, 755 1, config); 756 return rc; 757} 758 759/*=========================================================================== 760* FUNCTION : flushSuperbuffer 761 * 762 * DESCRIPTION: flush the all superbuffer frames. 763 * 764 * PARAMETERS : 765 * @frame_idx : frame index of focused frame 766 * 767 * RETURN : int32_t type of status 768 * NO_ERROR -- success 769 * none-zero failure code 770 *==========================================================================*/ 771int32_t QCameraPicChannel::flushSuperbuffer(uint32_t frame_idx) 772{ 773 int32_t rc = m_camOps->flush_super_buf_queue(m_camHandle, m_handle, frame_idx); 774 return rc; 775} 776 777/*=========================================================================== 778 * FUNCTION : QCameraVideoChannel 779 * 780 * DESCRIPTION: constructor of QCameraVideoChannel 781 * 782 * PARAMETERS : 783 * @cam_handle : camera handle 784 * @cam_ops : ptr to camera ops table 785 * 786 * RETURN : none 787 *==========================================================================*/ 788QCameraVideoChannel::QCameraVideoChannel(uint32_t cam_handle, 789 mm_camera_ops_t *cam_ops) : 790 QCameraChannel(cam_handle, cam_ops) 791{ 792} 793 794/*=========================================================================== 795 * FUNCTION : QCameraVideoChannel 796 * 797 * DESCRIPTION: default constructor of QCameraVideoChannel 798 * 799 * PARAMETERS : none 800 * 801 * RETURN : none 802 *==========================================================================*/ 803QCameraVideoChannel::QCameraVideoChannel() 804{ 805} 806 807/*=========================================================================== 808 * FUNCTION : ~QCameraVideoChannel 809 * 810 * DESCRIPTION: destructor of QCameraVideoChannel 811 * 812 * PARAMETERS : none 813 * 814 * RETURN : none 815 *==========================================================================*/ 816QCameraVideoChannel::~QCameraVideoChannel() 817{ 818} 819 820/*=========================================================================== 821 * FUNCTION : takePicture 822 * 823 * DESCRIPTION: send request for queued snapshot frames 824 * 825 * PARAMETERS : 826 * @mm_camera_req_buf_t : request buf info 827 * 828 * RETURN : int32_t type of status 829 * NO_ERROR -- success 830 * none-zero failure code 831 *==========================================================================*/ 832int32_t QCameraVideoChannel::takePicture(mm_camera_req_buf_t *buf) 833{ 834 int32_t rc = m_camOps->request_super_buf(m_camHandle, m_handle, buf); 835 return rc; 836} 837 838/*=========================================================================== 839 * FUNCTION : cancelPicture 840 * 841 * DESCRIPTION: cancel request for queued snapshot frames 842 * 843 * PARAMETERS : none 844 * 845 * RETURN : int32_t type of status 846 * NO_ERROR -- success 847 * none-zero failure code 848 *==========================================================================*/ 849int32_t QCameraVideoChannel::cancelPicture() 850{ 851 int32_t rc = m_camOps->cancel_super_buf_request(m_camHandle, m_handle); 852 return rc; 853} 854 855/*=========================================================================== 856 * FUNCTION : releaseFrame 857 * 858 * DESCRIPTION: return video frame from app 859 * 860 * PARAMETERS : 861 * @opaque : ptr to video frame to be returned 862 * @isMetaData : if frame is a metadata or real frame 863 * 864 * RETURN : int32_t type of status 865 * NO_ERROR -- success 866 * none-zero failure code 867 *==========================================================================*/ 868int32_t QCameraVideoChannel::releaseFrame(const void * opaque, bool isMetaData) 869{ 870 QCameraStream *pVideoStream = NULL; 871 for (size_t i = 0; i < mStreams.size(); i++) { 872 if (mStreams[i] != NULL && mStreams[i]->isTypeOf(CAM_STREAM_TYPE_VIDEO)) { 873 pVideoStream = mStreams[i]; 874 break; 875 } 876 } 877 878 if (NULL == pVideoStream) { 879 LOGE("No video stream in the channel"); 880 return BAD_VALUE; 881 } 882 883 int32_t rc = pVideoStream->bufDone(opaque, isMetaData); 884 return rc; 885} 886 887/*=========================================================================== 888 * FUNCTION : QCameraReprocessChannel 889 * 890 * DESCRIPTION: constructor of QCameraReprocessChannel 891 * 892 * PARAMETERS : 893 * @cam_handle : camera handle 894 * @cam_ops : ptr to camera ops table 895 * @pp_mask : post-proccess feature mask 896 * 897 * RETURN : none 898 *==========================================================================*/ 899QCameraReprocessChannel::QCameraReprocessChannel(uint32_t cam_handle, 900 mm_camera_ops_t *cam_ops) : 901 QCameraChannel(cam_handle, cam_ops), 902 m_pSrcChannel(NULL), 903 mPassCount(0) 904{ 905 memset(mSrcStreamHandles, 0, sizeof(mSrcStreamHandles)); 906} 907 908/*=========================================================================== 909 * FUNCTION : QCameraReprocessChannel 910 * 911 * DESCRIPTION: default constructor of QCameraReprocessChannel 912 * 913 * PARAMETERS : none 914 * 915 * RETURN : none 916 *==========================================================================*/ 917QCameraReprocessChannel::QCameraReprocessChannel() : 918 m_pSrcChannel(NULL), 919 mPassCount(0) 920{ 921} 922 923/*=========================================================================== 924 * FUNCTION : ~QCameraReprocessChannel 925 * 926 * DESCRIPTION: destructor of QCameraReprocessChannel 927 * 928 * PARAMETERS : none 929 * 930 * RETURN : none 931 *==========================================================================*/ 932QCameraReprocessChannel::~QCameraReprocessChannel() 933{ 934} 935 936/*=========================================================================== 937 * FUNCTION : addReprocStreamsFromSource 938 * 939 * DESCRIPTION: add reprocess streams from input source channel 940 * 941 * PARAMETERS : 942 * @allocator : stream related buffer allocator 943 * @featureConfig : pp feature configuration 944 * @pSrcChannel : ptr to input source channel that needs reprocess 945 * @minStreamBufNum: number of stream buffers needed 946 * @burstNum : number of burst captures needed 947 * @paddingInfo : padding information 948 * @param : reference to parameters 949 * @contStream : continous streaming mode or burst 950 * @offline : configure for offline reprocessing 951 * 952 * RETURN : int32_t type of status 953 * NO_ERROR -- success 954 * none-zero failure code 955 *==========================================================================*/ 956int32_t QCameraReprocessChannel::addReprocStreamsFromSource( 957 QCameraAllocator& allocator, cam_pp_feature_config_t &featureConfig, 958 QCameraChannel *pSrcChannel, uint8_t minStreamBufNum, uint8_t burstNum, 959 cam_padding_info_t *paddingInfo, QCameraParametersIntf ¶m, bool contStream, 960 bool offline) 961{ 962 int32_t rc = 0; 963 QCameraStream *pStream = NULL; 964 QCameraHeapMemory *pStreamInfoBuf = NULL; 965 QCameraHeapMemory *pMiscBuf = NULL; 966 cam_stream_info_t *streamInfo = NULL; 967 cam_padding_info_t padding; 968 969 memset(mSrcStreamHandles, 0, sizeof(mSrcStreamHandles)); 970 if (NULL == paddingInfo) { 971 return BAD_VALUE; 972 } 973 padding = *paddingInfo; 974 //Use maximum padding so that the buffer 975 //can be rotated 976 padding.width_padding = MAX(padding.width_padding, padding.height_padding); 977 padding.height_padding = padding.width_padding; 978 padding.offset_info.offset_x = 0; 979 padding.offset_info.offset_y = 0; 980 981 LOGD("num of src stream = %d", pSrcChannel->getNumOfStreams()); 982 983 for (uint32_t i = 0; i < pSrcChannel->getNumOfStreams(); i++) { 984 cam_pp_feature_config_t pp_featuremask = featureConfig; 985 pStream = pSrcChannel->getStreamByIndex(i); 986 if (pStream != NULL) { 987 if (param.getofflineRAW() && !((pStream->isTypeOf(CAM_STREAM_TYPE_RAW)) 988 || (pStream->isTypeOf(CAM_STREAM_TYPE_POSTVIEW)) 989 || (pStream->isTypeOf(CAM_STREAM_TYPE_METADATA)) 990 || (pStream->isOrignalTypeOf(CAM_STREAM_TYPE_RAW)))) { 991 //Skip all the stream other than RAW and POSTVIEW incase of offline of RAW 992 continue; 993 } 994 995 if (pStream->isTypeOf(CAM_STREAM_TYPE_RAW) 996 && (!param.getofflineRAW())) { 997 // Skip raw for reprocess now because PP module cannot handle 998 // meta data&raw. May need furthur discussion if Imaginglib need meta data 999 continue; 1000 } 1001 1002 if (((pStream->isTypeOf(CAM_STREAM_TYPE_METADATA)) 1003 && !(param.getManualCaptureMode() >= 1004 CAM_MANUAL_CAPTURE_TYPE_3)) 1005 || (pStream->isTypeOf(CAM_STREAM_TYPE_ANALYSIS))) { 1006 // Skip metadata 1007 continue; 1008 } 1009 1010 if (pStream->isTypeOf(CAM_STREAM_TYPE_PREVIEW) || 1011 pStream->isTypeOf(CAM_STREAM_TYPE_POSTVIEW) || 1012 pStream->isOrignalTypeOf(CAM_STREAM_TYPE_PREVIEW) || 1013 pStream->isOrignalTypeOf(CAM_STREAM_TYPE_POSTVIEW)) { 1014 uint32_t feature_mask = featureConfig.feature_mask; 1015 1016 // skip thumbnail reprocessing if not needed 1017 if (!param.needThumbnailReprocess(&feature_mask)) { 1018 continue; 1019 } 1020 // CAC, SHARPNESS, FLIP and WNR would have been already applied - 1021 // on preview/postview stream in realtime. 1022 // So, need not apply again. 1023 feature_mask &= ~(CAM_QCOM_FEATURE_DENOISE2D | 1024 CAM_QCOM_FEATURE_CAC | 1025 CAM_QCOM_FEATURE_SHARPNESS | 1026 CAM_QCOM_FEATURE_FLIP | 1027 CAM_QCOM_FEATURE_RAW_PROCESSING); 1028 if (!feature_mask) { 1029 // Skip thumbnail stream reprocessing since no other 1030 //reprocessing is enabled. 1031 continue; 1032 } 1033 } 1034 1035 if (pStream->isTypeOf(CAM_STREAM_TYPE_METADATA)) { 1036 pp_featuremask.feature_mask = 0; 1037 pp_featuremask.feature_mask |= CAM_QCOM_FEATURE_METADATA_PROCESSING; 1038 } 1039 1040 pStreamInfoBuf = allocator.allocateStreamInfoBuf(CAM_STREAM_TYPE_OFFLINE_PROC); 1041 if (pStreamInfoBuf == NULL) { 1042 LOGE("no mem for stream info buf"); 1043 rc = NO_MEMORY; 1044 break; 1045 } 1046 1047 streamInfo = (cam_stream_info_t *)pStreamInfoBuf->getPtr(0); 1048 memset(streamInfo, 0, sizeof(cam_stream_info_t)); 1049 streamInfo->stream_type = CAM_STREAM_TYPE_OFFLINE_PROC; 1050 // Enable CPP high performance mode to put it in turbo frequency mode for 1051 // burst/longshot/HDR snapshot cases 1052 streamInfo->perf_mode = CAM_PERF_HIGH_PERFORMANCE; 1053 if (param.getofflineRAW() && pStream->isTypeOf(CAM_STREAM_TYPE_RAW)) { 1054 streamInfo->fmt = CAM_FORMAT_YUV_420_NV21; 1055 } else { 1056 rc = pStream->getFormat(streamInfo->fmt); 1057 } 1058 1059 if (pStream->isTypeOf(CAM_STREAM_TYPE_POSTVIEW) || 1060 pStream->isTypeOf(CAM_STREAM_TYPE_PREVIEW)) { 1061 param.getThumbnailSize(&(streamInfo->dim.width), &(streamInfo->dim.height)); 1062 } else { 1063 if ((param.isPostProcScaling()) && 1064 (pp_featuremask.feature_mask & CAM_QCOM_FEATURE_SCALE)) { 1065 rc = param.getStreamDimension(CAM_STREAM_TYPE_OFFLINE_PROC, 1066 streamInfo->dim); 1067 } else if ((param.getofflineRAW()) && 1068 (pStream->isTypeOf(CAM_STREAM_TYPE_RAW))) { 1069 param.getStreamDimension(CAM_STREAM_TYPE_SNAPSHOT,streamInfo->dim); 1070 } else { 1071 rc = pStream->getFrameDimension(streamInfo->dim); 1072 } 1073 } 1074 1075 if ( contStream ) { 1076 streamInfo->streaming_mode = CAM_STREAMING_MODE_CONTINUOUS; 1077 streamInfo->num_of_burst = 0; 1078 } else { 1079 streamInfo->streaming_mode = CAM_STREAMING_MODE_BURST; 1080 streamInfo->num_of_burst = burstNum; 1081 } 1082 streamInfo->num_bufs = minStreamBufNum; 1083 1084 cam_stream_reproc_config_t rp_cfg; 1085 memset(&rp_cfg, 0, sizeof(cam_stream_reproc_config_t)); 1086 if (offline) { 1087 cam_frame_len_offset_t offset; 1088 memset(&offset, 0, sizeof(cam_frame_len_offset_t)); 1089 1090 rp_cfg.pp_type = CAM_OFFLINE_REPROCESS_TYPE; 1091 pStream->getFormat(rp_cfg.offline.input_fmt); 1092 pStream->getFrameDimension(rp_cfg.offline.input_dim); 1093 pStream->getFrameOffset(offset); 1094 rp_cfg.offline.input_buf_planes.plane_info = offset; 1095 rp_cfg.offline.input_type = pStream->getMyOriginalType(); 1096 //For input metadata + input buffer 1097 rp_cfg.offline.num_of_bufs = 2; 1098 } else { 1099 rp_cfg.pp_type = CAM_ONLINE_REPROCESS_TYPE; 1100 rp_cfg.online.input_stream_id = pStream->getMyServerID(); 1101 rp_cfg.online.input_stream_type = pStream->getMyOriginalType(); 1102 } 1103 param.getStreamRotation(streamInfo->stream_type, 1104 streamInfo->pp_config, streamInfo->dim); 1105 streamInfo->reprocess_config = rp_cfg; 1106 streamInfo->reprocess_config.pp_feature_config = pp_featuremask; 1107 1108 if (!(pStream->isTypeOf(CAM_STREAM_TYPE_SNAPSHOT) 1109 || pStream->isOrignalTypeOf(CAM_STREAM_TYPE_SNAPSHOT) 1110 || pStream->isTypeOf(CAM_STREAM_TYPE_RAW) 1111 || pStream->isOrignalTypeOf(CAM_STREAM_TYPE_RAW))) { 1112 // CAC, SHARPNESS, FLIP and WNR would have been already applied - 1113 // on preview/postview stream in realtime. Need not apply again. 1114 streamInfo->reprocess_config.pp_feature_config.feature_mask &= 1115 ~CAM_QCOM_FEATURE_CAC; 1116 streamInfo->reprocess_config.pp_feature_config.feature_mask &= 1117 ~CAM_QCOM_FEATURE_SHARPNESS; 1118 streamInfo->reprocess_config.pp_feature_config.feature_mask &= 1119 ~CAM_QCOM_FEATURE_FLIP; 1120 //Don't do WNR for thumbnail 1121 streamInfo->reprocess_config.pp_feature_config.feature_mask &= 1122 ~CAM_QCOM_FEATURE_DENOISE2D; 1123 streamInfo->reprocess_config.pp_feature_config.feature_mask &= 1124 ~CAM_QCOM_FEATURE_CDS; 1125 streamInfo->reprocess_config.pp_feature_config.feature_mask &= 1126 ~CAM_QCOM_FEATURE_DSDN; 1127 //No need of RAW processing for other than RAW streams 1128 streamInfo->reprocess_config.pp_feature_config.feature_mask &= 1129 ~CAM_QCOM_FEATURE_RAW_PROCESSING; 1130 1131 if (param.isHDREnabled() 1132 && !param.isHDRThumbnailProcessNeeded()){ 1133 streamInfo->reprocess_config.pp_feature_config.feature_mask 1134 &= ~CAM_QCOM_FEATURE_HDR; 1135 } 1136 } 1137 1138 cam_stream_type_t type = CAM_STREAM_TYPE_DEFAULT; 1139 if (offline) { 1140 type = streamInfo->reprocess_config.offline.input_type; 1141 } else { 1142 type = streamInfo->reprocess_config.online.input_stream_type; 1143 } 1144 if (type == CAM_STREAM_TYPE_SNAPSHOT) { 1145 int flipMode = param.getFlipMode(type); 1146 if (flipMode > 0) { 1147 streamInfo->reprocess_config.pp_feature_config.feature_mask |= 1148 CAM_QCOM_FEATURE_FLIP; 1149 streamInfo->reprocess_config.pp_feature_config.flip = (uint32_t)flipMode; 1150 } 1151 } 1152 1153 if ((streamInfo->reprocess_config.pp_feature_config.feature_mask 1154 & CAM_QCOM_FEATURE_SCALE) 1155 && param.isReprocScaleEnabled() 1156 && param.isUnderReprocScaling()) { 1157 //we only Scale Snapshot frame 1158 if (pStream->isTypeOf(CAM_STREAM_TYPE_SNAPSHOT)) { 1159 streamInfo->dim.width = 1160 streamInfo->reprocess_config.pp_feature_config.scale_param.output_width; 1161 streamInfo->dim.height = 1162 streamInfo->reprocess_config.pp_feature_config.scale_param.output_height; 1163 } 1164 LOGH("stream width=%d, height=%d.", 1165 streamInfo->dim.width, streamInfo->dim.height); 1166 } 1167 1168 // save source stream handler 1169 mSrcStreamHandles[mStreams.size()] = pStream->getMyHandle(); 1170 1171 pMiscBuf = allocator.allocateMiscBuf(streamInfo); 1172 1173 LOGH("Configure Reprocessing: stream = %d, res = %dX%d, fmt = %d, type = %d", 1174 pStream->getMyOriginalType(), streamInfo->dim.width, 1175 streamInfo->dim.height, streamInfo->fmt, type); 1176 1177 // add reprocess stream 1178 if (streamInfo->reprocess_config.pp_feature_config.feature_mask 1179 & CAM_QCOM_FEATURE_ROTATION) { 1180 rc = addStream(allocator, pStreamInfoBuf, pMiscBuf, 1181 minStreamBufNum, &padding, NULL, NULL, false, false, 1182 streamInfo->reprocess_config.pp_feature_config.rotation); 1183 } else { 1184 rc = addStream(allocator, pStreamInfoBuf, pMiscBuf, 1185 minStreamBufNum, &padding, NULL, NULL, false, false); 1186 } 1187 if (rc != NO_ERROR) { 1188 LOGE("add reprocess stream failed, ret = %d", rc); 1189 break; 1190 } 1191 } 1192 } 1193 1194 if (rc == NO_ERROR) { 1195 m_pSrcChannel = pSrcChannel; 1196 } 1197 return rc; 1198} 1199 1200/*=========================================================================== 1201 * FUNCTION : getStreamBySrouceHandle 1202 * 1203 * DESCRIPTION: find reprocess stream by its source stream handle 1204 * 1205 * PARAMETERS : 1206 * @srcHandle : source stream handle 1207 * 1208 * RETURN : ptr to reprocess stream if found. NULL if not found 1209 *==========================================================================*/ 1210QCameraStream * QCameraReprocessChannel::getStreamBySrouceHandle(uint32_t srcHandle) 1211{ 1212 QCameraStream *pStream = NULL; 1213 1214 for (size_t i = 0; i < mStreams.size(); i++) { 1215 if (mSrcStreamHandles[i] == srcHandle) { 1216 pStream = mStreams[i]; 1217 break; 1218 } 1219 } 1220 1221 return pStream; 1222} 1223 1224/*=========================================================================== 1225 * FUNCTION : stop 1226 * 1227 * DESCRIPTION: stop channel and unmap offline buffers 1228 * 1229 * PARAMETERS : none 1230 * 1231 * RETURN : int32_t type of status 1232 * NO_ERROR -- success 1233 * none-zero failure code 1234 *==========================================================================*/ 1235int32_t QCameraReprocessChannel::stop() 1236{ 1237 int32_t rc = QCameraChannel::stop(); 1238 1239 if (!mOfflineBuffers.empty()) { 1240 QCameraStream *stream = NULL; 1241 List<OfflineBuffer>::iterator it = mOfflineBuffers.begin(); 1242 int error = NO_ERROR; 1243 for( ; it != mOfflineBuffers.end(); it++) { 1244 stream = (*it).stream; 1245 if (NULL != stream) { 1246 error = stream->unmapBuf((*it).type, 1247 (*it).index, 1248 -1); 1249 if (NO_ERROR != error) { 1250 LOGE("Error during offline buffer unmap %d", 1251 error); 1252 } 1253 } 1254 } 1255 mOfflineBuffers.clear(); 1256 } 1257 return rc; 1258} 1259 1260/*=========================================================================== 1261 * FUNCTION : doReprocessOffline 1262 * 1263 * DESCRIPTION: request to do offline reprocess on the frame 1264 * 1265 * PARAMETERS : 1266 * @frame : frame to be performed a reprocess 1267 * @meta_buf : Metadata buffer for reprocessing 1268 * @pStream : Actual reprocess stream 1269 * 1270 * RETURN : int32_t type of status 1271 * NO_ERROR -- success 1272 * none-zero failure code 1273 *==========================================================================*/ 1274int32_t QCameraReprocessChannel::doReprocessOffline(mm_camera_buf_def_t *frame, 1275 mm_camera_buf_def_t *meta_buf, QCameraStream *pStream) 1276{ 1277 int32_t rc = 0; 1278 OfflineBuffer mappedBuffer; 1279 uint32_t buf_index = 0; 1280 uint32_t meta_buf_index = 0; 1281 1282 if ((frame == NULL) || (meta_buf == NULL)) { 1283 LOGE("Invalid Input Paramters"); 1284 return INVALID_OPERATION; 1285 } 1286 1287 if (pStream == NULL) { 1288 pStream = getStreamBySrouceHandle(frame->stream_id); 1289 if (pStream == NULL) { 1290 LOGE("Input validation failed."); 1291 return INVALID_OPERATION; 1292 } 1293 } 1294 1295 if (!mOfflineBuffers.empty()) { 1296 List<OfflineBuffer>::iterator it = mOfflineBuffers.begin(); 1297 for( ; it != mOfflineBuffers.end(); it++) { 1298 buf_index = (buf_index < ((*it).index)) ? ((*it).index) : buf_index; 1299 } 1300 buf_index += 1; 1301 } 1302 1303 meta_buf_index = buf_index; 1304 if (meta_buf != NULL) { 1305 rc = pStream->mapBuf(CAM_MAPPING_BUF_TYPE_OFFLINE_META_BUF, 1306 meta_buf_index, 1307 -1, 1308 meta_buf->fd, 1309 meta_buf->frame_len); 1310 if (NO_ERROR != rc ) { 1311 LOGE("Error during metadata buffer mapping"); 1312 rc = -1; 1313 return rc; 1314 } 1315 1316 mappedBuffer.index = meta_buf_index; 1317 mappedBuffer.stream = pStream; 1318 mappedBuffer.type = CAM_MAPPING_BUF_TYPE_OFFLINE_META_BUF; 1319 mOfflineBuffers.push_back(mappedBuffer); 1320 buf_index += 1; 1321 } 1322 1323 rc = pStream->mapBuf(CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF, 1324 buf_index, 1325 -1, 1326 frame->fd, 1327 frame->frame_len); 1328 if (NO_ERROR != rc ) { 1329 LOGE("Error during reprocess input buffer mapping"); 1330 rc = -1; 1331 return rc; 1332 } 1333 mappedBuffer.index = buf_index; 1334 mappedBuffer.stream = pStream; 1335 mappedBuffer.type = CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF; 1336 mOfflineBuffers.push_back(mappedBuffer); 1337 1338 cam_stream_parm_buffer_t param; 1339 memset(¶m, 0, sizeof(cam_stream_parm_buffer_t)); 1340 1341 param.type = CAM_STREAM_PARAM_TYPE_DO_REPROCESS; 1342 param.reprocess.buf_index = buf_index; 1343 param.reprocess.frame_idx = frame->frame_idx; 1344 1345 if (meta_buf != NULL) { 1346 param.reprocess.meta_present = 1; 1347 param.reprocess.meta_buf_index = meta_buf_index; 1348 } 1349 1350 LOGI("Offline reprocessing id = %d buf Id = %d meta index = %d type = %d", 1351 param.reprocess.frame_idx, param.reprocess.buf_index, 1352 param.reprocess.meta_buf_index, pStream->getMyOriginalType()); 1353 1354 rc = pStream->setParameter(param); 1355 if (rc != NO_ERROR) { 1356 LOGE("stream setParameter for reprocess failed"); 1357 return rc; 1358 } 1359 return rc; 1360} 1361 1362/*=========================================================================== 1363 * FUNCTION : doReprocessOffline 1364 * 1365 * DESCRIPTION: request to do offline reprocess on the frame 1366 * 1367 * PARAMETERS : 1368 * @frame : frame to be performed a reprocess 1369 * @meta_buf : Metadata buffer for reprocessing 1370 * @mParameter : camera parameters 1371 * 1372 * RETURN : int32_t type of status 1373 * NO_ERROR -- success 1374 * none-zero failure code 1375 *==========================================================================*/ 1376int32_t QCameraReprocessChannel::doReprocessOffline(mm_camera_super_buf_t *frame, 1377 mm_camera_buf_def_t *meta_buf, QCameraParametersIntf &mParameter) 1378{ 1379 int32_t rc = 0; 1380 QCameraStream *pStream = NULL; 1381 1382 if (mStreams.size() < 1) { 1383 LOGE("No reprocess streams"); 1384 return -1; 1385 } 1386 if (m_pSrcChannel == NULL) { 1387 LOGE("No source channel for reprocess"); 1388 return -1; 1389 } 1390 1391 if (frame == NULL) { 1392 LOGE("Invalid source frame"); 1393 return BAD_VALUE; 1394 } 1395 1396 for (uint32_t i = 0; i < frame->num_bufs; i++) { 1397 pStream = getStreamBySrouceHandle(frame->bufs[i]->stream_id); 1398 if ((pStream != NULL) && 1399 (m_handle == pStream->getChannelHandle())) { 1400 if (mParameter.getofflineRAW() && 1401 !((pStream->isOrignalTypeOf(CAM_STREAM_TYPE_RAW)) 1402 || (pStream->isOrignalTypeOf(CAM_STREAM_TYPE_METADATA)))) { 1403 continue; 1404 } 1405 1406 if ((pStream->isOrignalTypeOf(CAM_STREAM_TYPE_METADATA) 1407 && (mParameter.getManualCaptureMode() 1408 < CAM_MANUAL_CAPTURE_TYPE_3)) 1409 || (pStream->isTypeOf(CAM_STREAM_TYPE_ANALYSIS))) { 1410 // Skip metadata for reprocess now because PP module cannot handle meta data 1411 // May need furthur discussion if Imaginglib need meta data 1412 continue; 1413 } 1414 1415 // Update Metadata 1416 if (meta_buf != NULL) { 1417 uint32_t stream_id = frame->bufs[i]->stream_id; 1418 QCameraStream *srcStream = 1419 m_pSrcChannel->getStreamByHandle(stream_id); 1420 metadata_buffer_t *pMetaData = 1421 (metadata_buffer_t *)meta_buf->buffer; 1422 if ((NULL != pMetaData) && (NULL != srcStream)) { 1423 IF_META_AVAILABLE(cam_crop_data_t, crop, 1424 CAM_INTF_META_CROP_DATA, pMetaData) { 1425 if (MAX_NUM_STREAMS > crop->num_of_streams) { 1426 for (int j = 0; j < MAX_NUM_STREAMS; j++) { 1427 if (crop->crop_info[j].stream_id == 1428 srcStream->getMyServerID()) { 1429 // Store crop/roi information for offline reprocess 1430 // in the reprocess stream slot 1431 crop->crop_info[crop->num_of_streams].crop = 1432 crop->crop_info[j].crop; 1433 crop->crop_info[crop->num_of_streams].roi_map = 1434 crop->crop_info[j].roi_map; 1435 for (uint8_t k = 0; k < mStreams.size(); k++) { 1436 if (srcStream->getMyType() == 1437 mStreams[k]->getMyOriginalType()) { 1438 crop->crop_info[crop->num_of_streams].stream_id = 1439 mStreams[k]->getMyServerID(); 1440 break; 1441 } 1442 } 1443 crop->num_of_streams++; 1444 break; 1445 } 1446 } 1447 } else { 1448 LOGE("No space to add reprocess stream crop/roi information"); 1449 } 1450 } 1451 } 1452 } 1453 1454 rc = doReprocessOffline (frame->bufs[i], meta_buf, pStream); 1455 } 1456 } 1457 return rc; 1458} 1459 1460/*=========================================================================== 1461 * FUNCTION : doReprocess 1462 * 1463 * DESCRIPTION: request to do a reprocess on the frame 1464 * 1465 * PARAMETERS : 1466 * @frame : frame to be performed a reprocess 1467 * @mParameter : camera parameters 1468 * @pMetaStream: Metadata stream handle 1469 * @meta_buf_index : Metadata buffer index 1470 * 1471 * RETURN : int32_t type of status 1472 * NO_ERROR -- success 1473 * none-zero failure code 1474 *==========================================================================*/ 1475int32_t QCameraReprocessChannel::doReprocess(mm_camera_super_buf_t *frame, 1476 QCameraParametersIntf &mParameter, QCameraStream *pMetaStream, 1477 uint8_t meta_buf_index) 1478{ 1479 int32_t rc = 0; 1480 if (mStreams.size() < 1) { 1481 LOGE("No reprocess streams"); 1482 return -1; 1483 } 1484 if (m_pSrcChannel == NULL) { 1485 LOGE("No source channel for reprocess"); 1486 return -1; 1487 } 1488 1489 if (pMetaStream == NULL) { 1490 LOGW("Null Metadata buffer for processing"); 1491 } 1492 1493 for (uint32_t i = 0; i < frame->num_bufs; i++) { 1494 QCameraStream *pStream = getStreamBySrouceHandle(frame->bufs[i]->stream_id); 1495 if ((pStream != NULL) && (m_handle == pStream->getChannelHandle())) { 1496 if (mParameter.getofflineRAW() && !((pStream->isOrignalTypeOf(CAM_STREAM_TYPE_RAW)) 1497 || (pStream->isOrignalTypeOf(CAM_STREAM_TYPE_POSTVIEW)) 1498 || (pStream->isOrignalTypeOf(CAM_STREAM_TYPE_METADATA)))) { 1499 //Skip all the stream other than RAW and POSTVIEW incase of offline of RAW 1500 continue; 1501 } 1502 if ((pStream->isOrignalTypeOf(CAM_STREAM_TYPE_METADATA) 1503 && (mParameter.getManualCaptureMode() 1504 < CAM_MANUAL_CAPTURE_TYPE_3)) 1505 || (pStream->isTypeOf(CAM_STREAM_TYPE_ANALYSIS))) { 1506 // Skip metadata for reprocess now because PP module cannot handle meta data 1507 // May need furthur discussion if Imaginglib need meta data 1508 continue; 1509 } 1510 1511 cam_stream_parm_buffer_t param; 1512 memset(¶m, 0, sizeof(cam_stream_parm_buffer_t)); 1513 param.type = CAM_STREAM_PARAM_TYPE_DO_REPROCESS; 1514 param.reprocess.buf_index = frame->bufs[i]->buf_idx; 1515 param.reprocess.frame_idx = frame->bufs[i]->frame_idx; 1516 if (pMetaStream != NULL) { 1517 // we have meta data frame bundled, sent together with reprocess frame 1518 param.reprocess.meta_present = 1; 1519 param.reprocess.meta_stream_handle = pMetaStream->getMyServerID(); 1520 param.reprocess.meta_buf_index = meta_buf_index; 1521 } 1522 1523 LOGI("Online reprocessing id = %d buf Id = %d meta index = %d type = %d", 1524 param.reprocess.frame_idx, param.reprocess.buf_index, 1525 param.reprocess.meta_buf_index, pStream->getMyOriginalType()); 1526 1527 rc = pStream->setParameter(param); 1528 if (rc != NO_ERROR) { 1529 LOGE("stream setParameter for reprocess failed"); 1530 break; 1531 } 1532 } 1533 } 1534 return rc; 1535} 1536 1537/*=========================================================================== 1538 * FUNCTION : doReprocess 1539 * 1540 * DESCRIPTION: request to do a reprocess on the frame 1541 * 1542 * PARAMETERS : 1543 * @buf_fd : fd to the input buffer that needs reprocess 1544 * @buf_lenght : length of the input buffer 1545 * @ret_val : result of reprocess. 1546 * Example: Could be faceID in case of register face image. 1547 * 1548 * RETURN : int32_t type of status 1549 * NO_ERROR -- success 1550 * none-zero failure code 1551 *==========================================================================*/ 1552int32_t QCameraReprocessChannel::doReprocess(int buf_fd, 1553 size_t buf_length, int32_t &ret_val) 1554{ 1555 int32_t rc = 0; 1556 if (mStreams.size() < 1) { 1557 LOGE("No reprocess streams"); 1558 return -1; 1559 } 1560 1561 uint32_t buf_idx = 0; 1562 for (size_t i = 0; i < mStreams.size(); i++) { 1563 if ((mStreams[i] != NULL) && 1564 (m_handle != mStreams[i]->getChannelHandle())) { 1565 continue; 1566 } 1567 rc = mStreams[i]->mapBuf(CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF, 1568 buf_idx, -1, 1569 buf_fd, buf_length); 1570 1571 if (rc == NO_ERROR) { 1572 cam_stream_parm_buffer_t param; 1573 memset(¶m, 0, sizeof(cam_stream_parm_buffer_t)); 1574 param.type = CAM_STREAM_PARAM_TYPE_DO_REPROCESS; 1575 param.reprocess.buf_index = buf_idx; 1576 rc = mStreams[i]->setParameter(param); 1577 if (rc == NO_ERROR) { 1578 ret_val = param.reprocess.ret_val; 1579 } 1580 mStreams[i]->unmapBuf(CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF, 1581 buf_idx, -1); 1582 } 1583 } 1584 return rc; 1585} 1586 1587}; // namespace qcamera 1588