QCamera3Channel.cpp revision 14dfc272241ba78c85a327da2872e71b3208f8c5
1/* Copyright (c) 2012-2013, 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 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 "QCamera3Channel.h" 43 44using namespace android; 45 46#define MIN_STREAMING_BUFFER_NUM 7+11 47 48namespace qcamera { 49static const char ExifAsciiPrefix[] = 50 { 0x41, 0x53, 0x43, 0x49, 0x49, 0x0, 0x0, 0x0 }; // "ASCII\0\0\0" 51static const char ExifUndefinedPrefix[] = 52 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; // "\0\0\0\0\0\0\0\0" 53 54#define GPS_PROCESSING_METHOD_SIZE 101 55#define EXIF_ASCII_PREFIX_SIZE 8 //(sizeof(ExifAsciiPrefix)) 56#define FOCAL_LENGTH_DECIMAL_PRECISION 100 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 } 243 244 for (int i = 0; i < m_numStreams; i++) { 245 if (mStreams[i] != NULL) { 246 mStreams[i]->start(); 247 } 248 } 249 rc = m_camOps->start_channel(m_camHandle, m_handle); 250 251 if (rc != NO_ERROR) { 252 for (int i = 0; i < m_numStreams; i++) { 253 if (mStreams[i] != NULL) { 254 mStreams[i]->stop(); 255 } 256 } 257 } else { 258 m_bIsActive = true; 259 } 260 261 return rc; 262} 263 264/*=========================================================================== 265 * FUNCTION : stop 266 * 267 * DESCRIPTION: stop a channel, which will stop all streams belong to this channel 268 * 269 * PARAMETERS : none 270 * 271 * RETURN : int32_t type of status 272 * NO_ERROR -- success 273 * none-zero failure code 274 *==========================================================================*/ 275int32_t QCamera3Channel::stop() 276{ 277 int32_t rc = NO_ERROR; 278 if(!m_bIsActive) { 279 ALOGE("%s: Attempt to stop inactive channel",__func__); 280 return rc; 281 } 282 283 rc = m_camOps->stop_channel(m_camHandle, m_handle); 284 285 for (int i = 0; i < m_numStreams; i++) { 286 if (mStreams[i] != NULL) { 287 mStreams[i]->stop(); 288 } 289 } 290 291 m_bIsActive = false; 292 return rc; 293} 294 295/*=========================================================================== 296 * FUNCTION : bufDone 297 * 298 * DESCRIPTION: return a stream buf back to kernel 299 * 300 * PARAMETERS : 301 * @recvd_frame : stream buf frame to be returned 302 * 303 * RETURN : int32_t type of status 304 * NO_ERROR -- success 305 * none-zero failure code 306 *==========================================================================*/ 307int32_t QCamera3Channel::bufDone(mm_camera_super_buf_t *recvd_frame) 308{ 309 int32_t rc = NO_ERROR; 310 for (int i = 0; i < recvd_frame->num_bufs; i++) { 311 if (recvd_frame->bufs[i] != NULL) { 312 for (int j = 0; j < m_numStreams; j++) { 313 if (mStreams[j] != NULL && 314 mStreams[j]->getMyHandle() == recvd_frame->bufs[i]->stream_id) { 315 rc = mStreams[j]->bufDone(recvd_frame->bufs[i]->buf_idx); 316 break; // break loop j 317 } 318 } 319 } 320 } 321 322 return rc; 323} 324 325/*=========================================================================== 326 * FUNCTION : getStreamTypeMask 327 * 328 * DESCRIPTION: Get bit mask of all stream types in this channel 329 * 330 * PARAMETERS : None 331 * 332 * RETURN : Bit mask of all stream types in this channel 333 *==========================================================================*/ 334uint32_t QCamera3Channel::getStreamTypeMask() 335{ 336 uint32_t mask = 0; 337 for (int i = 0; i < m_numStreams; i++) { 338 mask |= (0x1 << mStreams[i]->getMyType()); 339 } 340 return mask; 341} 342 343/*=========================================================================== 344 * FUNCTION : getInternalFormatBuffer 345 * 346 * DESCRIPTION: return buffer in the internal format structure 347 * 348 * PARAMETERS : 349 * @streamHandle : buffer handle 350 * 351 * RETURN : stream object. NULL if not found 352 *==========================================================================*/ 353mm_camera_buf_def_t* QCamera3RegularChannel::getInternalFormatBuffer( 354 buffer_handle_t * buffer) 355{ 356 int32_t index; 357 if(buffer == NULL) 358 return NULL; 359 index = mMemory->getMatchBufIndex((void*)buffer); 360 if(index < 0) { 361 ALOGE("%s: Could not find object among registered buffers",__func__); 362 return NULL; 363 } 364 return mStreams[0]->getInternalFormatBuffer(index); 365} 366 367/*=========================================================================== 368 * FUNCTION : getStreamByHandle 369 * 370 * DESCRIPTION: return stream object by stream handle 371 * 372 * PARAMETERS : 373 * @streamHandle : stream handle 374 * 375 * RETURN : stream object. NULL if not found 376 *==========================================================================*/ 377QCamera3Stream *QCamera3Channel::getStreamByHandle(uint32_t streamHandle) 378{ 379 for (int i = 0; i < m_numStreams; i++) { 380 if (mStreams[i] != NULL && mStreams[i]->getMyHandle() == streamHandle) { 381 return mStreams[i]; 382 } 383 } 384 return NULL; 385} 386 387/*=========================================================================== 388 * FUNCTION : getStreamByIndex 389 * 390 * DESCRIPTION: return stream object by index 391 * 392 * PARAMETERS : 393 * @streamHandle : stream handle 394 * 395 * RETURN : stream object. NULL if not found 396 *==========================================================================*/ 397QCamera3Stream *QCamera3Channel::getStreamByIndex(uint8_t index) 398{ 399 if (index < m_numStreams) { 400 return mStreams[index]; 401 } 402 return NULL; 403} 404 405/*=========================================================================== 406 * FUNCTION : streamCbRoutine 407 * 408 * DESCRIPTION: callback routine for stream 409 * 410 * PARAMETERS : 411 * @streamHandle : stream handle 412 * 413 * RETURN : stream object. NULL if not found 414 *==========================================================================*/ 415void QCamera3Channel::streamCbRoutine(mm_camera_super_buf_t *super_frame, 416 QCamera3Stream *stream, void *userdata) 417{ 418 QCamera3Channel *channel = (QCamera3Channel *)userdata; 419 if (channel == NULL) { 420 ALOGE("%s: invalid channel pointer", __func__); 421 return; 422 } 423 channel->streamCbRoutine(super_frame, stream); 424} 425 426/*=========================================================================== 427 * FUNCTION : QCamera3RegularChannel 428 * 429 * DESCRIPTION: constrcutor of QCamera3RegularChannel 430 * 431 * PARAMETERS : 432 * @cam_handle : camera handle 433 * @cam_ops : ptr to camera ops table 434 * @cb_routine : callback routine to frame aggregator 435 * @stream : camera3_stream_t structure 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 QCamera3Channel(cam_handle, cam_ops, cb_routine, 446 paddingInfo, userData), 447 mCamera3Stream(stream), 448 mNumBufs(0), 449 mCamera3Buffers(NULL), 450 mMemory(NULL), 451 mWidth(stream->width), 452 mHeight(stream->height) 453{ 454} 455 456/*=========================================================================== 457 * FUNCTION : QCamera3RegularChannel 458 * 459 * DESCRIPTION: constrcutor of QCamera3RegularChannel 460 * 461 * PARAMETERS : 462 * @cam_handle : camera handle 463 * @cam_ops : ptr to camera ops table 464 * @cb_routine : callback routine to frame aggregator 465 * @stream : camera3_stream_t structure 466 * 467 * RETURN : none 468 *==========================================================================*/ 469QCamera3RegularChannel::QCamera3RegularChannel(uint32_t cam_handle, 470 mm_camera_ops_t *cam_ops, 471 channel_cb_routine cb_routine, 472 cam_padding_info_t *paddingInfo, 473 void *userData, 474 camera3_stream_t *stream, 475 uint32_t width, uint32_t height) : 476 QCamera3Channel(cam_handle, cam_ops, cb_routine, 477 paddingInfo, userData), 478 mCamera3Stream(stream), 479 mNumBufs(0), 480 mCamera3Buffers(NULL), 481 mMemory(NULL), 482 mWidth(width), 483 mHeight(height) 484{ 485} 486 487/*=========================================================================== 488 * FUNCTION : ~QCamera3RegularChannel 489 * 490 * DESCRIPTION: destructor of QCamera3RegularChannel 491 * 492 * PARAMETERS : none 493 * 494 * RETURN : none 495 *==========================================================================*/ 496QCamera3RegularChannel::~QCamera3RegularChannel() 497{ 498 if (mCamera3Buffers) { 499 delete[] mCamera3Buffers; 500 } 501} 502 503int32_t QCamera3RegularChannel::initialize() 504{ 505 //TO DO 506 return 0; 507} 508 509/*=========================================================================== 510 * FUNCTION : request 511 * 512 * DESCRIPTION: process a request from camera service. Stream on if ncessary. 513 * 514 * PARAMETERS : 515 * @buffer : buffer to be filled for this request 516 * 517 * RETURN : 0 on a success start of capture 518 * -EINVAL on invalid input 519 * -ENODEV on serious error 520 *==========================================================================*/ 521int32_t QCamera3RegularChannel::request(buffer_handle_t *buffer, uint32_t frameNumber) 522{ 523 //FIX ME: Return buffer back in case of failures below. 524 525 int32_t rc = NO_ERROR; 526 int index; 527 if(!m_bIsActive) { 528 ALOGD("%s: First request on this channel starting stream",__func__); 529 start(); 530 if(rc != NO_ERROR) { 531 ALOGE("%s: Failed to start the stream on the request",__func__); 532 return rc; 533 } 534 } else { 535 ALOGV("%s: Request on an existing stream",__func__); 536 } 537 538 if(!mMemory) { 539 ALOGE("%s: error, Gralloc Memory object not yet created for this stream",__func__); 540 return NO_MEMORY; 541 } 542 543 index = mMemory->getMatchBufIndex((void*)buffer); 544 if(index < 0) { 545 ALOGE("%s: Could not find object among registered buffers",__func__); 546 return DEAD_OBJECT; 547 } 548 549 rc = mStreams[0]->bufDone(index); 550 if(rc != NO_ERROR) { 551 ALOGE("%s: Failed to Q new buffer to stream",__func__); 552 return rc; 553 } 554 555 rc = mMemory->markFrameNumber(index, frameNumber); 556 return rc; 557} 558 559/*=========================================================================== 560 * FUNCTION : registerBuffers 561 * 562 * DESCRIPTION: register streaming buffers to the channel object 563 * 564 * PARAMETERS : 565 * @num_buffers : number of buffers to be registered 566 * @buffers : buffer to be registered 567 * 568 * RETURN : 0 on a success start of capture 569 * -EINVAL on invalid input 570 * -ENOMEM on failure to register the buffer 571 * -ENODEV on serious error 572 *==========================================================================*/ 573int32_t QCamera3RegularChannel::registerBuffers(uint32_t num_buffers, buffer_handle_t **buffers) 574{ 575 int rc = 0; 576 struct private_handle_t *priv_handle = (struct private_handle_t *)(*buffers[0]); 577 cam_stream_type_t streamType; 578 cam_format_t streamFormat; 579 cam_dimension_t streamDim; 580 581 rc = init(NULL, NULL); 582 if (rc < 0) { 583 ALOGE("%s: init failed", __func__); 584 return rc; 585 } 586 587 if (mCamera3Stream->format == HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED) { 588 if (priv_handle->flags & private_handle_t::PRIV_FLAGS_VIDEO_ENCODER) { 589 streamType = CAM_STREAM_TYPE_VIDEO; 590 streamFormat = CAM_FORMAT_YUV_420_NV12; 591 } else if (priv_handle->flags & private_handle_t::PRIV_FLAGS_HW_TEXTURE) { 592 streamType = CAM_STREAM_TYPE_PREVIEW; 593 streamFormat = CAM_FORMAT_YUV_420_NV21; 594 } else { 595 //TODO: Add a new flag in libgralloc for ZSL buffers, and its size needs 596 // to be properly aligned and padded. 597 ALOGE("%s: priv_handle->flags 0x%x not supported", 598 __func__, priv_handle->flags); 599 streamType = CAM_STREAM_TYPE_SNAPSHOT; 600 streamFormat = CAM_FORMAT_YUV_420_NV21; 601 } 602 } else if(mCamera3Stream->format == HAL_PIXEL_FORMAT_YCbCr_420_888) { 603 streamType = CAM_STREAM_TYPE_CALLBACK; 604 streamFormat = CAM_FORMAT_YUV_420_NV21; 605 } else { 606 //TODO: Fail for other types of streams for now 607 ALOGE("%s: format is not IMPLEMENTATION_DEFINED or flexible", __func__); 608 return -EINVAL; 609 } 610 611 /* Bookkeep buffer set because they go out of scope after register call */ 612 mNumBufs = num_buffers; 613 mCamera3Buffers = new buffer_handle_t*[num_buffers]; 614 if (mCamera3Buffers == NULL) { 615 ALOGE("%s: Failed to allocate buffer_handle_t*", __func__); 616 return -ENOMEM; 617 } 618 for (size_t i = 0; i < num_buffers; i++) 619 mCamera3Buffers[i] = buffers[i]; 620 621 streamDim.width = mWidth; 622 streamDim.height = mHeight; 623 624 rc = QCamera3Channel::addStream(streamType, streamFormat, streamDim, 625 num_buffers); 626 return rc; 627} 628 629void QCamera3RegularChannel::streamCbRoutine( 630 mm_camera_super_buf_t *super_frame, 631 QCamera3Stream *stream) 632{ 633 //FIXME Q Buf back in case of error? 634 uint8_t frameIndex; 635 buffer_handle_t *resultBuffer; 636 int32_t resultFrameNumber; 637 camera3_stream_buffer_t result; 638 639 if(!super_frame) { 640 ALOGE("%s: Invalid Super buffer",__func__); 641 return; 642 } 643 644 if(super_frame->num_bufs != 1) { 645 ALOGE("%s: Multiple streams are not supported",__func__); 646 return; 647 } 648 if(super_frame->bufs[0] == NULL ) { 649 ALOGE("%s: Error, Super buffer frame does not contain valid buffer", 650 __func__); 651 return; 652 } 653 654 frameIndex = (uint8_t)super_frame->bufs[0]->buf_idx; 655 if(frameIndex >= mNumBufs) { 656 ALOGE("%s: Error, Invalid index for buffer",__func__); 657 if(stream) { 658 stream->bufDone(frameIndex); 659 } 660 return; 661 } 662 663 ////Use below data to issue framework callback 664 resultBuffer = mCamera3Buffers[frameIndex]; 665 resultFrameNumber = mMemory->getFrameNumber(frameIndex); 666 667 result.stream = mCamera3Stream; 668 result.buffer = resultBuffer; 669 result.status = CAMERA3_BUFFER_STATUS_OK; 670 result.acquire_fence = -1; 671 result.release_fence = -1; 672 673 mChannelCB(NULL, &result, resultFrameNumber, mUserData); 674 free(super_frame); 675 return; 676} 677 678QCamera3Memory* QCamera3RegularChannel::getStreamBufs(uint32_t /*len*/) 679{ 680 if (mNumBufs == 0 || mCamera3Buffers == NULL) { 681 ALOGE("%s: buffers not registered yet", __func__); 682 return NULL; 683 } 684 685 mMemory = new QCamera3GrallocMemory(); 686 if (mMemory == NULL) { 687 return NULL; 688 } 689 690 if (mMemory->registerBuffers(mNumBufs, mCamera3Buffers) < 0) { 691 delete mMemory; 692 mMemory = NULL; 693 return NULL; 694 } 695 return mMemory; 696} 697 698void QCamera3RegularChannel::putStreamBufs() 699{ 700 mMemory->unregisterBuffers(); 701 delete mMemory; 702 mMemory = NULL; 703} 704 705int QCamera3RegularChannel::kMaxBuffers = 7; 706 707QCamera3MetadataChannel::QCamera3MetadataChannel(uint32_t cam_handle, 708 mm_camera_ops_t *cam_ops, 709 channel_cb_routine cb_routine, 710 cam_padding_info_t *paddingInfo, 711 void *userData) : 712 QCamera3Channel(cam_handle, cam_ops, 713 cb_routine, paddingInfo, userData), 714 mMemory(NULL) 715{ 716} 717 718QCamera3MetadataChannel::~QCamera3MetadataChannel() 719{ 720 if (m_bIsActive) 721 stop(); 722 723 if (mMemory) { 724 mMemory->deallocate(); 725 delete mMemory; 726 mMemory = NULL; 727 } 728} 729 730int32_t QCamera3MetadataChannel::initialize() 731{ 732 int32_t rc; 733 cam_dimension_t streamDim; 734 735 if (mMemory || m_numStreams > 0) { 736 ALOGE("%s: metadata channel already initialized", __func__); 737 return -EINVAL; 738 } 739 740 rc = init(NULL, NULL); 741 if (rc < 0) { 742 ALOGE("%s: init failed", __func__); 743 return rc; 744 } 745 746 streamDim.width = sizeof(metadata_buffer_t), 747 streamDim.height = 1; 748 rc = QCamera3Channel::addStream(CAM_STREAM_TYPE_METADATA, CAM_FORMAT_MAX, 749 streamDim, MIN_STREAMING_BUFFER_NUM); 750 if (rc < 0) { 751 ALOGE("%s: addStream failed", __func__); 752 } 753 return rc; 754} 755 756int32_t QCamera3MetadataChannel::request(buffer_handle_t * /*buffer*/, 757 uint32_t /*frameNumber*/) 758{ 759 if (!m_bIsActive) { 760 return start(); 761 } 762 else 763 return 0; 764} 765 766int32_t QCamera3MetadataChannel::registerBuffers(uint32_t /*num_buffers*/, 767 buffer_handle_t ** /*buffers*/) 768{ 769 // no registerBuffers are supported for metadata channel 770 return -EINVAL; 771} 772 773void QCamera3MetadataChannel::streamCbRoutine( 774 mm_camera_super_buf_t *super_frame, 775 QCamera3Stream * /*stream*/) 776{ 777 uint32_t requestNumber = 0; 778 if (super_frame == NULL || super_frame->num_bufs != 1) { 779 ALOGE("%s: super_frame is not valid", __func__); 780 return; 781 } 782 mChannelCB(super_frame, NULL, requestNumber, mUserData); 783} 784 785QCamera3Memory* QCamera3MetadataChannel::getStreamBufs(uint32_t len) 786{ 787 int rc; 788 if (len < sizeof(metadata_buffer_t)) { 789 ALOGE("%s: size doesn't match %d vs %d", __func__, 790 len, sizeof(metadata_buffer_t)); 791 return NULL; 792 } 793 mMemory = new QCamera3HeapMemory(); 794 if (!mMemory) { 795 ALOGE("%s: unable to create metadata memory", __func__); 796 return NULL; 797 } 798 rc = mMemory->allocate(MIN_STREAMING_BUFFER_NUM, len, true); 799 if (rc < 0) { 800 ALOGE("%s: unable to allocate metadata memory", __func__); 801 delete mMemory; 802 mMemory = NULL; 803 return NULL; 804 } 805 memset(mMemory->getPtr(0), 0, sizeof(metadata_buffer_t)); 806 return mMemory; 807} 808 809void QCamera3MetadataChannel::putStreamBufs() 810{ 811 mMemory->deallocate(); 812 delete mMemory; 813 mMemory = NULL; 814} 815 816/*=========================================================================== 817 * FUNCTION : jpegEvtHandle 818 * 819 * DESCRIPTION: Function registerd to mm-jpeg-interface to handle jpeg events. 820 Construct result payload and call mChannelCb to deliver buffer 821 to framework. 822 * 823 * PARAMETERS : 824 * @status : status of jpeg job 825 * @client_hdl: jpeg client handle 826 * @jobId : jpeg job Id 827 * @p_ouput : ptr to jpeg output result struct 828 * @userdata : user data ptr 829 * 830 * RETURN : none 831 *==========================================================================*/ 832void QCamera3PicChannel::jpegEvtHandle(jpeg_job_status_t status, 833 uint32_t /*client_hdl*/, 834 uint32_t jobId, 835 mm_jpeg_output_t *p_output, 836 void *userdata) 837{ 838 buffer_handle_t *resultBuffer; 839 int32_t resultFrameNumber; 840 int resultStatus = CAMERA3_BUFFER_STATUS_OK; 841 camera3_stream_buffer_t result; 842 camera3_jpeg_blob_t jpegHeader; 843 char* jpeg_eof = 0; 844 int maxJpegSize; 845 QCamera3PicChannel *obj = (QCamera3PicChannel *)userdata; 846 if (obj) { 847 848 //Release any cached metabuffer information 849 if (obj->mMetaFrame != NULL && obj->m_pMetaChannel != NULL) { 850 ((QCamera3MetadataChannel*)(obj->m_pMetaChannel))->bufDone(obj->mMetaFrame); 851 obj->mMetaFrame = NULL; 852 obj->m_pMetaChannel = NULL; 853 } else { 854 ALOGE("%s: Meta frame was NULL", __func__); 855 } 856 //Construct payload for process_capture_result. Call mChannelCb 857 858 qcamera_jpeg_data_t *job = obj->m_postprocessor.findJpegJobByJobId(jobId); 859 860 if ((job == NULL) || (status == JPEG_JOB_STATUS_ERROR)) { 861 ALOGE("%s: Error in jobId: (%d) with status: %d", __func__, jobId, status); 862 resultStatus = CAMERA3_BUFFER_STATUS_ERROR; 863 } 864 865 //Construct jpeg transient header of type camera3_jpeg_blob_t 866 //Append at the end of jpeg image of buf_filled_len size 867 868 jpegHeader.jpeg_blob_id = CAMERA3_JPEG_BLOB_ID; 869 jpegHeader.jpeg_size = p_output->buf_filled_len; 870 871 872 char* jpeg_buf = (char *)p_output->buf_vaddr; 873 874 if(obj->mJpegSettings->max_jpeg_size <= 0 || 875 obj->mJpegSettings->max_jpeg_size > obj->mMemory->getSize(obj->mCurrentBufIndex)){ 876 ALOGE("%s:Max Jpeg size :%d is out of valid range setting to size of buffer", 877 __func__, obj->mJpegSettings->max_jpeg_size); 878 maxJpegSize = obj->mMemory->getSize(obj->mCurrentBufIndex); 879 } else { 880 maxJpegSize = obj->mJpegSettings->max_jpeg_size; 881 ALOGE("%s: Setting max jpeg size to %d",__func__, maxJpegSize); 882 } 883 jpeg_eof = &jpeg_buf[maxJpegSize-sizeof(jpegHeader)]; 884 memcpy(jpeg_eof, &jpegHeader, sizeof(jpegHeader)); 885 obj->mMemory->cleanInvalidateCache(obj->mCurrentBufIndex); 886 887 ////Use below data to issue framework callback 888 resultBuffer = obj->mCamera3Buffers[obj->mCurrentBufIndex]; 889 resultFrameNumber = obj->mMemory->getFrameNumber(obj->mCurrentBufIndex); 890 891 result.stream = obj->mCamera3Stream; 892 result.buffer = resultBuffer; 893 result.status = resultStatus; 894 result.acquire_fence = -1; 895 result.release_fence = -1; 896 897 ALOGV("%s: Issue Callback", __func__); 898 obj->mChannelCB(NULL, &result, resultFrameNumber, obj->mUserData); 899 900 // release internal data for jpeg job 901 if (job != NULL) { 902 obj->m_postprocessor.releaseJpegJobData(job); 903 free(job); 904 } 905 return; 906 // } 907 } else { 908 ALOGE("%s: Null userdata in jpeg callback", __func__); 909 } 910} 911 912QCamera3PicChannel::QCamera3PicChannel(uint32_t cam_handle, 913 mm_camera_ops_t *cam_ops, 914 channel_cb_routine cb_routine, 915 cam_padding_info_t *paddingInfo, 916 void *userData, 917 camera3_stream_t *stream) : 918 QCamera3Channel(cam_handle, cam_ops, cb_routine, 919 paddingInfo, userData), 920 m_postprocessor(this), 921 mCamera3Stream(stream), 922 mNumBufs(0), 923 mCamera3Buffers(NULL), 924 mJpegSettings(NULL), 925 mCurrentBufIndex(-1), 926 mMemory(NULL), 927 mYuvMemory(NULL), 928 mMetaFrame(NULL) 929{ 930 int32_t rc = m_postprocessor.init(jpegEvtHandle, this); 931 if (rc != 0) { 932 ALOGE("Init Postprocessor failed"); 933 } 934} 935 936QCamera3PicChannel::~QCamera3PicChannel() 937{ 938 int32_t rc = m_postprocessor.deinit(); 939 if (rc != 0) { 940 ALOGE("De-init Postprocessor failed"); 941 } 942 if (mCamera3Buffers) { 943 delete[] mCamera3Buffers; 944 } 945} 946 947int32_t QCamera3PicChannel::initialize() 948{ 949 int32_t rc = NO_ERROR; 950 cam_dimension_t streamDim; 951 cam_stream_type_t streamType; 952 cam_format_t streamFormat; 953 mm_camera_channel_attr_t attr; 954 955 memset(&attr, 0, sizeof(mm_camera_channel_attr_t)); 956 attr.notify_mode = MM_CAMERA_SUPER_BUF_NOTIFY_BURST; 957 attr.look_back = 1; 958 attr.post_frame_skip = 1; 959 attr.water_mark = 1; 960 attr.max_unmatched_frames = 1; 961 962 rc = init(&attr, NULL); 963 if (rc < 0) { 964 ALOGE("%s: init failed", __func__); 965 return rc; 966 } 967 968 streamType = CAM_STREAM_TYPE_NON_ZSL_SNAPSHOT; 969 streamFormat = CAM_FORMAT_YUV_420_NV21; 970 streamDim.width = mCamera3Stream->width; 971 streamDim.height = mCamera3Stream->height; 972 973 int num_buffers = 1; 974 975 rc = QCamera3Channel::addStream(streamType, streamFormat, streamDim, 976 num_buffers); 977 978 return rc; 979} 980 981int32_t QCamera3PicChannel::request(buffer_handle_t *buffer, 982 uint32_t frameNumber, jpeg_settings_t* jpegSettings, 983 mm_camera_buf_def_t *pInputBuffer,QCamera3Channel* pInputChannel) 984{ 985 //FIX ME: Return buffer back in case of failures below. 986 987 int32_t rc = NO_ERROR; 988 int index; 989 mJpegSettings = jpegSettings; 990 // Picture stream has already been started before any request comes in 991 if (!m_bIsActive) { 992 ALOGE("%s: Picture stream should have been started before any request", 993 __func__); 994 return -EINVAL; 995 } 996 if (pInputBuffer == NULL) 997 mStreams[0]->bufDone(0); 998 999 if(!mMemory) { 1000 if(pInputBuffer) { 1001 mMemory = new QCamera3GrallocMemory(); 1002 if (mMemory == NULL) { 1003 return NO_MEMORY; 1004 } 1005 1006 //Registering Jpeg output buffer 1007 if (mMemory->registerBuffers(mNumBufs, mCamera3Buffers) < 0) { 1008 delete mMemory; 1009 mMemory = NULL; 1010 return NO_MEMORY; 1011 } 1012 } else { 1013 ALOGE("%s: error, Gralloc Memory object not yet created for this stream",__func__); 1014 return NO_MEMORY; 1015 } 1016 } 1017 1018 index = mMemory->getMatchBufIndex((void*)buffer); 1019 if(index < 0) { 1020 ALOGE("%s: Could not find object among registered buffers",__func__); 1021 return DEAD_OBJECT; 1022 } 1023 rc = mMemory->markFrameNumber(index, frameNumber); 1024 1025 //Start the postprocessor for jpeg encoding. Pass mMemory as destination buffer 1026 mCurrentBufIndex = index; 1027 1028 if(pInputBuffer) { 1029 m_postprocessor.start(mMemory, index, pInputChannel); 1030 ALOGD("%s: Post-process started", __func__); 1031 ALOGD("%s: Issue call to reprocess", __func__); 1032 m_postprocessor.processAuxiliaryData(pInputBuffer,pInputChannel); 1033 } else { 1034 m_postprocessor.start(mMemory, index, this); 1035 } 1036 return rc; 1037} 1038 1039/*=========================================================================== 1040 * FUNCTION : dataNotifyCB 1041 * 1042 * DESCRIPTION: Channel Level callback used for super buffer data notify. 1043 * This function is registered with mm-camera-interface to handle 1044 * data notify 1045 * 1046 * PARAMETERS : 1047 * @recvd_frame : stream frame received 1048 * userdata : user data ptr 1049 * 1050 * RETURN : none 1051 *==========================================================================*/ 1052void QCamera3PicChannel::dataNotifyCB(mm_camera_super_buf_t *recvd_frame, 1053 void *userdata) 1054{ 1055 ALOGV("%s: E\n", __func__); 1056 QCamera3PicChannel *channel = (QCamera3PicChannel *)userdata; 1057 1058 if (channel == NULL) { 1059 ALOGE("%s: invalid channel pointer", __func__); 1060 return; 1061 } 1062 1063 if(channel->m_numStreams != 1) { 1064 ALOGE("%s: Error: Bug: This callback assumes one stream per channel",__func__); 1065 return; 1066 } 1067 1068 1069 if(channel->mStreams[0] == NULL) { 1070 ALOGE("%s: Error: Invalid Stream object",__func__); 1071 return; 1072 } 1073 1074 channel->QCamera3PicChannel::streamCbRoutine(recvd_frame, channel->mStreams[0]); 1075 1076 ALOGV("%s: X\n", __func__); 1077 return; 1078} 1079 1080 1081int32_t QCamera3PicChannel::registerBuffers(uint32_t num_buffers, 1082 buffer_handle_t **buffers) 1083{ 1084 int rc = 0; 1085 cam_stream_type_t streamType; 1086 cam_format_t streamFormat; 1087 1088 ALOGV("%s: E",__func__); 1089 rc = QCamera3PicChannel::initialize(); 1090 if (rc < 0) { 1091 ALOGE("%s: init failed", __func__); 1092 return rc; 1093 } 1094 1095 if (mCamera3Stream->format == HAL_PIXEL_FORMAT_BLOB) { 1096 streamType = CAM_STREAM_TYPE_NON_ZSL_SNAPSHOT; 1097 streamFormat = CAM_FORMAT_YUV_420_NV21; 1098 } else { 1099 //TODO: Fail for other types of streams for now 1100 ALOGE("%s: format is not BLOB", __func__); 1101 return -EINVAL; 1102 } 1103 /* Bookkeep buffer set because they go out of scope after register call */ 1104 mNumBufs = num_buffers; 1105 mCamera3Buffers = new buffer_handle_t*[num_buffers]; 1106 if (mCamera3Buffers == NULL) { 1107 ALOGE("%s: Failed to allocate buffer_handle_t*", __func__); 1108 return -ENOMEM; 1109 } 1110 for (size_t i = 0; i < num_buffers; i++) 1111 mCamera3Buffers[i] = buffers[i]; 1112 1113 ALOGV("%s: X",__func__); 1114 return rc; 1115} 1116 1117void QCamera3PicChannel::streamCbRoutine(mm_camera_super_buf_t *super_frame, 1118 QCamera3Stream *stream) 1119{ 1120 //TODO 1121 //Used only for getting YUV. Jpeg callback will be sent back from channel 1122 //directly to HWI. Refer to func jpegEvtHandle 1123 1124 //Got the yuv callback. Calling yuv callback handler in PostProc 1125 uint8_t frameIndex; 1126 mm_camera_super_buf_t* frame = NULL; 1127 if(!super_frame) { 1128 ALOGE("%s: Invalid Super buffer",__func__); 1129 return; 1130 } 1131 1132 if(super_frame->num_bufs != 1) { 1133 ALOGE("%s: Multiple streams are not supported",__func__); 1134 return; 1135 } 1136 if(super_frame->bufs[0] == NULL ) { 1137 ALOGE("%s: Error, Super buffer frame does not contain valid buffer", 1138 __func__); 1139 return; 1140 } 1141 1142 frameIndex = (uint8_t)super_frame->bufs[0]->buf_idx; 1143 if(frameIndex >= mNumBufs) { 1144 ALOGE("%s: Error, Invalid index for buffer",__func__); 1145 if(stream) { 1146 stream->bufDone(frameIndex); 1147 } 1148 return; 1149 } 1150 1151 frame = (mm_camera_super_buf_t *)malloc(sizeof(mm_camera_super_buf_t)); 1152 if (frame == NULL) { 1153 ALOGE("%s: Error allocating memory to save received_frame structure.", 1154 __func__); 1155 if(stream) { 1156 stream->bufDone(frameIndex); 1157 } 1158 return; 1159 } 1160 *frame = *super_frame; 1161 1162 m_postprocessor.processData(frame); 1163 free(super_frame); 1164 return; 1165} 1166 1167QCamera3Memory* QCamera3PicChannel::getStreamBufs(uint32_t len) 1168{ 1169 int rc = 0; 1170 1171 if (mNumBufs == 0 || mCamera3Buffers == NULL) { 1172 ALOGE("%s: buffers not registered yet", __func__); 1173 return NULL; 1174 } 1175 1176 if(mMemory) { 1177 delete mMemory; 1178 mMemory = NULL; 1179 } 1180 mMemory = new QCamera3GrallocMemory(); 1181 if (mMemory == NULL) { 1182 return NULL; 1183 } 1184 1185 //Registering Jpeg output buffer 1186 if (mMemory->registerBuffers(mNumBufs, mCamera3Buffers) < 0) { 1187 delete mMemory; 1188 mMemory = NULL; 1189 return NULL; 1190 } 1191 1192 mYuvMemory = new QCamera3HeapMemory(); 1193 if (!mYuvMemory) { 1194 ALOGE("%s: unable to create metadata memory", __func__); 1195 return NULL; 1196 } 1197 1198 //Queue YUV buffers in the beginning mQueueAll = true 1199 rc = mYuvMemory->allocate(1, len, false); 1200 if (rc < 0) { 1201 ALOGE("%s: unable to allocate metadata memory", __func__); 1202 delete mYuvMemory; 1203 mYuvMemory = NULL; 1204 return NULL; 1205 } 1206 return mYuvMemory; 1207} 1208 1209void QCamera3PicChannel::putStreamBufs() 1210{ 1211 mMemory->unregisterBuffers(); 1212 delete mMemory; 1213 mMemory = NULL; 1214 1215 mYuvMemory->deallocate(); 1216 delete mYuvMemory; 1217 mYuvMemory = NULL; 1218} 1219 1220bool QCamera3PicChannel::isRawSnapshot() 1221{ 1222 return !(mJpegSettings->is_jpeg_format); 1223} 1224/*=========================================================================== 1225 * FUNCTION : getThumbnailSize 1226 * 1227 * DESCRIPTION: get user set thumbnail size 1228 * 1229 * PARAMETERS : 1230 * @dim : output of thumbnail dimension 1231 * 1232 * RETURN : none 1233 *==========================================================================*/ 1234void QCamera3PicChannel::getThumbnailSize(cam_dimension_t &dim) 1235{ 1236 dim = mJpegSettings->thumbnail_size; 1237} 1238 1239/*=========================================================================== 1240 * FUNCTION : getJpegQuality 1241 * 1242 * DESCRIPTION: get user set jpeg quality 1243 * 1244 * PARAMETERS : none 1245 * 1246 * RETURN : jpeg quality setting 1247 *==========================================================================*/ 1248int QCamera3PicChannel::getJpegQuality() 1249{ 1250 int quality = mJpegSettings->jpeg_quality; 1251 if (quality < 0) { 1252 quality = 85; //set to default quality value 1253 } 1254 return quality; 1255} 1256 1257/*=========================================================================== 1258 * FUNCTION : getJpegRotation 1259 * 1260 * DESCRIPTION: get rotation information to be passed into jpeg encoding 1261 * 1262 * PARAMETERS : none 1263 * 1264 * RETURN : rotation information 1265 *==========================================================================*/ 1266int QCamera3PicChannel::getJpegRotation() { 1267 int rotation = mJpegSettings->jpeg_orientation; 1268 if (rotation < 0) { 1269 rotation = 0; 1270 } 1271 return rotation; 1272} 1273 1274void QCamera3PicChannel::queueMetadata(mm_camera_super_buf_t *metadata_buf, 1275 QCamera3Channel *pMetaChannel, 1276 bool relinquish) 1277{ 1278 if(relinquish) 1279 mMetaFrame = metadata_buf; 1280 m_pMetaChannel = pMetaChannel; 1281 m_postprocessor.processPPMetadata(metadata_buf); 1282} 1283/*=========================================================================== 1284 * FUNCTION : getRational 1285 * 1286 * DESCRIPTION: compose rational struct 1287 * 1288 * PARAMETERS : 1289 * @rat : ptr to struct to store rational info 1290 * @num :num of the rational 1291 * @denom : denom of the rational 1292 * 1293 * RETURN : int32_t type of status 1294 * NO_ERROR -- success 1295 * none-zero failure code 1296 *==========================================================================*/ 1297int32_t getRational(rat_t *rat, int num, int denom) 1298{ 1299 if (NULL == rat) { 1300 ALOGE("%s: NULL rat input", __func__); 1301 return BAD_VALUE; 1302 } 1303 rat->num = num; 1304 rat->denom = denom; 1305 return NO_ERROR; 1306} 1307 1308/*=========================================================================== 1309 * FUNCTION : parseGPSCoordinate 1310 * 1311 * DESCRIPTION: parse GPS coordinate string 1312 * 1313 * PARAMETERS : 1314 * @coord_str : [input] coordinate string 1315 * @coord : [output] ptr to struct to store coordinate 1316 * 1317 * RETURN : int32_t type of status 1318 * NO_ERROR -- success 1319 * none-zero failure code 1320 *==========================================================================*/ 1321int parseGPSCoordinate(const char *coord_str, rat_t* coord) 1322{ 1323 if(coord == NULL) { 1324 ALOGE("%s: error, invalid argument coord == NULL", __func__); 1325 return BAD_VALUE; 1326 } 1327 float degF = atof(coord_str); 1328 if (degF < 0) { 1329 degF = -degF; 1330 } 1331 float minF = (degF - (int) degF) * 60; 1332 float secF = (minF - (int) minF) * 60; 1333 1334 getRational(&coord[0], (int)degF, 1); 1335 getRational(&coord[1], (int)minF, 1); 1336 getRational(&coord[2], (int)(secF * 10000), 10000); 1337 return NO_ERROR; 1338} 1339 1340/*=========================================================================== 1341 * FUNCTION : getExifDateTime 1342 * 1343 * DESCRIPTION: query exif date time 1344 * 1345 * PARAMETERS : 1346 * @dateTime : string to store exif date time 1347 * @count : lenght of the dateTime string 1348 * 1349 * RETURN : int32_t type of status 1350 * NO_ERROR -- success 1351 * none-zero failure code 1352 *==========================================================================*/ 1353int32_t getExifDateTime(char *dateTime, uint32_t &count) 1354{ 1355 //get time and date from system 1356 time_t rawtime; 1357 struct tm * timeinfo; 1358 time(&rawtime); 1359 timeinfo = localtime (&rawtime); 1360 //Write datetime according to EXIF Spec 1361 //"YYYY:MM:DD HH:MM:SS" (20 chars including \0) 1362 snprintf(dateTime, 20, "%04d:%02d:%02d %02d:%02d:%02d", 1363 timeinfo->tm_year + 1900, timeinfo->tm_mon + 1, 1364 timeinfo->tm_mday, timeinfo->tm_hour, 1365 timeinfo->tm_min, timeinfo->tm_sec); 1366 count = 20; 1367 1368 return NO_ERROR; 1369} 1370 1371/*=========================================================================== 1372 * FUNCTION : getExifFocalLength 1373 * 1374 * DESCRIPTION: get exif focal lenght 1375 * 1376 * PARAMETERS : 1377 * @focalLength : ptr to rational strcut to store focal lenght 1378 * 1379 * RETURN : int32_t type of status 1380 * NO_ERROR -- success 1381 * none-zero failure code 1382 *==========================================================================*/ 1383int32_t getExifFocalLength(rat_t *focalLength, float value) 1384{ 1385 int focalLengthValue = 1386 (int)(value * FOCAL_LENGTH_DECIMAL_PRECISION); 1387 return getRational(focalLength, focalLengthValue, FOCAL_LENGTH_DECIMAL_PRECISION); 1388} 1389 1390/*=========================================================================== 1391 * FUNCTION : getExifExpTimeInfo 1392 * 1393 * DESCRIPTION: get exif exposure time information 1394 * 1395 * PARAMETERS : 1396 * @expoTimeInfo : expousure time value 1397 * RETURN : nt32_t type of status 1398 * NO_ERROR -- success 1399 * none-zero failure code 1400 *==========================================================================*/ 1401int32_t getExifExpTimeInfo(rat_t *expoTimeInfo, int64_t value) 1402{ 1403 1404 int cal_exposureTime; 1405 if (value != 0) 1406 cal_exposureTime = value; 1407 else 1408 cal_exposureTime = 60; 1409 1410 return getRational(expoTimeInfo, 1, cal_exposureTime); 1411} 1412 1413/*=========================================================================== 1414 * FUNCTION : getExifGpsProcessingMethod 1415 * 1416 * DESCRIPTION: get GPS processing method 1417 * 1418 * PARAMETERS : 1419 * @gpsProcessingMethod : string to store GPS process method 1420 * @count : lenght of the string 1421 * 1422 * RETURN : int32_t type of status 1423 * NO_ERROR -- success 1424 * none-zero failure code 1425 *==========================================================================*/ 1426int32_t getExifGpsProcessingMethod(char *gpsProcessingMethod, 1427 uint32_t &count, char* value) 1428{ 1429 if(value != NULL) { 1430 memcpy(gpsProcessingMethod, ExifAsciiPrefix, EXIF_ASCII_PREFIX_SIZE); 1431 count = EXIF_ASCII_PREFIX_SIZE; 1432 strncpy(gpsProcessingMethod + EXIF_ASCII_PREFIX_SIZE, value, strlen(value)); 1433 count += strlen(value); 1434 gpsProcessingMethod[count++] = '\0'; // increase 1 for the last NULL char 1435 return NO_ERROR; 1436 } else { 1437 return BAD_VALUE; 1438 } 1439} 1440 1441/*=========================================================================== 1442 * FUNCTION : getExifLatitude 1443 * 1444 * DESCRIPTION: get exif latitude 1445 * 1446 * PARAMETERS : 1447 * @latitude : ptr to rational struct to store latitude info 1448 * @ladRef : charater to indicate latitude reference 1449 * 1450 * RETURN : int32_t type of status 1451 * NO_ERROR -- success 1452 * none-zero failure code 1453 *==========================================================================*/ 1454int32_t getExifLatitude(rat_t *latitude, 1455 char *latRef, double value) 1456{ 1457 char str[30]; 1458 snprintf(str, sizeof(str), "%f", value); 1459 if(str != NULL) { 1460 parseGPSCoordinate(str, latitude); 1461 1462 //set Latitude Ref 1463 float latitudeValue = strtof(str, 0); 1464 if(latitudeValue < 0.0f) { 1465 latRef[0] = 'S'; 1466 } else { 1467 latRef[0] = 'N'; 1468 } 1469 latRef[1] = '\0'; 1470 return NO_ERROR; 1471 }else{ 1472 return BAD_VALUE; 1473 } 1474} 1475 1476/*=========================================================================== 1477 * FUNCTION : getExifLongitude 1478 * 1479 * DESCRIPTION: get exif longitude 1480 * 1481 * PARAMETERS : 1482 * @longitude : ptr to rational struct to store longitude info 1483 * @lonRef : charater to indicate longitude reference 1484 * 1485 * RETURN : int32_t type of status 1486 * NO_ERROR -- success 1487 * none-zero failure code 1488 *==========================================================================*/ 1489int32_t getExifLongitude(rat_t *longitude, 1490 char *lonRef, double value) 1491{ 1492 char str[30]; 1493 snprintf(str, sizeof(str), "%f", value); 1494 if(str != NULL) { 1495 parseGPSCoordinate(str, longitude); 1496 1497 //set Longitude Ref 1498 float longitudeValue = strtof(str, 0); 1499 if(longitudeValue < 0.0f) { 1500 lonRef[0] = 'W'; 1501 } else { 1502 lonRef[0] = 'E'; 1503 } 1504 lonRef[1] = '\0'; 1505 return NO_ERROR; 1506 }else{ 1507 return BAD_VALUE; 1508 } 1509} 1510 1511/*=========================================================================== 1512 * FUNCTION : getExifAltitude 1513 * 1514 * DESCRIPTION: get exif altitude 1515 * 1516 * PARAMETERS : 1517 * @altitude : ptr to rational struct to store altitude info 1518 * @altRef : charater to indicate altitude reference 1519 * 1520 * RETURN : int32_t type of status 1521 * NO_ERROR -- success 1522 * none-zero failure code 1523 *==========================================================================*/ 1524int32_t getExifAltitude(rat_t *altitude, 1525 char *altRef, double value) 1526{ 1527 char str[30]; 1528 snprintf(str, sizeof(str), "%f", value); 1529 if(str != NULL) { 1530 double value = atof(str); 1531 *altRef = 0; 1532 if(value < 0){ 1533 *altRef = 1; 1534 value = -value; 1535 } 1536 return getRational(altitude, value*1000, 1000); 1537 }else{ 1538 return BAD_VALUE; 1539 } 1540} 1541 1542/*=========================================================================== 1543 * FUNCTION : getExifGpsDateTimeStamp 1544 * 1545 * DESCRIPTION: get exif GPS date time stamp 1546 * 1547 * PARAMETERS : 1548 * @gpsDateStamp : GPS date time stamp string 1549 * @bufLen : length of the string 1550 * @gpsTimeStamp : ptr to rational struct to store time stamp info 1551 * 1552 * RETURN : int32_t type of status 1553 * NO_ERROR -- success 1554 * none-zero failure code 1555 *==========================================================================*/ 1556int32_t getExifGpsDateTimeStamp(char *gpsDateStamp, 1557 uint32_t bufLen, 1558 rat_t *gpsTimeStamp, int64_t value) 1559{ 1560 char str[30]; 1561 snprintf(str, sizeof(str), "%lld", value); 1562 if(str != NULL) { 1563 time_t unixTime = (time_t)atol(str); 1564 struct tm *UTCTimestamp = gmtime(&unixTime); 1565 1566 strftime(gpsDateStamp, bufLen, "%Y:%m:%d", UTCTimestamp); 1567 1568 getRational(&gpsTimeStamp[0], UTCTimestamp->tm_hour, 1); 1569 getRational(&gpsTimeStamp[1], UTCTimestamp->tm_min, 1); 1570 getRational(&gpsTimeStamp[2], UTCTimestamp->tm_sec, 1); 1571 1572 return NO_ERROR; 1573 } else { 1574 return BAD_VALUE; 1575 } 1576} 1577 1578int32_t getExifExposureValue(srat_t* exposure_val, int32_t exposure_comp, 1579 cam_rational_type_t step) 1580{ 1581 exposure_val->num = exposure_comp * step.numerator; 1582 exposure_val->denom = step.denominator; 1583 return 0; 1584} 1585/*=========================================================================== 1586 * FUNCTION : getExifData 1587 * 1588 * DESCRIPTION: get exif data to be passed into jpeg encoding 1589 * 1590 * PARAMETERS : none 1591 * 1592 * RETURN : exif data from user setting and GPS 1593 *==========================================================================*/ 1594QCamera3Exif *QCamera3PicChannel::getExifData() 1595{ 1596 QCamera3Exif *exif = new QCamera3Exif(); 1597 if (exif == NULL) { 1598 ALOGE("%s: No memory for QCamera3Exif", __func__); 1599 return NULL; 1600 } 1601 1602 int32_t rc = NO_ERROR; 1603 uint32_t count = 0; 1604 1605 // add exif entries 1606 char dateTime[20]; 1607 memset(dateTime, 0, sizeof(dateTime)); 1608 count = 20; 1609 rc = getExifDateTime(dateTime, count); 1610 if(rc == NO_ERROR) { 1611 exif->addEntry(EXIFTAGID_EXIF_DATE_TIME_ORIGINAL, 1612 EXIF_ASCII, 1613 count, 1614 (void *)dateTime); 1615 } else { 1616 ALOGE("%s: getExifDateTime failed", __func__); 1617 } 1618 1619 rat_t focalLength; 1620 rc = getExifFocalLength(&focalLength, mJpegSettings->lens_focal_length); 1621 if (rc == NO_ERROR) { 1622 exif->addEntry(EXIFTAGID_FOCAL_LENGTH, 1623 EXIF_RATIONAL, 1624 1, 1625 (void *)&(focalLength)); 1626 } else { 1627 ALOGE("%s: getExifFocalLength failed", __func__); 1628 } 1629 1630 uint16_t isoSpeed = (uint16_t)mJpegSettings->sensor_sensitivity; 1631 exif->addEntry(EXIFTAGID_ISO_SPEED_RATING, 1632 EXIF_SHORT, 1633 1, 1634 (void *)&(isoSpeed)); 1635 1636 rat_t sensorExpTime ; 1637 rc = getExifExpTimeInfo(&sensorExpTime, (int64_t)mJpegSettings->sensor_exposure_time); 1638 if (rc == NO_ERROR){ 1639 exif->addEntry(EXIFTAGID_EXPOSURE_TIME, 1640 EXIF_RATIONAL, 1641 1, 1642 (void *)&(sensorExpTime)); 1643 } else { 1644 ALOGE("%s: getExifExpTimeInfo failed", __func__); 1645 } 1646 1647 if (strlen(mJpegSettings->gps_processing_method) > 0) { 1648 char gpsProcessingMethod[EXIF_ASCII_PREFIX_SIZE + GPS_PROCESSING_METHOD_SIZE]; 1649 count = 0; 1650 rc = getExifGpsProcessingMethod(gpsProcessingMethod, count, mJpegSettings->gps_processing_method); 1651 if(rc == NO_ERROR) { 1652 exif->addEntry(EXIFTAGID_GPS_PROCESSINGMETHOD, 1653 EXIF_ASCII, 1654 count, 1655 (void *)gpsProcessingMethod); 1656 } else { 1657 ALOGE("%s: getExifGpsProcessingMethod failed", __func__); 1658 } 1659 } 1660 1661 if (mJpegSettings->gps_coordinates[0]) { 1662 rat_t latitude[3]; 1663 char latRef[2]; 1664 rc = getExifLatitude(latitude, latRef, *(mJpegSettings->gps_coordinates[0])); 1665 if(rc == NO_ERROR) { 1666 exif->addEntry(EXIFTAGID_GPS_LATITUDE, 1667 EXIF_RATIONAL, 1668 3, 1669 (void *)latitude); 1670 exif->addEntry(EXIFTAGID_GPS_LATITUDE_REF, 1671 EXIF_ASCII, 1672 2, 1673 (void *)latRef); 1674 } else { 1675 ALOGE("%s: getExifLatitude failed", __func__); 1676 } 1677 } 1678 1679 if (mJpegSettings->gps_coordinates[1]) { 1680 rat_t longitude[3]; 1681 char lonRef[2]; 1682 rc = getExifLongitude(longitude, lonRef, *(mJpegSettings->gps_coordinates[1])); 1683 if(rc == NO_ERROR) { 1684 exif->addEntry(EXIFTAGID_GPS_LONGITUDE, 1685 EXIF_RATIONAL, 1686 3, 1687 (void *)longitude); 1688 1689 exif->addEntry(EXIFTAGID_GPS_LONGITUDE_REF, 1690 EXIF_ASCII, 1691 2, 1692 (void *)lonRef); 1693 } else { 1694 ALOGE("%s: getExifLongitude failed", __func__); 1695 } 1696 } 1697 1698 if (mJpegSettings->gps_coordinates[2]) { 1699 rat_t altitude; 1700 char altRef; 1701 rc = getExifAltitude(&altitude, &altRef, *(mJpegSettings->gps_coordinates[2])); 1702 if(rc == NO_ERROR) { 1703 exif->addEntry(EXIFTAGID_GPS_ALTITUDE, 1704 EXIF_RATIONAL, 1705 1, 1706 (void *)&(altitude)); 1707 1708 exif->addEntry(EXIFTAGID_GPS_ALTITUDE_REF, 1709 EXIF_BYTE, 1710 1, 1711 (void *)&altRef); 1712 } else { 1713 ALOGE("%s: getExifAltitude failed", __func__); 1714 } 1715 } 1716 1717 if (mJpegSettings->gps_timestamp) { 1718 char gpsDateStamp[20]; 1719 rat_t gpsTimeStamp[3]; 1720 rc = getExifGpsDateTimeStamp(gpsDateStamp, 20, gpsTimeStamp, *(mJpegSettings->gps_timestamp)); 1721 if(rc == NO_ERROR) { 1722 exif->addEntry(EXIFTAGID_GPS_DATESTAMP, 1723 EXIF_ASCII, 1724 strlen(gpsDateStamp) + 1, 1725 (void *)gpsDateStamp); 1726 1727 exif->addEntry(EXIFTAGID_GPS_TIMESTAMP, 1728 EXIF_RATIONAL, 1729 3, 1730 (void *)gpsTimeStamp); 1731 } else { 1732 ALOGE("%s: getExifGpsDataTimeStamp failed", __func__); 1733 } 1734 } 1735 1736 srat_t exposure_val; 1737 rc = getExifExposureValue(&exposure_val, mJpegSettings->exposure_compensation, 1738 mJpegSettings->exposure_comp_step); 1739 if(rc == NO_ERROR) { 1740 exif->addEntry(EXIFTAGID_EXPOSURE_BIAS_VALUE, 1741 EXIF_SRATIONAL, 1742 1, 1743 (void *)(&exposure_val)); 1744 } else { 1745 ALOGE("%s: getExifExposureValue failed ", __func__); 1746 } 1747 1748 return exif; 1749} 1750 1751int QCamera3PicChannel::kMaxBuffers = 1; 1752 1753/*=========================================================================== 1754 * FUNCTION : QCamera3ReprocessChannel 1755 * 1756 * DESCRIPTION: constructor of QCamera3ReprocessChannel 1757 * 1758 * PARAMETERS : 1759 * @cam_handle : camera handle 1760 * @cam_ops : ptr to camera ops table 1761 * @pp_mask : post-proccess feature mask 1762 * 1763 * RETURN : none 1764 *==========================================================================*/ 1765QCamera3ReprocessChannel::QCamera3ReprocessChannel(uint32_t cam_handle, 1766 mm_camera_ops_t *cam_ops, 1767 channel_cb_routine cb_routine, 1768 cam_padding_info_t *paddingInfo, 1769 void *userData, void *ch_hdl) : 1770 QCamera3Channel(cam_handle, cam_ops, cb_routine, paddingInfo, userData), 1771 picChHandle(ch_hdl), 1772 m_pSrcChannel(NULL), 1773 m_pMetaChannel(NULL), 1774 mMemory(NULL) 1775{ 1776 memset(mSrcStreamHandles, 0, sizeof(mSrcStreamHandles)); 1777} 1778 1779 1780/*=========================================================================== 1781 * FUNCTION : QCamera3ReprocessChannel 1782 * 1783 * DESCRIPTION: constructor of QCamera3ReprocessChannel 1784 * 1785 * PARAMETERS : 1786 * @cam_handle : camera handle 1787 * @cam_ops : ptr to camera ops table 1788 * @pp_mask : post-proccess feature mask 1789 * 1790 * RETURN : none 1791 *==========================================================================*/ 1792int32_t QCamera3ReprocessChannel::initialize() 1793{ 1794 int32_t rc = NO_ERROR; 1795 mm_camera_channel_attr_t attr; 1796 1797 memset(&attr, 0, sizeof(mm_camera_channel_attr_t)); 1798 attr.notify_mode = MM_CAMERA_SUPER_BUF_NOTIFY_CONTINUOUS; 1799 attr.max_unmatched_frames = 1; 1800 1801 rc = init(&attr, NULL); 1802 if (rc < 0) { 1803 ALOGE("%s: init failed", __func__); 1804 } 1805 return rc; 1806} 1807 1808 1809/*=========================================================================== 1810 * FUNCTION : QCamera3ReprocessChannel 1811 * 1812 * DESCRIPTION: constructor of QCamera3ReprocessChannel 1813 * 1814 * PARAMETERS : 1815 * @cam_handle : camera handle 1816 * @cam_ops : ptr to camera ops table 1817 * @pp_mask : post-proccess feature mask 1818 * 1819 * RETURN : none 1820 *==========================================================================*/ 1821void QCamera3ReprocessChannel::streamCbRoutine(mm_camera_super_buf_t *super_frame, 1822 QCamera3Stream *stream) 1823{ 1824 //Got the pproc data callback. Now send to jpeg encoding 1825 uint8_t frameIndex; 1826 mm_camera_super_buf_t* frame = NULL; 1827 QCamera3PicChannel *obj = (QCamera3PicChannel *)picChHandle; 1828 1829 if(!super_frame) { 1830 ALOGE("%s: Invalid Super buffer",__func__); 1831 return; 1832 } 1833 1834 if(super_frame->num_bufs != 1) { 1835 ALOGE("%s: Multiple streams are not supported",__func__); 1836 return; 1837 } 1838 if(super_frame->bufs[0] == NULL ) { 1839 ALOGE("%s: Error, Super buffer frame does not contain valid buffer", 1840 __func__); 1841 return; 1842 } 1843 1844 frameIndex = (uint8_t)super_frame->bufs[0]->buf_idx; 1845 frame = (mm_camera_super_buf_t *)malloc(sizeof(mm_camera_super_buf_t)); 1846 if (frame == NULL) { 1847 ALOGE("%s: Error allocating memory to save received_frame structure.", 1848 __func__); 1849 if(stream) { 1850 stream->bufDone(frameIndex); 1851 } 1852 return; 1853 } 1854 *frame = *super_frame; 1855 obj->m_postprocessor.processPPData(frame); 1856 return; 1857} 1858 1859/*=========================================================================== 1860 * FUNCTION : QCamera3ReprocessChannel 1861 * 1862 * DESCRIPTION: default constructor of QCamera3ReprocessChannel 1863 * 1864 * PARAMETERS : none 1865 * 1866 * RETURN : none 1867 *==========================================================================*/ 1868QCamera3ReprocessChannel::QCamera3ReprocessChannel() : 1869 m_pSrcChannel(NULL), 1870 m_pMetaChannel(NULL) 1871{ 1872} 1873 1874/*=========================================================================== 1875 * FUNCTION : QCamera3ReprocessChannel 1876 * 1877 * DESCRIPTION: register the buffers of the reprocess channel 1878 * 1879 * PARAMETERS : none 1880 * 1881 * RETURN : none 1882 *==========================================================================*/ 1883int32_t QCamera3ReprocessChannel::registerBuffers( 1884 uint32_t /*num_buffers*/, buffer_handle_t ** /*buffers*/) 1885{ 1886 return 0; 1887} 1888 1889/*=========================================================================== 1890 * FUNCTION : getStreamBufs 1891 * 1892 * DESCRIPTION: register the buffers of the reprocess channel 1893 * 1894 * PARAMETERS : none 1895 * 1896 * RETURN : QCamera3Memory * 1897 *==========================================================================*/ 1898QCamera3Memory* QCamera3ReprocessChannel::getStreamBufs(uint32_t len) 1899{ 1900 int rc = 0; 1901 1902 mMemory = new QCamera3HeapMemory(); 1903 if (!mMemory) { 1904 ALOGE("%s: unable to create reproc memory", __func__); 1905 return NULL; 1906 } 1907 1908 //Queue YUV buffers in the beginning mQueueAll = true 1909 rc = mMemory->allocate(2, len, true); 1910 if (rc < 0) { 1911 ALOGE("%s: unable to allocate reproc memory", __func__); 1912 delete mMemory; 1913 mMemory = NULL; 1914 return NULL; 1915 } 1916 return mMemory; 1917} 1918 1919/*=========================================================================== 1920 * FUNCTION : getStreamBufs 1921 * 1922 * DESCRIPTION: register the buffers of the reprocess channel 1923 * 1924 * PARAMETERS : none 1925 * 1926 * RETURN : 1927 *==========================================================================*/ 1928void QCamera3ReprocessChannel::putStreamBufs() 1929{ 1930 mMemory->deallocate(); 1931 delete mMemory; 1932 mMemory = NULL; 1933} 1934 1935/*=========================================================================== 1936 * FUNCTION : ~QCamera3ReprocessChannel 1937 * 1938 * DESCRIPTION: destructor of QCamera3ReprocessChannel 1939 * 1940 * PARAMETERS : none 1941 * 1942 * RETURN : none 1943 *==========================================================================*/ 1944QCamera3ReprocessChannel::~QCamera3ReprocessChannel() 1945{ 1946} 1947 1948/*=========================================================================== 1949 * FUNCTION : getStreamBySourceHandle 1950 * 1951 * DESCRIPTION: find reprocess stream by its source stream handle 1952 * 1953 * PARAMETERS : 1954 * @srcHandle : source stream handle 1955 * 1956 * RETURN : ptr to reprocess stream if found. NULL if not found 1957 *==========================================================================*/ 1958QCamera3Stream * QCamera3ReprocessChannel::getStreamBySourceHandle(uint32_t srcHandle) 1959{ 1960 QCamera3Stream *pStream = NULL; 1961 1962 for (int i = 0; i < m_numStreams; i++) { 1963 if (mSrcStreamHandles[i] == srcHandle) { 1964 pStream = mStreams[i]; 1965 break; 1966 } 1967 } 1968 return pStream; 1969} 1970 1971/*=========================================================================== 1972 * FUNCTION : metadataBufDone 1973 * 1974 * DESCRIPTION: buf done method for a metadata buffer 1975 * 1976 * PARAMETERS : 1977 * @recvd_frame : received metadata frame 1978 * 1979 * RETURN : 1980 *==========================================================================*/ 1981int32_t QCamera3ReprocessChannel::metadataBufDone(mm_camera_super_buf_t *recvd_frame) 1982{ 1983 int32_t rc; 1984 rc = ((QCamera3MetadataChannel*)m_pMetaChannel)->bufDone(recvd_frame); 1985 free(recvd_frame); 1986 recvd_frame = NULL; 1987 return rc; 1988} 1989 1990/*=========================================================================== 1991 * FUNCTION : doReprocess 1992 * 1993 * DESCRIPTION: request to do a reprocess on the frame 1994 * 1995 * PARAMETERS : 1996 * @frame : frame to be performed a reprocess 1997 * 1998 * RETURN : int32_t type of status 1999 * NO_ERROR -- success 2000 * none-zero failure code 2001 *==========================================================================*/ 2002int32_t QCamera3ReprocessChannel::doReprocess(mm_camera_super_buf_t *frame, 2003 mm_camera_super_buf_t *meta_frame) 2004{ 2005 int32_t rc = 0; 2006 if (m_numStreams < 1) { 2007 ALOGE("%s: No reprocess stream is created", __func__); 2008 return -1; 2009 } 2010 if (m_pSrcChannel == NULL) { 2011 ALOGE("%s: No source channel for reprocess", __func__); 2012 return -1; 2013 } 2014 for (int i = 0; i < frame->num_bufs; i++) { 2015 QCamera3Stream *pStream = getStreamBySourceHandle(frame->bufs[i]->stream_id); 2016 if (pStream != NULL) { 2017 cam_stream_parm_buffer_t param; 2018 memset(¶m, 0, sizeof(cam_stream_parm_buffer_t)); 2019 param.type = CAM_STREAM_PARAM_TYPE_DO_REPROCESS; 2020 param.reprocess.buf_index = frame->bufs[i]->buf_idx; 2021 param.reprocess.frame_idx = frame->bufs[i]->frame_idx; 2022 if (meta_frame != NULL) { 2023 param.reprocess.meta_present = 1; 2024 param.reprocess.meta_stream_handle = m_pMetaChannel->mStreams[0]->getMyServerID(); 2025 param.reprocess.meta_buf_index = meta_frame->bufs[0]->buf_idx; 2026 } 2027 rc = pStream->setParameter(param); 2028 if (rc != NO_ERROR) { 2029 ALOGE("%s: stream setParameter for reprocess failed", __func__); 2030 break; 2031 } 2032 } 2033 } 2034 return rc; 2035} 2036 2037/*=========================================================================== 2038 * FUNCTION : doReprocess 2039 * 2040 * DESCRIPTION: request to do a reprocess on the frame 2041 * 2042 * PARAMETERS : 2043 * @buf_fd : fd to the input buffer that needs reprocess 2044 * @buf_lenght : length of the input buffer 2045 * @ret_val : result of reprocess. 2046 * Example: Could be faceID in case of register face image. 2047 * 2048 * RETURN : int32_t type of status 2049 * NO_ERROR -- success 2050 * none-zero failure code 2051 *==========================================================================*/ 2052int32_t QCamera3ReprocessChannel::doReprocess(int buf_fd, 2053 uint32_t buf_length, 2054 int32_t &ret_val, 2055 mm_camera_super_buf_t *meta_frame) 2056{ 2057 int32_t rc = 0; 2058 if (m_numStreams < 1) { 2059 ALOGE("%s: No reprocess stream is created", __func__); 2060 return -1; 2061 } 2062 if (meta_frame == NULL) { 2063 ALOGE("%s: Did not get corresponding metadata in time", __func__); 2064 return -1; 2065 } 2066 2067 uint32_t buf_idx = 0; 2068 for (int i = 0; i < m_numStreams; i++) { 2069 rc = mStreams[i]->mapBuf(CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF, 2070 buf_idx, -1, 2071 buf_fd, buf_length); 2072 2073 if (rc == NO_ERROR) { 2074 cam_stream_parm_buffer_t param; 2075 memset(¶m, 0, sizeof(cam_stream_parm_buffer_t)); 2076 param.type = CAM_STREAM_PARAM_TYPE_DO_REPROCESS; 2077 param.reprocess.buf_index = buf_idx; 2078 param.reprocess.meta_present = 1; 2079 param.reprocess.meta_stream_handle = m_pMetaChannel->mStreams[0]->getMyServerID(); 2080 param.reprocess.meta_buf_index = meta_frame->bufs[0]->buf_idx; 2081 rc = mStreams[i]->setParameter(param); 2082 if (rc == NO_ERROR) { 2083 ret_val = param.reprocess.ret_val; 2084 } 2085 mStreams[i]->unmapBuf(CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF, 2086 buf_idx, -1); 2087 } 2088 } 2089 return rc; 2090} 2091 2092/*=========================================================================== 2093 * FUNCTION : addReprocStreamsFromSource 2094 * 2095 * DESCRIPTION: add reprocess streams from input source channel 2096 * 2097 * PARAMETERS : 2098 * @config : pp feature configuration 2099 * @pSrcChannel : ptr to input source channel that needs reprocess 2100 * @pMetaChannel : ptr to metadata channel to get corresp. metadata 2101 * 2102 * RETURN : int32_t type of status 2103 * NO_ERROR -- success 2104 * none-zero failure code 2105 *==========================================================================*/ 2106int32_t QCamera3ReprocessChannel::addReprocStreamsFromSource(cam_pp_feature_config_t &config, 2107 QCamera3Channel *pSrcChannel, 2108 QCamera3Channel *pMetaChannel) 2109{ 2110 int32_t rc = 0; 2111 QCamera3Stream *pSrcStream = pSrcChannel->getStreamByIndex(0); 2112 if (pSrcStream == NULL) { 2113 ALOGE("%s: source channel doesn't have a stream", __func__); 2114 return BAD_VALUE; 2115 } 2116 cam_stream_reproc_config_t reprocess_config; 2117 cam_dimension_t streamDim; 2118 cam_stream_type_t streamType; 2119 cam_format_t streamFormat; 2120 cam_frame_len_offset_t frameOffset; 2121 int num_buffers = 2; 2122 2123 streamType = CAM_STREAM_TYPE_OFFLINE_PROC; 2124 pSrcStream->getFormat(streamFormat); 2125 pSrcStream->getFrameDimension(streamDim); 2126 pSrcStream->getFrameOffset(frameOffset); 2127 2128 reprocess_config.pp_type = CAM_ONLINE_REPROCESS_TYPE; 2129 reprocess_config.online.input_stream_id = pSrcStream->getMyServerID(); 2130 reprocess_config.online.input_stream_type = pSrcStream->getMyType(); 2131 reprocess_config.pp_feature_config = config; 2132 2133 mSrcStreamHandles[m_numStreams] = pSrcStream->getMyHandle(); 2134 2135 if (reprocess_config.pp_feature_config.feature_mask & CAM_QCOM_FEATURE_ROTATION) { 2136 if (reprocess_config.pp_feature_config.rotation == ROTATE_90 || 2137 reprocess_config.pp_feature_config.rotation == ROTATE_270) { 2138 // rotated by 90 or 270, need to switch width and height 2139 int32_t temp = streamDim.height; 2140 streamDim.height = streamDim.width; 2141 streamDim.width = temp; 2142 } 2143 } 2144 2145 QCamera3Stream *pStream = new QCamera3Stream(m_camHandle, 2146 m_handle, 2147 m_camOps, 2148 mPaddingInfo, 2149 (QCamera3Channel*)this); 2150 if (pStream == NULL) { 2151 ALOGE("%s: No mem for Stream", __func__); 2152 return NO_MEMORY; 2153 } 2154 2155 rc = pStream->init(streamType, streamFormat, streamDim, &reprocess_config, 2156 num_buffers,QCamera3Channel::streamCbRoutine, this); 2157 2158 2159 if (rc == 0) { 2160 mStreams[m_numStreams] = pStream; 2161 m_numStreams++; 2162 } else { 2163 ALOGE("%s: failed to create reprocess stream", __func__); 2164 delete pStream; 2165 } 2166 2167 if (rc == NO_ERROR) { 2168 m_pSrcChannel = pSrcChannel; 2169 m_pMetaChannel = pMetaChannel; 2170 } 2171 if(m_camOps->request_super_buf(m_camHandle,m_handle,1) < 0) { 2172 ALOGE("%s: Request for super buffer failed",__func__); 2173 } 2174 return rc; 2175} 2176 2177 2178}; // namespace qcamera 2179