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