QCamera3Channel.cpp revision 9b6685ef8c0b801d1599a40ac1a27788c0a93c1c
1/* Copyright (c) 2012-2014, The Linux Foundataion. All rights reserved. 2* 3* Redistribution and use in source and binary forms, with or without 4* modification, are permitted provided that the following conditions are 5* met: 6* * Redistributions of source code must retain the above copyright 7* notice, this list of conditions and the following disclaimer. 8* * Redistributions in binary form must reproduce the above 9* copyright notice, this list of conditions and the following 10* disclaimer in the documentation and/or other materials provided 11* with the distribution. 12* * Neither the name of The Linux Foundation nor the names of its 13* contributors may be used to endorse or promote products derived 14* from this software without specific prior written permission. 15* 16* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED 17* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 18* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT 19* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS 20* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 23* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 24* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 25* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 26* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27* 28*/ 29 30#define LOG_TAG "QCamera3Channel" 31//#define LOG_NDEBUG 0 32#include <fcntl.h> 33#include <stdlib.h> 34#include <cstdlib> 35#include <stdio.h> 36#include <string.h> 37#include <hardware/camera3.h> 38#include <system/camera_metadata.h> 39#include <gralloc_priv.h> 40#include <utils/Log.h> 41#include <utils/Errors.h> 42#include <cutils/properties.h> 43#include "QCamera3Channel.h" 44 45using namespace android; 46 47#define MIN_STREAMING_BUFFER_NUM 7+11 48 49namespace qcamera { 50static const char ExifAsciiPrefix[] = 51 { 0x41, 0x53, 0x43, 0x49, 0x49, 0x0, 0x0, 0x0 }; // "ASCII\0\0\0" 52static const char ExifUndefinedPrefix[] = 53 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; // "\0\0\0\0\0\0\0\0" 54 55#define EXIF_ASCII_PREFIX_SIZE 8 //(sizeof(ExifAsciiPrefix)) 56#define FOCAL_LENGTH_DECIMAL_PRECISION 1000 57 58/*=========================================================================== 59 * FUNCTION : QCamera3Channel 60 * 61 * DESCRIPTION: constrcutor of QCamera3Channel 62 * 63 * PARAMETERS : 64 * @cam_handle : camera handle 65 * @cam_ops : ptr to camera ops table 66 * 67 * RETURN : none 68 *==========================================================================*/ 69QCamera3Channel::QCamera3Channel(uint32_t cam_handle, 70 mm_camera_ops_t *cam_ops, 71 channel_cb_routine cb_routine, 72 cam_padding_info_t *paddingInfo, 73 void *userData) 74{ 75 m_camHandle = cam_handle; 76 m_camOps = cam_ops; 77 m_bIsActive = false; 78 79 m_handle = 0; 80 m_numStreams = 0; 81 memset(mStreams, 0, sizeof(mStreams)); 82 mUserData = userData; 83 84 mStreamInfoBuf = NULL; 85 mChannelCB = cb_routine; 86 mPaddingInfo = paddingInfo; 87} 88 89/*=========================================================================== 90 * FUNCTION : QCamera3Channel 91 * 92 * DESCRIPTION: default constrcutor of QCamera3Channel 93 * 94 * PARAMETERS : none 95 * 96 * RETURN : none 97 *==========================================================================*/ 98QCamera3Channel::QCamera3Channel() 99{ 100 m_camHandle = 0; 101 m_camOps = NULL; 102 m_bIsActive = false; 103 104 m_handle = 0; 105 m_numStreams = 0; 106 memset(mStreams, 0, sizeof(mStreams)); 107 mUserData = NULL; 108 109 mStreamInfoBuf = NULL; 110 mChannelCB = NULL; 111 mPaddingInfo = NULL; 112} 113 114/*=========================================================================== 115 * FUNCTION : ~QCamera3Channel 116 * 117 * DESCRIPTION: destructor of QCamera3Channel 118 * 119 * PARAMETERS : none 120 * 121 * RETURN : none 122 *==========================================================================*/ 123QCamera3Channel::~QCamera3Channel() 124{ 125 if (m_bIsActive) 126 stop(); 127 128 for (int i = 0; i < m_numStreams; i++) { 129 if (mStreams[i] != NULL) { 130 delete mStreams[i]; 131 mStreams[i] = 0; 132 } 133 } 134 if (m_handle) { 135 m_camOps->delete_channel(m_camHandle, m_handle); 136 ALOGE("%s: deleting channel %d", __func__, m_handle); 137 m_handle = 0; 138 } 139 m_numStreams = 0; 140} 141 142/*=========================================================================== 143 * FUNCTION : init 144 * 145 * DESCRIPTION: initialization of channel 146 * 147 * PARAMETERS : 148 * @attr : channel bundle attribute setting 149 * @dataCB : data notify callback 150 * @userData: user data ptr 151 * 152 * RETURN : int32_t type of status 153 * NO_ERROR -- success 154 * none-zero failure code 155 *==========================================================================*/ 156int32_t QCamera3Channel::init(mm_camera_channel_attr_t *attr, 157 mm_camera_buf_notify_t dataCB) 158{ 159 m_handle = m_camOps->add_channel(m_camHandle, 160 attr, 161 dataCB, 162 this); 163 if (m_handle == 0) { 164 ALOGE("%s: Add channel failed", __func__); 165 return UNKNOWN_ERROR; 166 } 167 return NO_ERROR; 168} 169 170/*=========================================================================== 171 * FUNCTION : addStream 172 * 173 * DESCRIPTION: add a stream into channel 174 * 175 * PARAMETERS : 176 * @allocator : stream related buffer allocator 177 * @streamInfoBuf : ptr to buf that constains stream info 178 * @minStreamBufNum: number of stream buffers needed 179 * @paddingInfo : padding information 180 * @stream_cb : stream data notify callback 181 * @userdata : user data ptr 182 * 183 * RETURN : int32_t type of status 184 * NO_ERROR -- success 185 * none-zero failure code 186 *==========================================================================*/ 187int32_t QCamera3Channel::addStream(cam_stream_type_t streamType, 188 cam_format_t streamFormat, 189 cam_dimension_t streamDim, 190 uint8_t minStreamBufNum) 191{ 192 int32_t rc = NO_ERROR; 193 194 if (m_numStreams >= 1) { 195 ALOGE("%s: Only one stream per channel supported in v3 Hal", __func__); 196 return BAD_VALUE; 197 } 198 199 if (m_numStreams >= MAX_STREAM_NUM_IN_BUNDLE) { 200 ALOGE("%s: stream number (%d) exceeds max limit (%d)", 201 __func__, m_numStreams, MAX_STREAM_NUM_IN_BUNDLE); 202 return BAD_VALUE; 203 } 204 QCamera3Stream *pStream = new QCamera3Stream(m_camHandle, 205 m_handle, 206 m_camOps, 207 mPaddingInfo, 208 this); 209 if (pStream == NULL) { 210 ALOGE("%s: No mem for Stream", __func__); 211 return NO_MEMORY; 212 } 213 214 rc = pStream->init(streamType, streamFormat, streamDim, NULL, minStreamBufNum, 215 streamCbRoutine, this); 216 if (rc == 0) { 217 mStreams[m_numStreams] = pStream; 218 m_numStreams++; 219 } else { 220 delete pStream; 221 } 222 return rc; 223} 224 225/*=========================================================================== 226 * FUNCTION : start 227 * 228 * DESCRIPTION: start channel, which will start all streams belong to this channel 229 * 230 * PARAMETERS : 231 * 232 * RETURN : int32_t type of status 233 * NO_ERROR -- success 234 * none-zero failure code 235 *==========================================================================*/ 236int32_t QCamera3Channel::start() 237{ 238 int32_t rc = NO_ERROR; 239 240 if (m_numStreams > 1) { 241 ALOGE("%s: bundle not supported", __func__); 242 } else if (m_numStreams == 0) { 243 return NO_INIT; 244 } 245 246 for (int i = 0; i < m_numStreams; i++) { 247 if (mStreams[i] != NULL) { 248 mStreams[i]->start(); 249 } 250 } 251 rc = m_camOps->start_channel(m_camHandle, m_handle); 252 253 if (rc != NO_ERROR) { 254 for (int i = 0; i < m_numStreams; i++) { 255 if (mStreams[i] != NULL) { 256 mStreams[i]->stop(); 257 } 258 } 259 } else { 260 m_bIsActive = true; 261 } 262 263 return rc; 264} 265 266/*=========================================================================== 267 * FUNCTION : stop 268 * 269 * DESCRIPTION: stop a channel, which will stop all streams belong to this channel 270 * 271 * PARAMETERS : none 272 * 273 * RETURN : int32_t type of status 274 * NO_ERROR -- success 275 * none-zero failure code 276 *==========================================================================*/ 277int32_t QCamera3Channel::stop() 278{ 279 int32_t rc = NO_ERROR; 280 if(!m_bIsActive) { 281 ALOGE("%s: Attempt to stop inactive channel",__func__); 282 return rc; 283 } 284 285 for (int i = 0; i < m_numStreams; i++) { 286 if (mStreams[i] != NULL) { 287 mStreams[i]->stop(); 288 } 289 } 290 291 rc = m_camOps->stop_channel(m_camHandle, m_handle); 292 293 m_bIsActive = false; 294 return rc; 295} 296 297/*=========================================================================== 298 * FUNCTION : bufDone 299 * 300 * DESCRIPTION: return a stream buf back to kernel 301 * 302 * PARAMETERS : 303 * @recvd_frame : stream buf frame to be returned 304 * 305 * RETURN : int32_t type of status 306 * NO_ERROR -- success 307 * none-zero failure code 308 *==========================================================================*/ 309int32_t QCamera3Channel::bufDone(mm_camera_super_buf_t *recvd_frame) 310{ 311 int32_t rc = NO_ERROR; 312 for (int i = 0; i < recvd_frame->num_bufs; i++) { 313 if (recvd_frame->bufs[i] != NULL) { 314 for (int j = 0; j < m_numStreams; j++) { 315 if (mStreams[j] != NULL && 316 mStreams[j]->getMyHandle() == recvd_frame->bufs[i]->stream_id) { 317 rc = mStreams[j]->bufDone(recvd_frame->bufs[i]->buf_idx); 318 break; // break loop j 319 } 320 } 321 } 322 } 323 324 return rc; 325} 326 327/*=========================================================================== 328 * FUNCTION : getStreamTypeMask 329 * 330 * DESCRIPTION: Get bit mask of all stream types in this channel 331 * 332 * PARAMETERS : None 333 * 334 * RETURN : Bit mask of all stream types in this channel 335 *==========================================================================*/ 336uint32_t QCamera3Channel::getStreamTypeMask() 337{ 338 uint32_t mask = 0; 339 for (int i = 0; i < m_numStreams; i++) { 340 mask |= (0x1 << mStreams[i]->getMyType()); 341 } 342 return mask; 343} 344 345/*=========================================================================== 346 * FUNCTION : getStreamID 347 * 348 * DESCRIPTION: Get StreamID of requested stream type 349 * 350 * PARAMETERS : streamMask 351 * 352 * RETURN : Stream ID 353 *==========================================================================*/ 354uint32_t QCamera3Channel::getStreamID(uint32_t streamMask) 355{ 356 uint32_t streamID = 0; 357 for (int i = 0; i < m_numStreams; i++) { 358 if (streamMask == (uint32_t )(0x1 << mStreams[i]->getMyType())) { 359 streamID = mStreams[i]->getMyServerID(); 360 break; 361 } 362 } 363 return streamID; 364} 365 366/*=========================================================================== 367 * FUNCTION : getStreamByHandle 368 * 369 * DESCRIPTION: return stream object by stream handle 370 * 371 * PARAMETERS : 372 * @streamHandle : stream handle 373 * 374 * RETURN : stream object. NULL if not found 375 *==========================================================================*/ 376QCamera3Stream *QCamera3Channel::getStreamByHandle(uint32_t streamHandle) 377{ 378 for (int i = 0; i < m_numStreams; i++) { 379 if (mStreams[i] != NULL && mStreams[i]->getMyHandle() == streamHandle) { 380 return mStreams[i]; 381 } 382 } 383 return NULL; 384} 385 386/*=========================================================================== 387 * FUNCTION : getStreamByIndex 388 * 389 * DESCRIPTION: return stream object by index 390 * 391 * PARAMETERS : 392 * @streamHandle : stream handle 393 * 394 * RETURN : stream object. NULL if not found 395 *==========================================================================*/ 396QCamera3Stream *QCamera3Channel::getStreamByIndex(uint8_t index) 397{ 398 if (index < m_numStreams) { 399 return mStreams[index]; 400 } 401 return NULL; 402} 403 404/*=========================================================================== 405 * FUNCTION : streamCbRoutine 406 * 407 * DESCRIPTION: callback routine for stream 408 * 409 * PARAMETERS : 410 * @streamHandle : stream handle 411 * 412 * RETURN : stream object. NULL if not found 413 *==========================================================================*/ 414void QCamera3Channel::streamCbRoutine(mm_camera_super_buf_t *super_frame, 415 QCamera3Stream *stream, void *userdata) 416{ 417 QCamera3Channel *channel = (QCamera3Channel *)userdata; 418 if (channel == NULL) { 419 ALOGE("%s: invalid channel pointer", __func__); 420 return; 421 } 422 channel->streamCbRoutine(super_frame, stream); 423} 424 425/*=========================================================================== 426 * FUNCTION : QCamera3RegularChannel 427 * 428 * DESCRIPTION: constrcutor of QCamera3RegularChannel 429 * 430 * PARAMETERS : 431 * @cam_handle : camera handle 432 * @cam_ops : ptr to camera ops table 433 * @cb_routine : callback routine to frame aggregator 434 * @stream : camera3_stream_t structure 435 * @stream_type: Channel stream type 436 * 437 * RETURN : none 438 *==========================================================================*/ 439QCamera3RegularChannel::QCamera3RegularChannel(uint32_t cam_handle, 440 mm_camera_ops_t *cam_ops, 441 channel_cb_routine cb_routine, 442 cam_padding_info_t *paddingInfo, 443 void *userData, 444 camera3_stream_t *stream, 445 cam_stream_type_t stream_type) : 446 QCamera3Channel(cam_handle, cam_ops, cb_routine, 447 paddingInfo, userData), 448 mCamera3Stream(stream), 449 mNumBufs(0), 450 mStreamType(stream_type) 451{ 452} 453 454/*=========================================================================== 455 * FUNCTION : ~QCamera3RegularChannel 456 * 457 * DESCRIPTION: destructor of QCamera3RegularChannel 458 * 459 * PARAMETERS : none 460 * 461 * RETURN : none 462 *==========================================================================*/ 463QCamera3RegularChannel::~QCamera3RegularChannel() 464{ 465} 466 467/*=========================================================================== 468 * FUNCTION : initialize 469 * 470 * DESCRIPTION: Initialize and add camera channel & stream 471 * 472 * PARAMETERS : 473 * 474 * RETURN : int32_t type of status 475 * NO_ERROR -- success 476 * none-zero failure code 477 *==========================================================================*/ 478 479int32_t QCamera3RegularChannel::initialize() 480{ 481 int32_t rc = NO_ERROR; 482 cam_format_t streamFormat; 483 cam_dimension_t streamDim; 484 485 if (NULL == mCamera3Stream) { 486 ALOGE("%s: Camera stream uninitialized", __func__); 487 return NO_INIT; 488 } 489 490 if (1 <= m_numStreams) { 491 // Only one stream per channel supported in v3 Hal 492 return NO_ERROR; 493 } 494 495 rc = init(NULL, NULL); 496 if (rc < 0) { 497 ALOGE("%s: init failed", __func__); 498 return rc; 499 } 500 501 mNumBufs = CAM_MAX_NUM_BUFS_PER_STREAM; 502 503 if (mCamera3Stream->format == HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED) { 504 if (mStreamType == CAM_STREAM_TYPE_VIDEO) { 505 streamFormat = CAM_FORMAT_YUV_420_NV12; 506 } else if (mStreamType == CAM_STREAM_TYPE_PREVIEW) { 507 streamFormat = CAM_FORMAT_YUV_420_NV21; 508 } else { 509 //TODO: Add a new flag in libgralloc for ZSL buffers, and its size needs 510 // to be properly aligned and padded. 511 streamFormat = CAM_FORMAT_YUV_420_NV21; 512 } 513 } else if(mCamera3Stream->format == HAL_PIXEL_FORMAT_YCbCr_420_888) { 514 streamFormat = CAM_FORMAT_YUV_420_NV21; 515 } else if (mCamera3Stream->format == HAL_PIXEL_FORMAT_RAW_OPAQUE || 516 mCamera3Stream->format == HAL_PIXEL_FORMAT_RAW16) { 517 // Bayer pattern doesn't matter here. 518 // All CAMIF raw format uses 10bit. 519 streamFormat = CAM_FORMAT_BAYER_QCOM_RAW_10BPP_GBRG; 520 } else { 521 522 //TODO: Fail for other types of streams for now 523 ALOGE("%s: format is not IMPLEMENTATION_DEFINED or flexible", __func__); 524 return -EINVAL; 525 } 526 527 streamDim.width = mCamera3Stream->width; 528 streamDim.height = mCamera3Stream->height; 529 530 rc = QCamera3Channel::addStream(mStreamType, 531 streamFormat, 532 streamDim, 533 mNumBufs); 534 535 return rc; 536} 537 538/*=========================================================================== 539 * FUNCTION : start 540 * 541 * DESCRIPTION: start a regular channel 542 * 543 * PARAMETERS : 544 * 545 * RETURN : int32_t type of status 546 * NO_ERROR -- success 547 * none-zero failure code 548 *==========================================================================*/ 549int32_t QCamera3RegularChannel::start() 550{ 551 int32_t rc = NO_ERROR; 552 553 if (0 < mMemory.getCnt()) { 554 rc = QCamera3Channel::start(); 555 } 556 557 return rc; 558} 559/*=========================================================================== 560 * FUNCTION : getInternalFormatBuffer 561 * 562 * DESCRIPTION: return buffer in the internal format structure 563 * 564 * PARAMETERS : 565 * @streamHandle : buffer handle 566 * 567 * RETURN : stream object. NULL if not found 568 *==========================================================================*/ 569mm_camera_buf_def_t* QCamera3RegularChannel::getInternalFormatBuffer( 570 buffer_handle_t * buffer) 571{ 572 int32_t index; 573 if(buffer == NULL) 574 return NULL; 575 index = mMemory.getMatchBufIndex((void*)buffer); 576 if(index < 0) { 577 ALOGE("%s: Could not find object among registered buffers",__func__); 578 return NULL; 579 } 580 return mStreams[0]->getInternalFormatBuffer(index); 581} 582 583/*=========================================================================== 584 * FUNCTION : request 585 * 586 * DESCRIPTION: process a request from camera service. Stream on if ncessary. 587 * 588 * PARAMETERS : 589 * @buffer : buffer to be filled for this request 590 * 591 * RETURN : 0 on a success start of capture 592 * -EINVAL on invalid input 593 * -ENODEV on serious error 594 *==========================================================================*/ 595int32_t QCamera3RegularChannel::request(buffer_handle_t *buffer, uint32_t frameNumber) 596{ 597 //FIX ME: Return buffer back in case of failures below. 598 599 int32_t rc = NO_ERROR; 600 int index; 601 602 if (NULL == buffer) { 603 ALOGE("%s: Invalid buffer in channel request", __func__); 604 return BAD_VALUE; 605 } 606 607 if(!m_bIsActive) { 608 rc = registerBuffer(buffer); 609 if (NO_ERROR != rc) { 610 ALOGE("%s: On-the-fly buffer registration failed %d", 611 __func__, rc); 612 return rc; 613 } 614 615 rc = start(); 616 if (NO_ERROR != rc) { 617 return rc; 618 } 619 } else { 620 ALOGV("%s: Request on an existing stream",__func__); 621 } 622 623 index = mMemory.getMatchBufIndex((void*)buffer); 624 if(index < 0) { 625 rc = registerBuffer(buffer); 626 if (NO_ERROR != rc) { 627 ALOGE("%s: On-the-fly buffer registration failed %d", 628 __func__, rc); 629 return rc; 630 } 631 632 index = mMemory.getMatchBufIndex((void*)buffer); 633 if (index < 0) { 634 ALOGE("%s: Could not find object among registered buffers", 635 __func__); 636 return DEAD_OBJECT; 637 } 638 } 639 640 rc = mStreams[0]->bufDone(index); 641 if(rc != NO_ERROR) { 642 ALOGE("%s: Failed to Q new buffer to stream",__func__); 643 return rc; 644 } 645 646 rc = mMemory.markFrameNumber(index, frameNumber); 647 return rc; 648} 649 650/*=========================================================================== 651 * FUNCTION : registerBuffer 652 * 653 * DESCRIPTION: register streaming buffer to the channel object 654 * 655 * PARAMETERS : 656 * @buffer : buffer to be registered 657 * 658 * RETURN : int32_t type of status 659 * NO_ERROR -- success 660 * none-zero failure code 661 *==========================================================================*/ 662int32_t QCamera3RegularChannel::registerBuffer(buffer_handle_t *buffer) 663{ 664 int rc = 0; 665 666 if ((uint32_t)mMemory.getCnt() > (mNumBufs - 1)) { 667 ALOGE("%s: Trying to register more buffers than initially requested", 668 __func__); 669 return BAD_VALUE; 670 } 671 672 if (0 == m_numStreams) { 673 rc = initialize(); 674 if (rc != NO_ERROR) { 675 ALOGE("%s: Couldn't initialize camera stream %d", 676 __func__, rc); 677 return rc; 678 } 679 } 680 681 rc = mMemory.registerBuffer(buffer); 682 if (ALREADY_EXISTS == rc) { 683 return NO_ERROR; 684 } else if (NO_ERROR != rc) { 685 ALOGE("%s: Buffer %p couldn't be registered %d", __func__, buffer, rc); 686 return rc; 687 } 688 689 return rc; 690} 691 692void QCamera3RegularChannel::streamCbRoutine( 693 mm_camera_super_buf_t *super_frame, 694 QCamera3Stream *stream) 695{ 696 //FIXME Q Buf back in case of error? 697 uint8_t frameIndex; 698 buffer_handle_t *resultBuffer; 699 int32_t resultFrameNumber; 700 camera3_stream_buffer_t result; 701 702 if(!super_frame) { 703 ALOGE("%s: Invalid Super buffer",__func__); 704 return; 705 } 706 707 if(super_frame->num_bufs != 1) { 708 ALOGE("%s: Multiple streams are not supported",__func__); 709 return; 710 } 711 if(super_frame->bufs[0] == NULL ) { 712 ALOGE("%s: Error, Super buffer frame does not contain valid buffer", 713 __func__); 714 return; 715 } 716 717 frameIndex = (uint8_t)super_frame->bufs[0]->buf_idx; 718 if(frameIndex >= mNumBufs) { 719 ALOGE("%s: Error, Invalid index for buffer",__func__); 720 if(stream) { 721 stream->bufDone(frameIndex); 722 } 723 return; 724 } 725 726 ////Use below data to issue framework callback 727 resultBuffer = (buffer_handle_t *)mMemory.getBufferHandle(frameIndex); 728 resultFrameNumber = mMemory.getFrameNumber(frameIndex); 729 730 result.stream = mCamera3Stream; 731 result.buffer = resultBuffer; 732 result.status = CAMERA3_BUFFER_STATUS_OK; 733 result.acquire_fence = -1; 734 result.release_fence = -1; 735 736 mChannelCB(NULL, &result, resultFrameNumber, mUserData); 737 free(super_frame); 738 return; 739} 740 741QCamera3Memory* QCamera3RegularChannel::getStreamBufs(uint32_t /*len*/) 742{ 743 return &mMemory; 744} 745 746void QCamera3RegularChannel::putStreamBufs() 747{ 748 mMemory.unregisterBuffers(); 749} 750 751int QCamera3RegularChannel::kMaxBuffers = 7; 752 753QCamera3MetadataChannel::QCamera3MetadataChannel(uint32_t cam_handle, 754 mm_camera_ops_t *cam_ops, 755 channel_cb_routine cb_routine, 756 cam_padding_info_t *paddingInfo, 757 void *userData) : 758 QCamera3Channel(cam_handle, cam_ops, 759 cb_routine, paddingInfo, userData), 760 mMemory(NULL) 761{ 762} 763 764QCamera3MetadataChannel::~QCamera3MetadataChannel() 765{ 766 if (m_bIsActive) 767 stop(); 768 769 if (mMemory) { 770 mMemory->deallocate(); 771 delete mMemory; 772 mMemory = NULL; 773 } 774} 775 776int32_t QCamera3MetadataChannel::initialize() 777{ 778 int32_t rc; 779 cam_dimension_t streamDim; 780 781 if (mMemory || m_numStreams > 0) { 782 ALOGE("%s: metadata channel already initialized", __func__); 783 return -EINVAL; 784 } 785 786 rc = init(NULL, NULL); 787 if (rc < 0) { 788 ALOGE("%s: init failed", __func__); 789 return rc; 790 } 791 792 streamDim.width = sizeof(metadata_buffer_t), 793 streamDim.height = 1; 794 rc = QCamera3Channel::addStream(CAM_STREAM_TYPE_METADATA, CAM_FORMAT_MAX, 795 streamDim, MIN_STREAMING_BUFFER_NUM); 796 if (rc < 0) { 797 ALOGE("%s: addStream failed", __func__); 798 } 799 return rc; 800} 801 802int32_t QCamera3MetadataChannel::request(buffer_handle_t * /*buffer*/, 803 uint32_t /*frameNumber*/) 804{ 805 if (!m_bIsActive) { 806 return start(); 807 } 808 else 809 return 0; 810} 811 812void QCamera3MetadataChannel::streamCbRoutine( 813 mm_camera_super_buf_t *super_frame, 814 QCamera3Stream * /*stream*/) 815{ 816 uint32_t requestNumber = 0; 817 if (super_frame == NULL || super_frame->num_bufs != 1) { 818 ALOGE("%s: super_frame is not valid", __func__); 819 return; 820 } 821 mChannelCB(super_frame, NULL, requestNumber, mUserData); 822} 823 824QCamera3Memory* QCamera3MetadataChannel::getStreamBufs(uint32_t len) 825{ 826 int rc; 827 if (len < sizeof(metadata_buffer_t)) { 828 ALOGE("%s: size doesn't match %d vs %d", __func__, 829 len, sizeof(metadata_buffer_t)); 830 return NULL; 831 } 832 mMemory = new QCamera3HeapMemory(); 833 if (!mMemory) { 834 ALOGE("%s: unable to create metadata memory", __func__); 835 return NULL; 836 } 837 rc = mMemory->allocate(MIN_STREAMING_BUFFER_NUM, len, true); 838 if (rc < 0) { 839 ALOGE("%s: unable to allocate metadata memory", __func__); 840 delete mMemory; 841 mMemory = NULL; 842 return NULL; 843 } 844 memset(mMemory->getPtr(0), 0, sizeof(metadata_buffer_t)); 845 return mMemory; 846} 847 848void QCamera3MetadataChannel::putStreamBufs() 849{ 850 mMemory->deallocate(); 851 delete mMemory; 852 mMemory = NULL; 853} 854/*************************************************************************************/ 855// RAW Channel related functions 856int QCamera3RawChannel::kMaxBuffers = 7; 857 858QCamera3RawChannel::QCamera3RawChannel(uint32_t cam_handle, 859 mm_camera_ops_t *cam_ops, 860 channel_cb_routine cb_routine, 861 cam_padding_info_t *paddingInfo, 862 void *userData, 863 camera3_stream_t *stream, 864 bool raw_16) : 865 QCamera3RegularChannel(cam_handle, cam_ops, 866 cb_routine, paddingInfo, userData, stream, 867 CAM_STREAM_TYPE_RAW), 868 mIsRaw16(raw_16) 869{ 870 char prop[PROPERTY_VALUE_MAX]; 871 property_get("persist.camera.raw.dump", prop, "0"); 872 mRawDump = atoi(prop); 873} 874 875QCamera3RawChannel::~QCamera3RawChannel() 876{ 877} 878 879void QCamera3RawChannel::streamCbRoutine( 880 mm_camera_super_buf_t *super_frame, 881 QCamera3Stream * stream) 882{ 883 /* Move this back down once verified */ 884 if (mRawDump) 885 dumpRawSnapshot(super_frame->bufs[0]); 886 887 if (mIsRaw16) 888 convertToRaw16(super_frame->bufs[0]); 889 890 //Make sure cache coherence because extra processing is done 891 mMemory.cleanInvalidateCache(super_frame->bufs[0]->buf_idx); 892 893 QCamera3RegularChannel::streamCbRoutine(super_frame, stream); 894 return; 895} 896 897void QCamera3RawChannel::dumpRawSnapshot(mm_camera_buf_def_t *frame) 898{ 899 QCamera3Stream *stream = getStreamByIndex(0); 900 char buf[32]; 901 memset(buf, 0, sizeof(buf)); 902 cam_dimension_t dim; 903 memset(&dim, 0, sizeof(dim)); 904 stream->getFrameDimension(dim); 905 906 cam_frame_len_offset_t offset; 907 memset(&offset, 0, sizeof(cam_frame_len_offset_t)); 908 stream->getFrameOffset(offset); 909 snprintf(buf, sizeof(buf), "/data/r_%d_%dx%d.raw", 910 frame->frame_idx, offset.mp[0].stride, offset.mp[0].scanline); 911 912 int file_fd = open(buf, O_RDWR| O_CREAT, 0777); 913 if (file_fd) { 914 int written_len = write(file_fd, frame->buffer, frame->frame_len); 915 ALOGE("%s: written number of bytes %d", __func__, written_len); 916 close(file_fd); 917 } else { 918 ALOGE("%s: failed to open file to dump image", __func__); 919 } 920 921} 922 923void QCamera3RawChannel::convertToRaw16(mm_camera_buf_def_t *frame) 924{ 925 // Convert image buffer from Opaque raw format to RAW16 format 926 // 10bit Opaque raw is stored in the format of: 927 // 0000 - p5 - p4 - p3 - p2 - p1 - p0 928 // where p0 to p5 are 6 pixels (each is 10bit)_and most significant 929 // 4 bits are 0s. Each 64bit word contains 6 pixels. 930 931 QCamera3Stream *stream = getStreamByIndex(0); 932 cam_dimension_t dim; 933 memset(&dim, 0, sizeof(dim)); 934 stream->getFrameDimension(dim); 935 936 cam_frame_len_offset_t offset; 937 memset(&offset, 0, sizeof(cam_frame_len_offset_t)); 938 stream->getFrameOffset(offset); 939 940 uint32_t raw16_stride = (dim.width + 15) & ~15; 941 uint16_t* raw16_buffer = (uint16_t *)frame->buffer; 942 943 // In-place format conversion. 944 // Raw16 format always occupy more memory than opaque raw10. 945 // Convert to Raw16 by iterating through all pixels from bottom-right 946 // to top-left of the image. 947 // One special notes: 948 // 1. Cross-platform raw16's stride is 16 pixels. 949 // 2. Opaque raw10's stride is 6 pixels, and aligned to 16 bytes. 950 for (int y = dim.height-1; y >= 0; y--) { 951 uint64_t* row_start = (uint64_t *)frame->buffer + 952 y * offset.mp[0].stride / 6; 953 for (int x = dim.width-1; x >= 0; x--) { 954 uint16_t raw16_pixel = 0x3FF & (row_start[x/6] >> (10*(x%6))); 955 raw16_buffer[y*raw16_stride+x] = raw16_pixel; 956 } 957 } 958} 959 960/*************************************************************************************/ 961 962/*=========================================================================== 963 * FUNCTION : jpegEvtHandle 964 * 965 * DESCRIPTION: Function registerd to mm-jpeg-interface to handle jpeg events. 966 Construct result payload and call mChannelCb to deliver buffer 967 to framework. 968 * 969 * PARAMETERS : 970 * @status : status of jpeg job 971 * @client_hdl: jpeg client handle 972 * @jobId : jpeg job Id 973 * @p_ouput : ptr to jpeg output result struct 974 * @userdata : user data ptr 975 * 976 * RETURN : none 977 *==========================================================================*/ 978void QCamera3PicChannel::jpegEvtHandle(jpeg_job_status_t status, 979 uint32_t /*client_hdl*/, 980 uint32_t jobId, 981 mm_jpeg_output_t *p_output, 982 void *userdata) 983{ 984 buffer_handle_t *resultBuffer, *jpegBufferHandle; 985 int32_t resultFrameNumber; 986 int resultStatus = CAMERA3_BUFFER_STATUS_OK; 987 camera3_stream_buffer_t result; 988 camera3_jpeg_blob_t jpegHeader; 989 char* jpeg_eof = 0; 990 int maxJpegSize; 991 QCamera3PicChannel *obj = (QCamera3PicChannel *)userdata; 992 if (obj) { 993 994 //Release any cached metabuffer information 995 if (obj->mMetaFrame != NULL && obj->m_pMetaChannel != NULL) { 996 ((QCamera3MetadataChannel*)(obj->m_pMetaChannel))->bufDone(obj->mMetaFrame); 997 obj->mMetaFrame = NULL; 998 obj->m_pMetaChannel = NULL; 999 } else { 1000 ALOGE("%s: Meta frame was NULL", __func__); 1001 } 1002 //Construct payload for process_capture_result. Call mChannelCb 1003 1004 qcamera_jpeg_data_t *job = obj->m_postprocessor.findJpegJobByJobId(jobId); 1005 1006 if ((job == NULL) || (status == JPEG_JOB_STATUS_ERROR)) { 1007 ALOGE("%s: Error in jobId: (%d) with status: %d", __func__, jobId, status); 1008 resultStatus = CAMERA3_BUFFER_STATUS_ERROR; 1009 } 1010 1011 //Construct jpeg transient header of type camera3_jpeg_blob_t 1012 //Append at the end of jpeg image of buf_filled_len size 1013 1014 jpegHeader.jpeg_blob_id = CAMERA3_JPEG_BLOB_ID; 1015 jpegHeader.jpeg_size = p_output->buf_filled_len; 1016 1017 1018 char* jpeg_buf = (char *)p_output->buf_vaddr; 1019 1020 // Gralloc buffer may have additional padding for 4K page size 1021 // Follow size guidelines based on spec since framework relies 1022 // on that to reach end of buffer and with it the header 1023 1024 //Handle same as resultBuffer, but for readablity 1025 jpegBufferHandle = 1026 (buffer_handle_t *)obj->mMemory.getBufferHandle(obj->mCurrentBufIndex); 1027 1028 maxJpegSize = ((private_handle_t*)(*jpegBufferHandle))->width; 1029 if (maxJpegSize > obj->mMemory.getSize(obj->mCurrentBufIndex)) { 1030 maxJpegSize = obj->mMemory.getSize(obj->mCurrentBufIndex); 1031 } 1032 1033 jpeg_eof = &jpeg_buf[maxJpegSize-sizeof(jpegHeader)]; 1034 memcpy(jpeg_eof, &jpegHeader, sizeof(jpegHeader)); 1035 obj->mMemory.cleanInvalidateCache(obj->mCurrentBufIndex); 1036 1037 ////Use below data to issue framework callback 1038 resultBuffer = (buffer_handle_t *)obj->mMemory.getBufferHandle(obj->mCurrentBufIndex); 1039 resultFrameNumber = obj->mMemory.getFrameNumber(obj->mCurrentBufIndex); 1040 1041 result.stream = obj->mCamera3Stream; 1042 result.buffer = resultBuffer; 1043 result.status = resultStatus; 1044 result.acquire_fence = -1; 1045 result.release_fence = -1; 1046 1047 ALOGV("%s: Issue Callback", __func__); 1048 obj->mChannelCB(NULL, &result, resultFrameNumber, obj->mUserData); 1049 1050 // release internal data for jpeg job 1051 if (job != NULL) { 1052 obj->m_postprocessor.releaseJpegJobData(job); 1053 free(job); 1054 } 1055 return; 1056 // } 1057 } else { 1058 ALOGE("%s: Null userdata in jpeg callback", __func__); 1059 } 1060} 1061 1062QCamera3PicChannel::QCamera3PicChannel(uint32_t cam_handle, 1063 mm_camera_ops_t *cam_ops, 1064 channel_cb_routine cb_routine, 1065 cam_padding_info_t *paddingInfo, 1066 void *userData, 1067 camera3_stream_t *stream) : 1068 QCamera3Channel(cam_handle, cam_ops, cb_routine, 1069 paddingInfo, userData), 1070 m_postprocessor(this), 1071 mCamera3Stream(stream), 1072 mNumBufs(0), 1073 mCurrentBufIndex(-1), 1074 mYuvMemory(NULL), 1075 mMetaFrame(NULL) 1076{ 1077 mYuvWidth = stream->width; 1078 mYuvHeight = stream->height; 1079 int32_t rc = m_postprocessor.init(&mMemory, jpegEvtHandle, this); 1080 if (rc != 0) { 1081 ALOGE("Init Postprocessor failed"); 1082 } 1083} 1084 1085QCamera3PicChannel::~QCamera3PicChannel() 1086{ 1087 int32_t rc = m_postprocessor.deinit(); 1088 if (rc != 0) { 1089 ALOGE("De-init Postprocessor failed"); 1090 } 1091} 1092 1093int32_t QCamera3PicChannel::initialize() 1094{ 1095 int32_t rc = NO_ERROR; 1096 cam_dimension_t streamDim; 1097 cam_stream_type_t streamType; 1098 cam_format_t streamFormat; 1099 mm_camera_channel_attr_t attr; 1100 1101 if (NULL == mCamera3Stream) { 1102 ALOGE("%s: Camera stream uninitialized", __func__); 1103 return NO_INIT; 1104 } 1105 1106 if (1 <= m_numStreams) { 1107 // Only one stream per channel supported in v3 Hal 1108 return NO_ERROR; 1109 } 1110 1111 memset(&attr, 0, sizeof(mm_camera_channel_attr_t)); 1112 attr.notify_mode = MM_CAMERA_SUPER_BUF_NOTIFY_BURST; 1113 attr.look_back = 1; 1114 attr.post_frame_skip = 1; 1115 attr.water_mark = 1; 1116 attr.max_unmatched_frames = 1; 1117 1118 rc = init(&attr, NULL); 1119 if (rc < 0) { 1120 ALOGE("%s: init failed", __func__); 1121 return rc; 1122 } 1123 1124 streamType = CAM_STREAM_TYPE_NON_ZSL_SNAPSHOT; 1125 streamFormat = CAM_FORMAT_YUV_420_NV21; 1126 streamDim.width = mYuvWidth; 1127 streamDim.height = mYuvHeight; 1128 1129 int num_buffers = 1; 1130 mNumBufs = CAM_MAX_NUM_BUFS_PER_STREAM; 1131 rc = QCamera3Channel::addStream(streamType, streamFormat, streamDim, 1132 num_buffers); 1133 1134 return rc; 1135} 1136 1137int32_t QCamera3PicChannel::request(buffer_handle_t *buffer, 1138 uint32_t frameNumber, 1139 mm_camera_buf_def_t *pInputBuffer, 1140 metadata_buffer_t *metadata) 1141{ 1142 //FIX ME: Return buffer back in case of failures below. 1143 1144 int32_t rc = NO_ERROR; 1145 int index; 1146 // Picture stream has already been started before any request comes in 1147 if (!m_bIsActive) { 1148 ALOGE("%s: Channel not started!!", __func__); 1149 return NO_INIT; 1150 } 1151 1152 index = mMemory.getMatchBufIndex((void*)buffer); 1153 if(index < 0) { 1154 rc = registerBuffer(buffer); 1155 if (NO_ERROR != rc) { 1156 ALOGE("%s: On-the-fly buffer registration failed %d", 1157 __func__, rc); 1158 return rc; 1159 } 1160 1161 index = mMemory.getMatchBufIndex((void*)buffer); 1162 if (index < 0) { 1163 ALOGE("%s: Could not find object among registered buffers",__func__); 1164 return DEAD_OBJECT; 1165 } 1166 } 1167 rc = mMemory.markFrameNumber(index, frameNumber); 1168 1169 //Start the postprocessor for jpeg encoding. Pass mMemory as destination buffer 1170 mCurrentBufIndex = index; 1171 1172 // Start postprocessor 1173 m_postprocessor.start(this, metadata); 1174 1175 // Queue jpeg settings 1176 rc = queueJpegSetting(index, metadata); 1177 1178 if (pInputBuffer == NULL) 1179 mStreams[0]->bufDone(0); 1180 else { 1181 mm_camera_super_buf_t *src_frame = NULL; 1182 src_frame = (mm_camera_super_buf_t *)malloc( 1183 sizeof(mm_camera_super_buf_t)); 1184 if (src_frame == NULL) { 1185 ALOGE("%s: No memory for src frame", __func__); 1186 return NO_MEMORY; 1187 } 1188 memset(src_frame, 0, sizeof(mm_camera_super_buf_t)); 1189 src_frame->num_bufs = 1; 1190 src_frame->bufs[0] = pInputBuffer; 1191 1192 ALOGD("%s: Post-process started", __func__); 1193 ALOGD("%s: Issue call to reprocess", __func__); 1194 1195 m_postprocessor.processPPMetadata(metadata); 1196 m_postprocessor.processData(src_frame); 1197 } 1198 return rc; 1199} 1200 1201/*=========================================================================== 1202 * FUNCTION : dataNotifyCB 1203 * 1204 * DESCRIPTION: Channel Level callback used for super buffer data notify. 1205 * This function is registered with mm-camera-interface to handle 1206 * data notify 1207 * 1208 * PARAMETERS : 1209 * @recvd_frame : stream frame received 1210 * userdata : user data ptr 1211 * 1212 * RETURN : none 1213 *==========================================================================*/ 1214void QCamera3PicChannel::dataNotifyCB(mm_camera_super_buf_t *recvd_frame, 1215 void *userdata) 1216{ 1217 ALOGV("%s: E\n", __func__); 1218 QCamera3PicChannel *channel = (QCamera3PicChannel *)userdata; 1219 1220 if (channel == NULL) { 1221 ALOGE("%s: invalid channel pointer", __func__); 1222 return; 1223 } 1224 1225 if(channel->m_numStreams != 1) { 1226 ALOGE("%s: Error: Bug: This callback assumes one stream per channel",__func__); 1227 return; 1228 } 1229 1230 1231 if(channel->mStreams[0] == NULL) { 1232 ALOGE("%s: Error: Invalid Stream object",__func__); 1233 return; 1234 } 1235 1236 channel->QCamera3PicChannel::streamCbRoutine(recvd_frame, channel->mStreams[0]); 1237 1238 ALOGV("%s: X\n", __func__); 1239 return; 1240} 1241 1242/*=========================================================================== 1243 * FUNCTION : registerBuffer 1244 * 1245 * DESCRIPTION: register streaming buffer to the channel object 1246 * 1247 * PARAMETERS : 1248 * @buffer : buffer to be registered 1249 * 1250 * RETURN : int32_t type of status 1251 * NO_ERROR -- success 1252 * none-zero failure code 1253 *==========================================================================*/ 1254int32_t QCamera3PicChannel::registerBuffer(buffer_handle_t *buffer) 1255{ 1256 int rc = 0; 1257 1258 if ((uint32_t)mMemory.getCnt() > (mNumBufs - 1)) { 1259 ALOGE("%s: Trying to register more buffers than initially requested", 1260 __func__); 1261 return BAD_VALUE; 1262 } 1263 1264 if (0 == m_numStreams) { 1265 rc = initialize(); 1266 if (rc != NO_ERROR) { 1267 ALOGE("%s: Couldn't initialize camera stream %d", 1268 __func__, rc); 1269 return rc; 1270 } 1271 } 1272 rc = mMemory.registerBuffer(buffer); 1273 if (ALREADY_EXISTS == rc) { 1274 return NO_ERROR; 1275 } else if (NO_ERROR != rc) { 1276 ALOGE("%s: Buffer %p couldn't be registered %d", __func__, buffer, rc); 1277 return rc; 1278 } 1279 1280 return rc; 1281} 1282 1283void QCamera3PicChannel::streamCbRoutine(mm_camera_super_buf_t *super_frame, 1284 QCamera3Stream *stream) 1285{ 1286 //TODO 1287 //Used only for getting YUV. Jpeg callback will be sent back from channel 1288 //directly to HWI. Refer to func jpegEvtHandle 1289 1290 //Got the yuv callback. Calling yuv callback handler in PostProc 1291 uint8_t frameIndex; 1292 mm_camera_super_buf_t* frame = NULL; 1293 if(!super_frame) { 1294 ALOGE("%s: Invalid Super buffer",__func__); 1295 return; 1296 } 1297 1298 if(super_frame->num_bufs != 1) { 1299 ALOGE("%s: Multiple streams are not supported",__func__); 1300 return; 1301 } 1302 if(super_frame->bufs[0] == NULL ) { 1303 ALOGE("%s: Error, Super buffer frame does not contain valid buffer", 1304 __func__); 1305 return; 1306 } 1307 1308 frameIndex = (uint8_t)super_frame->bufs[0]->buf_idx; 1309 if(frameIndex >= mNumBufs) { 1310 ALOGE("%s: Error, Invalid index for buffer",__func__); 1311 if(stream) { 1312 stream->bufDone(frameIndex); 1313 } 1314 return; 1315 } 1316 1317 frame = (mm_camera_super_buf_t *)malloc(sizeof(mm_camera_super_buf_t)); 1318 if (frame == NULL) { 1319 ALOGE("%s: Error allocating memory to save received_frame structure.", 1320 __func__); 1321 if(stream) { 1322 stream->bufDone(frameIndex); 1323 } 1324 return; 1325 } 1326 *frame = *super_frame; 1327 m_postprocessor.processData(frame); 1328 free(super_frame); 1329 return; 1330} 1331 1332QCamera3Memory* QCamera3PicChannel::getStreamBufs(uint32_t len) 1333{ 1334 int rc = 0; 1335 1336 mYuvMemory = new QCamera3HeapMemory(); 1337 if (!mYuvMemory) { 1338 ALOGE("%s: unable to create metadata memory", __func__); 1339 return NULL; 1340 } 1341 1342 //Queue YUV buffers in the beginning mQueueAll = true 1343 rc = mYuvMemory->allocate(1, len, false); 1344 if (rc < 0) { 1345 ALOGE("%s: unable to allocate metadata memory", __func__); 1346 delete mYuvMemory; 1347 mYuvMemory = NULL; 1348 return NULL; 1349 } 1350 return mYuvMemory; 1351} 1352 1353void QCamera3PicChannel::putStreamBufs() 1354{ 1355 mMemory.unregisterBuffers(); 1356 1357 mYuvMemory->deallocate(); 1358 delete mYuvMemory; 1359 mYuvMemory = NULL; 1360} 1361 1362int32_t QCamera3PicChannel::queueReprocMetadata(metadata_buffer_t *metadata) 1363{ 1364 return m_postprocessor.processPPMetadata(metadata); 1365} 1366 1367int32_t QCamera3PicChannel::queueJpegSetting(int32_t index, metadata_buffer_t *metadata) 1368{ 1369 jpeg_settings_t *settings = 1370 (jpeg_settings_t *)malloc(sizeof(jpeg_settings_t)); 1371 1372 if (!settings) { 1373 ALOGE("%s: out of memory allocating jpeg_settings", __func__); 1374 return -ENOMEM; 1375 } 1376 1377 memset(settings, 0, sizeof(jpeg_settings_t)); 1378 1379 settings->out_buf_index = index; 1380 1381 settings->jpeg_orientation = 0; 1382 if (IS_PARM_VALID(CAM_INTF_META_JPEG_ORIENTATION, metadata)) { 1383 int32_t *orientation = (int32_t *)POINTER_OF( 1384 CAM_INTF_META_JPEG_ORIENTATION, metadata); 1385 settings->jpeg_orientation = *orientation; 1386 } 1387 1388 settings->jpeg_quality = 85; 1389 if (IS_PARM_VALID(CAM_INTF_META_JPEG_QUALITY, metadata)) { 1390 uint8_t *quality = (uint8_t *)POINTER_OF( 1391 CAM_INTF_META_JPEG_QUALITY, metadata); 1392 settings->jpeg_quality = *quality; 1393 } 1394 1395 if (IS_PARM_VALID(CAM_INTF_META_JPEG_THUMB_QUALITY, metadata)) { 1396 uint8_t *quality = (uint8_t *)POINTER_OF( 1397 CAM_INTF_META_JPEG_THUMB_QUALITY, metadata); 1398 settings->jpeg_thumb_quality = *quality; 1399 } 1400 1401 if (IS_PARM_VALID(CAM_INTF_META_JPEG_THUMB_SIZE, metadata)) { 1402 cam_dimension_t *dimension = (cam_dimension_t *)POINTER_OF( 1403 CAM_INTF_META_JPEG_THUMB_SIZE, metadata); 1404 settings->thumbnail_size = *dimension; 1405 } 1406 1407 settings->gps_timestamp_valid = 0; 1408 if (IS_PARM_VALID(CAM_INTF_META_JPEG_GPS_TIMESTAMP, metadata)) { 1409 int64_t *timestamp = (int64_t *)POINTER_OF( 1410 CAM_INTF_META_JPEG_GPS_TIMESTAMP, metadata); 1411 settings->gps_timestamp = *timestamp; 1412 settings->gps_timestamp_valid = 1; 1413 } 1414 1415 settings->gps_coordinates_valid = 0; 1416 if (IS_PARM_VALID(CAM_INTF_META_JPEG_GPS_COORDINATES, metadata)) { 1417 double *coordinates = (double *)POINTER_OF( 1418 CAM_INTF_META_JPEG_GPS_COORDINATES, metadata); 1419 memcpy(settings->gps_coordinates, coordinates, 3*sizeof(double)); 1420 settings->gps_coordinates_valid = 1; 1421 } 1422 1423 if (IS_PARM_VALID(CAM_INTF_META_JPEG_GPS_PROC_METHODS, metadata)) { 1424 char *proc_methods = (char *)POINTER_OF( 1425 CAM_INTF_META_JPEG_GPS_PROC_METHODS, metadata); 1426 memset(settings->gps_processing_method, 0, 1427 sizeof(settings->gps_processing_method)); 1428 strncpy(settings->gps_processing_method, proc_methods, 1429 sizeof(settings->gps_processing_method)); 1430 } 1431 1432 return m_postprocessor.processJpegSettingData(settings); 1433} 1434 1435/*=========================================================================== 1436 * FUNCTION : getRational 1437 * 1438 * DESCRIPTION: compose rational struct 1439 * 1440 * PARAMETERS : 1441 * @rat : ptr to struct to store rational info 1442 * @num :num of the rational 1443 * @denom : denom of the rational 1444 * 1445 * RETURN : int32_t type of status 1446 * NO_ERROR -- success 1447 * none-zero failure code 1448 *==========================================================================*/ 1449int32_t getRational(rat_t *rat, int num, int denom) 1450{ 1451 if (NULL == rat) { 1452 ALOGE("%s: NULL rat input", __func__); 1453 return BAD_VALUE; 1454 } 1455 rat->num = num; 1456 rat->denom = denom; 1457 return NO_ERROR; 1458} 1459 1460/*=========================================================================== 1461 * FUNCTION : parseGPSCoordinate 1462 * 1463 * DESCRIPTION: parse GPS coordinate string 1464 * 1465 * PARAMETERS : 1466 * @coord_str : [input] coordinate string 1467 * @coord : [output] ptr to struct to store coordinate 1468 * 1469 * RETURN : int32_t type of status 1470 * NO_ERROR -- success 1471 * none-zero failure code 1472 *==========================================================================*/ 1473int parseGPSCoordinate(const char *coord_str, rat_t* coord) 1474{ 1475 if(coord == NULL) { 1476 ALOGE("%s: error, invalid argument coord == NULL", __func__); 1477 return BAD_VALUE; 1478 } 1479 float degF = atof(coord_str); 1480 if (degF < 0) { 1481 degF = -degF; 1482 } 1483 float minF = (degF - (int) degF) * 60; 1484 float secF = (minF - (int) minF) * 60; 1485 1486 getRational(&coord[0], (int)degF, 1); 1487 getRational(&coord[1], (int)minF, 1); 1488 getRational(&coord[2], (int)(secF * 10000), 10000); 1489 return NO_ERROR; 1490} 1491 1492/*=========================================================================== 1493 * FUNCTION : getExifDateTime 1494 * 1495 * DESCRIPTION: query exif date time 1496 * 1497 * PARAMETERS : 1498 * @dateTime : string to store exif date time 1499 * @subsecTime : string to store exif subsec time 1500 * @count : length of the dateTime string 1501 * @subsecCount: length of the subsecTime string 1502 * 1503 * RETURN : int32_t type of status 1504 * NO_ERROR -- success 1505 * none-zero failure code 1506 *==========================================================================*/ 1507int32_t getExifDateTime(char *dateTime, char *subsecTime, 1508 uint32_t &count, uint32_t &subsecCount) 1509{ 1510 //get time and date from system 1511 struct timeval tv; 1512 struct tm *timeinfo; 1513 1514 gettimeofday(&tv, NULL); 1515 timeinfo = localtime(&tv.tv_sec); 1516 //Write datetime according to EXIF Spec 1517 //"YYYY:MM:DD HH:MM:SS" (20 chars including \0) 1518 snprintf(dateTime, 20, "%04d:%02d:%02d %02d:%02d:%02d", 1519 timeinfo->tm_year + 1900, timeinfo->tm_mon + 1, 1520 timeinfo->tm_mday, timeinfo->tm_hour, 1521 timeinfo->tm_min, timeinfo->tm_sec); 1522 count = 20; 1523 1524 //Write subsec according to EXIF Sepc 1525 snprintf(subsecTime, 7, "%06ld", tv.tv_usec); 1526 subsecCount = 7; 1527 return NO_ERROR; 1528} 1529 1530/*=========================================================================== 1531 * FUNCTION : getExifFocalLength 1532 * 1533 * DESCRIPTION: get exif focal lenght 1534 * 1535 * PARAMETERS : 1536 * @focalLength : ptr to rational strcut to store focal lenght 1537 * 1538 * RETURN : int32_t type of status 1539 * NO_ERROR -- success 1540 * none-zero failure code 1541 *==========================================================================*/ 1542int32_t getExifFocalLength(rat_t *focalLength, float value) 1543{ 1544 int focalLengthValue = 1545 (int)(value * FOCAL_LENGTH_DECIMAL_PRECISION); 1546 return getRational(focalLength, focalLengthValue, FOCAL_LENGTH_DECIMAL_PRECISION); 1547} 1548 1549/*=========================================================================== 1550 * FUNCTION : getExifExpTimeInfo 1551 * 1552 * DESCRIPTION: get exif exposure time information 1553 * 1554 * PARAMETERS : 1555 * @expoTimeInfo : expousure time value 1556 * RETURN : nt32_t type of status 1557 * NO_ERROR -- success 1558 * none-zero failure code 1559 *==========================================================================*/ 1560int32_t getExifExpTimeInfo(rat_t *expoTimeInfo, int64_t value) 1561{ 1562 1563 int cal_exposureTime; 1564 if (value != 0) 1565 cal_exposureTime = value; 1566 else 1567 cal_exposureTime = 60; 1568 1569 return getRational(expoTimeInfo, 1, cal_exposureTime); 1570} 1571 1572/*=========================================================================== 1573 * FUNCTION : getExifGpsProcessingMethod 1574 * 1575 * DESCRIPTION: get GPS processing method 1576 * 1577 * PARAMETERS : 1578 * @gpsProcessingMethod : string to store GPS process method 1579 * @count : lenght of the string 1580 * 1581 * RETURN : int32_t type of status 1582 * NO_ERROR -- success 1583 * none-zero failure code 1584 *==========================================================================*/ 1585int32_t getExifGpsProcessingMethod(char *gpsProcessingMethod, 1586 uint32_t &count, char* value) 1587{ 1588 if(value != NULL) { 1589 memcpy(gpsProcessingMethod, ExifAsciiPrefix, EXIF_ASCII_PREFIX_SIZE); 1590 count = EXIF_ASCII_PREFIX_SIZE; 1591 strncpy(gpsProcessingMethod + EXIF_ASCII_PREFIX_SIZE, value, strlen(value)); 1592 count += strlen(value); 1593 gpsProcessingMethod[count++] = '\0'; // increase 1 for the last NULL char 1594 return NO_ERROR; 1595 } else { 1596 return BAD_VALUE; 1597 } 1598} 1599 1600/*=========================================================================== 1601 * FUNCTION : getExifLatitude 1602 * 1603 * DESCRIPTION: get exif latitude 1604 * 1605 * PARAMETERS : 1606 * @latitude : ptr to rational struct to store latitude info 1607 * @ladRef : charater to indicate latitude reference 1608 * 1609 * RETURN : int32_t type of status 1610 * NO_ERROR -- success 1611 * none-zero failure code 1612 *==========================================================================*/ 1613int32_t getExifLatitude(rat_t *latitude, 1614 char *latRef, double value) 1615{ 1616 char str[30]; 1617 snprintf(str, sizeof(str), "%f", value); 1618 if(str != NULL) { 1619 parseGPSCoordinate(str, latitude); 1620 1621 //set Latitude Ref 1622 float latitudeValue = strtof(str, 0); 1623 if(latitudeValue < 0.0f) { 1624 latRef[0] = 'S'; 1625 } else { 1626 latRef[0] = 'N'; 1627 } 1628 latRef[1] = '\0'; 1629 return NO_ERROR; 1630 }else{ 1631 return BAD_VALUE; 1632 } 1633} 1634 1635/*=========================================================================== 1636 * FUNCTION : getExifLongitude 1637 * 1638 * DESCRIPTION: get exif longitude 1639 * 1640 * PARAMETERS : 1641 * @longitude : ptr to rational struct to store longitude info 1642 * @lonRef : charater to indicate longitude reference 1643 * 1644 * RETURN : int32_t type of status 1645 * NO_ERROR -- success 1646 * none-zero failure code 1647 *==========================================================================*/ 1648int32_t getExifLongitude(rat_t *longitude, 1649 char *lonRef, double value) 1650{ 1651 char str[30]; 1652 snprintf(str, sizeof(str), "%f", value); 1653 if(str != NULL) { 1654 parseGPSCoordinate(str, longitude); 1655 1656 //set Longitude Ref 1657 float longitudeValue = strtof(str, 0); 1658 if(longitudeValue < 0.0f) { 1659 lonRef[0] = 'W'; 1660 } else { 1661 lonRef[0] = 'E'; 1662 } 1663 lonRef[1] = '\0'; 1664 return NO_ERROR; 1665 }else{ 1666 return BAD_VALUE; 1667 } 1668} 1669 1670/*=========================================================================== 1671 * FUNCTION : getExifAltitude 1672 * 1673 * DESCRIPTION: get exif altitude 1674 * 1675 * PARAMETERS : 1676 * @altitude : ptr to rational struct to store altitude info 1677 * @altRef : charater to indicate altitude reference 1678 * 1679 * RETURN : int32_t type of status 1680 * NO_ERROR -- success 1681 * none-zero failure code 1682 *==========================================================================*/ 1683int32_t getExifAltitude(rat_t *altitude, 1684 char *altRef, double value) 1685{ 1686 char str[30]; 1687 snprintf(str, sizeof(str), "%f", value); 1688 if(str != NULL) { 1689 double value = atof(str); 1690 *altRef = 0; 1691 if(value < 0){ 1692 *altRef = 1; 1693 value = -value; 1694 } 1695 return getRational(altitude, value*1000, 1000); 1696 }else{ 1697 return BAD_VALUE; 1698 } 1699} 1700 1701/*=========================================================================== 1702 * FUNCTION : getExifGpsDateTimeStamp 1703 * 1704 * DESCRIPTION: get exif GPS date time stamp 1705 * 1706 * PARAMETERS : 1707 * @gpsDateStamp : GPS date time stamp string 1708 * @bufLen : length of the string 1709 * @gpsTimeStamp : ptr to rational struct to store time stamp info 1710 * 1711 * RETURN : int32_t type of status 1712 * NO_ERROR -- success 1713 * none-zero failure code 1714 *==========================================================================*/ 1715int32_t getExifGpsDateTimeStamp(char *gpsDateStamp, 1716 uint32_t bufLen, 1717 rat_t *gpsTimeStamp, int64_t value) 1718{ 1719 char str[30]; 1720 snprintf(str, sizeof(str), "%lld", value); 1721 if(str != NULL) { 1722 time_t unixTime = (time_t)atol(str); 1723 struct tm *UTCTimestamp = gmtime(&unixTime); 1724 1725 strftime(gpsDateStamp, bufLen, "%Y:%m:%d", UTCTimestamp); 1726 1727 getRational(&gpsTimeStamp[0], UTCTimestamp->tm_hour, 1); 1728 getRational(&gpsTimeStamp[1], UTCTimestamp->tm_min, 1); 1729 getRational(&gpsTimeStamp[2], UTCTimestamp->tm_sec, 1); 1730 1731 return NO_ERROR; 1732 } else { 1733 return BAD_VALUE; 1734 } 1735} 1736 1737int32_t getExifExposureValue(srat_t* exposure_val, int32_t exposure_comp, 1738 cam_rational_type_t step) 1739{ 1740 exposure_val->num = exposure_comp * step.numerator; 1741 exposure_val->denom = step.denominator; 1742 return 0; 1743} 1744/*=========================================================================== 1745 * FUNCTION : getExifData 1746 * 1747 * DESCRIPTION: get exif data to be passed into jpeg encoding 1748 * 1749 * PARAMETERS : none 1750 * 1751 * RETURN : exif data from user setting and GPS 1752 *==========================================================================*/ 1753QCamera3Exif *QCamera3PicChannel::getExifData(metadata_buffer_t *metadata, 1754 jpeg_settings_t *jpeg_settings) 1755{ 1756 QCamera3Exif *exif = new QCamera3Exif(); 1757 if (exif == NULL) { 1758 ALOGE("%s: No memory for QCamera3Exif", __func__); 1759 return NULL; 1760 } 1761 1762 int32_t rc = NO_ERROR; 1763 uint32_t count = 0; 1764 1765 // add exif entries 1766 { 1767 char dateTime[20]; 1768 char subsecTime[7]; 1769 uint32_t subsecCount; 1770 memset(dateTime, 0, sizeof(dateTime)); 1771 memset(subsecTime, 0, sizeof(subsecTime)); 1772 count = 20; 1773 subsecCount = 7; 1774 rc = getExifDateTime(dateTime, subsecTime, count, subsecCount); 1775 if(rc == NO_ERROR) { 1776 exif->addEntry(EXIFTAGID_DATE_TIME, 1777 EXIF_ASCII, 1778 count, 1779 (void *)dateTime); 1780 exif->addEntry(EXIFTAGID_EXIF_DATE_TIME_ORIGINAL, 1781 EXIF_ASCII, 1782 count, 1783 (void *)dateTime); 1784 exif->addEntry(EXIFTAGID_EXIF_DATE_TIME_DIGITIZED, 1785 EXIF_ASCII, 1786 count, 1787 (void *)dateTime); 1788 exif->addEntry(EXIFTAGID_SUBSEC_TIME, 1789 EXIF_ASCII, 1790 subsecCount, 1791 (void *)subsecTime); 1792 exif->addEntry(EXIFTAGID_SUBSEC_TIME_ORIGINAL, 1793 EXIF_ASCII, 1794 subsecCount, 1795 (void *)subsecTime); 1796 exif->addEntry(EXIFTAGID_SUBSEC_TIME_DIGITIZED, 1797 EXIF_ASCII, 1798 subsecCount, 1799 (void *)subsecTime); 1800 } else { 1801 ALOGE("%s: getExifDateTime failed", __func__); 1802 } 1803 } 1804 1805 if (IS_PARM_VALID(CAM_INTF_META_LENS_FOCAL_LENGTH, metadata)) { 1806 float focal_length = *(float *)POINTER_OF( 1807 CAM_INTF_META_LENS_FOCAL_LENGTH, metadata); 1808 rat_t focalLength; 1809 rc = getExifFocalLength(&focalLength, focal_length); 1810 if (rc == NO_ERROR) { 1811 exif->addEntry(EXIFTAGID_FOCAL_LENGTH, 1812 EXIF_RATIONAL, 1813 1, 1814 (void *)&(focalLength)); 1815 } else { 1816 ALOGE("%s: getExifFocalLength failed", __func__); 1817 } 1818 } 1819 1820 if (IS_PARM_VALID(CAM_INTF_META_SENSOR_SENSITIVITY, metadata)) { 1821 int16_t isoSpeed = *(int32_t *)POINTER_OF( 1822 CAM_INTF_META_SENSOR_SENSITIVITY, metadata); 1823 exif->addEntry(EXIFTAGID_ISO_SPEED_RATING, 1824 EXIF_SHORT, 1825 1, 1826 (void *)&(isoSpeed)); 1827 } 1828 1829 if (IS_PARM_VALID(CAM_INTF_META_SENSOR_EXPOSURE_TIME, metadata)) { 1830 int64_t sensor_exposure_time = *(int64_t *)POINTER_OF( 1831 CAM_INTF_META_SENSOR_EXPOSURE_TIME, metadata); 1832 rat_t sensorExpTime; 1833 rc = getExifExpTimeInfo(&sensorExpTime, sensor_exposure_time); 1834 if (rc == NO_ERROR){ 1835 exif->addEntry(EXIFTAGID_EXPOSURE_TIME, 1836 EXIF_RATIONAL, 1837 1, 1838 (void *)&(sensorExpTime)); 1839 } else { 1840 ALOGE("%s: getExifExpTimeInfo failed", __func__); 1841 } 1842 } 1843 1844 if (strlen(jpeg_settings->gps_processing_method) > 0) { 1845 char gpsProcessingMethod[ 1846 EXIF_ASCII_PREFIX_SIZE + GPS_PROCESSING_METHOD_SIZE]; 1847 count = 0; 1848 rc = getExifGpsProcessingMethod(gpsProcessingMethod, 1849 count, jpeg_settings->gps_processing_method); 1850 if(rc == NO_ERROR) { 1851 exif->addEntry(EXIFTAGID_GPS_PROCESSINGMETHOD, 1852 EXIF_ASCII, 1853 count, 1854 (void *)gpsProcessingMethod); 1855 } else { 1856 ALOGE("%s: getExifGpsProcessingMethod failed", __func__); 1857 } 1858 } 1859 1860 if (jpeg_settings->gps_coordinates_valid) { 1861 1862 //latitude 1863 rat_t latitude[3]; 1864 char latRef[2]; 1865 rc = getExifLatitude(latitude, latRef, 1866 jpeg_settings->gps_coordinates[0]); 1867 if(rc == NO_ERROR) { 1868 exif->addEntry(EXIFTAGID_GPS_LATITUDE, 1869 EXIF_RATIONAL, 1870 3, 1871 (void *)latitude); 1872 exif->addEntry(EXIFTAGID_GPS_LATITUDE_REF, 1873 EXIF_ASCII, 1874 2, 1875 (void *)latRef); 1876 } else { 1877 ALOGE("%s: getExifLatitude failed", __func__); 1878 } 1879 1880 //longitude 1881 rat_t longitude[3]; 1882 char lonRef[2]; 1883 rc = getExifLongitude(longitude, lonRef, 1884 jpeg_settings->gps_coordinates[1]); 1885 if(rc == NO_ERROR) { 1886 exif->addEntry(EXIFTAGID_GPS_LONGITUDE, 1887 EXIF_RATIONAL, 1888 3, 1889 (void *)longitude); 1890 1891 exif->addEntry(EXIFTAGID_GPS_LONGITUDE_REF, 1892 EXIF_ASCII, 1893 2, 1894 (void *)lonRef); 1895 } else { 1896 ALOGE("%s: getExifLongitude failed", __func__); 1897 } 1898 1899 //altitude 1900 rat_t altitude; 1901 char altRef; 1902 rc = getExifAltitude(&altitude, &altRef, 1903 jpeg_settings->gps_coordinates[2]); 1904 if(rc == NO_ERROR) { 1905 exif->addEntry(EXIFTAGID_GPS_ALTITUDE, 1906 EXIF_RATIONAL, 1907 1, 1908 (void *)&(altitude)); 1909 1910 exif->addEntry(EXIFTAGID_GPS_ALTITUDE_REF, 1911 EXIF_BYTE, 1912 1, 1913 (void *)&altRef); 1914 } else { 1915 ALOGE("%s: getExifAltitude failed", __func__); 1916 } 1917 } 1918 1919 if (jpeg_settings->gps_timestamp_valid) { 1920 1921 char gpsDateStamp[20]; 1922 rat_t gpsTimeStamp[3]; 1923 rc = getExifGpsDateTimeStamp(gpsDateStamp, 20, gpsTimeStamp, 1924 jpeg_settings->gps_timestamp); 1925 if(rc == NO_ERROR) { 1926 exif->addEntry(EXIFTAGID_GPS_DATESTAMP, 1927 EXIF_ASCII, 1928 strlen(gpsDateStamp) + 1, 1929 (void *)gpsDateStamp); 1930 1931 exif->addEntry(EXIFTAGID_GPS_TIMESTAMP, 1932 EXIF_RATIONAL, 1933 3, 1934 (void *)gpsTimeStamp); 1935 } else { 1936 ALOGE("%s: getExifGpsDataTimeStamp failed", __func__); 1937 } 1938 } 1939 1940 if (IS_PARM_VALID(CAM_INTF_PARM_EV, metadata) && 1941 IS_PARM_VALID(CAM_INTF_PARM_EV_STEP, metadata)) { 1942 int32_t exposure_comp = *(int32_t *)POINTER_OF( 1943 CAM_INTF_PARM_EV, metadata); 1944 cam_rational_type_t comp_step = *(cam_rational_type_t *)POINTER_OF( 1945 CAM_INTF_PARM_EV_STEP, metadata); 1946 srat_t exposure_val; 1947 rc = getExifExposureValue(&exposure_val, exposure_comp, comp_step); 1948 if(rc == NO_ERROR) { 1949 exif->addEntry(EXIFTAGID_EXPOSURE_BIAS_VALUE, 1950 EXIF_SRATIONAL, 1951 1, 1952 (void *)(&exposure_val)); 1953 } else { 1954 ALOGE("%s: getExifExposureValue failed ", __func__); 1955 } 1956 } 1957 1958 char value[PROPERTY_VALUE_MAX]; 1959 if (property_get("ro.product.manufacturer", value, "QCOM-AA") > 0) { 1960 exif->addEntry(EXIFTAGID_MAKE, 1961 EXIF_ASCII, 1962 strlen(value) + 1, 1963 (void *)value); 1964 } else { 1965 ALOGE("%s: getExifMaker failed", __func__); 1966 } 1967 1968 if (property_get("ro.product.model", value, "QCAM-AA") > 0) { 1969 exif->addEntry(EXIFTAGID_MODEL, 1970 EXIF_ASCII, 1971 strlen(value) + 1, 1972 (void *)value); 1973 } else { 1974 ALOGE("%s: getExifModel failed", __func__); 1975 } 1976 1977 return exif; 1978} 1979 1980void QCamera3PicChannel::overrideYuvSize(uint32_t width, uint32_t height) 1981{ 1982 mYuvWidth = width; 1983 mYuvHeight = height; 1984} 1985 1986int QCamera3PicChannel::kMaxBuffers = 1; 1987 1988/*=========================================================================== 1989 * FUNCTION : QCamera3ReprocessChannel 1990 * 1991 * DESCRIPTION: constructor of QCamera3ReprocessChannel 1992 * 1993 * PARAMETERS : 1994 * @cam_handle : camera handle 1995 * @cam_ops : ptr to camera ops table 1996 * @pp_mask : post-proccess feature mask 1997 * 1998 * RETURN : none 1999 *==========================================================================*/ 2000QCamera3ReprocessChannel::QCamera3ReprocessChannel(uint32_t cam_handle, 2001 mm_camera_ops_t *cam_ops, 2002 channel_cb_routine cb_routine, 2003 cam_padding_info_t *paddingInfo, 2004 void *userData, void *ch_hdl) : 2005 QCamera3Channel(cam_handle, cam_ops, cb_routine, paddingInfo, userData), 2006 picChHandle(ch_hdl), 2007 m_pSrcChannel(NULL), 2008 m_pMetaChannel(NULL), 2009 mMemory(NULL) 2010{ 2011 memset(mSrcStreamHandles, 0, sizeof(mSrcStreamHandles)); 2012} 2013 2014 2015/*=========================================================================== 2016 * FUNCTION : QCamera3ReprocessChannel 2017 * 2018 * DESCRIPTION: constructor of QCamera3ReprocessChannel 2019 * 2020 * PARAMETERS : 2021 * @cam_handle : camera handle 2022 * @cam_ops : ptr to camera ops table 2023 * @pp_mask : post-proccess feature mask 2024 * 2025 * RETURN : none 2026 *==========================================================================*/ 2027int32_t QCamera3ReprocessChannel::initialize() 2028{ 2029 int32_t rc = NO_ERROR; 2030 mm_camera_channel_attr_t attr; 2031 2032 memset(&attr, 0, sizeof(mm_camera_channel_attr_t)); 2033 attr.notify_mode = MM_CAMERA_SUPER_BUF_NOTIFY_CONTINUOUS; 2034 attr.max_unmatched_frames = 1; 2035 2036 rc = init(&attr, NULL); 2037 if (rc < 0) { 2038 ALOGE("%s: init failed", __func__); 2039 } 2040 return rc; 2041} 2042 2043 2044/*=========================================================================== 2045 * FUNCTION : QCamera3ReprocessChannel 2046 * 2047 * DESCRIPTION: constructor of QCamera3ReprocessChannel 2048 * 2049 * PARAMETERS : 2050 * @cam_handle : camera handle 2051 * @cam_ops : ptr to camera ops table 2052 * @pp_mask : post-proccess feature mask 2053 * 2054 * RETURN : none 2055 *==========================================================================*/ 2056void QCamera3ReprocessChannel::streamCbRoutine(mm_camera_super_buf_t *super_frame, 2057 QCamera3Stream *stream) 2058{ 2059 //Got the pproc data callback. Now send to jpeg encoding 2060 uint8_t frameIndex; 2061 mm_camera_super_buf_t* frame = NULL; 2062 QCamera3PicChannel *obj = (QCamera3PicChannel *)picChHandle; 2063 2064 if(!super_frame) { 2065 ALOGE("%s: Invalid Super buffer",__func__); 2066 return; 2067 } 2068 2069 if(super_frame->num_bufs != 1) { 2070 ALOGE("%s: Multiple streams are not supported",__func__); 2071 return; 2072 } 2073 if(super_frame->bufs[0] == NULL ) { 2074 ALOGE("%s: Error, Super buffer frame does not contain valid buffer", 2075 __func__); 2076 return; 2077 } 2078 2079 frameIndex = (uint8_t)super_frame->bufs[0]->buf_idx; 2080 frame = (mm_camera_super_buf_t *)malloc(sizeof(mm_camera_super_buf_t)); 2081 if (frame == NULL) { 2082 ALOGE("%s: Error allocating memory to save received_frame structure.", 2083 __func__); 2084 if(stream) { 2085 stream->bufDone(frameIndex); 2086 } 2087 return; 2088 } 2089 *frame = *super_frame; 2090 obj->m_postprocessor.processPPData(frame); 2091 free(super_frame); 2092 return; 2093} 2094 2095/*=========================================================================== 2096 * FUNCTION : QCamera3ReprocessChannel 2097 * 2098 * DESCRIPTION: default constructor of QCamera3ReprocessChannel 2099 * 2100 * PARAMETERS : none 2101 * 2102 * RETURN : none 2103 *==========================================================================*/ 2104QCamera3ReprocessChannel::QCamera3ReprocessChannel() : 2105 m_pSrcChannel(NULL), 2106 m_pMetaChannel(NULL) 2107{ 2108} 2109 2110/*=========================================================================== 2111 * FUNCTION : getStreamBufs 2112 * 2113 * DESCRIPTION: register the buffers of the reprocess channel 2114 * 2115 * PARAMETERS : none 2116 * 2117 * RETURN : QCamera3Memory * 2118 *==========================================================================*/ 2119QCamera3Memory* QCamera3ReprocessChannel::getStreamBufs(uint32_t len) 2120{ 2121 int rc = 0; 2122 2123 mMemory = new QCamera3HeapMemory(); 2124 if (!mMemory) { 2125 ALOGE("%s: unable to create reproc memory", __func__); 2126 return NULL; 2127 } 2128 2129 //Queue YUV buffers in the beginning mQueueAll = true 2130 rc = mMemory->allocate(2, len, true); 2131 if (rc < 0) { 2132 ALOGE("%s: unable to allocate reproc memory", __func__); 2133 delete mMemory; 2134 mMemory = NULL; 2135 return NULL; 2136 } 2137 return mMemory; 2138} 2139 2140/*=========================================================================== 2141 * FUNCTION : getStreamBufs 2142 * 2143 * DESCRIPTION: register the buffers of the reprocess channel 2144 * 2145 * PARAMETERS : none 2146 * 2147 * RETURN : 2148 *==========================================================================*/ 2149void QCamera3ReprocessChannel::putStreamBufs() 2150{ 2151 mMemory->deallocate(); 2152 delete mMemory; 2153 mMemory = NULL; 2154} 2155 2156/*=========================================================================== 2157 * FUNCTION : ~QCamera3ReprocessChannel 2158 * 2159 * DESCRIPTION: destructor of QCamera3ReprocessChannel 2160 * 2161 * PARAMETERS : none 2162 * 2163 * RETURN : none 2164 *==========================================================================*/ 2165QCamera3ReprocessChannel::~QCamera3ReprocessChannel() 2166{ 2167} 2168 2169/*=========================================================================== 2170 * FUNCTION : getStreamBySrcHandle 2171 * 2172 * DESCRIPTION: find reprocess stream by its source stream handle 2173 * 2174 * PARAMETERS : 2175 * @srcHandle : source stream handle 2176 * 2177 * RETURN : ptr to reprocess stream if found. NULL if not found 2178 *==========================================================================*/ 2179QCamera3Stream * QCamera3ReprocessChannel::getStreamBySrcHandle(uint32_t srcHandle) 2180{ 2181 QCamera3Stream *pStream = NULL; 2182 2183 for (int i = 0; i < m_numStreams; i++) { 2184 if (mSrcStreamHandles[i] == srcHandle) { 2185 pStream = mStreams[i]; 2186 break; 2187 } 2188 } 2189 return pStream; 2190} 2191 2192/*=========================================================================== 2193 * FUNCTION : getSrcStreamBySrcHandle 2194 * 2195 * DESCRIPTION: find source stream by source stream handle 2196 * 2197 * PARAMETERS : 2198 * @srcHandle : source stream handle 2199 * 2200 * RETURN : ptr to reprocess stream if found. NULL if not found 2201 *==========================================================================*/ 2202QCamera3Stream * QCamera3ReprocessChannel::getSrcStreamBySrcHandle(uint32_t srcHandle) 2203{ 2204 QCamera3Stream *pStream = NULL; 2205 2206 for (int i = 0; i < m_numStreams; i++) { 2207 if (mSrcStreamHandles[i] == srcHandle) { 2208 pStream = m_pSrcChannel->getStreamByIndex(i); 2209 break; 2210 } 2211 } 2212 return pStream; 2213} 2214 2215/*=========================================================================== 2216 * FUNCTION : metadataBufDone 2217 * 2218 * DESCRIPTION: buf done method for a metadata buffer 2219 * 2220 * PARAMETERS : 2221 * @recvd_frame : received metadata frame 2222 * 2223 * RETURN : 2224 *==========================================================================*/ 2225int32_t QCamera3ReprocessChannel::metadataBufDone(mm_camera_super_buf_t *recvd_frame) 2226{ 2227 int32_t rc; 2228 rc = ((QCamera3MetadataChannel*)m_pMetaChannel)->bufDone(recvd_frame); 2229 free(recvd_frame); 2230 recvd_frame = NULL; 2231 return rc; 2232} 2233 2234/*=========================================================================== 2235 * FUNCTION : doReprocess 2236 * 2237 * DESCRIPTION: request to do a reprocess on the frame 2238 * 2239 * PARAMETERS : 2240 * @frame : frame to be performed a reprocess 2241 * 2242 * RETURN : int32_t type of status 2243 * NO_ERROR -- success 2244 * none-zero failure code 2245 *==========================================================================*/ 2246int32_t QCamera3ReprocessChannel::doReprocess(mm_camera_super_buf_t *frame, 2247 mm_camera_super_buf_t *meta_frame) 2248{ 2249 int32_t rc = 0; 2250 if (m_numStreams < 1) { 2251 ALOGE("%s: No reprocess stream is created", __func__); 2252 return -1; 2253 } 2254 if (m_pSrcChannel == NULL) { 2255 ALOGE("%s: No source channel for reprocess", __func__); 2256 return -1; 2257 } 2258 for (int i = 0; i < frame->num_bufs; i++) { 2259 QCamera3Stream *pStream = getStreamBySrcHandle(frame->bufs[i]->stream_id); 2260 if (pStream != NULL) { 2261 cam_stream_parm_buffer_t param; 2262 memset(¶m, 0, sizeof(cam_stream_parm_buffer_t)); 2263 param.type = CAM_STREAM_PARAM_TYPE_DO_REPROCESS; 2264 param.reprocess.buf_index = frame->bufs[i]->buf_idx; 2265 if (meta_frame != NULL) { 2266 param.reprocess.meta_present = 1; 2267 param.reprocess.meta_stream_handle = m_pMetaChannel->mStreams[0]->getMyServerID(); 2268 param.reprocess.meta_buf_index = meta_frame->bufs[0]->buf_idx; 2269 } 2270 rc = pStream->setParameter(param); 2271 if (rc != NO_ERROR) { 2272 ALOGE("%s: stream setParameter for reprocess failed", __func__); 2273 break; 2274 } 2275 } 2276 } 2277 return rc; 2278} 2279 2280int32_t QCamera3ReprocessChannel::doReprocessOffline(mm_camera_super_buf_t *frame, 2281 metadata_buffer_t *metadata) 2282{ 2283 int32_t rc = 0; 2284 if (m_numStreams < 1) { 2285 ALOGE("%s: No reprocess stream is created", __func__); 2286 return -1; 2287 } 2288 if (m_pSrcChannel == NULL) { 2289 ALOGE("%s: No source channel for reprocess", __func__); 2290 return -1; 2291 } 2292 2293 uint32_t buf_idx = 0; 2294 for (int i = 0; i < frame->num_bufs; i++) { 2295 QCamera3Stream *pStream = getStreamBySrcHandle(frame->bufs[i]->stream_id); 2296 QCamera3Stream *pSrcStream = getSrcStreamBySrcHandle(frame->bufs[i]->stream_id); 2297 if (pStream != NULL && pSrcStream != NULL) { 2298 2299 rc = mStreams[i]->mapBuf( 2300 CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF, 2301 buf_idx, -1, 2302 frame->bufs[i]->fd, frame->bufs[i]->frame_len); 2303 2304 if (rc == NO_ERROR) { 2305 cam_stream_parm_buffer_t param; 2306 memset(¶m, 0, sizeof(cam_stream_parm_buffer_t)); 2307 param.type = CAM_STREAM_PARAM_TYPE_DO_REPROCESS; 2308 param.reprocess.buf_index = frame->bufs[i]->buf_idx; 2309 2310 param.reprocess.meta_present = 1; 2311 char* private_data = (char *)POINTER_OF( 2312 CAM_INTF_META_PRIVATE_DATA, metadata); 2313 memcpy(param.reprocess.private_data, private_data, 2314 MAX_METADATA_PAYLOAD_SIZE); 2315 2316 // Find crop info for reprocess stream 2317 cam_crop_data_t *crop_data = (cam_crop_data_t *) 2318 POINTER_OF(CAM_INTF_META_CROP_DATA, metadata); 2319 for (int j = 0; j < crop_data->num_of_streams; j++) { 2320 if (crop_data->crop_info[j].stream_id == 2321 pSrcStream->getMyServerID()) { 2322 param.reprocess.crop_rect = 2323 crop_data->crop_info[j].crop; 2324 break; 2325 } 2326 } 2327 rc = pStream->setParameter(param); 2328 if (rc != NO_ERROR) { 2329 ALOGE("%s: stream setParameter for reprocess failed", __func__); 2330 break; 2331 } 2332 } 2333 } 2334 } 2335 return rc; 2336} 2337 2338 2339/*=========================================================================== 2340 * FUNCTION : doReprocess 2341 * 2342 * DESCRIPTION: request to do a reprocess on the frame 2343 * 2344 * PARAMETERS : 2345 * @buf_fd : fd to the input buffer that needs reprocess 2346 * @buf_lenght : length of the input buffer 2347 * @ret_val : result of reprocess. 2348 * Example: Could be faceID in case of register face image. 2349 * 2350 * RETURN : int32_t type of status 2351 * NO_ERROR -- success 2352 * none-zero failure code 2353 *==========================================================================*/ 2354int32_t QCamera3ReprocessChannel::doReprocess(int buf_fd, 2355 uint32_t buf_length, 2356 int32_t &ret_val, 2357 mm_camera_super_buf_t *meta_frame) 2358{ 2359 int32_t rc = 0; 2360 if (m_numStreams < 1) { 2361 ALOGE("%s: No reprocess stream is created", __func__); 2362 return -1; 2363 } 2364 if (meta_frame == NULL) { 2365 ALOGE("%s: Did not get corresponding metadata in time", __func__); 2366 return -1; 2367 } 2368 2369 uint32_t buf_idx = 0; 2370 for (int i = 0; i < m_numStreams; i++) { 2371 rc = mStreams[i]->mapBuf(CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF, 2372 buf_idx, -1, 2373 buf_fd, buf_length); 2374 2375 if (rc == NO_ERROR) { 2376 cam_stream_parm_buffer_t param; 2377 memset(¶m, 0, sizeof(cam_stream_parm_buffer_t)); 2378 param.type = CAM_STREAM_PARAM_TYPE_DO_REPROCESS; 2379 param.reprocess.buf_index = buf_idx; 2380 param.reprocess.meta_present = 1; 2381 param.reprocess.meta_stream_handle = m_pMetaChannel->mStreams[0]->getMyServerID(); 2382 param.reprocess.meta_buf_index = meta_frame->bufs[0]->buf_idx; 2383 rc = mStreams[i]->setParameter(param); 2384 if (rc == NO_ERROR) { 2385 ret_val = param.reprocess.ret_val; 2386 } 2387 mStreams[i]->unmapBuf(CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF, 2388 buf_idx, -1); 2389 } 2390 } 2391 return rc; 2392} 2393 2394/*=========================================================================== 2395 * FUNCTION : addReprocStreamsFromSource 2396 * 2397 * DESCRIPTION: add reprocess streams from input source channel 2398 * 2399 * PARAMETERS : 2400 * @config : pp feature configuration 2401 * @pSrcChannel : ptr to input source channel that needs reprocess 2402 * @pMetaChannel : ptr to metadata channel to get corresp. metadata 2403 * @offline : configure for offline reprocessing 2404 * 2405 * RETURN : int32_t type of status 2406 * NO_ERROR -- success 2407 * none-zero failure code 2408 *==========================================================================*/ 2409int32_t QCamera3ReprocessChannel::addReprocStreamsFromSource(cam_pp_feature_config_t &pp_config, 2410 QCamera3Channel *pSrcChannel, 2411 QCamera3Channel *pMetaChannel) 2412{ 2413 int32_t rc = 0; 2414 QCamera3Stream *pSrcStream = pSrcChannel->getStreamByIndex(0); 2415 if (pSrcStream == NULL) { 2416 ALOGE("%s: source channel doesn't have a stream", __func__); 2417 return BAD_VALUE; 2418 } 2419 cam_stream_reproc_config_t reprocess_config; 2420 cam_dimension_t streamDim; 2421 cam_stream_type_t streamType; 2422 cam_format_t streamFormat; 2423 cam_frame_len_offset_t frameOffset; 2424 int num_buffers = 2; 2425 2426 streamType = CAM_STREAM_TYPE_OFFLINE_PROC; 2427 pSrcStream->getFormat(streamFormat); 2428 pSrcStream->getFrameDimension(streamDim); 2429 pSrcStream->getFrameOffset(frameOffset); 2430 reprocess_config.pp_type = CAM_OFFLINE_REPROCESS_TYPE; 2431 2432 reprocess_config.offline.input_fmt = streamFormat; 2433 reprocess_config.offline.input_dim = streamDim; 2434 reprocess_config.offline.input_buf_planes.plane_info = frameOffset; 2435 reprocess_config.offline.num_of_bufs = num_buffers; 2436 reprocess_config.offline.input_stream_type = pSrcStream->getMyType(); 2437 2438 2439 reprocess_config.pp_feature_config = pp_config; 2440 mSrcStreamHandles[m_numStreams] = pSrcStream->getMyHandle(); 2441 2442 // pp feature config 2443 if (pp_config.feature_mask & CAM_QCOM_FEATURE_ROTATION) { 2444 if (pp_config.rotation == ROTATE_90 || 2445 pp_config.rotation == ROTATE_270) { 2446 // rotated by 90 or 270, need to switch width and height 2447 int32_t temp = streamDim.height; 2448 streamDim.height = streamDim.width; 2449 streamDim.width = temp; 2450 } 2451 } 2452 2453 QCamera3Stream *pStream = new QCamera3Stream(m_camHandle, 2454 m_handle, 2455 m_camOps, 2456 mPaddingInfo, 2457 (QCamera3Channel*)this); 2458 if (pStream == NULL) { 2459 ALOGE("%s: No mem for Stream", __func__); 2460 return NO_MEMORY; 2461 } 2462 2463 rc = pStream->init(streamType, streamFormat, streamDim, &reprocess_config, 2464 num_buffers,QCamera3Channel::streamCbRoutine, this); 2465 2466 2467 if (rc == 0) { 2468 mStreams[m_numStreams] = pStream; 2469 m_numStreams++; 2470 } else { 2471 ALOGE("%s: failed to create reprocess stream", __func__); 2472 delete pStream; 2473 } 2474 2475 if (rc == NO_ERROR) { 2476 m_pSrcChannel = pSrcChannel; 2477 m_pMetaChannel = pMetaChannel; 2478 } 2479 if(m_camOps->request_super_buf(m_camHandle,m_handle,1) < 0) { 2480 ALOGE("%s: Request for super buffer failed",__func__); 2481 } 2482 return rc; 2483} 2484 2485cam_dimension_t QCamera3SupportChannel::kDim = {640, 480}; 2486 2487QCamera3SupportChannel::QCamera3SupportChannel(uint32_t cam_handle, 2488 mm_camera_ops_t *cam_ops, 2489 cam_padding_info_t *paddingInfo, 2490 void *userData) : 2491 QCamera3Channel(cam_handle, cam_ops, 2492 NULL, paddingInfo, userData), 2493 mMemory(NULL) 2494{ 2495} 2496 2497QCamera3SupportChannel::~QCamera3SupportChannel() 2498{ 2499 if (m_bIsActive) 2500 stop(); 2501 2502 if (mMemory) { 2503 mMemory->deallocate(); 2504 delete mMemory; 2505 mMemory = NULL; 2506 } 2507} 2508 2509int32_t QCamera3SupportChannel::initialize() 2510{ 2511 int32_t rc; 2512 2513 if (mMemory || m_numStreams > 0) { 2514 ALOGE("%s: metadata channel already initialized", __func__); 2515 return -EINVAL; 2516 } 2517 2518 rc = init(NULL, NULL); 2519 if (rc < 0) { 2520 ALOGE("%s: init failed", __func__); 2521 return rc; 2522 } 2523 2524 // Hardcode to VGA size for now 2525 rc = QCamera3Channel::addStream(CAM_STREAM_TYPE_CALLBACK, 2526 CAM_FORMAT_YUV_420_NV21, kDim, MIN_STREAMING_BUFFER_NUM); 2527 if (rc < 0) { 2528 ALOGE("%s: addStream failed", __func__); 2529 } 2530 return rc; 2531} 2532 2533int32_t QCamera3SupportChannel::request(buffer_handle_t * /*buffer*/, 2534 uint32_t /*frameNumber*/) 2535{ 2536 return NO_ERROR; 2537} 2538 2539void QCamera3SupportChannel::streamCbRoutine( 2540 mm_camera_super_buf_t *super_frame, 2541 QCamera3Stream * /*stream*/) 2542{ 2543 if (super_frame == NULL || super_frame->num_bufs != 1) { 2544 ALOGE("%s: super_frame is not valid", __func__); 2545 return; 2546 } 2547 bufDone(super_frame); 2548 free(super_frame); 2549} 2550 2551QCamera3Memory* QCamera3SupportChannel::getStreamBufs(uint32_t len) 2552{ 2553 int rc; 2554 2555 mMemory = new QCamera3HeapMemory(); 2556 if (!mMemory) { 2557 ALOGE("%s: unable to create heap memory", __func__); 2558 return NULL; 2559 } 2560 rc = mMemory->allocate(MIN_STREAMING_BUFFER_NUM, len, true); 2561 if (rc < 0) { 2562 ALOGE("%s: unable to allocate heap memory", __func__); 2563 delete mMemory; 2564 mMemory = NULL; 2565 return NULL; 2566 } 2567 return mMemory; 2568} 2569 2570void QCamera3SupportChannel::putStreamBufs() 2571{ 2572 mMemory->deallocate(); 2573 delete mMemory; 2574 mMemory = NULL; 2575} 2576 2577}; // namespace qcamera 2578