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